diff options
Diffstat (limited to 'apps/plugins/puzzles/src/flip.c')
-rw-r--r-- | apps/plugins/puzzles/src/flip.c | 89 |
1 files changed, 36 insertions, 53 deletions
diff --git a/apps/plugins/puzzles/src/flip.c b/apps/plugins/puzzles/src/flip.c index 5d4f2250aa..044d6c30c3 100644 --- a/apps/plugins/puzzles/src/flip.c +++ b/apps/plugins/puzzles/src/flip.c | |||
@@ -8,7 +8,12 @@ | |||
8 | #include <string.h> | 8 | #include <string.h> |
9 | #include <assert.h> | 9 | #include <assert.h> |
10 | #include <ctype.h> | 10 | #include <ctype.h> |
11 | #include <math.h> | 11 | #include <limits.h> |
12 | #ifdef NO_TGMATH_H | ||
13 | # include <math.h> | ||
14 | #else | ||
15 | # include <tgmath.h> | ||
16 | #endif | ||
12 | 17 | ||
13 | #include "puzzles.h" | 18 | #include "puzzles.h" |
14 | #include "tree234.h" | 19 | #include "tree234.h" |
@@ -181,9 +186,16 @@ static game_params *custom_params(const config_item *cfg) | |||
181 | 186 | ||
182 | static const char *validate_params(const game_params *params, bool full) | 187 | static const char *validate_params(const game_params *params, bool full) |
183 | { | 188 | { |
189 | int wh; | ||
190 | |||
184 | if (params->w <= 0 || params->h <= 0) | 191 | if (params->w <= 0 || params->h <= 0) |
185 | return "Width and height must both be greater than zero"; | 192 | return "Width and height must both be greater than zero"; |
186 | return NULL; | 193 | if (params->w > (INT_MAX - 3) / params->h) |
194 | return "Width times height must not be unreasonably large"; | ||
195 | wh = params->w * params->h; | ||
196 | if (wh > (INT_MAX - 3) / wh) | ||
197 | return "Width times height is too large"; | ||
198 | return NULL; | ||
187 | } | 199 | } |
188 | 200 | ||
189 | static char *encode_bitmap(unsigned char *bmp, int len) | 201 | static char *encode_bitmap(unsigned char *bmp, int len) |
@@ -905,7 +917,7 @@ static game_ui *new_ui(const game_state *state) | |||
905 | { | 917 | { |
906 | game_ui *ui = snew(game_ui); | 918 | game_ui *ui = snew(game_ui); |
907 | ui->cx = ui->cy = 0; | 919 | ui->cx = ui->cy = 0; |
908 | ui->cdraw = false; | 920 | ui->cdraw = getenv_bool("PUZZLES_SHOW_CURSOR", false); |
909 | return ui; | 921 | return ui; |
910 | } | 922 | } |
911 | 923 | ||
@@ -914,18 +926,16 @@ static void free_ui(game_ui *ui) | |||
914 | sfree(ui); | 926 | sfree(ui); |
915 | } | 927 | } |
916 | 928 | ||
917 | static char *encode_ui(const game_ui *ui) | 929 | static void game_changed_state(game_ui *ui, const game_state *oldstate, |
918 | { | 930 | const game_state *newstate) |
919 | return NULL; | ||
920 | } | ||
921 | |||
922 | static void decode_ui(game_ui *ui, const char *encoding) | ||
923 | { | 931 | { |
924 | } | 932 | } |
925 | 933 | ||
926 | static void game_changed_state(game_ui *ui, const game_state *oldstate, | 934 | static const char *current_key_label(const game_ui *ui, |
927 | const game_state *newstate) | 935 | const game_state *state, int button) |
928 | { | 936 | { |
937 | if (IS_CURSOR_SELECT(button)) return "Flip"; | ||
938 | return ""; | ||
929 | } | 939 | } |
930 | 940 | ||
931 | struct game_drawstate { | 941 | struct game_drawstate { |
@@ -940,7 +950,7 @@ static char *interpret_move(const game_state *state, game_ui *ui, | |||
940 | int x, int y, int button) | 950 | int x, int y, int button) |
941 | { | 951 | { |
942 | int w = state->w, h = state->h, wh = w * h; | 952 | int w = state->w, h = state->h, wh = w * h; |
943 | char buf[80], *nullret = NULL; | 953 | char buf[80], *nullret = MOVE_UNUSED; |
944 | 954 | ||
945 | if (button == LEFT_BUTTON || IS_CURSOR_SELECT(button)) { | 955 | if (button == LEFT_BUTTON || IS_CURSOR_SELECT(button)) { |
946 | int tx, ty; | 956 | int tx, ty; |
@@ -951,7 +961,7 @@ static char *interpret_move(const game_state *state, game_ui *ui, | |||
951 | tx = ui->cx; ty = ui->cy; | 961 | tx = ui->cx; ty = ui->cy; |
952 | ui->cdraw = true; | 962 | ui->cdraw = true; |
953 | } | 963 | } |
954 | nullret = UI_UPDATE; | 964 | nullret = MOVE_UI_UPDATE; |
955 | 965 | ||
956 | if (tx >= 0 && tx < w && ty >= 0 && ty < h) { | 966 | if (tx >= 0 && tx < w && ty >= 0 && ty < h) { |
957 | /* | 967 | /* |
@@ -969,25 +979,12 @@ static char *interpret_move(const game_state *state, game_ui *ui, | |||
969 | sprintf(buf, "M%d,%d", tx, ty); | 979 | sprintf(buf, "M%d,%d", tx, ty); |
970 | return dupstr(buf); | 980 | return dupstr(buf); |
971 | } else { | 981 | } else { |
972 | return NULL; | 982 | return MOVE_NO_EFFECT; |
973 | } | 983 | } |
974 | } | 984 | } |
975 | } | 985 | } else if (IS_CURSOR_MOVE(button)) |
976 | else if (IS_CURSOR_MOVE(button)) { | 986 | nullret = move_cursor(button, &ui->cx, &ui->cy, state->w, state->h, |
977 | int dx = 0, dy = 0; | 987 | false, &ui->cdraw); |
978 | switch (button) { | ||
979 | case CURSOR_UP: dy = -1; break; | ||
980 | case CURSOR_DOWN: dy = 1; break; | ||
981 | case CURSOR_RIGHT: dx = 1; break; | ||
982 | case CURSOR_LEFT: dx = -1; break; | ||
983 | default: assert(!"shouldn't get here"); | ||
984 | } | ||
985 | ui->cx += dx; ui->cy += dy; | ||
986 | ui->cx = min(max(ui->cx, 0), state->w - 1); | ||
987 | ui->cy = min(max(ui->cy, 0), state->h - 1); | ||
988 | ui->cdraw = true; | ||
989 | nullret = UI_UPDATE; | ||
990 | } | ||
991 | 988 | ||
992 | return nullret; | 989 | return nullret; |
993 | } | 990 | } |
@@ -1045,7 +1042,7 @@ static game_state *execute_move(const game_state *from, const char *move) | |||
1045 | */ | 1042 | */ |
1046 | 1043 | ||
1047 | static void game_compute_size(const game_params *params, int tilesize, | 1044 | static void game_compute_size(const game_params *params, int tilesize, |
1048 | int *x, int *y) | 1045 | const game_ui *ui, int *x, int *y) |
1049 | { | 1046 | { |
1050 | /* Ick: fake up `ds->tilesize' for macro expansion purposes */ | 1047 | /* Ick: fake up `ds->tilesize' for macro expansion purposes */ |
1051 | struct { int tilesize; } ads, *ds = &ads; | 1048 | struct { int tilesize; } ads, *ds = &ads; |
@@ -1145,7 +1142,7 @@ static void draw_tile(drawing *dr, game_drawstate *ds, const game_state *state, | |||
1145 | coords[7] = by + TILE_SIZE - (int)((float)TILE_SIZE * animtime); | 1142 | coords[7] = by + TILE_SIZE - (int)((float)TILE_SIZE * animtime); |
1146 | 1143 | ||
1147 | colour = (tile & 1 ? COL_WRONG : COL_RIGHT); | 1144 | colour = (tile & 1 ? COL_WRONG : COL_RIGHT); |
1148 | if (animtime < 0.5) | 1145 | if (animtime < 0.5F) |
1149 | colour = COL_WRONG + COL_RIGHT - colour; | 1146 | colour = COL_WRONG + COL_RIGHT - colour; |
1150 | 1147 | ||
1151 | draw_polygon(dr, coords, 4, colour, COL_GRID); | 1148 | draw_polygon(dr, coords, 4, colour, COL_GRID); |
@@ -1159,7 +1156,7 @@ static void draw_tile(drawing *dr, game_drawstate *ds, const game_state *state, | |||
1159 | for (j = 0; j < w; j++) | 1156 | for (j = 0; j < w; j++) |
1160 | if (state->matrix->matrix[(y*w+x)*wh + i*w+j]) { | 1157 | if (state->matrix->matrix[(y*w+x)*wh + i*w+j]) { |
1161 | int ox = j - x, oy = i - y; | 1158 | int ox = j - x, oy = i - y; |
1162 | int td = TILE_SIZE / 16; | 1159 | int td = TILE_SIZE / 16 ? TILE_SIZE / 16 : 1; |
1163 | int cx = (bx + TILE_SIZE/2) + (2 * ox - 1) * td; | 1160 | int cx = (bx + TILE_SIZE/2) + (2 * ox - 1) * td; |
1164 | int cy = (by + TILE_SIZE/2) + (2 * oy - 1) * td; | 1161 | int cy = (by + TILE_SIZE/2) + (2 * oy - 1) * td; |
1165 | if (ox == 0 && oy == 0) | 1162 | if (ox == 0 && oy == 0) |
@@ -1202,9 +1199,6 @@ static void game_redraw(drawing *dr, game_drawstate *ds, | |||
1202 | int i, flashframe; | 1199 | int i, flashframe; |
1203 | 1200 | ||
1204 | if (!ds->started) { | 1201 | if (!ds->started) { |
1205 | draw_rect(dr, 0, 0, TILE_SIZE * w + 2 * BORDER, | ||
1206 | TILE_SIZE * h + 2 * BORDER, COL_BACKGROUND); | ||
1207 | |||
1208 | /* | 1202 | /* |
1209 | * Draw the grid lines. | 1203 | * Draw the grid lines. |
1210 | */ | 1204 | */ |
@@ -1309,19 +1303,6 @@ static int game_status(const game_state *state) | |||
1309 | return state->completed ? +1 : 0; | 1303 | return state->completed ? +1 : 0; |
1310 | } | 1304 | } |
1311 | 1305 | ||
1312 | static bool game_timing_state(const game_state *state, game_ui *ui) | ||
1313 | { | ||
1314 | return true; | ||
1315 | } | ||
1316 | |||
1317 | static void game_print_size(const game_params *params, float *x, float *y) | ||
1318 | { | ||
1319 | } | ||
1320 | |||
1321 | static void game_print(drawing *dr, const game_state *state, int tilesize) | ||
1322 | { | ||
1323 | } | ||
1324 | |||
1325 | #ifdef COMBINED | 1306 | #ifdef COMBINED |
1326 | #define thegame flip | 1307 | #define thegame flip |
1327 | #endif | 1308 | #endif |
@@ -1343,12 +1324,14 @@ const struct game thegame = { | |||
1343 | free_game, | 1324 | free_game, |
1344 | true, solve_game, | 1325 | true, solve_game, |
1345 | true, game_can_format_as_text_now, game_text_format, | 1326 | true, game_can_format_as_text_now, game_text_format, |
1327 | NULL, NULL, /* get_prefs, set_prefs */ | ||
1346 | new_ui, | 1328 | new_ui, |
1347 | free_ui, | 1329 | free_ui, |
1348 | encode_ui, | 1330 | NULL, /* encode_ui */ |
1349 | decode_ui, | 1331 | NULL, /* decode_ui */ |
1350 | NULL, /* game_request_keys */ | 1332 | NULL, /* game_request_keys */ |
1351 | game_changed_state, | 1333 | game_changed_state, |
1334 | current_key_label, | ||
1352 | interpret_move, | 1335 | interpret_move, |
1353 | execute_move, | 1336 | execute_move, |
1354 | PREFERRED_TILE_SIZE, game_compute_size, game_set_size, | 1337 | PREFERRED_TILE_SIZE, game_compute_size, game_set_size, |
@@ -1360,8 +1343,8 @@ const struct game thegame = { | |||
1360 | game_flash_length, | 1343 | game_flash_length, |
1361 | game_get_cursor_location, | 1344 | game_get_cursor_location, |
1362 | game_status, | 1345 | game_status, |
1363 | false, false, game_print_size, game_print, | 1346 | false, false, NULL, NULL, /* print_size, print */ |
1364 | true, /* wants_statusbar */ | 1347 | true, /* wants_statusbar */ |
1365 | false, game_timing_state, | 1348 | false, NULL, /* timing_state */ |
1366 | 0, /* flags */ | 1349 | 0, /* flags */ |
1367 | }; | 1350 | }; |