diff options
-rw-r--r-- | apps/plugins/puzzles/rockbox.c | 72 |
1 files changed, 55 insertions, 17 deletions
diff --git a/apps/plugins/puzzles/rockbox.c b/apps/plugins/puzzles/rockbox.c index eabe739657..7fe7998c39 100644 --- a/apps/plugins/puzzles/rockbox.c +++ b/apps/plugins/puzzles/rockbox.c | |||
@@ -49,7 +49,7 @@ | |||
49 | /* how many ticks between timer callbacks */ | 49 | /* how many ticks between timer callbacks */ |
50 | #define TIMER_INTERVAL (HZ / 50) | 50 | #define TIMER_INTERVAL (HZ / 50) |
51 | 51 | ||
52 | /* no c200v2 */ | 52 | /* Disable some features if we're memory constrained (c200v2) */ |
53 | #if PLUGIN_BUFFER_SIZE > 0x14000 | 53 | #if PLUGIN_BUFFER_SIZE > 0x14000 |
54 | #define DEBUG_MENU | 54 | #define DEBUG_MENU |
55 | #define FONT_CACHING | 55 | #define FONT_CACHING |
@@ -61,12 +61,14 @@ | |||
61 | #define BG_B .9f | 61 | #define BG_B .9f |
62 | #define BG_COLOR LCD_RGBPACK((int)(255*BG_R), (int)(255*BG_G), (int)(255*BG_B)) | 62 | #define BG_COLOR LCD_RGBPACK((int)(255*BG_R), (int)(255*BG_G), (int)(255*BG_B)) |
63 | 63 | ||
64 | /* used for invalid config value message */ | ||
64 | #define ERROR_COLOR LCD_RGBPACK(255, 0, 0) | 65 | #define ERROR_COLOR LCD_RGBPACK(255, 0, 0) |
65 | 66 | ||
67 | /* subtract two to allow for the fixed and UI fonts */ | ||
66 | #define MAX_FONTS (MAXUSERFONTS - 2) | 68 | #define MAX_FONTS (MAXUSERFONTS - 2) |
67 | #define FONT_TABLE PLUGIN_GAMES_DATA_DIR "/.sgt-puzzles.fnttab" | 69 | #define FONT_TABLE PLUGIN_GAMES_DATA_DIR "/.sgt-puzzles.fnttab" |
68 | 70 | ||
69 | /* font bundle size range */ | 71 | /* font bundle size range (in pixels) */ |
70 | #define BUNDLE_MIN 7 | 72 | #define BUNDLE_MIN 7 |
71 | #define BUNDLE_MAX 36 | 73 | #define BUNDLE_MAX 36 |
72 | #define BUNDLE_COUNT (BUNDLE_MAX - BUNDLE_MIN + 1) | 74 | #define BUNDLE_COUNT (BUNDLE_MAX - BUNDLE_MIN + 1) |
@@ -74,7 +76,7 @@ | |||
74 | /* max length of C_STRING config vals */ | 76 | /* max length of C_STRING config vals */ |
75 | #define MAX_STRLEN 128 | 77 | #define MAX_STRLEN 128 |
76 | 78 | ||
77 | /* try to increment a numeric config value up to this much */ | 79 | /* attempt to increment a numeric config value up to this much */ |
78 | #define CHOOSER_MAX_INCR 2 | 80 | #define CHOOSER_MAX_INCR 2 |
79 | 81 | ||
80 | /* max font table line */ | 82 | /* max font table line */ |
@@ -90,15 +92,19 @@ | |||
90 | #define midend_colors midend_colours | 92 | #define midend_colors midend_colours |
91 | #endif | 93 | #endif |
92 | 94 | ||
93 | /* zoom stuff */ | 95 | /* magnification factor */ |
94 | #define ZOOM_FACTOR 3 | 96 | #define ZOOM_FACTOR 3 |
97 | |||
98 | /* distance to pan per click (in pixels) */ | ||
95 | #define PAN_X (MIN(LCD_HEIGHT, LCD_WIDTH) / 4) | 99 | #define PAN_X (MIN(LCD_HEIGHT, LCD_WIDTH) / 4) |
96 | #define PAN_Y (MIN(LCD_HEIGHT, LCD_WIDTH) / 4) | 100 | #define PAN_Y (MIN(LCD_HEIGHT, LCD_WIDTH) / 4) |
97 | 101 | ||
98 | /* utility macros */ | 102 | /* utility macros */ |
99 | #undef ABS | 103 | #undef ABS |
100 | #define ABS(a) ((a)<0?-(a):(a)) | 104 | #define ABS(a) ((a)<0?-(a):(a)) |
101 | #define SWAP(a, b, t) do { t = a; a = b; b = t; } while(0); | 105 | #define SWAP(a, b, t) do { t = a; a = b; b = t; } while(0) |
106 | |||
107 | /* fixed-point stuff (for antialiased lines) */ | ||
102 | #define fp_fpart(f, bits) ((f) & ((1 << (bits)) - 1)) | 108 | #define fp_fpart(f, bits) ((f) & ((1 << (bits)) - 1)) |
103 | #define fp_rfpart(f, bits) ((1 << (bits)) - fp_fpart(f, bits)) | 109 | #define fp_rfpart(f, bits) ((1 << (bits)) - fp_fpart(f, bits)) |
104 | #define FRACBITS 16 | 110 | #define FRACBITS 16 |
@@ -170,8 +176,11 @@ static struct { | |||
170 | // used in menu titles - make sure to initialize! | 176 | // used in menu titles - make sure to initialize! |
171 | static char menu_desc[32]; | 177 | static char menu_desc[32]; |
172 | 178 | ||
173 | /* These are re-implementations of many rockbox drawing functions, adapted to | 179 | /* |
174 | * draw into a custom framebuffer (used for the zoom feature). */ | 180 | * These are re-implementations of many rockbox drawing functions, adapted to |
181 | * draw into a custom framebuffer (used for the zoom feature): | ||
182 | */ | ||
183 | |||
175 | static void zoom_drawpixel(int x, int y) | 184 | static void zoom_drawpixel(int x, int y) |
176 | { | 185 | { |
177 | if(y < zoom_clipu || y >= zoom_clipd) | 186 | if(y < zoom_clipu || y >= zoom_clipd) |
@@ -319,9 +328,11 @@ static void zoom_mono_bitmap(const unsigned char *bits, int x, int y, int w, int | |||
319 | } | 328 | } |
320 | } | 329 | } |
321 | 330 | ||
322 | /* Rockbox's alpha format is actually pretty sane: each byte holds | 331 | /* |
332 | * Rockbox's alpha format is actually pretty sane: each byte holds | ||
323 | * alpha values for two horizontally adjacent pixels. Low half is | 333 | * alpha values for two horizontally adjacent pixels. Low half is |
324 | * leftmost pixel. See lcd-16bit-common.c for more info. */ | 334 | * leftmost pixel. See lcd-16bit-common.c for more info. |
335 | */ | ||
325 | static void zoom_alpha_bitmap(const unsigned char *bits, int x, int y, int w, int h) | 336 | static void zoom_alpha_bitmap(const unsigned char *bits, int x, int y, int w, int h) |
326 | { | 337 | { |
327 | const unsigned char *ptr = bits; | 338 | const unsigned char *ptr = bits; |
@@ -351,7 +362,28 @@ static void zoom_alpha_bitmap(const unsigned char *bits, int x, int y, int w, in | |||
351 | } | 362 | } |
352 | } | 363 | } |
353 | 364 | ||
354 | /* font management routines */ | 365 | /* |
366 | * Font management routines | ||
367 | * | ||
368 | * Many puzzles need a dynamic font size, especially when zooming | ||
369 | * in. Rockbox's default font set does not provide the consistency we | ||
370 | * need across different sizes, so instead we ship a custom font pack | ||
371 | * for sgt-puzzles, available from [1] or through Rockbox Utility. | ||
372 | * | ||
373 | * The font pack consists of 3 small-size fonts, and the Deja Vu | ||
374 | * Sans/Mono fonts, rasterized in sizes from 10 to BUNDLE_MAX | ||
375 | * (currently 36). | ||
376 | * | ||
377 | * The font loading code below tries to be smart about loading fonts: | ||
378 | * when games are saved, the set of fonts that were loaded during | ||
379 | * execution is written to a "font table" on disk. On subsequent | ||
380 | * loads, the fonts in this table are precached while the game is | ||
381 | * loaded (and the disk is spinning, on hard drive devices). We also | ||
382 | * have a form of LRU caching implemented to dynamically evict fonts | ||
383 | * from Rockbox's in-memory cache, which is of limited size. | ||
384 | * | ||
385 | * [1]: http://download.rockbox.org/useful/sgt-fonts.zip | ||
386 | */ | ||
355 | 387 | ||
356 | static struct bundled_font { | 388 | static struct bundled_font { |
357 | int status; /* -3 = never tried loading, or unloaded, -2 = failed to load, >= -1: loaded successfully */ | 389 | int status; /* -3 = never tried loading, or unloaded, -2 = failed to load, >= -1: loaded successfully */ |
@@ -411,8 +443,10 @@ static void font_path(char *buf, int type, int size) | |||
411 | 443 | ||
412 | static void rb_setfont(int type, int size) | 444 | static void rb_setfont(int type, int size) |
413 | { | 445 | { |
414 | /* out of range (besides, no puzzle should ever need this large | 446 | /* |
415 | of a font, anyways) */ | 447 | * First, clamp to range. No puzzle should ever need this large of |
448 | * a font, anyways. | ||
449 | */ | ||
416 | if(size > BUNDLE_MAX) | 450 | if(size > BUNDLE_MAX) |
417 | size = BUNDLE_MAX; | 451 | size = BUNDLE_MAX; |
418 | 452 | ||
@@ -420,7 +454,7 @@ static void rb_setfont(int type, int size) | |||
420 | { | 454 | { |
421 | if(size < 7) /* no teeny-tiny fonts */ | 455 | if(size < 7) /* no teeny-tiny fonts */ |
422 | size = 7; | 456 | size = 7; |
423 | /* assume monospace for these */ | 457 | /* assume monospace for 7-9px fonts */ |
424 | type = FONT_FIXED; | 458 | type = FONT_FIXED; |
425 | } | 459 | } |
426 | 460 | ||
@@ -432,7 +466,7 @@ static void rb_setfont(int type, int size) | |||
432 | /* never loaded */ | 466 | /* never loaded */ |
433 | char buf[MAX_PATH]; | 467 | char buf[MAX_PATH]; |
434 | font_path(buf, type, size); | 468 | font_path(buf, type, size); |
435 | if(n_fonts >= MAX_FONTS) /* safety margin, FIXME */ | 469 | if(n_fonts >= MAX_FONTS) |
436 | { | 470 | { |
437 | /* unload an old font */ | 471 | /* unload an old font */ |
438 | int oldest_use = -1, oldest_idx = -1; | 472 | int oldest_use = -1, oldest_idx = -1; |
@@ -1278,12 +1312,16 @@ static void rb_draw_update(void *handle, int x, int y, int w, int h) | |||
1278 | { | 1312 | { |
1279 | LOGF("rb_draw_update(%d, %d, %d, %d)", x, y, w, h); | 1313 | LOGF("rb_draw_update(%d, %d, %d, %d)", x, y, w, h); |
1280 | 1314 | ||
1281 | /* It seems that the puzzles use a different definition of | 1315 | /* |
1316 | * It seems that the puzzles use a different definition of | ||
1282 | * "updating" the display than Rockbox does; by calling this | 1317 | * "updating" the display than Rockbox does; by calling this |
1283 | * function, it tells us that it has either already drawn to the | 1318 | * function, it tells us that it has either already drawn to the |
1284 | * updated area (as rockbox assumes), or that it WILL draw to the | 1319 | * updated area (as rockbox assumes), or that it WILL draw to the |
1285 | * said area. Thus we simply remember a rectangle that contains | 1320 | * said area in the future (in which case we will draw |
1286 | * all the updated regions and update it at the very end. */ | 1321 | * nothing). Because we don't know which of these is the case, we |
1322 | * simply remember a rectangle that contains all the updated | ||
1323 | * regions and update it at the very end. | ||
1324 | */ | ||
1287 | 1325 | ||
1288 | /* adapted from gtk.c */ | 1326 | /* adapted from gtk.c */ |
1289 | if (!need_draw_update || ud_l > x ) ud_l = x; | 1327 | if (!need_draw_update || ud_l > x ) ud_l = x; |