diff options
Diffstat (limited to 'uisimulator/sdl/lcd-sdl.c')
-rw-r--r-- | uisimulator/sdl/lcd-sdl.c | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/uisimulator/sdl/lcd-sdl.c b/uisimulator/sdl/lcd-sdl.c new file mode 100644 index 0000000000..758ab90ef9 --- /dev/null +++ b/uisimulator/sdl/lcd-sdl.c | |||
@@ -0,0 +1,291 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 Dan Everton | ||
11 | * | ||
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. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include "uisdl.h" | ||
21 | #include "lcd.h" | ||
22 | #include "lcd-playersim.h" | ||
23 | |||
24 | SDL_Surface* lcd_surface; | ||
25 | |||
26 | #if LCD_DEPTH == 16 | ||
27 | #else | ||
28 | SDL_Color lcd_palette[(1<<LCD_DEPTH)]; | ||
29 | SDL_Color lcd_color_zero = {UI_LCD_BGCOLORLIGHT, 0}; | ||
30 | SDL_Color lcd_color_max = {0, 0, 0, 0}; | ||
31 | |||
32 | #endif | ||
33 | |||
34 | #ifdef HAVE_LCD_BITMAP | ||
35 | |||
36 | #ifdef HAVE_REMOTE_LCD | ||
37 | SDL_Surface *remote_surface; | ||
38 | SDL_Color remote_palette[(1<<LCD_REMOTE_DEPTH)]; | ||
39 | SDL_Color remote_color_zero = {UI_REMOTE_BGCOLORLIGHT, 0}; | ||
40 | SDL_Color remote_color_max = {0, 0, 0, 0}; | ||
41 | |||
42 | #endif | ||
43 | |||
44 | void lcd_update (void) | ||
45 | { | ||
46 | /* update a full screen rect */ | ||
47 | lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); | ||
48 | } | ||
49 | |||
50 | void lcd_update_rect(int x_start, int y_start, int width, int height) | ||
51 | { | ||
52 | int x, y; | ||
53 | int xmax, ymax; | ||
54 | |||
55 | ymax = y_start + height; | ||
56 | xmax = x_start + width; | ||
57 | |||
58 | if(xmax > LCD_WIDTH) | ||
59 | xmax = LCD_WIDTH; | ||
60 | if(ymax >= LCD_HEIGHT) | ||
61 | ymax = LCD_HEIGHT; | ||
62 | |||
63 | SDL_LockSurface(lcd_surface); | ||
64 | |||
65 | int bpp = lcd_surface->format->BytesPerPixel; | ||
66 | |||
67 | for (x = x_start; x < xmax; x++) | ||
68 | { | ||
69 | for (y = y_start; y < ymax; y++) | ||
70 | { | ||
71 | Uint8 *p = (Uint8 *)lcd_surface->pixels + y * lcd_surface->pitch + x * bpp; | ||
72 | |||
73 | #if LCD_DEPTH == 1 | ||
74 | *(Uint32 *)p = ((lcd_framebuffer[y/8][x] >> (y & 7)) & 1); | ||
75 | #elif LCD_DEPTH == 2 | ||
76 | *(Uint32 *)p = ((lcd_framebuffer[y/4][x] >> (2 * (y & 3))) & 3); | ||
77 | #elif LCD_DEPTH == 16 | ||
78 | #if LCD_PIXELFORMAT == RGB565SWAPPED | ||
79 | unsigned bits = lcd_framebuffer[y][x]; | ||
80 | *(Uint32 *)p = (bits >> 8) | (bits << 8); | ||
81 | #else | ||
82 | *(Uint32 *)p = lcd_framebuffer[y][x]; | ||
83 | #endif | ||
84 | #endif | ||
85 | } | ||
86 | } | ||
87 | |||
88 | SDL_UnlockSurface(lcd_surface); | ||
89 | |||
90 | SDL_Rect src = {x_start, y_start, xmax, ymax}; | ||
91 | SDL_Rect dest = {UI_LCD_POSX + x_start, UI_LCD_POSY + y_start, xmax, ymax}; | ||
92 | |||
93 | |||
94 | SDL_BlitSurface(lcd_surface, &src, gui_surface, &dest); | ||
95 | SDL_UpdateRect(gui_surface, dest.x, dest.y, dest.w, dest.h); | ||
96 | SDL_Flip(gui_surface); | ||
97 | |||
98 | } | ||
99 | |||
100 | #ifdef HAVE_REMOTE_LCD | ||
101 | |||
102 | extern unsigned char lcd_remote_framebuffer[LCD_REMOTE_HEIGHT/8][LCD_REMOTE_WIDTH]; | ||
103 | |||
104 | void lcd_remote_update (void) | ||
105 | { | ||
106 | lcd_remote_update_rect(0, 0, LCD_REMOTE_WIDTH, LCD_REMOTE_HEIGHT); | ||
107 | } | ||
108 | |||
109 | void lcd_remote_update_rect(int x_start, int y_start, | ||
110 | int width, int height) | ||
111 | { | ||
112 | int x, y; | ||
113 | int xmax, ymax; | ||
114 | |||
115 | ymax = y_start + height; | ||
116 | xmax = x_start + width; | ||
117 | |||
118 | if(xmax > LCD_REMOTE_WIDTH) | ||
119 | xmax = LCD_REMOTE_WIDTH; | ||
120 | if(ymax >= LCD_REMOTE_HEIGHT) | ||
121 | ymax = LCD_REMOTE_HEIGHT; | ||
122 | |||
123 | SDL_LockSurface(remote_surface); | ||
124 | |||
125 | int bpp = remote_surface->format->BytesPerPixel; | ||
126 | |||
127 | for (x = x_start; x < xmax; x++) | ||
128 | for (y = y_start; y < ymax; y++) | ||
129 | { | ||
130 | Uint8 *p = (Uint8 *)remote_surface->pixels + y * remote_surface->pitch + x * bpp; | ||
131 | |||
132 | *(Uint32 *)p = ((lcd_remote_framebuffer[y/8][x] >> (y & 7)) & 1); | ||
133 | } | ||
134 | |||
135 | SDL_UnlockSurface(remote_surface); | ||
136 | |||
137 | SDL_Rect src = {x_start, y_start, xmax, ymax}; | ||
138 | SDL_Rect dest = {UI_REMOTE_POSX + x_start, UI_REMOTE_POSY + y_start, xmax, ymax}; | ||
139 | |||
140 | SDL_BlitSurface(remote_surface, &src, gui_surface, &dest); | ||
141 | SDL_UpdateRect(gui_surface, dest.x, dest.y, dest.w, dest.h); | ||
142 | SDL_Flip(gui_surface); | ||
143 | |||
144 | } | ||
145 | |||
146 | #endif /* HAVE_REMOTE_LCD */ | ||
147 | #endif /* HAVE_LCD_BITMAP */ | ||
148 | |||
149 | #ifdef HAVE_LCD_CHARCELLS | ||
150 | /* Defined in lcd-playersim.c */ | ||
151 | extern void lcd_print_char(int x, int y); | ||
152 | extern bool lcd_display_redraw; | ||
153 | extern unsigned char hardware_buffer_lcd[11][2]; | ||
154 | static unsigned char lcd_buffer_copy[11][2]; | ||
155 | |||
156 | void lcd_update(void) | ||
157 | { | ||
158 | int x, y; | ||
159 | bool changed = false; | ||
160 | SDL_Rect dest = {UI_LCD_POSX, UI_LCD_POSY, UI_LCD_WIDTH, UI_LCD_HEIGHT}; | ||
161 | |||
162 | for (y = 0; y < 2; y++) | ||
163 | { | ||
164 | for (x = 0; x < 11; x++) | ||
165 | { | ||
166 | if (lcd_display_redraw || | ||
167 | lcd_buffer_copy[x][y] != hardware_buffer_lcd[x][y]) | ||
168 | { | ||
169 | lcd_buffer_copy[x][y] = hardware_buffer_lcd[x][y]; | ||
170 | lcd_print_char(x, y); | ||
171 | changed = true; | ||
172 | } | ||
173 | } | ||
174 | } | ||
175 | if (changed) | ||
176 | { | ||
177 | SDL_BlitSurface(lcd_surface, NULL, gui_surface, &dest); | ||
178 | SDL_UpdateRect(gui_surface, dest.x, dest.y, dest.w, dest.h); | ||
179 | SDL_Flip(gui_surface); | ||
180 | } | ||
181 | lcd_display_redraw = false; | ||
182 | } | ||
183 | |||
184 | void drawdots(int color, struct coordinate *points, int count) | ||
185 | { | ||
186 | int bpp = lcd_surface->format->BytesPerPixel; | ||
187 | |||
188 | SDL_LockSurface(lcd_surface); | ||
189 | |||
190 | while (count--) | ||
191 | { | ||
192 | Uint8 *p = (Uint8 *)lcd_surface->pixels + (points[count].y) * lcd_surface->pitch + (points[count].x) * bpp; | ||
193 | |||
194 | *p = color; | ||
195 | } | ||
196 | |||
197 | SDL_UnlockSurface(lcd_surface); | ||
198 | } | ||
199 | |||
200 | void drawrectangles(int color, struct rectangle *points, int count) | ||
201 | { | ||
202 | int bpp = lcd_surface->format->BytesPerPixel; | ||
203 | |||
204 | SDL_LockSurface(lcd_surface); | ||
205 | |||
206 | while (count--) | ||
207 | { | ||
208 | int x; | ||
209 | int y; | ||
210 | int ix; | ||
211 | int iy; | ||
212 | |||
213 | for (x = points[count].x, ix = 0; ix < points[count].width; x++, ix++) | ||
214 | { | ||
215 | for (y = points[count].y, iy = 0; iy < points[count].height; y++, iy++) | ||
216 | { | ||
217 | Uint8 *p = (Uint8 *)lcd_surface->pixels + y * lcd_surface->pitch + x * bpp; | ||
218 | |||
219 | *p = color; | ||
220 | } | ||
221 | } | ||
222 | } | ||
223 | |||
224 | SDL_UnlockSurface(lcd_surface); | ||
225 | } | ||
226 | #endif /* HAVE_LCD_CHARCELLS */ | ||
227 | |||
228 | #if LCD_DEPTH <= 8 | ||
229 | /* set a range of bitmap indices to a gradient from startcolour to endcolour */ | ||
230 | void lcdcolors(int index, int count, SDL_Color *start, SDL_Color *end) | ||
231 | { | ||
232 | int i; | ||
233 | |||
234 | count--; | ||
235 | for (i = 0; i <= count; i++) | ||
236 | { | ||
237 | lcd_palette[i+index].r = start->r | ||
238 | + (end->r - start->r) * i / count; | ||
239 | lcd_palette[i+index].g = start->g | ||
240 | + (end->g - start->g) * i / count; | ||
241 | lcd_palette[i+index].b = start->b | ||
242 | + (end->b - start->b) * i / count; | ||
243 | } | ||
244 | |||
245 | SDL_SetPalette(lcd_surface, SDL_LOGPAL|SDL_PHYSPAL, lcd_palette, index, count); | ||
246 | } | ||
247 | #endif | ||
248 | |||
249 | #ifdef HAVE_REMOTE_LCD | ||
250 | /* set a range of bitmap indices to a gradient from startcolour to endcolour */ | ||
251 | void lcdremotecolors(int index, int count, SDL_Color *start, SDL_Color *end) | ||
252 | { | ||
253 | int i; | ||
254 | |||
255 | count--; | ||
256 | for (i = 0; i <= count; i++) | ||
257 | { | ||
258 | remote_palette[i+index].r = start->r | ||
259 | + (end->r - start->r) * i / count; | ||
260 | remote_palette[i+index].g = start->g | ||
261 | + (end->g - start->g) * i / count; | ||
262 | remote_palette[i+index].b = start->b | ||
263 | + (end->b - start->b) * i / count; | ||
264 | } | ||
265 | |||
266 | SDL_SetPalette(remote_surface, SDL_LOGPAL|SDL_PHYSPAL, remote_palette, index, count); | ||
267 | } | ||
268 | #endif | ||
269 | |||
270 | /* initialise simulator lcd driver */ | ||
271 | void simlcdinit(void) | ||
272 | { | ||
273 | #if LCD_DEPTH == 16 | ||
274 | lcd_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, LCD_WIDTH, LCD_HEIGHT, 16, | ||
275 | 0, 0, 0, 0); | ||
276 | #else | ||
277 | lcd_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, LCD_WIDTH, LCD_HEIGHT, 8, | ||
278 | 0, 0, 0, 0); | ||
279 | #endif | ||
280 | |||
281 | #if LCD_DEPTH <= 8 | ||
282 | lcdcolors(0, (1<<LCD_DEPTH), &lcd_color_zero, &lcd_color_max); | ||
283 | #endif | ||
284 | |||
285 | #ifdef HAVE_REMOTE_LCD | ||
286 | remote_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, LCD_REMOTE_WIDTH, LCD_REMOTE_HEIGHT, 8, | ||
287 | 0, 0, 0, 0); | ||
288 | |||
289 | lcdremotecolors(0, (1<<LCD_REMOTE_DEPTH), &remote_color_zero, &remote_color_max); | ||
290 | #endif | ||
291 | } | ||