Skip to content

Commit

Permalink
Use Use appropriate platform-specific paths for assets and userdata; c…
Browse files Browse the repository at this point in the history
…lose #10, #53, #47

This commit also allows overriding these path at build time through
-DPATH_ASSETS=.. and -DPATH_USERDATA=..
  • Loading branch information
phoboslab committed Aug 28, 2023
1 parent 18ebcc7 commit 108cfac
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 24 deletions.
4 changes: 4 additions & 0 deletions src/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ bool platform_get_fullscreen();
void platform_set_fullscreen(bool fullscreen);
void platform_set_audio_mix_cb(void (*cb)(float *buffer, uint32_t len));

uint8_t *platform_load_asset(const char *name, uint32_t *bytes_read);
uint8_t *platform_load_userdata(const char *name, uint32_t *bytes_read);
uint32_t platform_store_userdata(const char *name, void *bytes, int32_t len);

#if defined(RENDERER_SOFTWARE)
rgba_t *platform_get_screenbuffer(int32_t *pitch);
#endif
Expand Down
72 changes: 67 additions & 5 deletions src/platform_sdl.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@
#include "platform.h"
#include "input.h"
#include "system.h"
#include "utils.h"
#include "mem.h"

static uint64_t perf_freq = 0;
static bool wants_to_exit = false;
static SDL_Window *window;
static SDL_AudioDeviceID audio_device;
static SDL_GameController *gamepad;
static void (*audio_callback)(float *buffer, uint32_t len) = NULL;
static char *path_assets = NULL;
static char *path_userdata = NULL;
static char *temp_path = NULL;


