diff options
author | Sebastian Leonhardt <sebastian.leonhardt@web.de> | 2016-01-08 01:05:36 +0100 |
---|---|---|
committer | Solomon Peachy <pizza@shaftnet.org> | 2024-06-30 17:24:16 -0400 |
commit | 102c3742487dba76ec72d5f56a2c3041344b2d68 (patch) | |
tree | 4931ad34d2cc0bac56d9984b9ead355d012ad63a /apps/plugins/xrick/system/sysvid_rockbox.c | |
parent | 6f1e67e5e318ba2fd0f5ec1892c7b6633ec6521c (diff) | |
download | rockbox-102c3742487dba76ec72d5f56a2c3041344b2d68.tar.gz rockbox-102c3742487dba76ec72d5f56a2c3041344b2d68.zip |
added xrick game
original xrick code by 'BigOrno' at:
http://www.bigorno.net/xrick/
Rockbox port, plus bugfixes at:
https://github.com/pierluigi-vicinanza/xrick
Further changes:
* Additonal fixes from g#3026
* Port to modern plugin API
* Add Pluginlib keymap fallback
* Support all >1bpp screens
* Fix build warnings in miniz
* Better error message when resources are missing
Change-Id: Id83928bc2539901b0221692f65cbca41389c58e7
Diffstat (limited to 'apps/plugins/xrick/system/sysvid_rockbox.c')
-rw-r--r-- | apps/plugins/xrick/system/sysvid_rockbox.c | 402 |
1 files changed, 402 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..236bc87616 --- /dev/null +++ b/apps/plugins/xrick/system/sysvid_rockbox.c | |||
@@ -0,0 +1,402 @@ | |||
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 | */ | ||
39 | U8 *sysvid_fb = NULL; /* xRick generic 320x200 8bpp frame buffer */ | ||
40 | |||
41 | /* | ||
42 | * Local variables | ||
43 | */ | ||
44 | static fb_data palette[256] IBSS_ATTR; | ||
45 | static bool isVideoInitialised = false; | ||
46 | #ifndef HAVE_LCD_COLOR | ||
47 | # include "lib/grey.h" | ||
48 | GREY_INFO_STRUCT_IRAM | ||
49 | static unsigned char greybuffer[LCD_HEIGHT * LCD_WIDTH] IBSS_ATTR; /* off screen buffer */ | ||
50 | static unsigned char *gbuf; | ||
51 | # if LCD_PIXELFORMAT == HORIZONTAL_PACKING | ||
52 | enum { GREYBUFSIZE = (((LCD_WIDTH+7)/8)*LCD_HEIGHT*16+200) }; | ||
53 | # else | ||
54 | enum { GREYBUFSIZE = (LCD_WIDTH*((LCD_HEIGHT+7)/8)*16+200) }; | ||
55 | # endif | ||
56 | #endif /* ndef HAVE_LCD_COLOR */ | ||
57 | |||
58 | static fb_data *lcd_fb = NULL; | ||
59 | |||
60 | #if (LCD_HEIGHT < SYSVID_HEIGHT) | ||
61 | enum { ROW_RESIZE_STEP = (LCD_HEIGHT << 16) / SYSVID_HEIGHT }; | ||
62 | |||
63 | static bool rowsToSkip[SYSVID_HEIGHT]; | ||
64 | |||
65 | /* | ||
66 | * | ||
67 | */ | ||
68 | static void calculateRowsToSkip(void) | ||
69 | { | ||
70 | U32 currentRow, prevResizedRow; | ||
71 | |||
72 | prevResizedRow = 0; | ||
73 | rowsToSkip[0] = false; | ||
74 | |||
75 | for (currentRow = 1; currentRow < SYSVID_HEIGHT; ++currentRow) | ||
76 | { | ||
77 | U32 resizedRow = (currentRow * ROW_RESIZE_STEP) >> 16; | ||
78 | if (resizedRow == prevResizedRow) | ||
79 | { | ||
80 | rowsToSkip[currentRow] = true; | ||
81 | } | ||
82 | prevResizedRow = resizedRow; | ||
83 | } | ||
84 | } | ||
85 | #endif /* (LCD_HEIGHT < SYSVID_HEIGHT) */ | ||
86 | |||
87 | #if (LCD_WIDTH < SYSVID_WIDTH) | ||
88 | enum { COLUMN_RESIZE_STEP = (LCD_WIDTH << 16) / (SYSVID_WIDTH + (DRAW_XYMAP_SCRLEFT*2)) }; | ||
89 | |||
90 | static bool columnsToSkip[SYSVID_WIDTH + (DRAW_XYMAP_SCRLEFT*2)]; | ||
91 | |||
92 | /* | ||
93 | * | ||
94 | */ | ||
95 | static void calculateColumnsToSkip(void) | ||
96 | { | ||
97 | U32 currentColumn, prevResizedColumn; | ||
98 | |||
99 | prevResizedColumn = 0; | ||
100 | columnsToSkip[0] = false; | ||
101 | |||
102 | for (currentColumn = 1; currentColumn < (SYSVID_WIDTH + (DRAW_XYMAP_SCRLEFT*2)); ++currentColumn) | ||
103 | { | ||
104 | U32 resizedColumn = (currentColumn * COLUMN_RESIZE_STEP) >> 16; | ||
105 | if (resizedColumn == prevResizedColumn) | ||
106 | { | ||
107 | columnsToSkip[currentColumn] = true; | ||
108 | } | ||
109 | prevResizedColumn = resizedColumn; | ||
110 | } | ||
111 | } | ||
112 | #endif /* (LCD_WIDTH < SYSVID_WIDTH) */ | ||
113 | |||
114 | /* | ||
115 | * | ||
116 | */ | ||
117 | void sysvid_setPalette(img_color_t *pal, U16 n) | ||
118 | { | ||
119 | U16 i; | ||
120 | |||
121 | for (i = 0; i < n; i++) | ||
122 | { | ||
123 | #ifdef HAVE_LCD_COLOR | ||
124 | palette[i] = LCD_RGBPACK(pal[i].r, pal[i].g, pal[i].b); | ||
125 | #else | ||
126 | palette[i] = ((3 * pal[i].r) + (6 * pal[i].g) + pal[i].b) / 10; | ||
127 | #endif | ||
128 | } | ||
129 | } | ||
130 | |||
131 | /* | ||
132 | * | ||
133 | */ | ||
134 | void sysvid_setGamePalette() | ||
135 | { | ||
136 | sysvid_setPalette(game_colors, game_color_count); | ||
137 | } | ||
138 | |||
139 | /* | ||
140 | * Update screen | ||
141 | */ | ||
142 | void sysvid_update(const rect_t *rects) | ||
143 | { | ||
144 | unsigned sourceRow, sourceLastRow; | ||
145 | unsigned sourceColumn, sourceLastColumn; | ||
146 | unsigned resizedRow, resizedColumn; | ||
147 | unsigned resizedWidth, resizedHeight; | ||
148 | unsigned x, y; | ||
149 | U8 *sourceBuf, *sourceTemp; | ||
150 | fb_data *destBuf, *destTemp; | ||
151 | |||
152 | if (!rects) | ||
153 | { | ||
154 | return; | ||
155 | } | ||
156 | |||
157 | while (rects) | ||
158 | { | ||
159 | sourceRow = rects->y; | ||
160 | sourceLastRow = sourceRow + rects->height; | ||
161 | sourceColumn = rects->x; | ||
162 | sourceLastColumn = sourceColumn + rects->width; | ||
163 | |||
164 | #if (LCD_WIDTH < SYSVID_WIDTH) | ||
165 | /* skip black borders */ | ||
166 | if (sourceColumn < -DRAW_XYMAP_SCRLEFT) | ||
167 | { | ||
168 | sourceColumn = -DRAW_XYMAP_SCRLEFT; | ||
169 | } | ||
170 | if (sourceLastColumn > (SYSVID_WIDTH + DRAW_XYMAP_SCRLEFT)) | ||
171 | { | ||
172 | sourceLastColumn = SYSVID_WIDTH + DRAW_XYMAP_SCRLEFT; | ||
173 | } | ||
174 | |||
175 | /* skip unwanted columns */ | ||
176 | while (columnsToSkip[sourceColumn + DRAW_XYMAP_SCRLEFT] /* && sourceColumn < (SYSVID_WIDTH + DRAW_XYMAP_SCRLEFT) */) | ||
177 | { | ||
178 | ++sourceColumn; | ||
179 | } | ||
180 | |||
181 | resizedColumn = ((sourceColumn + DRAW_XYMAP_SCRLEFT) * COLUMN_RESIZE_STEP) >> 16; | ||
182 | resizedWidth = 0; | ||
183 | #else | ||
184 | resizedColumn = sourceColumn; | ||
185 | resizedWidth = rects->width; | ||
186 | #endif /* (LCD_WIDTH < SYSVID_WIDTH) */ | ||
187 | |||
188 | #if (LCD_HEIGHT < SYSVID_HEIGHT) | ||
189 | /* skip unwanted rows */ | ||
190 | while (rowsToSkip[sourceRow] /* && sourceRow < SYSVID_HEIGHT */) | ||
191 | { | ||
192 | ++sourceRow; | ||
193 | } | ||
194 | |||
195 | resizedRow = (sourceRow * ROW_RESIZE_STEP) >> 16; | ||
196 | resizedHeight = 0; | ||
197 | #else | ||
198 | resizedRow = sourceRow; | ||
199 | resizedHeight = rects->height; | ||
200 | #endif /* (LCD_HEIGHT < SYSVID_HEIGHT) */ | ||
201 | |||
202 | sourceBuf = sysvid_fb; | ||
203 | sourceBuf += sourceColumn + sourceRow * SYSVID_WIDTH; | ||
204 | |||
205 | #ifdef HAVE_LCD_COLOR | ||
206 | if(!lcd_fb) | ||
207 | { | ||
208 | struct viewport *vp_main = rb->lcd_set_viewport(NULL); | ||
209 | lcd_fb = vp_main->buffer->fb_ptr; | ||
210 | } | ||
211 | destBuf = lcd_fb; | ||
212 | #else | ||
213 | destBuf = greybuffer; | ||
214 | #endif /* HAVE_LCD_COLOR */ | ||
215 | destBuf += resizedColumn + resizedRow * LCD_WIDTH; | ||
216 | |||
217 | #if (LCD_WIDTH < SYSVID_WIDTH) | ||
218 | sourceColumn += DRAW_XYMAP_SCRLEFT; | ||
219 | sourceLastColumn += DRAW_XYMAP_SCRLEFT; | ||
220 | #endif /* (LCD_WIDTH < SYSVID_WIDTH) */ | ||
221 | |||
222 | for (y = sourceRow; y < sourceLastRow; ++y) | ||
223 | { | ||
224 | #if (LCD_HEIGHT < SYSVID_HEIGHT) | ||
225 | if (rowsToSkip[y]) | ||
226 | { | ||
227 | sourceBuf += SYSVID_WIDTH; | ||
228 | continue; | ||
229 | } | ||
230 | |||
231 | ++resizedHeight; | ||
232 | #endif /* (LCD_HEIGHT < SYSVID_HEIGHT) */ | ||
233 | |||
234 | sourceTemp = sourceBuf; | ||
235 | destTemp = destBuf; | ||
236 | for (x = sourceColumn; x < sourceLastColumn; ++x) | ||
237 | { | ||
238 | #if (LCD_WIDTH < SYSVID_WIDTH) | ||
239 | if (columnsToSkip[x]) | ||
240 | { | ||
241 | ++sourceTemp; | ||
242 | continue; | ||
243 | } | ||
244 | |||
245 | if (y == sourceRow) | ||
246 | { | ||
247 | ++resizedWidth; | ||
248 | } | ||
249 | #endif /* (LCD_WIDTH < SYSVID_WIDTH) */ | ||
250 | |||
251 | *destTemp = palette[*sourceTemp]; | ||
252 | |||
253 | ++sourceTemp; | ||
254 | ++destTemp; | ||
255 | } | ||
256 | |||
257 | sourceBuf += SYSVID_WIDTH; | ||
258 | destBuf += LCD_WIDTH; | ||
259 | } | ||
260 | |||
261 | #ifdef HAVE_LCD_COLOR | ||
262 | IFDEBUG_VIDEO2( | ||
263 | for (y = resizedRow; y < resizedRow + resizedHeight; ++y) | ||
264 | { | ||
265 | destBuf = lcd_fb + resizedColumn + y * LCD_WIDTH; | ||
266 | *destBuf = palette[0x01]; | ||
267 | *(destBuf + resizedWidth - 1) = palette[0x01]; | ||
268 | } | ||
269 | |||
270 | for (x = resizedColumn; x < resizedColumn + resizedWidth; ++x) | ||
271 | { | ||
272 | destBuf = rb->lcd_fb + x + resizedRow * LCD_WIDTH; | ||
273 | *destBuf = palette[0x01]; | ||
274 | *(destBuf + (resizedHeight - 1) * LCD_WIDTH) = palette[0x01]; | ||
275 | } | ||
276 | ); | ||
277 | |||
278 | rb->lcd_update_rect(resizedColumn, resizedRow, resizedWidth, resizedHeight); | ||
279 | #else | ||
280 | grey_ub_gray_bitmap_part(greybuffer, resizedColumn, resizedRow, LCD_WIDTH, resizedColumn, resizedRow, resizedWidth, resizedHeight); | ||
281 | #endif /* HAVE_LCD_COLOR */ | ||
282 | |||
283 | rects = rects->next; | ||
284 | } | ||
285 | } | ||
286 | |||
287 | /* | ||
288 | * Clear screen | ||
289 | * (077C) | ||
290 | */ | ||
291 | void sysvid_clear(void) | ||
292 | { | ||
293 | rb->memset(sysvid_fb, 0, sizeof(U8) * SYSVID_WIDTH * SYSVID_HEIGHT); | ||
294 | } | ||
295 | |||
296 | /* | ||
297 | * Initialise video | ||
298 | */ | ||
299 | bool sysvid_init() | ||
300 | { | ||
301 | bool success; | ||
302 | |||
303 | if (isVideoInitialised) | ||
304 | { | ||
305 | return true; | ||
306 | } | ||
307 | |||
308 | IFDEBUG_VIDEO(sys_printf("xrick/video: start\n");); | ||
309 | |||
310 | success = false; | ||
311 | do | ||
312 | { | ||
313 | /* allocate xRick generic frame buffer into memory */ | ||
314 | sysvid_fb = sysmem_push(sizeof(U8) * SYSVID_WIDTH * SYSVID_HEIGHT); | ||
315 | if (!sysvid_fb) | ||
316 | { | ||
317 | sys_error("(video) unable to allocate frame buffer"); | ||
318 | break; | ||
319 | } | ||
320 | |||
321 | #ifndef HAVE_LCD_COLOR | ||
322 | gbuf = sysmem_push(GREYBUFSIZE); | ||
323 | if (!gbuf) | ||
324 | { | ||
325 | sys_error("(video) unable to allocate buffer for greyscale functions"); | ||
326 | break; | ||
327 | } | ||
328 | |||
329 | if (!grey_init(gbuf, GREYBUFSIZE, GREY_ON_COP, LCD_WIDTH, LCD_HEIGHT, NULL)) | ||
330 | { | ||
331 | sys_error("(video) not enough memory to initialise greyscale functions"); | ||
332 | break; | ||
333 | } | ||
334 | #endif /* ndef HAVE_LCD_COLOR */ | ||
335 | |||
336 | success = true; | ||
337 | } while (false); | ||
338 | |||
339 | if (!success) | ||
340 | { | ||
341 | #ifndef HAVE_LCD_COLOR | ||
342 | sysmem_pop(gbuf); | ||
343 | #endif | ||
344 | sysmem_pop(sysvid_fb); | ||
345 | return false; | ||
346 | } | ||
347 | |||
348 | #if (LCD_HEIGHT < SYSVID_HEIGHT) | ||
349 | calculateRowsToSkip(); | ||
350 | #endif | ||
351 | #if (LCD_WIDTH < SYSVID_WIDTH) | ||
352 | calculateColumnsToSkip(); | ||
353 | #endif | ||
354 | |||
355 | #if LCD_DEPTH > 1 | ||
356 | rb->lcd_set_backdrop(NULL); | ||
357 | #endif | ||
358 | /* Turn off backlight timeout */ | ||
359 | backlight_ignore_timeout(); | ||
360 | |||
361 | rb->lcd_set_foreground(LCD_WHITE); | ||
362 | rb->lcd_set_background(LCD_BLACK); | ||
363 | rb->lcd_clear_display(); | ||
364 | |||
365 | #ifdef HAVE_LCD_COLOR | ||
366 | rb->lcd_update(); | ||
367 | #else | ||
368 | /* switch on greyscale overlay */ | ||
369 | grey_show(true); | ||
370 | #endif /* HAVE_LCD_COLOR */ | ||
371 | |||
372 | isVideoInitialised = true; | ||
373 | IFDEBUG_VIDEO(sys_printf("xrick/video: ready\n");); | ||
374 | return true; | ||
375 | } | ||
376 | |||
377 | /* | ||
378 | * Shutdown video | ||
379 | */ | ||
380 | void sysvid_shutdown(void) | ||
381 | { | ||
382 | if (!isVideoInitialised) | ||
383 | { | ||
384 | return; | ||
385 | } | ||
386 | |||
387 | #ifndef HAVE_LCD_COLOR | ||
388 | grey_show(false); | ||
389 | grey_release(); | ||
390 | |||
391 | sysmem_pop(gbuf); | ||
392 | #endif /* ndef HAVE_LCD_COLOR */ | ||
393 | sysmem_pop(sysvid_fb); | ||
394 | |||
395 | /* Turn on backlight timeout (revert to settings) */ | ||
396 | backlight_use_settings(); | ||
397 | |||
398 | isVideoInitialised = false; | ||
399 | IFDEBUG_VIDEO(sys_printf("xrick/video: stop\n");); | ||
400 | } | ||
401 | |||
402 | /* eof */ | ||