chiark / gitweb /
Add method for frontends to query the backend's cursor location.
authorFranklin Wei <franklin@rockbox.org>
Tue, 7 Jul 2020 02:06:30 +0000 (22:06 -0400)
committerSimon Tatham <anakin@pobox.com>
Mon, 7 Dec 2020 19:40:06 +0000 (19:40 +0000)
The Rockbox frontend allows games to be displayed in a "zoomed-in"
state targets with small displays. Currently we use a modal interface
-- a "viewing" mode in which the cursor keys are used to pan around
the rendered bitmap; and an "interaction" mode that actually sends
keys to the game.

This commit adds a midend_get_cursor_location() function to allow the
frontend to retrieve the backend's cursor location or other "region of
interest" -- such as the player location in Cube or Inertia.

With this information, the Rockbox frontend can now intelligently
follow the cursor around in the zoomed-in state, eliminating the need
for a modal interface.

47 files changed:
blackbox.c
bridges.c
cube.c
devel.but
dominosa.c
fifteen.c
filling.c
flip.c
flood.c
galaxies.c
guess.c
inertia.c
keen.c
lightup.c
loopy.c
magnets.c
map.c
midend.c
mines.c
net.c
netslide.c
nullgame.c
palisade.c
pattern.c
pearl.c
pegs.c
puzzles.h
range.c
rect.c
samegame.c
signpost.c
singles.c
sixteen.c
slant.c
solo.c
tents.c
towers.c
tracks.c
twiddle.c
undead.c
unequal.c
unfinished/group.c
unfinished/separate.c
unfinished/slide.c
unfinished/sokoban.c
unruly.c
untangle.c

