tty-solitaire/lib/keyboard.c

144 lines
3.5 KiB
C
Raw Normal View History

2011-05-08 02:09:39 +00:00
#include <stdlib.h>
2011-05-29 20:34:59 +00:00
#include <assert.h>
#include "card.h"
#include "game.h"
#include "display.h"
2011-05-08 23:38:36 +00:00
#include "curses.h"
#include "keyboard.h"
2011-02-17 01:50:29 +00:00
static bool cursor_on_stock(struct cursor *cursor) {
2011-05-09 03:38:31 +00:00
return((cursor->x == CURSOR_BEGIN_X) && (cursor->y == CURSOR_BEGIN_Y));
2011-02-17 01:50:29 +00:00
}
2011-05-31 05:49:06 +00:00
static struct stack **cursor_stack(struct cursor *cursor) {
2011-05-09 03:38:31 +00:00
if (cursor->y == CURSOR_BEGIN_Y) {
2010-04-22 04:50:19 +00:00
switch (cursor->x) {
2011-05-31 05:49:06 +00:00
case CURSOR_STOCK_X: return(&(deck->stock));
case CURSOR_WASTE_PILE_X: return(&(deck->waste_pile));
case CURSOR_FOUNDATION_0_X: return(&(deck->foundation[0]));
case CURSOR_FOUNDATION_1_X: return(&(deck->foundation[1]));
case CURSOR_FOUNDATION_2_X: return(&(deck->foundation[2]));
case CURSOR_FOUNDATION_3_X: return(&(deck->foundation[3]));
2011-05-29 20:34:59 +00:00
default: assert(false && "invalid stack");
2010-04-22 04:50:19 +00:00
}
} else {
switch (cursor->x) {
2011-05-31 05:49:06 +00:00
case CURSOR_MANEUVRE_0_X: return(&(deck->maneuvre[0]));
case CURSOR_MANEUVRE_1_X: return(&(deck->maneuvre[1]));
case CURSOR_MANEUVRE_2_X: return(&(deck->maneuvre[2]));
case CURSOR_MANEUVRE_3_X: return(&(deck->maneuvre[3]));
case CURSOR_MANEUVRE_4_X: return(&(deck->maneuvre[4]));
case CURSOR_MANEUVRE_5_X: return(&(deck->maneuvre[5]));
case CURSOR_MANEUVRE_6_X: return(&(deck->maneuvre[6]));
2011-05-29 20:34:59 +00:00
default: assert(false && "invalid stack");
2010-04-22 04:50:19 +00:00
}
}
}
2011-02-06 06:45:53 +00:00
static bool cursor_on_invalid_spot(struct cursor *cursor) {
2011-02-06 01:42:14 +00:00
return(cursor->x == CURSOR_INVALID_SPOT_X &&
2011-05-29 20:34:59 +00:00
cursor->y == CURSOR_INVALID_SPOT_Y);
2011-02-06 01:42:14 +00:00
}
2011-02-06 06:45:53 +00:00
static void handle_stock_event() {
if (!empty(deck->stock)) {
move_card(&(deck->stock), &(deck->waste_pile));
expose_card(deck->waste_pile->card);
draw_stack(deck->stock);
draw_stack(deck->waste_pile);
}
}
2011-02-06 06:45:53 +00:00
static void handle_card_movement(struct cursor *cursor) {
2011-05-31 05:49:06 +00:00
struct stack **origin = cursor_stack(cursor);
struct stack **destination;
2010-04-22 04:50:19 +00:00
int option;
2011-05-31 05:49:06 +00:00
if (cursor_on_invalid_spot(cursor) || empty(*origin)) {
2011-02-06 01:42:14 +00:00
return;
}
2011-05-31 05:49:06 +00:00
mark_cursor(cursor);
draw_cursor(cursor);
2010-04-22 04:50:19 +00:00
while (1) {
switch (option = getch()) {
2011-05-31 05:49:06 +00:00
case KEY_ESCAPE:
if (cursor->marked) {
unmark_cursor(cursor);
draw_cursor(cursor);
}
break;
2011-02-06 06:14:17 +00:00
case 'h':
case KEY_LEFT:
move_cursor(cursor, LEFT);
2011-05-09 05:04:38 +00:00
draw_cursor(cursor);
2011-02-06 06:14:17 +00:00
break;
case 'j':
case KEY_DOWN:
move_cursor(cursor, DOWN);
2011-05-09 05:04:38 +00:00
draw_cursor(cursor);
2011-02-06 06:14:17 +00:00
break;
case 'k':
case KEY_UP:
move_cursor(cursor, UP);
2011-05-09 05:04:38 +00:00
draw_cursor(cursor);
2011-02-06 06:14:17 +00:00
break;
case 'l':
case KEY_RIGHT:
move_cursor(cursor, RIGHT);
2011-05-09 05:04:38 +00:00
draw_cursor(cursor);
2011-02-06 06:14:17 +00:00
break;
case KEY_SPACEBAR:
2011-05-08 02:09:39 +00:00
destination = cursor_stack(cursor);
2011-05-31 05:49:06 +00:00
if (valid_move(*origin, *destination)) {
erase_stack(*origin);
move_card(origin, destination);
draw_stack(*origin);
draw_stack(*destination);
2011-02-06 06:14:17 +00:00
}
2011-05-31 05:49:06 +00:00
unmark_cursor(cursor);
draw_cursor(cursor);
2011-02-06 06:14:17 +00:00
return;
2011-05-08 02:09:39 +00:00
case 'q':
case 'Q':
end_curses();
2011-05-09 05:04:38 +00:00
end_game();
2011-05-08 02:09:39 +00:00
exit(0);
2010-04-22 04:50:19 +00:00
}
}
}
void handle_keyboard_event(int key) {
switch (key) {
case 'h':
case KEY_LEFT:
move_cursor(cursor, LEFT);
2011-05-09 05:04:38 +00:00
draw_cursor(cursor);
break;
case 'j':
case KEY_DOWN:
move_cursor(cursor, DOWN);
2011-05-09 05:04:38 +00:00
draw_cursor(cursor);
break;
case 'k':
case KEY_UP:
move_cursor(cursor, UP);
2011-05-09 05:04:38 +00:00
draw_cursor(cursor);
break;
case 'l':
case KEY_RIGHT:
move_cursor(cursor, RIGHT);
2011-05-09 05:04:38 +00:00
draw_cursor(cursor);
break;
case KEY_SPACEBAR:
if (cursor_on_stock(cursor)) {
handle_stock_event();
} else {
handle_card_movement(cursor);
}
break;
}
}