From 57db318a9e2de5cf9422ccf96e4f55df4840b88f Mon Sep 17 00:00:00 2001 From: Franklin Wei Date: Sat, 22 Jul 2017 11:00:47 -0400 Subject: stuff Change-Id: Ic707fb03c2472b9a0c4ea3e64eb3620c411f661c --- apps/plugins/puzzles/rockbox.c | 126 ++++++++++++++++++++++++++++++++++--- apps/plugins/puzzles/src/inertia.c | 8 +-- 2 files changed, 120 insertions(+), 14 deletions(-) (limited to 'apps/plugins') 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 { -- cgit v1.1