100 lines
2.8 KiB
C
100 lines
2.8 KiB
C
#include "gpu.h"
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
static void clear(int b[20][10]) {
|
|
memset(b, 0, 20 * 10 * sizeof(int));
|
|
}
|
|
|
|
static void set(int b[20][10], int r, int c, int v) {
|
|
if (r >= 0 && r < 20 && c >= 0 && c < 10) b[r][c] = v;
|
|
}
|
|
|
|
static void rect(int b[20][10], int r, int c, int h, int w, int v) {
|
|
for (int dr = 0; dr < h; dr++)
|
|
for (int dc = 0; dc < w; dc++)
|
|
set(b, r + dr, c + dc, v);
|
|
}
|
|
|
|
/* tetromino shapes: flat arrays of 8 ints (4 cells * 2 coords) */
|
|
static const int PIECE_T[] = {0,1, 1,0, 1,1, 1,2};
|
|
static const int PIECE_L[] = {0,0, 0,1, 0,2, 1,0};
|
|
static const int PIECE_J[] = {0,0, 0,1, 0,2, 1,2};
|
|
static const int PIECE_S[] = {0,1, 0,2, 1,0, 1,1};
|
|
static const int PIECE_Z[] = {0,0, 0,1, 1,1, 1,2};
|
|
static const int PIECE_O[] = {0,0, 0,1, 1,0, 1,1};
|
|
static const int PIECE_I[] = {0,0, 1,0, 2,0, 3,0};
|
|
|
|
static const int *PIECES[7] = {PIECE_T, PIECE_L, PIECE_J, PIECE_S, PIECE_Z, PIECE_O, PIECE_I};
|
|
static const int PCOLORS[7] = {5, 3, 2, 1, 7, 4, 6};
|
|
|
|
static void place_piece(int b[20][10], int r, int c, int pi, int v) {
|
|
const int *cells = PIECES[pi % 7];
|
|
for (int i = 0; i < 4; i++)
|
|
set(b, r + cells[i*2], c + cells[i*2+1], v);
|
|
}
|
|
|
|
static void fill_next(int n[4][4], int pi) {
|
|
memset(n, 0, 4 * 4 * sizeof(int));
|
|
const int *cells = PIECES[pi % 7];
|
|
for (int i = 0; i < 4; i++)
|
|
n[cells[i*2]][cells[i*2+1]] = PCOLORS[pi % 7];
|
|
}
|
|
|
|
int main() {
|
|
gpu_t *gpu = gpu_init();
|
|
if (!gpu) { fprintf(stderr, "failed to launch gpu\n"); return 1; }
|
|
|
|
int b1[20][10], b2[20][10], n1[4][4], n2[4][4];
|
|
clear(b1);
|
|
clear(b2);
|
|
|
|
/* --- Player 1: stack with pieces on top --- */
|
|
/* bottom layer */
|
|
rect(b1, 16, 0, 4, 10, 1);
|
|
rect(b1, 15, 1, 1, 8, 2);
|
|
rect(b1, 14, 2, 1, 6, 3);
|
|
rect(b1, 13, 3, 1, 4, 4);
|
|
rect(b1, 12, 4, 1, 2, 5);
|
|
|
|
/* a Tetromino falling */
|
|
place_piece(b1, 2, 3, 0, PCOLORS[0]); /* T piece */
|
|
|
|
/* --- Player 2: different palette, similar stack --- */
|
|
rect(b2, 16, 0, 4, 10, 1);
|
|
rect(b2, 15, 2, 1, 6, 2);
|
|
rect(b2, 14, 3, 1, 4, 3);
|
|
rect(b2, 13, 4, 1, 2, 4);
|
|
rect(b2, 12, 5, 1, 1, 5);
|
|
|
|
place_piece(b2, 3, 4, 3, PCOLORS[3]); /* S piece */
|
|
|
|
/* --- Next pieces --- */
|
|
fill_next(n1, 2); /* J */
|
|
fill_next(n2, 5); /* O */
|
|
|
|
gpu_update(gpu, b1, b2, n1, n2);
|
|
|
|
/* Animate: cycle through pieces falling on player 1 */
|
|
for (int frame = 0; frame < 60; frame++) {
|
|
usleep(100000); /* 100ms */
|
|
|
|
clear(b1);
|
|
rect(b1, 16, 0, 4, 10, 1);
|
|
rect(b1, 15, 1, 1, 8, 2);
|
|
rect(b1, 14, 2, 1, 6, 3);
|
|
rect(b1, 13, 3, 1, 4, 4);
|
|
rect(b1, 12, 4, 1, 2, 5);
|
|
|
|
int pi = frame / 8 % 7;
|
|
int row = 2 + (frame % 8);
|
|
place_piece(b1, row, 3, pi, PCOLORS[pi]);
|
|
fill_next(n1, (pi + 1) % 7);
|
|
|
|
gpu_update(gpu, b1, b2, n1, n2);
|
|
}
|
|
|
|
gpu_close(gpu);
|
|
return 0;
|
|
}
|