index 3067fbf1f1e9dd5a8930dc0bd515d19508942408..5a6be4e3e331d4eb589d9dd672abfbdfdf541678 100644 (file)
@@ -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 */
index d12aa0bb6cd1460a9c27f3c8ffada65305ad18de..83086c97610e6136154a76d1c30ef4c2cce4eeec 100644 (file)
--- 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 bda7623f977839619cdd65476c79765813533215..8c8c46faed33ee694da4fc665c62d1c22682d44f 100644 (file)
--- 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 */
index 9f95ad7dd487b5c687649fdfeb7d665cd21564cd..8dbc46277a28c1e09a5bbe6a9e4eeb7af4d4d8bf 100644 (file)
--- 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);
index 67a1d69c91038a0ec0790f60696bbed6d489239e..758db4f50673a3f5de852184a594c22f7bf4f4a8 100644 (file)
@@ -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 */
index ba991e711afaa47e596b04d8417581a01266b166..4b877dc0987e109e4b43d4841c335c86a2efca70 100644 (file)
--- 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 */
index 4e84ef76af5f01f3be8bf2ea1aa4ed3d292f4bfa..3231384084cee1e5c1a4e27004dea690cbbd77ca 100644 (file)
--- 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 29c888edf22455bdf3b2075138516704308b8e0f..5d4f2250aa16dfdc0b4a8cfe9768a034bc056b46 100644 (file)
--- 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 cb1ef28305b65767cdd1d39f8bf5a189be6a7b4f..ea433022a5615a88d591ffc2790acb754c67d716 100644 (file)
--- 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 */
index fe7cd24ecf957cc6880922e0fed64f375b13173e..2761ed2523097e007bd371e72f86b7e4ab1913e5 100644 (file)
@@ -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 e5ebd5509b7de44c40f643402409ed91d1173e9d..a50157944294bc8986252da3a656789ca8484163 100644 (file)
--- 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 */
index 3e1496f42bdce8548db8d7f6ea96246204486d03..5d50b8a49f9fe1e90a626b2c90bb9036d01db6c5 100644 (file)
--- 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 70e3e5432cc67886fc108f2632dc219c0313a6c2..6b9610dbcdcc6f3ec85b4665db55b3aa12a08c5a 100644 (file)
--- 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 */
index 90811d5475873b53e9eaac896a7d89710ad18d89..ab4be9ec873cba463b7579d907beba4be9e97c2f 100644 (file)
--- 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 f2875a2e93b8d440a80827ce66ab4431ab9dc54d..176b56285c0483d3764798874ee1d33b49f69725 100644 (file)
--- 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 */,
index 1a5f37f1fdc131274c8569f5838729ad5002e7b8..edbb8490ade57e95ad0a7006c0165e22ba5701a7 100644 (file)
--- 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 ac0bea1a5a23aa9ac5daf040766ec2c39ba5d227..412305cfde3301341f1b35c44617f97d4025cf9f 100644 (file)
--- 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 */
index b3032e7287aa37fc75ee3c0af2e2a3f2a53b3f6f..15636d4cfb0032bd3842feb4b73d2efe17fc9075 100644 (file)
--- 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 ee2d5bb621edcdda17f3aa69c45e5f5b307083a4..b48dc306a346fe0b454a60b1f55bdc029ffd9114 100644 (file)
--- 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 1a0c6cd127388ab8904b3323267d01ffc4f56dbb..5796e95da73a654d8fee91d39c6fda574d1c7bc3 100644 (file)
--- 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 */
index bb658fc701bc7e289a6f74ae7ff31bfbc4d0fd9a..7465d70a925ef94357d5726dcdde5dbf3402a14b 100644 (file)
@@ -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 */
index 2fa4da6ffd222715633677fe27312ee61eb7c642..d923bc87101166ef255eba2014a24af811323bda 100644 (file)
@@ -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 */
index 6ffbf2dd69f48dc3fb9ed3774a4ce0222a2878dd..317fb7b16ec99fcb960f15512280c9974fbad367 100644 (file)
@@ -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 */
index d191bb2862bda6d730b9e54e5a7055ff82b85bad..b9a3d6efa646bc9899b43cee74a71771394bec63 100644 (file)
--- 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 ccbba5189791510079f384041050e697b4d81741..2657d45a6785013abd520fbc70b9e100a5a9a4a2 100644 (file)
--- 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 db9caf298f28ed098807747ec292615ad8c99834..ec12aa9552436c3454bba8d430b6dac05771589b 100644 (file)
--- 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 */
index daec081c8dfb4103a3038a19098955db211b09ef..d46a70e188341dce0d6a89dc3a2a5473b0ea6ac1 100644 (file)
--- 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 64bd17da5690a7a7a694297de9b8c84af2819aaa..fc0a5405f16b444ead21a42041289f1e4c917548 100644 (file)
--- 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 51def2e3bdb27466393668ac650775c56ec55730..3cb67bd5636db09e7e079504ce6987782188098b 100644 (file)
--- 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 */
index 272c7b457dd5bed57c59048273415ac4854ac15e..615c60e0a5e7a9ffb2a69815584d68594ff2fa6c 100644 (file)
@@ -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 */
index b5164fb289dede86a1ee6a56b40f9f770f38ac0f..d7344c88a3dc9a9ad6a348afdc8dab6227155771 100644 (file)
@@ -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 */
index 3dde8c2b8753b1541fbe43416f1252b113f8c25c..202ce08b2025de0bfabd6b44355fec88c0b327bd 100644 (file)
--- 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 */
index ba60a867b4c1c8c4e50d1df7a97c36f5e8b0c8bd..d153e50e64669f12976cc0136f05740fdec21ea0 100644 (file)
--- 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 70b2585b810ea3878a62bfd9d28cb8169dba8792..ed290fe57d7bb8ca11d0b77d2f784ea9ac604e03 100644 (file)
--- 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 cfe38c5bd916a6626320f09046e2b0187d93211e..49753f41dcfa06381cc574fd501fe796349308fa 100644 (file)
--- 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 1e601f5836ed8b63afe3d406869f2c36369cbad4..ee06172bafe8301029461940cfb54fe04aeca40d 100644 (file)
--- 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 */
index aee088fb54a6d18508818ef15ef407f3a64a9d38..13c652b819b3b6277121608451ef71767254bf52 100644 (file)
--- 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 */
index 4a7e9b0a00abb87ef50d6fb4f672f71f49cfc674..9149c2ac6fe2aed596fe33a2da476a8bafba87c4 100644 (file)
--- 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 */
index 07e2f81d58ed23bcb4d923cbfeed3afd1d6a16df..32716e5e6e6cab1821e93a6d02b97a7e5f5953cf 100644 (file)
--- 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 */
index 781c15d7916f81fd8d01f7a2b8ce4dd154491b3c..4dba828d486ab6ced95365f17da1e6cb06b193be 100644 (file)
--- 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 */
index 0db020624917092cac1f31b85f9a20931df54126..a5155453544a55c89c59a7b4a2f457c9ce31974e 100644 (file)
--- 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 */
index 006a9e0ee603424cf21bb01107f6802843fdf5f2..8e0185741e7adbeaa207a618462e08fd7543eccc 100644 (file)
@@ -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 */
index 88dc8ed060e556a01e1be35184cae6056053fe31..39243afb922a1ff6fa10a40ac48209c96e9a3710 100644 (file)
@@ -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 */
index 5ad1237d581f9ab96e508c29a1e59fc0bf7d53a7..c7a3dcecf77b6d45b39b22634772e85be1afbfe3 100644 (file)
@@ -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 */
index 7d42a12c5d7d860090c720dbc094cd6483d25ad5..ecc222c9062cbfa16f1d7651395f1fa7a471b953 100644 (file)
@@ -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 */
index e69c31b6b94a354b06066bc5f53882a2ac33b741..a1f06332e050e3495fa6ff6a1cedc077811b1f53 100644 (file)
--- 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 */
index 492935617a4e66e72b9a8ab506c2e9a397b8bb54..df30e1d32c2e0c279ff8c84252e35e9ce1ac2b92 100644 (file)
@@ -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 */