aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/all.h15
-rw-r--r--source/game.c76
-rw-r--r--source/gamemode.c71
-rw-r--r--source/main.c9
-rw-r--r--source/raylib.c6
-rw-r--r--source/update.c61
6 files changed, 107 insertions, 131 deletions
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;
}
}
}