Net: Fix off-grid dragging, including a segfault

When a drag started outside the grid (or no drag has started yet),
ensure the drag state in game_ui says so and bail out accordingly.

Previously, such a drag would manipulate the tile the last valid drag
started from, if any, else segfault.

Also, allow drags that start on-grid and then go off-grid to continue
rotating.
This commit is contained in:
Chris Boyle
2024-03-29 18:08:47 +00:00
committed by Simon Tatham
parent 80aac31040
commit fd304c53cc

24
net.c
View File

@ -2041,6 +2041,9 @@ static game_ui *new_ui(const game_state *state)
get_random_seed(&seed, &seedsize); get_random_seed(&seed, &seedsize);
ui->rs = random_new(seed, seedsize); ui->rs = random_new(seed, seedsize);
sfree(seed); sfree(seed);
#ifdef USE_DRAGGING
ui->dragstartx = ui->dragstarty = ui->dragtilex = ui->dragtiley = -1;
#endif
} else { } else {
ui->rs = NULL; ui->rs = NULL;
} }
@ -2169,12 +2172,22 @@ static char *interpret_move(const game_state *state, game_ui *ui,
*/ */
x -= WINDOW_OFFSET + LINE_THICK; x -= WINDOW_OFFSET + LINE_THICK;
y -= WINDOW_OFFSET + LINE_THICK; y -= WINDOW_OFFSET + LINE_THICK;
if (x < 0 || y < 0)
return nullret;
tx = x / TILE_SIZE; tx = x / TILE_SIZE;
ty = y / TILE_SIZE; ty = y / TILE_SIZE;
if (tx >= state->width || ty >= state->height) if (x < 0 || y < 0 || tx >= state->width || ty >= state->height) {
#ifdef USE_DRAGGING
if (IS_MOUSE_DOWN(button)) {
ui->dragstartx = ui->dragstarty = ui->dragtilex = ui->dragtiley = -1;
return nullret;
}
/*
* else: Despite the mouse moving off the grid, let drags and releases
* continue to manipulate the tile they started from.
*/
#else
return nullret; return nullret;
#endif
}
/* Transform from physical to game coords */ /* Transform from physical to game coords */
tx = (tx + ui->org_x) % state->width; tx = (tx + ui->org_x) % state->width;
ty = (ty + ui->org_y) % state->height; ty = (ty + ui->org_y) % state->height;
@ -2212,6 +2225,9 @@ static char *interpret_move(const game_state *state, game_ui *ui,
|| button == RIGHT_DRAG || button == RIGHT_DRAG
#endif #endif
) { ) {
if (ui->dragtilex < 0)
return nullret;
/* /*
* Find the new drag point and see if it necessitates a * Find the new drag point and see if it necessitates a
* rotation. * rotation.
@ -2265,7 +2281,7 @@ static char *interpret_move(const game_state *state, game_ui *ui,
|| button == RIGHT_RELEASE || button == RIGHT_RELEASE
#endif #endif
) { ) {
if (!ui->dragged) { if (!ui->dragged && ui->dragtilex >= 0) {
/* /*
* There was a click but no perceptible drag: * There was a click but no perceptible drag:
* revert to single-click behaviour. * revert to single-click behaviour.