diff options
| -rw-r--r-- | cube.c | 80 | ||||
| -rw-r--r-- | fifteen.c | 5 | ||||
| -rw-r--r-- | midend.c | 2 | ||||
| -rw-r--r-- | mines.c | 4 | ||||
| -rw-r--r-- | net.c | 3 | ||||
| -rw-r--r-- | netslide.c | 2 | ||||
| -rw-r--r-- | nullgame.c | 4 | ||||
| -rw-r--r-- | pattern.c | 5 | ||||
| -rw-r--r-- | puzzles.h | 4 | ||||
| -rw-r--r-- | rect.c | 5 | ||||
| -rw-r--r-- | sixteen.c | 5 | ||||
| -rw-r--r-- | solo.c | 4 | ||||
| -rw-r--r-- | twiddle.c | 4 |
13 files changed, 94 insertions, 33 deletions
@@ -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; @@ -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; @@ -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) { /* @@ -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; @@ -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; @@ -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; @@ -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; } @@ -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; @@ -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); @@ -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; @@ -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; @@ -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; @@ -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; |