From a633c9cbdfce4f939a4e931c1b0882d32f488e75 Mon Sep 17 00:00:00 2001 From: Klemen Plestenjak Date: Mon, 29 Jan 2024 16:41:13 +0100 Subject: [PATCH] Implement FullScreen and FPS opts --- .gitignore | 2 ++ game/constants.h | 2 +- game/game_state.h | 25 +++++++++++------ game/main.c | 65 ++++++++++++++++++++++++++++---------------- game/systems/s_ui.c | 24 ++++++++-------- game/utils.h | 5 ++-- settings.ini | Bin 16 -> 0 bytes 7 files changed, 76 insertions(+), 47 deletions(-) delete mode 100644 settings.ini diff --git a/.gitignore b/.gitignore index 962ad24..09b2baa 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ venv/ scripts/__pycache__/ imgui.ini +settings.ini +game_data.ini diff --git a/game/constants.h b/game/constants.h index 2d8ea07..64c106b 100644 --- a/game/constants.h +++ b/game/constants.h @@ -15,7 +15,7 @@ typedef enum Player { // defined in main.c -extern const char *SETTINGS_PATH; +extern const char *GAME_DATA_SAVE_PATH; #endif //PIXELDEFENSE_CONSTANTS_H diff --git a/game/game_state.h b/game/game_state.h index 05f7d85..66ea5ab 100644 --- a/game/game_state.h +++ b/game/game_state.h @@ -26,23 +26,30 @@ typedef struct DrawData { typedef struct Options { // Video bool fullscreen; - bool vsync; + bool limitFps; // 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 GameData { + Options options; +} GameData; + +static GameData getDefaultGameData() { + return (GameData) { + .options = { + .fullscreen = false, + .limitFps = true, + .master = 0.5f, + .music = 0.5f, + .sound = 0.5f + } }; } + typedef struct PlayerResources { i64 wood; i64 food; @@ -63,7 +70,7 @@ typedef struct Game { Font font; - Options options; + GameData gameData; PlayerResources playerResources[PLAYER_COUNT]; Player player; diff --git a/game/main.c b/game/main.c index ff8c959..93f6548 100644 --- a/game/main.c +++ b/game/main.c @@ -18,7 +18,7 @@ #include "sounds.h" // Constants -const char *SETTINGS_PATH = "settings.ini"; +const char *GAME_DATA_SAVE_PATH = "game_data.ini"; // Constants end ECS_COMPONENT_DECLARE(Game); @@ -99,7 +99,7 @@ int cmpDrawData(const void *a, const void *b) { } -bool serializeOptions(const char *path, const Options *opts) { +bool serializeGameData(const char *path, const GameData *gameData) { #ifdef EMSCRIPTEN char buf[4096]; @@ -109,7 +109,7 @@ bool serializeOptions(const char *path, const Options *opts) { bzLogInfo("write path: %s", path); FILE *f = fopen(path, "w"); if (!f) return false; - size_t numWritten = fwrite(opts, sizeof(*opts), 1, f); + size_t numWritten = fwrite(gameData, sizeof(*gameData), 1, f); fclose(f); #ifdef EMSCRIPTEN // Sync FS @@ -122,7 +122,7 @@ bool serializeOptions(const char *path, const Options *opts) { return numWritten == 1; } -bool deserializeOptions(const char *path, Options *optsOut) { +bool deserializeGameData(const char *path, GameData *gameData) { #ifdef EMSCRIPTEN char buf[4096]; snprintf(buf, sizeof(buf), "%s%s", "/game/", path); @@ -134,15 +134,29 @@ bool deserializeOptions(const char *path, Options *optsOut) { bzLogInfo("start reading"); if (!f) return false; bzLogInfo("reading"); - Options opts; - size_t numRead = fread(&opts, sizeof(opts), 1, f); + GameData data; + size_t numRead = fread(&data, sizeof(data), 1, f); fclose(f); if (numRead == 1) { - *optsOut = opts; + *gameData = data; return true; } return false; } +void applyOptions(const Options *options) { + SoundState *sounds = ecs_singleton_get_mut(ECS, SoundState); + soundsApplyVolume(sounds, options->master, options->music, options->sound); + + bool isFullscreen = IsWindowFullscreen(); + bool wantFullscreen = options->fullscreen; + if (isFullscreen != wantFullscreen) + ToggleFullscreen(); + + if (options->limitFps) + SetTargetFPS(60); + else + SetTargetFPS(0); +} bool init(void *userData) { // Center window @@ -333,7 +347,7 @@ void deinit(void *userData) { InputState *input = ecs_singleton_get_mut(ECS, InputState); SoundState *sounds = ecs_singleton_get_mut(ECS, SoundState); - serializeOptions(SETTINGS_PATH, &game->options); + serializeGameData(GAME_DATA_SAVE_PATH, &game->gameData); unloadMap(game); @@ -379,25 +393,23 @@ void update(float dt, void *userData) { char titleBuf[32]; snprintf(titleBuf, sizeof(titleBuf), "FPS: %d | %.2f ms", GetFPS(), GetFrameTime() * 1000); - //SetWindowTitle(titleBuf); + SetWindowTitle(titleBuf); Game *game = ecs_singleton_get_mut(ECS, Game); InputState *input = ecs_singleton_get_mut(ECS, InputState); { - static bool optsLoaded = false; - if (!optsLoaded) { + static bool gameDataLoaded = false; + if (!gameDataLoaded) { // Load settings - const char *path = SETTINGS_PATH; - Options opts; - if (deserializeOptions(path, &opts)) { - game->options = opts; - } else { - game->options = getDefaultOptions(); + const char *path = GAME_DATA_SAVE_PATH; + GameData gameData = getDefaultGameData(); + if (deserializeGameData(path, &gameData)) { + bzLogWarning("Failed to read game data: %s.", path); } - SoundState *sounds = ecs_singleton_get_mut(ECS, SoundState); - soundsApplyVolume(sounds, opts.master, opts.music, opts.sound); - optsLoaded = true; + game->gameData = gameData; + applyOptions(&gameData.options); + gameDataLoaded = true; } } @@ -719,9 +731,16 @@ void imguiRender(float dt, void *userData) { } if (igCollapsingHeader_TreeNodeFlags("Resources", 0)) { PlayerResources resources = game->playerResources[game->player]; - igText("Wood: %lld", resources.wood); - igText("Food: %lld", resources.food); - igText("Gold: %lld", resources.gold); + i32 wood = resources.wood; + i32 food = resources.food; + i32 gold = resources.gold; + igSliderInt("Wood: ", &wood, 0, 10000, "%d", 0); + igSliderInt("Food: ", &food, 0, 10000, "%d", 0); + igSliderInt("Gold: ", &gold, 0, 10000, "%d", 0); + resources.wood = wood; + resources.food = food; + resources.gold = gold; + game->playerResources[game->player] = resources; igText("Pop: %lld", resources.pop); igText("Pop Capacity: %lld", resources.pop); } diff --git a/game/systems/s_ui.c b/game/systems/s_ui.c index 4d5a43d..d94fb27 100644 --- a/game/systems/s_ui.c +++ b/game/systems/s_ui.c @@ -278,17 +278,18 @@ void drawSettingsUI(Game *game, f32 dt) { .type = BZ_UI_LAYOUT_FLEX_BOX, .flags = BZ_UI_FLEX_DIR_COLUMN | BZ_UI_FLEX_JUSTIFY_CENTER | BZ_UI_FLEX_ALIGN_CENTER }); - static Options opts; + static GameData gameData = {}; if (game->screenPrevFrame != SCREEN_SETTINGS) - opts = game->options; + gameData = game->gameData; uiSettingsLabel("Video"); - uiSettingsCheckbox("Fullscreen", &opts.fullscreen); - uiSettingsCheckbox("V-Sync", &opts.vsync); + uiSettingsCheckbox("Fullscreen", &gameData.options.fullscreen); + uiSettingsCheckbox("Limit FPS", &gameData.options.limitFps); + //uiSettingsCheckbox("V-Sync", &opts.vsync); uiSettingsLabel("Audio"); - uiSettingsSlider("Master: ", &opts.master); - uiSettingsSlider("Music: ", &opts.music); - uiSettingsSlider("Sound: ", &opts.sound); + uiSettingsSlider("Master: ", &gameData.options.master); + uiSettingsSlider("Music: ", &gameData.options.music); + uiSettingsSlider("Sound: ", &gameData.options.sound); bzUIPopParent(UI); bzUIPushDiv(UI, (BzUISize) {BZ_UI_SIZE_REL_PARENT, 0.8f}, @@ -302,13 +303,12 @@ void drawSettingsUI(Game *game, f32 dt) { setScreen(game, SCREEN_MAIN_MENU); } if (uiSettingsButton("Reset")) { - opts = game->options; + gameData = game->gameData; } if (uiSettingsButton("Apply")) { - serializeOptions(SETTINGS_PATH, &opts); - game->options = opts; - SoundState *sounds = ecs_singleton_get_mut(ECS, SoundState); - soundsApplyVolume(sounds, opts.master, opts.music, opts.sound); + serializeGameData(GAME_DATA_SAVE_PATH, &gameData); + game->gameData = gameData; + applyOptions(&game->gameData.options); setScreen(game, SCREEN_MAIN_MENU); } diff --git a/game/utils.h b/game/utils.h index 0869824..d94b6a7 100644 --- a/game/utils.h +++ b/game/utils.h @@ -19,7 +19,8 @@ static Rectangle getCameraBounds(Camera2D camera) { } // Implemented in main.c -bool serializeOptions(const char *path, const Options *opts); -bool deserializeOptions(const char *path, Options *optsOut); +bool serializeGameData(const char *path, const GameData *gameData); +bool deserializeGameData(const char *path, GameData *gameData); +void applyOptions(const Options *options); #endif //PIXELDEFENSE_UTILS_H diff --git a/settings.ini b/settings.ini deleted file mode 100644 index 4c05921b6b2ff15ad48f5ddd325953a6d0b9a880..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16 TcmZQzU|=|V=8PSXvIk)R9uNZ}