summaryrefslogtreecommitdiff
path: root/apps/plugins/puzzles/src/twiddle.c
diff options
context:
space:
mode:
authorFranklin Wei <franklin@rockbox.org>2024-07-22 21:43:25 -0400
committerFranklin Wei <franklin@rockbox.org>2024-07-22 21:44:08 -0400
commit09aa8de52cb962f1ceebfb1fd44f2c54a924fc5c (patch)
tree182bd4efb2dc8ca4fcb369d8cccab0c0f290d054 /apps/plugins/puzzles/src/twiddle.c
parentc72030f98c953a82ed6f5c7132ad000c3d5f4a16 (diff)
downloadrockbox-09aa8de52cb962f1ceebfb1fd44f2c54a924fc5c.tar.gz
rockbox-09aa8de52cb962f1ceebfb1fd44f2c54a924fc5c.zip
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
Diffstat (limited to 'apps/plugins/puzzles/src/twiddle.c')
-rw-r--r--apps/plugins/puzzles/src/twiddle.c94
1 files changed, 39 insertions, 55 deletions
diff --git a/apps/plugins/puzzles/src/twiddle.c b/apps/plugins/puzzles/src/twiddle.c
index a107925aee..b3aa06f1d5 100644
--- a/apps/plugins/puzzles/src/twiddle.c
+++ b/apps/plugins/puzzles/src/twiddle.c
@@ -10,7 +10,12 @@
10#include <string.h> 10#include <string.h>
11#include <assert.h> 11#include <assert.h>
12#include <ctype.h> 12#include <ctype.h>
13#include <math.h> 13#include <limits.h>
14#ifdef NO_TGMATH_H
15# include <math.h>
16#else
17# include <tgmath.h>
18#endif
14 19
15#include "puzzles.h" 20#include "puzzles.h"
16 21
@@ -123,14 +128,16 @@ static void decode_params(game_params *ret, char const *string)
123 while (*string) { 128 while (*string) {
124 if (*string == 'r') { 129 if (*string == 'r') {
125 ret->rowsonly = true; 130 ret->rowsonly = true;
131 string++;
126 } else if (*string == 'o') { 132 } else if (*string == 'o') {
127 ret->orientable = true; 133 ret->orientable = true;
134 string++;
128 } else if (*string == 'm') { 135 } else if (*string == 'm') {
129 string++; 136 string++;
130 ret->movetarget = atoi(string); 137 ret->movetarget = atoi(string);
131 while (string[1] && isdigit((unsigned char)string[1])) string++; 138 while (*string && isdigit((unsigned char)*string)) string++;
132 } 139 } else
133 string++; 140 string++;
134 } 141 }
135} 142}
136 143
@@ -210,6 +217,8 @@ static const char *validate_params(const game_params *params, bool full)
210 return "Width must be at least the rotating block size"; 217 return "Width must be at least the rotating block size";
211 if (params->h < params->n) 218 if (params->h < params->n)
212 return "Height must be at least the rotating block size"; 219 return "Height must be at least the rotating block size";
220 if (params->w > INT_MAX / params->h)
221 return "Width times height must not be unreasonably large";
213 if (params->movetarget < 0) 222 if (params->movetarget < 0)
214 return "Number of shuffling moves may not be negative"; 223 return "Number of shuffling moves may not be negative";
215 return NULL; 224 return NULL;
@@ -615,7 +624,7 @@ static game_ui *new_ui(const game_state *state)
615 624
616 ui->cur_x = 0; 625 ui->cur_x = 0;
617 ui->cur_y = 0; 626 ui->cur_y = 0;
618 ui->cur_visible = false; 627 ui->cur_visible = getenv_bool("PUZZLES_SHOW_CURSOR", false);
619 628
620 return ui; 629 return ui;
621} 630}
@@ -625,18 +634,20 @@ static void free_ui(game_ui *ui)
625 sfree(ui); 634 sfree(ui);
626} 635}
627 636
628static char *encode_ui(const game_ui *ui) 637static void game_changed_state(game_ui *ui, const game_state *oldstate,
629{ 638 const game_state *newstate)
630 return NULL;
631}
632
633static void decode_ui(game_ui *ui, const char *encoding)
634{ 639{
635} 640}
636 641
637static void game_changed_state(game_ui *ui, const game_state *oldstate, 642static const char *current_key_label(const game_ui *ui,
638 const game_state *newstate) 643 const game_state *state, int button)
639{ 644{
645 if (!ui->cur_visible) return "";
646 switch (button) {
647 case CURSOR_SELECT: return "Turn left";
648 case CURSOR_SELECT2: return "Turn right";
649 }
650 return "";
640} 651}
641 652
642struct game_drawstate { 653struct game_drawstate {
@@ -657,18 +668,9 @@ static char *interpret_move(const game_state *state, game_ui *ui,
657 668
658 button = button & (~MOD_MASK | MOD_NUM_KEYPAD); 669 button = button & (~MOD_MASK | MOD_NUM_KEYPAD);
659 670
660 if (IS_CURSOR_MOVE(button)) { 671 if (IS_CURSOR_MOVE(button))
661 if (button == CURSOR_LEFT && ui->cur_x > 0) 672 return move_cursor(button, &ui->cur_x, &ui->cur_y, w-n+1, h-n+1,
662 ui->cur_x--; 673 false, &ui->cur_visible);
663 if (button == CURSOR_RIGHT && (ui->cur_x+n) < (w))
664 ui->cur_x++;
665 if (button == CURSOR_UP && ui->cur_y > 0)
666 ui->cur_y--;
667 if (button == CURSOR_DOWN && (ui->cur_y+n) < (h))
668 ui->cur_y++;
669 ui->cur_visible = true;
670 return UI_UPDATE;
671 }
672 674
673 if (button == LEFT_BUTTON || button == RIGHT_BUTTON) { 675 if (button == LEFT_BUTTON || button == RIGHT_BUTTON) {
674 /* 676 /*
@@ -691,7 +693,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
691 dir = (button == CURSOR_SELECT2) ? -1 : +1; 693 dir = (button == CURSOR_SELECT2) ? -1 : +1;
692 } else { 694 } else {
693 ui->cur_visible = true; 695 ui->cur_visible = true;
694 return UI_UPDATE; 696 return MOVE_UI_UPDATE;
695 } 697 }
696 } else if (button == 'a' || button == 'A' || button==MOD_NUM_KEYPAD+'7') { 698 } else if (button == 'a' || button == 'A' || button==MOD_NUM_KEYPAD+'7') {
697 x = y = 0; 699 x = y = 0;
@@ -791,7 +793,7 @@ static game_state *execute_move(const game_state *from, const char *move)
791 */ 793 */
792 794
793static void game_compute_size(const game_params *params, int tilesize, 795static void game_compute_size(const game_params *params, int tilesize,
794 int *x, int *y) 796 const game_ui *ui, int *x, int *y)
795{ 797{
796 /* Ick: fake up `ds->tilesize' for macro expansion purposes */ 798 /* Ick: fake up `ds->tilesize' for macro expansion purposes */
797 struct { int tilesize; } ads, *ds = &ads; 799 struct { int tilesize; } ads, *ds = &ads;
@@ -870,8 +872,8 @@ static void rotate(int *xy, struct rotation *rot)
870 xf2 = rot->c * xf + rot->s * yf; 872 xf2 = rot->c * xf + rot->s * yf;
871 yf2 = - rot->s * xf + rot->c * yf; 873 yf2 = - rot->s * xf + rot->c * yf;
872 874
873 xy[0] = (int)(xf2 + rot->ox + 0.5); /* round to nearest */ 875 xy[0] = (int)(xf2 + rot->ox + 0.5F); /* round to nearest */
874 xy[1] = (int)(yf2 + rot->oy + 0.5); /* round to nearest */ 876 xy[1] = (int)(yf2 + rot->oy + 0.5F); /* round to nearest */
875 } 877 }
876} 878}
877 879
@@ -1058,7 +1060,7 @@ static int highlight_colour(float angle)
1058 COL_LOWLIGHT, 1060 COL_LOWLIGHT,
1059 }; 1061 };
1060 1062
1061 return colours[(int)((angle + 2*PI) / (PI/16)) & 31]; 1063 return colours[(int)((angle + 2*(float)PI) / ((float)PI/16)) & 31];
1062} 1064}
1063 1065
1064static float game_anim_length_real(const game_state *oldstate, 1066static float game_anim_length_real(const game_state *oldstate,
@@ -1135,13 +1137,6 @@ static void game_redraw(drawing *dr, game_drawstate *ds,
1135 if (!ds->started) { 1137 if (!ds->started) {
1136 int coords[10]; 1138 int coords[10];
1137 1139
1138 draw_rect(dr, 0, 0,
1139 TILE_SIZE * state->w + 2 * BORDER,
1140 TILE_SIZE * state->h + 2 * BORDER, COL_BACKGROUND);
1141 draw_update(dr, 0, 0,
1142 TILE_SIZE * state->w + 2 * BORDER,
1143 TILE_SIZE * state->h + 2 * BORDER);
1144
1145 /* 1140 /*
1146 * Recessed area containing the whole puzzle. 1141 * Recessed area containing the whole puzzle.
1147 */ 1142 */
@@ -1189,7 +1184,7 @@ static void game_redraw(drawing *dr, game_drawstate *ds,
1189 rot->cw = rot->ch = TILE_SIZE * state->n; 1184 rot->cw = rot->ch = TILE_SIZE * state->n;
1190 rot->ox = rot->cx + rot->cw/2; 1185 rot->ox = rot->cx + rot->cw/2;
1191 rot->oy = rot->cy + rot->ch/2; 1186 rot->oy = rot->cy + rot->ch/2;
1192 angle = (float)((-PI/2 * lastr) * (1.0 - animtime / anim_max)); 1187 angle = ((-(float)PI/2 * lastr) * (1.0F - animtime / anim_max));
1193 rot->c = (float)cos(angle); 1188 rot->c = (float)cos(angle);
1194 rot->s = (float)sin(angle); 1189 rot->s = (float)sin(angle);
1195 1190
@@ -1282,19 +1277,6 @@ static void game_redraw(drawing *dr, game_drawstate *ds,
1282 } 1277 }
1283} 1278}
1284 1279
1285static bool game_timing_state(const game_state *state, game_ui *ui)
1286{
1287 return true;
1288}
1289
1290static void game_print_size(const game_params *params, float *x, float *y)
1291{
1292}
1293
1294static void game_print(drawing *dr, const game_state *state, int tilesize)
1295{
1296}
1297
1298#ifdef COMBINED 1280#ifdef COMBINED
1299#define thegame twiddle 1281#define thegame twiddle
1300#endif 1282#endif
@@ -1316,12 +1298,14 @@ const struct game thegame = {
1316 free_game, 1298 free_game,
1317 true, solve_game, 1299 true, solve_game,
1318 true, game_can_format_as_text_now, game_text_format, 1300 true, game_can_format_as_text_now, game_text_format,
1301 NULL, NULL, /* get_prefs, set_prefs */
1319 new_ui, 1302 new_ui,
1320 free_ui, 1303 free_ui,
1321 encode_ui, 1304 NULL, /* encode_ui */
1322 decode_ui, 1305 NULL, /* decode_ui */
1323 NULL, /* game_request_keys */ 1306 NULL, /* game_request_keys */
1324 game_changed_state, 1307 game_changed_state,
1308 current_key_label,
1325 interpret_move, 1309 interpret_move,
1326 execute_move, 1310 execute_move,
1327 PREFERRED_TILE_SIZE, game_compute_size, game_set_size, 1311 PREFERRED_TILE_SIZE, game_compute_size, game_set_size,
@@ -1333,9 +1317,9 @@ const struct game thegame = {
1333 game_flash_length, 1317 game_flash_length,
1334 game_get_cursor_location, 1318 game_get_cursor_location,
1335 game_status, 1319 game_status,
1336 false, false, game_print_size, game_print, 1320 false, false, NULL, NULL, /* print_size, print */
1337 true, /* wants_statusbar */ 1321 true, /* wants_statusbar */
1338 false, game_timing_state, 1322 false, NULL, /* timing_state */
1339 0, /* flags */ 1323 0, /* flags */
1340}; 1324};
1341 1325