summaryrefslogtreecommitdiff
path: root/uisimulator/sdl/lcd-bitmap.c
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2010-05-15 21:02:47 +0000
committerThomas Martitz <kugel@rockbox.org>2010-05-15 21:02:47 +0000
commit3d0cee8abbaf764958743e8a7851eee94e60a913 (patch)
treea96b1ec825003a71643a7da4707c300f64824f82 /uisimulator/sdl/lcd-bitmap.c
parentdcf442e61f21fb2aef5ce7de0547f733557b156e (diff)
downloadrockbox-3d0cee8abbaf764958743e8a7851eee94e60a913.tar.gz
rockbox-3d0cee8abbaf764958743e8a7851eee94e60a913.zip
- Move uisimulator/sdl/*.[ch] into the target tree, under firmware/target/hosted/sdl, uisdl.c is split up across button-sdl.c and system-sdl.c.
- Refactor the program startup. main() is now in main.c like on target, and the implicit application thread will now act as our main thread (previously a separate one was created for this in thread initialization). This is part of Rockbox as an application and is the first step to make an application port from the uisimulator. In a further step the sim bits from the sdl build will be separated out. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26065 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'uisimulator/sdl/lcd-bitmap.c')
-rw-r--r--uisimulator/sdl/lcd-bitmap.c415
1 files changed, 0 insertions, 415 deletions
diff --git a/uisimulator/sdl/lcd-bitmap.c b/uisimulator/sdl/lcd-bitmap.c
deleted file mode 100644
index 0bd90196e4..0000000000
--- a/uisimulator/sdl/lcd-bitmap.c
+++ /dev/null
@@ -1,415 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 Dan Everton
11 *
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.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "debug.h"
23#include "uisdl.h"
24#include "lcd-sdl.h"
25#include "screendump.h"
26
27SDL_Surface* lcd_surface;
28
29#if LCD_DEPTH <= 8
30#ifdef HAVE_BACKLIGHT
31SDL_Color lcd_bl_color_dark = {RED_CMP(LCD_BL_DARKCOLOR),
32 GREEN_CMP(LCD_BL_DARKCOLOR),
33 BLUE_CMP(LCD_BL_DARKCOLOR), 0};
34SDL_Color lcd_bl_color_bright = {RED_CMP(LCD_BL_BRIGHTCOLOR),
35 GREEN_CMP(LCD_BL_BRIGHTCOLOR),
36 BLUE_CMP(LCD_BL_BRIGHTCOLOR), 0};
37#ifdef HAVE_LCD_SPLIT
38SDL_Color lcd_bl_color2_dark = {RED_CMP(LCD_BL_DARKCOLOR_2),
39 GREEN_CMP(LCD_BL_DARKCOLOR_2),
40 BLUE_CMP(LCD_BL_DARKCOLOR_2), 0};
41SDL_Color lcd_bl_color2_bright = {RED_CMP(LCD_BL_BRIGHTCOLOR_2),
42 GREEN_CMP(LCD_BL_BRIGHTCOLOR_2),
43 BLUE_CMP(LCD_BL_BRIGHTCOLOR_2), 0};
44#endif
45#endif /* HAVE_BACKLIGHT */
46SDL_Color lcd_color_dark = {RED_CMP(LCD_DARKCOLOR),
47 GREEN_CMP(LCD_DARKCOLOR),
48 BLUE_CMP(LCD_DARKCOLOR), 0};
49SDL_Color lcd_color_bright = {RED_CMP(LCD_BRIGHTCOLOR),
50 GREEN_CMP(LCD_BRIGHTCOLOR),
51 BLUE_CMP(LCD_BRIGHTCOLOR), 0};
52#ifdef HAVE_LCD_SPLIT
53SDL_Color lcd_color2_dark = {RED_CMP(LCD_DARKCOLOR_2),
54 GREEN_CMP(LCD_DARKCOLOR_2),
55 BLUE_CMP(LCD_DARKCOLOR_2), 0};
56SDL_Color lcd_color2_bright = {RED_CMP(LCD_BRIGHTCOLOR_2),
57 GREEN_CMP(LCD_BRIGHTCOLOR_2),
58 BLUE_CMP(LCD_BRIGHTCOLOR_2), 0};
59#endif
60
61#ifdef HAVE_LCD_SPLIT
62#define NUM_SHADES 128
63#else
64#define NUM_SHADES 129
65#endif
66
67#else /* LCD_DEPTH > 8 */
68
69#ifdef HAVE_TRANSFLECTIVE_LCD
70#define BACKLIGHT_OFF_ALPHA 85 /* 1/3 brightness */
71#else
72#define BACKLIGHT_OFF_ALPHA 0 /* pitch black */
73#endif
74
75#endif /* LCD_DEPTH */
76
77#if LCD_DEPTH < 8
78unsigned long (*lcd_ex_getpixel)(int, int) = NULL;
79#endif /* LCD_DEPTH < 8 */
80
81#if LCD_DEPTH == 2
82/* Only defined for positive, non-split LCD for now */
83static const unsigned char colorindex[4] = {128, 85, 43, 0};
84#endif
85
86static unsigned long get_lcd_pixel(int x, int y)
87{
88#if LCD_DEPTH == 1
89#ifdef HAVE_NEGATIVE_LCD
90 return (lcd_framebuffer[y/8][x] & (1 << (y & 7))) ? (NUM_SHADES-1) : 0;
91#else
92 return (lcd_framebuffer[y/8][x] & (1 << (y & 7))) ? 0 : (NUM_SHADES-1);
93#endif
94#elif LCD_DEPTH == 2
95#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
96 return colorindex[(lcd_framebuffer[y][x/4] >> (2 * (~x & 3))) & 3];
97#elif LCD_PIXELFORMAT == VERTICAL_PACKING
98 return colorindex[(lcd_framebuffer[y/4][x] >> (2 * (y & 3))) & 3];
99#elif LCD_PIXELFORMAT == VERTICAL_INTERLEAVED
100 unsigned bits = (lcd_framebuffer[y/8][x] >> (y & 7)) & 0x0101;
101 return colorindex[(bits | (bits >> 7)) & 3];
102#endif
103#elif LCD_DEPTH == 16
104#if LCD_PIXELFORMAT == RGB565SWAPPED
105 unsigned bits = lcd_framebuffer[y][x];
106 return (bits >> 8) | (bits << 8);
107#else
108#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
109 return *(&lcd_framebuffer[0][0]+LCD_HEIGHT*x+y);
110#else
111 return lcd_framebuffer[y][x];
112#endif
113#endif
114#endif
115}
116
117void lcd_update(void)
118{
119 /* update a full screen rect */
120 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
121}
122
123void lcd_update_rect(int x_start, int y_start, int width, int height)
124{
125 sdl_update_rect(lcd_surface, x_start, y_start, width, height,
126 LCD_WIDTH, LCD_HEIGHT, get_lcd_pixel);
127 sdl_gui_update(lcd_surface, x_start, y_start, width,
128 height + LCD_SPLIT_LINES, SIM_LCD_WIDTH, SIM_LCD_HEIGHT,
129 background ? UI_LCD_POSX : 0, background? UI_LCD_POSY : 0);
130}
131
132#ifdef HAVE_BACKLIGHT
133void sim_backlight(int value)
134{
135#if LCD_DEPTH <= 8
136 if (value > 0) {
137 sdl_set_gradient(lcd_surface, &lcd_bl_color_dark,
138 &lcd_bl_color_bright, 0, NUM_SHADES);
139#ifdef HAVE_LCD_SPLIT
140 sdl_set_gradient(lcd_surface, &lcd_bl_color2_dark,
141 &lcd_bl_color2_bright, NUM_SHADES, NUM_SHADES);
142#endif
143 } else {
144 sdl_set_gradient(lcd_surface, &lcd_color_dark,
145 &lcd_color_bright, 0, NUM_SHADES);
146#ifdef HAVE_LCD_SPLIT
147 sdl_set_gradient(lcd_surface, &lcd_color2_dark,
148 &lcd_color2_bright, NUM_SHADES, NUM_SHADES);
149#endif
150 }
151#else /* LCD_DEPTH > 8 */
152 SDL_SetAlpha(lcd_surface, SDL_SRCALPHA, (value * 255) / 100);
153#endif /* LCD_DEPTH */
154
155 sdl_gui_update(lcd_surface, 0, 0, SIM_LCD_WIDTH, SIM_LCD_HEIGHT,
156 SIM_LCD_WIDTH, SIM_LCD_HEIGHT,
157 background ? UI_LCD_POSX : 0, background? UI_LCD_POSY : 0);
158}
159#endif /* HAVE_BACKLIGHT */
160
161/* initialise simulator lcd driver */
162void sim_lcd_init(void)
163{
164#if LCD_DEPTH == 16
165 lcd_surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
166 SIM_LCD_WIDTH * display_zoom,
167 SIM_LCD_HEIGHT * display_zoom,
168 LCD_DEPTH, 0, 0, 0, 0);
169#elif LCD_DEPTH <= 8
170 lcd_surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
171 SIM_LCD_WIDTH * display_zoom,
172 SIM_LCD_HEIGHT * display_zoom,
173 8, 0, 0, 0, 0);
174
175#ifdef HAVE_BACKLIGHT
176 sdl_set_gradient(lcd_surface, &lcd_bl_color_dark,
177 &lcd_bl_color_bright, 0, NUM_SHADES);
178#ifdef HAVE_LCD_SPLIT
179 sdl_set_gradient(lcd_surface, &lcd_bl_color2_dark,
180 &lcd_bl_color2_bright, NUM_SHADES, NUM_SHADES);
181#endif
182#else /* !HAVE_BACKLIGHT */
183 sdl_set_gradient(lcd_surface, &lcd_color_dark,
184 &lcd_color_bright, 0, NUM_SHADES);
185#ifdef HAVE_LCD_SPLIT
186 sdl_set_gradient(lcd_surface, &lcd_color2_dark,
187 &lcd_color2_bright, NUM_SHADES, NUM_SHADES);
188#endif
189#endif /* !HAVE_BACKLIGHT */
190#endif /* LCD_DEPTH */
191}
192
193#if LCD_DEPTH < 8
194void sim_lcd_ex_init(unsigned long (*getpixel)(int, int))
195{
196 lcd_ex_getpixel = getpixel;
197}
198
199void sim_lcd_ex_update_rect(int x_start, int y_start, int width, int height)
200{
201 if (lcd_ex_getpixel) {
202 sdl_update_rect(lcd_surface, x_start, y_start, width, height,
203 LCD_WIDTH, LCD_HEIGHT, lcd_ex_getpixel);
204 sdl_gui_update(lcd_surface, x_start, y_start, width,
205 height + LCD_SPLIT_LINES, SIM_LCD_WIDTH, SIM_LCD_HEIGHT,
206 background ? UI_LCD_POSX : 0,
207 background ? UI_LCD_POSY : 0);
208 }
209}
210#endif
211
212#ifdef HAVE_LCD_COLOR
213/**
214 * |R| |1.000000 -0.000001 1.402000| |Y'|
215 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
216 * |B| |1.000000 1.772000 0.000000| |Pr|
217 * Scaled, normalized, rounded and tweaked to yield RGB 565:
218 * |R| |74 0 101| |Y' - 16| >> 9
219 * |G| = |74 -24 -51| |Cb - 128| >> 8
220 * |B| |74 128 0| |Cr - 128| >> 9
221 */
222#define YFAC (74)
223#define RVFAC (101)
224#define GUFAC (-24)
225#define GVFAC (-51)
226#define BUFAC (128)
227
228static inline int clamp(int val, int min, int max)
229{
230 if (val < min)
231 val = min;
232 else if (val > max)
233 val = max;
234 return val;
235}
236
237void lcd_yuv_set_options(unsigned options)
238{
239 (void)options;
240}
241
242/* Draw a partial YUV colour bitmap - similiar behavior to lcd_blit_yuv
243 in the core */
244void lcd_blit_yuv(unsigned char * const src[3],
245 int src_x, int src_y, int stride,
246 int x, int y, int width, int height)
247{
248 const unsigned char *ysrc, *usrc, *vsrc;
249 int linecounter;
250 fb_data *dst, *row_end;
251 long z;
252
253 /* width and height must be >= 2 and an even number */
254 width &= ~1;
255 linecounter = height >> 1;
256
257#if LCD_WIDTH >= LCD_HEIGHT
258 dst = &lcd_framebuffer[y][x];
259 row_end = dst + width;
260#else
261 dst = &lcd_framebuffer[x][LCD_WIDTH - y - 1];
262 row_end = dst + LCD_WIDTH * width;
263#endif
264
265 z = stride * src_y;
266 ysrc = src[0] + z + src_x;
267 usrc = src[1] + (z >> 2) + (src_x >> 1);
268 vsrc = src[2] + (usrc - src[1]);
269
270 /* stride => amount to jump from end of last row to start of next */
271 stride -= width;
272
273 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
274
275 do
276 {
277 do
278 {
279 int y, cb, cr, rv, guv, bu, r, g, b;
280
281 y = YFAC*(*ysrc++ - 16);
282 cb = *usrc++ - 128;
283 cr = *vsrc++ - 128;
284
285 rv = RVFAC*cr;
286 guv = GUFAC*cb + GVFAC*cr;
287 bu = BUFAC*cb;
288
289 r = y + rv;
290 g = y + guv;
291 b = y + bu;
292
293 if ((unsigned)(r | g | b) > 64*256-1)
294 {
295 r = clamp(r, 0, 64*256-1);
296 g = clamp(g, 0, 64*256-1);
297 b = clamp(b, 0, 64*256-1);
298 }
299
300 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
301
302#if LCD_WIDTH >= LCD_HEIGHT
303 dst++;
304#else
305 dst += LCD_WIDTH;
306#endif
307
308 y = YFAC*(*ysrc++ - 16);
309 r = y + rv;
310 g = y + guv;
311 b = y + bu;
312
313 if ((unsigned)(r | g | b) > 64*256-1)
314 {
315 r = clamp(r, 0, 64*256-1);
316 g = clamp(g, 0, 64*256-1);
317 b = clamp(b, 0, 64*256-1);
318 }
319
320 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
321
322#if LCD_WIDTH >= LCD_HEIGHT
323 dst++;
324#else
325 dst += LCD_WIDTH;
326#endif
327 }
328 while (dst < row_end);
329
330 ysrc += stride;
331 usrc -= width >> 1;
332 vsrc -= width >> 1;
333
334#if LCD_WIDTH >= LCD_HEIGHT
335 row_end += LCD_WIDTH;
336 dst += LCD_WIDTH - width;
337#else
338 row_end -= 1;
339 dst -= LCD_WIDTH*width + 1;
340#endif
341
342 do
343 {
344 int y, cb, cr, rv, guv, bu, r, g, b;
345
346 y = YFAC*(*ysrc++ - 16);
347 cb = *usrc++ - 128;
348 cr = *vsrc++ - 128;
349
350 rv = RVFAC*cr;
351 guv = GUFAC*cb + GVFAC*cr;
352 bu = BUFAC*cb;
353
354 r = y + rv;
355 g = y + guv;
356 b = y + bu;
357
358 if ((unsigned)(r | g | b) > 64*256-1)
359 {
360 r = clamp(r, 0, 64*256-1);
361 g = clamp(g, 0, 64*256-1);
362 b = clamp(b, 0, 64*256-1);
363 }
364
365 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
366
367#if LCD_WIDTH >= LCD_HEIGHT
368 dst++;
369#else
370 dst += LCD_WIDTH;
371#endif
372
373 y = YFAC*(*ysrc++ - 16);
374 r = y + rv;
375 g = y + guv;
376 b = y + bu;
377
378 if ((unsigned)(r | g | b) > 64*256-1)
379 {
380 r = clamp(r, 0, 64*256-1);
381 g = clamp(g, 0, 64*256-1);
382 b = clamp(b, 0, 64*256-1);
383 }
384
385 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
386
387#if LCD_WIDTH >= LCD_HEIGHT
388 dst++;
389#else
390 dst += LCD_WIDTH;
391#endif
392 }
393 while (dst < row_end);
394
395 ysrc += stride;
396 usrc += stride >> 1;
397 vsrc += stride >> 1;
398
399#if LCD_WIDTH >= LCD_HEIGHT
400 row_end += LCD_WIDTH;
401 dst += LCD_WIDTH - width;
402#else
403 row_end -= 1;
404 dst -= LCD_WIDTH*width + 1;
405#endif
406 }
407 while (--linecounter > 0);
408
409#if LCD_WIDTH >= LCD_HEIGHT
410 lcd_update_rect(x, y, width, height);
411#else
412 lcd_update_rect(LCD_WIDTH - y - height, x, height, width);
413#endif
414}
415#endif /* HAVE_LCD_COLOR */