From 09aa8de52cb962f1ceebfb1fd44f2c54a924fc5c Mon Sep 17 00:00:00 2001 From: Franklin Wei Date: Mon, 22 Jul 2024 21:43:25 -0400 Subject: puzzles: resync with upstream This brings the puzzles source in sync with Simon's branch, commit fd304c5 (from March 2024), with some added Rockbox-specific compatibility changes: https://www.franklinwei.com/git/puzzles/commit/?h=rockbox-devel&id=516830d9d76bdfe64fe5ccf2a9b59c33f5c7c078 There are quite a lot of backend changes, including a new "Mosaic" puzzle. In addition, some new frontend changes were necessary: - New "Preferences" menu to access the user preferences system. - Enabled spacebar input for several games. Change-Id: I94c7df674089c92f32d5f07025f6a1059068af1e --- apps/plugins/puzzles/src/rect.c | 82 ++++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 38 deletions(-) (limited to 'apps/plugins/puzzles/src/rect.c') diff --git a/apps/plugins/puzzles/src/rect.c b/apps/plugins/puzzles/src/rect.c index b13de75fd4..c3ee1ab478 100644 --- a/apps/plugins/puzzles/src/rect.c +++ b/apps/plugins/puzzles/src/rect.c @@ -26,7 +26,11 @@ #include #include #include -#include +#ifdef NO_TGMATH_H +# include +#else +# include +#endif #include "puzzles.h" @@ -163,10 +167,7 @@ static char *encode_params(const game_params *params, bool full) sprintf(data, "%dx%d", params->w, params->h); if (full && params->expandfactor) - { - sprintf(data + strlen(data), "e"); - ftoa(data + strlen(data), params->expandfactor); - } + sprintf(data + strlen(data), "e%g", params->expandfactor); if (full && !params->unique) strcat(data, "a"); @@ -192,7 +193,7 @@ static config_item *game_configure(const game_params *params) ret[2].name = "Expansion factor"; ret[2].type = C_STRING; - ftoa(buf, params->expandfactor); + sprintf(buf, "%g", params->expandfactor); ret[2].u.string.sval = dupstr(buf); ret[3].name = "Ensure unique solution"; @@ -221,6 +222,8 @@ static const char *validate_params(const game_params *params, bool full) { if (params->w <= 0 || params->h <= 0) return "Width and height must both be greater than zero"; + if (params->w > INT_MAX / params->h) + return "Width times height must not be unreasonably large"; if (params->w*params->h < 2) return "Grid area must be greater than one"; if (params->expandfactor < 0.0F) @@ -2207,7 +2210,7 @@ static game_ui *new_ui(const game_state *state) reset_ui(ui); ui->erasing = false; ui->cur_x = ui->cur_y = 0; - ui->cur_visible = false; + ui->cur_visible = getenv_bool("PUZZLES_SHOW_CURSOR", false); ui->cur_dragging = false; return ui; } @@ -2217,15 +2220,6 @@ static void free_ui(game_ui *ui) sfree(ui); } -static char *encode_ui(const game_ui *ui) -{ - return NULL; -} - -static void decode_ui(game_ui *ui, const char *encoding) -{ -} - static void coord_round(float x, float y, int *xr, int *yr) { float xs, ys, xv, yv, dx, dy, dist; @@ -2377,6 +2371,21 @@ struct game_drawstate { unsigned long *visible; }; +static const char *current_key_label(const game_ui *ui, + const game_state *state, int button) +{ + if (IS_CURSOR_SELECT(button) && ui->cur_visible && + !(ui->drag_start_x >= 0 && !ui->cur_dragging)) { + if (ui->cur_dragging) { + if (!ui->dragged) return "Cancel"; + if ((button == CURSOR_SELECT2) == ui->erasing) return "Done"; + return "Cancel"; + } + return button == CURSOR_SELECT ? "Mark" : "Erase"; + } + return ""; +} + static char *interpret_move(const game_state *from, game_ui *ui, const game_drawstate *ds, int x, int y, int button) @@ -2385,7 +2394,7 @@ static char *interpret_move(const game_state *from, game_ui *ui, bool startdrag = false, enddrag = false, active = false, erasing = false; char buf[80], *ret; - button &= ~MOD_MASK; + button = STRIP_BUTTON_MODIFIERS(button); coord_round(FROMCOORD((float)x), FROMCOORD((float)y), &xc, &yc); @@ -2406,10 +2415,11 @@ static char *interpret_move(const game_state *from, game_ui *ui, enddrag = true; erasing = (button == RIGHT_RELEASE); } else if (IS_CURSOR_MOVE(button)) { - move_cursor(button, &ui->cur_x, &ui->cur_y, from->w, from->h, false); - ui->cur_visible = true; + char *ret; + ret = move_cursor(button, &ui->cur_x, &ui->cur_y, from->w, from->h, + false, &ui->cur_visible); active = true; - if (!ui->cur_dragging) return UI_UPDATE; + if (!ui->cur_dragging || ret != MOVE_UI_UPDATE) return ret; coord_round((float)ui->cur_x + 0.5F, (float)ui->cur_y + 0.5F, &xc, &yc); } else if (IS_CURSOR_SELECT(button)) { if (ui->drag_start_x >= 0 && !ui->cur_dragging) { @@ -2422,7 +2432,7 @@ static char *interpret_move(const game_state *from, game_ui *ui, if (!ui->cur_visible) { assert(!ui->cur_dragging); ui->cur_visible = true; - return UI_UPDATE; + return MOVE_UI_UPDATE; } coord_round((float)ui->cur_x + 0.5F, (float)ui->cur_y + 0.5F, &xc, &yc); erasing = (button == CURSOR_SELECT2); @@ -2443,7 +2453,7 @@ static char *interpret_move(const game_state *from, game_ui *ui, reset_ui(ui); /* cancel keyboard dragging */ ui->cur_dragging = false; } - return UI_UPDATE; + return MOVE_UI_UPDATE; } else if (button != LEFT_DRAG && button != RIGHT_DRAG) { return NULL; } @@ -2527,7 +2537,7 @@ static char *interpret_move(const game_state *from, game_ui *ui, if (ret) return ret; /* a move has been made */ else if (active) - return UI_UPDATE; + return MOVE_UI_UPDATE; else return NULL; } @@ -2621,7 +2631,7 @@ static game_state *execute_move(const game_state *from, const char *move) #define MAX4(x,y,z,w) ( max(max(x,y),max(z,w)) ) static void game_compute_size(const game_params *params, int tilesize, - int *x, int *y) + const game_ui *ui, int *x, int *y) { /* Ick: fake up `ds->tilesize' for macro expansion purposes */ struct { int tilesize; } ads, *ds = &ads; @@ -2796,9 +2806,6 @@ static void game_redraw(drawing *dr, game_drawstate *ds, } if (!ds->started) { - draw_rect(dr, 0, 0, - state->w * TILE_SIZE + 2*BORDER + 1, - state->h * TILE_SIZE + 2*BORDER + 1, COL_BACKGROUND); draw_rect(dr, COORD(0)-1, COORD(0)-1, ds->w*TILE_SIZE+3, ds->h*TILE_SIZE+3, COL_LINE); ds->started = true; @@ -2901,24 +2908,21 @@ static int game_status(const game_state *state) return state->completed ? +1 : 0; } -static bool game_timing_state(const game_state *state, game_ui *ui) -{ - return true; -} - -static void game_print_size(const game_params *params, float *x, float *y) +static void game_print_size(const game_params *params, const game_ui *ui, + float *x, float *y) { int pw, ph; /* * I'll use 5mm squares by default. */ - game_compute_size(params, 500, &pw, &ph); + game_compute_size(params, 500, ui, &pw, &ph); *x = pw / 100.0F; *y = ph / 100.0F; } -static void game_print(drawing *dr, const game_state *state, int tilesize) +static void game_print(drawing *dr, const game_state *state, const game_ui *ui, + int tilesize) { int w = state->w, h = state->h; int ink = print_mono_colour(dr, 0); @@ -2992,12 +2996,14 @@ const struct game thegame = { free_game, true, solve_game, true, game_can_format_as_text_now, game_text_format, + NULL, NULL, /* get_prefs, set_prefs */ new_ui, free_ui, - encode_ui, - decode_ui, + NULL, /* encode_ui */ + NULL, /* decode_ui */ NULL, /* game_request_keys */ game_changed_state, + current_key_label, interpret_move, execute_move, PREFERRED_TILE_SIZE, game_compute_size, game_set_size, @@ -3011,7 +3017,7 @@ const struct game thegame = { game_status, true, false, game_print_size, game_print, true, /* wants_statusbar */ - false, game_timing_state, + false, NULL, /* timing_state */ 0, /* flags */ }; -- cgit v1.2.3