1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2006 Dan Everton
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
24 SDL_Surface
* lcd_surface
;
25 int lcd_backlight_val
;
29 SDL_Color lcd_backlight_color_zero
= {UI_LCD_BGCOLORLIGHT
, 0};
30 SDL_Color lcd_backlight_color_max
= {UI_LCD_FGCOLORLIGHT
, 0};
32 SDL_Color lcd_color_zero
= {UI_LCD_BGCOLOR
, 0};
33 SDL_Color lcd_color_max
= {UI_LCD_FGCOLOR
, 0};
37 int lcd_ex_shades
= 0;
38 unsigned long (*lcd_ex_getpixel
)(int, int) = NULL
;
41 static unsigned long get_lcd_pixel(int x
, int y
)
44 return ((lcd_framebuffer
[y
/8][x
] >> (y
& 7)) & 1);
46 #if LCD_PIXELFORMAT == HORIZONTAL_PACKING
47 return ((lcd_framebuffer
[y
][x
/4] >> (2 * (~x
& 3))) & 3);
48 #elif LCD_PIXELFORMAT == VERTICAL_PACKING
49 return ((lcd_framebuffer
[y
/4][x
] >> (2 * (y
& 3))) & 3);
50 #elif LCD_PIXELFORMAT == VERTICAL_INTERLEAVED
51 unsigned bits
= (lcd_framebuffer
[y
/8][x
] >> (y
& 7)) & 0x0101;
52 return (bits
| (bits
>> 7)) & 3;
55 #if LCD_PIXELFORMAT == RGB565SWAPPED
56 unsigned bits
= lcd_framebuffer
[y
][x
];
57 return (bits
>> 8) | (bits
<< 8);
59 return lcd_framebuffer
[y
][x
];
66 /* update a full screen rect */
67 lcd_update_rect(0, 0, LCD_WIDTH
, LCD_HEIGHT
);
70 void lcd_update_rect(int x_start
, int y_start
, int width
, int height
)
72 sdl_update_rect(lcd_surface
, x_start
, y_start
, width
, height
, LCD_WIDTH
,
73 LCD_HEIGHT
, get_lcd_pixel
);
74 sdl_gui_update(lcd_surface
, x_start
, y_start
, width
, height
, LCD_WIDTH
,
75 LCD_HEIGHT
, background
? UI_LCD_POSX
: 0, background
? UI_LCD_POSY
: 0);
79 void sim_backlight(int value
)
81 lcd_backlight_val
= value
;
85 sdl_set_gradient(lcd_surface
, &lcd_backlight_color_zero
,
86 &lcd_backlight_color_max
, 0, (1<<LCD_DEPTH
));
88 sdl_set_gradient(lcd_surface
, &lcd_color_zero
, &lcd_color_max
,
94 sdl_set_gradient(lcd_surface
, &lcd_backlight_color_max
,
95 &lcd_backlight_color_zero
, (1<<LCD_DEPTH
),
98 sdl_set_gradient(lcd_surface
, &lcd_color_max
, &lcd_color_zero
,
99 (1<<LCD_DEPTH
), lcd_ex_shades
);
104 sdl_gui_update(lcd_surface
, 0, 0, LCD_WIDTH
, LCD_HEIGHT
, LCD_WIDTH
,
105 LCD_HEIGHT
, background
? UI_LCD_POSX
: 0, background
? UI_LCD_POSY
: 0);
111 /* initialise simulator lcd driver */
112 void sim_lcd_init(void)
115 lcd_surface
= SDL_CreateRGBSurface(SDL_SWSURFACE
, LCD_WIDTH
* display_zoom
,
116 LCD_HEIGHT
* display_zoom
, LCD_DEPTH
, 0, 0, 0, 0);
118 lcd_surface
= SDL_CreateRGBSurface(SDL_SWSURFACE
, LCD_WIDTH
* display_zoom
,
119 LCD_HEIGHT
* display_zoom
, 8, 0, 0, 0, 0);
123 #ifdef HAVE_BACKLIGHT
124 sdl_set_gradient(lcd_surface
, &lcd_backlight_color_zero
, &lcd_color_max
,
127 sdl_set_gradient(lcd_surface
, &lcd_color_zero
, &lcd_color_max
, 0,
134 void sim_lcd_ex_init(int shades
, unsigned long (*getpixel
)(int, int))
136 lcd_ex_shades
= shades
;
137 lcd_ex_getpixel
= getpixel
;
139 #ifdef HAVE_BACKLIGHT
140 if (lcd_backlight_val
> 0) {
141 sdl_set_gradient(lcd_surface
, &lcd_color_max
,
142 &lcd_backlight_color_zero
, (1<<LCD_DEPTH
),
148 sdl_set_gradient(lcd_surface
, &lcd_color_max
, &lcd_color_zero
,
149 (1<<LCD_DEPTH
), shades
);
154 void sim_lcd_ex_update_rect(int x_start
, int y_start
, int width
, int height
)
156 if (lcd_ex_getpixel
) {
157 sdl_update_rect(lcd_surface
, x_start
, y_start
, width
, height
,
158 LCD_WIDTH
, LCD_HEIGHT
, lcd_ex_getpixel
);
159 sdl_gui_update(lcd_surface
, x_start
, y_start
, width
, height
, LCD_WIDTH
,
160 LCD_HEIGHT
, background
? UI_LCD_POSX
: 0,
161 background
? UI_LCD_POSY
: 0);
166 #ifdef HAVE_LCD_COLOR
168 * |R| |1.000000 -0.000001 1.402000| |Y'|
169 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
170 * |B| |1.000000 1.772000 0.000000| |Pr|
171 * Scaled, normalized, rounded and tweaked to yield RGB 565:
172 * |R| |74 0 101| |Y' - 16| >> 9
173 * |G| = |74 -24 -51| |Cb - 128| >> 8
174 * |B| |74 128 0| |Cr - 128| >> 9
182 static inline int clamp(int val
, int min
, int max
)
191 void lcd_yuv_set_options(unsigned options
)
196 /* Draw a partial YUV colour bitmap - similiar behavior to lcd_blit_yuv
198 void lcd_blit_yuv(unsigned char * const src
[3],
199 int src_x
, int src_y
, int stride
,
200 int x
, int y
, int width
, int height
)
202 const unsigned char *ysrc
, *usrc
, *vsrc
;
204 fb_data
*dst
, *row_end
;
207 /* width and height must be >= 2 and an even number */
209 linecounter
= height
>> 1;
211 #if LCD_WIDTH >= LCD_HEIGHT
212 dst
= &lcd_framebuffer
[y
][x
];
213 row_end
= dst
+ width
;
215 dst
= &lcd_framebuffer
[x
][LCD_WIDTH
- y
- 1];
216 row_end
= dst
+ LCD_WIDTH
* width
;
220 ysrc
= src
[0] + z
+ src_x
;
221 usrc
= src
[1] + (z
>> 2) + (src_x
>> 1);
222 vsrc
= src
[2] + (usrc
- src
[1]);
224 /* stride => amount to jump from end of last row to start of next */
227 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
233 int y
, cb
, cr
, rv
, guv
, bu
, r
, g
, b
;
235 y
= YFAC
*(*ysrc
++ - 16);
240 guv
= GUFAC
*cb
+ GVFAC
*cr
;
247 if ((unsigned)(r
| g
| b
) > 64*256-1)
249 r
= clamp(r
, 0, 64*256-1);
250 g
= clamp(g
, 0, 64*256-1);
251 b
= clamp(b
, 0, 64*256-1);
254 *dst
= LCD_RGBPACK_LCD(r
>> 9, g
>> 8, b
>> 9);
256 #if LCD_WIDTH >= LCD_HEIGHT
262 y
= YFAC
*(*ysrc
++ - 16);
267 if ((unsigned)(r
| g
| b
) > 64*256-1)
269 r
= clamp(r
, 0, 64*256-1);
270 g
= clamp(g
, 0, 64*256-1);
271 b
= clamp(b
, 0, 64*256-1);
274 *dst
= LCD_RGBPACK_LCD(r
>> 9, g
>> 8, b
>> 9);
276 #if LCD_WIDTH >= LCD_HEIGHT
282 while (dst
< row_end
);
288 #if LCD_WIDTH >= LCD_HEIGHT
289 row_end
+= LCD_WIDTH
;
290 dst
+= LCD_WIDTH
- width
;
293 dst
-= LCD_WIDTH
*width
+ 1;
298 int y
, cb
, cr
, rv
, guv
, bu
, r
, g
, b
;
300 y
= YFAC
*(*ysrc
++ - 16);
305 guv
= GUFAC
*cb
+ GVFAC
*cr
;
312 if ((unsigned)(r
| g
| b
) > 64*256-1)
314 r
= clamp(r
, 0, 64*256-1);
315 g
= clamp(g
, 0, 64*256-1);
316 b
= clamp(b
, 0, 64*256-1);
319 *dst
= LCD_RGBPACK_LCD(r
>> 9, g
>> 8, b
>> 9);
321 #if LCD_WIDTH >= LCD_HEIGHT
327 y
= YFAC
*(*ysrc
++ - 16);
332 if ((unsigned)(r
| g
| b
) > 64*256-1)
334 r
= clamp(r
, 0, 64*256-1);
335 g
= clamp(g
, 0, 64*256-1);
336 b
= clamp(b
, 0, 64*256-1);
339 *dst
= LCD_RGBPACK_LCD(r
>> 9, g
>> 8, b
>> 9);
341 #if LCD_WIDTH >= LCD_HEIGHT
347 while (dst
< row_end
);
353 #if LCD_WIDTH >= LCD_HEIGHT
354 row_end
+= LCD_WIDTH
;
355 dst
+= LCD_WIDTH
- width
;
358 dst
-= LCD_WIDTH
*width
+ 1;
361 while (--linecounter
> 0);
363 #if LCD_WIDTH >= LCD_HEIGHT
364 lcd_update_rect(x
, y
, width
, height
);
366 lcd_update_rect(LCD_WIDTH
- y
- height
, x
, height
, width
);
369 #endif /* HAVE_LCD_COLOR */