summaryrefslogtreecommitdiff
path: root/apps/plugins/xrick/system/sysvid_rockbox.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/xrick/system/sysvid_rockbox.c')
-rw-r--r--apps/plugins/xrick/system/sysvid_rockbox.c409
1 files changed, 409 insertions, 0 deletions
diff --git a/apps/plugins/xrick/system/sysvid_rockbox.c b/apps/plugins/xrick/system/sysvid_rockbox.c
new file mode 100644
index 0000000000..e93522f6c9
--- /dev/null
+++ b/apps/plugins/xrick/system/sysvid_rockbox.c
@@ -0,0 +1,409 @@
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Port of xrick, a Rick Dangerous clone, to Rockbox.
11 * See http://www.bigorno.net/xrick/
12 *
13 * Copyright (C) 2008-2014 Pierluigi Vicinanza
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
24
25#include "xrick/system/system.h"
26
27#include "xrick/config.h"
28#include "xrick/draw.h"
29#include "xrick/game.h"
30#include "xrick/data/img.h"
31#include "xrick/debug.h"
32
33#include "plugin.h"
34#include "lib/helper.h"
35
36/*
37 * Global variables
38 */
39U8 *sysvid_fb = NULL; /* xRick generic 320x200 8bpp frame buffer */
40
41/*
42 * Local variables
43 */
44static fb_data palette[256] IBSS_ATTR;
45static bool isVideoInitialised = false;
46#ifndef HAVE_LCD_COLOR
47# include "lib/grey.h"
48GREY_INFO_STRUCT_IRAM
49static unsigned char greybuffer[LCD_HEIGHT * LCD_WIDTH] IBSS_ATTR; /* off screen buffer */
50static unsigned char *gbuf;
51# if LCD_PIXELFORMAT == HORIZONTAL_PACKING
52enum { GREYBUFSIZE = (((LCD_WIDTH+7)/8)*LCD_HEIGHT*16+200) };
53# else
54enum { GREYBUFSIZE = (LCD_WIDTH*((LCD_HEIGHT+7)/8)*16+200) };
55# endif
56#endif /* ndef HAVE_LCD_COLOR */
57
58#ifdef HAVE_LCD_COLOR
59static fb_data *lcd_fb = NULL;
60#endif
61
62#if (LCD_HEIGHT < SYSVID_HEIGHT)
63enum { ROW_RESIZE_STEP = (LCD_HEIGHT << 16) / SYSVID_HEIGHT };
64
65static bool rowsToSkip[SYSVID_HEIGHT];
66
67/*
68 *
69 */
70static void calculateRowsToSkip(void)
71{
72 U32 currentRow, prevResizedRow;
73
74 prevResizedRow = 0;
75 rowsToSkip[0] = false;
76
77 for (currentRow = 1; currentRow < SYSVID_HEIGHT; ++currentRow)
78 {
79 U32 resizedRow = (currentRow * ROW_RESIZE_STEP) >> 16;
80 if (resizedRow == prevResizedRow)
81 {
82 rowsToSkip[currentRow] = true;
83 }
84 prevResizedRow = resizedRow;
85 }
86}
87#endif /* (LCD_HEIGHT < SYSVID_HEIGHT) */
88
89#if (LCD_WIDTH < SYSVID_WIDTH)
90enum { COLUMN_RESIZE_STEP = (LCD_WIDTH << 16) / (SYSVID_WIDTH + (DRAW_XYMAP_SCRLEFT*2)) };
91
92static bool columnsToSkip[SYSVID_WIDTH + (DRAW_XYMAP_SCRLEFT*2)];
93
94/*
95 *
96 */
97static void calculateColumnsToSkip(void)
98{
99 U32 currentColumn, prevResizedColumn;
100
101 prevResizedColumn = 0;
102 columnsToSkip[0] = false;
103
104 for (currentColumn = 1; currentColumn < (SYSVID_WIDTH + (DRAW_XYMAP_SCRLEFT*2)); ++currentColumn)
105 {
106 U32 resizedColumn = (currentColumn * COLUMN_RESIZE_STEP) >> 16;
107 if (resizedColumn == prevResizedColumn)
108 {
109 columnsToSkip[currentColumn] = true;
110 }
111 prevResizedColumn = resizedColumn;
112 }
113}
114#endif /* (LCD_WIDTH < SYSVID_WIDTH) */
115
116/*
117 *
118 */
119void sysvid_setPalette(img_color_t *pal, U16 n)
120{
121 U16 i;
122
123 for (i = 0; i < n; i++)
124 {
125#ifdef HAVE_LCD_COLOR
126#if (LCD_PIXELFORMAT == RGB888) || (LCD_PIXELFORMAT == XRGB8888)
127 unsigned long x = LCD_RGBPACK(pal[i].r, pal[i].g, pal[i].b);
128 palette[i] = FB_SCALARPACK(x);
129#else
130 palette[i] = LCD_RGBPACK(pal[i].r, pal[i].g, pal[i].b);
131#endif
132#else
133 palette[i] = ((3 * pal[i].r) + (6 * pal[i].g) + pal[i].b) / 10;
134#endif
135 }
136}
137
138/*
139 *
140 */
141void sysvid_setGamePalette()
142{
143 sysvid_setPalette(game_colors, game_color_count);
144}
145
146/*
147 * Update screen
148 */
149void sysvid_update(const rect_t *rects)
150{
151 unsigned sourceRow, sourceLastRow;
152 unsigned sourceColumn, sourceLastColumn;
153 unsigned resizedRow, resizedColumn;
154 unsigned resizedWidth, resizedHeight;
155 unsigned x, y;
156 U8 *sourceBuf, *sourceTemp;
157 fb_data *destBuf, *destTemp;
158
159 if (!rects)
160 {
161 return;
162 }
163
164 while (rects)
165 {
166 sourceRow = rects->y;
167 sourceLastRow = sourceRow + rects->height;
168 sourceColumn = rects->x;
169 sourceLastColumn = sourceColumn + rects->width;
170
171#if (LCD_WIDTH < SYSVID_WIDTH)
172 /* skip black borders */
173 if (sourceColumn < -DRAW_XYMAP_SCRLEFT)
174 {
175 sourceColumn = -DRAW_XYMAP_SCRLEFT;
176 }
177 if (sourceLastColumn > (SYSVID_WIDTH + DRAW_XYMAP_SCRLEFT))
178 {
179 sourceLastColumn = SYSVID_WIDTH + DRAW_XYMAP_SCRLEFT;
180 }
181
182 /* skip unwanted columns */
183 while (columnsToSkip[sourceColumn + DRAW_XYMAP_SCRLEFT] /* && sourceColumn < (SYSVID_WIDTH + DRAW_XYMAP_SCRLEFT) */)
184 {
185 ++sourceColumn;
186 }
187
188 resizedColumn = ((sourceColumn + DRAW_XYMAP_SCRLEFT) * COLUMN_RESIZE_STEP) >> 16;
189 resizedWidth = 0;
190#else
191 resizedColumn = sourceColumn;
192 resizedWidth = rects->width;
193#endif /* (LCD_WIDTH < SYSVID_WIDTH) */
194
195#if (LCD_HEIGHT < SYSVID_HEIGHT)
196 /* skip unwanted rows */
197 while (rowsToSkip[sourceRow] /* && sourceRow < SYSVID_HEIGHT */)
198 {
199 ++sourceRow;
200 }
201
202 resizedRow = (sourceRow * ROW_RESIZE_STEP) >> 16;
203 resizedHeight = 0;
204#else
205 resizedRow = sourceRow;
206 resizedHeight = rects->height;
207#endif /* (LCD_HEIGHT < SYSVID_HEIGHT) */
208
209 sourceBuf = sysvid_fb;
210 sourceBuf += sourceColumn + sourceRow * SYSVID_WIDTH;
211
212#ifdef HAVE_LCD_COLOR
213 if(!lcd_fb)
214 {
215 struct viewport *vp_main = rb->lcd_set_viewport(NULL);
216 lcd_fb = vp_main->buffer->fb_ptr;
217 }
218 destBuf = lcd_fb;
219#else
220 destBuf = (fb_data*) greybuffer;
221#endif /* HAVE_LCD_COLOR */
222 destBuf += resizedColumn + resizedRow * LCD_WIDTH;
223
224#if (LCD_WIDTH < SYSVID_WIDTH)
225 sourceColumn += DRAW_XYMAP_SCRLEFT;
226 sourceLastColumn += DRAW_XYMAP_SCRLEFT;
227#endif /* (LCD_WIDTH < SYSVID_WIDTH) */
228
229 for (y = sourceRow; y < sourceLastRow; ++y)
230 {
231#if (LCD_HEIGHT < SYSVID_HEIGHT)
232 if (rowsToSkip[y])
233 {
234 sourceBuf += SYSVID_WIDTH;
235 continue;
236 }
237
238 ++resizedHeight;
239#endif /* (LCD_HEIGHT < SYSVID_HEIGHT) */
240
241 sourceTemp = sourceBuf;
242 destTemp = destBuf;
243 for (x = sourceColumn; x < sourceLastColumn; ++x)
244 {
245#if (LCD_WIDTH < SYSVID_WIDTH)
246 if (columnsToSkip[x])
247 {
248 ++sourceTemp;
249 continue;
250 }
251
252 if (y == sourceRow)
253 {
254 ++resizedWidth;
255 }
256#endif /* (LCD_WIDTH < SYSVID_WIDTH) */
257
258 *destTemp = palette[*sourceTemp];
259
260 ++sourceTemp;
261 ++destTemp;
262 }
263
264 sourceBuf += SYSVID_WIDTH;
265 destBuf += LCD_WIDTH;
266 }
267
268#ifdef HAVE_LCD_COLOR
269 IFDEBUG_VIDEO2(
270 for (y = resizedRow; y < resizedRow + resizedHeight; ++y)
271 {
272 destBuf = lcd_fb + resizedColumn + y * LCD_WIDTH;
273 *destBuf = palette[0x01];
274 *(destBuf + resizedWidth - 1) = palette[0x01];
275 }
276
277 for (x = resizedColumn; x < resizedColumn + resizedWidth; ++x)
278 {
279 destBuf = rb->lcd_fb + x + resizedRow * LCD_WIDTH;
280 *destBuf = palette[0x01];
281 *(destBuf + (resizedHeight - 1) * LCD_WIDTH) = palette[0x01];
282 }
283 );
284
285 rb->lcd_update_rect(resizedColumn, resizedRow, resizedWidth, resizedHeight);
286#else
287 grey_ub_gray_bitmap_part(greybuffer, resizedColumn, resizedRow, LCD_WIDTH, resizedColumn, resizedRow, resizedWidth, resizedHeight);
288#endif /* HAVE_LCD_COLOR */
289
290 rects = rects->next;
291 }
292}
293
294/*
295 * Clear screen
296 * (077C)
297 */
298void sysvid_clear(void)
299{
300 rb->memset(sysvid_fb, 0, sizeof(U8) * SYSVID_WIDTH * SYSVID_HEIGHT);
301}
302
303/*
304 * Initialise video
305 */
306bool sysvid_init()
307{
308 bool success;
309
310 if (isVideoInitialised)
311 {
312 return true;
313 }
314
315 IFDEBUG_VIDEO(sys_printf("xrick/video: start\n"););
316
317 success = false;
318 do
319 {
320 /* allocate xRick generic frame buffer into memory */
321 sysvid_fb = sysmem_push(sizeof(U8) * SYSVID_WIDTH * SYSVID_HEIGHT);
322 if (!sysvid_fb)
323 {
324 sys_error("(video) unable to allocate frame buffer");
325 break;
326 }
327
328#ifndef HAVE_LCD_COLOR
329 gbuf = sysmem_push(GREYBUFSIZE);
330 if (!gbuf)
331 {
332 sys_error("(video) unable to allocate buffer for greyscale functions");
333 break;
334 }
335
336 if (!grey_init(gbuf, GREYBUFSIZE, GREY_ON_COP, LCD_WIDTH, LCD_HEIGHT, NULL))
337 {
338 sys_error("(video) not enough memory to initialise greyscale functions");
339 break;
340 }
341#endif /* ndef HAVE_LCD_COLOR */
342
343 success = true;
344 } while (false);
345
346 if (!success)
347 {
348#ifndef HAVE_LCD_COLOR
349 sysmem_pop(gbuf);
350#endif
351 sysmem_pop(sysvid_fb);
352 return false;
353 }
354
355#if (LCD_HEIGHT < SYSVID_HEIGHT)
356 calculateRowsToSkip();
357#endif
358#if (LCD_WIDTH < SYSVID_WIDTH)
359 calculateColumnsToSkip();
360#endif
361
362#if LCD_DEPTH > 1
363 rb->lcd_set_backdrop(NULL);
364#endif
365 /* Turn off backlight timeout */
366 backlight_ignore_timeout();
367
368 rb->lcd_set_foreground(LCD_WHITE);
369 rb->lcd_set_background(LCD_BLACK);
370 rb->lcd_clear_display();
371
372#ifdef HAVE_LCD_COLOR
373 rb->lcd_update();
374#else
375 /* switch on greyscale overlay */
376 grey_show(true);
377#endif /* HAVE_LCD_COLOR */
378
379 isVideoInitialised = true;
380 IFDEBUG_VIDEO(sys_printf("xrick/video: ready\n"););
381 return true;
382}
383
384/*
385 * Shutdown video
386 */
387void sysvid_shutdown(void)
388{
389 if (!isVideoInitialised)
390 {
391 return;
392 }
393
394#ifndef HAVE_LCD_COLOR
395 grey_show(false);
396 grey_release();
397
398 sysmem_pop(gbuf);
399#endif /* ndef HAVE_LCD_COLOR */
400 sysmem_pop(sysvid_fb);
401
402 /* Turn on backlight timeout (revert to settings) */
403 backlight_use_settings();
404
405 isVideoInitialised = false;
406 IFDEBUG_VIDEO(sys_printf("xrick/video: stop\n"););
407}
408
409/* eof */