summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/plugins/puzzles/rockbox.c126
-rw-r--r--apps/plugins/puzzles/src/inertia.c8
2 files changed, 120 insertions, 14 deletions
diff --git a/apps/plugins/puzzles/rockbox.c b/apps/plugins/puzzles/rockbox.c
index 18194da..bac05a0 100644
--- a/apps/plugins/puzzles/rockbox.c
+++ b/apps/plugins/puzzles/rockbox.c
@@ -923,18 +923,110 @@ static int list_choose(const char *list_str, const char *title)
}
}
-/* return value is only meaningful when type == C_STRING */
-static bool do_configure_item(config_item *cfg)
+static bool is_integer(const char *str)
{
+ while(*str)
+ {
+ if(!isdigit(*str++))
+ return false;
+ }
+ return true;
+}
+
+/* max length of C_STRING config vals */
+#define MAX_STRLEN 128
+
+static void int_chooser(config_item *cfgs, int idx, int val)
+{
+ config_item *cfg = cfgs + idx;
+ int old_val = val;
+
+ rb->snprintf(cfg->sval, MAX_STRLEN, "%d", val);
+
+ rb->lcd_clear_display();
+ while(1)
+ {
+ rb->lcd_puts(0, 0, cfg->name);
+ rb->lcd_putsf(0, 1, "< %d >", val);
+ rb->lcd_update();
+
+ int d = 0;
+ int button = rb->button_get(true);
+ switch(button)
+ {
+ case BTN_RIGHT:
+ case BTN_RIGHT | BUTTON_REPEAT:
+ d = 1;
+ break;
+ case BTN_LEFT:
+ case BTN_LEFT | BUTTON_REPEAT:
+ d = -1;
+ break;
+ case BTN_FIRE:
+ /* config is already set */
+ return;
+ case BTN_PAUSE:
+ if(val != old_val)
+ rb->splash(HZ, "Canceled.");
+ val = old_val;
+ rb->snprintf(cfg->sval, MAX_STRLEN, "%d", val);
+ return;
+ }
+ if(d)
+ {
+ val += d;
+ rb->snprintf(cfg->sval, MAX_STRLEN, "%d", val);
+ char *ret = midend_set_config(me, CFG_SETTINGS, cfgs);
+
+ if(ret) /* failure */
+ {
+ /* bright, annoying red */
+ rb->lcd_set_foreground(LCD_RGBPACK(255,0,0));
+ rb->lcd_puts(0, 2, ret);
+
+ /* reset value */
+ val -= d;
+ rb->snprintf(cfg->sval, MAX_STRLEN, "%d", val);
+ assert(!midend_set_config(me, CFG_SETTINGS, cfgs));
+ rb->lcd_set_foreground(LCD_WHITE);
+ }
+ else
+ {
+ /* clear any error message */
+ rb->lcd_clear_display();
+ }
+ }
+ }
+}
+
+/* return value is only meaningful when type == C_STRING, where it
+ * indicates whether cfg->sval has been freed or otherwise altered */
+static bool do_configure_item(config_item *cfgs, int idx)
+{
+ config_item *cfg = cfgs + idx;
switch(cfg->type)
{
case C_STRING:
{
-#define MAX_STRLEN 128
char *newstr = smalloc(MAX_STRLEN);
- rb->strlcpy(newstr, cfg->sval, MAX_STRLEN);
+
rb->lcd_set_foreground(LCD_WHITE);
rb->lcd_set_background(LCD_BLACK);
+
+ if(is_integer(cfg->sval))
+ {
+ int val = atoi(cfg->sval);
+
+ /* we now free the original string and give int_chooser()
+ * a clean buffer to work with */
+ sfree(cfg->sval);
+ cfg->sval = newstr;
+
+ int_chooser(cfgs, idx, val);
+ return true;
+ }
+
+ rb->strlcpy(newstr, cfg->sval, MAX_STRLEN);
if(rb->kbd_input(newstr, MAX_STRLEN) < 0)
{
sfree(newstr);
@@ -1021,26 +1113,35 @@ static bool config_menu(void)
{
case ACTION_STD_OK:
{
- config_item old;
int pos = rb->gui_synclist_get_sel_pos(&list);
+
+ /* store the initial state */
+ config_item old;
memcpy(&old, config + pos, sizeof(old));
+
char *old_str = NULL;
if(old.type == C_STRING)
old_str = dupstr(old.sval);
- bool freed_str = do_configure_item(config + pos);
+
+ bool freed_str = do_configure_item(config, pos);
char *err = midend_set_config(me, CFG_SETTINGS, config);
+
if(err)
{
rb->splash(HZ, err);
+
+ /* restore old state */
memcpy(config + pos, &old, sizeof(old));
- if(freed_str)
+
+ if(old.type == C_STRING && freed_str)
config[pos].sval = old_str;
}
else
{
if(old.type == C_STRING)
{
- /* success, and we duplicated the old string, so free it */
+ /* success, and we duplicated the old string when
+ * we didn't need to, so free it now */
sfree(old_str);
}
success = true;
@@ -1836,7 +1937,6 @@ static bool load_game(void)
return false;
}
rb->close(fd);
- /* success, we delete the save */
rb->remove(SAVE_FILE);
return true;
}
@@ -1854,14 +1954,20 @@ static bool load_game(void)
rb->splash(HZ, ret);
sfree(ret);
rb->close(fd);
+ rb->remove(SAVE_FILE);
return false;
}
rb->close(fd);
- /* success, we delete the save */
rb->remove(SAVE_FILE);
+ /* success */
return true;
}
rb->splashf(HZ, "Cannot load save game for %s!", game);
+
+ /* clean up, even on failure */
+ rb->close(fd);
+ rb->remove(SAVE_FILE);
+
return false;
#endif
}
diff --git a/apps/plugins/puzzles/src/inertia.c b/apps/plugins/puzzles/src/inertia.c
index c22d2e1..05fba4f 100644
--- a/apps/plugins/puzzles/src/inertia.c
+++ b/apps/plugins/puzzles/src/inertia.c
@@ -1866,10 +1866,10 @@ static void draw_player(drawing *dr, game_drawstate *ds, int x, int y,
x2 = (x1+x3) / 4;
y2 = (y1+y3) / 4;
- coords[d*4+0] = x + TILESIZE/2 + (int)((TILESIZE*3/7) * x1);
- coords[d*4+1] = y + TILESIZE/2 + (int)((TILESIZE*3/7) * y1);
- coords[d*4+2] = x + TILESIZE/2 + (int)((TILESIZE*3/7) * x2);
- coords[d*4+3] = y + TILESIZE/2 + (int)((TILESIZE*3/7) * y2);
+ coords[d*4+0] = x + TILESIZE/2 + (int)((TILESIZE*3/7) * x2);
+ coords[d*4+1] = y + TILESIZE/2 + (int)((TILESIZE*3/7) * y2);
+ coords[d*4+2] = x + TILESIZE/2 + (int)((TILESIZE*3/7) * x1);
+ coords[d*4+3] = y + TILESIZE/2 + (int)((TILESIZE*3/7) * y1);
}
draw_polygon(dr, coords, DIRECTIONS*2, COL_DEAD_PLAYER, COL_OUTLINE);
} else {