diff options
| author | Ben Harris <bjh21@bjh21.me.uk> | 2022-12-05 01:13:26 +0000 |
|---|---|---|
| committer | Ben Harris <bjh21@bjh21.me.uk> | 2022-12-09 20:48:30 +0000 |
| commit | a3310ab857f088489b35ebf10733ba284a24d27f (patch) | |
| tree | 6ae25aaf1bfce3151fbe17e51c49ec12d0c74538 /samegame.c | |
| parent | 1d91522babe41fcf7cbfb06633ae6bc5606db367 (diff) | |
| download | puzzles-a3310ab857f088489b35ebf10733ba284a24d27f.zip puzzles-a3310ab857f088489b35ebf10733ba284a24d27f.tar.gz puzzles-a3310ab857f088489b35ebf10733ba284a24d27f.tar.bz2 puzzles-a3310ab857f088489b35ebf10733ba284a24d27f.tar.xz | |
New backend function: current_key_label()
This provides a way for the front end to ask how a particular key should
be labelled right now (specifically, for a given game_state and
game_ui). This is useful on feature phones where it's conventional to
put a small caption above each soft key indicating what it currently
does.
The function currently provides labels only for CURSOR_SELECT and
CURSOR_SELECT2. This is because these are the only keys that need
labelling on KaiOS.
The concept of labelling keys also turns up in the request_keys() call,
but there are quite a few differences. The labels returned by
current_key_label() are dynamic and likely to vary with each move, while
the labels provided by request_keys() are constant for a given
game_params. Also, the keys returned by request_keys() don't generally
include CURSOR_SELECT and CURSOR_SELECT2, because those aren't necessary
on platforms with pointing devices. It might be possible to provide a
unified API covering both of this, but I think it would be quite
difficult to work with.
Where a key is to be unlabelled, current_key_label() is expected to
return an empty string. This leaves open the possibility of NULL
indicating a fallback to button2label or the label specified by
request_keys() in the future.
It's tempting to try to implement current_key_label() by calling
interpret_move() and parsing its output. This doesn't work for two
reasons. One is that interpret_move() is entitled to modify the
game_ui, and there isn't really a practical way to back those changes
out. The other is that the information returned by interpret_move()
isn't sufficient to generate a label. For instance, in many puzzles it
generates moves that toggle the state of a square, but we want the label
to reflect which state the square will be toggled to. The result is
that I've generally ended up pulling bits of code from interpret_move()
and execute_move() together to implement current_key_label().
Alongside the back-end function, there's a midend_current_key_label()
that's a thin wrapper around the back-end function. It just adds an
assertion about which key's being requested and a default null
implementation so that back-ends can avoid defining the function if it
will do nothing useful.
Diffstat (limited to 'samegame.c')
| -rw-r--r-- | samegame.c | 20 |
1 files changed, 20 insertions, 0 deletions
@@ -1109,6 +1109,25 @@ static void game_changed_state(game_ui *ui, const game_state *oldstate, ui->displaysel = false; } +static const char *current_key_label(const game_ui *ui, + const game_state *state, int button) +{ + if (IS_CURSOR_SELECT(button)) { + int x = ui->xsel, y = ui->ysel, c = COL(state,x,y); + if (c == 0) return ""; + if (ISSEL(ui, x, y)) + return button == CURSOR_SELECT2 ? "Unselect" : "Remove"; + if ((x > 0 && COL(state,x-1,y) == c) || + (x+1 < state->params.w && COL(state,x+1,y) == c) || + (y > 0 && COL(state,x,y-1) == c) || + (y+1 < state->params.h && COL(state,x,y+1) == c)) + return "Select"; + /* Cursor is over a lone square, so we can't select it. */ + if (ui->nselected) return "Unselect"; + } + return ""; +} + static char *sel_movedesc(game_ui *ui, const game_state *state) { int i; @@ -1670,6 +1689,7 @@ const struct game thegame = { decode_ui, NULL, /* game_request_keys */ game_changed_state, + current_key_label, interpret_move, execute_move, PREFERRED_TILE_SIZE, game_compute_size, game_set_size, |