diff options
Diffstat (limited to 'apps/plugins/puzzles/src')
-rw-r--r-- | apps/plugins/puzzles/src/gtk.c | 6 | ||||
-rw-r--r-- | apps/plugins/puzzles/src/map.c | 67 | ||||
-rw-r--r-- | apps/plugins/puzzles/src/solo.c | 30 |
3 files changed, 73 insertions, 30 deletions
diff --git a/apps/plugins/puzzles/src/gtk.c b/apps/plugins/puzzles/src/gtk.c index 37ba8078e2..3078e517ba 100644 --- a/apps/plugins/puzzles/src/gtk.c +++ b/apps/plugins/puzzles/src/gtk.c | |||
@@ -1397,7 +1397,9 @@ static gint configure_area(GtkWidget *widget, | |||
1397 | { | 1397 | { |
1398 | frontend *fe = (frontend *)data; | 1398 | frontend *fe = (frontend *)data; |
1399 | resize_puzzle_to_area(fe, event->width, event->height); | 1399 | resize_puzzle_to_area(fe, event->width, event->height); |
1400 | #if GTK_CHECK_VERSION(3,0,0) | ||
1400 | fe->awaiting_resize_ack = FALSE; | 1401 | fe->awaiting_resize_ack = FALSE; |
1402 | #endif | ||
1401 | return TRUE; | 1403 | return TRUE; |
1402 | } | 1404 | } |
1403 | 1405 | ||
@@ -1522,8 +1524,8 @@ static void msgbox_button_clicked(GtkButton *button, gpointer data) | |||
1522 | gtk_widget_destroy(GTK_WIDGET(data)); | 1524 | gtk_widget_destroy(GTK_WIDGET(data)); |
1523 | } | 1525 | } |
1524 | 1526 | ||
1525 | int message_box(GtkWidget *parent, char *title, char *msg, int centre, | 1527 | int message_box(GtkWidget *parent, const char *title, const char *msg, |
1526 | int type) | 1528 | int centre, int type) |
1527 | { | 1529 | { |
1528 | GtkWidget *window, *hbox, *text, *button; | 1530 | GtkWidget *window, *hbox, *text, *button; |
1529 | char *titles; | 1531 | char *titles; |
diff --git a/apps/plugins/puzzles/src/map.c b/apps/plugins/puzzles/src/map.c index cdcd5861a8..3a1633590c 100644 --- a/apps/plugins/puzzles/src/map.c +++ b/apps/plugins/puzzles/src/map.c | |||
@@ -2340,18 +2340,21 @@ struct game_drawstate { | |||
2340 | ((button) == CURSOR_UP) ? -1 : 0) | 2340 | ((button) == CURSOR_UP) ? -1 : 0) |
2341 | 2341 | ||
2342 | 2342 | ||
2343 | static int region_from_coords(const game_state *state, | 2343 | /* |
2344 | const game_drawstate *ds, int x, int y) | 2344 | * Return the map region containing a point in tile (tx,ty), offset by |
2345 | * (x_eps,y_eps) from the centre of the tile. | ||
2346 | */ | ||
2347 | static int region_from_logical_coords(const game_state *state, int tx, int ty, | ||
2348 | int x_eps, int y_eps) | ||
2345 | { | 2349 | { |
2346 | int w = state->p.w, h = state->p.h, wh = w*h /*, n = state->p.n */; | 2350 | int w = state->p.w, h = state->p.h, wh = w*h /*, n = state->p.n */; |
2347 | int tx = FROMCOORD(x), ty = FROMCOORD(y); | 2351 | |
2348 | int dx = x - COORD(tx), dy = y - COORD(ty); | ||
2349 | int quadrant; | 2352 | int quadrant; |
2350 | 2353 | ||
2351 | if (tx < 0 || tx >= w || ty < 0 || ty >= h) | 2354 | if (tx < 0 || tx >= w || ty < 0 || ty >= h) |
2352 | return -1; /* border */ | 2355 | return -1; /* border */ |
2353 | 2356 | ||
2354 | quadrant = 2 * (dx > dy) + (TILESIZE - dx > dy); | 2357 | quadrant = 2 * (x_eps > y_eps) + (-x_eps > y_eps); |
2355 | quadrant = (quadrant == 0 ? BE : | 2358 | quadrant = (quadrant == 0 ? BE : |
2356 | quadrant == 1 ? LE : | 2359 | quadrant == 1 ? LE : |
2357 | quadrant == 2 ? RE : TE); | 2360 | quadrant == 2 ? RE : TE); |
@@ -2359,12 +2362,28 @@ static int region_from_coords(const game_state *state, | |||
2359 | return state->map->map[quadrant * wh + ty*w+tx]; | 2362 | return state->map->map[quadrant * wh + ty*w+tx]; |
2360 | } | 2363 | } |
2361 | 2364 | ||
2365 | static int region_from_coords(const game_state *state, | ||
2366 | const game_drawstate *ds, int x, int y) | ||
2367 | { | ||
2368 | int tx = FROMCOORD(x), ty = FROMCOORD(y); | ||
2369 | return region_from_logical_coords( | ||
2370 | state, tx, ty, x - COORD(tx) - TILESIZE/2, y - COORD(ty) - TILESIZE/2); | ||
2371 | } | ||
2372 | |||
2373 | static int region_from_ui_cursor(const game_state *state, const game_ui *ui) | ||
2374 | { | ||
2375 | assert(ui->cur_visible); | ||
2376 | return region_from_logical_coords(state, ui->cur_x, ui->cur_y, | ||
2377 | EPSILON_X(ui->cur_lastmove), | ||
2378 | EPSILON_Y(ui->cur_lastmove)); | ||
2379 | } | ||
2380 | |||
2362 | static char *interpret_move(const game_state *state, game_ui *ui, | 2381 | static char *interpret_move(const game_state *state, game_ui *ui, |
2363 | const game_drawstate *ds, | 2382 | const game_drawstate *ds, |
2364 | int x, int y, int button) | 2383 | int x, int y, int button) |
2365 | { | 2384 | { |
2366 | char *bufp, buf[256]; | 2385 | char *bufp, buf[256]; |
2367 | int alt_button; | 2386 | int alt_button, drop_region; |
2368 | 2387 | ||
2369 | /* | 2388 | /* |
2370 | * Enable or disable numeric labels on regions. | 2389 | * Enable or disable numeric labels on regions. |
@@ -2379,19 +2398,15 @@ static char *interpret_move(const game_state *state, game_ui *ui, | |||
2379 | ui->cur_visible = 1; | 2398 | ui->cur_visible = 1; |
2380 | ui->cur_moved = 1; | 2399 | ui->cur_moved = 1; |
2381 | ui->cur_lastmove = button; | 2400 | ui->cur_lastmove = button; |
2382 | ui->dragx = COORD(ui->cur_x) + TILESIZE/2 + EPSILON_X(button); | ||
2383 | ui->dragy = COORD(ui->cur_y) + TILESIZE/2 + EPSILON_Y(button); | ||
2384 | return UI_UPDATE; | 2401 | return UI_UPDATE; |
2385 | } | 2402 | } |
2386 | if (IS_CURSOR_SELECT(button)) { | 2403 | if (IS_CURSOR_SELECT(button)) { |
2387 | if (!ui->cur_visible) { | 2404 | if (!ui->cur_visible) { |
2388 | ui->dragx = COORD(ui->cur_x) + TILESIZE/2 + EPSILON_X(ui->cur_lastmove); | ||
2389 | ui->dragy = COORD(ui->cur_y) + TILESIZE/2 + EPSILON_Y(ui->cur_lastmove); | ||
2390 | ui->cur_visible = 1; | 2405 | ui->cur_visible = 1; |
2391 | return UI_UPDATE; | 2406 | return UI_UPDATE; |
2392 | } | 2407 | } |
2393 | if (ui->drag_colour == -2) { /* not currently cursor-dragging, start. */ | 2408 | if (ui->drag_colour == -2) { /* not currently cursor-dragging, start. */ |
2394 | int r = region_from_coords(state, ds, ui->dragx, ui->dragy); | 2409 | int r = region_from_ui_cursor(state, ui); |
2395 | if (r >= 0) { | 2410 | if (r >= 0) { |
2396 | ui->drag_colour = state->colouring[r]; | 2411 | ui->drag_colour = state->colouring[r]; |
2397 | ui->drag_pencil = (ui->drag_colour >= 0) ? 0 : state->pencil[r]; | 2412 | ui->drag_pencil = (ui->drag_colour >= 0) ? 0 : state->pencil[r]; |
@@ -2402,11 +2417,10 @@ static char *interpret_move(const game_state *state, game_ui *ui, | |||
2402 | ui->cur_moved = 0; | 2417 | ui->cur_moved = 0; |
2403 | return UI_UPDATE; | 2418 | return UI_UPDATE; |
2404 | } else { /* currently cursor-dragging; drop the colour in the new region. */ | 2419 | } else { /* currently cursor-dragging; drop the colour in the new region. */ |
2405 | x = COORD(ui->cur_x) + TILESIZE/2 + EPSILON_X(ui->cur_lastmove); | ||
2406 | y = COORD(ui->cur_y) + TILESIZE/2 + EPSILON_Y(ui->cur_lastmove); | ||
2407 | alt_button = (button == CURSOR_SELECT2) ? 1 : 0; | 2420 | alt_button = (button == CURSOR_SELECT2) ? 1 : 0; |
2408 | /* Double-select removes current colour. */ | 2421 | /* Double-select removes current colour. */ |
2409 | if (!ui->cur_moved) ui->drag_colour = -1; | 2422 | if (!ui->cur_moved) ui->drag_colour = -1; |
2423 | drop_region = region_from_ui_cursor(state, ui); | ||
2410 | goto drag_dropped; | 2424 | goto drag_dropped; |
2411 | } | 2425 | } |
2412 | } | 2426 | } |
@@ -2439,6 +2453,7 @@ static char *interpret_move(const game_state *state, game_ui *ui, | |||
2439 | if ((button == LEFT_RELEASE || button == RIGHT_RELEASE) && | 2453 | if ((button == LEFT_RELEASE || button == RIGHT_RELEASE) && |
2440 | ui->drag_colour > -2) { | 2454 | ui->drag_colour > -2) { |
2441 | alt_button = (button == RIGHT_RELEASE) ? 1 : 0; | 2455 | alt_button = (button == RIGHT_RELEASE) ? 1 : 0; |
2456 | drop_region = region_from_coords(state, ds, x, y); | ||
2442 | goto drag_dropped; | 2457 | goto drag_dropped; |
2443 | } | 2458 | } |
2444 | 2459 | ||
@@ -2446,7 +2461,7 @@ static char *interpret_move(const game_state *state, game_ui *ui, | |||
2446 | 2461 | ||
2447 | drag_dropped: | 2462 | drag_dropped: |
2448 | { | 2463 | { |
2449 | int r = region_from_coords(state, ds, x, y); | 2464 | int r = drop_region; |
2450 | int c = ui->drag_colour; | 2465 | int c = ui->drag_colour; |
2451 | int p = ui->drag_pencil; | 2466 | int p = ui->drag_pencil; |
2452 | int oldp; | 2467 | int oldp; |
@@ -2972,29 +2987,37 @@ static void game_redraw(drawing *dr, game_drawstate *ds, | |||
2972 | * Draw the dragged colour blob if any. | 2987 | * Draw the dragged colour blob if any. |
2973 | */ | 2988 | */ |
2974 | if ((ui->drag_colour > -2) || ui->cur_visible) { | 2989 | if ((ui->drag_colour > -2) || ui->cur_visible) { |
2975 | int bg, iscur = 0; | 2990 | int bg, iscur = 0, cursor_x, cursor_y; |
2976 | if (ui->drag_colour >= 0) | 2991 | if (ui->drag_colour >= 0) |
2977 | bg = COL_0 + ui->drag_colour; | 2992 | bg = COL_0 + ui->drag_colour; |
2978 | else if (ui->drag_colour == -1) { | 2993 | else if (ui->drag_colour == -1) { |
2979 | bg = COL_BACKGROUND; | 2994 | bg = COL_BACKGROUND; |
2980 | } else { | 2995 | } else { |
2981 | int r = region_from_coords(state, ds, ui->dragx, ui->dragy); | 2996 | int r = region_from_ui_cursor(state, ui); |
2982 | int c = (r < 0) ? -1 : state->colouring[r]; | 2997 | int c = (r < 0) ? -1 : state->colouring[r]; |
2983 | assert(ui->cur_visible); | ||
2984 | /*bg = COL_GRID;*/ | 2998 | /*bg = COL_GRID;*/ |
2985 | bg = (c < 0) ? COL_BACKGROUND : COL_0 + c; | 2999 | bg = (c < 0) ? COL_BACKGROUND : COL_0 + c; |
2986 | iscur = 1; | 3000 | iscur = 1; |
2987 | } | 3001 | } |
2988 | 3002 | ||
2989 | ds->dragx = ui->dragx - TILESIZE/2 - 2; | 3003 | if (ui->cur_visible) { |
2990 | ds->dragy = ui->dragy - TILESIZE/2 - 2; | 3004 | cursor_x = COORD(ui->cur_x) + TILESIZE/2 + |
3005 | EPSILON_X(ui->cur_lastmove); | ||
3006 | cursor_y = COORD(ui->cur_y) + TILESIZE/2 + | ||
3007 | EPSILON_Y(ui->cur_lastmove); | ||
3008 | } else { | ||
3009 | cursor_x = ui->dragx; | ||
3010 | cursor_y = ui->dragy; | ||
3011 | } | ||
3012 | ds->dragx = cursor_x - TILESIZE/2 - 2; | ||
3013 | ds->dragy = cursor_y - TILESIZE/2 - 2; | ||
2991 | blitter_save(dr, ds->bl, ds->dragx, ds->dragy); | 3014 | blitter_save(dr, ds->bl, ds->dragx, ds->dragy); |
2992 | draw_circle(dr, ui->dragx, ui->dragy, | 3015 | draw_circle(dr, cursor_x, cursor_y, |
2993 | iscur ? TILESIZE/4 : TILESIZE/2, bg, COL_GRID); | 3016 | iscur ? TILESIZE/4 : TILESIZE/2, bg, COL_GRID); |
2994 | for (i = 0; i < FOUR; i++) | 3017 | for (i = 0; i < FOUR; i++) |
2995 | if (ui->drag_pencil & (1 << i)) | 3018 | if (ui->drag_pencil & (1 << i)) |
2996 | draw_circle(dr, ui->dragx + ((i*4+2)%10-3) * TILESIZE/10, | 3019 | draw_circle(dr, cursor_x + ((i*4+2)%10-3) * TILESIZE/10, |
2997 | ui->dragy + (i*2-3) * TILESIZE/10, | 3020 | cursor_y + (i*2-3) * TILESIZE/10, |
2998 | TILESIZE/8, COL_0 + i, COL_0 + i); | 3021 | TILESIZE/8, COL_0 + i, COL_0 + i); |
2999 | draw_update(dr, ds->dragx, ds->dragy, TILESIZE + 3, TILESIZE + 3); | 3022 | draw_update(dr, ds->dragx, ds->dragy, TILESIZE + 3, TILESIZE + 3); |
3000 | ds->drag_visible = TRUE; | 3023 | ds->drag_visible = TRUE; |
diff --git a/apps/plugins/puzzles/src/solo.c b/apps/plugins/puzzles/src/solo.c index ef2852f1d9..dd04cdf281 100644 --- a/apps/plugins/puzzles/src/solo.c +++ b/apps/plugins/puzzles/src/solo.c | |||
@@ -1013,12 +1013,23 @@ static int solver_set(struct solver_usage *usage, | |||
1013 | 1013 | ||
1014 | /* | 1014 | /* |
1015 | * If count == 0, then there's a row with no 1s at all and | 1015 | * If count == 0, then there's a row with no 1s at all and |
1016 | * the puzzle is internally inconsistent. However, we ought | 1016 | * the puzzle is internally inconsistent. |
1017 | * to have caught this already during the simpler reasoning | ||
1018 | * methods, so we can safely fail an assertion if we reach | ||
1019 | * this point here. | ||
1020 | */ | 1017 | */ |
1021 | assert(count > 0); | 1018 | if (count == 0) { |
1019 | #ifdef STANDALONE_SOLVER | ||
1020 | if (solver_show_working) { | ||
1021 | va_list ap; | ||
1022 | printf("%*s", solver_recurse_depth*4, | ||
1023 | ""); | ||
1024 | va_start(ap, fmt); | ||
1025 | vprintf(fmt, ap); | ||
1026 | va_end(ap); | ||
1027 | printf(":\n%*s solver_set: impossible on entry\n", | ||
1028 | solver_recurse_depth*4, ""); | ||
1029 | } | ||
1030 | #endif | ||
1031 | return -1; | ||
1032 | } | ||
1022 | if (count == 1) | 1033 | if (count == 1) |
1023 | rowidx[i] = colidx[first] = FALSE; | 1034 | rowidx[i] = colidx[first] = FALSE; |
1024 | } | 1035 | } |
@@ -1465,7 +1476,14 @@ static int solver_killer_sums(struct solver_usage *usage, int b, | |||
1465 | assert(nsquares == 0); | 1476 | assert(nsquares == 0); |
1466 | return 0; | 1477 | return 0; |
1467 | } | 1478 | } |
1468 | assert(nsquares > 0); | 1479 | if (nsquares == 0) { |
1480 | #ifdef STANDALONE_SOLVER | ||
1481 | if (solver_show_working) | ||
1482 | printf("%*skiller: cage has no usable squares left\n", | ||
1483 | solver_recurse_depth*4, ""); | ||
1484 | #endif | ||
1485 | return -1; | ||
1486 | } | ||
1469 | 1487 | ||
1470 | if (nsquares < 2 || nsquares > 4) | 1488 | if (nsquares < 2 || nsquares > 4) |
1471 | return 0; | 1489 | return 0; |