From 1097c6e09dcea3b3d25b5c4b9bcf6f7dc69b7eeb Mon Sep 17 00:00:00 2001 From: Quinn Date: Mon, 27 Jan 2025 16:16:23 +0100 Subject: [PATCH] make shape data identifiable by ID and rotation --- src/game/tetromino/placing.c | 34 +----------------------- src/game/tetromino/shapes.c | 40 +++++++++++++++++++++++++++++ src/game/tetromino/shapes.h | 50 ++++++++++++++++-------------------- 3 files changed, 63 insertions(+), 61 deletions(-) create mode 100644 src/game/tetromino/shapes.c diff --git a/src/game/tetromino/placing.c b/src/game/tetromino/placing.c index 82e63e5..d8a9b2b 100644 --- a/src/game/tetromino/placing.c +++ b/src/game/tetromino/placing.c @@ -40,38 +40,6 @@ void tmp_set_all(GameData* game_data) { void tmp_set_random(GameData* game_data) { uint32_t x = rand() % TETROMINO_COUNT; - Shape shape = 0; - Colour colour = {0}; - switch (x) { - case 0: - shape = TETROMINO_I; - colour = COLOUR_CYAN; - break; - case 1: - shape = TETROMINO_J; - colour = COLOUR_BLUE; - break; - case 2: - shape = TETROMINO_L; - colour = COLOUR_ORANGE; - break; - case 3: - shape = TETROMINO_O; - colour = COLOUR_YELLOW; - break; - case 4: - shape = TETROMINO_S; - colour = COLOUR_RED; - break; - case 5: - shape = TETROMINO_T; - colour = COLOUR_MAGENTA; - break; - case 6: - shape = TETROMINO_Z; - colour = COLOUR_GREEN; - break; - } - set_shape(game_data->row, shape, colour, 1, 1); + //set_shape(game_data->row, shape, colour, 1, 1); } diff --git a/src/game/tetromino/shapes.c b/src/game/tetromino/shapes.c new file mode 100644 index 0000000..0108900 --- /dev/null +++ b/src/game/tetromino/shapes.c @@ -0,0 +1,40 @@ +#include "shapes.h" + +/* 0 1 2 3 */ +#define TET_SHAPE_O ((Shape)0xCC00) // 1100 1100 0000 0000 the O tetromino with no rotation +#define TET_SHAPE_I ((Shape)0x8888) // 1000 1000 1000 1000 the I tetromino with no rotation +#define TET_SHAPE_I_90 ((Shape)0x000F) // 0000 0000 0000 1111 the I tetromino with a no rotation +#define TET_SHAPE_S ((Shape)0x6C00) // 0110 1100 0000 0000 the S tetromino with no rotation +#define TET_SHAPE_S_90 ((Shape)0x8C40) // 1000 1100 0100 0000 the S tetromino with a no rotation +#define TET_SHAPE_Z ((Shape)0xC600) // 1100 0110 0000 0000 the Z tetromino with no rotation +#define TET_SHAPE_Z_90 ((Shape)0x4C80) // 0100 1100 1000 0000 the Z tetromino with a no rotation +#define TET_SHAPE_T ((Shape)0xE400) // 1110 0100 0000 0000 the T tetromino with no rotation +#define TET_SHAPE_T_90 ((Shape)0xCC80) // 1100 1100 1000 0000 the T tetromino with a no rotation +#define TET_SHAPE_T_180 ((Shape)0x4E00) // 0100 1110 0000 0000 the T tetromino with a 180° rotation +#define TET_SHAPE_T_270 ((Shape)0x2620) // 0010 0110 0010 0000 the T tetromino with a 270° rotation +#define TET_SHAPE_L ((Shape)0x88C0) // 1000 1000 1100 0000 the L tetromino with no rotation +#define TET_SHAPE_L_90 ((Shape)0xE800) // 1110 1000 0000 0000 the L tetromino with a no rotation +#define TET_SHAPE_L_180 ((Shape)0xC440) // 1100 0100 0100 0000 the L tetromino with a 180° rotation +#define TET_SHAPE_L_270 ((Shape)0x02E0) // 0000 0010 1110 0000 the L tetromino with a 270° rotation +#define TET_SHAPE_J ((Shape)0x44C0) // 0100 0100 1100 0000 the J tetromino with no rotation +#define TET_SHAPE_J_90 ((Shape)0x8E00) // 1000 1110 0000 0000 the J tetromino with a no rotation +#define TET_SHAPE_J_180 ((Shape)0xC880) // 1100 1000 1000 0000 the J tetromino with a 180° rotation +#define TET_SHAPE_J_270 ((Shape)0xC400) // 1110 0010 0000 0000 the J tetromino with a 270° rotation + +Shape shape_from_id(ShapeId id) { + // clang-format off + static const Shape shapes[TETROMINO_COUNT][4] = { + // 0° 90° 180° 170° + {TET_SHAPE_O, TET_SHAPE_O, TET_SHAPE_O, TET_SHAPE_O}, + {TET_SHAPE_I, TET_SHAPE_I_90, TET_SHAPE_I, TET_SHAPE_I_90}, + {TET_SHAPE_S, TET_SHAPE_S_90, TET_SHAPE_S, TET_SHAPE_S_90}, + {TET_SHAPE_Z, TET_SHAPE_Z_90, TET_SHAPE_Z, TET_SHAPE_Z_90}, + {TET_SHAPE_T, TET_SHAPE_T_90, TET_SHAPE_T, TET_SHAPE_T_90}, + {TET_SHAPE_L, TET_SHAPE_L_90, TET_SHAPE_L_180, TET_SHAPE_L_270}, + {TET_SHAPE_J, TET_SHAPE_J_90, TET_SHAPE_J_180, TET_SHAPE_J_270}, + }; + // clang-format on + + // first 3 bits is the shape type, the rest is rotation data + return shapes[id & 7][id >> 3]; +} diff --git a/src/game/tetromino/shapes.h b/src/game/tetromino/shapes.h index 0b2613c..e87eb72 100644 --- a/src/game/tetromino/shapes.h +++ b/src/game/tetromino/shapes.h @@ -1,37 +1,29 @@ #pragma once #include -#define SHAPE_WIDTH 4 -#define SHAPE_HEIGHT 4 - -#define TETROMINO_COUNT 7 typedef uint16_t Shape; -enum { - // clang-format off - /* 0 1 2 3 */ - TETROMINO_I = 0x8888, // 1000 1000 1000 1000 the I tetromino with no rotation - TETROMINO_I_90 = 0x000F, // 0000 0000 0000 1111 the I tetromino with a no rotation - TETROMINO_O = 0xCC00, // 1100 1100 0000 0000 the O tetromino with no rotation - TETROMINO_T = 0xE400, // 1110 0100 0000 0000 the T tetromino with no rotation - TETROMINO_T_90 = 0xCC80, // 1100 1100 1000 0000 the T tetromino with a no rotation - TETROMINO_T_180 = 0x4E00, // 0100 1110 0000 0000 the T tetromino with a 180° rotation - TETROMINO_T_270 = 0x2620, // 0010 0110 0010 0000 the T tetromino with a 270° rotation - TETROMINO_L = 0x88C0, // 1000 1000 1100 0000 the L tetromino with no rotation - TETROMINO_L_90 = 0xE800, // 1110 1000 0000 0000 the L tetromino with a no rotation - TETROMINO_L_180 = 0xC440, // 1100 0100 0100 0000 the L tetromino with a 180° rotation - TETROMINO_L_270 = 0x02E0, // 0000 0010 1110 0000 the L tetromino with a 270° rotation - TETROMINO_J = 0x44C0, // 0100 0100 1100 0000 the J tetromino with no rotation - TETROMINO_J_90 = 0x8E00, // 1000 1110 0000 0000 the J tetromino with a no rotation - TETROMINO_J_180 = 0xC880, // 1100 1000 1000 0000 the J tetromino with a 180° rotation - TETROMINO_J_270 = 0xC400, // 1110 0010 0000 0000 the J tetromino with a 270° rotation - TETROMINO_S = 0x6C00, // 0110 1100 0000 0000 the S tetromino with no rotation - TETROMINO_S_90 = 0x8C40, // 1000 1100 0100 0000 the S tetromino with a no rotation - TETROMINO_Z = 0xC600, // 1100 0110 0000 0000 the Z tetromino with no rotation - TETROMINO_Z_90 = 0x4C80, // 0100 1100 1000 0000 the Z tetromino with a no rotation - // clang-format on -}; typedef uint8_t ShapeRow; +typedef uint8_t ShapeId; +enum { + TETROMINO_O = 0, + TETROMINO_I = 1, + TETROMINO_S = 2, + TETROMINO_Z = 3, + TETROMINO_T = 4, + TETROMINO_L = 5, + TETROMINO_J = 6, + TETROMINO_ROTATED_90 = 8, + TETROMINO_ROTATED_180 = 16, + TETROMINO_ROTATED_270 = 24, +}; + +#define SHAPE_WIDTH ((uint8_t)(sizeof(Shape) * 8 / 2)) +#define SHAPE_HEIGHT ((uint8_t)(sizeof(Shape) * 8 / 2)) +#define TETROMINO_COUNT 7 + + + static inline ShapeRow shape_get_row(Shape shape, uint8_t index) { return shape >> (((SHAPE_HEIGHT - 1) - index) * 4) & 0xF; } @@ -39,3 +31,5 @@ static inline ShapeRow shape_get_row(Shape shape, uint8_t index) { static inline _Bool is_set(ShapeRow row, uint8_t index) { return (row >> ((SHAPE_WIDTH - 1) - index) & 1) != 0; } + +Shape shape_from_id(ShapeId id);