From cd8b4df268a55051c4bc9f42a88e0a6494dcfd2e Mon Sep 17 00:00:00 2001 From: Filip Kolinsky Date: Wed, 3 Jun 2026 20:49:48 +0200 Subject: [PATCH 1/2] The piuio emu_libs as well as the x11_input_handler can now be anywhere --- src/main/util/fs.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/main/util/fs.c b/src/main/util/fs.c index 3556b9d..e6c65d5 100644 --- a/src/main/util/fs.c +++ b/src/main/util/fs.c @@ -210,15 +210,39 @@ char *util_fs_get_filename(const char *path) char *util_fs_get_abs_path(const char *path) { + size_t path_len; char *real_path; + if (!path) { + return NULL; + } + + path_len = strlen(path); + + if (path_len == 0) { + real_path = (char *) util_xmalloc(1); + real_path[0] = '\0'; + return real_path; + } + + /* Keep explicit absolute paths untouched to support external mount points. */ + if (path[0] == '/') { + real_path = (char *) util_xmalloc(path_len + 1); + memcpy(real_path, path, path_len + 1); + return real_path; + } + real_path = realpath(path, NULL); if (!real_path) { - log_error( + log_warn( "Resolving path '%s' to absolute path failed: %s", path, strerror(errno)); + + /* Fall back to the original path and let the dynamic loader resolve it. */ + real_path = (char *) util_xmalloc(path_len + 1); + memcpy(real_path, path, path_len + 1); } return real_path; From 4e05c2892501f3efc6fa911e310ab10cd498f1da Mon Sep 17 00:00:00 2001 From: Filip Kolinsky Date: Wed, 3 Jun 2026 21:02:06 +0200 Subject: [PATCH 2/2] Keyboard/Joystick config bin file loads either from next to the game or wherever the emu_lib is located --- src/main/ptapi/io/piubtn/joystick/joystick.c | 19 +++++++++++ src/main/ptapi/io/piubtn/keyboard/keyboard.c | 18 ++++++++++ src/main/ptapi/io/piuio/joystick/joystick.c | 19 ++++++++++- src/main/ptapi/io/piuio/keyboard/keyboard.c | 18 +++++++++- src/main/util/proc.c | 35 ++++++++++++++++++++ src/main/util/proc.h | 12 +++++++ 6 files changed, 119 insertions(+), 2 deletions(-) diff --git a/src/main/ptapi/io/piubtn/joystick/joystick.c b/src/main/ptapi/io/piubtn/joystick/joystick.c index 045e717..cd8e0d1 100644 --- a/src/main/ptapi/io/piubtn/joystick/joystick.c +++ b/src/main/ptapi/io/piubtn/joystick/joystick.c @@ -60,6 +60,21 @@ bool ptapi_io_piubtn_open() struct io_util_joystick_util_device_info device_info[MAX_NUM_JOYSTICKS]; size_t devices_connected; + if (util_proc_get_folder_path_shared_object( + (void *) ptapi_io_piubtn_open, path, sizeof(path))) { + config_path = util_str_merge(path, CONFIG_FILENAME); + + log_info("Loading configuration from emu lib path: %s", config_path); + + if (ptapi_io_piubtn_joystick_util_conf_read_from_file( + &ptapi_io_piubtn_joystick_util_conf, config_path)) { + free(config_path); + goto conf_loaded; + } + + free(config_path); + } + // The game changes the working directory to the 'game' sub-folder. Therefore, // ./my-config does not work here. if (!util_proc_get_folder_path_executable_no_ld_linux(path, sizeof(path))) { @@ -69,6 +84,8 @@ bool ptapi_io_piubtn_open() config_path = util_str_merge(path, CONFIG_FILENAME); + log_info("Loading configuration from executable path: %s", config_path); + if (!ptapi_io_piubtn_joystick_util_conf_read_from_file( &ptapi_io_piubtn_joystick_util_conf, config_path)) { log_error("Loading joystick config file %s failed.", CONFIG_FILENAME); @@ -78,6 +95,8 @@ bool ptapi_io_piubtn_open() free(config_path); +conf_loaded: + devices_connected = io_util_joystick_util_scan(device_info, MAX_NUM_JOYSTICKS); diff --git a/src/main/ptapi/io/piubtn/keyboard/keyboard.c b/src/main/ptapi/io/piubtn/keyboard/keyboard.c index 8e251f8..63631d8 100644 --- a/src/main/ptapi/io/piubtn/keyboard/keyboard.c +++ b/src/main/ptapi/io/piubtn/keyboard/keyboard.c @@ -48,6 +48,22 @@ bool ptapi_io_piubtn_open() char path[PATH_MAX]; char *config_path; + if (util_proc_get_folder_path_shared_object( + (void *) ptapi_io_piubtn_open, path, sizeof(path))) { + config_path = util_str_merge(path, CONFIG_FILENAME); + + log_info("Loading configuration from emu lib path: %s", config_path); + + if (ptapi_io_piubtn_keyboard_util_conf_read_from_file( + &ptapi_io_piubtn_keyboard_conf, config_path)) { + free(config_path); + memset(ptapi_io_piubtn_keyboard_buffer, 0, sizeof(bool) * KEY_MAP_SIZE); + return true; + } + + free(config_path); + } + // The game changes the working directory to the 'game' sub-folder. Therefore, // ./my-config does not work here. if (!util_proc_get_folder_path_executable_no_ld_linux(path, sizeof(path))) { @@ -57,6 +73,8 @@ bool ptapi_io_piubtn_open() config_path = util_str_merge(path, CONFIG_FILENAME); + log_info("Loading configuration from executable path: %s", config_path); + if (!ptapi_io_piubtn_keyboard_util_conf_read_from_file( &ptapi_io_piubtn_keyboard_conf, config_path)) { log_error("Loading keyboard config file %s failed.", config_path); diff --git a/src/main/ptapi/io/piuio/joystick/joystick.c b/src/main/ptapi/io/piuio/joystick/joystick.c index 48d615f..71cc42c 100644 --- a/src/main/ptapi/io/piuio/joystick/joystick.c +++ b/src/main/ptapi/io/piuio/joystick/joystick.c @@ -60,6 +60,21 @@ bool ptapi_io_piuio_open() struct io_util_joystick_util_device_info device_info[MAX_NUM_JOYSTICKS]; size_t devices_connected; + if (util_proc_get_folder_path_shared_object( + (void *) ptapi_io_piuio_open, path, sizeof(path))) { + config_path = util_str_merge(path, CONFIG_FILENAME); + + log_info("Loading configuration from emu lib path: %s", config_path); + + if (ptapi_io_piuio_joystick_util_conf_read_from_file( + &ptapi_io_piuio_joystick_util_conf, config_path)) { + free(config_path); + goto conf_loaded; + } + + free(config_path); + } + // The game changes the working directory to the 'game' sub-folder. Therefore, // ./my-config does not work here. if (!util_proc_get_folder_path_executable_no_ld_linux(path, sizeof(path))) { @@ -69,7 +84,7 @@ bool ptapi_io_piuio_open() config_path = util_str_merge(path, CONFIG_FILENAME); - log_info("Loading configuration: ", config_path); + log_info("Loading configuration from executable path: %s", config_path); if (!ptapi_io_piuio_joystick_util_conf_read_from_file( &ptapi_io_piuio_joystick_util_conf, config_path)) { @@ -80,6 +95,8 @@ bool ptapi_io_piuio_open() free(config_path); +conf_loaded: + devices_connected = io_util_joystick_util_scan(device_info, MAX_NUM_JOYSTICKS); diff --git a/src/main/ptapi/io/piuio/keyboard/keyboard.c b/src/main/ptapi/io/piuio/keyboard/keyboard.c index 8a07c01..ffd4b28 100644 --- a/src/main/ptapi/io/piuio/keyboard/keyboard.c +++ b/src/main/ptapi/io/piuio/keyboard/keyboard.c @@ -47,6 +47,22 @@ bool ptapi_io_piuio_open() char path[PATH_MAX]; char *config_path; + if (util_proc_get_folder_path_shared_object( + (void *) ptapi_io_piuio_open, path, sizeof(path))) { + config_path = util_str_merge(path, CONFIG_FILENAME); + + log_info("Loading configuration from emu lib path: %s", config_path); + + if (ptapi_io_piuio_keyboard_util_conf_read_from_file( + &ptapi_io_piuio_keyboard_conf, config_path)) { + free(config_path); + memset(ptapi_io_piuio_keyboard_buffer, 0, sizeof(bool) * KEY_MAP_SIZE); + return true; + } + + free(config_path); + } + // The game changes the working directory to the 'game' sub-folder. Therefore, // ./my-config does not work here. if (!util_proc_get_folder_path_executable_no_ld_linux(path, sizeof(path))) { @@ -56,7 +72,7 @@ bool ptapi_io_piuio_open() config_path = util_str_merge(path, CONFIG_FILENAME); - log_info("Loading configuration: ", config_path); + log_info("Loading configuration from executable path: %s", config_path); if (!ptapi_io_piuio_keyboard_util_conf_read_from_file( &ptapi_io_piuio_keyboard_conf, config_path)) { diff --git a/src/main/util/proc.c b/src/main/util/proc.c index 692832f..31bd913 100644 --- a/src/main/util/proc.c +++ b/src/main/util/proc.c @@ -1,5 +1,6 @@ #define LOG_MODULE "util-proc" +#include #include #include #include @@ -205,6 +206,40 @@ bool util_proc_get_folder_path_executable_no_ld_linux(char *buffer, size_t size) } } +bool util_proc_get_folder_path_shared_object( + void *symbol, char *buffer, size_t size) +{ + Dl_info info; + + if (!symbol || !buffer || size == 0) { + return false; + } + + if (!dladdr(symbol, &info) || !info.dli_fname) { + return false; + } + + if (strlen(info.dli_fname) >= size) { + return false; + } + + strcpy(buffer, info.dli_fname); + + // If shared object in the root folder, keep the single / + size_t pos = strlen(buffer) - 1; + while (pos > 0 && buffer[pos] != '/') { + buffer[pos] = '\0'; + pos--; + } + + // delete / + if (pos > 0) { + buffer[pos] = '\0'; + } + + return true; +} + void util_proc_log_info() { log_info( diff --git a/src/main/util/proc.h b/src/main/util/proc.h index e260290..297253a 100644 --- a/src/main/util/proc.h +++ b/src/main/util/proc.h @@ -43,6 +43,18 @@ bool util_proc_get_folder_path_executable(char *buffer, size_t size); bool util_proc_get_folder_path_executable_no_ld_linux( char *buffer, size_t size); +/** + * Get the full path of the folder of the shared object that contains the + * supplied symbol. + * + * @param symbol Pointer to any symbol in the target shared object. + * @param buffer Buffer to read the path into. + * @param size Size of the buffer. + * @return True on success, false on failure. + */ +bool util_proc_get_folder_path_shared_object( + void *symbol, char *buffer, size_t size); + /** * Log information about the current process to the console. */