31 #include "constants.hh"
33 #include "psyqo/fragments.hh"
34 #include "psyqo/gpu.hh"
35 #include "psyqo/primitives/rectangles.hh"
42 template <
size_t COLUMNS,
size_t ROWS>
44 static constexpr
size_t Columns = COLUMNS;
45 static constexpr
size_t Rows = ROWS;
48 enum CellType : uint8_t { Empty, Cyan, Yellow, Purple, Blue, Orange, Red, Green };
49 static constexpr
unsigned BLOCK_SIZE = 10;
50 static constexpr
unsigned SCREEN_WIDTH = 320;
51 static constexpr
unsigned SCREEN_HEIGHT = 240;
52 static constexpr
unsigned LEFT = SCREEN_WIDTH / 2 - (BLOCK_SIZE * COLUMNS / 2);
53 static constexpr
unsigned TOP = SCREEN_HEIGHT / 2 - (BLOCK_SIZE * ROWS / 2);
61 for (
size_t x = 0; x < COLUMNS; x++) {
62 for (
size_t y = 0; y < ROWS; y++) {
63 m_cells[x][y] = Empty;
66 m_fieldFragment.count = 0;
67 m_blockFragment.count = 0;
71 void fillRandom(
Rand& rand) {
72 for (
size_t x = 0; x < COLUMNS; x++) {
73 for (
size_t y = 0; y < ROWS; y++) {
74 m_cells[x][y] = CellType(rand.rand<7>() + 1);
80 bool collision(
unsigned block,
int x,
int y,
unsigned rotation) {
81 for (
size_t i = 0; i < 4; i++) {
82 for (
size_t j = 0; j < 4; j++) {
83 if (PIECES[block - 1][rotation][j][i]) {
86 if ((xx < 0) || (yy < 0) || (xx >= COLUMNS) || (yy >= ROWS) || (m_cells[xx][yy] != Empty)) {
96 void place(
unsigned block,
int x,
int y,
unsigned rotation) {
97 for (
size_t i = 0; i < 4; i++) {
98 for (
size_t j = 0; j < 4; j++) {
99 if (PIECES[block - 1][rotation][j][i]) {
100 m_cells[x + i][y + j] = CellType(block);
110 for (
size_t y = 0; y < ROWS; y++) {
112 for (
size_t x = 0; x < COLUMNS; x++) {
113 if (m_cells[x][y] == Empty) {
119 for (
size_t x = 0; x < COLUMNS; x++) {
120 m_cells[x][y] = Empty;
122 for (
size_t yy = y; yy > 0; yy--) {
123 for (
size_t x = 0; x < COLUMNS; x++) {
124 m_cells[x][yy] = m_cells[x][yy - 1];
162 unsigned m_oldFieldFragmentCount;
163 unsigned m_oldBlockFragmentCount;
169 m_fieldFragment.prologue.outerField.position.x = LEFT - 2;
170 m_fieldFragment.prologue.outerField.position.y = TOP;
171 m_fieldFragment.prologue.outerField.size.x = BLOCK_SIZE * COLUMNS + 4;
172 m_fieldFragment.prologue.outerField.size.y = BLOCK_SIZE * ROWS + 2;
173 m_fieldFragment.prologue.outerField.setColor(DARKERGREY);
174 m_fieldFragment.prologue.innerField.position.x = LEFT;
175 m_fieldFragment.prologue.innerField.position.y = TOP;
176 m_fieldFragment.prologue.innerField.size.x = BLOCK_SIZE * COLUMNS;
177 m_fieldFragment.prologue.innerField.size.y = BLOCK_SIZE * ROWS;
178 m_fieldFragment.prologue.innerField.setColor(DARKGREY);
179 for (
auto& block : m_fieldFragment.primitives) {
180 block.outer.size.w = block.outer.size.h = BLOCK_SIZE;
187 void emptyFragments() {
188 m_oldFieldFragmentCount = m_fieldFragment.count;
189 m_oldBlockFragmentCount = m_blockFragment.count;
190 m_fieldFragment.count = 0;
191 m_blockFragment.count = 0;
197 void restoreFragments() {
198 m_fieldFragment.count = m_oldFieldFragmentCount;
199 m_blockFragment.count = m_oldBlockFragmentCount;
206 void updateFieldFragment() {
207 unsigned counter = 0;
211 for (
size_t x = 0; x < COLUMNS; ++x) {
212 for (
size_t y = 0; y < ROWS; ++y) {
214 auto& block = m_fieldFragment.primitives[counter];
215 switch (m_cells[x][y]) {
220 block.outer.setColor(RED);
221 block.inner.setColor(HIRED);
224 block.outer.setColor(ORANGE);
225 block.inner.setColor(HIORANGE);
228 block.outer.setColor(YELLOW);
229 block.inner.setColor(HIYELLOW);
232 block.outer.setColor(GREEN);
233 block.inner.setColor(HIGREEN);
236 block.outer.setColor(BLUE);
237 block.inner.setColor(HIBLUE);
240 block.outer.setColor(CYAN);
241 block.inner.setColor(HICYAN);
244 block.outer.setColor(PURPLE);
245 block.inner.setColor(HIPURPLE);
249 block.outer.position.x = LEFT + x * BLOCK_SIZE;
250 block.outer.position.y = TOP + y * BLOCK_SIZE;
251 block.inner.position.x = LEFT + x * BLOCK_SIZE + 1;
252 block.inner.position.y = TOP + y * BLOCK_SIZE + 1;
257 m_fieldFragment.count = counter;
264 void updateBlockFragment(
unsigned block,
unsigned x,
unsigned y,
unsigned rotation) {
266 m_blockFragment.count = 0;
269 unsigned counter = 0;
270 for (
size_t i = 0; i < 4; i++) {
271 for (
size_t j = 0; j < 4; j++) {
272 if (PIECES[block - 1][rotation][j][i]) {
273 auto& blockFragment = m_blockFragment.primitives[counter];
274 blockFragment.position.x = LEFT + x * BLOCK_SIZE + i * BLOCK_SIZE + 1;
275 blockFragment.position.y = TOP + y * BLOCK_SIZE + j * BLOCK_SIZE + 1;
276 blockFragment.setColor(PIECES_HICOLORS[block - 1]);
281 m_blockFragment.count = counter;
293 CellType m_cells[COLUMNS][ROWS];
The singleton GPU class.
Definition: gpu.hh:57
void sendFragment(const Fragment &fragment)
Immediately sends a fragment to the GPU. This is a blocking operation. See the fragments....
Definition: gpu.hh:166
Definition: playfield.hh:43
The 8x8 Rectangle primitive.
Definition: rectangles.hh:115
The Rectangle primitive.
Definition: rectangles.hh:46