diff --git a/apps/plugins/puzzles/rockbox.c b/apps/plugins/puzzles/rockbox.c index 04d7e6d6e4..51b5e0890b 100644 --- a/apps/plugins/puzzles/rockbox.c +++ b/apps/plugins/puzzles/rockbox.c @@ -37,6 +37,7 @@ #include "src/puzzles.h" +#include "lib/helper.h" #include "lib/keymaps.h" #include "lib/playback_control.h" #include "lib/simple_viewer.h" @@ -139,6 +140,7 @@ extern bool audiobuf_available; /* defined in rbmalloc.c */ static fb_data *zoom_fb; /* dynamically allocated */ static int zoom_x = -1, zoom_y = -1, zoom_w, zoom_h, zoom_clipu, zoom_clipd, zoom_clipl, zoom_clipr; +static bool zoom_force_center; static int cur_font = FONT_UI; static bool need_draw_update = false; @@ -171,7 +173,7 @@ static bool load_success; /* ...did I mention there's a secret debug menu? */ static struct { int slowmo_factor; - bool timerflash, clipoff, shortcuts, no_aa, polyanim; + bool timerflash, clipoff, shortcuts, no_aa, polyanim, highlight_cursor; } debug_settings; // used in menu titles - make sure to initialize! @@ -337,7 +339,7 @@ static void zoom_mono_bitmap(const unsigned char *bits, int x, int y, int w, int static void zoom_alpha_bitmap(const unsigned char *bits, int x, int y, int w, int h) { const unsigned char *ptr = bits; - unsigned char buf; + unsigned char buf = 0; int n_read = 0; /* how many 4-bit nibbles we've read (read new when even) */ unsigned int pix = rb->lcd_get_foreground(); @@ -751,7 +753,7 @@ static void draw_antialiased_line(fb_data *fb, int w, int h, int x0, int y0, int dx = x1 - x0; dy = y1 - y0; - if(!(dx << FRACBITS)) + if((dx << FRACBITS) == 0) return; /* bail out */ long gradient = fp_div(dy << FRACBITS, dx << FRACBITS, FRACBITS); @@ -1349,6 +1351,16 @@ static void rb_start_draw(void *handle) static void rb_end_draw(void *handle) { (void) handle; + + if(debug_settings.highlight_cursor) + { + rb->lcd_set_foreground(LCD_RGBPACK(255,0,255)); + int x, y, w, h; + midend_get_cursor_location(me, &x, &y, &w, &h); + if(x >= 0) + rb->lcd_drawrect(x, y, w, h); + } + /* we ignore the backend's redraw requests and just * unconditionally update everything */ #if 0 @@ -1991,6 +2003,47 @@ static void zoom_clamp_panning(void) { zoom_x = zoom_w - LCD_WIDTH; } +static bool point_in_rect(int px, int py, + int rx, int ry, + int rw, int rh) { + return (rx <= px && px < rx + rw) && (ry <= py && py < ry + rh); +} + + +static void zoom_center_on_cursor(void) { + /* get cursor bounding rectangle */ + int x, y, w, h; + + midend_get_cursor_location(me, &x, &y, &w, &h); + + /* no cursor */ + if(x < 0) + return; + + /* check if either of the top-left and bottom-right corners are + * off-screen */ + bool off_screen = (!point_in_rect(x, y, zoom_x, zoom_y, LCD_WIDTH, LCD_HEIGHT) || + !point_in_rect(x + w, y + h, zoom_x, zoom_y, LCD_WIDTH, LCD_HEIGHT)); + + if(off_screen || zoom_force_center) + { + /* if so, recenter */ + int cx, cy; + cx = x + w / 2; + cy = y + h / 2; + + bool x_pan = x < zoom_x || zoom_x + LCD_WIDTH <= x + w; + if(x_pan || zoom_force_center) + zoom_x = cx - LCD_WIDTH / 2; + + bool y_pan = y < zoom_y || zoom_y + LCD_HEIGHT <= y + h; + if(y_pan || zoom_force_center) + zoom_y = cy - LCD_HEIGHT / 2; + + zoom_clamp_panning(); + } +} + /* This function handles zoom mode, where the user can either pan * around a zoomed-in image or play a zoomed-in version of the game. */ static void zoom(void) @@ -2137,6 +2190,8 @@ static void zoom(void) if(timer_on) timer_cb(); + zoom_center_on_cursor(); + midend_redraw(me); /* blit */ @@ -2624,6 +2679,7 @@ static void init_default_settings(void) debug_settings.shortcuts = false; debug_settings.no_aa = false; debug_settings.polyanim = false; + debug_settings.highlight_cursor = false; } #ifdef DEBUG_MENU @@ -2672,6 +2728,8 @@ static void debug_menu(void) "Toggle send keys on release", "Toggle ignore repeats", "Toggle right-click on hold vs. dragging", + "Toggle highlight cursor region", + "Toggle force zoom on center", "Back"); bool quit = false; int sel = 0; @@ -2693,37 +2751,43 @@ static void debug_menu(void) break; } case 2: - debug_settings.timerflash = !debug_settings.timerflash; + debug_settings.timerflash ^= true; break; case 3: - debug_settings.clipoff = !debug_settings.clipoff; + debug_settings.clipoff ^= true; break; case 4: - debug_settings.shortcuts = !debug_settings.shortcuts; + debug_settings.shortcuts ^= true; break; case 5: - debug_settings.no_aa = !debug_settings.no_aa; + debug_settings.no_aa ^= true; break; case 6: bench_aa(); break; case 7: - debug_settings.polyanim = !debug_settings.polyanim; + debug_settings.polyanim ^= true; break; case 8: - mouse_mode = !mouse_mode; + mouse_mode ^= true; break; case 9: - input_settings.want_spacebar = !input_settings.want_spacebar; + input_settings.want_spacebar ^= true; break; case 10: - input_settings.falling_edge = !input_settings.falling_edge; + input_settings.falling_edge ^= true; break; case 11: - input_settings.ignore_repeats = !input_settings.ignore_repeats; + input_settings.ignore_repeats ^= true; break; case 12: - input_settings.rclick_on_hold = !input_settings.rclick_on_hold; + input_settings.rclick_on_hold ^= true; + break; + case 13: + debug_settings.highlight_cursor ^= true; + break; + case 14: + zoom_force_center ^= true; break; default: quit = true; @@ -2952,10 +3016,10 @@ static void init_tlsf(void) init_memory_pool(giant_buffer_len, giant_buffer); } -static int read_wrapper(void *ptr, void *buf, int len) +static bool read_wrapper(void *ptr, void *buf, int len) { int fd = (int) ptr; - return rb->read(fd, buf, len); + return rb->read(fd, buf, len) == len; } static void write_wrapper(void *ptr, const void *buf, int len) @@ -3067,6 +3131,12 @@ static void tune_input(const char *name) }; input_settings.numerical_chooser = string_in_list(name, number_chooser_games); + + static const char *force_center_games[] = { + "Inertia", + NULL + }; + zoom_force_center = string_in_list(name, force_center_games); } static const char *init_for_game(const game *gm, int load_fd) @@ -3241,7 +3311,7 @@ static void save_fonts(void) final |= oldmask; uint32_t left = final >> 31; uint32_t right = final & 0x7fffffff; - rb->fdprintf(outfd, "%s:%lu:%lu\n", midend_which_game(me)->name, left, right); + rb->fdprintf(outfd, "%s:%u:%u\n", midend_which_game(me)->name, (unsigned)left, (unsigned)right); rb->close(outfd); rb->rename(FONT_TABLE ".tmp", FONT_TABLE); } diff --git a/apps/plugins/puzzles/src/blackbox.c b/apps/plugins/puzzles/src/blackbox.c index c52c50812d..a9c1f88261 100644 --- a/apps/plugins/puzzles/src/blackbox.c +++ b/apps/plugins/puzzles/src/blackbox.c @@ -1100,6 +1100,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. */ @@ -1544,6 +1558,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/apps/plugins/puzzles/src/bridges.c b/apps/plugins/puzzles/src/bridges.c index d12aa0bb6c..83086c9761 100644 --- a/apps/plugins/puzzles/src/bridges.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/cube.c b/apps/plugins/puzzles/src/cube.c index bda7623f97..8c8c46faed 100644 --- a/apps/plugins/puzzles/src/cube.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/devel.but b/apps/plugins/puzzles/src/devel.but index 9f95ad7dd4..741a7944ac 100644 --- a/apps/plugins/puzzles/src/devel.but +++ b/apps/plugins/puzzles/src/devel.but @@ -1289,6 +1289,50 @@ 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, 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 frontends to query the location of the backend's +cursor. With knowledge of this location, a frontend 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. All return values are in units of pixels in +screenspace coordinates. In the event that a cursor is not visible on +screen, this function should return and leave the return parameters +untouched \dash the mid-end 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 mid-end 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 cursor location. However, in other cases such as Cube +or Inertia, there is no \q{cursor} in the conventional sense \dash the +player 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 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 mid-end will +notice either of these cases and behave appropriately. + \S{backend-status} \cw{status()} \c int (*status)(const game_state *state); @@ -1586,10 +1630,10 @@ to the midend when the frontend deems appropriate. The backend should set \cw{*nkeys} to the number of elements in the returned array. -The field for this function point in the \cw{game} structure might be -set to \cw{NULL} (and indeed it is for the majority of the games) to -indicate that no additional buttons (apart from the cursor keys) are -required to play the game. +The field for this function pointer in the \cw{game} structure might +be set to \cw{NULL} (and indeed it is for the majority of the games) +to indicate that no additional buttons (apart from the cursor keys) +are required to play the game. This function should not be called directly by frontends. Instead, frontends should use \cw{midend_request_keys()} @@ -3307,6 +3351,30 @@ 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 void midend_get_cursor_location(midend *me, +\c int *x, int *y, int *w, int *h); + +This function returns the location of the backend's on-screen cursor +or other region of interest in the parameters \cw{*x}, \cw{*y}, +\cw{*w} and \cw{*h}, which describe a rectangle with an upper-left +corner at \cw{(*x,*y)} and a size of \cw{*w} pixels wide by \cw{*h} +pixels tall. The mid-end will ignore any return parameters that may be +equal to \cw{NULL}. + +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 frontend can, for example, ensure that the region +of interest remains visible even if the entire puzzle is too big to +fit on the screen. + +If there is no such region (if either the cursor is not visible, or if +the game does not have cursor support), both \cw{*x} and \cw{*y} will +be set to \cw{-1}. + \H{midend-status} \cw{midend_status()} \c int midend_status(midend *me); diff --git a/apps/plugins/puzzles/src/dominosa.c b/apps/plugins/puzzles/src/dominosa.c index 67a1d69c91..758db4f506 100644 --- a/apps/plugins/puzzles/src/dominosa.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/fifteen.c b/apps/plugins/puzzles/src/fifteen.c index ba991e711a..4b877dc098 100644 --- a/apps/plugins/puzzles/src/fifteen.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/filling.c b/apps/plugins/puzzles/src/filling.c index f67d9fadba..6d9beb5c28 100644 --- a/apps/plugins/puzzles/src/filling.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/flip.c b/apps/plugins/puzzles/src/flip.c index 29c888edf2..5d4f2250aa 100644 --- a/apps/plugins/puzzles/src/flip.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/flood.c b/apps/plugins/puzzles/src/flood.c index 67c3225be4..74214a50b6 100644 --- a/apps/plugins/puzzles/src/flood.c +++ b/apps/plugins/puzzles/src/flood.c @@ -1279,6 +1279,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) { @@ -1361,6 +1375,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/apps/plugins/puzzles/src/galaxies.c b/apps/plugins/puzzles/src/galaxies.c index fe7cd24ecf..9172b90e12 100644 --- a/apps/plugins/puzzles/src/galaxies.c +++ b/apps/plugins/puzzles/src/galaxies.c @@ -382,12 +382,15 @@ static bool ok_to_add_assoc_with_opposite( static void add_assoc_with_opposite(game_state *state, space *tile, space *dot) { space *opposite = space_opposite_dot(state, tile, dot); - assert(ok_to_add_assoc_with_opposite_internal(state, tile, opposite)); + if(opposite) + { + assert(ok_to_add_assoc_with_opposite_internal(state, tile, opposite)); - remove_assoc_with_opposite(state, tile); - add_assoc(state, tile, dot); - remove_assoc_with_opposite(state, opposite); - add_assoc(state, opposite, dot); + remove_assoc_with_opposite(state, tile); + add_assoc(state, tile, dot); + remove_assoc_with_opposite(state, opposite); + add_assoc(state, opposite, dot); + } } static space *sp2dot(const game_state *state, int x, int y) @@ -3469,6 +3472,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 +3729,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/apps/plugins/puzzles/src/guess.c b/apps/plugins/puzzles/src/guess.c index e5ebd5509b..a501579442 100644 --- a/apps/plugins/puzzles/src/guess.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/inertia.c b/apps/plugins/puzzles/src/inertia.c index 838f8dee96..726c89c7dd 100644 --- a/apps/plugins/puzzles/src/inertia.c +++ b/apps/plugins/puzzles/src/inertia.c @@ -2186,6 +2186,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) { /* @@ -2245,6 +2256,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/apps/plugins/puzzles/src/keen.c b/apps/plugins/puzzles/src/keen.c index 70e3e5432c..6b9610dbcd 100644 --- a/apps/plugins/puzzles/src/keen.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/lightup.c b/apps/plugins/puzzles/src/lightup.c index 90811d5475..ab4be9ec87 100644 --- a/apps/plugins/puzzles/src/lightup.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/loopy.c b/apps/plugins/puzzles/src/loopy.c index f2875a2e93..176b56285c 100644 --- a/apps/plugins/puzzles/src/loopy.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/magnets.c b/apps/plugins/puzzles/src/magnets.c index 1a5f37f1fd..edbb8490ad 100644 --- a/apps/plugins/puzzles/src/magnets.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/map.c b/apps/plugins/puzzles/src/map.c index 4e65aa91a6..9df2d22b52 100644 --- a/apps/plugins/puzzles/src/map.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/midend.c b/apps/plugins/puzzles/src/midend.c index a8dd179690..87605a9da8 100644 --- a/apps/plugins/puzzles/src/midend.c +++ b/apps/plugins/puzzles/src/midend.c @@ -1464,6 +1464,25 @@ void midend_request_id_changes(midend *me, void (*notify)(void *), void *ctx) me->game_id_change_notify_ctx = ctx; } +void 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_out) + *x_out = x; + if(y_out) + *y_out = y; + if(w_out) + *w_out = w; + if(h_out) + *h_out = h; +} + void midend_supersede_game_desc(midend *me, const char *desc, const char *privdesc) { diff --git a/apps/plugins/puzzles/src/mines.c b/apps/plugins/puzzles/src/mines.c index ae717d3f37..706777c4f1 100644 --- a/apps/plugins/puzzles/src/mines.c +++ b/apps/plugins/puzzles/src/mines.c @@ -3152,6 +3152,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) { /* @@ -3213,6 +3226,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/apps/plugins/puzzles/src/net.c b/apps/plugins/puzzles/src/net.c index 36f8aca483..d3032b6fe2 100644 --- a/apps/plugins/puzzles/src/net.c +++ b/apps/plugins/puzzles/src/net.c @@ -3090,6 +3090,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; @@ -3271,6 +3285,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/apps/plugins/puzzles/src/netslide.c b/apps/plugins/puzzles/src/netslide.c index 727ff0a910..14af2a689d 100644 --- a/apps/plugins/puzzles/src/netslide.c +++ b/apps/plugins/puzzles/src/netslide.c @@ -1830,6 +1830,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; @@ -1884,6 +1898,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/apps/plugins/puzzles/src/nullgame.c b/apps/plugins/puzzles/src/nullgame.c index 2fa4da6ffd..d923bc8710 100644 --- a/apps/plugins/puzzles/src/nullgame.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/palisade.c b/apps/plugins/puzzles/src/palisade.c index 759fcaa75d..e941661a0e 100644 --- a/apps/plugins/puzzles/src/palisade.c +++ b/apps/plugins/puzzles/src/palisade.c @@ -1288,6 +1288,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; @@ -1401,6 +1414,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/apps/plugins/puzzles/src/pattern.c b/apps/plugins/puzzles/src/pattern.c index a43982f452..df720b7d82 100644 --- a/apps/plugins/puzzles/src/pattern.c +++ b/apps/plugins/puzzles/src/pattern.c @@ -1918,6 +1918,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; @@ -2029,6 +2042,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/apps/plugins/puzzles/src/pearl.c b/apps/plugins/puzzles/src/pearl.c index ccbba51897..2657d45a67 100644 --- a/apps/plugins/puzzles/src/pearl.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/pegs.c b/apps/plugins/puzzles/src/pegs.c index db9caf298f..ec12aa9552 100644 --- a/apps/plugins/puzzles/src/pegs.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/puzzles.h b/apps/plugins/puzzles/src/puzzles.h index 45ae321cc6..5560aabe03 100644 --- a/apps/plugins/puzzles/src/puzzles.h +++ b/apps/plugins/puzzles/src/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); +void 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); @@ -684,6 +686,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/apps/plugins/puzzles/src/range.c b/apps/plugins/puzzles/src/range.c index 64bd17da56..fc0a5405f1 100644 --- a/apps/plugins/puzzles/src/range.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/rect.c b/apps/plugins/puzzles/src/rect.c index 2cb01bfa5d..b13de75fd4 100644 --- a/apps/plugins/puzzles/src/rect.c +++ b/apps/plugins/puzzles/src/rect.c @@ -2883,6 +2883,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; @@ -2994,6 +3007,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/apps/plugins/puzzles/src/samegame.c b/apps/plugins/puzzles/src/samegame.c index 272c7b457d..615c60e0a5 100644 --- a/apps/plugins/puzzles/src/samegame.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/signpost.c b/apps/plugins/puzzles/src/signpost.c index abf4c6a79c..9aee255ebe 100644 --- a/apps/plugins/puzzles/src/signpost.c +++ b/apps/plugins/puzzles/src/signpost.c @@ -2188,6 +2188,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; @@ -2275,6 +2288,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/apps/plugins/puzzles/src/singles.c b/apps/plugins/puzzles/src/singles.c index 3dde8c2b87..202ce08b20 100644 --- a/apps/plugins/puzzles/src/singles.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/sixteen.c b/apps/plugins/puzzles/src/sixteen.c index e47147a8a5..0b02038c43 100644 --- a/apps/plugins/puzzles/src/sixteen.c +++ b/apps/plugins/puzzles/src/sixteen.c @@ -1147,6 +1147,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; @@ -1201,6 +1214,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/apps/plugins/puzzles/src/slant.c b/apps/plugins/puzzles/src/slant.c index 70b2585b81..ed290fe57d 100644 --- a/apps/plugins/puzzles/src/slant.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/solo.c b/apps/plugins/puzzles/src/solo.c index cfe38c5bd9..49753f41dc 100644 --- a/apps/plugins/puzzles/src/solo.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/tents.c b/apps/plugins/puzzles/src/tents.c index 1e601f5836..ee06172baf 100644 --- a/apps/plugins/puzzles/src/tents.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/towers.c b/apps/plugins/puzzles/src/towers.c index aee088fb54..13c652b819 100644 --- a/apps/plugins/puzzles/src/towers.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/tracks.c b/apps/plugins/puzzles/src/tracks.c index 924836afa9..3cf5df70a1 100644 --- a/apps/plugins/puzzles/src/tracks.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/twiddle.c b/apps/plugins/puzzles/src/twiddle.c index 5f2ea02e6f..a107925aee 100644 --- a/apps/plugins/puzzles/src/twiddle.c +++ b/apps/plugins/puzzles/src/twiddle.c @@ -1092,6 +1092,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; @@ -1318,6 +1331,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/apps/plugins/puzzles/src/undead.c b/apps/plugins/puzzles/src/undead.c index 781c15d791..4dba828d48 100644 --- a/apps/plugins/puzzles/src/undead.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/unequal.c b/apps/plugins/puzzles/src/unequal.c index 556cf01c45..153954e510 100644 --- a/apps/plugins/puzzles/src/unequal.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/unfinished/group.c b/apps/plugins/puzzles/src/unfinished/group.c index 006a9e0ee6..8e0185741e 100644 --- a/apps/plugins/puzzles/src/unfinished/group.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/unfinished/separate.c b/apps/plugins/puzzles/src/unfinished/separate.c index 88dc8ed060..39243afb92 100644 --- a/apps/plugins/puzzles/src/unfinished/separate.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/unfinished/slide.c b/apps/plugins/puzzles/src/unfinished/slide.c index 5ad1237d58..c7a3dcecf7 100644 --- a/apps/plugins/puzzles/src/unfinished/slide.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/unfinished/sokoban.c b/apps/plugins/puzzles/src/unfinished/sokoban.c index 7d42a12c5d..ecc222c906 100644 --- a/apps/plugins/puzzles/src/unfinished/sokoban.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/unruly.c b/apps/plugins/puzzles/src/unruly.c index e69c31b6b9..a1f06332e0 100644 --- a/apps/plugins/puzzles/src/unruly.c +++ b/apps/plugins/puzzles/src/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/apps/plugins/puzzles/src/untangle.c b/apps/plugins/puzzles/src/untangle.c index eff93382cd..0d3e0e6135 100644 --- a/apps/plugins/puzzles/src/untangle.c +++ b/apps/plugins/puzzles/src/untangle.c @@ -1581,6 +1581,25 @@ 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->dragpoint >= 0 || ui->cursorpoint >= 0) { + int idx = (ui->dragpoint >= 0) ? ui->dragpoint : ui->cursorpoint; + + int cx, cy; + cx = ds->x[idx]; + cy = ds->y[idx]; + + *x = cx - CIRCLE_RADIUS; + *y = cy - CIRCLE_RADIUS; + *w = *h = 2 * CIRCLE_RADIUS + 1; + } +} + static int game_status(const game_state *state) { return state->completed ? +1 : 0; @@ -1635,6 +1654,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 */