From d206aa8f7e32b87622e168635e62e61c42e28067 Mon Sep 17 00:00:00 2001 From: Matt Borgerson Date: Wed, 25 Mar 2020 23:03:29 -0700 Subject: [PATCH] ui: Use SDL to determine resource/preference base paths --- ui/Makefile.objs | 17 +++++----- ui/xemu-custom-widgets.c | 5 +-- ui/xemu-data.c | 72 ++++++++++++++++++++++++++++++++++++++++ ui/xemu-data.h | 34 +++++++++++++++++++ ui/xemu-hud.cc | 3 +- ui/xemu-settings.c | 28 +++++++--------- 6 files changed, 132 insertions(+), 27 deletions(-) create mode 100644 ui/xemu-data.c create mode 100644 ui/xemu-data.h diff --git a/ui/Makefile.objs b/ui/Makefile.objs index 56bbf711a5..3d06e206e1 100644 --- a/ui/Makefile.objs +++ b/ui/Makefile.objs @@ -25,19 +25,20 @@ endif # Override with xemu UI sdl.mo-objs := \ - xemu.o \ - xemu-hud.o \ - xemu-custom-widgets.o \ - xemu-input.o \ - xemu-monitor.o \ - xemu-settings.o \ - xemu-shaders.o \ imgui/imgui.o \ imgui/imgui_demo.o \ imgui/imgui_draw.o \ imgui/imgui_widgets.o \ imgui/examples/imgui_impl_opengl3.o \ - imgui/examples/imgui_impl_sdl.o + imgui/examples/imgui_impl_sdl.o \ + xemu.o \ + xemu-custom-widgets.o \ + xemu-data.o \ + xemu-hud.o \ + xemu-input.o \ + xemu-monitor.o \ + xemu-settings.o \ + xemu-shaders.o \ ui/xemu-shaders.o: ui/shader/xemu-logo-frag.h diff --git a/ui/xemu-custom-widgets.c b/ui/xemu-custom-widgets.c index c6f823ae2d..555a7f90c1 100644 --- a/ui/xemu-custom-widgets.c +++ b/ui/xemu-custom-widgets.c @@ -24,6 +24,7 @@ #include "xemu-shaders.h" #include "xemu-custom-widgets.h" +#include "xemu-data.h" static struct decal_shader *s = NULL; static struct decal_shader *s_logo = NULL; @@ -66,9 +67,9 @@ void initialize_custom_ui_rendering(void) glGetIntegerv(GL_VIEWPORT, vp); glActiveTexture(GL_TEXTURE0); - g_ui_tex = load_texture_from_file("data/controller-mask.png"); + g_ui_tex = load_texture_from_file(xemu_get_resource_path("controller-mask.png")); s = create_decal_shader(SHADER_TYPE_MASK); - g_logo_tex = load_texture_from_file("data/logo-sdf.png"); + g_logo_tex = load_texture_from_file(xemu_get_resource_path("logo-sdf.png")); s_logo = create_decal_shader(SHADER_TYPE_LOGO); controller_fbo = create_fbo(512, 512); logo_fbo = create_fbo(512, 512); diff --git a/ui/xemu-data.c b/ui/xemu-data.c new file mode 100644 index 0000000000..955dae4fad --- /dev/null +++ b/ui/xemu-data.c @@ -0,0 +1,72 @@ +/* + * xemu Data File and Path Helpers + * + * Copyright (C) 2020 Matt Borgerson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include + +#include "xemu-data.h" + +static int path_exists(const char *path) +{ + FILE *fd = fopen(path, "rb"); + if (fd == NULL) return 0; + fclose(fd); + return 1; +} + +const char *xemu_get_resource_path(const char *filename) +{ + // Allocate an arbitrarily long buffer for resource path storage FIXME: This + // could be done better with a growing printf. Keep it simple for now. + const size_t resource_path_buffer_len = 1024; + static char *sdl_base_path = NULL; + static char *resource_path = NULL; + + if (!sdl_base_path) { + sdl_base_path = SDL_GetBasePath(); + } + + if (!resource_path) { + resource_path = malloc(resource_path_buffer_len); + assert(resource_path != NULL); + } + + // Try whichever location SDL deems appropriate + snprintf(resource_path, resource_path_buffer_len, "%sdata/%s", + sdl_base_path, filename); + + if (path_exists(resource_path)) { + return resource_path; + } + + // Try parent directory if launched from source root + snprintf(resource_path, resource_path_buffer_len, "%s../data/%s", + sdl_base_path, filename); + + if (path_exists(resource_path)) { + return resource_path; + } + + // Path not found or file not readable + assert(0); + return NULL; +} diff --git a/ui/xemu-data.h b/ui/xemu-data.h new file mode 100644 index 0000000000..d0a4831fbe --- /dev/null +++ b/ui/xemu-data.h @@ -0,0 +1,34 @@ +/* + * xemu Data File and Path Helpers + * + * Copyright (C) 2020 Matt Borgerson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XEMU_DATA +#define XEMU_DATA + +#ifdef __cplusplus +extern "C" { +#endif + +// Note: Not thread safe. Returns a pointer to an internally allocated buffer. +const char *xemu_get_resource_path(const char *filename); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ui/xemu-hud.cc b/ui/xemu-hud.cc index b3534c7cd5..cec588d1ec 100644 --- a/ui/xemu-hud.cc +++ b/ui/xemu-hud.cc @@ -29,6 +29,7 @@ #include "xemu-custom-widgets.h" #include "xemu-monitor.h" #include "xemu-version.h" +#include "xemu-data.h" #include "imgui/imgui.h" #include "imgui/examples/imgui_impl_sdl.h" @@ -111,7 +112,7 @@ void xemu_hud_init(SDL_Window* window, void* sdl_gl_context) io.IniFilename = NULL; // Load fonts - io.Fonts->AddFontFromFileTTF("./data/Roboto-Medium.ttf", 16); + io.Fonts->AddFontFromFileTTF(xemu_get_resource_path("Roboto-Medium.ttf"), 16); fixed_width_font = io.Fonts->AddFontDefault(); // Setup Platform/Renderer bindings diff --git a/ui/xemu-settings.c b/ui/xemu-settings.c index fee5a6bf7d..defab17b6a 100644 --- a/ui/xemu-settings.c +++ b/ui/xemu-settings.c @@ -166,29 +166,25 @@ const char *xemu_settings_get_path(void) return settings_path; } - // Note: Ideally SDL_GetPrefPath should be used here to determine where the - // settings file should be stored. However, until xemu gains a proper - // installer, assume it will be run in "portable mode" such that everything - // needed to run is all in the same directory, or specified explicitly by - // the user via config file. -#if 0 char *base = SDL_GetPrefPath("xemu", "xemu"); -#else - // char *base = SDL_GetBasePath(); - // if (base == NULL) { - // base = strdup("./"); - // } - char *base = strdup("./"); -#endif assert(base != NULL); size_t base_len = strlen(base); + size_t filename_len = strlen(filename); - size_t len = base_len + filename_len + 1; - char *path = malloc(len); + size_t final_len = base_len + filename_len; + final_len += 1; // Terminating null byte + + char *path = malloc(final_len); + assert(path != NULL); + + // Copy base part memcpy(path, base, base_len); free(base); + + // Copy filename part memcpy(path+base_len, filename, strlen(filename)); - path[len-1] = '\0'; + path[final_len-1] = '\0'; + settings_path = path; fprintf(stderr, "%s: config path: %s\n", __func__, settings_path);