From 692f5744ad2afb4290958f889b272bf377efebf2 Mon Sep 17 00:00:00 2001 From: Klemen Plestenjak Date: Wed, 10 Jan 2024 19:38:56 +0100 Subject: [PATCH] Add options --- game/game_state.h | 23 ++++++++++++++++++ game/main.c | 60 +++++++++++++++++++++++++++++++++++++---------- 2 files changed, 70 insertions(+), 13 deletions(-) diff --git a/game/game_state.h b/game/game_state.h index 92b196e..c277374 100644 --- a/game/game_state.h +++ b/game/game_state.h @@ -19,8 +19,29 @@ typedef struct DrawData { f32 rotation; } DrawData; +typedef struct Options { + // Video + bool fullscreen; + bool vsync; + // Audio + f32 master; + f32 music; + f32 sound; +} Options; + +static Options getDefaultOptions() { + return (Options) { + .fullscreen = false, + .vsync = false, + .master = 5.0f, + .music = 5.0f, + .sound = 5.0f, + }; +} + typedef struct Game { GameScreen screen; + GameScreen screenPrevFrame; Camera2D camera; BzTileset tileset; BzTileMap map; @@ -29,6 +50,8 @@ typedef struct Game { Font font; + Options options; + struct { i64 wood; i64 iron; diff --git a/game/main.c b/game/main.c index dd37908..96a56b9 100644 --- a/game/main.c +++ b/game/main.c @@ -144,6 +144,24 @@ int cmpDrawData(const void *a, const void *b) { return cmpVal; } +bool serializeOptions(const char *path, const Options *opts) { + FILE *f = fopen(path, "w"); + size_t numWritten = fwrite(opts, sizeof(*opts), 1, f); + fclose(f); + return numWritten == 1; +} +bool deserializeOptions(const char *path, Options *optsOut) { + FILE *f = fopen(path, "r"); + Options opts; + size_t numRead = fread(&opts, sizeof(opts), 1, f); + fclose(f); + if (numRead == 1) { + *optsOut = opts; + return true; + } + return false; +} + bool init(void *userData) { // Center window int monitor = GetCurrentMonitor(); @@ -303,6 +321,18 @@ bool init(void *userData) { game->debug.drawPath = true; game->debug.inspecting = bzArrayCreate(ecs_entity_t, 10); + + // Load settings + const char *workDir = GetApplicationDirectory(); + char buf[FILENAME_MAX]; + snprintf(buf, sizeof(buf), "%s%s", workDir, "settings"); + Options opts; + if (deserializeOptions(buf, &opts)) { + game->options = opts; + } else { + game->options = getDefaultOptions(); + } + return true; } void deinit(void *userData) { @@ -311,6 +341,11 @@ void deinit(void *userData) { InputState *input = ecs_singleton_get_mut(ECS, InputState); SoundState *sounds = ecs_singleton_get_mut(ECS, SoundState); + const char *workDir = GetApplicationDirectory(); + char buf[FILENAME_MAX]; + snprintf(buf, sizeof(buf), "%s%s", workDir, "settings"); + serializeOptions(buf, &game->options); + unloadMap(game); // Destroy queries @@ -588,6 +623,7 @@ static void renderMainMenu(Game *game, float dt) { loadMap(game, "assets/maps/pathing_test.tmj"); } if (uiMainMenuButton("Settings")) { + game->screenPrevFrame = game->screen; game->screen = SCREEN_SETTINGS; } if (uiMainMenuButton("Exit")) { @@ -616,19 +652,17 @@ static void renderSettings(Game *game, float dt) { .type = BZ_UI_LAYOUT_FLEX_BOX, .flags = BZ_UI_FLEX_DIR_COLUMN | BZ_UI_FLEX_JUSTIFY_CENTER | BZ_UI_FLEX_ALIGN_CENTER }); - static bool fullscreen = false; - static bool vsync = false; + static Options opts; + if (game->screenPrevFrame != SCREEN_SETTINGS) + opts = game->options; uiSettingsLabel("Video"); - uiSettingsCheckbox("Fullscreen", &fullscreen); - uiSettingsCheckbox("V-Sync", &vsync); + uiSettingsCheckbox("Fullscreen", &opts.fullscreen); + uiSettingsCheckbox("V-Sync", &opts.vsync); - static f32 master = 50.0f; - static f32 music = 50.0f; - static f32 sound = 50.0f; uiSettingsLabel("Audio"); - uiSettingsSlider("Master: ", &master); - uiSettingsSlider("Music: ", &music); - uiSettingsSlider("Sound: ", &sound); + uiSettingsSlider("Master: ", &opts.master); + uiSettingsSlider("Music: ", &opts.music); + uiSettingsSlider("Sound: ", &opts.sound); bzUIPopParent(UI); bzUIPushDiv(UI, (BzUISize) {BZ_UI_SIZE_REL_PARENT, 0.8f}, @@ -642,9 +676,10 @@ static void renderSettings(Game *game, float dt) { game->screen = SCREEN_MAIN_MENU; } if (uiSettingsButton("Reset")) { - + opts = game->options; } if (uiSettingsButton("Apply")) { + game->options = opts; game->screen = SCREEN_MAIN_MENU; } @@ -678,10 +713,9 @@ void render(float dt, void *userData) { renderGame(game, dt); drawOverScreen(shadow); renderSettings(game, dt); + game->screenPrevFrame = SCREEN_SETTINGS; break; } - - } void igInspectComp(const char *label, ecs_entity_t entity, ecs_entity_t comp, ImGuiCompFn fn) {