1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2006 Dan Everton
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
26 SDL_Surface
* lcd_surface
;
27 int lcd_backlight_val
;
31 SDL_Color lcd_backlight_color_zero
= {UI_LCD_BGCOLORLIGHT
, 0};
32 SDL_Color lcd_backlight_color_max
= {UI_LCD_FGCOLORLIGHT
, 0};
34 SDL_Color lcd_color_zero
= {UI_LCD_BGCOLOR
, 0};
35 SDL_Color lcd_color_max
= {UI_LCD_FGCOLOR
, 0};
39 int lcd_ex_shades
= 0;
40 unsigned long (*lcd_ex_getpixel
)(int, int) = NULL
;
43 static unsigned long get_lcd_pixel(int x
, int y
)
46 return ((lcd_framebuffer
[y
/8][x
] >> (y
& 7)) & 1);
48 #if LCD_PIXELFORMAT == HORIZONTAL_PACKING
49 return ((lcd_framebuffer
[y
][x
/4] >> (2 * (~x
& 3))) & 3);
50 #elif LCD_PIXELFORMAT == VERTICAL_PACKING
51 return ((lcd_framebuffer
[y
/4][x
] >> (2 * (y
& 3))) & 3);
52 #elif LCD_PIXELFORMAT == VERTICAL_INTERLEAVED
53 unsigned bits
= (lcd_framebuffer
[y
/8][x
] >> (y
& 7)) & 0x0101;
54 return (bits
| (bits
>> 7)) & 3;
57 #if LCD_PIXELFORMAT == RGB565SWAPPED
58 unsigned bits
= lcd_framebuffer
[y
][x
];
59 return (bits
>> 8) | (bits
<< 8);
61 return lcd_framebuffer
[y
][x
];
68 /* update a full screen rect */
69 lcd_update_rect(0, 0, LCD_WIDTH
, LCD_HEIGHT
);
72 void lcd_update_rect(int x_start
, int y_start
, int width
, int height
)
74 sdl_update_rect(lcd_surface
, x_start
, y_start
, width
, height
, LCD_WIDTH
,
75 LCD_HEIGHT
, get_lcd_pixel
);
76 sdl_gui_update(lcd_surface
, x_start
, y_start
, width
, height
, LCD_WIDTH
,
77 LCD_HEIGHT
, background
? UI_LCD_POSX
: 0, background
? UI_LCD_POSY
: 0);
81 void sim_backlight(int value
)
83 lcd_backlight_val
= value
;
87 sdl_set_gradient(lcd_surface
, &lcd_backlight_color_zero
,
88 &lcd_backlight_color_max
, 0, (1<<LCD_DEPTH
));
90 sdl_set_gradient(lcd_surface
, &lcd_color_zero
, &lcd_color_max
,
96 sdl_set_gradient(lcd_surface
, &lcd_backlight_color_max
,
97 &lcd_backlight_color_zero
, (1<<LCD_DEPTH
),
100 sdl_set_gradient(lcd_surface
, &lcd_color_max
, &lcd_color_zero
,
101 (1<<LCD_DEPTH
), lcd_ex_shades
);
106 sdl_gui_update(lcd_surface
, 0, 0, LCD_WIDTH
, LCD_HEIGHT
, LCD_WIDTH
,
107 LCD_HEIGHT
, background
? UI_LCD_POSX
: 0, background
? UI_LCD_POSY
: 0);
113 /* initialise simulator lcd driver */
114 void sim_lcd_init(void)
117 lcd_surface
= SDL_CreateRGBSurface(SDL_SWSURFACE
, LCD_WIDTH
* display_zoom
,
118 LCD_HEIGHT
* display_zoom
, LCD_DEPTH
, 0, 0, 0, 0);
120 lcd_surface
= SDL_CreateRGBSurface(SDL_SWSURFACE
, LCD_WIDTH
* display_zoom
,
121 LCD_HEIGHT
* display_zoom
, 8, 0, 0, 0, 0);
125 #ifdef HAVE_BACKLIGHT
126 sdl_set_gradient(lcd_surface
, &lcd_backlight_color_zero
, &lcd_color_max
,
129 sdl_set_gradient(lcd_surface
, &lcd_color_zero
, &lcd_color_max
, 0,
136 void sim_lcd_ex_init(int shades
, unsigned long (*getpixel
)(int, int))
138 lcd_ex_shades
= shades
;
139 lcd_ex_getpixel
= getpixel
;
141 #ifdef HAVE_BACKLIGHT
142 if (lcd_backlight_val
> 0) {
143 sdl_set_gradient(lcd_surface
, &lcd_color_max
,
144 &lcd_backlight_color_zero
, (1<<LCD_DEPTH
),
150 sdl_set_gradient(lcd_surface
, &lcd_color_max
, &lcd_color_zero
,
151 (1<<LCD_DEPTH
), shades
);
156 void sim_lcd_ex_update_rect(int x_start
, int y_start
, int width
, int height
)
158 if (lcd_ex_getpixel
) {
159 sdl_update_rect(lcd_surface
, x_start
, y_start
, width
, height
,
160 LCD_WIDTH
, LCD_HEIGHT
, lcd_ex_getpixel
);
161 sdl_gui_update(lcd_surface
, x_start
, y_start
, width
, height
, LCD_WIDTH
,
162 LCD_HEIGHT
, background
? UI_LCD_POSX
: 0,
163 background
? UI_LCD_POSY
: 0);
168 #ifdef HAVE_LCD_COLOR
170 * |R| |1.000000 -0.000001 1.402000| |Y'|
171 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
172 * |B| |1.000000 1.772000 0.000000| |Pr|
173 * Scaled, normalized, rounded and tweaked to yield RGB 565:
174 * |R| |74 0 101| |Y' - 16| >> 9
175 * |G| = |74 -24 -51| |Cb - 128| >> 8
176 * |B| |74 128 0| |Cr - 128| >> 9
184 static inline int clamp(int val
, int min
, int max
)
193 void lcd_yuv_set_options(unsigned options
)
198 /* Draw a partial YUV colour bitmap - similiar behavior to lcd_blit_yuv
200 void lcd_blit_yuv(unsigned char * const src
[3],
201 int src_x
, int src_y
, int stride
,
202 int x
, int y
, int width
, int height
)
204 const unsigned char *ysrc
, *usrc
, *vsrc
;
206 fb_data
*dst
, *row_end
;
209 /* width and height must be >= 2 and an even number */
211 linecounter
= height
>> 1;
213 #if LCD_WIDTH >= LCD_HEIGHT
214 dst
= &lcd_framebuffer
[y
][x
];
215 row_end
= dst
+ width
;
217 dst
= &lcd_framebuffer
[x
][LCD_WIDTH
- y
- 1];
218 row_end
= dst
+ LCD_WIDTH
* width
;
222 ysrc
= src
[0] + z
+ src_x
;
223 usrc
= src
[1] + (z
>> 2) + (src_x
>> 1);
224 vsrc
= src
[2] + (usrc
- src
[1]);
226 /* stride => amount to jump from end of last row to start of next */
229 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
235 int y
, cb
, cr
, rv
, guv
, bu
, r
, g
, b
;
237 y
= YFAC
*(*ysrc
++ - 16);
242 guv
= GUFAC
*cb
+ GVFAC
*cr
;
249 if ((unsigned)(r
| g
| b
) > 64*256-1)
251 r
= clamp(r
, 0, 64*256-1);
252 g
= clamp(g
, 0, 64*256-1);
253 b
= clamp(b
, 0, 64*256-1);
256 *dst
= LCD_RGBPACK_LCD(r
>> 9, g
>> 8, b
>> 9);
258 #if LCD_WIDTH >= LCD_HEIGHT
264 y
= YFAC
*(*ysrc
++ - 16);
269 if ((unsigned)(r
| g
| b
) > 64*256-1)
271 r
= clamp(r
, 0, 64*256-1);
272 g
= clamp(g
, 0, 64*256-1);
273 b
= clamp(b
, 0, 64*256-1);
276 *dst
= LCD_RGBPACK_LCD(r
>> 9, g
>> 8, b
>> 9);
278 #if LCD_WIDTH >= LCD_HEIGHT
284 while (dst
< row_end
);
290 #if LCD_WIDTH >= LCD_HEIGHT
291 row_end
+= LCD_WIDTH
;
292 dst
+= LCD_WIDTH
- width
;
295 dst
-= LCD_WIDTH
*width
+ 1;
300 int y
, cb
, cr
, rv
, guv
, bu
, r
, g
, b
;
302 y
= YFAC
*(*ysrc
++ - 16);
307 guv
= GUFAC
*cb
+ GVFAC
*cr
;
314 if ((unsigned)(r
| g
| b
) > 64*256-1)
316 r
= clamp(r
, 0, 64*256-1);
317 g
= clamp(g
, 0, 64*256-1);
318 b
= clamp(b
, 0, 64*256-1);
321 *dst
= LCD_RGBPACK_LCD(r
>> 9, g
>> 8, b
>> 9);
323 #if LCD_WIDTH >= LCD_HEIGHT
329 y
= YFAC
*(*ysrc
++ - 16);
334 if ((unsigned)(r
| g
| b
) > 64*256-1)
336 r
= clamp(r
, 0, 64*256-1);
337 g
= clamp(g
, 0, 64*256-1);
338 b
= clamp(b
, 0, 64*256-1);
341 *dst
= LCD_RGBPACK_LCD(r
>> 9, g
>> 8, b
>> 9);
343 #if LCD_WIDTH >= LCD_HEIGHT
349 while (dst
< row_end
);
355 #if LCD_WIDTH >= LCD_HEIGHT
356 row_end
+= LCD_WIDTH
;
357 dst
+= LCD_WIDTH
- width
;
360 dst
-= LCD_WIDTH
*width
+ 1;
363 while (--linecounter
> 0);
365 #if LCD_WIDTH >= LCD_HEIGHT
366 lcd_update_rect(x
, y
, width
, height
);
368 lcd_update_rect(LCD_WIDTH
- y
- height
, x
, height
, width
);
371 #endif /* HAVE_LCD_COLOR */