mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 08:01:30 -07:00
Mouse-based interface for Cube: you left-click anywhere on the grid
and it moves the polyhedron in the general direction of the mouse pointer. (I had this in my initial throwaway Python implementation of this game, but never reimplemented it in this version. It's harder with triangles, but not too much harder.) Since the logical-to-physical coordinate mapping in Cube is dynamically computed, this has involved an interface change which touches all puzzles: make_move() is now passed a pointer to the game_drawstate, which it may of course completely ignore if it wishes. [originally from svn r5877]
This commit is contained in:
80
cube.c
80
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;
|
||||
|
@ -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;
|
||||
|
||||
|
2
midend.c
2
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) {
|
||||
/*
|
||||
|
4
mines.c
4
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;
|
||||
|
3
net.c
3
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;
|
||||
|
@ -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);
|
||||
|
5
rect.c
5
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;
|
||||
|
@ -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;
|
||||
|
4
solo.c
4
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;
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user