-
Notifications
You must be signed in to change notification settings - Fork 2
/
game.h
221 lines (178 loc) · 4.12 KB
/
game.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
#ifndef GAME_H
#define GAME_H
#include "core/core.h"
#define BOARD_WIDTH 10
#define BOARD_HEIGHT 20
#define BLOCK_SIDE 30
#define BLOCK_PAD 4
struct GameState;
enum Scene {
TITLE = 0,
IN_ROUND,
OPTIONS,
GAME_OVER,
REPLAY_FINISHED,
HIGH_SCORES,
CREDITS,
};
struct Transition {
enum Type {
NONE = 0,
CHECKER_IN_OUT,
CHECKER_IN_OUT_ROTATE,
FADE_IN_OUT,
ROWS_ACROSS,
};
Type type = NONE;
Scene to;
float duration;
float t = 0;
float z = 0;
DrawOpts2d opts = {};
void (*fn)(GameState *) = NULL;
};
struct FlashMessage {
bool active;
char text[255];
Vec2 pos;
Vec2 vel = {};
float lifetime;
float totalLifetime = 2.0f;
};
struct Block {
int x;
int y;
bool inUse;
bool onBoard;
Color color;
float rotation;
Vec2 pos;
// on board
Vec2 targetPos;
float tweenStep;
// not on board
float rotv;
Vec2 vel;
float timeLeft;
};
struct Cell {
bool full;
int blockIndex;
//Block *block;
};
struct Piece {
int x;
int y;
int type;
int orientation;
};
enum RotationDir {
CW,
CCW,
};
struct Settings {
struct {
SDL_Keycode left = SDLK_LEFT;
SDL_Keycode right = SDLK_RIGHT;
SDL_Keycode down = SDLK_DOWN;
SDL_Keycode drop = SDLK_UP;
SDL_Keycode store = SDLK_LSHIFT;
SDL_Keycode rotateCW = SDLK_x;
SDL_Keycode rotateCCW = SDLK_z;
SDL_Keycode pause = SDLK_p;
SDL_Keycode rewind = SDLK_BACKSPACE;
SDL_Keycode reset = SDLK_r;
SDL_Keycode mute = SDLK_m;
SDL_Keycode save = SDLK_LEFTBRACKET;
SDL_Keycode restore = SDLK_RIGHTBRACKET;
} controls;
bool soundEffects = true;
bool rewindSound = true;
bool showGhost = true;
bool screenShake = true;
float renderScale = 1.0f;
uint32_t moveDelayMillis = 64;
uint32_t moveStartDelayMillis = 100;
};
DECLARE_SERDE(Settings);
bool loadSettings(Settings *s, const char *file);
bool saveSettings(Settings *s, const char *file);
// TODO(ktravis): cleanup
bool compileExtraShaders(Renderer *r);
#define NUM_PIECES 7
#define FLASH_MESSAGE_COUNT 32
#define QUEUE_SIZE (2*2*NUM_PIECES)
#define MAX_BLOCKS (2*BOARD_HEIGHT*BOARD_WIDTH)
struct InRoundState {
uint32_t score;
float droptick;
int combo = 0;
int stored;
bool canStore;
float elapsed;
// want smooth control
struct {
bool left;
bool right;
bool down;
} held;
Cell board[BOARD_HEIGHT][BOARD_WIDTH];
int queue[QUEUE_SIZE];
int queueRemaining;
Block blocks[MAX_BLOCKS];
int lastBlockInUse;
Piece faller;
bool roundInProgress = false;
bool paused = false;
bool gameOver = false;
bool moving = false;
float moveDelayMillis = 0;
float dropAccel = 0;
float shaking;
FlashMessage messages[FLASH_MESSAGE_COUNT];
};
#define SANDS_OF_TIME 1024
#define RW_THRESHOLD 32
struct RewindBuffer {
int cursor = 0;
int size = 0;
InRoundState savedStates[SANDS_OF_TIME];
bool rewinding = false;
int rewindCount = 0;
int rwFactor = 2;
};
struct HighScore {
char name[16] = {};
uint32_t score = 0;
};
#define HIGH_SCORE_LIST_LENGTH 10
struct GameState {
Scene scenes[128];
int currentScene;
Settings settings;
HighScore highScores[HIGH_SCORE_LIST_LENGTH] = {};
float fps;
Transition transition;
Vec2 lastMousePos;
// scene specific:
// TITLE
MenuContext titleMenu;
// IN_ROUND
InRoundState inRound = {};
RewindBuffer rw = {};
// OPTIONS
int currentMenu = 0;
MenuContext menus[0];
MenuContext options;
MenuContext controlsMenu;
MenuContext settingsMenu;
int newHighScore = -1;
int highScoreNameCursor = 0;
};
bool startGame(GameState *, Renderer *, App *);
bool updateGameState(GameState *st, InputData in);
bool updateScene(GameState *st, InputData in, Scene s);
void renderGameState(Renderer *r, GameState *st);
void renderScene(Renderer *r, GameState *st, Scene s);
void renderTransition(Renderer *r, GameState *st);
#endif // GAME_H