huge portion of rewrite done, basic movement updates to UI

This commit is contained in:
John Landers
2024-01-14 22:48:15 -06:00
parent eac68c789e
commit f2b9a0842a
14 changed files with 573 additions and 195 deletions

View File

@@ -1,5 +1,8 @@
#include "m_block.h"
#include <limits.h>
#include <stdlib.h>
#include <time.h>
#define BLOCK_ARRAY_COLUMNS 10
#define BLOCK_ARRAY_ROWS 20
@@ -7,44 +10,357 @@
block_t *_blocks[BLOCK_ARRAY_LENGTH];
block_t *_updated_blocks[BLOCK_ARRAY_LENGTH];
int updated_blocks_current_length = 0;
block_t *_recently_spawned_blocks[BLOCKS_WITHIN_A_TETROMINO];
int _updated_blocks_current_length = 0;
int _spawn_tetromino_flag = 1;
int _can_spawn_tetromino_flag = 1;
btype_t _next_block_type = bt_Empty;
const int _spawn_x = BLOCK_ARRAY_COLUMNS / 2 - 1;
const point_offset_t _shift_down_offset = {0, 1};
const point_offset_t _shift_left_offset = {-1, 0};
const point_offset_t _shift_right_offset = {1, 0};
void (*on_block_spawn)(block_t *blocks[BLOCKS_WITHIN_A_TETROMINO]);
void M_Create_Blocks(void)
{
int i;
for (i = 0; i < BLOCK_ARRAY_LENGTH; i++)
{
block_t *block = malloc(sizeof(block_t));
block->point.x = i % BLOCK_ARRAY_COLUMNS;
block->point.y = i / BLOCK_ARRAY_COLUMNS;
block->type = bt_Empty;
void M_B_Create_Blocks(void) {
int i;
for (i = 0; i < BLOCK_ARRAY_LENGTH; i++) {
block_t *block = malloc(sizeof(block_t));
block->id = -1;
block->point.x = i % BLOCK_ARRAY_COLUMNS;
block->point.y = i / BLOCK_ARRAY_COLUMNS;
block->type = bt_Empty;
_blocks[i] = block;
_blocks[i] = block;
}
}
void M_B_Update_Blocks(void) {
M_B_Reset_Blocks_Updated();
if (_spawn_tetromino_flag) {
M_B_Spawn_Blocks();
M_B_Set_Next_Block_Type();
_spawn_tetromino_flag = 0;
}
}
block_t **M_B_Get_Blocks(int *length) {
*length = BLOCK_ARRAY_LENGTH;
return _blocks;
}
block_t **M_B_Get_Updated_Blocks(int *length) {
*length = _updated_blocks_current_length;
return _updated_blocks;
}
void M_B_Destroy_Blocks(void) {
int i;
for (i = 0; i < BLOCK_ARRAY_LENGTH; i++) {
free(_blocks[i]);
}
}
void M_B_Reset_Blocks_Updated(void) { _updated_blocks_current_length = 0; }
void M_B_On_Block_Spawn(void (*callback)(block_t **blocks)) {
on_block_spawn = callback;
}
void M_B_Spawn_Blocks(void) {
struct point_offset_t offsets[BLOCKS_WITHIN_A_TETROMINO];
if (_next_block_type == bt_Empty) {
M_B_Set_Next_Block_Type();
}
switch (_next_block_type) {
case bt_I:
offsets[0].x_offset = 0;
offsets[0].y_offset = 0;
offsets[1].x_offset = 0;
offsets[1].y_offset = 1;
offsets[2].x_offset = 0;
offsets[2].y_offset = 2;
offsets[3].x_offset = 0;
offsets[3].y_offset = 3;
break;
case bt_J:
offsets[0].x_offset = 2;
offsets[0].y_offset = 0;
offsets[1].x_offset = 0;
offsets[1].y_offset = 1;
offsets[2].x_offset = 1;
offsets[2].y_offset = 1;
offsets[3].x_offset = 2;
offsets[3].y_offset = 1;
break;
case bt_L:
offsets[0].x_offset = 0;
offsets[0].y_offset = 0;
offsets[1].x_offset = 0;
offsets[1].y_offset = 1;
offsets[2].x_offset = 1;
offsets[2].y_offset = 1;
offsets[3].x_offset = 2;
offsets[3].y_offset = 1;
break;
case bt_O:
offsets[0].x_offset = 0;
offsets[0].y_offset = 0;
offsets[1].x_offset = 1;
offsets[1].y_offset = 0;
offsets[2].x_offset = 0;
offsets[2].y_offset = 1;
offsets[3].x_offset = 1;
offsets[3].y_offset = 1;
break;
case bt_S:
offsets[0].x_offset = 1;
offsets[0].y_offset = 0;
offsets[1].x_offset = 2;
offsets[1].y_offset = 0;
offsets[2].x_offset = 0;
offsets[2].y_offset = 1;
offsets[3].x_offset = 1;
offsets[3].y_offset = 1;
break;
case bt_T:
offsets[0].x_offset = 1;
offsets[0].y_offset = 0;
offsets[1].x_offset = 0;
offsets[1].y_offset = 1;
offsets[2].x_offset = 1;
offsets[2].y_offset = 1;
offsets[3].x_offset = 2;
offsets[3].y_offset = 1;
break;
case bt_Z:
offsets[0].x_offset = 0;
offsets[0].y_offset = 0;
offsets[1].x_offset = 1;
offsets[1].y_offset = 0;
offsets[2].x_offset = 1;
offsets[2].y_offset = 1;
offsets[3].x_offset = 2;
offsets[3].y_offset = 1;
break;
default:
break;
}
if (M_B_Try_Spawn_Blocks_With_Offset(offsets)) {
on_block_spawn(_recently_spawned_blocks);
}
}
void M_B_Set_Next_Block_Type(void) {
_next_block_type = M_B_Get_Random_Block_Type();
}
btype_t M_B_Get_Random_Block_Type(void) {
srand(time(NULL));
return (btype_t)(rand() % 7) + 1;
}
int M_B_Try_Spawn_Blocks_With_Offset(point_offset_t *offsets) {
int i = 0, kinda_unique_id = M_B_Generate_Block_Id();
point_t spawn_point;
block_t *spawn_block;
while (i < BLOCKS_WITHIN_A_TETROMINO) {
spawn_point.x = _spawn_x + offsets->x_offset;
spawn_point.y = offsets->y_offset;
spawn_block = M_B_Get_Block_At_Point(spawn_point);
if (spawn_block->type != bt_Empty) {
_can_spawn_tetromino_flag = 0;
return 0;
}
spawn_block->id = kinda_unique_id;
M_B_Set_Block_Type(spawn_block, _next_block_type);
_recently_spawned_blocks[i] = spawn_block;
i++;
offsets++;
}
return 1;
}
void M_Update_Blocks(void)
{
/* implement */
block_t *M_B_Get_Block_At_Point(point_t point) {
return _blocks[(point.x % BLOCK_ARRAY_COLUMNS) +
(point.y * BLOCK_ARRAY_COLUMNS)];
}
block_t **M_Get_Blocks(int *length)
{
*length = BLOCK_ARRAY_LENGTH;
return _blocks;
void M_B_Set_Block_Type(block_t *block, btype_t type) {
block->type = type;
M_B_Register_Updated_block(block);
}
block_t **M_Get_Updated_Blocks(int *length)
{
*length = updated_blocks_current_length;
return _updated_blocks;
void M_B_Register_Updated_block(block_t *block) {
if (_updated_blocks_current_length < BLOCK_ARRAY_LENGTH) {
_updated_blocks[_updated_blocks_current_length] = block;
_updated_blocks_current_length++;
}
}
void M_Destroy_Blocks(void)
{
int i;
for (i = 0; i < BLOCK_ARRAY_LENGTH; i++)
{
free(_blocks[i]);
int M_B_Can_Move_Blocks_Left(block_t **blocks) {
int i = 0, result = 1;
for (; i < BLOCKS_WITHIN_A_TETROMINO; i++) {
if (!M_B_Can_Move_Block_Left(*(blocks[i]))) {
result = 0;
break;
}
}
return result;
}
int M_B_Can_Move_Block_Left(block_t block) {
point_t left_adj_block_point;
left_adj_block_point.x = block.point.x - 1;
left_adj_block_point.y = block.point.y;
if (left_adj_block_point.x < 0) {
return 0;
} else if (M_B_Point_Intersects_Static_Block(left_adj_block_point,
block.id)) {
return 0;
} else {
return 1;
}
}
block_t *M_B_Move_Block_Left(block_t *block) {
/* Kinda dupe from right and down, might consolidate */
block_t *updated_block = M_B_Get_Block_At_Offset(block, _shift_left_offset);
updated_block->id = block->id;
M_B_Set_Block_Type(updated_block, block->type);
block->id = -1;
M_B_Set_Block_Type(block, bt_Empty);
return updated_block;
}
int M_B_Can_Move_Blocks_Right(block_t **blocks) {
int i = 0, result = 1;
for (; i < BLOCKS_WITHIN_A_TETROMINO; i++) {
if (!M_B_Can_Move_Block_Right(*(blocks[i]))) {
result = 0;
break;
}
}
return result;
}
int M_B_Can_Move_Block_Right(block_t block) {
point_t right_adj_block_point;
right_adj_block_point.x = block.point.x + 1;
right_adj_block_point.y = block.point.y;
if (right_adj_block_point.x >= BLOCK_ARRAY_COLUMNS) {
return 0;
} else if (M_B_Point_Intersects_Static_Block(right_adj_block_point,
block.id)) {
return 0;
} else {
return 1;
}
}
block_t *M_B_Move_Block_Right(block_t *block) {
block_t *updated_block = M_B_Get_Block_At_Offset(block, _shift_right_offset);
updated_block->id = block->id;
M_B_Set_Block_Type(updated_block, block->type);
block->id = -1;
M_B_Set_Block_Type(block, bt_Empty);
return updated_block;
}
int M_B_Can_Move_Blocks_Down(block_t **blocks) {
int i = 0, result = 1;
for (; i < BLOCKS_WITHIN_A_TETROMINO; i++) {
if (!M_B_Can_Move_Block_Down(*(blocks[i]))) {
result = 0;
break;
}
}
if (!result) {
_spawn_tetromino_flag = 1;
}
return result;
}
int M_B_Can_Move_Block_Down(block_t block) {
point_t bottom_adj_block_point;
bottom_adj_block_point.x = block.point.x;
bottom_adj_block_point.y = block.point.y + 1;
if (bottom_adj_block_point.y >= BLOCK_ARRAY_ROWS) {
return 0;
} else if (M_B_Point_Intersects_Static_Block(bottom_adj_block_point,
block.id)) {
return 0;
} else {
return 1;
}
}
block_t *M_B_Move_Block_Down(block_t *block) {
block_t *updated_block = M_B_Get_Block_At_Offset(block, _shift_down_offset);
updated_block->id = block->id;
M_B_Set_Block_Type(updated_block, block->type);
block->id = -1;
M_B_Set_Block_Type(block, bt_Empty);
return updated_block;
}
block_t *M_B_Get_Block_At_Offset(block_t *block, point_offset_t offset) {
point_t updated_point;
updated_point.x = block->point.x + offset.x_offset;
updated_point.y = block->point.y + offset.y_offset;
return M_B_Get_Block_At_Point(updated_point);
}
int M_B_Point_Intersects_Static_Block(point_t point, int id) {
int result = 0;
block_t *block_at_point = M_B_Get_Block_At_Point(point);
if (block_at_point->type != bt_Empty && block_at_point->id != id) {
result = 1;
}
return result;
}
int M_B_Generate_Block_Id(void) {
/* The odds of this not being unique are high enough, surely
SURELY
*/
srand(time(NULL));
return rand();
}