diff --git a/blackbox.c b/blackbox.c index 3067fbf..5a6be4e 100644 --- a/blackbox.c +++ b/blackbox.c @@ -1098,6 +1098,20 @@ badmove: return NULL; } + +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->cur_visible) { + *x = TODRAW(ui->cur_x); + *y = TODRAW(ui->cur_y); + *w = *h = TILE_SIZE; + } +} + /* ---------------------------------------------------------------------- * Drawing routines. */ @@ -1542,6 +1556,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, false, false, game_print_size, game_print, true, /* wants_statusbar */ diff --git a/bridges.c b/bridges.c index d12aa0b..83086c9 100644 --- a/bridges.c +++ b/bridges.c @@ -2146,6 +2146,20 @@ struct game_drawstate { bool started, dragging; }; + +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->cur_visible) { + *x = COORD(ui->cur_x); + *y = COORD(ui->cur_y); + *w = *h = TILE_SIZE; + } +} + /* * The contents of ds->grid are complicated, because of the circular * islands which overlap their own grid square into neighbouring @@ -3267,6 +3281,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, true, false, game_print_size, game_print, false, /* wants_statusbar */ diff --git a/cube.c b/cube.c index bda7623..8c8c46f 100644 --- a/cube.c +++ b/cube.c @@ -1535,6 +1535,27 @@ static void game_free_drawstate(drawing *dr, game_drawstate *ds) sfree(ds); } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + struct bbox bb; + + bb.l = 2.0F * (params->d1 + params->d2); + bb.r = -2.0F * (params->d1 + params->d2); + bb.u = 2.0F * (params->d1 + params->d2); + bb.d = -2.0F * (params->d1 + params->d2); + + find_bbox_callback(&bb, state->grid->squares + state->current); + + *x = ((int)(bb.l * GRID_SCALE) + ds->ox); + *y = ((int)(bb.u * GRID_SCALE) + ds->oy); + *w = (bb.r - bb.l) * GRID_SCALE; + *h = (bb.d - bb.u) * GRID_SCALE; +} + static void game_redraw(drawing *dr, game_drawstate *ds, const game_state *oldstate, const game_state *state, int dir, const game_ui *ui, @@ -1762,6 +1783,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, false, false, game_print_size, game_print, true, /* wants_statusbar */ diff --git a/devel.but b/devel.but index 9f95ad7..8dbc462 100644 --- a/devel.but +++ b/devel.but @@ -1289,6 +1289,51 @@ a mine from the colour it uses when you complete the game. In order to achieve this, its \cw{flash_length()} function has to store a flag in the \c{game_ui} to indicate which flash type is required.) +\S{backend-get-cursor-location} \cw{get_cursor_location()} + +\c void (*get_cursor_location)(const game_ui *ui, +\c const game_drawstate *ds, +\c const game_state *state, +\c const game_params *params, +\c int *x, int *y, +\c int *w, int *h); + +This function queries the backend for the rectangular region +containing the cursor (in games that have one), or other region of +interest. + +This function is called by only +\cw{midend_get_cursor_location()}(\k{midend-get-cursor-location}). Its +purpose is to allow front ends to query the location of the backend's +cursor. With knowledge of this location, a front end can, for example, +ensure that the region of interest remains visible if the puzzle is +too big to fit on the screen at once. + +On returning, \cw{*x}, \cw{*y} should be set to the X and Y +coordinates of the upper-left corner of the rectangular region of +interest, and \cw{*w} and \cw{*h} should be the width and height of +that region, respectively. In the event that a cursor is not visible +on screen, this function should return and leave the return parameters +untouched \dash the midend will notice this. The backend need not +bother checking that \cw{x}, \cw{y}, \cw{w} and \cw{h} are +non-\cw{NULL} \dash the midend guarantees that they will not be. + +Defining what constitutes a \q{region of interest} is left up to the +backend. If a game provides a conventional cursor \dash such as Mines, +Solo, or any of the other grid-based games \dash the most logical +choice is of course the location of the cursor itself. However, in +other cases such as Cube or Inertia, there is no \q{cursor} in the +conventional sense \dash the player instead controls an object moving +around the screen. In these cases, it makes sense to define the region +of interest as the bounding box of the player object or another +sensible region \dash such as the grid square the player is sitting on +in Cube. + +If a backend does not provide a cursor mechanism at all, the backend +is free to provide an empty implementation of this function, or a +\cw{NULL} pointer in the \cw{game} structure \dash the midend will +notice either of these cases and behave appropriately. + \S{backend-status} \cw{status()} \c int (*status)(const game_state *state); @@ -3307,6 +3352,34 @@ The front end can expect its drawing API and/or function. Some back ends require that \cw{midend_size()} (\k{midend-size}) is called before \cw{midend_solve()}. +\H{midend-get-cursor-location} \cw{midend_get_cursor_location()} + +\c bool midend_get_cursor_location(midend *me, +\c int *x, int *y, +\c int *w, int *h); + +This function requests the location of the back end's on-screen cursor +or other region of interest. + +What exactly this region contains is up to the backend, but in general +the region will be an area that the player is controlling with the +cursor keys \dash such as the player location in Cube and Inertia, or +the cursor in any of the conventional grid-based games. With knowledge +of this location, a front end can, for example, ensure that the region +of interest remains visible even if the entire puzzle is too big to +fit on the screen. + +On success, this function returns \cw{true}, and the locations pointed +to by \cw{x}, \cw{y}, \cw{w} and \cw{h} are updated to describe the +cursor region, which has an upper-left corner located at \cw{(*x,*y)} +and a size of \cw{*w} pixels wide by \cw{*h} pixels tall. The caller +may pass \cw{NULL} for any number of these pointers, which will be +ignored. + +On failure, this function returns \cw{false}. Failure can occur if +there is currently no active cursor region, or if the back end lacks +cursor support. + \H{midend-status} \cw{midend_status()} \c int midend_status(midend *me); diff --git a/dominosa.c b/dominosa.c index 67a1d69..758db4f 100644 --- a/dominosa.c +++ b/dominosa.c @@ -3328,6 +3328,20 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->cur_visible) + { + *x = BORDER + ((2 * ui->cur_x + 1) * TILESIZE) / 4; + *y = BORDER + ((2 * ui->cur_y + 1) * TILESIZE) / 4; + *w = *h = TILESIZE / 2 + 2; + } +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -3422,6 +3436,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, true, false, game_print_size, game_print, false, /* wants_statusbar */ diff --git a/fifteen.c b/fifteen.c index ba991e7..4b877dc 100644 --- a/fifteen.c +++ b/fifteen.c @@ -1061,6 +1061,17 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + *x = COORD(X(state, state->gap_pos)); + *y = COORD(Y(state, state->gap_pos)); + *w = *h = TILE_SIZE; +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -1115,6 +1126,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, false, false, game_print_size, game_print, true, /* wants_statusbar */ diff --git a/filling.c b/filling.c index 4e84ef7..3231384 100644 --- a/filling.c +++ b/filling.c @@ -2060,6 +2060,20 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->cur_visible) + { + *x = BORDER + ui->cur_x * TILE_SIZE; + *y = BORDER + ui->cur_y * TILE_SIZE; + *w = *h = TILE_SIZE; + } +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -2165,6 +2179,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, true, false, game_print_size, game_print, false, /* wants_statusbar */ diff --git a/flip.c b/flip.c index 29c888e..5d4f225 100644 --- a/flip.c +++ b/flip.c @@ -1290,6 +1290,20 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->cdraw) + { + *x = COORD(ui->cx); + *y = COORD(ui->cy); + *w = *h = TILE_SIZE; + } +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -1344,6 +1358,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, false, false, game_print_size, game_print, true, /* wants_statusbar */ diff --git a/flood.c b/flood.c index cb1ef28..ea43302 100644 --- a/flood.c +++ b/flood.c @@ -1277,6 +1277,20 @@ static float game_anim_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->cursor_visible) + { + *x = COORD(ui->cx); + *y = COORD(ui->cy); + *w = *h = TILESIZE; + } +} + static int game_status(const game_state *state) { if (state->complete && state->moves <= state->movelimit) { @@ -1359,6 +1373,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, false, false, game_print_size, game_print, true, /* wants_statusbar */ diff --git a/galaxies.c b/galaxies.c index fe7cd24..2761ed2 100644 --- a/galaxies.c +++ b/galaxies.c @@ -3469,6 +3469,37 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->cur_visible) { + space *sp = &SPACE(state, ui->cur_x, ui->cur_y); + + if(sp->flags & F_DOT) { + *x = SCOORD(ui->cur_x) - DOT_SIZE; + *y = SCOORD(ui->cur_y) - DOT_SIZE; + *w = *h = 2 * DOT_SIZE + 1; + } else if(sp->type != s_tile) { + int dx = (ui->cur_x % 2) ? CURSOR_SIZE : CURSOR_SIZE/3; + int dy = (ui->cur_y % 2) ? CURSOR_SIZE : CURSOR_SIZE/3; + int x1 = SCOORD(ui->cur_x)-dx, y1 = SCOORD(ui->cur_y)-dy; + int xs = dx*2+1, ys = dy*2+1; + + *x = x1; + *y = y1; + *w = xs; + *h = ys; + } else { + *x = SCOORD(ui->cur_x) - CURSOR_SIZE; + *y = SCOORD(ui->cur_y) - CURSOR_SIZE; + *w = *h = 2 * CURSOR_SIZE + 1; + } + } +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -3695,6 +3726,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, #ifdef EDITOR false, false, NULL, NULL, diff --git a/guess.c b/guess.c index e5ebd55..a501579 100644 --- a/guess.c +++ b/guess.c @@ -1448,6 +1448,20 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->display_cur && !state->solved) { + *x = GUESS_X(state->next_go, ui->peg_cur) - CGAP; + *y = GUESS_Y(state->next_go, ui->peg_cur) - CGAP; + + *w = *h = 2 * (PEGRAD + CGAP) + 1; + } +} + static int game_status(const game_state *state) { /* @@ -1508,6 +1522,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, false, false, game_print_size, game_print, false, /* wants_statusbar */ diff --git a/inertia.c b/inertia.c index 3e1496f..5d50b8a 100644 --- a/inertia.c +++ b/inertia.c @@ -2181,6 +2181,17 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + *x = ds->pbgx; + *y = ds->pbgy; + *w = *h = TILESIZE; +} + static int game_status(const game_state *state) { /* @@ -2240,6 +2251,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, false, false, game_print_size, game_print, true, /* wants_statusbar */ diff --git a/keen.c b/keen.c index 70e3e54..6b9610d 100644 --- a/keen.c +++ b/keen.c @@ -2198,6 +2198,20 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->hshow) { + *x = BORDER + ui->hx * TILESIZE + 1 + GRIDEXTRA; + *y = BORDER + ui->hy * TILESIZE + 1 + GRIDEXTRA; + + *w = *h = TILESIZE-1-2*GRIDEXTRA; + } +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -2480,6 +2494,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, true, false, game_print_size, game_print, false, /* wants_statusbar */ diff --git a/lightup.c b/lightup.c index 90811d5..ab4be9e 100644 --- a/lightup.c +++ b/lightup.c @@ -2217,6 +2217,19 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->cur_visible) { + *x = COORD(ui->cur_x); + *y = COORD(ui->cur_y); + *w = *h = TILE_SIZE; + } +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -2325,6 +2338,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, true, false, game_print_size, game_print, false, /* wants_statusbar */ diff --git a/loopy.c b/loopy.c index f2875a2..176b562 100644 --- a/loopy.c +++ b/loopy.c @@ -3537,6 +3537,14 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ +} + static int game_status(const game_state *state) { return state->solved ? +1 : 0; @@ -3675,6 +3683,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, true, false, game_print_size, game_print, false /* wants_statusbar */, diff --git a/magnets.c b/magnets.c index 1a5f37f..edbb849 100644 --- a/magnets.c +++ b/magnets.c @@ -2291,6 +2291,19 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->cur_visible) { + *x = COORD(ui->cur_x); + *y = COORD(ui->cur_y); + *w = *h = TILE_SIZE; + } +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -2432,6 +2445,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, true, false, game_print_size, game_print, false, /* wants_statusbar */ diff --git a/map.c b/map.c index ac0bea1..412305c 100644 --- a/map.c +++ b/map.c @@ -3061,6 +3061,19 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->cur_visible) { + *x = COORD(ui->cur_x); + *y = COORD(ui->cur_y); + *w = *h = TILESIZE; + } +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -3260,6 +3273,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, true, true, game_print_size, game_print, false, /* wants_statusbar */ diff --git a/midend.c b/midend.c index b3032e7..15636d4 100644 --- a/midend.c +++ b/midend.c @@ -1464,6 +1464,35 @@ void midend_request_id_changes(midend *me, void (*notify)(void *), void *ctx) me->game_id_change_notify_ctx = ctx; } +bool midend_get_cursor_location(midend *me, + int *x_out, int *y_out, + int *w_out, int *h_out) +{ + int x, y, w, h; + x = y = -1; + w = h = 1; + + if(me->ourgame->get_cursor_location) + me->ourgame->get_cursor_location(me->ui, + me->drawstate, + me->states[me->statepos-1].state, + me->params, + &x, &y, &w, &h); + + if(x == -1 && y == -1) + return false; + + if(x_out) + *x_out = x; + if(y_out) + *y_out = y; + if(w_out) + *w_out = w; + if(h_out) + *h_out = h; + return true; +} + void midend_supersede_game_desc(midend *me, const char *desc, const char *privdesc) { diff --git a/mines.c b/mines.c index ee2d5bb..b48dc30 100644 --- a/mines.c +++ b/mines.c @@ -3150,6 +3150,19 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->cur_visible) { + *x = COORD(ui->cur_x); + *y = COORD(ui->cur_y); + *w = *h = TILE_SIZE; + } +} + static int game_status(const game_state *state) { /* @@ -3211,6 +3224,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, false, false, game_print_size, game_print, true, /* wants_statusbar */ diff --git a/net.c b/net.c index 1a0c6cd..5796e95 100644 --- a/net.c +++ b/net.c @@ -3087,6 +3087,20 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->cur_visible) { + *x = WINDOW_OFFSET + TILE_SIZE * ui->cur_x; + *y = WINDOW_OFFSET + TILE_SIZE * ui->cur_y; + + *w = *h = TILE_SIZE; + } +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -3268,6 +3282,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, true, false, game_print_size, game_print, true, /* wants_statusbar */ diff --git a/netslide.c b/netslide.c index bb658fc..7465d70 100644 --- a/netslide.c +++ b/netslide.c @@ -1825,6 +1825,20 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->cur_visible) { + *x = BORDER + WINDOW_OFFSET + TILE_SIZE * ui->cur_x; + *y = BORDER + WINDOW_OFFSET + TILE_SIZE * ui->cur_y; + + *w = *h = TILE_SIZE; + } +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -1879,6 +1893,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, false, false, game_print_size, game_print, true, /* wants_statusbar */ diff --git a/nullgame.c b/nullgame.c index 2fa4da6..d923bc8 100644 --- a/nullgame.c +++ b/nullgame.c @@ -242,6 +242,14 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ +} + static int game_status(const game_state *state) { return 0; @@ -296,6 +304,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, false, false, game_print_size, game_print, false, /* wants_statusbar */ diff --git a/palisade.c b/palisade.c index 6ffbf2d..317fb7b 100644 --- a/palisade.c +++ b/palisade.c @@ -1274,6 +1274,19 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->show) { + *x = MARGIN + TILESIZE * ui->x; + *y = MARGIN + TILESIZE * ui->y; + *w = *h = TILESIZE; + } +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -1387,6 +1400,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, true, false, game_print_size, game_print, true, /* wants_statusbar */ diff --git a/pattern.c b/pattern.c index d191bb2..b9a3d6e 100644 --- a/pattern.c +++ b/pattern.c @@ -1916,6 +1916,19 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->cur_visible) { + *x = TOCOORD(ds->w, ui->cur_x); + *y = TOCOORD(ds->h, ui->cur_y); + *w = *h = TILE_SIZE; + } +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -2027,6 +2040,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, true, false, game_print_size, game_print, false, /* wants_statusbar */ diff --git a/pearl.c b/pearl.c index ccbba51..2657d45 100644 --- a/pearl.c +++ b/pearl.c @@ -2542,6 +2542,19 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->cursor_active) { + *x = COORD(ui->curx); + *y = COORD(ui->cury); + *w = *h = TILE_SIZE; + } +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -2635,6 +2648,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, true, false, game_print_size, game_print, false, /* wants_statusbar */ diff --git a/pegs.c b/pegs.c index db9caf2..ec12aa9 100644 --- a/pegs.c +++ b/pegs.c @@ -1280,6 +1280,19 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->cur_visible) { + *x = COORD(ui->cur_x); + *y = COORD(ui->cur_y); + *w = *h = TILESIZE; + } +} + static int game_status(const game_state *state) { /* @@ -1338,6 +1351,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, false, false, game_print_size, game_print, false, /* wants_statusbar */ diff --git a/puzzles.h b/puzzles.h index daec081..d46a70e 100644 --- a/puzzles.h +++ b/puzzles.h @@ -347,6 +347,8 @@ const char *identify_game(char **name, bool (*read)(void *ctx, void *buf, int len), void *rctx); void midend_request_id_changes(midend *me, void (*notify)(void *), void *ctx); +bool midend_get_cursor_location(midend *me, int *x, int *y, int *w, int *h); + /* Printing functions supplied by the mid-end */ const char *midend_print_puzzle(midend *me, document *doc, bool with_soln); int midend_tilesize(midend *me); @@ -680,6 +682,11 @@ struct game { const game_state *newstate, int dir, game_ui *ui); float (*flash_length)(const game_state *oldstate, const game_state *newstate, int dir, game_ui *ui); + void (*get_cursor_location)(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h); int (*status)(const game_state *state); bool can_print, can_print_in_colour; void (*print_size)(const game_params *params, float *x, float *y); diff --git a/range.c b/range.c index 64bd17d..fc0a540 100644 --- a/range.c +++ b/range.c @@ -1572,6 +1572,19 @@ static float game_flash_length(const game_state *from, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->cursor_show) { + *x = BORDER + TILESIZE * ui->c; + *y = BORDER + TILESIZE * ui->r; + *w = *h = TILESIZE; + } +} + static int game_status(const game_state *state) { return state->was_solved ? +1 : 0; @@ -1823,6 +1836,7 @@ struct game const thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, true, false, game_print_size, game_print, false, /* wants_statusbar */ diff --git a/rect.c b/rect.c index 51def2e..3cb67bd 100644 --- a/rect.c +++ b/rect.c @@ -2880,6 +2880,19 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->cur_visible) { + *x = COORD(ui->cur_x); + *y = COORD(ui->cur_y); + *w = *h = TILE_SIZE; + } +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -2991,6 +3004,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, true, false, game_print_size, game_print, true, /* wants_statusbar */ diff --git a/samegame.c b/samegame.c index 272c7b4..615c60e 100644 --- a/samegame.c +++ b/samegame.c @@ -1615,6 +1615,19 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->displaysel) { + *x = COORD(ui->xsel); + *y = COORD(ui->ysel); + *w = *h = TILE_SIZE; + } +} + static int game_status(const game_state *state) { /* @@ -1673,6 +1686,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, false, false, game_print_size, game_print, true, /* wants_statusbar */ diff --git a/signpost.c b/signpost.c index b5164fb..d7344c8 100644 --- a/signpost.c +++ b/signpost.c @@ -2187,6 +2187,19 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->cshow) { + *x = COORD(ui->cx); + *y = COORD(ui->cy); + *w = *h = TILE_SIZE; + } +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -2274,6 +2287,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, true, false, game_print_size, game_print, false, /* wants_statusbar */ diff --git a/singles.c b/singles.c index 3dde8c2..202ce08 100644 --- a/singles.c +++ b/singles.c @@ -1758,6 +1758,19 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->cshow) { + *x = COORD(ui->cx); + *y = COORD(ui->cy); + *w = *h = TILE_SIZE; + } +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -1850,6 +1863,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, true, false, game_print_size, game_print, false, /* wants_statusbar */ diff --git a/sixteen.c b/sixteen.c index ba60a86..d153e50 100644 --- a/sixteen.c +++ b/sixteen.c @@ -1146,6 +1146,19 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->cur_visible) { + *x = COORD(ui->cur_x); + *y = COORD(ui->cur_y); + *w = *h = TILE_SIZE; + } +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -1200,6 +1213,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, false, false, game_print_size, game_print, true, /* wants_statusbar */ diff --git a/slant.c b/slant.c index 70b2585..ed290fe 100644 --- a/slant.c +++ b/slant.c @@ -2064,6 +2064,19 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->cur_visible) { + *x = COORD(ui->cur_x); + *y = COORD(ui->cur_y); + *w = *h = TILESIZE; + } +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -2181,6 +2194,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, true, false, game_print_size, game_print, false, /* wants_statusbar */ diff --git a/solo.c b/solo.c index cfe38c5..49753f4 100644 --- a/solo.c +++ b/solo.c @@ -5297,6 +5297,19 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->hshow) { + *x = BORDER + ui->hx * TILE_SIZE + 1 + GRIDEXTRA; + *y = BORDER + ui->hy * TILE_SIZE + 1 + GRIDEXTRA; + *w = *h = TILE_SIZE; + } +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -5622,6 +5635,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, true, false, game_print_size, game_print, false, /* wants_statusbar */ diff --git a/tents.c b/tents.c index 1e601f5..ee06172 100644 --- a/tents.c +++ b/tents.c @@ -2554,6 +2554,19 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->cdisp) { + *x = COORD(ui->cx); + *y = COORD(ui->cy); + *w = *h = TILESIZE; + } +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -2630,6 +2643,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, true, false, game_print_size, game_print, false, /* wants_statusbar */ diff --git a/towers.c b/towers.c index aee088f..13c652b 100644 --- a/towers.c +++ b/towers.c @@ -1935,6 +1935,19 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->hshow) { + *x = COORD(ui->hx); + *y = COORD(ui->hy); + *w = *h = TILESIZE; + } +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -2060,6 +2073,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, true, false, game_print_size, game_print, false, /* wants_statusbar */ diff --git a/tracks.c b/tracks.c index 4a7e9b0..9149c2a 100644 --- a/tracks.c +++ b/tracks.c @@ -2854,6 +2854,37 @@ static float game_flash_length(const game_state *oldstate, const game_state *new return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->cursor_active) { + int off = HALFSZ / 4; + int cx = COORD(ui->curx / 2) + off; + int cy = COORD(ui->cury / 2) + off; + int cw, ch; + cw = ch = TILE_SIZE - (2*off) + 1; + + if(ui->curx % 2 == 0) { + /* left border */ + cx -= off; + cw = 2 * off + 1; + } + if(ui->cury % 2 == 0) { + /* upper border */ + cy -= off; + ch = 2 * off + 1; + } + + *x = cx; + *y = cy; + *w = cw; + *h = ch; + } +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -2948,6 +2979,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, true, false, game_print_size, game_print, false, /* wants_statusbar */ diff --git a/twiddle.c b/twiddle.c index 07e2f81..32716e5 100644 --- a/twiddle.c +++ b/twiddle.c @@ -1090,6 +1090,19 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->cur_visible) { + *x = COORD(ui->cur_x); + *y = COORD(ui->cur_y); + *w = *h = state->n * TILE_SIZE; + } +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -1316,6 +1329,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, false, false, game_print_size, game_print, true, /* wants_statusbar */ diff --git a/undead.c b/undead.c index 781c15d..4dba828 100644 --- a/undead.c +++ b/undead.c @@ -2727,6 +2727,19 @@ static float game_flash_length(const game_state *oldstate, !newstate->cheated) ? FLASH_TIME : 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->hshow) { + *x = BORDER + (ui->hx) * TILESIZE; + *y = BORDER + (ui->hy + 1) * TILESIZE; + *w = *h = TILESIZE; + } +} + static int game_status(const game_state *state) { return state->solved; @@ -2781,6 +2794,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, false, false, game_print_size, game_print, false, /* wants_statusbar */ diff --git a/unequal.c b/unequal.c index 0db0206..a515545 100644 --- a/unequal.c +++ b/unequal.c @@ -2041,6 +2041,19 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->hshow) { + *x = COORD(ui->hx); + *y = COORD(ui->hy); + *w = *h = TILE_SIZE; + } +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -2135,6 +2148,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, true, false, game_print_size, game_print, false, /* wants_statusbar */ diff --git a/unfinished/group.c b/unfinished/group.c index 006a9e0..8e01857 100644 --- a/unfinished/group.c +++ b/unfinished/group.c @@ -2196,6 +2196,14 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -2320,6 +2328,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, true, false, game_print_size, game_print, false, /* wants_statusbar */ diff --git a/unfinished/separate.c b/unfinished/separate.c index 88dc8ed..39243af 100644 --- a/unfinished/separate.c +++ b/unfinished/separate.c @@ -799,6 +799,14 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ +} + static int game_status(const game_state *state) { return 0; @@ -853,6 +861,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, false, false, game_print_size, game_print, false, /* wants_statusbar */ diff --git a/unfinished/slide.c b/unfinished/slide.c index 5ad1237..c7a3dce 100644 --- a/unfinished/slide.c +++ b/unfinished/slide.c @@ -2297,6 +2297,14 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -2351,6 +2359,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, false, false, game_print_size, game_print, true, /* wants_statusbar */ diff --git a/unfinished/sokoban.c b/unfinished/sokoban.c index 7d42a12..ecc222c 100644 --- a/unfinished/sokoban.c +++ b/unfinished/sokoban.c @@ -1415,6 +1415,14 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -1469,6 +1477,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, false, false, game_print_size, game_print, false, /* wants_statusbar */ diff --git a/unruly.c b/unruly.c index e69c31b..a1f0633 100644 --- a/unruly.c +++ b/unruly.c @@ -1860,6 +1860,19 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ + if(ui->cursor) { + *x = COORD(ui->cx); + *y = COORD(ui->cy); + *w = *h = TILE_SIZE; + } +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -1948,6 +1961,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, true, false, game_print_size, game_print, false, /* wants_statusbar */ diff --git a/untangle.c b/untangle.c index 4929356..df30e1d 100644 --- a/untangle.c +++ b/untangle.c @@ -1428,6 +1428,14 @@ static float game_flash_length(const game_state *oldstate, return 0.0F; } +static void game_get_cursor_location(const game_ui *ui, + const game_drawstate *ds, + const game_state *state, + const game_params *params, + int *x, int *y, int *w, int *h) +{ +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -1482,6 +1490,7 @@ const struct game thegame = { game_redraw, game_anim_length, game_flash_length, + game_get_cursor_location, game_status, false, false, game_print_size, game_print, false, /* wants_statusbar */