diff options
author | Oxore <oxore@protonmail.com> | 2019-09-23 02:25:43 +0300 |
---|---|---|
committer | Oxore <oxore@protonmail.com> | 2019-09-23 02:28:25 +0300 |
commit | 95a088365fc78d4a9f6625ecfdf324dbb5614dcc (patch) | |
tree | d1c3a5408ae427844b2b3d7628879d7c79ec4a8e | |
parent | 7f7a7793621df7b3fdfe1578baad04cea47f3d09 (diff) |
Refactor 4: Controls
Consolidate controls related variables in `controls` structure and put
it into `game` structure.
-rw-r--r-- | include/common.h | 22 | ||||
-rw-r--r-- | src/engine.c | 121 | ||||
-rw-r--r-- | src/target/tetris.c | 23 |
3 files changed, 89 insertions, 77 deletions
diff --git a/include/common.h b/include/common.h index 36a2d21..3922a9f 100644 --- a/include/common.h +++ b/include/common.h @@ -9,6 +9,24 @@ enum game_state { GS_PAUSED }; +// Bits in bitmap of keys +#define RIGHT (1 << 0) +#define UP (1 << 1) +#define DOWN (1 << 2) +#define LEFT (1 << 3) +#define RIGHTHOLD (1 << 4) +#define HARDDROP (1 << 5) +#define PAUSE (1 << 6) +#define LEFTHOLD (1 << 7) +#define GAMEOVER (1 << 8) + +struct controls { + uint32_t keys; // bitmap of keys pressed + sfClock *repPushDown; // repeat latency when hold Down arrow + sfClock *repKeyLeft; // repeat latency when hold Left arrow + sfClock *repKeyRight; // repeat latency when hold Right arrow +}; + struct game { enum game_state state; size_t level; @@ -19,9 +37,7 @@ struct game { sfClock *over_wait_tick; sfClock *putTick; sfClock *mTick; - sfClock *repPushDown; // repeat latency when hold Down arrow - sfClock *repKeyLeft; // repeat latency when hold Left arrow - sfClock *repKeyRight; // repeat latency when hold Right arrow + struct controls controls; struct field *fld; struct field *nxt; diff --git a/src/engine.c b/src/engine.c index 7ab9705..8ff53fc 100644 --- a/src/engine.c +++ b/src/engine.c @@ -43,16 +43,6 @@ #include "painter.h" #include "engine.h" -#define RIGHT (1 << 0) -#define UP (1 << 1) -#define DOWN (1 << 2) -#define LEFT (1 << 3) -#define RIGHTHOLD (1 << 4) -#define HARDDROP (1 << 5) -#define PAUSE (1 << 6) -#define LEFTHOLD (1 << 7) -#define GAMEOVER (1 << 8) - static int level_move_latency[] = { L00LATENCY, L01LATENCY, @@ -94,8 +84,6 @@ static int rmlines_score[] = { RM_4LINES_SCORE }; -static int keys = 0; - static void render_score_value(struct game *game, void *obj) { struct text *text = obj; @@ -422,108 +410,105 @@ static void signal_right(struct game *game) } } -static int game_keys(struct game *game) +static int game_keys(struct controls *ctl) { - // TODO: Should not accept `struct game *` argument - // Should permute only `keys` variable, reset timers and return changed keys - int ret = 0; /* PAUSE */ if (sfKeyboard_isKeyPressed(sfKeyP)) { - if (!(keys & PAUSE)) { - keys |= PAUSE; + if (!(ctl->keys & PAUSE)) { + ctl->keys |= PAUSE; ret |= PAUSE; } } else { - keys &= ~PAUSE; + ctl->keys &= ~PAUSE; } /* UP */ if (sfKeyboard_isKeyPressed(sfKeyUp)) { - if (!(keys & UP)) { - keys = keys | UP; + if (!(ctl->keys & UP)) { + ctl->keys |= UP; ret |= UP; } } else { - keys = keys & ~UP; + ctl->keys = ctl->keys & ~UP; } /* HARDDROP */ if (sfKeyboard_isKeyPressed(sfKeySpace)) { - if (!(keys & HARDDROP)) { - keys |= HARDDROP; + if (!(ctl->keys & HARDDROP)) { + ctl->keys |= HARDDROP; ret |= HARDDROP; } } else { - keys &= ~HARDDROP; + ctl->keys &= ~HARDDROP; } /* DOWN */ if (sfKeyboard_isKeyPressed(sfKeyDown)) { - if (!(keys & DOWN)) { - keys = keys | DOWN; + if (!(ctl->keys & DOWN)) { + ctl->keys |= DOWN; ret |= DOWN; - sfClock_restart(game->repPushDown); + sfClock_restart(ctl->repPushDown); } else { - if (sfClock_getElapsedTime(game->repPushDown).microseconds + if (sfClock_getElapsedTime(ctl->repPushDown).microseconds >= moveRepeatLatency2) - keys &= ~DOWN; + ctl->keys &= ~DOWN; } } else { - keys &= ~DOWN; + ctl->keys &= ~DOWN; } /* LEFT */ if (sfKeyboard_isKeyPressed(sfKeyLeft) && !sfKeyboard_isKeyPressed(sfKeyRight)) { - if (!(keys & LEFT)) { - keys = keys | LEFT; + if (!(ctl->keys & LEFT)) { + ctl->keys |= LEFT; ret |= LEFT; - sfClock_restart(game->repKeyLeft); - } else if (!(keys & LEFTHOLD)) { - if (sfClock_getElapsedTime(game->repKeyLeft).microseconds + sfClock_restart(ctl->repKeyLeft); + } else if (!(ctl->keys & LEFTHOLD)) { + if (sfClock_getElapsedTime(ctl->repKeyLeft).microseconds >= moveRepeatLatency1) { - keys |= LEFTHOLD; - keys &= ~LEFT; + ctl->keys |= LEFTHOLD; + ctl->keys &= ~LEFT; } } else { - if (sfClock_getElapsedTime(game->repKeyLeft).microseconds + if (sfClock_getElapsedTime(ctl->repKeyLeft).microseconds >= moveRepeatLatency2) - keys &= ~LEFT; + ctl->keys &= ~LEFT; } } else { - keys &= ~LEFT; - keys &= ~LEFTHOLD; + ctl->keys &= ~LEFT; + ctl->keys &= ~LEFTHOLD; } /* RIGHT */ if (sfKeyboard_isKeyPressed(sfKeyRight) && !sfKeyboard_isKeyPressed(sfKeyLeft)) { - if (!(keys & RIGHT)) { - keys = keys | RIGHT; + if (!(ctl->keys & RIGHT)) { + ctl->keys |= RIGHT; ret |= RIGHT; - sfClock_restart(game->repKeyRight); - } else if (!(keys & RIGHTHOLD)) { - if (sfClock_getElapsedTime(game->repKeyRight).microseconds + sfClock_restart(ctl->repKeyRight); + } else if (!(ctl->keys & RIGHTHOLD)) { + if (sfClock_getElapsedTime(ctl->repKeyRight).microseconds >= moveRepeatLatency1) { - keys |= RIGHTHOLD; - keys &= ~RIGHT; + ctl->keys |= RIGHTHOLD; + ctl->keys &= ~RIGHT; } } else { - if (sfClock_getElapsedTime(game->repKeyRight).microseconds + if (sfClock_getElapsedTime(ctl->repKeyRight).microseconds >= moveRepeatLatency2) - keys &= ~RIGHT; + ctl->keys &= ~RIGHT; } } else { - keys &= ~RIGHT; - keys &= ~RIGHTHOLD; + ctl->keys &= ~RIGHT; + ctl->keys &= ~RIGHTHOLD; } return ret; } -static int pause_keys(struct game *game) +static int pause_keys(struct controls *ctl) { // TODO: merge with game_keys @@ -531,13 +516,12 @@ static int pause_keys(struct game *game) /* PAUSE */ if (sfKeyboard_isKeyPressed(sfKeyP)) { - if (!(keys & PAUSE)) { - keys |= PAUSE; + if (!(ctl->keys & PAUSE)) { + ctl->keys |= PAUSE; ret |= PAUSE; - sfClock_restart(game->putTick); } } else { - keys &= ~PAUSE; + ctl->keys &= ~PAUSE; } return ret; @@ -605,11 +589,11 @@ static int menu_loop(struct game *game) menu_tick(game); if (sfKeyboard_isKeyPressed(sfKeyS)) { - if (!(keys & GAMEOVER)) { + if (!(game->controls.keys & GAMEOVER)) { ret = MENU_LOOP_GAME_START; } } else { - keys = 0; + game->controls.keys = 0; } return ret; @@ -623,10 +607,10 @@ static int game_loop(struct game *game) struct field *fld = game->fld; struct field *nxt = game->nxt; - // TODO: Elaborate on precedence of timers and keys checking + // TODO: Elaborate on precedence of timers and ctl->keys checking // Here should be only one return statement - at the end of the function - int ret_keys = game_keys(game); + int ret_keys = game_keys(&game->controls); if (ret_keys & PAUSE) { ret = GAME_LOOP_PAUSE; @@ -703,7 +687,7 @@ static int game_over_wait_loop(struct game *game) } #define GAME_OVER_LOOP_MENU 1 -static int game_over_loop(void) +static int game_over_loop(struct controls *ctl) { int anykey = 0; int ret = 0; @@ -713,12 +697,12 @@ static int game_over_loop(void) anykey = 1; if (anykey) { - if (!(keys & GAMEOVER)) { - keys |= GAMEOVER; + if (!(ctl->keys & GAMEOVER)) { + ctl->keys |= GAMEOVER; ret = GAME_OVER_LOOP_MENU; } } else { - keys &= ~GAMEOVER; + ctl->keys &= ~GAMEOVER; } return ret; @@ -727,8 +711,9 @@ static int game_over_loop(void) #define PAUSE_LOOP_UNPAUSE 1 static int pause_loop(struct game *game) { - int ret = pause_keys(game); + int ret = pause_keys(&game->controls); if (ret & PAUSE) { + sfClock_restart(game->putTick); return PAUSE_LOOP_UNPAUSE; } return 0; @@ -753,7 +738,7 @@ void main_loop(struct game *game) break; case GS_GAME_OVER: - ret = game_over_loop(); + ret = game_over_loop(&game->controls); if (ret == GAME_OVER_LOOP_MENU) transition_menu(game); break; diff --git a/src/target/tetris.c b/src/target/tetris.c index e090120..d53970a 100644 --- a/src/target/tetris.c +++ b/src/target/tetris.c @@ -8,6 +8,7 @@ #include <SFML/System/Clock.h> #include <SFML/Graphics/RenderWindow.h> #include <stdbool.h> +#include <stdint.h> #include <stdlib.h> #include <time.h> @@ -47,6 +48,16 @@ int main() .level = 1, .moveLatency = L00LATENCY, .lines = 0, + .gameTick = NULL, + .over_wait_tick = NULL, + .putTick = NULL, + .mTick = NULL, + .controls = { + .keys = 0, + .repPushDown = NULL, + .repKeyLeft = NULL, + .repKeyRight = NULL, + }, .fld = &fld, .nxt = &nxt, .texts = NULL, @@ -57,9 +68,9 @@ int main() game.over_wait_tick = sfClock_create(); game.putTick = sfClock_create(); game.mTick = sfClock_create(); - game.repPushDown = sfClock_create(); - game.repKeyLeft = sfClock_create(); - game.repKeyRight = sfClock_create(); + game.controls.repPushDown = sfClock_create(); + game.controls.repKeyLeft = sfClock_create(); + game.controls.repKeyRight = sfClock_create(); painter_load_font("dat/arial.ttf"); @@ -132,9 +143,9 @@ cleanup_load_texts: sfClock_destroy(game.over_wait_tick); sfClock_destroy(game.putTick); sfClock_destroy(game.mTick); - sfClock_destroy(game.repPushDown); - sfClock_destroy(game.repKeyLeft); - sfClock_destroy(game.repKeyRight); + sfClock_destroy(game.controls.repPushDown); + sfClock_destroy(game.controls.repKeyLeft); + sfClock_destroy(game.controls.repKeyRight); return EXIT_SUCCESS; } |