summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2017-01-13 23:52:04 -0500
committerFranklin Wei <git@fwei.tk>2017-01-13 23:52:04 -0500
commitc1b913bb7da17374cec5688c16d2f0e96ae5e662 (patch)
treeef030fbf32217b09c3cf652818df34ae9214a929
parent823f726f834932534fc21ba6227b5169fc707a20 (diff)
downloadrockbox-c1b913bb7da17374cec5688c16d2f0e96ae5e662.tar.gz
rockbox-c1b913bb7da17374cec5688c16d2f0e96ae5e662.zip
Revert "puzzles: antialiased line drawing and optional "shortcuts" for undo/redo"
This reverts commit 8e4429853d1ac024ac2b8069636cc210cf5bab1b. Change-Id: Id622d58ad4b3b9dd3313811c8a2f83202d21f5ee
-rw-r--r--apps/plugins/puzzles/puzzles.make4
-rw-r--r--apps/plugins/puzzles/rockbox.c422
-rw-r--r--apps/plugins/puzzles/untangle.c15
3 files changed, 104 insertions, 337 deletions
diff --git a/apps/plugins/puzzles/puzzles.make b/apps/plugins/puzzles/puzzles.make
index f49b663197..4052423fb9 100644
--- a/apps/plugins/puzzles/puzzles.make
+++ b/apps/plugins/puzzles/puzzles.make
@@ -43,8 +43,8 @@ ROCKS += $(PUZZLES_ROCKS)
43endif 43endif
44 44
45# Hack to suppress all warnings: 45# Hack to suppress all warnings:
46PUZZLESFLAGS = $(filter-out -O%,$(PLUGINFLAGS)) -O3 \ 46PUZZLESFLAGS = $(filter-out -O%,$(PLUGINFLAGS)) -Os \
47 -Wno-unused-parameter -Wno-sign-compare -Wno-strict-aliasing -w \ 47 -Wno-unused-parameter -Wno-sign-compare -Wno-strict-aliasing -w \
48 -DFOR_REAL -I$(PUZZLES_SRCDIR) 48 -DFOR_REAL -I$(PUZZLES_SRCDIR)
49ifdef PUZZLES_COMBINED 49ifdef PUZZLES_COMBINED
50PUZZLESFLAGS += -DCOMBINED 50PUZZLESFLAGS += -DCOMBINED
diff --git a/apps/plugins/puzzles/rockbox.c b/apps/plugins/puzzles/rockbox.c
index c3921a80b6..3e3bd15f33 100644
--- a/apps/plugins/puzzles/rockbox.c
+++ b/apps/plugins/puzzles/rockbox.c
@@ -30,7 +30,6 @@
30#include "lib/playback_control.h" 30#include "lib/playback_control.h"
31#endif 31#endif
32#include "lib/xlcd.h" 32#include "lib/xlcd.h"
33#include "fixedpoint.h"
34 33
35/* how many ticks between timer callbacks */ 34/* how many ticks between timer callbacks */
36#define TIMER_INTERVAL (HZ / 50) 35#define TIMER_INTERVAL (HZ / 50)
@@ -76,7 +75,7 @@ extern bool audiobuf_available;
76 75
77static struct settings_t { 76static struct settings_t {
78 int slowmo_factor; 77 int slowmo_factor;
79 bool bulk, timerflash, clipoff, shortcuts, no_aa; 78 bool bulk, timerflash, clipoff;
80} settings; 79} settings;
81 80
82/* clipping is implemented through viewports and offsetting 81/* clipping is implemented through viewports and offsetting
@@ -180,129 +179,14 @@ static void rb_draw_rect(void *handle, int x, int y, int w, int h, int color)
180 rb->lcd_fillrect(x, y, w, h); 179 rb->lcd_fillrect(x, y, w, h);
181} 180}
182 181
183#define SWAP(a, b, t) do { t = a; a = b; b = t; } while(0);
184
185#define fp_fpart(f, bits) ((f) & ((1 << (bits)) - 1))
186#define fp_rfpart(f, bits) ((1 << (bits)) - fp_fpart(f, bits))
187
188#define FRACBITS 16
189
190/* most of our time drawing lines is spent in this function! */
191static inline void plot(unsigned x, unsigned y, unsigned long a,
192 unsigned long r1, unsigned long g1, unsigned long b1,
193 unsigned cl, unsigned cr, unsigned cu, unsigned cd)
194{
195 /* This is really quite possibly the least efficient way of doing
196 this. A better way would be in draw_antialiased_line(), but the
197 problem with that is that the algorithms I investigated at
198 least were incorrect at least part of the time and didn't make
199 drawing much faster overall. */
200 if(!(cl <= x && x < cr && cu <= y && y < cd))
201 return;
202
203 fb_data *ptr = rb->lcd_framebuffer + y * LCD_WIDTH + x;
204 fb_data orig = *ptr;
205 unsigned long r2, g2, b2;
206 r2 = RGB_UNPACK_RED(orig);
207 g2 = RGB_UNPACK_GREEN(orig);
208 b2 = RGB_UNPACK_BLUE(orig);
209
210 unsigned long r, g, b;
211 r = ((r1 * a) + (r2 * (256 - a))) >> 8;
212 g = ((g1 * a) + (g2 * (256 - a))) >> 8;
213 b = ((b1 * a) + (b2 * (256 - a))) >> 8;
214
215 *ptr = LCD_RGBPACK(r, g, b);
216}
217
218#undef ABS
219#define ABS(a) ((a)<0?-(a):(a))
220
221/* speed benchmark: 34392 lines/sec vs 112687 non-antialiased
222 * lines/sec at full optimization on ipod6g */
223
224/* expects UN-OFFSET coordinates, directly access framebuffer */
225static void draw_antialiased_line(int x0, int y0, int x1, int y1)
226{
227 /* fixed-point Wu's algorithm, modified for integer-only endpoints */
228
229 /* passed to plot() to avoid re-calculation */
230 unsigned short l = 0, r = LCD_WIDTH, u = 0, d = LCD_HEIGHT;
231 if(clipped)
232 {
233 l = clip_rect.x;
234 r = clip_rect.x + clip_rect.width;
235 u = clip_rect.y;
236 d = clip_rect.y + clip_rect.height;
237 }
238
239 bool steep = ABS(y1 - y0) > ABS(x1 - x0);
240 int tmp;
241 if(steep)
242 {
243 SWAP(x0, y0, tmp);
244 SWAP(x1, y1, tmp);
245 }
246 if(x0 > x1)
247 {
248 SWAP(x0, x1, tmp);
249 SWAP(y0, y1, tmp);
250 }
251
252 int dx, dy;
253 dx = x1 - x0;
254 dy = y1 - y0;
255
256 if(!(dx << FRACBITS))
257 return; /* bail out */
258
259 long gradient = fp_div(dy << FRACBITS, dx << FRACBITS, FRACBITS);
260 long intery = (y0 << FRACBITS);
261
262 unsigned color = rb->lcd_get_foreground();
263 unsigned long r1, g1, b1;
264 r1 = RGB_UNPACK_RED(color);
265 g1 = RGB_UNPACK_GREEN(color);
266 b1 = RGB_UNPACK_BLUE(color);
267
268 /* main loop */
269 if(steep)
270 {
271 for(int x = x0; x <= x1; ++x, intery += gradient)
272 {
273 unsigned y = intery >> FRACBITS;
274 unsigned alpha = fp_fpart(intery, FRACBITS) >> (FRACBITS - 8);
275
276 plot(y, x, (1 << 8) - alpha, r1, g1, b1, l, r, u, d);
277 plot(y + 1, x, alpha, r1, g1, b1, l, r, u, d);
278 }
279 }
280 else
281 {
282 for(int x = x0; x <= x1; ++x, intery += gradient)
283 {
284 unsigned y = intery >> FRACBITS;
285 unsigned alpha = fp_fpart(intery, FRACBITS) >> (FRACBITS - 8);
286
287 plot(x, y, (1 << 8) - alpha, r1, g1, b1, l, r, u, d);
288 plot(x, y + 1, alpha, r1, g1, b1, l, r, u, d);
289 }
290 }
291}
292
293static void rb_draw_line(void *handle, int x1, int y1, int x2, int y2, 182static void rb_draw_line(void *handle, int x1, int y1, int x2, int y2,
294 int color) 183 int color)
295{ 184{
296 LOGF("rb_draw_line(%d, %d, %d, %d, %d)", x1, y1, x2, y2, color); 185 LOGF("rb_draw_line(%d, %d, %d, %d, %d)", x1, y1, x2, y2, color);
186 offset_coords(&x1, &y1);
187 offset_coords(&x2, &y2);
297 rb_color(color); 188 rb_color(color);
298 if(settings.no_aa) 189 rb->lcd_drawline(x1, y1, x2, y2);
299 {
300 offset_coords(&x1, &y1);
301 offset_coords(&x2, &y2);
302 rb->lcd_drawline(x1, y1, x2, y2);
303 }
304 else
305 draw_antialiased_line(x1, y1, x2, y2);
306} 190}
307 191
308/* 192/*
@@ -467,15 +351,12 @@ static void rb_draw_poly(void *handle, int *coords, int npoints,
467 y1 = coords[2 * (i - 1) + 1]; 351 y1 = coords[2 * (i - 1) + 1];
468 x2 = coords[2 * i]; 352 x2 = coords[2 * i];
469 y2 = coords[2 * i + 1]; 353 y2 = coords[2 * i + 1];
470 if(settings.no_aa) 354 offset_coords(&x1, &y1);
471 { 355 offset_coords(&x2, &y2);
472 offset_coords(&x1, &y1); 356 rb->lcd_drawline(x1, y1,
473 offset_coords(&x2, &y2); 357 x2, y2);
474 rb->lcd_drawline(x1, y1, 358 //rb->lcd_update();
475 x2, y2); 359 //rb->sleep(HZ/2);
476 }
477 else
478 draw_antialiased_line(x1, y1, x2, y2);
479 } 360 }
480 361
481 int x1, y1, x2, y2; 362 int x1, y1, x2, y2;
@@ -483,16 +364,11 @@ static void rb_draw_poly(void *handle, int *coords, int npoints,
483 y1 = coords[1]; 364 y1 = coords[1];
484 x2 = coords[2 * (npoints - 1)]; 365 x2 = coords[2 * (npoints - 1)];
485 y2 = coords[2 * (npoints - 1) + 1]; 366 y2 = coords[2 * (npoints - 1) + 1];
486 if(settings.no_aa) 367 offset_coords(&x1, &y1);
487 { 368 offset_coords(&x2, &y2);
488 offset_coords(&x1, &y1);
489 offset_coords(&x2, &y2);
490 369
491 rb->lcd_drawline(x1, y1, 370 rb->lcd_drawline(x1, y1,
492 x2, y2); 371 x2, y2);
493 }
494 else
495 draw_antialiased_line(x1, y1, x2, y2);
496} 372}
497 373
498static void rb_draw_circle(void *handle, int cx, int cy, int radius, 374static void rb_draw_circle(void *handle, int cx, int cy, int radius,
@@ -518,6 +394,25 @@ struct blitter {
518 struct bitmap bmp; 394 struct bitmap bmp;
519}; 395};
520 396
397static blitter *rb_blitter_new(void *handle, int w, int h)
398{
399 LOGF("rb_blitter_new");
400 blitter *b = snew(blitter);
401 b->bmp.width = w;
402 b->bmp.height = h;
403 b->bmp.data = smalloc(w * h * sizeof(fb_data));
404 b->have_data = false;
405 return b;
406}
407
408static void rb_blitter_free(void *handle, blitter *bl)
409{
410 LOGF("rb_blitter_free");
411 sfree(bl->bmp.data);
412 sfree(bl);
413 return;
414}
415
521/* originally from emcc.c */ 416/* originally from emcc.c */
522static void trim_rect(int *x, int *y, int *w, int *h) 417static void trim_rect(int *x, int *y, int *w, int *h)
523{ 418{
@@ -535,10 +430,10 @@ static void trim_rect(int *x, int *y, int *w, int *h)
535 y1 = *y + *h; 430 y1 = *y + *h;
536 431
537 /* Clip each coordinate at both extremes of the canvas */ 432 /* Clip each coordinate at both extremes of the canvas */
538 x0 = (x0 < 0 ? 0 : x0 > LCD_WIDTH - 1 ? LCD_WIDTH - 1: x0); 433 x0 = (x0 < 0 ? 0 : x0 > LCD_WIDTH ? LCD_WIDTH : x0);
539 x1 = (x1 < 0 ? 0 : x1 > LCD_WIDTH - 1 ? LCD_WIDTH - 1: x1); 434 x1 = (x1 < 0 ? 0 : x1 > LCD_WIDTH ? LCD_WIDTH : x1);
540 y0 = (y0 < 0 ? 0 : y0 > LCD_HEIGHT - 1 ? LCD_HEIGHT - 1: y0); 435 y0 = (y0 < 0 ? 0 : y0 > LCD_HEIGHT ? LCD_HEIGHT : y0);
541 y1 = (y1 < 0 ? 0 : y1 > LCD_HEIGHT - 1 ? LCD_HEIGHT - 1: y1); 436 y1 = (y1 < 0 ? 0 : y1 > LCD_HEIGHT ? LCD_HEIGHT : y1);
542 437
543 /* Transform back into x,y,w,h to return */ 438 /* Transform back into x,y,w,h to return */
544 *x = x0; 439 *x = x0;
@@ -547,25 +442,6 @@ static void trim_rect(int *x, int *y, int *w, int *h)
547 *h = y1 - y0; 442 *h = y1 - y0;
548} 443}
549 444
550static blitter *rb_blitter_new(void *handle, int w, int h)
551{
552 LOGF("rb_blitter_new");
553 blitter *b = snew(blitter);
554 b->bmp.width = w;
555 b->bmp.height = h;
556 b->bmp.data = smalloc(w * h * sizeof(fb_data));
557 b->have_data = false;
558 return b;
559}
560
561static void rb_blitter_free(void *handle, blitter *bl)
562{
563 LOGF("rb_blitter_free");
564 sfree(bl->bmp.data);
565 sfree(bl);
566 return;
567}
568
569/* copy a section of the framebuffer */ 445/* copy a section of the framebuffer */
570static void rb_blitter_save(void *handle, blitter *bl, int x, int y) 446static void rb_blitter_save(void *handle, blitter *bl, int x, int y)
571{ 447{
@@ -747,6 +623,8 @@ void get_random_seed(void **randseed, int *randseedsize)
747 *randseed = snew(long); 623 *randseed = snew(long);
748 long seed = *rb->current_tick; 624 long seed = *rb->current_tick;
749 rb->memcpy(*randseed, &seed, sizeof(seed)); 625 rb->memcpy(*randseed, &seed, sizeof(seed));
626 //*(long*)*randseed = 42; // debug
627 //rb->splash(HZ, "DEBUG SEED ON");
750 *randseedsize = sizeof(long); 628 *randseedsize = sizeof(long);
751} 629}
752 630
@@ -805,11 +683,9 @@ static int list_choose(const char *list_str, const char *title)
805 } 683 }
806} 684}
807 685
808#define CONFIGMENU_FREEDSTR 1 686/* return value is only meaningful when type == C_STRING */
809#define CONFIGMENU_SUCCESS 2 687static bool do_configure_item(config_item *cfg)
810static int do_configure_item(config_item *cfg)
811{ 688{
812 int rc = 0;
813 switch(cfg->type) 689 switch(cfg->type)
814 { 690 {
815 case C_STRING: 691 case C_STRING:
@@ -822,46 +698,35 @@ static int do_configure_item(config_item *cfg)
822 if(rb->kbd_input(newstr, MAX_STRLEN) < 0) 698 if(rb->kbd_input(newstr, MAX_STRLEN) < 0)
823 { 699 {
824 sfree(newstr); 700 sfree(newstr);
825 return rc; 701 return false;
826 } 702 }
827 if(strcmp(newstr, cfg->sval))
828 rc |= CONFIGMENU_SUCCESS;
829 sfree(cfg->sval); 703 sfree(cfg->sval);
830 cfg->sval = newstr; 704 cfg->sval = newstr;
831 rc |= CONFIGMENU_FREEDSTR; 705 return true;
832 return rc;
833 } 706 }
834 case C_BOOLEAN: 707 case C_BOOLEAN:
835 { 708 {
836 bool res = cfg->ival != 0; 709 bool res = cfg->ival != 0;
837 bool orig = res;
838 rb->set_bool(cfg->name, &res); 710 rb->set_bool(cfg->name, &res);
839 711
840 /* seems to reset backdrop */ 712 /* seems to reset backdrop */
841 rb->lcd_set_backdrop(NULL); 713 rb->lcd_set_backdrop(NULL);
842 714
843 cfg->ival = res; 715 cfg->ival = res;
844 if(cfg->ival != orig)
845 rc |= CONFIGMENU_SUCCESS;
846 break; 716 break;
847 } 717 }
848 case C_CHOICES: 718 case C_CHOICES:
849 { 719 {
850 int old = cfg->ival;
851 int sel = list_choose(cfg->sval, cfg->name); 720 int sel = list_choose(cfg->sval, cfg->name);
852 if(sel >= 0) 721 if(sel >= 0)
853 {
854 cfg->ival = sel; 722 cfg->ival = sel;
855 }
856 if(cfg->ival != old)
857 rc |= CONFIGMENU_SUCCESS;
858 break; 723 break;
859 } 724 }
860 default: 725 default:
861 fatal("bad type"); 726 fatal("bad type");
862 break; 727 break;
863 } 728 }
864 return rc; 729 return false;
865} 730}
866 731
867const char *config_formatter(int sel, void *data, char *buf, size_t len) 732const char *config_formatter(int sel, void *data, char *buf, size_t len)
@@ -872,13 +737,11 @@ const char *config_formatter(int sel, void *data, char *buf, size_t len)
872 return buf; 737 return buf;
873} 738}
874 739
875static bool config_menu(void) 740static void config_menu(void)
876{ 741{
877 char *title; 742 char *title;
878 config_item *config = midend_get_config(me, CFG_SETTINGS, &title); 743 config_item *config = midend_get_config(me, CFG_SETTINGS, &title);
879 744
880 bool success = false;
881
882 if(!config) 745 if(!config)
883 { 746 {
884 rb->splash(HZ, "Nothing to configure."); 747 rb->splash(HZ, "Nothing to configure.");
@@ -922,13 +785,13 @@ static bool config_menu(void)
922 char *old_str; 785 char *old_str;
923 if(old.type == C_STRING) 786 if(old.type == C_STRING)
924 old_str = dupstr(old.sval); 787 old_str = dupstr(old.sval);
925 int rc = do_configure_item(config + pos); 788 bool freed_str = do_configure_item(config + pos);
926 char *err = midend_set_config(me, CFG_SETTINGS, config); 789 char *err = midend_set_config(me, CFG_SETTINGS, config);
927 if(err) 790 if(err)
928 { 791 {
929 rb->splash(HZ, err); 792 rb->splash(HZ, err);
930 memcpy(config + pos, &old, sizeof(old)); 793 memcpy(config + pos, &old, sizeof(old));
931 if(rc & CONFIGMENU_FREEDSTR) 794 if(freed_str)
932 config[pos].sval = old_str; 795 config[pos].sval = old_str;
933 } 796 }
934 else if(old.type == C_STRING) 797 else if(old.type == C_STRING)
@@ -936,10 +799,6 @@ static bool config_menu(void)
936 /* success, and we duplicated the old string, so free it */ 799 /* success, and we duplicated the old string, so free it */
937 sfree(old_str); 800 sfree(old_str);
938 } 801 }
939 if(!err && (rc & CONFIGMENU_SUCCESS))
940 {
941 success = true;
942 }
943 break; 802 break;
944 } 803 }
945 case ACTION_STD_PREV: 804 case ACTION_STD_PREV:
@@ -954,7 +813,6 @@ static bool config_menu(void)
954done: 813done:
955 sfree(title); 814 sfree(title);
956 free_cfg(config); 815 free_cfg(config);
957 return success;
958} 816}
959 817
960const char *preset_formatter(int sel, void *data, char *buf, size_t len) 818const char *preset_formatter(int sel, void *data, char *buf, size_t len)
@@ -966,12 +824,12 @@ const char *preset_formatter(int sel, void *data, char *buf, size_t len)
966 return buf; 824 return buf;
967} 825}
968 826
969static bool presets_menu(void) 827static void presets_menu(void)
970{ 828{
971 if(!midend_num_presets(me)) 829 if(!midend_num_presets(me))
972 { 830 {
973 rb->splash(HZ, "No presets!"); 831 rb->splash(HZ, "No presets!");
974 return false; 832 return;
975 } 833 }
976 834
977 /* display a list */ 835 /* display a list */
@@ -985,8 +843,9 @@ static bool presets_menu(void)
985 int current = midend_which_preset(me); 843 int current = midend_which_preset(me);
986 rb->gui_synclist_select_item(&list, current >= 0 ? current : 0); 844 rb->gui_synclist_select_item(&list, current >= 0 ? current : 0);
987 845
846 bool done = false;
988 rb->gui_synclist_set_title(&list, "Game Type", NOICON); 847 rb->gui_synclist_set_title(&list, "Game Type", NOICON);
989 while(1) 848 while (!done)
990 { 849 {
991 rb->gui_synclist_draw(&list); 850 rb->gui_synclist_draw(&list);
992 int button = rb->get_action(CONTEXT_LIST, TIMEOUT_BLOCK); 851 int button = rb->get_action(CONTEXT_LIST, TIMEOUT_BLOCK);
@@ -1001,11 +860,13 @@ static bool presets_menu(void)
1001 game_params *params; 860 game_params *params;
1002 midend_fetch_preset(me, sel, &junk, &params); 861 midend_fetch_preset(me, sel, &junk, &params);
1003 midend_set_params(me, params); 862 midend_set_params(me, params);
1004 return true; 863 done = true;
864 break;
1005 } 865 }
1006 case ACTION_STD_PREV: 866 case ACTION_STD_PREV:
1007 case ACTION_STD_CANCEL: 867 case ACTION_STD_CANCEL:
1008 return false; 868 done = true;
869 break;
1009 default: 870 default:
1010 break; 871 break;
1011 } 872 }
@@ -1087,37 +948,6 @@ static void init_default_settings(void)
1087 settings.slowmo_factor = 1; 948 settings.slowmo_factor = 1;
1088 settings.bulk = false; 949 settings.bulk = false;
1089 settings.timerflash = false; 950 settings.timerflash = false;
1090 settings.clipoff = false;
1091 settings.shortcuts = false;
1092 settings.no_aa = false;
1093}
1094
1095static void bench_aa(void)
1096{
1097 rb->sleep(0);
1098#ifdef HAVE_ADJUSTABLE_CPU_FREQ
1099 rb->cpu_boost(true);
1100#endif
1101 int next = *rb->current_tick + HZ;
1102 int i = 0;
1103 while(*rb->current_tick < next)
1104 {
1105 draw_antialiased_line(0, 0, 20, 31);
1106 ++i;
1107 }
1108 rb->splashf(HZ, "%d AA lines/sec", i);
1109 next = *rb->current_tick + HZ;
1110 int j = 0;
1111 while(*rb->current_tick < next)
1112 {
1113 rb->lcd_drawline(0, 0, 20, 31);
1114 ++j;
1115 }
1116 rb->splashf(HZ, "%d normal lines/sec", j);
1117 rb->splashf(HZ, "Efficiency: %d%%", 100 * i / j);
1118#ifdef HAVE_ADJUSTABLE_CPU_FREQ
1119 rb->cpu_boost(false);
1120#endif
1121} 951}
1122 952
1123static void debug_menu(void) 953static void debug_menu(void)
@@ -1128,9 +958,6 @@ static void debug_menu(void)
1128 "Toggle bulk update", 958 "Toggle bulk update",
1129 "Toggle flash pixel on timer", 959 "Toggle flash pixel on timer",
1130 "Toggle clip", 960 "Toggle clip",
1131 "Toggle shortcuts",
1132 "Toggle antialias",
1133 "Benchmark antialias",
1134 "Back"); 961 "Back");
1135 bool quit = false; 962 bool quit = false;
1136 int sel = 0; 963 int sel = 0;
@@ -1161,15 +988,6 @@ static void debug_menu(void)
1161 settings.clipoff = !settings.clipoff; 988 settings.clipoff = !settings.clipoff;
1162 break; 989 break;
1163 case 5: 990 case 5:
1164 settings.shortcuts = !settings.shortcuts;
1165 break;
1166 case 6:
1167 settings.no_aa = !settings.no_aa;
1168 break;
1169 case 7:
1170 bench_aa();
1171 break;
1172 case 8:
1173 default: 991 default:
1174 quit = true; 992 quit = true;
1175 break; 993 break;
@@ -1237,23 +1055,6 @@ static int pausemenu_cb(int action, const struct menu_item_ex *this_item)
1237 return action; 1055 return action;
1238} 1056}
1239 1057
1240static void clear_and_draw(void)
1241{
1242 rb->lcd_clear_display();
1243 rb->lcd_update();
1244
1245 midend_force_redraw(me);
1246 draw_title();
1247}
1248
1249static void reset_drawing(void)
1250{
1251 rb->lcd_set_viewport(NULL);
1252 rb->lcd_set_backdrop(NULL);
1253 rb->lcd_set_foreground(LCD_BLACK);
1254 rb->lcd_set_background(BG_COLOR);
1255}
1256
1257static int pause_menu(void) 1058static int pause_menu(void)
1258{ 1059{
1259#define static auto 1060#define static auto
@@ -1338,27 +1139,19 @@ static int pause_menu(void)
1338 playback_control(NULL); 1139 playback_control(NULL);
1339 break; 1140 break;
1340 case 9: 1141 case 9:
1341 if(presets_menu()) 1142 presets_menu();
1342 { 1143 midend_new_game(me);
1343 midend_new_game(me); 1144 fix_size();
1344 fix_size(); 1145 quit = true;
1345 reset_drawing();
1346 clear_and_draw();
1347 quit = true;
1348 }
1349 break; 1146 break;
1350 case 10: 1147 case 10:
1351 debug_menu(); 1148 debug_menu();
1352 break; 1149 break;
1353 case 11: 1150 case 11:
1354 if(config_menu()) 1151 config_menu();
1355 { 1152 midend_new_game(me);
1356 midend_new_game(me); 1153 fix_size();
1357 fix_size(); 1154 quit = true;
1358 reset_drawing();
1359 clear_and_draw();
1360 quit = true;
1361 }
1362 break; 1155 break;
1363#ifdef COMBINED 1156#ifdef COMBINED
1364 case 12: 1157 case 12:
@@ -1464,8 +1257,8 @@ static int process_input(int tmo)
1464 } 1257 }
1465 LOGF("accepting event 0x%08x", button); 1258 LOGF("accepting event 0x%08x", button);
1466 } 1259 }
1467 /* default is to ignore repeats except for untangle */ 1260 /* not inertia: events fire on presses */
1468 else if(strcmp("Untangle", midend_which_game(me)->name)) 1261 else
1469 { 1262 {
1470 /* start accepting input again after a release */ 1263 /* start accepting input again after a release */
1471 if(!button) 1264 if(!button)
@@ -1474,7 +1267,6 @@ static int process_input(int tmo)
1474 return 0; 1267 return 0;
1475 } 1268 }
1476 /* ignore repeats */ 1269 /* ignore repeats */
1477 /* Untangle gets special treatment */
1478 if(!accept_input) 1270 if(!accept_input)
1479 return 0; 1271 return 0;
1480 accept_input = false; 1272 accept_input = false;
@@ -1524,34 +1316,7 @@ static int process_input(int tmo)
1524 case BTN_FIRE: 1316 case BTN_FIRE:
1525 state = CURSOR_SELECT; 1317 state = CURSOR_SELECT;
1526 break; 1318 break;
1527
1528 default:
1529 break;
1530 }
1531
1532 if(settings.shortcuts)
1533 {
1534 static bool shortcuts_ok = true;
1535 switch(button)
1536 {
1537 case BTN_LEFT | BTN_FIRE:
1538 if(shortcuts_ok)
1539 midend_process_key(me, 0, 0, 'u');
1540 shortcuts_ok = false;
1541 break;
1542 case BTN_RIGHT | BTN_FIRE:
1543 if(shortcuts_ok)
1544 midend_process_key(me, 0, 0, 'r');
1545 shortcuts_ok = false;
1546 break;
1547 case 0:
1548 shortcuts_ok = true;
1549 break;
1550 default:
1551 break;
1552 }
1553 } 1319 }
1554
1555 LOGF("process_input done"); 1320 LOGF("process_input done");
1556 LOGF("------------------"); 1321 LOGF("------------------");
1557 return state; 1322 return state;
@@ -1638,23 +1403,13 @@ static void write_wrapper(void *ptr, void *buf, int len)
1638 rb->write(fd, buf, len); 1403 rb->write(fd, buf, len);
1639} 1404}
1640 1405
1641static void init_colors(void) 1406static void clear_and_draw(void)
1642{ 1407{
1643 float *floatcolors = midend_colors(me, &ncolors); 1408 rb->lcd_clear_display();
1409 rb->lcd_update();
1644 1410
1645 /* convert them to packed RGB */ 1411 midend_force_redraw(me);
1646 colors = smalloc(ncolors * sizeof(unsigned)); 1412 draw_title();
1647 unsigned *ptr = colors;
1648 float *floatptr = floatcolors;
1649 for(int i = 0; i < ncolors; ++i)
1650 {
1651 int r = 255 * *(floatptr++);
1652 int g = 255 * *(floatptr++);
1653 int b = 255 * *(floatptr++);
1654 LOGF("color %d is %d %d %d", i, r, g, b);
1655 *ptr++ = LCD_RGBPACK(r, g, b);
1656 }
1657 sfree(floatcolors);
1658} 1413}
1659 1414
1660static char *init_for_game(const game *gm, int load_fd, bool draw) 1415static char *init_for_game(const game *gm, int load_fd, bool draw)
@@ -1676,9 +1431,26 @@ static char *init_for_game(const game *gm, int load_fd, bool draw)
1676 1431
1677 fix_size(); 1432 fix_size();
1678 1433
1679 init_colors(); 1434 float *floatcolors = midend_colors(me, &ncolors);
1435
1436 /* convert them to packed RGB */
1437 colors = smalloc(ncolors * sizeof(unsigned));
1438 unsigned *ptr = colors;
1439 float *floatptr = floatcolors;
1440 for(int i = 0; i < ncolors; ++i)
1441 {
1442 int r = 255 * *(floatptr++);
1443 int g = 255 * *(floatptr++);
1444 int b = 255 * *(floatptr++);
1445 LOGF("color %d is %d %d %d", i, r, g, b);
1446 *ptr++ = LCD_RGBPACK(r, g, b);
1447 }
1448 sfree(floatcolors);
1680 1449
1681 reset_drawing(); 1450 rb->lcd_set_viewport(NULL);
1451 rb->lcd_set_backdrop(NULL);
1452 rb->lcd_set_foreground(LCD_BLACK);
1453 rb->lcd_set_background(BG_COLOR);
1682 1454
1683 if(draw) 1455 if(draw)
1684 { 1456 {
@@ -1918,26 +1690,22 @@ enum plugin_status plugin_start(const void *param)
1918 playback_control(NULL); 1690 playback_control(NULL);
1919 break; 1691 break;
1920 case 5: 1692 case 5:
1921 if(presets_menu()) 1693 presets_menu();
1694 if(!load_success)
1922 { 1695 {
1923 midend_new_game(me);
1924 fix_size();
1925 init_colors();
1926 reset_drawing();
1927 clear_and_draw(); 1696 clear_and_draw();
1928 goto game_loop; 1697 goto game_loop;
1929 } 1698 }
1699 quit = true;
1930 break; 1700 break;
1931 case 6: 1701 case 6:
1932 if(config_menu()) 1702 config_menu();
1703 if(!load_success)
1933 { 1704 {
1934 midend_new_game(me);
1935 fix_size();
1936 init_colors();
1937 reset_drawing();
1938 clear_and_draw(); 1705 clear_and_draw();
1939 goto game_loop; 1706 goto game_loop;
1940 } 1707 }
1708 quit = true;
1941 break; 1709 break;
1942 case 8: 1710 case 8:
1943 if(load_success) 1711 if(load_success)
diff --git a/apps/plugins/puzzles/untangle.c b/apps/plugins/puzzles/untangle.c
index d46afcbe66..839013809b 100644
--- a/apps/plugins/puzzles/untangle.c
+++ b/apps/plugins/puzzles/untangle.c
@@ -1162,17 +1162,18 @@ static char *interpret_move(const game_state *state, game_ui *ui,
1162 { 1162 {
1163 if(ui->dragpoint < 0) 1163 if(ui->dragpoint < 0)
1164 { 1164 {
1165 if(ui->cursorpoint < 0)
1166 {
1167 ui->cursorpoint = 0;
1168 return "";
1169 }
1170
1165 /* We're selecting a point here. */ 1171 /* We're selecting a point here. */
1166 /* Search all the points and find the closest one (2-D) in 1172 /* Search all the points and find the closest one (2-D) in
1167 * the given direction. */ 1173 * the given direction. */
1168 int i, best; 1174 int i, best;
1169 long bestd; 1175 long bestd;
1170 1176
1171 if(ui->cursorpoint < 0)
1172 {
1173 ui->cursorpoint = 0;
1174 }
1175
1176 /* 1177 /*
1177 * Begin drag. We drag the vertex _nearest_ to the pointer, 1178 * Begin drag. We drag the vertex _nearest_ to the pointer,
1178 * just in case one is nearly on top of another and we want 1179 * just in case one is nearly on top of another and we want
@@ -1195,7 +1196,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
1195 /* Figure out if this point falls into a 90 degree 1196 /* Figure out if this point falls into a 90 degree
1196 * range extending from the current point */ 1197 * range extending from the current point */
1197 1198
1198 float angle = atan2(-dy, dx); /* negate y to adjust for raster coordinates */ 1199 float angle = atan2(-dy, dx); /* adjust for raster coordinates */
1199 1200
1200 /* offset to [0..2*PI] */ 1201 /* offset to [0..2*PI] */
1201 if(angle < 0) 1202 if(angle < 0)
@@ -1493,8 +1494,6 @@ static void game_redraw(drawing *dr, game_drawstate *ds,
1493 ds->bg = bg; 1494 ds->bg = bg;
1494 1495
1495 game_compute_size(&state->params, ds->tilesize, &w, &h); 1496 game_compute_size(&state->params, ds->tilesize, &w, &h);
1496
1497 clip(dr, 0, 0, w, h);
1498 draw_rect(dr, 0, 0, w, h, bg); 1497 draw_rect(dr, 0, 0, w, h, bg);
1499 1498
1500 /* 1499 /*