aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cube.c80
-rw-r--r--fifteen.c5
-rw-r--r--midend.c2
-rw-r--r--mines.c4
-rw-r--r--net.c3
-rw-r--r--netslide.c2
-rw-r--r--nullgame.c4
-rw-r--r--pattern.c5
-rw-r--r--puzzles.h4
-rw-r--r--rect.c5
-rw-r--r--sixteen.c5
-rw-r--r--solo.c4
-rw-r--r--twiddle.c4
13 files changed, 94 insertions, 33 deletions
diff --git a/cube.c b/cube.c
index 2bce1bd..bf24960 100644
--- a/cube.c
+++ b/cube.c
@@ -11,6 +11,8 @@
#include "puzzles.h"
+#define PI 3.14159265358979323846264338327950884197169399
+
#define MAXVERTICES 20
#define MAXFACES 20
#define MAXORDER 4
@@ -1002,7 +1004,11 @@ static void free_ui(game_ui *ui)
{
}
-static game_state *make_move(game_state *from, game_ui *ui,
+struct game_drawstate {
+ int ox, oy; /* pixel position of float origin */
+};
+
+static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
int x, int y, int button)
{
int direction;
@@ -1016,7 +1022,9 @@ static game_state *make_move(game_state *from, game_ui *ui,
button = button & (~MOD_MASK | MOD_NUM_KEYPAD);
/*
- * All moves are made with the cursor keys or numeric keypad.
+ * Moves can be made with the cursor keys or numeric keypad, or
+ * alternatively you can left-click and the polyhedron will
+ * move in the general direction of the mouse pointer.
*/
if (button == CURSOR_UP || button == (MOD_NUM_KEYPAD | '8'))
direction = UP;
@@ -1034,7 +1042,69 @@ static game_state *make_move(game_state *from, game_ui *ui,
direction = UP_RIGHT;
else if (button == (MOD_NUM_KEYPAD | '3'))
direction = DOWN_RIGHT;
- else
+ else if (button == LEFT_BUTTON) {
+ /*
+ * Find the bearing of the click point from the current
+ * square's centre.
+ */
+ int cx, cy;
+ double angle;
+
+ cx = from->squares[from->current].x * GRID_SCALE + ds->ox;
+ cy = from->squares[from->current].y * GRID_SCALE + ds->oy;
+
+ if (x == cx && y == cy)
+ return NULL; /* clicked in exact centre! */
+ angle = atan2(y - cy, x - cx);
+
+ /*
+ * There are three possibilities.
+ *
+ * - This square is a square, so we choose between UP,
+ * DOWN, LEFT and RIGHT by dividing the available angle
+ * at the 45-degree points.
+ *
+ * - This square is an up-pointing triangle, so we choose
+ * between DOWN, LEFT and RIGHT by dividing into
+ * 120-degree arcs.
+ *
+ * - This square is a down-pointing triangle, so we choose
+ * between UP, LEFT and RIGHT in the inverse manner.
+ *
+ * Don't forget that since our y-coordinates increase
+ * downwards, `angle' is measured _clockwise_ from the
+ * x-axis, not anticlockwise as most mathematicians would
+ * instinctively assume.
+ */
+ if (from->squares[from->current].npoints == 4) {
+ /* Square. */
+ if (fabs(angle) > 3*PI/4)
+ direction = LEFT;
+ else if (fabs(angle) < PI/4)
+ direction = RIGHT;
+ else if (angle > 0)
+ direction = DOWN;
+ else
+ direction = UP;
+ } else if (from->squares[from->current].directions[UP] == 0) {
+ /* Up-pointing triangle. */
+ if (angle < -PI/2 || angle > 5*PI/6)
+ direction = LEFT;
+ else if (angle > PI/6)
+ direction = DOWN;
+ else
+ direction = RIGHT;
+ } else {
+ /* Down-pointing triangle. */
+ assert(from->squares[from->current].directions[DOWN] == 0);
+ if (angle > PI/2 || angle < -5*PI/6)
+ direction = LEFT;
+ else if (angle < -PI/6)
+ direction = UP;
+ else
+ direction = RIGHT;
+ }
+ } else
return NULL;
/*
@@ -1288,10 +1358,6 @@ struct bbox {
float l, r, u, d;
};
-struct game_drawstate {
- int ox, oy; /* pixel position of float origin */
-};
-
static void find_bbox_callback(void *ctx, struct grid_square *sq)
{
struct bbox *bb = (struct bbox *)ctx;
diff --git a/fifteen.c b/fifteen.c
index e7a41ef..49a3118 100644
--- a/fifteen.c
+++ b/fifteen.c
@@ -450,9 +450,8 @@ static void free_ui(game_ui *ui)
{
}
-static game_state *make_move(game_state *from, game_ui *ui,
- int x, int y, int button)
-{
+static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
+ int x, int y, int button) {
int gx, gy, dx, dy, ux, uy, up, p;
game_state *ret;
diff --git a/midend.c b/midend.c
index de20e14..1def041 100644
--- a/midend.c
+++ b/midend.c
@@ -325,7 +325,7 @@ static int midend_really_process_key(midend_data *me, int x, int y, int button)
} else {
game_state *s =
me->ourgame->make_move(me->states[me->statepos-1].state,
- me->ui, x, y, button);
+ me->ui, me->drawstate, x, y, button);
if (s == me->states[me->statepos-1].state) {
/*
diff --git a/mines.c b/mines.c
index 10ca76c..4006294 100644
--- a/mines.c
+++ b/mines.c
@@ -2229,8 +2229,8 @@ static void free_ui(game_ui *ui)
sfree(ui);
}
-static game_state *make_move(game_state *from, game_ui *ui, int x, int y,
- int button)
+static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
+ int x, int y, int button)
{
game_state *ret;
int cx, cy;
diff --git a/net.c b/net.c
index a2204c0..447f4e3 100644
--- a/net.c
+++ b/net.c
@@ -1798,8 +1798,7 @@ static void free_ui(game_ui *ui)
* Process a move.
*/
static game_state *make_move(game_state *state, game_ui *ui,
- int x, int y, int button)
-{
+ game_drawstate *ds, int x, int y, int button) {
game_state *ret, *nullret;
int tx, ty, orig;
int shift = button & MOD_SHFT, ctrl = button & MOD_CTRL;
diff --git a/netslide.c b/netslide.c
index 324946e..b81a816 100644
--- a/netslide.c
+++ b/netslide.c
@@ -1051,7 +1051,7 @@ static void slide_col(game_state *state, int dir, int col)
}
static game_state *make_move(game_state *state, game_ui *ui,
- int x, int y, int button)
+ game_drawstate *ds, int x, int y, int button)
{
int cx, cy;
int n, dx, dy;
diff --git a/nullgame.c b/nullgame.c
index 3ec6b75..56694de 100644
--- a/nullgame.c
+++ b/nullgame.c
@@ -142,8 +142,8 @@ static void free_ui(game_ui *ui)
{
}
-static game_state *make_move(game_state *from, game_ui *ui, int x, int y,
- int button)
+static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
+ int x, int y, int button)
{
return NULL;
}
diff --git a/pattern.c b/pattern.c
index 419e4aa..4cd3669 100644
--- a/pattern.c
+++ b/pattern.c
@@ -764,9 +764,8 @@ static void free_ui(game_ui *ui)
sfree(ui);
}
-static game_state *make_move(game_state *from, game_ui *ui,
- int x, int y, int button)
-{
+static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
+ int x, int y, int button) {
game_state *ret;
button &= ~MOD_MASK;
diff --git a/puzzles.h b/puzzles.h
index bf441c6..de0f819 100644
--- a/puzzles.h
+++ b/puzzles.h
@@ -227,8 +227,8 @@ struct game {
char *(*text_format)(game_state *state);
game_ui *(*new_ui)(game_state *state);
void (*free_ui)(game_ui *ui);
- game_state *(*make_move)(game_state *from, game_ui *ui, int x, int y,
- int button);
+ game_state *(*make_move)(game_state *from, game_ui *ui, game_drawstate *ds,
+ int x, int y, int button);
void (*size)(game_params *params, int *x, int *y);
float *(*colours)(frontend *fe, game_state *state, int *ncolours);
game_drawstate *(*new_drawstate)(game_state *state);
diff --git a/rect.c b/rect.c
index c1eaa2c..9e4204d 100644
--- a/rect.c
+++ b/rect.c
@@ -2178,9 +2178,8 @@ static void ui_draw_rect(game_state *state, game_ui *ui,
}
}
-static game_state *make_move(game_state *from, game_ui *ui,
- int x, int y, int button)
-{
+static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
+ int x, int y, int button) {
int xc, yc;
int startdrag = FALSE, enddrag = FALSE, active = FALSE;
game_state *ret;
diff --git a/sixteen.c b/sixteen.c
index c6664c1..c202de1 100644
--- a/sixteen.c
+++ b/sixteen.c
@@ -577,9 +577,8 @@ static void free_ui(game_ui *ui)
{
}
-static game_state *make_move(game_state *from, game_ui *ui,
- int x, int y, int button)
-{
+static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
+ int x, int y, int button) {
int cx, cy;
int dx, dy, tx, ty, n;
game_state *ret;
diff --git a/solo.c b/solo.c
index 168551c..f3afb02 100644
--- a/solo.c
+++ b/solo.c
@@ -1821,8 +1821,8 @@ static void free_ui(game_ui *ui)
sfree(ui);
}
-static game_state *make_move(game_state *from, game_ui *ui, int x, int y,
- int button)
+static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
+ int x, int y, int button)
{
int c = from->c, r = from->r, cr = c*r;
int tx, ty;
diff --git a/twiddle.c b/twiddle.c
index f7bfd4a..273ce8c 100644
--- a/twiddle.c
+++ b/twiddle.c
@@ -618,8 +618,8 @@ static void free_ui(game_ui *ui)
{
}
-static game_state *make_move(game_state *from, game_ui *ui, int x, int y,
- int button)
+static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
+ int x, int y, int button)
{
int w = from->w, h = from->h, n = from->n, wh = w*h;
game_state *ret;