From 45d4f91bd9422d3303137be72894a92b7d144751 Mon Sep 17 00:00:00 2001 From: Quinn Date: Fri, 18 Apr 2025 21:27:39 +0200 Subject: [PATCH] write code to improve handling of paths, to be more consistent. I don't think I want to place the local data paths there... --- src/game/paths.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ src/game/paths.h | 13 ++++++++++ 2 files changed, 78 insertions(+) create mode 100644 src/game/paths.c create mode 100644 src/game/paths.h diff --git a/src/game/paths.c b/src/game/paths.c new file mode 100644 index 0000000..237446a --- /dev/null +++ b/src/game/paths.c @@ -0,0 +1,65 @@ +#include "paths.h" + +#include +#include + +#include "../util/compat.h" + +char const* restrict path_dat = NULL; +char const* restrict path_font = NULL; +char const* restrict path_music = NULL; +char const* restrict path_place_sfx = NULL; + +// gets the game's data path, returns 0 on failure, otherwise the datapath's string length +static unsigned getdatpath(void) { + char const* home = getenv(unixonly("HOME") winonly("APPDATA")); // get the user data directory path (appropriated for each platform) + if (!home) home = "."; // if this failed, set the path to `.`, which represents cwd + + unsigned len = strlen(home); + len += 1 + 20 unixonly(+13); // add 21 bytes to the home length, to account for adding .local/share later + char* datpath = malloc(len); + if (!datpath) return 0; + + // copy the data from home into the datapath + strcpy(datpath, home); + +#ifdef __unix__ + // include the .local/share directory, if the HOME environment variable was valid + if (home[0] != '.') strcat(datpath, "/.local/share"); + else { + // if the HOME directory wasn't defined, shrink the string + len -= 13; + void* ptr = realloc(datpath, len); + if (ptr) datpath = ptr; // likely doesn't actually change the pointer, but just to be sure + } +#endif + + strcat(datpath, PATH_SEP_STR "quinns_tetris_clone"); + path_dat = datpath; + return len; +} + +static inline char const* init_path(char const* const restrict str, unsigned len) { + void* ptr = malloc(len); + if (!ptr) return NULL; + strcpy(ptr, path_dat); + strcat(ptr, str); + return ptr; +} + +int paths_init(void) { + unsigned len = getdatpath(); + if (!len) return 1; + + // these are explicitly static, as string literals just work like that + path_font = init_path("pixeldroid_botic-regular.ttf", len + 28); + path_music = init_path("korobeiniki.wav", len + 15); + path_place_sfx = init_path("place.wav", len + 9); + return -(!path_font || !path_music || !path_place_sfx); +} + +void paths_free(void) { + free((void*)path_dat), path_dat = NULL; + free((void*)path_music), path_music = NULL; + free((void*)path_place_sfx), path_place_sfx = NULL; +} diff --git a/src/game/paths.h b/src/game/paths.h new file mode 100644 index 0000000..10bc66a --- /dev/null +++ b/src/game/paths.h @@ -0,0 +1,13 @@ +#pragma once + +extern char const* restrict path_dat; +extern char const* restrict path_font; +extern char const* restrict path_music; +extern char const* restrict path_place_sfx; + +/* initializes the paths, paths are evaluated to NULL upon failure. + returns 0 upon success, >0 upon failure <0 upon non-critical failure */ +int paths_init(void); + +/* frees allocated data */ +void paths_free(void);