aboutsummaryrefslogtreecommitdiff
path: root/midend.c
diff options
context:
space:
mode:
authorSimon Tatham <anakin@pobox.com>2005-07-05 18:13:31 +0000
committerSimon Tatham <anakin@pobox.com>2005-07-05 18:13:31 +0000
commitb74dac6de22e783ac6619411743df6bca1755a8b (patch)
tree3291c5880b6167a0af7625d399ae9093a1f1cdfa /midend.c
parenta4e3d69de23af4597fb1fd9a465f354a06568ffe (diff)
downloadpuzzles-b74dac6de22e783ac6619411743df6bca1755a8b.zip
puzzles-b74dac6de22e783ac6619411743df6bca1755a8b.tar.gz
puzzles-b74dac6de22e783ac6619411743df6bca1755a8b.tar.bz2
puzzles-b74dac6de22e783ac6619411743df6bca1755a8b.tar.xz
Refactored the game_size() interface, which was getting really
unpleasant and requiring lots of special cases to be taken care of by every single game. The new interface exposes an integer `tile size' or `scale' parameter to the midend and provides two much simpler routines: one which computes the pixel window size given a game_params and a tile size, and one which is given a tile size and must set up a drawstate appropriately. All the rest of the complexity is handled in the midend, mostly by binary search, so grubby special cases only have to be dealt with once. [originally from svn r6059]
Diffstat (limited to 'midend.c')
-rw-r--r--midend.c68
1 files changed, 57 insertions, 11 deletions
diff --git a/midend.c b/midend.c
index df661b5..b5efda6 100644
--- a/midend.c
+++ b/midend.c
@@ -78,7 +78,7 @@ struct midend_data {
int pressed_mouse_button;
- int winwidth, winheight;
+ int tilesize, winwidth, winheight;
};
#define ensure(me) do { \
@@ -121,7 +121,7 @@ midend_data *midend_new(frontend *fe, const game *ourgame)
me->laststatus = NULL;
me->timing = FALSE;
me->elapsed = 0.0F;
- me->winwidth = me->winheight = 0;
+ me->tilesize = me->winwidth = me->winheight = 0;
sfree(randseed);
@@ -169,11 +169,63 @@ void midend_free(midend_data *me)
sfree(me);
}
+static void midend_size_new_drawstate(midend_data *me)
+{
+ /*
+ * Don't even bother, if we haven't worked out our tile size
+ * anyway yet.
+ */
+ if (me->tilesize > 0) {
+ me->ourgame->compute_size(me->params, me->tilesize,
+ &me->winwidth, &me->winheight);
+ me->ourgame->set_size(me->drawstate, me->params, me->tilesize);
+ }
+}
+
void midend_size(midend_data *me, int *x, int *y, int expand)
{
- me->ourgame->size(me->params, me->drawstate, x, y, expand);
- me->winwidth = *x;
- me->winheight = *y;
+ int min, max;
+ int rx, ry;
+
+ /*
+ * Find the tile size that best fits within the given space. If
+ * `expand' is TRUE, we must actually find the _largest_ such
+ * tile size; otherwise, we bound above at the game's preferred
+ * tile size.
+ */
+ if (expand) {
+ max = 1;
+ do {
+ max *= 2;
+ me->ourgame->compute_size(me->params, max, &rx, &ry);
+ } while (rx <= *x && ry <= *y);
+ } else
+ max = me->ourgame->preferred_tilesize + 1;
+ min = 1;
+
+ /*
+ * Now binary-search between min and max. We're looking for a
+ * boundary rather than a value: the point at which tile sizes
+ * stop fitting within the given dimensions. Thus, we stop when
+ * max and min differ by exactly 1.
+ */
+ while (max - min > 1) {
+ int mid = (max + min) / 2;
+ me->ourgame->compute_size(me->params, mid, &rx, &ry);
+ if (rx <= *x && ry <= *y)
+ min = mid;
+ else
+ max = mid;
+ }
+
+ /*
+ * Now `min' is a valid size, and `max' isn't. So use `min'.
+ */
+
+ me->tilesize = min;
+ midend_size_new_drawstate(me);
+ *x = me->winwidth;
+ *y = me->winheight;
}
void midend_set_params(midend_data *me, game_params *params)
@@ -192,12 +244,6 @@ static void midend_set_timer(midend_data *me)
deactivate_timer(me->frontend);
}
-static void midend_size_new_drawstate(midend_data *me)
-{
- me->ourgame->size(me->params, me->drawstate, &me->winwidth, &me->winheight,
- TRUE);
-}
-
void midend_force_redraw(midend_data *me)
{
if (me->drawstate)