From ea6be8f0af766ed15b19260ae17fa793d3d6d4d8 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sat, 22 Apr 2023 10:51:37 +0100 Subject: [PATCH] Require games to accept new_ui(NULL) if they have preferences. This will be necessary in the next commit, so that the midend can make a game_ui out of nothing in order to store preferences in it. The only game actually affected by this requirement is Pearl, which has a preference (GUI style) and also allocates space based on the game_state's grid size to store the coordinates of a path being dragged, so if there is no game_state, it can't do the latter - which is OK, because it also won't be expected to. --- devel.but | 18 +++++++++++++++--- pearl.c | 3 +-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/devel.but b/devel.but index 68a0df2..2459863 100644 --- a/devel.but +++ b/devel.but @@ -732,6 +732,10 @@ with this function. If there are no user preferences, you can set both this function pointer and \c{set_prefs} to \cw{NULL}. +If you implement these functions, you must also ensure that your +game's \cw{new_ui()} function can be called with a null \c{game_state} +pointer. (See \k{backend-new-ui}.) + In every \c{config_item} returned from this function, you must set an additional field beyond the ones described in \k{backend-configure}: @@ -928,9 +932,17 @@ allocations contained within it. \c game_ui *(*new_ui)(const game_state *state); This function allocates and returns a new \c{game_ui} structure for -playing a particular puzzle. It is passed a pointer to the initial -\c{game_state}, in case it needs to refer to that when setting up -the initial values for the new game. +playing a particular puzzle. + +Usually, this function is passed a pointer to the initial +\c{game_state}, in case it needs to refer to that when setting up the +initial values for the new game. + +However, if the puzzle defines \c{get_prefs()} and \c{set_prefs()} +functions, then this function may also be called with +\cw{state==NULL}. In this situation it must still allocate a +\c{game_ui} which can be used by \c{get_prefs()} and \c{set_prefs()}, +although it need not be usable for actually playing a game. \S{backend-free-ui} \cw{free_ui()} diff --git a/pearl.c b/pearl.c index 7265c70..0e90044 100644 --- a/pearl.c +++ b/pearl.c @@ -1897,10 +1897,9 @@ static void legacy_prefs_override(struct game_ui *ui_out) static game_ui *new_ui(const game_state *state) { game_ui *ui = snew(game_ui); - int sz = state->shared->sz; ui->ndragcoords = -1; - ui->dragcoords = snewn(sz, int); + ui->dragcoords = state ? snewn(state->shared->sz, int) : NULL; ui->cursor_active = getenv_bool("PUZZLES_SHOW_CURSOR", false); ui->curx = ui->cury = 0;