Now we have the UI abstraction, use it to implement keyboard control

in Net.

[originally from svn r4214]
This commit is contained in:
Simon Tatham
2004-05-11 19:24:22 +00:00
parent a03b4b467f
commit ed9b669b29

97
net.c
View File

@ -724,13 +724,24 @@ static unsigned char *compute_active(game_state *state)
return active; return active;
} }
struct game_ui {
int cur_x, cur_y;
int cur_visible;
};
game_ui *new_ui(game_state *state) game_ui *new_ui(game_state *state)
{ {
return NULL; game_ui *ui = snew(game_ui);
ui->cur_x = state->width / 2;
ui->cur_y = state->height / 2;
ui->cur_visible = FALSE;
return ui;
} }
void free_ui(game_ui *ui) void free_ui(game_ui *ui)
{ {
sfree(ui);
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -738,16 +749,19 @@ void free_ui(game_ui *ui)
*/ */
game_state *make_move(game_state *state, game_ui *ui, int x, int y, int button) game_state *make_move(game_state *state, game_ui *ui, int x, int y, int button)
{ {
game_state *ret; game_state *ret, *nullret;
int tx, ty, orig; int tx, ty, orig;
/* nullret = NULL;
* All moves in Net are made with the mouse.
*/ if (button == LEFT_BUTTON ||
if (button != LEFT_BUTTON && button == MIDDLE_BUTTON ||
button != MIDDLE_BUTTON && button == RIGHT_BUTTON) {
button != RIGHT_BUTTON)
return NULL; if (ui->cur_visible) {
ui->cur_visible = FALSE;
nullret = state;
}
/* /*
* The button must have been clicked on a valid tile. * The button must have been clicked on a valid tile.
@ -755,14 +769,40 @@ game_state *make_move(game_state *state, game_ui *ui, int x, int y, int button)
x -= WINDOW_OFFSET + TILE_BORDER; x -= WINDOW_OFFSET + TILE_BORDER;
y -= WINDOW_OFFSET + TILE_BORDER; y -= WINDOW_OFFSET + TILE_BORDER;
if (x < 0 || y < 0) if (x < 0 || y < 0)
return NULL; return nullret;
tx = x / TILE_SIZE; tx = x / TILE_SIZE;
ty = y / TILE_SIZE; ty = y / TILE_SIZE;
if (tx >= state->width || ty >= state->height) if (tx >= state->width || ty >= state->height)
return NULL; return nullret;
if (x % TILE_SIZE >= TILE_SIZE - TILE_BORDER || if (x % TILE_SIZE >= TILE_SIZE - TILE_BORDER ||
y % TILE_SIZE >= TILE_SIZE - TILE_BORDER) y % TILE_SIZE >= TILE_SIZE - TILE_BORDER)
return NULL; return nullret;
} else if (button == CURSOR_UP || button == CURSOR_DOWN ||
button == CURSOR_RIGHT || button == CURSOR_LEFT) {
if (button == CURSOR_UP && ui->cur_y > 0)
ui->cur_y--;
else if (button == CURSOR_DOWN && ui->cur_y < state->height-1)
ui->cur_y++;
else if (button == CURSOR_LEFT && ui->cur_x > 0)
ui->cur_x--;
else if (button == CURSOR_RIGHT && ui->cur_x < state->width-1)
ui->cur_x++;
else
return nullret; /* no cursor movement */
ui->cur_visible = TRUE;
return state; /* UI activity has occurred */
} else if (button == 'a' || button == 's' || button == 'd' ||
button == 'A' || button == 'S' || button == 'D') {
tx = ui->cur_x;
ty = ui->cur_y;
if (button == 'a' || button == 'A')
button = LEFT_BUTTON;
else if (button == 's' || button == 'S')
button = MIDDLE_BUTTON;
else if (button == 'd' || button == 'D')
button = RIGHT_BUTTON;
} else
return nullret;
/* /*
* The middle button locks or unlocks a tile. (A locked tile * The middle button locks or unlocks a tile. (A locked tile
@ -785,7 +825,7 @@ game_state *make_move(game_state *state, game_ui *ui, int x, int y, int button)
* locked tile. * locked tile.
*/ */
if (tile(state, tx, ty) & LOCKED) if (tile(state, tx, ty) & LOCKED)
return NULL; return nullret;
/* /*
* Otherwise, turn the tile one way or the other. Left button * Otherwise, turn the tile one way or the other. Left button
@ -987,7 +1027,7 @@ static void draw_barrier(frontend *fe, int x, int y, int dir, int phase)
} }
static void draw_tile(frontend *fe, game_state *state, int x, int y, int tile, static void draw_tile(frontend *fe, game_state *state, int x, int y, int tile,
float angle) float angle, int cursor)
{ {
int bx = WINDOW_OFFSET + TILE_SIZE * x; int bx = WINDOW_OFFSET + TILE_SIZE * x;
int by = WINDOW_OFFSET + TILE_SIZE * y; int by = WINDOW_OFFSET + TILE_SIZE * y;
@ -1022,6 +1062,26 @@ static void draw_tile(frontend *fe, game_state *state, int x, int y, int tile,
TILE_SIZE-TILE_BORDER, TILE_SIZE-TILE_BORDER, TILE_SIZE-TILE_BORDER, TILE_SIZE-TILE_BORDER,
tile & LOCKED ? COL_LOCKED : COL_BACKGROUND); tile & LOCKED ? COL_LOCKED : COL_BACKGROUND);
/*
* Draw an inset outline rectangle as a cursor, in whichever of
* COL_LOCKED and COL_BACKGROUND we aren't currently drawing
* in.
*/
if (cursor) {
draw_line(fe, bx+TILE_SIZE/8, by+TILE_SIZE/8,
bx+TILE_SIZE/8, by+TILE_SIZE-TILE_SIZE/8,
tile & LOCKED ? COL_BACKGROUND : COL_LOCKED);
draw_line(fe, bx+TILE_SIZE/8, by+TILE_SIZE/8,
bx+TILE_SIZE-TILE_SIZE/8, by+TILE_SIZE/8,
tile & LOCKED ? COL_BACKGROUND : COL_LOCKED);
draw_line(fe, bx+TILE_SIZE-TILE_SIZE/8, by+TILE_SIZE/8,
bx+TILE_SIZE-TILE_SIZE/8, by+TILE_SIZE-TILE_SIZE/8,
tile & LOCKED ? COL_BACKGROUND : COL_LOCKED);
draw_line(fe, bx+TILE_SIZE/8, by+TILE_SIZE-TILE_SIZE/8,
bx+TILE_SIZE-TILE_SIZE/8, by+TILE_SIZE-TILE_SIZE/8,
tile & LOCKED ? COL_BACKGROUND : COL_LOCKED);
}
/* /*
* Set up the rotation matrix. * Set up the rotation matrix.
*/ */
@ -1269,10 +1329,13 @@ void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate,
if (index(state, ds->visible, x, y) != c || if (index(state, ds->visible, x, y) != c ||
index(state, ds->visible, x, y) == 0xFF || index(state, ds->visible, x, y) == 0xFF ||
(x == tx && y == ty)) { (x == tx && y == ty) ||
(ui->cur_visible && x == ui->cur_x && y == ui->cur_y)) {
draw_tile(fe, state, x, y, c, draw_tile(fe, state, x, y, c,
(x == tx && y == ty ? angle : 0.0F)); (x == tx && y == ty ? angle : 0.0F),
if (x == tx && y == ty) (ui->cur_visible && x == ui->cur_x && y == ui->cur_y));
if ((x == tx && y == ty) ||
(ui->cur_visible && x == ui->cur_x && y == ui->cur_y))
index(state, ds->visible, x, y) = 0xFF; index(state, ds->visible, x, y) = 0xFF;
else else
index(state, ds->visible, x, y) = c; index(state, ds->visible, x, y) = c;