summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2017-10-29 12:42:34 -0400
committerFranklin Wei <git@fwei.tk>2017-10-29 12:49:39 -0400
commit47ebf623cbfa46bd37456cce28a192471b46ddd5 (patch)
tree9678921e3f66278bd7298ccbf38d85e7af5daf76 /apps
parentb2c470719a79f301ff4e9a6adcc5307ef47cfacf (diff)
downloadrockbox-47ebf623cbfa46bd37456cce28a192471b46ddd5.tar.gz
rockbox-47ebf623cbfa46bd37456cce28a192471b46ddd5.zip
puzzles: improve zoom rendering
This adds colored font rendering, as well as a workaround for font loading while zoomed. Additionally, the frontend has been modified to match the new upstream API. Change-Id: I8c3fe57e6854f176485bf792cf4778cd54a21674
Diffstat (limited to 'apps')
-rw-r--r--apps/plugins/puzzles/rbmalloc.c24
-rw-r--r--apps/plugins/puzzles/rockbox.c117
2 files changed, 86 insertions, 55 deletions
diff --git a/apps/plugins/puzzles/rbmalloc.c b/apps/plugins/puzzles/rbmalloc.c
index 5bf914ff87..1cb903ef4f 100644
--- a/apps/plugins/puzzles/rbmalloc.c
+++ b/apps/plugins/puzzles/rbmalloc.c
@@ -14,12 +14,9 @@
14int allocs = 0; 14int allocs = 0;
15int frees = 0; 15int frees = 0;
16 16
17bool audiobuf_available = 17/* We don't load as an overlay anymore, so the audiobuf should always
18#ifndef COMBINED 18 * be available. */
19 true; 19bool audiobuf_available = true;
20#else
21 false;
22#endif
23 20
24static bool grab_audiobuf(void) 21static bool grab_audiobuf(void)
25{ 22{
@@ -29,10 +26,23 @@ static bool grab_audiobuf(void)
29 if(rb->audio_status()) 26 if(rb->audio_status())
30 rb->audio_stop(); 27 rb->audio_stop();
31 28
32 size_t sz, junk; 29 size_t sz;
30
33 void *audiobuf = rb->plugin_get_audio_buffer(&sz); 31 void *audiobuf = rb->plugin_get_audio_buffer(&sz);
34 extern char *giant_buffer; 32 extern char *giant_buffer;
35 33
34#if 0
35 /* Try aligning if tlsf crashes in add_new_area(). This is
36 * disabled now since things seem to work without it. */
37 void *old = audiobuf;
38
39 /* I'm sorry. */
40 audiobuf = (void*)((int) audiobuf & ~0xff);
41 audiobuf += 0x100;
42
43 sz -= audiobuf - old;
44#endif
45
36 add_new_area(audiobuf, sz, giant_buffer); 46 add_new_area(audiobuf, sz, giant_buffer);
37 audiobuf_available = false; 47 audiobuf_available = false;
38 return true; 48 return true;
diff --git a/apps/plugins/puzzles/rockbox.c b/apps/plugins/puzzles/rockbox.c
index 59984a7891..b79070cba8 100644
--- a/apps/plugins/puzzles/rockbox.c
+++ b/apps/plugins/puzzles/rockbox.c
@@ -64,8 +64,8 @@
64#define midend_colors midend_colours 64#define midend_colors midend_colours
65#endif 65#endif
66 66
67#define PAN_X LCD_WIDTH / 4 67#define PAN_X (MIN(LCD_HEIGHT, LCD_WIDTH) / 4)
68#define PAN_Y LCD_WIDTH / 4 /* not a typo */ 68#define PAN_Y (MIN(LCD_HEIGHT, LCD_WIDTH) / 4)
69 69
70#define ZOOM_FACTOR 3 70#define ZOOM_FACTOR 3
71 71
@@ -84,7 +84,9 @@ static int help_times = 0;
84static void fix_size(void); 84static void fix_size(void);
85 85
86static struct viewport clip_rect; 86static struct viewport clip_rect;
87static bool clipped = false, audiobuf_available, zoom_enabled = false; 87static bool clipped = false, zoom_enabled = false;
88
89extern bool audiobuf_available;
88 90
89static fb_data *zoom_fb; 91static fb_data *zoom_fb;
90static int zoom_w, zoom_h, zoom_clipu, zoom_clipd, zoom_clipl, zoom_clipr; 92static int zoom_w, zoom_h, zoom_clipu, zoom_clipd, zoom_clipl, zoom_clipr;
@@ -209,6 +211,7 @@ static void zoom_drawcircle(int cx, int cy, int radius)
209 * efficiency? */ 211 * efficiency? */
210static void zoom_mono_bitmap(const unsigned char *bits, int x, int y, int w, int h) 212static void zoom_mono_bitmap(const unsigned char *bits, int x, int y, int w, int h)
211{ 213{
214 unsigned int pix = rb->lcd_get_foreground();
212 for(int i = 0; i < h / 8 + 1; ++i) 215 for(int i = 0; i < h / 8 + 1; ++i)
213 { 216 {
214 for(int j = 0; j < w; ++j) 217 for(int j = 0; j < w; ++j)
@@ -219,11 +222,11 @@ static void zoom_mono_bitmap(const unsigned char *bits, int x, int y, int w, int
219 if(column & 1) 222 if(column & 1)
220 { 223 {
221#if LCD_DEPTH == 24 224#if LCD_DEPTH == 24
222 zoom_fb[(y + i * 8 + dy) * zoom_w + x + j].b = RGB_UNPACK_BLUE(LCD_BLACK); 225 zoom_fb[(y + i * 8 + dy) * zoom_w + x + j].b = RGB_UNPACK_BLUE(pix);
223 zoom_fb[(y + i * 8 + dy) * zoom_w + x + j].g = RGB_UNPACK_GREEN(LCD_BLACK); 226 zoom_fb[(y + i * 8 + dy) * zoom_w + x + j].g = RGB_UNPACK_GREEN(pix);
224 zoom_fb[(y + i * 8 + dy) * zoom_w + x + j].r = RGB_UNPACK_RED(LCD_BLACK); 227 zoom_fb[(y + i * 8 + dy) * zoom_w + x + j].r = RGB_UNPACK_RED(pix);
225#else 228#else
226 zoom_fb[(y + i * 8 + dy) * zoom_w + x + j] = LCD_BLACK; 229 zoom_fb[(y + i * 8 + dy) * zoom_w + x + j] = pix;
227#endif 230#endif
228 } 231 }
229 column >>= 1; 232 column >>= 1;
@@ -240,6 +243,10 @@ static void zoom_alpha_bitmap(const unsigned char *bits, int x, int y, int w, in
240 const unsigned char *ptr = bits; 243 const unsigned char *ptr = bits;
241 unsigned char buf; 244 unsigned char buf;
242 int n_read = 0; /* how many 4-bit nibbles we've read (read new when even) */ 245 int n_read = 0; /* how many 4-bit nibbles we've read (read new when even) */
246
247 unsigned int pix = rb->lcd_get_foreground();
248 unsigned int r = RGB_UNPACK_RED(pix), g = RGB_UNPACK_GREEN(pix), b = RGB_UNPACK_BLUE(pix);
249
243 for(int i = 0; i < h; ++i) 250 for(int i = 0; i < h; ++i)
244 { 251 {
245 for(int j = 0; j < w; ++j) 252 for(int j = 0; j < w; ++j)
@@ -254,7 +261,7 @@ static void zoom_alpha_bitmap(const unsigned char *bits, int x, int y, int w, in
254 261
255 int plot_alpha = (pix_alpha << 4) | pix_alpha; /* so 0xF -> 0xFF, 0x1 -> 0x11, etc. */ 262 int plot_alpha = (pix_alpha << 4) | pix_alpha; /* so 0xF -> 0xFF, 0x1 -> 0x11, etc. */
256 263
257 plot(zoom_fb, zoom_w, zoom_h, x + j, y + i, plot_alpha, 0, 0, 0, 264 plot(zoom_fb, zoom_w, zoom_h, x + j, y + i, plot_alpha, r, g, b,
258 0, zoom_w, 0, zoom_h); 265 0, zoom_w, 0, zoom_h);
259 } 266 }
260 } 267 }
@@ -394,8 +401,9 @@ static void rb_setfont(int type, int size)
394{ 401{
395 /* out of range (besides, no puzzle should ever need this large 402 /* out of range (besides, no puzzle should ever need this large
396 of a font, anyways) */ 403 of a font, anyways) */
397 if(BUNDLE_MAX < size) 404 if(size > BUNDLE_MAX)
398 size = BUNDLE_MAX; 405 size = BUNDLE_MAX;
406
399 if(size < 10) 407 if(size < 10)
400 { 408 {
401 if(size < 7) /* no teeny-tiny fonts */ 409 if(size < 7) /* no teeny-tiny fonts */
@@ -459,7 +467,7 @@ fallback:
459} 467}
460 468
461static void rb_draw_text(void *handle, int x, int y, int fonttype, 469static void rb_draw_text(void *handle, int x, int y, int fonttype,
462 int fontsize, int align, int color, char *text) 470 int fontsize, int align, int color, const char *text)
463{ 471{
464 (void) fontsize; 472 (void) fontsize;
465 if(!zoom_enabled) 473 if(!zoom_enabled)
@@ -490,6 +498,7 @@ static void rb_draw_text(void *handle, int x, int y, int fonttype,
490 } 498 }
491 else 499 else
492 { 500 {
501 rb_color(color);
493 rb_setfont(fonttype, fontsize); /* size will be clamped if too large */ 502 rb_setfont(fonttype, fontsize); /* size will be clamped if too large */
494 503
495 int w, h; 504 int w, h;
@@ -1252,7 +1261,7 @@ static void rb_end_draw(void *handle)
1252 1261
1253static char *titlebar = NULL; 1262static char *titlebar = NULL;
1254 1263
1255static void rb_status_bar(void *handle, char *text) 1264static void rb_status_bar(void *handle, const char *text)
1256{ 1265{
1257 if(titlebar) 1266 if(titlebar)
1258 sfree(titlebar); 1267 sfree(titlebar);
@@ -1320,6 +1329,7 @@ const drawing_api rb_drawing = {
1320/* render to a virtual framebuffer and let the user pan (but not make any moves) */ 1329/* render to a virtual framebuffer and let the user pan (but not make any moves) */
1321static void zoom(void) 1330static void zoom(void)
1322{ 1331{
1332 rb->splash(0, "Please wait...");
1323 zoom_w = LCD_WIDTH * ZOOM_FACTOR, zoom_h = LCD_HEIGHT * ZOOM_FACTOR; 1333 zoom_w = LCD_WIDTH * ZOOM_FACTOR, zoom_h = LCD_HEIGHT * ZOOM_FACTOR;
1324 1334
1325 zoom_clipu = 0; 1335 zoom_clipu = 0;
@@ -1329,8 +1339,21 @@ static void zoom(void)
1329 1339
1330 midend_size(me, &zoom_w, &zoom_h, TRUE); 1340 midend_size(me, &zoom_w, &zoom_h, TRUE);
1331 1341
1332 /* allocate a framebuffer */ 1342 /* Allocating the framebuffer will mostly likely grab the
1343 * audiobuffer, which will make impossible to load new fonts, and
1344 * lead to zoomed puzzles being drawn with the default fallback
1345 * fonts. As a semi-workaround, we go ahead and load the biggest available
1346 * monospace and proportional fonts. */
1347 rb_setfont(FONT_FIXED, BUNDLE_MAX);
1348 rb_setfont(FONT_VARIABLE, BUNDLE_MAX);
1349
1333 zoom_fb = smalloc(zoom_w * zoom_h * sizeof(fb_data)); 1350 zoom_fb = smalloc(zoom_w * zoom_h * sizeof(fb_data));
1351 if(!zoom_fb)
1352 {
1353 rb->splashf(HZ * 2, "Not enough memory to allocate %d KB framebuffer!", zoom_w * zoom_h * sizeof(fb_data) / 1024);
1354 return;
1355 }
1356
1334 zoom_enabled = true; 1357 zoom_enabled = true;
1335 1358
1336 /* draws go to the enlarged framebuffer */ 1359 /* draws go to the enlarged framebuffer */
@@ -1530,7 +1553,7 @@ static void int_chooser(config_item *cfgs, int idx, int val)
1530 * a workaround for Unruly): */ 1553 * a workaround for Unruly): */
1531#define CHOOSER_MAX_INCR 2 1554#define CHOOSER_MAX_INCR 2
1532 1555
1533 char *ret; 1556 const char *ret;
1534 for(int i = 0; i < CHOOSER_MAX_INCR; ++i) 1557 for(int i = 0; i < CHOOSER_MAX_INCR; ++i)
1535 { 1558 {
1536 val += d; 1559 val += d;
@@ -1694,7 +1717,7 @@ static bool config_menu(void)
1694 old_str = dupstr(old.u.string.sval); 1717 old_str = dupstr(old.u.string.sval);
1695 1718
1696 bool freed_str = do_configure_item(config, pos); 1719 bool freed_str = do_configure_item(config, pos);
1697 char *err = midend_set_config(me, CFG_SETTINGS, config); 1720 const char *err = midend_set_config(me, CFG_SETTINGS, config);
1698 1721
1699 if(err) 1722 if(err)
1700 { 1723 {
@@ -1971,12 +1994,12 @@ static int pausemenu_cb(int action, const struct menu_item_ex *this_item)
1971 break; 1994 break;
1972 case 7: 1995 case 7:
1973 break; 1996 break;
1974 case 8: 1997 case 9:
1975 if(audiobuf_available) 1998 if(audiobuf_available)
1976 break; 1999 break;
1977 else 2000 else
1978 return ACTION_EXIT_MENUITEM; 2001 return ACTION_EXIT_MENUITEM;
1979 case 9: 2002 case 10:
1980 if(!midend_get_presets(me, NULL)->n_entries) 2003 if(!midend_get_presets(me, NULL)->n_entries)
1981 return ACTION_EXIT_MENUITEM; 2004 return ACTION_EXIT_MENUITEM;
1982 break; 2005 break;
@@ -2021,21 +2044,21 @@ static int pause_menu(void)
2021#define static auto 2044#define static auto
2022#define const 2045#define const
2023 MENUITEM_STRINGLIST(menu, NULL, pausemenu_cb, 2046 MENUITEM_STRINGLIST(menu, NULL, pausemenu_cb,
2024 "Resume Game", 2047 "Resume Game", // 0
2025 "New Game", 2048 "New Game", // 1
2026 "Restart Game", 2049 "Restart Game", // 2
2027 "Undo", 2050 "Undo", // 3
2028 "Redo", 2051 "Redo", // 4
2029 "Solve", 2052 "Solve", // 5
2030 "Zoom In", 2053 "Zoom In", // 6
2031 "Quick Help", 2054 "Quick Help", // 7
2032 "Extensive Help", 2055 "Extensive Help", // 8
2033 "Playback Control", 2056 "Playback Control", // 9
2034 "Game Type", 2057 "Game Type", // 10
2035 "Debug Menu", 2058 "Debug Menu", // 11
2036 "Configure Game", 2059 "Configure Game", // 12
2037 "Quit without Saving", 2060 "Quit without Saving", // 13
2038 "Quit"); 2061 "Quit"); // 14
2039#undef static 2062#undef static
2040#undef const 2063#undef const
2041 /* HACK ALERT */ 2064 /* HACK ALERT */
@@ -2082,7 +2105,7 @@ static int pause_menu(void)
2082 break; 2105 break;
2083 case 5: 2106 case 5:
2084 { 2107 {
2085 char *msg = midend_solve(me); 2108 const char *msg = midend_solve(me);
2086 if(msg) 2109 if(msg)
2087 rb->splash(HZ, msg); 2110 rb->splash(HZ, msg);
2088 quit = true; 2111 quit = true;
@@ -2391,7 +2414,7 @@ static int read_wrapper(void *ptr, void *buf, int len)
2391 return rb->read(fd, buf, len); 2414 return rb->read(fd, buf, len);
2392} 2415}
2393 2416
2394static void write_wrapper(void *ptr, void *buf, int len) 2417static void write_wrapper(void *ptr, const void *buf, int len)
2395{ 2418{
2396 int fd = (int) ptr; 2419 int fd = (int) ptr;
2397 rb->write(fd, buf, len); 2420 rb->write(fd, buf, len);
@@ -2416,7 +2439,7 @@ static void init_colors(void)
2416 sfree(floatcolors); 2439 sfree(floatcolors);
2417} 2440}
2418 2441
2419static char *init_for_game(const game *gm, int load_fd, bool draw) 2442static const char *init_for_game(const game *gm, int load_fd, bool draw)
2420{ 2443{
2421 me = midend_new(NULL, gm, &rb_drawing, NULL); 2444 me = midend_new(NULL, gm, &rb_drawing, NULL);
2422 2445
@@ -2424,7 +2447,7 @@ static char *init_for_game(const game *gm, int load_fd, bool draw)
2424 midend_new_game(me); 2447 midend_new_game(me);
2425 else 2448 else
2426 { 2449 {
2427 char *ret = midend_deserialize(me, read_wrapper, (void*) load_fd); 2450 const char *ret = midend_deserialize(me, read_wrapper, (void*) load_fd);
2428 if(ret) 2451 if(ret)
2429 return ret; 2452 return ret;
2430 } 2453 }
@@ -2584,7 +2607,7 @@ static void save_fonts(void)
2584 final |= oldmask; 2607 final |= oldmask;
2585 uint32_t left = final >> 31; 2608 uint32_t left = final >> 31;
2586 uint32_t right = final & 0x7fffffff; 2609 uint32_t right = final & 0x7fffffff;
2587 rb->fdprintf(outfd, "%s:%u:%u\n", midend_which_game(me)->name, left, right); 2610 rb->fdprintf(outfd, "%s:%lu:%lu\n", midend_which_game(me)->name, left, right);
2588 rb->close(outfd); 2611 rb->close(outfd);
2589 rb->rename(FONT_TABLE ".tmp", FONT_TABLE); 2612 rb->rename(FONT_TABLE ".tmp", FONT_TABLE);
2590 } 2613 }
@@ -2609,7 +2632,7 @@ static bool load_game(void)
2609 rb->splash(0, "Loading..."); 2632 rb->splash(0, "Loading...");
2610 2633
2611 char *game; 2634 char *game;
2612 char *ret = identify_game(&game, read_wrapper, (void*)fd); 2635 const char *ret = identify_game(&game, read_wrapper, (void*)fd);
2613 2636
2614 if(!*game && ret) 2637 if(!*game && ret)
2615 { 2638 {
@@ -2625,12 +2648,10 @@ static bool load_game(void)
2625 2648
2626 if(!strcmp(game, thegame.name)) 2649 if(!strcmp(game, thegame.name))
2627 { 2650 {
2628 sfree(ret);
2629 ret = init_for_game(&thegame, fd, false); 2651 ret = init_for_game(&thegame, fd, false);
2630 if(ret) 2652 if(ret)
2631 { 2653 {
2632 rb->splash(HZ, ret); 2654 rb->splash(HZ, ret);
2633 sfree(ret);
2634 rb->close(fd); 2655 rb->close(fd);
2635 rb->remove(fname); 2656 rb->remove(fname);
2636 return false; 2657 return false;
@@ -2755,15 +2776,15 @@ enum plugin_status plugin_start(const void *param)
2755#define static auto 2776#define static auto
2756#define const 2777#define const
2757 MENUITEM_STRINGLIST(menu, NULL, mainmenu_cb, 2778 MENUITEM_STRINGLIST(menu, NULL, mainmenu_cb,
2758 "Resume Game", 2779 "Resume Game", // 0
2759 "New Game", 2780 "New Game", // 1
2760 "Quick Help", 2781 "Quick Help", // 2
2761 "Extensive Help", 2782 "Extensive Help", // 3
2762 "Playback Control", 2783 "Playback Control", // 4
2763 "Game Type", 2784 "Game Type", // 5
2764 "Configure Game", 2785 "Configure Game", // 6
2765 "Quit without Saving", 2786 "Quit without Saving", // 7
2766 "Quit"); 2787 "Quit"); // 8
2767#undef static 2788#undef static
2768#undef const 2789#undef const
2769 2790