From 97ddf26c3d83a9ae2a99a3d6d2884a3ebecd3e03 Mon Sep 17 00:00:00 2001 From: Emil Williams Date: Sun, 15 Feb 2026 02:44:29 +0000 Subject: config_t 2, bomb minus bugs --- source/all.h | 15 ++++++----- source/game.c | 76 ++++++++++++++++++++++++++++++------------------------- source/gamemode.c | 71 ++++++++++----------------------------------------- source/main.c | 9 ++++--- source/raylib.c | 6 ++++- source/update.c | 61 ++++++++++++++++++++++++-------------------- 6 files changed, 107 insertions(+), 131 deletions(-) (limited to 'source') diff --git a/source/all.h b/source/all.h index 93ea881..d1f2761 100644 --- a/source/all.h +++ b/source/all.h @@ -19,8 +19,6 @@ (void) 0 /* ... */ #define StepStop(prefix) \ - prefix##s_per_second++; \ - prefix##_total++; \ prefix##_last = timespec_add(prefix##_last, prefix##_interval); \ if (timespec_cmp(prefix##_last, now) < 0) { \ prefix##_last = now; \ @@ -178,13 +176,16 @@ typedef struct { Rectangle enemy[4]; } enemies_t; +#define CONFIG_STRING_LIMIT 128 typedef struct { u16 resolution_x, resolution_y; u8 fps, ups; - char font[128]; - char spritesheet[128]; + char font[CONFIG_STRING_LIMIT]; + char spritesheet[CONFIG_STRING_LIMIT]; + char window_name[CONFIG_STRING_LIMIT]; u16 spritesheet_scale; /* --- */ + u8 player_count; u8 map_x, map_y; } config_t; @@ -205,13 +206,13 @@ typedef struct { /* game.c */ -void GameStart(char * program_name); +void GameStart(config_t config); void GameResize(game_t * game); +void GameReinitialize(game_t * game); /* gamemode.c */ -void MultiPlayer(game_t * game, u16 width, u16 height, u8 player_count); -void SinglePlayer(game_t * game, u16 width, u16 height); +void MultiPlayer(game_t * game); /* update.c */ diff --git a/source/game.c b/source/game.c index ea02cbb..b17bf73 100644 --- a/source/game.c +++ b/source/game.c @@ -1,13 +1,19 @@ #include "all.h" -static void GameInitialize(game_t * game, char * window_name); +static void GameInitialize(game_t * game); static void GameDeinitialize(game_t * game); static void GameLoop(game_t * game); static void GameReport(game_t * game, f32 fps, f32 ups, u32 total_fps, u32 total_ups); -void GameStart(char * program_name) { +void GameReinitialize(game_t * game) { + GameDeinitialize(game); + GameInitialize(game); +} + +void GameStart(config_t config) { _Alignas(64) game_t game[1] = {0}; - GameInitialize(game, program_name); + game->config = config; + GameInitialize(game); GameLoop(game); GameDeinitialize(game); } @@ -33,19 +39,25 @@ void GameResize(game_t * game) { } } -static void GameInitialize(game_t * game, char * window_name) { - - game->config = (config_t) { - .resolution_x = 600, - .resolution_y = 600, - .fps = 60, - .ups = 30, - .font = "fonts/Atkinson/mono/AtkinsonHyperlegibleMono-Bold.otf", - .spritesheet = "assets/simple.png", - .spritesheet_scale = 128, - .map_x = 13, - .map_y = 13, - }; +static void GameInitialize(game_t * game) { + /* Strict parameters */ +#define DEFAULT(a, b) ((b) ? (b) : (a)) + game->config.resolution_x = MAX(200, DEFAULT(600, game->config.resolution_x)); + game->config.resolution_y = MAX(200, DEFAULT(600, game->config.resolution_y)); + game->config.fps = MAX(1, DEFAULT(60, game->config.fps)); + game->config.ups = MAX(1, DEFAULT(30, game->config.ups)); + if (!*game->config.font) + { strlcpy(game->config.font, "fonts/Atkinson/mono/AtkinsonHyperlegibleMono-Bold.otf", CONFIG_STRING_LIMIT); } + if (!*game->config.spritesheet) + { strlcpy(game->config.spritesheet, "assets/simple.png", CONFIG_STRING_LIMIT); } + game->config.spritesheet_scale = DEFAULT(128, game->config.spritesheet_scale); + game->config.map_x = MAX(5, DEFAULT(13, game->config.map_x)); + game->config.map_y = MAX(5, DEFAULT(13, game->config.map_y)); + game->config.player_count = CLAMP(DEFAULT(4, game->config.player_count), 1, 4); + if (!*game->config.window_name) + { strlcpy(game->config.window_name, "Unset Window Name, lol lmao", CONFIG_STRING_LIMIT); } +#undef DEFAULT + { int t = game->config.spritesheet_scale; /* better, but not really good, it's FINE */ @@ -93,7 +105,7 @@ static void GameInitialize(game_t * game, char * window_name) { memcpy(game->enemies.enemy, enemy, sizeof(enemy)); } - MultiPlayer(game, game->config.map_x, game->config.map_y, 4); + MultiPlayer(game); game->tiles.color = (rand() % 4) | ((rand() % 4) << 2) | ((rand() % 4) << 4) | GAME_OPAQUE; if (game->tiles.color == GAME_OPAQUE) { game->tiles.color |= GAME_WHITE; } @@ -104,9 +116,7 @@ static void GameInitialize(game_t * game, char * window_name) { /* :config */ game->font = DefaultFont(game->config.font); - /* this is retarded (intentionally) */ - RaylibInitialize(game->config.resolution_x-1, game->config.resolution_y-1, window_name, game->font); - SetWindowSize(game->config.resolution_x, game->config.resolution_y); + RaylibInitialize(game->config.resolution_x, game->config.resolution_y, game->config.window_name, game->font); GameRecalculateViewport(game); game->spritesheet = LoadTexture(game->config.spritesheet); @@ -123,19 +133,11 @@ static void GameDeinitialize(game_t * game) { static void GameLoop(game_t * game) { - #define StepSimpleStart(prefix,linear) \ - prefix##_delta = timespec_sub(now, prefix##_last); \ - if (timespec_cmp(prefix##_delta, linear) >= 0) { \ - (void)0 - - #define StepSimpleStop(prefix) \ - prefix##_last = now; \ - } - timespec_t now, update_interval = {0, (f64) TIMESPEC_HZ / game->config.ups}, frame_interval = {0, (f64) TIMESPEC_HZ / game->config.fps}, + print_interval = {0, (f64) TIMESPEC_HZ }, update_last, frame_last, print_last, update_delta, frame_delta, print_delta, wait; @@ -153,10 +155,14 @@ static void GameLoop(game_t * game) { while (1) { StepStart(update); + updates_per_second++; + update_total++; if (Update(game, now)) { return; } StepStop(update); StepStart(frame); + frames_per_second++; + frame_total++; clock_gettime(CLOCK_MONOTONIC, &now); interpolation = CLAMP( @@ -178,14 +184,14 @@ static void GameLoop(game_t * game) { nanosleep(&wait, NULL); } - StepSimpleStart(print, one_second); + StepStart(print); GameReport(game, - round(frames_per_second / TIMESPEC_TO_F64(print_delta)), - round(updates_per_second / TIMESPEC_TO_F64(print_delta)), - frame_total, - update_total); + round(frames_per_second / TIMESPEC_TO_F64(print_delta)), + round(updates_per_second / TIMESPEC_TO_F64(print_delta)), + frame_total, + update_total); frames_per_second = updates_per_second = 0; - StepSimpleStop(print); + StepStop(print); clock_gettime(CLOCK_MONOTONIC, &now); } diff --git a/source/gamemode.c b/source/gamemode.c index cf5d06a..9c1055a 100644 --- a/source/gamemode.c +++ b/source/gamemode.c @@ -1,8 +1,16 @@ #include "all.h" -void MultiPlayer(game_t * game, u16 width, u16 height, u8 player_count) { +void MultiPlayer(game_t * game) { + u8 width = game->config.map_x; + u8 height = game->config.map_y; int i, j; + for (i = 0; i < PLAYER_LIMIT; ++i) { + for (j = 0; j < BOMB_LIMIT; ++j) { + game->bombs.timer[i][j] = 0; + } + } + for (i = 0; i < width; ++i) { for (j = 0; j < height; ++j) { game->tiles.state[i][j]._ = rand() % 10 ? IMPASSIBLE_BREAKABLE_WALL : PASSIBLE_NOTHING; @@ -17,8 +25,8 @@ void MultiPlayer(game_t * game, u16 width, u16 height, u8 player_count) { bzero(game->players.state, sizeof(*game->players.state) * PLAYER_LIMIT); - for (i = 0; i < MIN(PLAYER_LIMIT, player_count); ++i) { - game->players.state[i].bomb_limit = 1; + for (i = 0; i < MIN(PLAYER_LIMIT, game->config.player_count); ++i) { + game->players.state[i].bomb_limit = 15; game->players.state[i].power = 2; game->players.state[i].speed = 2; game->players.state[i].alive = 1; @@ -37,7 +45,7 @@ void MultiPlayer(game_t * game, u16 width, u16 height, u8 player_count) { GAME_BLUE | GAME_OPAQUE, }; - for (i = 0; i < MIN(player_count, PLAYER_LIMIT); ++i) { + for (i = 0; i < MIN(game->config.player_count, PLAYER_LIMIT); ++i) { game->players.x[i] = player_x[i % 4]; game->players.y[i] = player_y[i % 4]; game->players.color[i] = color[i % 4]; @@ -49,7 +57,7 @@ void MultiPlayer(game_t * game, u16 width, u16 height, u8 player_count) { u8 offset_y[12] = {0, 0, 1, height-1, height-1, height-2, 0, 0, 1, height-1, height-1, height-2}; - for (i = 0; i < MIN((player_count * 3), 12); ++i) { + for (i = 0; i < MIN((game->config.player_count * 3), 12); ++i) { game->tiles.state[offset_x[i]][offset_y[i]]._ = PASSIBLE_NOTHING; } @@ -60,56 +68,3 @@ void MultiPlayer(game_t * game, u16 width, u16 height, u8 player_count) { printf("\n"); } } - -/* missing proper player / bomb / enemy initialization */ -void SinglePlayer(game_t * game, u16 width, u16 height) { - u16 i, j; - - for (i = 0; i < width; ++i) { - for (j = 0; j < height; ++j) { - game->tiles.state[i][j]._ = rand() % 10 ? IMPASSIBLE_BREAKABLE_WALL : PASSIBLE_NOTHING; - } - } - - u16 x, y; - int distance, direction; - for (i = 0; i < ENEMY_LIMIT; ++i) { - distance = rand() % MIN(width, height); - direction = rand() % MOVEMENT_LAST; - x = rand() % width; - y = rand() % height; - game->enemies.x[i] = x; - game->enemies.y[i] = y; - game->enemies.movement[i] = direction; - game->tiles.state[x][y]._ = PASSIBLE_NOTHING; - for (j = -(distance/2); j+(distance/2) < distance; ++j) { - game->tiles.state - [x + (j * (direction == MOVEMENT_HORIZONTAL) * (x + j < width ))] - [y + (j * (direction == MOVEMENT_VERTICAL ) * (y + j < height))]._ = PASSIBLE_NOTHING; - } - } - - for (i = 1; i < width; i += 2) { - for (j = 1; j < height; j += 2) { - game->tiles.state[i][j]._ = IMPASSIBLE_WALL; - } - } - - game->tiles.state[0][0]._ = PASSIBLE_NOTHING; - game->tiles.state[1][0]._ = PASSIBLE_NOTHING; - game->tiles.state[0][1]._ = PASSIBLE_NOTHING; - - game->players.x[0] = 0; - game->players.y[0] = 0; - game->players.state[0].bomb_limit = 1; - game->players.state[0].power = 2; - game->players.state[0].speed = 3; - game->players.state[0].alive = 1; - - for (i = 0; i < width; ++i) { - for (j = 0; j < height; ++j) { - printf("%3d ", game->tiles.state[i][j]._); - } - printf("\n"); - } -} diff --git a/source/main.c b/source/main.c index 370e463..70ab419 100644 --- a/source/main.c +++ b/source/main.c @@ -3,10 +3,13 @@ int Main(int count, char ** arguments) { (void)count; - char * program_name = arguments[0]; + char * window_name = arguments[0]; + config_t config = (config_t){0}; + char * p = strchr(window_name, '/'); + strlcpy(config.window_name, p ? p+1 : window_name, CONFIG_STRING_LIMIT); srand(time(NULL)); - Root(program_name); - GameStart(program_name); + Root(window_name); + GameStart(config); return 0; } diff --git a/source/raylib.c b/source/raylib.c index d96aa4a..33ac72c 100644 --- a/source/raylib.c +++ b/source/raylib.c @@ -41,7 +41,11 @@ void RaylibInitialize(int horizontal, int vertical, char * window_name, Font def SetWindowState(FLAG_WINDOW_HIDDEN); /* we should spawn this in the center of the screen and have our window scale to the limit of the screen */ InitAudioDevice(); - SetWindowPosition(0, 0); + int monitor = GetCurrentMonitor(); + int width = GetMonitorWidth(monitor), height = GetMonitorHeight(monitor); + SetWindowPosition( + width/2-horizontal/2, + height/2-vertical/2); GuiLoadStyleDarkSimple(); GuiSetFont(default_font); } diff --git a/source/update.c b/source/update.c index 9cec977..2e8b282 100644 --- a/source/update.c +++ b/source/update.c @@ -2,9 +2,9 @@ static void CheckKilled(game_t * game); static void UpdateExplosions(game_t * game); -static void PlaceExplosive(game_t * game); +static void PlaceBomb(game_t * game); static int CheckInputDebug(game_t * game); -static void CheckInputPlaceExplosive(game_t * game); +static void CheckInputPlaceBomb(game_t * game); static void CheckInputMovement(game_t * game); static void UpdatePlayer(game_t * game); static void UpdateBomb(game_t * game); @@ -15,7 +15,7 @@ i16 Update(game_t * game, timespec_t now) { GameResize(game); if (CheckInputDebug(game)) { return 1; } CheckInputMovement(game); - CheckInputPlaceExplosive(game); + CheckInputPlaceBomb(game); UpdatePlayer(game); UpdateBomb(game); CheckKilled(game); @@ -46,7 +46,7 @@ static void UpdateExplosions(game_t * game) { } } -static void PlaceExplosive(game_t * game) { +static void PlaceBomb(game_t * game) { auto state = &game->players.state[game->client]; if (state->bomb_count < state->bomb_limit) { game->tiles.state @@ -57,7 +57,7 @@ static void PlaceExplosive(game_t * game) { game->bombs.state[game->client][state->bomb_count].power = state->power; game->bombs.state[game->client][state->bomb_count].pierce = state->pierce; game->bombs.state[game->client][state->bomb_count].bounce = state->bounce; - game->bombs.timer[game->client][state->bomb_count] = game->config.ups * 2; + game->bombs.timer[game->client][state->bomb_count] = game->config.ups; ++state->bomb_count; } } @@ -66,7 +66,8 @@ static int CheckInputDebug(game_t * game) { switch (GetKeyPressed()) { case KEY_ESCAPE: return 1; #ifndef NDEBUG - case KEY_R: MultiPlayer(game, game->config.map_x, game->config.map_y, 4); break; + case KEY_F1: GameReinitialize(game); break; + case KEY_R: MultiPlayer(game); break; case KEY_T: if (game->client < 3) game->client++; break; case KEY_G: if (game->client != 0) game->client--; break; #endif @@ -74,13 +75,13 @@ static int CheckInputDebug(game_t * game) { return 0; } -static void CheckInputPlaceExplosive(game_t * game) { +static void CheckInputPlaceBomb(game_t * game) { auto state = &game->players.state[game->client]; if ((IsKeyPressed(KEY_FIVE) || IsKeyPressed(KEY_SPACE) || IsKeyPressed(KEY_U) || IsKeyPressed(KEY_O) || IsKeyPressed(KEY_M) || IsKeyPressed(KEY_PERIOD) || IsKeyPressed(KEY_Z) || IsKeyPressed(KEY_C) || IsKeyPressed(KEY_Q) || IsKeyPressed(KEY_E) || IsKeyPressed(KEY_ENTER)) && state->alive) - { PlaceExplosive(game); } + { PlaceBomb(game); } } @@ -133,31 +134,37 @@ static void UpdatePlayer(game_t * game) { } static void UpdateBomb(game_t * game) { - u16 * b = *game->bombs.timer; + size_t i, j, k; ssize_t offset_x[4] = {-1, 1, 0, 0}, offset_y[4] = { 0, 0, -1, 1}; - size_t i, j; - for (i = 0; i < PLAYER_LIMIT * BOMB_LIMIT; ++i) { - if (b[i]) { - --b[i]; - if (!b[i]) { - /* game->tiles.state[(*game->bombs.x)[i]][(*game->bombs.y)[i]]._ = PASSIBLE_NOTHING; */ - /* explosion */ - for (j = 0; j < 4; ++j) { - i16 - rx = (*game->bombs.x)[i] + offset_x[j], - ry = (*game->bombs.y)[i] + offset_y[j]; - - if (game->tiles.state[rx][ry]._ & PASSIBLE || game->tiles.state[rx][ry]._ == IMPASSIBLE_BREAKABLE_WALL) { + for (i = 0; i < PLAYER_LIMIT; ++i) { + for (j = 0; j < BOMB_LIMIT; ++j) { + if (game->bombs.timer[i][j]) { + --game->bombs.timer[i][j]; + if (!game->bombs.timer[i][j]) { + ssize_t block[4] = {0}; + for (k = 0; k < 4 * game->players.state[i].power; ++k) { + if (block[k%4]) { continue; } + i16 + rx = game->bombs.x[i][j] + offset_x[k%4] * ((k / 4) + 1), + ry = game->bombs.y[i][j] + offset_y[k%4] * ((k / 4) + 1); if (rx < game->config.map_x && rx >= 0 - && ry < game->config.map_y && ry >= 0) - { game->tiles.state[rx][ry]._ = PASSIBLE_EXPLOSIVE_LETHAL; } + && ry < game->config.map_y && ry >= 0) + { + if (game->tiles.state[rx][ry]._ & PASSIBLE) { + game->tiles.state[rx][ry]._ = PASSIBLE_EXPLOSIVE_LETHAL; + } else if (game->tiles.state[rx][ry]._ == IMPASSIBLE_BREAKABLE_WALL) { + game->tiles.state[rx][ry]._ = PASSIBLE_EXPLOSIVE_LETHAL; + block[k%4] = 1; + } else { + block[k%4] = 1; + } + } } + game->tiles.state[game->bombs.x[i][j]][game->bombs.y[i][j]]._ = PASSIBLE_EXPLOSIVE_LETHAL; + --game->players.state[i].bomb_count; } - game->tiles.state[*game->bombs.x[i]][*game->bombs.y[i]]._ = PASSIBLE_EXPLOSIVE_LETHAL; - /* --- */ - --game->players.state[i>>2].bomb_count; } } } -- cgit v1.2.3