uint8_t platform_sdl_gamepad_map[] = {
Expand Down Expand Up @@ -223,6 +228,28 @@ void platform_set_audio_mix_cb(void (*cb)(float *buffer, uint32_t len)) {
}


uint8_t *platform_load_asset(const char *name, uint32_t *bytes_read) {
char *path = strcat(strcpy(temp_path, path_assets), name);
return file_load(path, bytes_read);
}

uint8_t *platform_load_userdata(const char *name, uint32_t *bytes_read) {
char *path = strcat(strcpy(temp_path, path_userdata), name);
if (!file_exists(path)) {
*bytes_read = 0;
return NULL;
}
return file_load(path, bytes_read);
}

uint32_t platform_store_userdata(const char *name, void *bytes, int32_t len) {
char *path = strcat(strcpy(temp_path, path_userdata), name);
return file_store(path, bytes, len);
}




#if defined(RENDERER_GL) // ----------------------------------------------------
#define PLATFORM_WINDOW_FLAGS SDL_WINDOW_OPENGL
SDL_GLContext platform_gl;
Expand Down Expand Up @@ -317,14 +344,50 @@ void platform_set_audio_mix_cb(void (*cb)(float *buffer, uint32_t len)) {
int main(int argc, char *argv[]) {
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER);

int gcdb_res = SDL_GameControllerAddMappingsFromFile("gamecontrollerdb.txt");
// Figure out the absolute asset and userdata paths. These may either be
// supplied at build time through -DPATH_ASSETS=.. and -DPATH_USERDATA=..
// or received at runtime from SDL. Note that SDL may return NULL for these.
// We fall back to the current directory (i.e. just "") in this case.

#ifdef PATH_ASSETS
path_assets = TOSTRING(PATH_ASSETS);
#else
path_assets = SDL_GetBasePath();
if (path_assets == NULL) {
path_assets = "";
}
#endif

#ifdef PATH_USERDATA
path_userdata = TOSTRING(PATH_USERDATA);
#else
path_userdata = SDL_GetPrefPath("phoboslab", "wipeout");
if (path_userdata == NULL) {
path_userdata = "";
}
#endif

// Reserve some space for concatenating the asset and userdata paths with
// local filenames.
temp_path = mem_bump(max(strlen(path_assets), strlen(path_userdata)) + 64);

// Load gamecontrollerdb.txt if present.
// FIXME: Should this load from userdata instead?
char *gcdb_path = strcat(strcpy(temp_path, path_assets), "gamecontrollerdb.txt");
int gcdb_res = SDL_GameControllerAddMappingsFromFile(gcdb_path);
if (gcdb_res < 0) {
printf("Failed to load gamecontrollerdb.txt\n");
}
else {
printf("load gamecontrollerdb.txt\n");
}



gamepad = platform_find_gamepad();

perf_freq = SDL_GetPerformanceFrequency();

audio_device = SDL_OpenAudioDevice(NULL, 0, &(SDL_AudioSpec){
.freq = 44100,
.format = AUDIO_F32,
Expand All @@ -333,10 +396,6 @@ int main(int argc, char *argv[]) {
.callback = platform_audio_callback
}, NULL, 0);

gamepad = platform_find_gamepad();

perf_freq = SDL_GetPerformanceFrequency();

window = SDL_CreateWindow(
SYSTEM_WINDOW_NAME,
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
Expand All @@ -357,6 +416,9 @@ int main(int argc, char *argv[]) {
system_cleanup();
platform_video_cleanup();

SDL_free(path_assets);
SDL_free(path_userdata);

SDL_CloseAudioDevice(audio_device);
SDL_Quit();
return 0;
Expand Down
39 changes: 39 additions & 0 deletions src/platform_sokol.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "platform.h"
#include "system.h"
#include "utils.h"
#include "mem.h"

#if defined(RENDERER_GL)
#ifdef __EMSCRIPTEN__
Expand All @@ -17,6 +19,22 @@
#include "libs/sokol_app.h"
#include "input.h"

// FIXME: we should figure out the actual path where the executabe resides,
// instead of just assuming it's in the pwd
#ifdef PATH_ASSETS
static const char *path_assets = TOSTRING(PATH_ASSETS);
#else
static const char *path_assets = "";
#endif

#ifdef PATH_USERDATA
static const char *path_userdata = TOSTRING(PATH_USERDATA);
#else
static const char *path_userdata = "";
#endif

static char *temp_path;

static const uint8_t keyboard_map[] = {
[SAPP_KEYCODE_SPACE] = INPUT_KEY_SPACE,
[SAPP_KEYCODE_APOSTROPHE] = INPUT_KEY_APOSTROPHE,
Expand Down Expand Up @@ -246,7 +264,28 @@ void platform_set_audio_mix_cb(void (*cb)(float *buffer, uint32_t len)) {
audio_callback = cb;
}

uint8_t *platform_load_asset(const char *name, uint32_t *bytes_read) {
char *path = strcat(strcpy(temp_path, path_assets), name);
return file_load(path, bytes_read);
}

uint8_t *platform_load_userdata(const char *name, uint32_t *bytes_read) {
char *path = strcat(strcpy(temp_path, path_userdata), name);
if (!file_exists(path)) {
*bytes_read = 0;
return NULL;
}
return file_load(path, bytes_read);
}

uint32_t platform_store_userdata(const char *name, void *bytes, int32_t len) {
char *path = strcat(strcpy(temp_path, path_userdata), name);
return file_store(path, bytes, len);
}

sapp_desc sokol_main(int argc, char* argv[]) {
temp_path = mem_bump(max(strlen(path_assets), strlen(path_userdata)) + 64);

stm_setup();

saudio_setup(&(saudio_desc){
Expand Down
6 changes: 3 additions & 3 deletions src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ char *get_path(const char *dir, const char *file) {
}


bool file_exists(char *path) {
bool file_exists(const char *path) {
struct stat s;
return (stat(path, &s) == 0);
}

uint8_t *file_load(char *path, uint32_t *bytes_read) {
uint8_t *file_load(const char *path, uint32_t *bytes_read) {
FILE *f = fopen(path, "rb");
error_if(!f, "Could not open file for reading: %s", path);

Expand All @@ -43,7 +43,7 @@ uint8_t *file_load(char *path, uint32_t *bytes_read) {
return bytes;
}

uint32_t file_store(char *path, void *bytes, int32_t len) {
uint32_t file_store(const char *path, void *bytes, int32_t len) {
FILE *f = fopen(path, "wb");
error_if(!f, "Could not open file for writing: %s", path);

Expand Down
6 changes: 3 additions & 3 deletions src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@ bool str_starts_with(const char *haystack, const char *needle);
float rand_float(float min, float max);
int32_t rand_int(int32_t min, int32_t max);

bool file_exists(char *path);
uint8_t *file_load(char *path, uint32_t *bytes_read);
uint32_t file_store(char *path, void *bytes, int32_t len);
bool file_exists(const char *path);
uint8_t *file_load(const char *path, uint32_t *bytes_read);
uint32_t file_store(const char *path, void *bytes, int32_t len);


#define sort(LIST, LEN, COMPARE_FUNC) \
Expand Down
12 changes: 8 additions & 4 deletions src/wipeout/game.c
Original file line number Diff line number Diff line change
Expand Up @@ -502,13 +502,17 @@ static int global_textures_len = 0;
static void *global_mem_mark = 0;

void game_init() {
if (file_exists("save.dat")) {
uint32_t size;
save_t *save_file = (save_t *)file_load("save.dat", &size);

uint32_t size;
save_t *save_file = (save_t *)platform_load_userdata("save.dat", &size);
if (save_file) {
if (size == sizeof(save_t) && save_file->magic == SAVE_DATA_MAGIC) {
printf("load save data success\n");
memcpy(&save, save_file, sizeof(save_t));
}
else {
printf("unexpected size/magic for save data");
}
mem_temp_free(save_file);
}

Expand Down Expand Up @@ -631,7 +635,7 @@ void game_update() {
// FIXME: use a text based format?
// FIXME: this should probably run async somewhere
save.is_dirty = false;
file_store("save.dat", &save, sizeof(save_t));
platform_store_userdata("save.dat", &save, sizeof(save_t));
printf("wrote save.dat\n");
}

Expand Down
7 changes: 4 additions & 3 deletions src/wipeout/image.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "../types.h"
#include "../mem.h"
#include "../utils.h"
#include "../platform.h"

#include "object.h"
#include "track.h"
Expand Down Expand Up @@ -229,7 +230,7 @@ void lzss_decompress(uint8_t *in_data, uint8_t *out_data) {
cmp_t *image_load_compressed(char *name) {
printf("load cmp %s\n", name);
uint32_t compressed_size;
uint8_t *compressed_bytes = file_load(name, &compressed_size);
uint8_t *compressed_bytes = platform_load_asset(name, &compressed_size);

uint32_t p = 0;
int32_t decompressed_size = 0;
Expand Down Expand Up @@ -263,7 +264,7 @@ cmp_t *image_load_compressed(char *name) {
uint16_t image_get_texture(char *name) {
printf("load: %s\n", name);
uint32_t size;
uint8_t *bytes = file_load(name, &size);
uint8_t *bytes = platform_load_asset(name, &size);
image_t *image = image_load_from_bytes(bytes, false);
uint32_t texture_index = render_texture_create(image->width, image->height, image->pixels);
mem_temp_free(image);
Expand All @@ -275,7 +276,7 @@ uint16_t image_get_texture(char *name) {
uint16_t image_get_texture_semi_trans(char *name) {
printf("load: %s\n", name);
uint32_t size;
uint8_t *bytes = file_load(name, &size);
uint8_t *bytes = platform_load_asset(name, &size);
image_t *image = image_load_from_bytes(bytes, true);
uint32_t texture_index = render_texture_create(image->width, image->height, image->pixels);
mem_temp_free(image);
Expand Down
3 changes: 2 additions & 1 deletion src/wipeout/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "../mem.h"
#include "../render.h"
#include "../utils.h"
#include "../platform.h"

#include "object.h"
#include "track.h"
Expand All @@ -26,7 +27,7 @@ static rgba_t int32_to_rgba(uint32_t v) {

Object *objects_load(char *name, texture_list_t tl) {
uint32_t length = 0;
uint8_t *bytes = file_load(name, &length);
uint8_t *bytes = platform_load_asset(name, &length);
if (!bytes) {
die("Failed to load file %s\n", name);
}
Expand Down
2 changes: 1 addition & 1 deletion src/wipeout/sfx.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ void sfx_load() {

// 16 byte blocks: 2 byte header, 14 bytes with 2x4bit samples each
uint32_t vb_size;
uint8_t *vb = file_load("wipeout/sound/wipeout.vb", &vb_size);
uint8_t *vb = platform_load_asset("wipeout/sound/wipeout.vb", &vb_size);
uint32_t num_samples = (vb_size / 16) * 28;

int16_t *sample_buffer = mem_bump(num_samples * sizeof(int16_t));
Expand Down
9 changes: 5 additions & 4 deletions src/wipeout/track.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "../utils.h"
#include "../render.h"
#include "../system.h"
#include "../platform.h"

#include "object.h"
#include "track.h"
Expand Down Expand Up @@ -87,7 +88,7 @@ void track_load(const char *base_path) {

ttf_t *track_load_tile_format(char *ttf_name) {
uint32_t ttf_size;
uint8_t *ttf_bytes = file_load(ttf_name, &ttf_size);
uint8_t *ttf_bytes = platform_load_asset(ttf_name, &ttf_size);

uint32_t p = 0;
uint32_t num_tiles = ttf_size / 42;
Expand Down Expand Up @@ -123,7 +124,7 @@ bool track_collect_pickups(track_face_t *face) {

vec3_t *track_load_vertices(char *file_name) {
uint32_t size;
uint8_t *bytes = file_load(file_name, &size);
uint8_t *bytes = platform_load_asset(file_name, &size);

g.track.vertex_count = size / 16; // VECTOR_SIZE
vec3_t *vertices = mem_temp_alloc(sizeof(vec3_t) * g.track.vertex_count);
Expand All @@ -147,7 +148,7 @@ static const vec2_t track_uv[2][4] = {

void track_load_faces(char *file_name, vec3_t *vertices) {
uint32_t size;
uint8_t *bytes = file_load(file_name, &size);
uint8_t *bytes = platform_load_asset(file_name, &size);

g.track.face_count = size / 20; // TRACK_FACE_DATA_SIZE
g.track.faces = mem_bump(sizeof(track_face_t) * g.track.face_count);
Expand Down Expand Up @@ -196,7 +197,7 @@ void track_load_faces(char *file_name, vec3_t *vertices) {

void track_load_sections(char *file_name) {
uint32_t size;
uint8_t *bytes = file_load(file_name, &size);
uint8_t *bytes = platform_load_asset(file_name, &size);

g.track.section_count = size / 156; // SECTION_DATA_SIZE
g.track.sections = mem_bump(sizeof(section_t) * g.track.section_count);
Expand Down

0 comments on commit 108cfac

Please sign in to comment.