summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2019-09-23 02:25:43 +0300
committerOxore <oxore@protonmail.com>2019-09-23 02:28:25 +0300
commit95a088365fc78d4a9f6625ecfdf324dbb5614dcc (patch)
treed1c3a5408ae427844b2b3d7628879d7c79ec4a8e
parent7f7a7793621df7b3fdfe1578baad04cea47f3d09 (diff)
Refactor 4: Controls
Consolidate controls related variables in `controls` structure and put it into `game` structure.
-rw-r--r--include/common.h22
-rw-r--r--src/engine.c121
-rw-r--r--src/target/tetris.c23
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;
}