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);
49 return ((lcd_framebuffer
[y
/4][x
] >> (2 * (y
& 3))) & 3);
52 #if LCD_PIXELFORMAT == RGB565SWAPPED
53 unsigned bits
= lcd_framebuffer
[y
][x
];
54 return (bits
>> 8) | (bits
<< 8);
56 return lcd_framebuffer
[y
][x
];
63 /* update a full screen rect */
64 lcd_update_rect(0, 0, LCD_WIDTH
, LCD_HEIGHT
);
67 void lcd_update_rect(int x_start
, int y_start
, int width
, int height
)
69 sdl_update_rect(lcd_surface
, x_start
, y_start
, width
, height
, LCD_WIDTH
,
70 LCD_HEIGHT
, get_lcd_pixel
);
71 sdl_gui_update(lcd_surface
, x_start
, y_start
, width
, height
, LCD_WIDTH
,
72 LCD_HEIGHT
, background
? UI_LCD_POSX
: 0, background
? UI_LCD_POSY
: 0);
76 void sim_backlight(int value
)
78 lcd_backlight_val
= value
;
82 sdl_set_gradient(lcd_surface
, &lcd_backlight_color_zero
,
83 &lcd_backlight_color_max
, 0, (1<<LCD_DEPTH
));
85 sdl_set_gradient(lcd_surface
, &lcd_color_zero
, &lcd_color_max
,
91 sdl_set_gradient(lcd_surface
, &lcd_backlight_color_max
,
92 &lcd_backlight_color_zero
, (1<<LCD_DEPTH
),
95 sdl_set_gradient(lcd_surface
, &lcd_color_max
, &lcd_color_zero
,
96 (1<<LCD_DEPTH
), lcd_ex_shades
);
101 sdl_gui_update(lcd_surface
, 0, 0, LCD_WIDTH
, LCD_HEIGHT
, LCD_WIDTH
,
102 LCD_HEIGHT
, background
? UI_LCD_POSX
: 0, background
? UI_LCD_POSY
: 0);
108 /* initialise simulator lcd driver */
109 void sim_lcd_init(void)
112 lcd_surface
= SDL_CreateRGBSurface(SDL_SWSURFACE
, LCD_WIDTH
* display_zoom
,
113 LCD_HEIGHT
* display_zoom
, LCD_DEPTH
, 0, 0, 0, 0);
115 lcd_surface
= SDL_CreateRGBSurface(SDL_SWSURFACE
, LCD_WIDTH
* display_zoom
,
116 LCD_HEIGHT
* display_zoom
, 8, 0, 0, 0, 0);
120 #ifdef HAVE_BACKLIGHT
121 sdl_set_gradient(lcd_surface
, &lcd_backlight_color_zero
, &lcd_color_max
,
124 sdl_set_gradient(lcd_surface
, &lcd_color_zero
, &lcd_color_max
, 0,
131 void sim_lcd_ex_init(int shades
, unsigned long (*getpixel
)(int, int))
133 lcd_ex_shades
= shades
;
134 lcd_ex_getpixel
= getpixel
;
136 #ifdef HAVE_BACKLIGHT
137 if (lcd_backlight_val
> 0) {
138 sdl_set_gradient(lcd_surface
, &lcd_color_max
,
139 &lcd_backlight_color_zero
, (1<<LCD_DEPTH
),
145 sdl_set_gradient(lcd_surface
, &lcd_color_max
, &lcd_color_zero
,
146 (1<<LCD_DEPTH
), shades
);
151 void sim_lcd_ex_update_rect(int x_start
, int y_start
, int width
, int height
)
153 if (lcd_ex_getpixel
) {
154 sdl_update_rect(lcd_surface
, x_start
, y_start
, width
, height
,
155 LCD_WIDTH
, LCD_HEIGHT
, lcd_ex_getpixel
);
156 sdl_gui_update(lcd_surface
, x_start
, y_start
, width
, height
, LCD_WIDTH
,
157 LCD_HEIGHT
, background
? UI_LCD_POSX
: 0,
158 background
? UI_LCD_POSY
: 0);
163 #ifdef HAVE_LCD_COLOR
165 * |R| |1.000000 -0.000001 1.402000| |Y'|
166 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
167 * |B| |1.000000 1.772000 0.000000| |Pr|
168 * Scaled, normalized, rounded and tweaked to yield RGB 565:
169 * |R| |74 0 101| |Y' - 16| >> 9
170 * |G| = |74 -24 -51| |Cb - 128| >> 8
171 * |B| |74 128 0| |Cr - 128| >> 9
179 static inline int clamp(int val
, int min
, int max
)
188 void lcd_yuv_set_options(unsigned options
)
193 /* Draw a partial YUV colour bitmap - similiar behavior to lcd_yuv_blit
195 void lcd_yuv_blit(unsigned char * const src
[3],
196 int src_x
, int src_y
, int stride
,
197 int x
, int y
, int width
, int height
)
199 const unsigned char *ysrc
, *usrc
, *vsrc
;
201 fb_data
*dst
, *row_end
;
204 /* width and height must be >= 2 and an even number */
206 linecounter
= height
>> 1;
208 #if LCD_WIDTH >= LCD_HEIGHT
209 dst
= &lcd_framebuffer
[y
][x
];
210 row_end
= dst
+ width
;
212 dst
= &lcd_framebuffer
[x
][LCD_WIDTH
- y
- 1];
213 row_end
= dst
+ LCD_WIDTH
* width
;
217 ysrc
= src
[0] + z
+ src_x
;
218 usrc
= src
[1] + (z
>> 2) + (src_x
>> 1);
219 vsrc
= src
[2] + (usrc
- src
[1]);
221 /* stride => amount to jump from end of last row to start of next */
224 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
230 int y
, cb
, cr
, rv
, guv
, bu
, r
, g
, b
;
232 y
= YFAC
*(*ysrc
++ - 16);
237 guv
= GUFAC
*cb
+ GVFAC
*cr
;
244 if ((unsigned)(r
| g
| b
) > 64*256-1)
246 r
= clamp(r
, 0, 64*256-1);
247 g
= clamp(g
, 0, 64*256-1);
248 b
= clamp(b
, 0, 64*256-1);
251 *dst
= LCD_RGBPACK_LCD(r
>> 9, g
>> 8, b
>> 9);
253 #if LCD_WIDTH >= LCD_HEIGHT
259 y
= YFAC
*(*ysrc
++ - 16);
264 if ((unsigned)(r
| g
| b
) > 64*256-1)
266 r
= clamp(r
, 0, 64*256-1);
267 g
= clamp(g
, 0, 64*256-1);
268 b
= clamp(b
, 0, 64*256-1);
271 *dst
= LCD_RGBPACK_LCD(r
>> 9, g
>> 8, b
>> 9);
273 #if LCD_WIDTH >= LCD_HEIGHT
279 while (dst
< row_end
);
285 #if LCD_WIDTH >= LCD_HEIGHT
286 row_end
+= LCD_WIDTH
;
287 dst
+= LCD_WIDTH
- width
;
290 dst
-= LCD_WIDTH
*width
+ 1;
295 int y
, cb
, cr
, rv
, guv
, bu
, r
, g
, b
;
297 y
= YFAC
*(*ysrc
++ - 16);
302 guv
= GUFAC
*cb
+ GVFAC
*cr
;
309 if ((unsigned)(r
| g
| b
) > 64*256-1)
311 r
= clamp(r
, 0, 64*256-1);
312 g
= clamp(g
, 0, 64*256-1);
313 b
= clamp(b
, 0, 64*256-1);
316 *dst
= LCD_RGBPACK_LCD(r
>> 9, g
>> 8, b
>> 9);
318 #if LCD_WIDTH >= LCD_HEIGHT
324 y
= YFAC
*(*ysrc
++ - 16);
329 if ((unsigned)(r
| g
| b
) > 64*256-1)
331 r
= clamp(r
, 0, 64*256-1);
332 g
= clamp(g
, 0, 64*256-1);
333 b
= clamp(b
, 0, 64*256-1);
336 *dst
= LCD_RGBPACK_LCD(r
>> 9, g
>> 8, b
>> 9);
338 #if LCD_WIDTH >= LCD_HEIGHT
344 while (dst
< row_end
);
350 #if LCD_WIDTH >= LCD_HEIGHT
351 row_end
+= LCD_WIDTH
;
352 dst
+= LCD_WIDTH
- width
;
355 dst
-= LCD_WIDTH
*width
+ 1;
358 while (--linecounter
> 0);
360 #if LCD_WIDTH >= LCD_HEIGHT
361 lcd_update_rect(x
, y
, width
, height
);
363 lcd_update_rect(LCD_WIDTH
- y
- height
, x
, height
, width
);
366 #endif /* HAVE_LCD_COLOR */