summaryrefslogtreecommitdiff
path: root/lib/cetris.h
blob: 1c3d8f0d7336b08df6b05aa6e3362fde52c8238b (plain)
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
#ifndef CETRIS_H
#define CETRIS_H

#ifdef __linux__
#define _GNU_SOURCE
#endif

#include <stdint.h>
#include <stdbool.h>

#define CETRIS_EXPORT

#define CETRIS_HI_RES 1

#if CETRIS_HI_RES
#define CETRIS_HZ 1000
typedef uint64_t ctick;
#else
#define CETRIS_HZ 60
typedef uint16_t ctick;
#endif

#define CETRIS_ENABLE_DAS 1

typedef struct {
  int8_t x;
  int8_t y;
} vec2;

typedef uint8_t piece_matrix[4];

enum {
  MINO_Z,
  MINO_L,
  MINO_O,
  MINO_S,
  MINO_I,
  MINO_J,
  MINO_T
};

enum {
  SLOT_OCCUPIED = 1,
};

enum { 
  INIT, 
  ONCE_RIGHT, 
  TWICE, 
  ONCE_LEFT 
};

enum {
  DOWN,
  RIGHT,
  LEFT,
  ROTATE_CCW,
  ROTATE_CW,
  HARD_DROP
};

typedef struct {
  vec2 pos;
  uint8_t t;
  uint8_t r;
  uint8_t ghost_y;
  bool locked;
  bool held;
  ctick lock_tick;
  ctick force_lock_tick;
  piece_matrix m;
} tetrimino;

typedef struct cetris_game cetris_game;

typedef struct {
  ctick drop_period;
  ctick next_piece_delay;
  ctick line_delay_clear;
  ctick lock_delay;
  ctick force_lock;

#if CETRIS_ENABLE_DAS
  ctick das_arr; 
  ctick das_das;
#endif
  
  uint8_t board_x;
  uint8_t board_y;
  uint8_t board_visible;

  uint8_t mino_start_x;
  uint8_t mino_start_y;

  uint8_t starting_level;
  bool wait_on_clear;

  ctick *levels;

  // variable win condition
  bool (*win_condition)(cetris_game *);
} cetris_config;

struct cetris_game {
  // playfield represented by a 2d array
  uint8_t **board;
  int8_t highest_line;

  // queue of all 7 possible tetrimino
  uint8_t piece_queue[7];
  uint8_t next_queue[7];
  uint8_t current_index;

  // current tetrimino
  tetrimino current;
  tetrimino held;
  bool piece_held;

  // waiting to start
  bool waiting;

  // internal game tick
  ctick tick;
  ctick next_drop_tick;
  ctick next_piece_tick;
  ctick down_move_tick;
  ctick *line_remove_tick;

#if CETRIS_HI_RES
  // microsecond accuracy timer
  long long timer;
#endif

#if CETRIS_ENABLE_DAS
  ctick das_wait;
  ctick next_das_move;
  uint8_t das_move;
  uint8_t held_moves[8];
#endif

  // progress trackers 
  uint8_t level;
  uint8_t lines;
  uint8_t line_combo;
  bool game_over;

  // events 
  uint8_t move_event;
  uint8_t line_event;
  uint8_t lock_event;
  uint8_t tetris_event;

  // scoring flags
  bool tspin;
  bool mini_tspin;

  // score counter
  uint16_t score;
  
  // config
  cetris_config config;
};

CETRIS_EXPORT bool update_game_tick(cetris_game *g);
CETRIS_EXPORT void move_piece(cetris_game *g, uint8_t move);
CETRIS_EXPORT void unhold_move(cetris_game* g, uint8_t move);
CETRIS_EXPORT void init_game(cetris_game *g);
CETRIS_EXPORT void hold_piece(cetris_game *g);
CETRIS_EXPORT const piece_matrix default_matrices[7];

#endif /* CETRIS_H */