diff --git a/.github/workflows/autobuild.yml b/.github/workflows/autobuild.yml index 765b3b39..12d499e5 100644 --- a/.github/workflows/autobuild.yml +++ b/.github/workflows/autobuild.yml @@ -612,7 +612,14 @@ jobs: echo "CMAKE_SHARED_LINKER_FLAGS_INIT = '-fuse-ld=lld'" | tee -a ${{ runner.temp }}/cross.ini echo "CMAKE_STATIC_LINKER_FLAGS_INIT = '-fuse-ld=lld'" | tee -a ${{ runner.temp }}/cross.ini echo '--------------------------------------------------------------------------------' - CLICOLOR_FORCE=1 meson setup build --cross-file ${{ runner.temp }}/cross.ini --buildtype release -Db_lto=true -Dlibretro=true + # If architecture is s390x and Clang version is older than 19.1.0, disable LTO due to https://github.com/llvm/llvm-project/issues/61101 + if [ '${{ matrix.arch_mkxpz }}' = 's390x' ] && (echo "$(clang --version | head -n 1 | sed -e 's/.*clang version * \([0-9.]*\).*/\1/')\n19.1.0" | sort -CV) + then + lto=false + else + lto=true + fi + CLICOLOR_FORCE=1 meson setup build --cross-file ${{ runner.temp }}/cross.ini --buildtype release -Db_lto=$lto -Dlibretro=true - name: Build core run: | @@ -1061,6 +1068,22 @@ jobs: apt remove -y meson cmake pip install meson cmake + - name: Build and install wiiurpxtool + run: | + if command -v wiiurpxtool + then + echo 'wiiurpxtool already installed' + else + cd ~ + git clone https://github.com/yawut/wiiurpxtool-ng + cd wiiurpxtool-ng + git checkout 682cc9f587dee507b400a307f5a0787efc5dcb72 + git submodule update --init --recursive + cmake -G Ninja . + ninja -v + mv wiiurpxtool-ng /usr/local/bin/wiiurpxtool + fi + - id: short-sha name: Get Git commit hash uses: benjlevesque/short-sha@v2.2 @@ -1242,7 +1265,6 @@ jobs: cd retroarch CLICOLOR_FORCE=1 make -f Makefile.libnx LIBRETRO=mkxp-z mv retroarch_switch.nro ~/dist/mkxp-z_libretro.nro - mv retroarch_switch.elf ~/dist/mkxp-z_libretro.elf - name: Upload artifact uses: actions/upload-artifact@v4 diff --git a/binding-sandbox/wasm-rt.h b/binding-sandbox/wasm-rt.h index a2d1b730..d6bcec57 100644 --- a/binding-sandbox/wasm-rt.h +++ b/binding-sandbox/wasm-rt.h @@ -28,6 +28,8 @@ # include #endif +#include + #ifdef __cplusplus extern "C" { #endif diff --git a/libretro/Makefile b/libretro/Makefile index ab91f91e..3d985bdd 100644 --- a/libretro/Makefile +++ b/libretro/Makefile @@ -18,6 +18,7 @@ GIT ?= git ZIP ?= zip XXD ?= xxd SED ?= sed +GREP ?= grep CC ?= cc CXX ?= c++ LD ?= ld @@ -91,6 +92,14 @@ $(OUTDIR)/sdl/include/SDL.h: $(OUTDIR)/mkxp-retro-ruby/mkxp-retro-ruby.h $(OUTDIR)/mkxp-retro-ruby/mkxp-retro-ruby-impl.h $(OUTDIR)/mkxp-retro-ruby/mkxp-retro-ruby_0.c $(OUTDIR)/mkxp-retro-ruby/mkxp-retro-ruby_1.c $(OUTDIR)/mkxp-retro-ruby/mkxp-retro-ruby_2.c $(OUTDIR)/mkxp-retro-ruby/mkxp-retro-ruby_3.c $(OUTDIR)/mkxp-retro-ruby/mkxp-retro-ruby_4.c $(OUTDIR)/mkxp-retro-ruby/mkxp-retro-ruby_5.c $(OUTDIR)/mkxp-retro-ruby/mkxp-retro-ruby_6.c $(OUTDIR)/mkxp-retro-ruby/mkxp-retro-ruby_7.c &: $(LIBDIR)/mkxp-retro-dist/bin/ruby mkdir -p $(OUTDIR)/mkxp-retro-ruby $(WASM2C) $(LIBDIR)/mkxp-retro-dist/bin/ruby -n ruby --num-outputs=8 -o $(OUTDIR)/mkxp-retro-ruby/mkxp-retro-ruby.c + # Find all the function types declared using `FUNC_TYPE_DECL_EXTERN_T` and redeclare them as macros to fix the "initializer element is not constant" compilation error that occurs when using GCC versions earlier than 8.1.0 + rm -f $(OUTDIR)/mkxp-retro-ruby/mkxp-retro-ruby-func-types.h + for func_type in $$($(GREP) -r 'FUNC_TYPE_DECL_EXTERN_T *([^()]*)' $(OUTDIR)/mkxp-retro-ruby/mkxp-retro-ruby-impl.h | $(GREP) -v '# *define' | $(SED) -e 's/FUNC_TYPE_DECL_EXTERN_T *( *\(.*\) *).*/\1/'); do \ + echo "#define $$func_type \"$$($(XXD) -c 0 -l 32 -p /dev/urandom | $(SED) -e 's/.\{2\}/\\x&/g')\"" >> $(OUTDIR)/mkxp-retro-ruby/mkxp-retro-ruby-func-types.h; \ + done + $(SED) -i 's/ *# *define * FUNC_TYPE_DECL_EXTERN_T *([^()]).*/#define FUNC_TYPE_DECL_EXTERN_T(x)/g' $(OUTDIR)/mkxp-retro-ruby/mkxp-retro-ruby-impl.h + $(SED) -i 's/ *# *define * FUNC_TYPE_EXTERN_T *([^()]).*/#define FUNC_TYPE_EXTERN_T(x) const char _mkxp_unused_##x[]/g' $(OUTDIR)/mkxp-retro-ruby/mkxp-retro-ruby-impl.h + $(SED) -i 's/ *# *define * FUNC_TYPE_T *([^()]).*/#define FUNC_TYPE_T(x) static const char _mkxp_unused_##x[]/g' $(OUTDIR)/mkxp-retro-ruby/mkxp-retro-ruby-impl.h $(OUTDIR)/mkxp-retro-dist.zip.cpp: $(LIBDIR)/mkxp-retro-dist.zip mkdir -p $(OUTDIR) diff --git a/meson.build b/meson.build index 11c0e6eb..7d446619 100644 --- a/meson.build +++ b/meson.build @@ -1,4 +1,4 @@ -project('mkxp-z', 'c', 'cpp', version: '2.4.2', meson_version: '>=1.3.0', default_options: ['cpp_std=c++14', 'buildtype=release']) +project('mkxp-z', 'c', 'cpp', version: '2.4.2', meson_version: '>=1.3.0', default_options: ['cpp_std=c++14', 'buildtype=release', 'b_staticpic=false']) host_system = host_machine.system() host_endian = host_machine.endian() @@ -8,7 +8,7 @@ is_emscripten = host_system == 'emscripten' core_is_static = is_emscripten or host_system == 'bare' or host_system == 'none' if not is_libretro and host_system == 'darwin' - error('\nThis Meson project no longer supports macOS. Please use the Xcode project instead.') + error('This Meson project no longer supports macOS. Please use the Xcode project instead.') endif xxd = find_program('xxd', native: true) @@ -39,19 +39,6 @@ global_sources += vcs_tag(command: ['git', 'rev-parse', '--short', 'HEAD'], fall if is_libretro libretro_stage1_path = get_option('libretro_stage1_path') - libretro_defines = [ - '-DMKXPZ_VERSION="@0@"'.format(meson.project_version()), - '-DMKXPZ_RETRO', - '-DSHARED_FLUID', - ] - if host_endian == 'big' - libretro_defines += '-DMKXPZ_BIG_ENDIAN' - endif - if is_emscripten or not compilers['cpp'].compiles('struct E {}; int main() { throw E(); }', name: 'check if C++ exceptions are supported') - libretro_defines += '-DMKXPZ_NO_EXCEPTIONS' - libretro_defines += '-DBOOST_NO_EXCEPTIONS' - endif - libretro_link_args = [] libretro_cflags = [] libretro_cppflags = [] @@ -85,32 +72,119 @@ if is_libretro libretro_link_args += '-Wl,--version-script,' + meson.current_source_dir() / 'libretro/link.T' endif + libretro_defines = [ + '-DMKXPZ_VERSION="@0@"'.format(meson.project_version()), + '-DMKXPZ_RETRO', + '-DSHARED_FLUID', + '-D_FILE_OFFSET_BITS=64', + '-DMPG123_NO_LARGENAME', + ] + + if host_endian == 'big' + libretro_defines += '-DMKXPZ_BIG_ENDIAN' + endif + + if is_emscripten or not compilers['cpp'].compiles('struct E {}; int main() { throw E(); }', name: 'C++ exceptions support check') + libretro_defines += '-DMKXPZ_NO_EXCEPTIONS' + libretro_defines += '-DBOOST_NO_EXCEPTIONS' + endif + + if not compilers['cpp'].has_header_symbol('mutex', 'std::mutex') + libretro_defines += '-DMKXPZ_NO_STD_MUTEX' + endif + + if not compilers['cpp'].has_header_symbol('mutex', 'std::recursive_mutex') + libretro_defines += '-DMKXPZ_NO_STD_RECURSIVE_MUTEX' + endif + + if not compilers['cpp'].has_header_symbol('thread', 'std::this_thread::yield') + libretro_defines += '-DMKXPZ_NO_STD_THIS_THREAD_YIELD' + endif + + if not compilers['cpp'].has_header('pthread.h') or not compilers['cpp'].compiles(''' + #include + int main() { + pthread_mutex_t mutex; + pthread_cond_t cond; + pthread_mutex_init(&mutex, NULL); + pthread_cond_init(&cond, NULL); + pthread_cond_signal(&cond); + pthread_mutex_lock(&mutex); + pthread_cond_wait(&cond, &mutex); + int result = pthread_self() != pthread_self(); + pthread_mutex_unlock(&mutex); + pthread_cond_destroy(&cond); + pthread_mutex_destroy(&mutex); + return result; + } + ''', name: 'pthread.h sanity check') + libretro_defines += '-DMKXPZ_NO_PTHREAD_H' + libretro_defines += '-DMKXPZ_NO_SEMAPHORE_H' + elif not compilers['cpp'].has_header('semaphore.h') or not compilers['cpp'].compiles(''' + #include + int main() { + sem_t sem; + sem_init(&sem, 0, 0); + sem_post(&sem); + sem_wait(&sem); + sem_destroy(&sem); + return 0; + } + ''', name: 'semaphore.h sanity check') + libretro_defines += '-DMKXPZ_NO_SEMAPHORE_H' + endif + + # Enable integer-only mode in FLAC when building with Vita SDK. Otherwise, we get an internal compiler error in FLAC__window_triangle: + # + # ../subprojects/flac/src/libFLAC/window.c: In function 'FLAC__window_triangle': + # ../subprojects/flac/src/libFLAC/window.c:197:1: error: unrecognizable insn: + # 197 | } + # | ^ + # (insn 191 190 192 21 (set (reg:V4SF 443) + # (mult:V4SF (reg:V4SF 443) + # (reg:V4SF 444))) "../subprojects/flac/src/libFLAC/window.c":189:43 -1 + # (nil)) + # during RTL pass: vregs + # ../subprojects/flac/src/libFLAC/window.c:197:1: internal compiler error: in extract_insn, at recog.c:2294 + # Please submit a full bug report, + # with preprocessed source if appropriate. + # See for instructions. + if compilers['c'].has_header_symbol('sys/config.h', '__vita__') + libretro_defines += '-DFLAC__INTEGER_ONLY_LIBRARY' + endif + + # Position-independent code is not supported on some platforms where we need to build a static library, e.g. https://github.com/vitasdk/vita-toolchain/issues/264 + use_pic = is_emscripten or not core_is_static + if not use_pic and get_option('b_staticpic') + error('The `b_staticpic` option needs to be disabled when building for this platform.') + endif + subdir('shader') cmake = import('cmake') boost_options = cmake.subproject_options() boost_options.add_cmake_defines({ - 'CMAKE_C_FLAGS': ' '.join(libretro_cflags), - 'CMAKE_CXX_FLAGS': ' '.join(libretro_cppflags), - 'CMAKE_POSITION_INDEPENDENT_CODE': get_option('b_staticpic'), + 'CMAKE_C_FLAGS': ' '.join(libretro_defines + libretro_cflags), + 'CMAKE_CXX_FLAGS': ' '.join(libretro_defines + libretro_cppflags), + 'CMAKE_POSITION_INDEPENDENT_CODE': use_pic, 'BUILD_TESTING': false, }) zlib_options = cmake.subproject_options() zlib_options.add_cmake_defines({ - 'CMAKE_C_FLAGS': ' '.join(libretro_cflags), - 'CMAKE_CXX_FLAGS': ' '.join(libretro_cppflags), - 'CMAKE_POSITION_INDEPENDENT_CODE': get_option('b_staticpic'), + 'CMAKE_C_FLAGS': ' '.join(libretro_defines + libretro_cflags), + 'CMAKE_CXX_FLAGS': ' '.join(libretro_defines + libretro_cppflags), + 'CMAKE_POSITION_INDEPENDENT_CODE': use_pic, 'BUILD_SHARED_LIBS': false, 'ZLIB_BUILD_EXAMPLES': false, }) libzip_options = cmake.subproject_options() libzip_options.add_cmake_defines({ - 'CMAKE_C_FLAGS': ' '.join(libretro_cflags), - 'CMAKE_CXX_FLAGS': ' '.join(libretro_cppflags), - 'CMAKE_POSITION_INDEPENDENT_CODE': get_option('b_staticpic'), + 'CMAKE_C_FLAGS': ' '.join(libretro_defines + libretro_cflags), + 'CMAKE_CXX_FLAGS': ' '.join(libretro_defines + libretro_cppflags), + 'CMAKE_POSITION_INDEPENDENT_CODE': use_pic, 'BUILD_SHARED_LIBS': false, 'LIBZIP_DO_INSTALL': false, 'BUILD_TOOLS': false, @@ -131,9 +205,9 @@ if is_libretro physfs_options = cmake.subproject_options() physfs_options.add_cmake_defines({ - 'CMAKE_C_FLAGS': ' '.join(libretro_cflags), - 'CMAKE_CXX_FLAGS': ' '.join(libretro_cppflags), - 'CMAKE_POSITION_INDEPENDENT_CODE': get_option('b_staticpic'), + 'CMAKE_C_FLAGS': ' '.join(libretro_defines + libretro_cflags), + 'CMAKE_CXX_FLAGS': ' '.join(libretro_defines + libretro_cppflags), + 'CMAKE_POSITION_INDEPENDENT_CODE': use_pic, 'PHYSFS_BUILD_STATIC': true, 'PHYSFS_BUILD_SHARED': false, 'PHYSFS_BUILD_TEST': false, @@ -142,9 +216,9 @@ if is_libretro openal_options = cmake.subproject_options() openal_options.add_cmake_defines({ - 'CMAKE_C_FLAGS': ' '.join(libretro_cflags), - 'CMAKE_CXX_FLAGS': ' '.join(libretro_cppflags), - 'CMAKE_POSITION_INDEPENDENT_CODE': get_option('b_staticpic'), + 'CMAKE_C_FLAGS': ' '.join(libretro_defines + libretro_cflags), + 'CMAKE_CXX_FLAGS': ' '.join(libretro_defines + libretro_cppflags), + 'CMAKE_POSITION_INDEPENDENT_CODE': use_pic, 'LIBTYPE': 'STATIC', 'ALSOFT_DLOPEN': false, 'ALSOFT_UTILS': false, @@ -175,18 +249,18 @@ if is_libretro fluidlite_options = cmake.subproject_options() fluidlite_options.add_cmake_defines({ - 'CMAKE_C_FLAGS': ' '.join(libretro_cflags), - 'CMAKE_CXX_FLAGS': ' '.join(libretro_cppflags), - 'CMAKE_POSITION_INDEPENDENT_CODE': get_option('b_staticpic'), + 'CMAKE_C_FLAGS': ' '.join(libretro_defines + libretro_cflags), + 'CMAKE_CXX_FLAGS': ' '.join(libretro_defines + libretro_cppflags), + 'CMAKE_POSITION_INDEPENDENT_CODE': use_pic, 'FLUIDLITE_BUILD_STATIC': true, 'FLUIDLITE_BUILD_SHARED': false, }) ogg_options = cmake.subproject_options() ogg_options.add_cmake_defines({ - 'CMAKE_C_FLAGS': ' '.join(libretro_cflags), - 'CMAKE_CXX_FLAGS': ' '.join(libretro_cppflags), - 'CMAKE_POSITION_INDEPENDENT_CODE': get_option('b_staticpic'), + 'CMAKE_C_FLAGS': ' '.join(libretro_defines + libretro_cflags), + 'CMAKE_CXX_FLAGS': ' '.join(libretro_defines + libretro_cppflags), + 'CMAKE_POSITION_INDEPENDENT_CODE': use_pic, 'BUILD_SHARED_LIBS': false, 'BUILD_TESTING': false, 'BUILD_FRAMEWORK': false, @@ -194,9 +268,9 @@ if is_libretro vorbis_options = cmake.subproject_options() vorbis_options.add_cmake_defines({ - 'CMAKE_C_FLAGS': ' '.join(libretro_cflags), - 'CMAKE_CXX_FLAGS': ' '.join(libretro_cppflags), - 'CMAKE_POSITION_INDEPENDENT_CODE': get_option('b_staticpic'), + 'CMAKE_C_FLAGS': ' '.join(libretro_defines + libretro_cflags), + 'CMAKE_CXX_FLAGS': ' '.join(libretro_defines + libretro_cppflags), + 'CMAKE_POSITION_INDEPENDENT_CODE': use_pic, 'BUILD_SHARED_LIBS': false, 'BUILD_TESTING': false, 'BUILD_FRAMEWORK': false, @@ -204,9 +278,9 @@ if is_libretro flac_options = cmake.subproject_options() flac_options.add_cmake_defines({ - 'CMAKE_C_FLAGS': ' '.join(libretro_cflags), - 'CMAKE_CXX_FLAGS': ' '.join(libretro_cppflags), - 'CMAKE_POSITION_INDEPENDENT_CODE': get_option('b_staticpic'), + 'CMAKE_C_FLAGS': ' '.join(libretro_defines + libretro_cflags), + 'CMAKE_CXX_FLAGS': ' '.join(libretro_defines + libretro_cppflags), + 'CMAKE_POSITION_INDEPENDENT_CODE': use_pic, 'BUILD_SHARED_LIBS': false, 'BUILD_CXXLIBS': false, 'BUILD_PROGRAMS': false, @@ -223,9 +297,9 @@ if is_libretro opus_options = cmake.subproject_options() opus_options.add_cmake_defines({ - 'CMAKE_C_FLAGS': ' '.join(libretro_cflags), - 'CMAKE_CXX_FLAGS': ' '.join(libretro_cppflags), - 'CMAKE_POSITION_INDEPENDENT_CODE': get_option('b_staticpic'), + 'CMAKE_C_FLAGS': ' '.join(libretro_defines + libretro_cflags), + 'CMAKE_CXX_FLAGS': ' '.join(libretro_defines + libretro_cppflags), + 'CMAKE_POSITION_INDEPENDENT_CODE': use_pic, 'BUILD_SHARED_LIBS': false, 'OPUS_BUILD_SHARED_LIBRARY': false, 'OPUS_BUILD_TESTING': false, @@ -241,9 +315,9 @@ if is_libretro mpg123_options = cmake.subproject_options() mpg123_options.add_cmake_defines({ - 'CMAKE_C_FLAGS': ' '.join(libretro_cflags), - 'CMAKE_CXX_FLAGS': ' '.join(libretro_cppflags), - 'CMAKE_POSITION_INDEPENDENT_CODE': get_option('b_staticpic'), + 'CMAKE_C_FLAGS': ' '.join(libretro_defines + libretro_cflags), + 'CMAKE_CXX_FLAGS': ' '.join(libretro_defines + libretro_cppflags), + 'CMAKE_POSITION_INDEPENDENT_CODE': use_pic, 'BUILD_SHARED_LIBS': false, 'BUILD_PROGRAMS': false, 'BUILD_LIBOUT123': false, @@ -253,9 +327,9 @@ if is_libretro libsndfile_options = cmake.subproject_options() libsndfile_options.add_cmake_defines({ - 'CMAKE_C_FLAGS': ' '.join(libretro_cflags), - 'CMAKE_CXX_FLAGS': ' '.join(libretro_cppflags), - 'CMAKE_POSITION_INDEPENDENT_CODE': get_option('b_staticpic'), + 'CMAKE_C_FLAGS': ' '.join(libretro_defines + libretro_cflags), + 'CMAKE_CXX_FLAGS': ' '.join(libretro_defines + libretro_cppflags), + 'CMAKE_POSITION_INDEPENDENT_CODE': use_pic, 'BUILD_SHARED_LIBS': false, 'BUILD_PROGRAMS': false, 'BUILD_EXAMPLES': false, @@ -362,6 +436,7 @@ if is_libretro ], sources: global_sources + [ 'src/core.cpp', + 'src/mkxp-threads.cpp', 'src/sharedstate.cpp', 'src/audio/alstream.cpp', 'src/audio/audio.cpp', diff --git a/src/core.cpp b/src/core.cpp index ed9eff4a..ba943e08 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -227,6 +227,7 @@ static bool init_sandbox() { fluid_set_log_function(FLUID_DBG, fluid_log, NULL); static fluid_fileapi_t fluid_fileapi = { + .data = NULL, .free = [](fluid_fileapi_t *f) { return 0; }, diff --git a/src/display/bitmap.cpp b/src/display/bitmap.cpp index c55c7258..f8a5430b 100644 --- a/src/display/bitmap.cpp +++ b/src/display/bitmap.cpp @@ -423,7 +423,6 @@ struct BitmapPrivate FBO::clear(); glState.clearColor.pop(); - glState.scissorBox.pop(); glState.scissorTest.pop(); } diff --git a/src/mkxp-threads.cpp b/src/mkxp-threads.cpp new file mode 100644 index 00000000..360134b9 --- /dev/null +++ b/src/mkxp-threads.cpp @@ -0,0 +1,157 @@ +/* +** mkxp-threads.cpp +** +** This file is part of mkxp. +** +** Copyright (C) 2013 - 2021 Amaryllis Kulla +** +** mkxp 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. +** +** mkxp 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 mkxp. If not, see . +*/ + +#include "mkxp-threads.h" +#include + +#if defined(MKXPZ_NO_SEMAPHORE_H) && !defined(MKXPZ_NO_PTHREAD_H) +struct mkxp_sem_private { + unsigned int value; + pthread_mutex_t mutex; + pthread_cond_t cond; +}; +#endif + +extern "C" mkxp_thread_t mkxp_thread_self() { +#ifndef MKXPZ_NO_PTHREAD_H + return pthread_self(); +#else + return 42; +#endif +} + +extern "C" int mkxp_mutex_init(mkxp_mutex_t *mutex, bool recursive) { +#ifndef MKXPZ_NO_PTHREAD_H + if (recursive) { + pthread_mutexattr_t attr; + if (pthread_mutexattr_init(&attr)) { + return -1; + } + if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) { + return -1; + } + return pthread_mutex_init(mutex, &attr); + } else { + return pthread_mutex_init(mutex, NULL); + } +#else + *mutex = 0; + return 0; +#endif +} + +extern "C" int mkxp_mutex_destroy(mkxp_mutex_t *mutex) { +#ifndef MKXPZ_NO_PTHREAD_H + return pthread_mutex_destroy(mutex); +#else + assert(!*mutex); + return 0; +#endif +} + +extern "C" int mkxp_mutex_lock(mkxp_mutex_t *mutex) { +#ifndef MKXPZ_NO_PTHREAD_H + return pthread_mutex_lock(mutex); +#else + ++*mutex; + return 0; +#endif +} + +extern "C" int mkxp_mutex_unlock(mkxp_mutex_t *mutex) { +#ifndef MKXPZ_NO_PTHREAD_H + return pthread_mutex_unlock(mutex); +#else + assert(*mutex); + --*mutex; + return 0; +#endif +} + +extern "C" int mkxp_sem_init(mkxp_sem_t *sem, unsigned int value) { +#ifndef MKXPZ_NO_SEMAPHORE_H + return sem_init(sem, 0, value); +#elif !defined(MKXPZ_NO_PTHREAD_H) + *sem = (void *)new mkxp_sem_private; + int mutex_init_result = pthread_mutex_init(&((struct mkxp_sem_private *)*sem)->mutex, NULL); + if (mutex_init_result) { + return -1; + } + int cond_init_result = pthread_cond_init(&((struct mkxp_sem_private *)*sem)->cond, NULL); + if (cond_init_result) { + pthread_mutex_destroy(&((struct mkxp_sem_private *)*sem)->mutex); + return -1; + } + ((struct mkxp_sem_private *)*sem)->value = value; + return 0; +#else + *sem = value; + return 0; +#endif +} + +extern "C" int mkxp_sem_destroy(mkxp_sem_t *sem) { +#ifndef MKXPZ_NO_SEMAPHORE_H + return sem_destroy(sem); +#elif !defined(MKXPZ_NO_PTHREAD_H) + pthread_cond_destroy(&((struct mkxp_sem_private *)*sem)->cond); + pthread_mutex_destroy(&((struct mkxp_sem_private *)*sem)->mutex); + delete (struct mkxp_sem_private *)*sem; + return 0; +#else + return 0; +#endif +} + +extern "C" int mkxp_sem_post(mkxp_sem_t *sem) { +#ifndef MKXPZ_NO_SEMAPHORE_H + return sem_post(sem); +#elif !defined(MKXPZ_NO_PTHREAD_H) + while (pthread_mutex_lock(&((struct mkxp_sem_private *)*sem)->mutex)) {} + ++((struct mkxp_sem_private *)*sem)->value; + pthread_cond_signal(&((struct mkxp_sem_private *)*sem)->cond); + pthread_mutex_unlock(&((struct mkxp_sem_private *)*sem)->mutex); + return 0; +#else + ++*sem; + return 0; +#endif +} + +extern "C" int mkxp_sem_wait(mkxp_sem_t *sem) { +#ifndef MKXPZ_NO_SEMAPHORE_H + return sem_wait(sem); +#elif !defined(MKXPZ_NO_PTHREAD_H) + while (pthread_mutex_lock(&((struct mkxp_sem_private *)*sem)->mutex)) {} + for (;;) { + if (((struct mkxp_sem_private *)*sem)->value) { + --((struct mkxp_sem_private *)*sem)->value; + pthread_mutex_unlock(&((struct mkxp_sem_private *)*sem)->mutex); + return 0; + } + while (pthread_cond_wait(&((struct mkxp_sem_private *)*sem)->cond, &((struct mkxp_sem_private *)*sem)->mutex)) {} + } +#else + assert(*sem); + --*sem; + return 0; +#endif +} diff --git a/src/mkxp-threads.h b/src/mkxp-threads.h new file mode 100644 index 00000000..84b6614e --- /dev/null +++ b/src/mkxp-threads.h @@ -0,0 +1,154 @@ +/* +** mkxp-threads.h +** +** This file is part of mkxp. +** +** Copyright (C) 2013 - 2021 Amaryllis Kulla +** +** mkxp 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. +** +** mkxp 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 mkxp. If not, see . +*/ + +#ifndef MKXPZ_THREADS_H +#define MKXPZ_THREADS_H + +#include +#include + +#ifndef MKXPZ_NO_PTHREAD_H +# include +#endif + +#ifndef MKXPZ_NO_SEMAPHORE_H +# include +#endif + +#ifdef __cplusplus +#include + +extern "C" { +#endif + +#ifndef MKXPZ_NO_PTHREAD_H +typedef pthread_t mkxp_thread_t; +typedef pthread_mutex_t mkxp_mutex_t; +#else +typedef size_t mkxp_thread_t; +typedef unsigned int mkxp_mutex_t; +#endif + +#ifndef MKXPZ_NO_SEMAPHORE_H +typedef sem_t mkxp_sem_t; +#elif !defined(MKXPZ_NO_PTHREAD_H) +typedef void *mkxp_sem_t; +#else +typedef unsigned int mkxp_sem_t; +#endif + +mkxp_thread_t mkxp_thread_self(void); + +int mkxp_mutex_init(mkxp_mutex_t *mutex, bool recursive); + +int mkxp_mutex_destroy(mkxp_mutex_t *mutex); + +int mkxp_mutex_lock(mkxp_mutex_t *mutex); + +int mkxp_mutex_unlock(mkxp_mutex_t *mutex); + +int mkxp_sem_init(mkxp_sem_t *sem, unsigned int value); + +int mkxp_sem_destroy(mkxp_sem_t *sem); + +int mkxp_sem_post(mkxp_sem_t *sem); + +int mkxp_sem_wait(mkxp_sem_t *sem); + +#ifdef __cplusplus +} + +# ifdef MKXPZ_NO_STD_MUTEX +namespace std { + class mutex { + public: + typedef mkxp_mutex_t *native_handle_type; + + mkxp_mutex_t inner; + + inline mutex() noexcept { + if (mkxp_mutex_init(&inner, false)) { + abort(); + } + } + + inline ~mutex() noexcept { + mkxp_mutex_destroy(&inner); + } + + inline void lock() noexcept { + if (mkxp_mutex_lock(&inner)) { + abort(); + } + } + + inline void unlock() noexcept { + if (mkxp_mutex_unlock(&inner)) { + abort(); + } + } + + inline native_handle_type native_handle() noexcept { + return &inner; + } + }; +} +# endif + +# ifdef MKXPZ_NO_STD_RECURSIVE_MUTEX +namespace std { + class recursive_mutex { + public: + typedef mkxp_mutex_t *native_handle_type; + + mkxp_mutex_t inner; + + inline recursive_mutex() noexcept { + if (mkxp_mutex_init(&inner, true)) { + abort(); + } + } + + inline ~recursive_mutex() noexcept { + mkxp_mutex_destroy(&inner); + } + + inline void lock() noexcept { + if (mkxp_mutex_lock(&inner)) { + abort(); + } + } + + inline void unlock() noexcept { + if (mkxp_mutex_unlock(&inner)) { + abort(); + } + } + + inline native_handle_type native_handle() noexcept { + return &inner; + } + }; +} +# endif +#endif + +#endif // MKXPZ_THREADS_H diff --git a/src/util/sigslot/signal.hpp b/src/util/sigslot/signal.hpp index 3dfd2def..ccf2d07d 100644 --- a/src/util/sigslot/signal.hpp +++ b/src/util/sigslot/signal.hpp @@ -1,7 +1,7 @@ #pragma once #include #include -#include +#include "mkxp-threads.h" #include #include #include @@ -348,7 +348,9 @@ struct spin_mutex { void lock() noexcept { while (true) { while (!state.load(std::memory_order_relaxed)) { +#ifndef MKXPZ_NO_STD_THIS_THREAD_YIELD std::this_thread::yield(); +#endif } if (try_lock()) { diff --git a/subprojects/boost_asio.wrap b/subprojects/boost_asio.wrap index b11a262a..91fa34a7 100644 --- a/subprojects/boost_asio.wrap +++ b/subprojects/boost_asio.wrap @@ -2,3 +2,4 @@ url = https://github.com/boostorg/asio revision = boost-1.87.0 depth = 1 +diff_files = boost_asio-counter.patch diff --git a/subprojects/mpg123.wrap b/subprojects/mpg123.wrap index 9e9e7197..6b2c4e5d 100644 --- a/subprojects/mpg123.wrap +++ b/subprojects/mpg123.wrap @@ -4,4 +4,4 @@ url = https://github.com/madebr/mpg123 revision = 45fbaaeb00072d689b9c2ac4b7d109343f30abee depth = 1 patch_directory = mpg123 -diff_files = mpg123-compat-str.patch, mpg123-emscripten-endian.patch, mpg123-intrinsics.patch, mpg123-libsyn123.patch, mpg123-offset.patch, mpg123-signal.patch +diff_files = mpg123-emscripten-endian.patch, mpg123-intrinsics.patch, mpg123-libsyn123.patch, mpg123-offset.patch, mpg123-pic.patch, mpg123-signal.patch diff --git a/subprojects/openal-soft.wrap b/subprojects/openal-soft.wrap index b985abff..b0896ced 100644 --- a/subprojects/openal-soft.wrap +++ b/subprojects/openal-soft.wrap @@ -2,4 +2,4 @@ url = https://github.com/kcat/openal-soft revision = 1.24.2 depth = 1 -diff_files = openal-soft-android-log.patch, openal-soft-atomic.patch, openal-soft-buildtype.patch, openal-soft-c11.patch, openal-soft-darwin-log.patch, openal-soft-devkitppc.patch, openal-soft-emscripten-pthread.patch, openal-soft-emscripten-setschedparam.patch, openal-soft-emscripten-symbol-conflict.patch, openal-soft-emscripten-tss.patch, openal-soft-event-thread.patch, openal-soft-flockfile.patch, openal-soft-int32.patch +diff_files = openal-soft-android-log.patch, openal-soft-atomic.patch, openal-soft-buildtype.patch, openal-soft-c11.patch, openal-soft-constexpr.patch, openal-soft-emscripten-pthread.patch, openal-soft-emscripten-setschedparam.patch, openal-soft-emscripten-symbol-conflict.patch, openal-soft-event-thread.patch, openal-soft-filesystem.patch, openal-soft-flockfile.patch, openal-soft-int32.patch, openal-soft-mkxp-threads.patch, openal-soft-null.patch, openal-soft-pic.patch, openal-soft-ps3.patch diff --git a/subprojects/packagefiles/boost_asio-counter.patch b/subprojects/packagefiles/boost_asio-counter.patch new file mode 100644 index 00000000..f6562eb9 --- /dev/null +++ b/subprojects/packagefiles/boost_asio-counter.patch @@ -0,0 +1,14 @@ +# Makes the `BOOST_ASIO_CORO_YIELD` and `BOOST_ASIO_CORO_FORK` macros always use the `__COUNTER__` macro, even with non-MSVC compilers. +# Using `__LINE__` results in "duplicate case value" compilation errors when targeting PlayStation 3 due to some idiosyncrasy in how the __LINE__ macro is parsed in the really old GCC version it's using. + +--- a/include/boost/asio/coroutine.hpp ++++ b/include/boost/asio/coroutine.hpp +@@ -319,7 +319,7 @@ private: + } \ + else + +-#if defined(_MSC_VER) ++#if true + # define BOOST_ASIO_CORO_YIELD BOOST_ASIO_CORO_YIELD_IMPL(__COUNTER__ + 1) + # define BOOST_ASIO_CORO_FORK BOOST_ASIO_CORO_FORK_IMPL(__COUNTER__ + 1) + #else // defined(_MSC_VER) diff --git a/subprojects/packagefiles/mpg123-compat-str.patch b/subprojects/packagefiles/mpg123-compat-str.patch deleted file mode 100644 index b232409f..00000000 --- a/subprojects/packagefiles/mpg123-compat-str.patch +++ /dev/null @@ -1,11 +0,0 @@ -# Removes the duplicate inclusion of compat_str.c. - ---- a/ports/cmake/src/compat/CMakeLists.txt -+++ b/ports/cmake/src/compat/CMakeLists.txt -@@ -8,6 +8,3 @@ add_library(${TARGET}_dl OBJECT - "${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/compat/compat_dl.c") - set_target_properties(${TARGET}_dl PROPERTIES POSITION_INDEPENDENT_CODE ON) - --add_library(${TARGET}_str OBJECT -- "${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/compat/compat_str.c") --set_target_properties(${TARGET}_str PROPERTIES POSITION_INDEPENDENT_CODE ON) diff --git a/subprojects/packagefiles/mpg123-offset.patch b/subprojects/packagefiles/mpg123-offset.patch index 2bc2626b..b39f935c 100644 --- a/subprojects/packagefiles/mpg123-offset.patch +++ b/subprojects/packagefiles/mpg123-offset.patch @@ -1,16 +1,5 @@ # Fixes a problem where the size of off_t is miscalculated on certain platforms. ---- a/ports/cmake/src/CMakeLists.txt -+++ b/ports/cmake/src/CMakeLists.txt -@@ -71,7 +71,7 @@ check_function_exists(fork HAVE_FORK) - check_function_exists(execvp HAVE_EXECVP) - check_function_exists(ctermid HAVE_CTERMID) - check_function_exists(clock_gettime HAVE_CLOCK_GETTIME) -- -+set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} /D_FILE_OFFSET_BITS=64) - check_type_size(off_t SIZEOF_OFF_T) - - if(SIZEOF_OFF_T LESS 8) --- a/src/libmpg123/lfs_wrap.c +++ b/src/libmpg123/lfs_wrap.c @@ -48,18 +48,22 @@ diff --git a/subprojects/packagefiles/mpg123-pic.patch b/subprojects/packagefiles/mpg123-pic.patch new file mode 100644 index 00000000..df08f1ba --- /dev/null +++ b/subprojects/packagefiles/mpg123-pic.patch @@ -0,0 +1,18 @@ +# Prevents mpg123's build system from forcibly enabling position-independent code. +# Also removes the duplicate inclusion of compat_str.c. That causes duplicate symbol errors when linking mpg123 as whole archive. + +--- a/ports/cmake/src/compat/CMakeLists.txt ++++ b/ports/cmake/src/compat/CMakeLists.txt +@@ -2,12 +2,6 @@ set(TARGET compat) + add_library(${TARGET} OBJECT + "${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/compat/compat.c" + "${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/compat/compat_str.c") +-set_target_properties(${TARGET} PROPERTIES POSITION_INDEPENDENT_CODE ON) + + add_library(${TARGET}_dl OBJECT + "${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/compat/compat_dl.c") +-set_target_properties(${TARGET}_dl PROPERTIES POSITION_INDEPENDENT_CODE ON) +- +-add_library(${TARGET}_str OBJECT +- "${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/compat/compat_str.c") +-set_target_properties(${TARGET}_str PROPERTIES POSITION_INDEPENDENT_CODE ON) diff --git a/subprojects/packagefiles/openal-soft-constexpr.patch b/subprojects/packagefiles/openal-soft-constexpr.patch new file mode 100644 index 00000000..5a256f4a --- /dev/null +++ b/subprojects/packagefiles/openal-soft-constexpr.patch @@ -0,0 +1,143 @@ +# Removes all exception throwing and logging inside of functions marked `constexpr` since old versions of GCC don't support it. +# When building for PlayStation 3, we use an old enough version of GCC for this to be a problem. + +--- a/al/auxeffectslot.cpp ++++ b/al/auxeffectslot.cpp +@@ -243,7 +243,7 @@ constexpr auto EffectSlotTypeFromEnum(ALenum type) noexcept -> EffectSlotType + case AL_EFFECT_DEDICATED_DIALOGUE: return EffectSlotType::Dedicated; + case AL_EFFECT_CONVOLUTION_SOFT: return EffectSlotType::Convolution; + } +- ERR("Unhandled effect enum: {:#04x}", as_unsigned(type)); ++ + return EffectSlotType::None; + } + +--- a/al/buffer.cpp ++++ b/al/buffer.cpp +@@ -88,8 +88,8 @@ constexpr auto EnumFromAmbiLayout(AmbiLayout layout) -> ALenum + case AmbiLayout::FuMa: return AL_FUMA_SOFT; + case AmbiLayout::ACN: return AL_ACN_SOFT; + } +- throw std::runtime_error{fmt::format("Invalid AmbiLayout: {}", +- int{al::to_underlying(layout)})}; ++ ++ abort(); + } + + constexpr auto AmbiScalingFromEnum(ALenum scale) noexcept -> std::optional +@@ -111,8 +111,8 @@ constexpr auto EnumFromAmbiScaling(AmbiScaling scale) -> ALenum + case AmbiScaling::N3D: return AL_N3D_SOFT; + case AmbiScaling::UHJ: break; + } +- throw std::runtime_error{fmt::format("Invalid AmbiScaling: {}", +- int{al::to_underlying(scale)})}; ++ ++ abort(); + } + + #if ALSOFT_EAX +--- a/al/debug.cpp ++++ b/al/debug.cpp +@@ -110,8 +110,8 @@ constexpr auto GetDebugSourceEnum(DebugSource source) -> ALenum + case DebugSource::Application: return AL_DEBUG_SOURCE_APPLICATION_EXT; + case DebugSource::Other: return AL_DEBUG_SOURCE_OTHER_EXT; + } +- throw std::runtime_error{fmt::format("Unexpected debug source value: {}", +- int{al::to_underlying(source)})}; ++ ++ abort(); + } + + constexpr auto GetDebugTypeEnum(DebugType type) -> ALenum +@@ -128,8 +128,8 @@ constexpr auto GetDebugTypeEnum(DebugType type) -> ALenum + case DebugType::PopGroup: return AL_DEBUG_TYPE_POP_GROUP_EXT; + case DebugType::Other: return AL_DEBUG_TYPE_OTHER_EXT; + } +- throw std::runtime_error{fmt::format("Unexpected debug type value: {}", +- int{al::to_underlying(type)})}; ++ ++ abort(); + } + + constexpr auto GetDebugSeverityEnum(DebugSeverity severity) -> ALenum +@@ -141,8 +141,8 @@ constexpr auto GetDebugSeverityEnum(DebugSeverity severity) -> ALenum + case DebugSeverity::Low: return AL_DEBUG_SEVERITY_LOW_EXT; + case DebugSeverity::Notification: return AL_DEBUG_SEVERITY_NOTIFICATION_EXT; + } +- throw std::runtime_error{fmt::format("Unexpected debug severity value: {}", +- int{al::to_underlying(severity)})}; ++ ++ abort(); + } + + +--- a/al/effects/chorus.cpp ++++ b/al/effects/chorus.cpp +@@ -43,8 +43,8 @@ constexpr ALenum EnumFromWaveform(ChorusWaveform type) + case ChorusWaveform::Sinusoid: return AL_CHORUS_WAVEFORM_SINUSOID; + case ChorusWaveform::Triangle: return AL_CHORUS_WAVEFORM_TRIANGLE; + } +- throw std::runtime_error{fmt::format("Invalid chorus waveform: {}", +- int{al::to_underlying(type)})}; ++ ++ abort(); + } + + constexpr EffectProps genDefaultChorusProps() noexcept +--- a/al/effects/fshifter.cpp ++++ b/al/effects/fshifter.cpp +@@ -40,7 +40,7 @@ constexpr ALenum EnumFromDirection(FShifterDirection dir) + case FShifterDirection::Up: return AL_FREQUENCY_SHIFTER_DIRECTION_UP; + case FShifterDirection::Off: return AL_FREQUENCY_SHIFTER_DIRECTION_OFF; + } +- throw std::runtime_error{fmt::format("Invalid direction: {}", int{al::to_underlying(dir)})}; ++ abort(); + } + + constexpr EffectProps genDefaultProps() noexcept +--- a/al/effects/modulator.cpp ++++ b/al/effects/modulator.cpp +@@ -40,8 +40,8 @@ constexpr ALenum EnumFromWaveform(ModulatorWaveform type) + case ModulatorWaveform::Sawtooth: return AL_RING_MODULATOR_SAWTOOTH; + case ModulatorWaveform::Square: return AL_RING_MODULATOR_SQUARE; + } +- throw std::runtime_error{fmt::format("Invalid modulator waveform: {}", +- int{al::to_underlying(type)})}; ++ ++ abort(); + } + + constexpr EffectProps genDefaultProps() noexcept +--- a/al/effects/vmorpher.cpp ++++ b/al/effects/vmorpher.cpp +@@ -97,7 +97,7 @@ constexpr ALenum EnumFromPhenome(VMorpherPhenome phenome) + HANDLE_PHENOME(V); + HANDLE_PHENOME(Z); + } +- throw std::runtime_error{fmt::format("Invalid phenome: {}", int{al::to_underlying(phenome)})}; ++ abort(); + #undef HANDLE_PHENOME + } + +@@ -119,8 +119,8 @@ constexpr ALenum EnumFromWaveform(VMorpherWaveform type) + case VMorpherWaveform::Triangle: return AL_VOCAL_MORPHER_WAVEFORM_TRIANGLE; + case VMorpherWaveform::Sawtooth: return AL_VOCAL_MORPHER_WAVEFORM_SAWTOOTH; + } +- throw std::runtime_error{fmt::format("Invalid vocal morpher waveform: {}", +- int{al::to_underlying(type)})}; ++ ++ abort(); + } + + constexpr EffectProps genDefaultProps() noexcept +--- a/al/state.cpp ++++ b/al/state.cpp +@@ -141,7 +141,7 @@ constexpr auto ALenumFromDistanceModel(DistanceModel model) -> ALenum + case DistanceModel::Exponent: return AL_EXPONENT_DISTANCE; + case DistanceModel::ExponentClamped: return AL_EXPONENT_DISTANCE_CLAMPED; + } +- throw std::runtime_error{"Unexpected distance model "+std::to_string(static_cast(model))}; ++ abort(); + } + + enum PropertyValue : ALenum { diff --git a/subprojects/packagefiles/openal-soft-darwin-log.patch b/subprojects/packagefiles/openal-soft-darwin-log.patch deleted file mode 100644 index cfb7ff97..00000000 --- a/subprojects/packagefiles/openal-soft-darwin-log.patch +++ /dev/null @@ -1,26 +0,0 @@ -# Removes the Apple-specific code from alconfig.cpp because we get missing symbol errors otherwise. - ---- a/alc/alconfig.cpp -+++ b/alc/alconfig.cpp -@@ -419,21 +419,6 @@ void ReadALConfig() - } - } - --#ifdef __APPLE__ -- CFBundleRef mainBundle = CFBundleGetMainBundle(); -- if(mainBundle) -- { -- CFURLRef configURL{CFBundleCopyResourceURL(mainBundle, CFSTR(".alsoftrc"), CFSTR(""), -- nullptr)}; -- -- std::array fileName{}; -- if(configURL && CFURLGetFileSystemRepresentation(configURL, true, fileName.data(), fileName.size())) -- { -- if(std::ifstream f{reinterpret_cast(fileName.data())}; f.is_open()) -- LoadConfigFromFile(f); -- } -- } --#endif - - if(auto homedir = al::getenv("HOME")) - { diff --git a/subprojects/packagefiles/openal-soft-devkitppc.patch b/subprojects/packagefiles/openal-soft-devkitppc.patch deleted file mode 100644 index 9fad3004..00000000 --- a/subprojects/packagefiles/openal-soft-devkitppc.patch +++ /dev/null @@ -1,133 +0,0 @@ -# devkitPPC does not provide POSIX semaphores, which OpenAL Soft needs. -# However, devkitPPC provides an alternative semaphore implementation in an external library, libogc. -# This patch makes OpenAL Soft use libogc semaphores if POSIX semaphores is not found. - ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -174,6 +174,11 @@ if("${CMAKE_C_PLATFORM_ID}" STREQUAL "QNX") - set(INC_PATHS ${INC_PATHS} /usr/include) - set(LINKER_FLAGS ${LINKER_FLAGS} -L/usr/lib) - endif() -+check_symbol_exists(__DEVKITPPC__ "sys/config.h" DEVKITPPC) -+if(DEVKITPPC) -+ set(CPP_DEFS ${CPP_DEFS} MKXPZ_DEVKITPPC) -+ set(INC_PATHS ${INC_PATHS} "$ENV{DEVKITPRO}/libogc/include") -+endif() - - # When the library is built for static linking, apps should define - # AL_LIBTYPE_STATIC when including the AL headers. ---- a/common/alsem.cpp -+++ b/common/alsem.cpp -@@ -55,8 +55,6 @@ void semaphore::post() - void semaphore::wait() noexcept - { WaitForSingleObject(static_cast(mSem), INFINITE); } - --bool semaphore::try_wait() noexcept --{ return WaitForSingleObject(static_cast(mSem), 0) == WAIT_OBJECT_0; } - - } // namespace al - -@@ -83,8 +81,6 @@ void semaphore::post() - void semaphore::wait() noexcept - { dispatch_semaphore_wait(mSem, DISPATCH_TIME_FOREVER); } - --bool semaphore::try_wait() noexcept --{ return dispatch_semaphore_wait(mSem, DISPATCH_TIME_NOW) == 0; } - - } // namespace al - -@@ -96,27 +92,41 @@ namespace al { - - semaphore::semaphore(unsigned int initial) - { -+#ifdef MKXPZ_DEVKITPPC -+ if(LWP_SemInit(&mSem, initial, 0xffffffff) != 0) -+#else - if(sem_init(&mSem, 0, initial) != 0) -+#endif - throw std::system_error(std::make_error_code(std::errc::resource_unavailable_try_again)); - } - - semaphore::~semaphore() -+#ifdef MKXPZ_DEVKITPPC -+{ LWP_SemDestroy(mSem); } -+#else - { sem_destroy(&mSem); } -+#endif - - void semaphore::post() - { -+#ifdef MKXPZ_DEVKITPPC -+ if(LWP_SemPost(mSem) != 0) -+#else - if(sem_post(&mSem) != 0) -+#endif - throw std::system_error(std::make_error_code(std::errc::value_too_large)); - } - - void semaphore::wait() noexcept - { -+#ifdef MKXPZ_DEVKITPPC -+ LWP_SemWait(mSem); -+#else - while(sem_wait(&mSem) == -1 && errno == EINTR) { - } -+#endif - } - --bool semaphore::try_wait() noexcept --{ return sem_trywait(&mSem) == 0; } - - } // namespace al - ---- a/common/alsem.h -+++ b/common/alsem.h -@@ -11,7 +11,11 @@ - #include /* Fallback option for Apple without a working libdispatch */ - #endif - #elif !defined(_WIN32) --#include -+# ifdef MKXPZ_DEVKITPPC -+# include -+# else -+# include -+# endif - #endif - - namespace al { -@@ -35,7 +39,6 @@ public: - - void post(); - void wait() noexcept; -- bool try_wait() noexcept; - }; - - } // namespace al ---- a/common/althrd_setname.cpp -+++ b/common/althrd_setname.cpp -@@ -55,13 +55,25 @@ using setname_t4 = int(*)(pthread_t, const char*, void*); - { func(name); } - - [[maybe_unused]] void setname_caller(setname_t2 func, const char *name) -+#ifdef MKXPZ_DEVKITPPC -+{ func(42, name); } -+#else - { func(pthread_self(), name); } -+#endif - - [[maybe_unused]] void setname_caller(setname_t3 func, const char *name) -+#ifdef MKXPZ_DEVKITPPC -+{ func(42, name); } -+#else - { func(pthread_self(), name); } -+#endif - - [[maybe_unused]] void setname_caller(setname_t4 func, const char *name) -+#ifdef MKXPZ_DEVKITPPC -+{ func(42, "%s", const_cast(name)); /* NOLINT(*-const-cast) */ } -+#else - { func(pthread_self(), "%s", const_cast(name)); /* NOLINT(*-const-cast) */ } -+#endif - - } // namespace - diff --git a/subprojects/packagefiles/openal-soft-emscripten-tss.patch b/subprojects/packagefiles/openal-soft-emscripten-tss.patch deleted file mode 100644 index 818170d3..00000000 --- a/subprojects/packagefiles/openal-soft-emscripten-tss.patch +++ /dev/null @@ -1,71 +0,0 @@ -# Fixes a compilation error in althreads.h when targeting Emscripten without pthread support. - ---- a/common/althreads.h -+++ b/common/althreads.h -@@ -13,7 +13,7 @@ - - #include - --#else -+#elif (!defined(__EMSCRIPTEN__) || defined(__EMSCRIPTEN_PTHREADS__)) && !defined(__DEVKITPPC__) && !defined(__vita__) - - #include - #endif -@@ -107,29 +107,57 @@ public: - - #else - -+#if (defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__)) || defined(__DEVKITPPC__) || defined(__vita__) -+ void **mTss; -+#else - tss_t mTss{}; -+#endif /* (defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__)) || defined(__DEVKITPPC__) || defined(__vita__) */ - - public: - tss() - { -+#if (defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__)) || defined(__DEVKITPPC__) || defined(__vita__) -+ if ((mTss = (void **)std::malloc(sizeof *mTss)) == NULL) -+ throw std::runtime_error{"al::tss::tss()"}; -+ *mTss = nullptr; -+#else - if(int res{tss_create(&mTss, nullptr)}; res != thrd_success) - throw std::runtime_error{"al::tss::tss()"}; -+#endif /* (defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__)) || defined(__DEVKITPPC__) || defined(__vita__) */ - } - explicit tss(const T &init) : tss{} - { -+#if (defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__)) || defined(__DEVKITPPC__) || defined(__vita__) -+ if ((mTss = (void **)std::malloc(sizeof *mTss)) == NULL) -+ throw std::runtime_error{"al::tss::tss()"}; -+ *mTss = to_ptr(init); -+#else - if(int res{tss_set(mTss, to_ptr(init))}; res != thrd_success) - throw std::runtime_error{"al::tss::tss(T)"}; -+#endif /* (defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__)) || defined(__DEVKITPPC__) || defined(__vita__) */ - } -+#if (defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__)) || defined(__DEVKITPPC__) || defined(__vita__) -+ ~tss() { std::free(mTss); } -+#else - ~tss() { tss_delete(mTss); } -+#endif /* (defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__)) || defined(__DEVKITPPC__) || defined(__vita__) */ - - void set(const T &value) const - { -+#if (defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__)) || defined(__DEVKITPPC__) || defined(__vita__) -+ *mTss = to_ptr(value); -+#else - if(int res{tss_set(mTss, to_ptr(value))}; res != thrd_success) - throw std::runtime_error{"al::tss::set(T)"}; -+#endif /* (defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__)) || defined(__DEVKITPPC__) || defined(__vita__) */ - } - - [[nodiscard]] -+#if (defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__)) || defined(__DEVKITPPC__) || defined(__vita__) -+ auto get() const noexcept -> T { return from_ptr(*mTss); } -+#else - auto get() const noexcept -> T { return from_ptr(tss_get(mTss)); } -+#endif /* (defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__)) || defined(__DEVKITPPC__) || defined(__vita__) */ - #endif /* _WIN32 */ - - tss(const tss&) = delete; diff --git a/subprojects/packagefiles/openal-soft-filesystem.patch b/subprojects/packagefiles/openal-soft-filesystem.patch new file mode 100644 index 00000000..aacec028 --- /dev/null +++ b/subprojects/packagefiles/openal-soft-filesystem.patch @@ -0,0 +1,627 @@ +# Disables OpenAL Soft's dependency on both `ghc::filesystem` and `std::filesystem`. None of those work when building for PlayStation 3. +# As a side effect, also prevents OpenAL Soft from loading from its config file. + +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -610,7 +610,7 @@ set(COMMON_OBJS + common/comptr.h + common/dynload.cpp + common/dynload.h +- common/filesystem.cpp ++ + common/filesystem.h + common/flexarray.h + common/intrusive_ptr.h +@@ -673,7 +673,7 @@ set(CORE_OBJS + core/fpu_ctrl.cpp + core/fpu_ctrl.h + core/front_stablizer.h +- core/helpers.cpp ++ + core/helpers.h + core/hrtf.cpp + core/hrtf.h +--- a/alc/alconfig.cpp ++++ b/alc/alconfig.cpp +@@ -46,7 +46,7 @@ + #include "alstring.h" + #include "core/helpers.h" + #include "core/logging.h" +-#include "filesystem.h" ++ + #include "strutils.h" + + #if ALSOFT_UWP +@@ -332,156 +332,156 @@ auto GetConfigValue(const std::string_view devName, const std::string_view block + #ifdef _WIN32 + void ReadALConfig() + { +- fs::path path; + +-#if !defined(_GAMING_XBOX) +- { +-#if !ALSOFT_UWP +- std::unique_ptr bufstore; +- const HRESULT hr{SHGetKnownFolderPath(FOLDERID_RoamingAppData, KF_FLAG_DONT_UNEXPAND, +- nullptr, al::out_ptr(bufstore))}; +- if(SUCCEEDED(hr)) +- { +- const std::wstring_view buffer{bufstore.get()}; +-#else +- winrt::Windows::Storage::ApplicationDataContainer localSettings = winrt::Windows::Storage::ApplicationData::Current().LocalSettings(); +- auto bufstore = Windows::Storage::ApplicationData::Current().RoamingFolder().Path(); +- std::wstring_view buffer{bufstore}; +- { +-#endif +- path = fs::path{buffer}; +- path /= L"alsoft.ini"; + +- TRACE("Loading config {}...", al::u8_as_char(path.u8string())); +- if(fs::ifstream f{path}; f.is_open()) +- LoadConfigFromFile(f); +- } +- } +-#endif + +- path = fs::u8path(GetProcBinary().path); +- if(!path.empty()) +- { +- path /= L"alsoft.ini"; +- TRACE("Loading config {}...", al::u8_as_char(path.u8string())); +- if(fs::ifstream f{path}; f.is_open()) +- LoadConfigFromFile(f); +- } + +- if(auto confpath = al::getenv(L"ALSOFT_CONF")) +- { +- path = *confpath; +- TRACE("Loading config {}...", al::u8_as_char(path.u8string())); +- if(fs::ifstream f{path}; f.is_open()) +- LoadConfigFromFile(f); +- } ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + } + + #else + + void ReadALConfig() + { +- fs::path path{"/etc/openal/alsoft.conf"}; +- +- TRACE("Loading config {}...", al::u8_as_char(path.u8string())); +- if(fs::ifstream f{path}; f.is_open()) +- LoadConfigFromFile(f); +- +- std::string confpaths{al::getenv("XDG_CONFIG_DIRS").value_or("/etc/xdg")}; +- /* Go through the list in reverse, since "the order of base directories +- * denotes their importance; the first directory listed is the most +- * important". Ergo, we need to load the settings from the later dirs +- * first so that the settings in the earlier dirs override them. +- */ +- while(!confpaths.empty()) +- { +- auto next = confpaths.rfind(':'); +- if(next < confpaths.length()) +- { +- path = fs::path{std::string_view{confpaths}.substr(next+1)}.lexically_normal(); +- confpaths.erase(next); +- } +- else +- { +- path = fs::path{confpaths}.lexically_normal(); +- confpaths.clear(); +- } + +- if(!path.is_absolute()) +- WARN("Ignoring XDG config dir: {}", al::u8_as_char(path.u8string())); +- else +- { +- path /= "alsoft.conf"; + +- TRACE("Loading config {}...", al::u8_as_char(path.u8string())); +- if(fs::ifstream f{path}; f.is_open()) +- LoadConfigFromFile(f); +- } +- } + +-#ifdef __APPLE__ +- CFBundleRef mainBundle = CFBundleGetMainBundle(); +- if(mainBundle) +- { +- CFURLRef configURL{CFBundleCopyResourceURL(mainBundle, CFSTR(".alsoftrc"), CFSTR(""), +- nullptr)}; + +- std::array fileName{}; +- if(configURL && CFURLGetFileSystemRepresentation(configURL, true, fileName.data(), fileName.size())) +- { +- if(std::ifstream f{reinterpret_cast(fileName.data())}; f.is_open()) +- LoadConfigFromFile(f); +- } +- } +-#endif + +- if(auto homedir = al::getenv("HOME")) +- { +- path = *homedir; +- path /= ".alsoftrc"; + +- TRACE("Loading config {}...", al::u8_as_char(path.u8string())); +- if(std::ifstream f{path}; f.is_open()) +- LoadConfigFromFile(f); +- } + +- if(auto configdir = al::getenv("XDG_CONFIG_HOME")) +- { +- path = *configdir; +- path /= "alsoft.conf"; +- } +- else +- { +- path.clear(); +- if(auto homedir = al::getenv("HOME")) +- { +- path = *homedir; +- path /= ".config/alsoft.conf"; +- } +- } +- if(!path.empty()) +- { +- TRACE("Loading config {}...", al::u8_as_char(path.u8string())); +- if(std::ifstream f{path}; f.is_open()) +- LoadConfigFromFile(f); +- } + +- path = GetProcBinary().path; +- if(!path.empty()) +- { +- path /= "alsoft.conf"; + +- TRACE("Loading config {}...", al::u8_as_char(path.u8string())); +- if(std::ifstream f{path}; f.is_open()) +- LoadConfigFromFile(f); +- } + +- if(auto confname = al::getenv("ALSOFT_CONF")) +- { +- TRACE("Loading config {}...", *confname); +- if(std::ifstream f{*confname}; f.is_open()) +- LoadConfigFromFile(f); +- } ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + } + #endif + +--- a/core/ambdec.cpp ++++ b/core/ambdec.cpp +@@ -15,7 +15,7 @@ + + #include "albit.h" + #include "alspan.h" +-#include "filesystem.h" ++ + #include "fmt/core.h" + + +@@ -60,231 +60,5 @@ AmbDecConf::~AmbDecConf() = default; + + std::optional AmbDecConf::load(const char *fname) noexcept + { +- fs::ifstream f{fs::u8path(fname)}; +- if(!f.is_open()) +- return std::string("Failed to open file \"")+fname+"\""; +- +- ReaderScope scope{ReaderScope::Global}; +- size_t speaker_pos{0}; +- size_t lfmatrix_pos{0}; +- size_t hfmatrix_pos{0}; +- size_t linenum{0}; +- +- std::string buffer; +- while(f.good() && std::getline(f, buffer)) +- { +- ++linenum; +- +- std::istringstream istr{buffer}; +- std::string command{read_word(istr)}; +- if(command.empty() || command[0] == '#') +- continue; +- +- if(command == "/}") +- { +- if(scope == ReaderScope::Global) +- return make_error(linenum, "Unexpected /}} in global scope"); +- scope = ReaderScope::Global; +- continue; +- } +- +- if(scope == ReaderScope::Speakers) +- { +- if(command == "add_spkr") +- { +- if(speaker_pos == Speakers.size()) +- return make_error(linenum, "Too many speakers specified"); +- +- AmbDecConf::SpeakerConf &spkr = Speakers[speaker_pos++]; +- istr >> spkr.Name; +- istr >> spkr.Distance; +- istr >> spkr.Azimuth; +- istr >> spkr.Elevation; +- istr >> spkr.Connection; +- } +- else +- return make_error(linenum, "Unexpected speakers command: {}", command); +- } +- else if(scope == ReaderScope::LFMatrix || scope == ReaderScope::HFMatrix) +- { +- auto &gains = (scope == ReaderScope::LFMatrix) ? LFOrderGain : HFOrderGain; +- auto matrix = (scope == ReaderScope::LFMatrix) ? LFMatrix : HFMatrix; +- auto &pos = (scope == ReaderScope::LFMatrix) ? lfmatrix_pos : hfmatrix_pos; +- +- if(command == "order_gain") +- { +- size_t toread{(ChanMask > Ambi3OrderMask) ? 5u : 4u}; +- std::size_t curgain{0u}; +- float value{}; +- while(toread) +- { +- --toread; +- istr >> value; +- if(curgain < std::size(gains)) +- gains[curgain++] = value; +- } +- } +- else if(command == "add_row") +- { +- if(pos == Speakers.size()) +- return make_error(linenum, "Too many matrix rows specified"); +- +- unsigned int mask{ChanMask}; +- +- AmbDecConf::CoeffArray &mtxrow = matrix[pos++]; +- mtxrow.fill(0.0f); +- +- float value{}; +- while(mask) +- { +- auto idx = static_cast(al::countr_zero(mask)); +- mask &= ~(1u << idx); +- +- istr >> value; +- if(idx < mtxrow.size()) +- mtxrow[idx] = value; +- } +- } +- else +- return make_error(linenum, "Unexpected matrix command: {}", command); +- } +- // Global scope commands +- else if(command == "/description") +- { +- while(istr.good() && std::isspace(istr.peek())) +- istr.ignore(); +- std::getline(istr, Description); +- while(!Description.empty() && std::isspace(Description.back())) +- Description.pop_back(); +- } +- else if(command == "/version") +- { +- if(Version) +- return make_error(linenum, "Duplicate version definition"); +- istr >> Version; +- if(Version != 3) +- return make_error(linenum, "Unsupported version: {}", Version); +- } +- else if(command == "/dec/chan_mask") +- { +- if(ChanMask) +- return make_error(linenum, "Duplicate chan_mask definition"); +- istr >> std::hex >> ChanMask >> std::dec; +- +- if(!ChanMask || ChanMask > Ambi4OrderMask) +- return make_error(linenum, "Invalid chan_mask: {:#x}", ChanMask); +- if(ChanMask > Ambi3OrderMask && CoeffScale == AmbDecScale::FuMa) +- return make_error(linenum, "FuMa not compatible with over third-order"); +- } +- else if(command == "/dec/freq_bands") +- { +- if(FreqBands) +- return make_error(linenum, "Duplicate freq_bands"); +- istr >> FreqBands; +- if(FreqBands != 1 && FreqBands != 2) +- return make_error(linenum, "Invalid freq_bands: {}", FreqBands); +- } +- else if(command == "/dec/speakers") +- { +- if(!Speakers.empty()) +- return make_error(linenum, "Duplicate speakers"); +- size_t numspeakers{}; +- istr >> numspeakers; +- if(!numspeakers) +- return make_error(linenum, "Invalid speakers: {}", numspeakers); +- Speakers.resize(numspeakers); +- } +- else if(command == "/dec/coeff_scale") +- { +- if(CoeffScale != AmbDecScale::Unset) +- return make_error(linenum, "Duplicate coeff_scale"); +- +- std::string scale{read_word(istr)}; +- if(scale == "n3d") CoeffScale = AmbDecScale::N3D; +- else if(scale == "sn3d") CoeffScale = AmbDecScale::SN3D; +- else if(scale == "fuma") CoeffScale = AmbDecScale::FuMa; +- else +- return make_error(linenum, "Unexpected coeff_scale: {}", scale); +- +- if(ChanMask > Ambi3OrderMask && CoeffScale == AmbDecScale::FuMa) +- return make_error(linenum, "FuMa not compatible with over third-order"); +- } +- else if(command == "/opt/xover_freq") +- { +- istr >> XOverFreq; +- } +- else if(command == "/opt/xover_ratio") +- { +- istr >> XOverRatio; +- } +- else if(command == "/opt/input_scale" || command == "/opt/nfeff_comp" +- || command == "/opt/delay_comp" || command == "/opt/level_comp") +- { +- /* Unused */ +- read_word(istr); +- } +- else if(command == "/speakers/{") +- { +- if(Speakers.empty()) +- return make_error(linenum, "Speakers defined without a count"); +- scope = ReaderScope::Speakers; +- } +- else if(command == "/lfmatrix/{" || command == "/hfmatrix/{" || command == "/matrix/{") +- { +- if(Speakers.empty()) +- return make_error(linenum, "Matrix defined without a speaker count"); +- if(!ChanMask) +- return make_error(linenum, "Matrix defined without a channel mask"); +- +- if(Matrix.empty()) +- { +- Matrix.resize(Speakers.size() * FreqBands); +- LFMatrix = al::span{Matrix}.first(Speakers.size()); +- HFMatrix = al::span{Matrix}.subspan(Speakers.size()*(FreqBands-1)); +- } +- +- if(FreqBands == 1) +- { +- if(command != "/matrix/{") +- return make_error(linenum, "Unexpected \"{}\" for a single-band decoder", +- command); +- scope = ReaderScope::HFMatrix; +- } +- else +- { +- if(command == "/lfmatrix/{") +- scope = ReaderScope::LFMatrix; +- else if(command == "/hfmatrix/{") +- scope = ReaderScope::HFMatrix; +- else +- return make_error(linenum, "Unexpected \"{}\" for a dual-band decoder", +- command); +- } +- } +- else if(command == "/end") +- { +- const auto endpos = static_cast(istr.tellg()); +- if(!is_at_end(buffer, endpos)) +- return make_error(linenum, "Extra junk on end: {}", +- std::string_view{buffer}.substr(endpos)); +- +- if(speaker_pos < Speakers.size() || hfmatrix_pos < Speakers.size() +- || (FreqBands == 2 && lfmatrix_pos < Speakers.size())) +- return make_error(linenum, "Incomplete decoder definition"); +- if(CoeffScale == AmbDecScale::Unset) +- return make_error(linenum, "No coefficient scaling defined"); +- +- return std::nullopt; +- } +- else +- return make_error(linenum, "Unexpected command: {}", command); +- +- istr.clear(); +- const auto endpos = static_cast(istr.tellg()); +- if(!is_at_end(buffer, endpos)) +- return make_error(linenum, "Extra junk on line: {}", +- std::string_view{buffer}.substr(endpos)); +- buffer.clear(); +- } +- return make_error(linenum, "Unexpected end of file"); ++ return std::string("OpenAL Soft's Ambisonics config loader is disabled by mkxp-z"); + } +--- a/core/hrtf.cpp ++++ b/core/hrtf.cpp +@@ -30,7 +30,7 @@ + #include "alspan.h" + #include "alstring.h" + #include "ambidefs.h" +-#include "filesystem.h" ++ + #include "filters/splitter.h" + #include "fmt/core.h" + #include "helpers.h" +@@ -1202,8 +1202,8 @@ std::vector EnumerateHrtf(std::optional pathopt) + std::lock_guard enumlock{EnumeratedHrtfLock}; + EnumeratedHrtfs.clear(); + +- for(const auto &fname : SearchDataFiles(".mhr"sv)) +- AddFileEntry(fname); ++ ++ + + bool usedefaults{true}; + if(pathopt) +@@ -1230,16 +1230,16 @@ std::vector EnumerateHrtf(std::optional pathopt) + entry.remove_suffix(1); + if(!entry.empty()) + { +- for(const auto &fname : SearchDataFiles(".mhr"sv, entry)) +- AddFileEntry(fname); ++ ++ + } + } + } + + if(usedefaults) + { +- for(const auto &fname : SearchDataFiles(".mhr"sv, "openal/hrtf"sv)) +- AddFileEntry(fname); ++ ++ + + if(!GetResource(IDR_DEFAULT_HRTF_MHR).empty()) + AddBuiltInEntry("Built-In HRTF", IDR_DEFAULT_HRTF_MHR); +@@ -1303,14 +1303,14 @@ try { + else + { + TRACE("Loading {}...", fname); +- auto fstr = std::make_unique(fs::u8path(fname), +- std::ios::binary); +- if(!fstr->is_open()) ++ ++ ERR("OpenAL Soft's HRTF loader is disabled by mkxp-z"); ++ if(true) + { + ERR("Could not open {}", fname); + return nullptr; + } +- stream = std::move(fstr); ++ + } + + auto hrtf = std::unique_ptr{}; diff --git a/subprojects/packagefiles/openal-soft-mkxp-threads.patch b/subprojects/packagefiles/openal-soft-mkxp-threads.patch new file mode 100644 index 00000000..6b5e62c8 --- /dev/null +++ b/subprojects/packagefiles/openal-soft-mkxp-threads.patch @@ -0,0 +1,547 @@ +# This patch makes OpenAL Soft use mkxp-threads.cpp instead of POSIX threads and `std::mutex` for portability reasons. + +--- a/al/auxeffectslot.cpp ++++ b/al/auxeffectslot.cpp +@@ -28,7 +28,7 @@ + #include + #include + #include +-#include ++#include "../../src/mkxp-threads.h" + #include + #include + #include +--- a/al/buffer.cpp ++++ b/al/buffer.cpp +@@ -32,7 +32,7 @@ + #include + #include + #include +-#include ++#include "../../src/mkxp-threads.h" + #include + #include + #include +--- a/al/debug.cpp ++++ b/al/debug.cpp +@@ -7,7 +7,7 @@ + #include + #include + #include +-#include ++#include "../../src/mkxp-threads.h" + #include + #include + #include +--- a/al/effect.cpp ++++ b/al/effect.cpp +@@ -27,7 +27,7 @@ + #include + #include + #include +-#include ++#include "../../src/mkxp-threads.h" + #include + #include + #include +--- a/al/event.cpp ++++ b/al/event.cpp +@@ -7,7 +7,7 @@ + #include + #include + #include +-#include ++#include "../../src/mkxp-threads.h" + #include + #include + #include +--- a/al/filter.cpp ++++ b/al/filter.cpp +@@ -28,7 +28,7 @@ + #include + #include + #include +-#include ++#include "../../src/mkxp-threads.h" + #include + #include + #include +--- a/al/listener.cpp ++++ b/al/listener.cpp +@@ -24,7 +24,7 @@ + + #include + #include +-#include ++#include "../../src/mkxp-threads.h" + + #include "AL/al.h" + #include "AL/alc.h" +--- a/al/source.cpp ++++ b/al/source.cpp +@@ -34,7 +34,7 @@ + #include + #include + #include +-#include ++#include "../../src/mkxp-threads.h" + #include + #include + #include +--- a/al/state.cpp ++++ b/al/state.cpp +@@ -26,7 +26,7 @@ + #include + #include + #include +-#include ++#include "../../src/mkxp-threads.h" + #include + #include + #include +--- a/alc/alc.cpp ++++ b/alc/alc.cpp +@@ -48,7 +48,7 @@ + #include + #include + #include +-#include ++#include "../../src/mkxp-threads.h" + #include + #include + #include +@@ -314,7 +314,7 @@ std::atomic LastNullDeviceError{ALC_NO_ERROR}; + bool TrapALCError{false}; + + /* One-time configuration init control */ +-std::once_flag alc_config_once{}; ++ + + /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process + * updates. +@@ -743,7 +743,7 @@ void alc_initconfig() + #endif // ALSOFT_EAX + } + inline void InitConfig() +-{ std::call_once(alc_config_once, [](){alc_initconfig();}); } ++{ alc_initconfig(); } + + + /************************************************ +--- a/alc/backends/alsa.cpp ++++ b/alc/backends/alsa.cpp +@@ -30,7 +30,7 @@ + #include + #include + #include +-#include ++#include "../../src/mkxp-threads.h" + #include + #include + #include +--- a/alc/backends/jack.cpp ++++ b/alc/backends/jack.cpp +@@ -27,7 +27,7 @@ + #include + #include + #include +-#include ++#include "../../src/mkxp-threads.h" + #include + #include + +--- a/alc/backends/opensl.cpp ++++ b/alc/backends/opensl.cpp +@@ -28,7 +28,7 @@ + #include + #include + #include +-#include ++#include "../../src/mkxp-threads.h" + #include + #include + #include +--- a/alc/backends/otherio.cpp ++++ b/alc/backends/otherio.cpp +@@ -49,7 +49,7 @@ + #include + #include + #include +-#include ++#include "../../src/mkxp-threads.h" + #include + #include + #include +--- a/alc/backends/pipewire.cpp ++++ b/alc/backends/pipewire.cpp +@@ -37,7 +37,7 @@ + #include + #include + #include +-#include ++#include "../../src/mkxp-threads.h" + #include + #include + #include +--- a/alc/backends/pulseaudio.cpp ++++ b/alc/backends/pulseaudio.cpp +@@ -33,7 +33,7 @@ + #include + #include + #include +-#include ++#include "../../src/mkxp-threads.h" + #include + #include + #include +--- a/alc/backends/wasapi.cpp ++++ b/alc/backends/wasapi.cpp +@@ -52,7 +52,7 @@ + #include + #include + #include +-#include ++#include "../../src/mkxp-threads.h" + #include + #include + #include +--- a/alc/context.h ++++ b/alc/context.h +@@ -8,7 +8,7 @@ + #include + #include + #include +-#include ++#include "../../src/mkxp-threads.h" + #include + #include + #include +--- a/alc/device.h ++++ b/alc/device.h +@@ -5,7 +5,7 @@ + + #include + #include +-#include ++#include "../../src/mkxp-threads.h" + #include + #include + #include +--- a/alc/events.h ++++ b/alc/events.h +@@ -5,7 +5,7 @@ + #include "opthelpers.h" + + #include +-#include ++#include "../../src/mkxp-threads.h" + #include + #include + +--- a/common/alsem.cpp ++++ b/common/alsem.cpp +@@ -55,8 +55,6 @@ void semaphore::post() + void semaphore::wait() noexcept + { WaitForSingleObject(static_cast(mSem), INFINITE); } + +-bool semaphore::try_wait() noexcept +-{ return WaitForSingleObject(static_cast(mSem), 0) == WAIT_OBJECT_0; } + + } // namespace al + +@@ -83,8 +81,6 @@ void semaphore::post() + void semaphore::wait() noexcept + { dispatch_semaphore_wait(mSem, DISPATCH_TIME_FOREVER); } + +-bool semaphore::try_wait() noexcept +-{ return dispatch_semaphore_wait(mSem, DISPATCH_TIME_NOW) == 0; } + + } // namespace al + +@@ -96,27 +92,25 @@ namespace al { + + semaphore::semaphore(unsigned int initial) + { +- if(sem_init(&mSem, 0, initial) != 0) +- throw std::system_error(std::make_error_code(std::errc::resource_unavailable_try_again)); ++ if(mkxp_sem_init(&mSem, initial) != 0) ++ abort(); + } + + semaphore::~semaphore() +-{ sem_destroy(&mSem); } ++{ mkxp_sem_destroy(&mSem); } + + void semaphore::post() + { +- if(sem_post(&mSem) != 0) +- throw std::system_error(std::make_error_code(std::errc::value_too_large)); ++ if(mkxp_sem_post(&mSem) != 0) ++ abort(); + } + + void semaphore::wait() noexcept + { +- while(sem_wait(&mSem) == -1 && errno == EINTR) { ++ while(mkxp_sem_wait(&mSem) == -1 && errno == EINTR) { + } + } + +-bool semaphore::try_wait() noexcept +-{ return sem_trywait(&mSem) == 0; } + + } // namespace al + +--- a/common/alsem.h ++++ b/common/alsem.h +@@ -11,7 +11,7 @@ + #include /* Fallback option for Apple without a working libdispatch */ + #endif + #elif !defined(_WIN32) +-#include ++#include "../../src/mkxp-threads.h" + #endif + + namespace al { +@@ -22,7 +22,7 @@ class semaphore { + #elif defined(AL_APPLE_HAVE_DISPATCH) + using native_type = dispatch_semaphore_t; + #else +- using native_type = sem_t; ++ using native_type = mkxp_sem_t; + #endif + native_type mSem{}; + +@@ -35,7 +35,6 @@ public: + + void post(); + void wait() noexcept; +- bool try_wait() noexcept; + }; + + } // namespace al +--- a/common/althrd_setname.cpp ++++ b/common/althrd_setname.cpp +@@ -39,39 +39,39 @@ void althrd_setname(const char *name [[maybe_unused]]) + + #else + +-#include +-#ifdef HAVE_PTHREAD_NP_H +-#include +-#endif ++#include "../../src/mkxp-threads.h" ++ ++ ++ ++ + + namespace { + + using setname_t1 = int(*)(const char*); +-using setname_t2 = int(*)(pthread_t, const char*); +-using setname_t3 = void(*)(pthread_t, const char*); +-using setname_t4 = int(*)(pthread_t, const char*, void*); ++using setname_t2 = int(*)(mkxp_thread_t, const char*); ++using setname_t3 = void(*)(mkxp_thread_t, const char*); ++using setname_t4 = int(*)(mkxp_thread_t, const char*, void*); + + [[maybe_unused]] void setname_caller(setname_t1 func, const char *name) + { func(name); } + + [[maybe_unused]] void setname_caller(setname_t2 func, const char *name) +-{ func(pthread_self(), name); } ++{ func(mkxp_thread_self(), name); } + + [[maybe_unused]] void setname_caller(setname_t3 func, const char *name) +-{ func(pthread_self(), name); } ++{ func(mkxp_thread_self(), name); } + + [[maybe_unused]] void setname_caller(setname_t4 func, const char *name) +-{ func(pthread_self(), "%s", const_cast(name)); /* NOLINT(*-const-cast) */ } ++{ func(mkxp_thread_self(), "%s", const_cast(name)); /* NOLINT(*-const-cast) */ } + + } // namespace + + void althrd_setname(const char *name [[maybe_unused]]) + { +-#if defined(HAVE_PTHREAD_SET_NAME_NP) +- setname_caller(pthread_set_name_np, name); +-#elif defined(HAVE_PTHREAD_SETNAME_NP) +- setname_caller(pthread_setname_np, name); +-#endif +-} + ++ ++ ++ ++ ++} + #endif +--- a/common/althreads.h ++++ b/common/althreads.h +@@ -5,7 +5,7 @@ + #include + #include + +-#ifdef _WIN32 ++#if false + #define WIN32_LEAN_AND_MEAN + #include + +@@ -13,7 +13,7 @@ + + #include + +-#else ++#elif false + + #include + #endif +@@ -54,7 +54,7 @@ class tss { + return static_cast(al::bit_cast(ptr)); + } + +-#ifdef _WIN32 ++#if false + DWORD mTss{TLS_OUT_OF_INDEXES}; + + public: +@@ -107,29 +107,30 @@ public: + + #else + +- tss_t mTss{}; ++ void **mTss; + + public: + tss() + { +- if(int res{tss_create(&mTss, nullptr)}; res != thrd_success) ++ if ((mTss = (void **)std::malloc(sizeof *mTss)) == NULL) + throw std::runtime_error{"al::tss::tss()"}; ++ *mTss = nullptr; + } + explicit tss(const T &init) : tss{} + { +- if(int res{tss_set(mTss, to_ptr(init))}; res != thrd_success) +- throw std::runtime_error{"al::tss::tss(T)"}; ++ if ((mTss = (void **)std::malloc(sizeof *mTss)) == NULL) ++ throw std::runtime_error{"al::tss::tss()"}; ++ *mTss = to_ptr(init); + } +- ~tss() { tss_delete(mTss); } ++ ~tss() { std::free(mTss); } + + void set(const T &value) const + { +- if(int res{tss_set(mTss, to_ptr(value))}; res != thrd_success) +- throw std::runtime_error{"al::tss::set(T)"}; ++ *mTss = to_ptr(value); + } + + [[nodiscard]] +- auto get() const noexcept -> T { return from_ptr(tss_get(mTss)); } ++ auto get() const noexcept -> T { return from_ptr(*mTss); } + #endif /* _WIN32 */ + + tss(const tss&) = delete; +--- a/core/context.h ++++ b/core/context.h +@@ -140,7 +140,7 @@ struct ContextBase { + */ + al::atomic_unique_ptr mActiveAuxSlots; + +- std::thread mEventThread; ++ + al::semaphore mEventSem; + std::unique_ptr mAsyncEvents; + using AsyncEventBitset = std::bitset; +--- a/core/dbus_wrap.cpp ++++ b/core/dbus_wrap.cpp +@@ -5,7 +5,7 @@ + + #if HAVE_DYNLOAD + +-#include ++#include "../../src/mkxp-threads.h" + #include + + #include "logging.h" +--- a/core/dbus_wrap.h ++++ b/core/dbus_wrap.h +@@ -9,7 +9,7 @@ + + #if HAVE_DYNLOAD + +-#include ++#include "../../src/mkxp-threads.h" + + #define DBUS_FUNCTIONS(MAGIC) \ + MAGIC(dbus_error_init) \ +--- a/core/helpers.cpp ++++ b/core/helpers.cpp +@@ -12,7 +12,7 @@ + #include + #include + #include +-#include ++#include "../../src/mkxp-threads.h" + #include + #include + #include +--- a/core/hrtf.cpp ++++ b/core/hrtf.cpp +@@ -15,7 +15,7 @@ + #include + #include + #include +-#include ++#include "../../src/mkxp-threads.h" + #include + #include + #include +--- a/core/logging.cpp ++++ b/core/logging.cpp +@@ -7,7 +7,7 @@ + #include + #include + #include +-#include ++#include "../../src/mkxp-threads.h" + #include + #include + #include +--- a/examples/alffplay.cpp ++++ b/examples/alffplay.cpp +@@ -20,7 +20,7 @@ + #include + #include + #include +-#include ++#include "../../src/mkxp-threads.h" + #include + #include + #include +--- a/router/alc.cpp ++++ b/router/alc.cpp +@@ -7,7 +7,7 @@ + #include + #include + #include +-#include ++#include "../../src/mkxp-threads.h" + #include + #include + #include +--- a/router/router.h ++++ b/router/router.h +@@ -8,7 +8,7 @@ + #include + #include + #include +-#include ++#include "../../src/mkxp-threads.h" + #include + #include + #include diff --git a/subprojects/packagefiles/openal-soft-null.patch b/subprojects/packagefiles/openal-soft-null.patch new file mode 100644 index 00000000..95ae96ac --- /dev/null +++ b/subprojects/packagefiles/openal-soft-null.patch @@ -0,0 +1,33 @@ +# Disables OpenAL Soft's null backend since it fails to compile for PlayStation 3. Don't worry, we don't need the null backend. + +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -897,7 +897,7 @@ set(ALC_OBJS ${ALC_OBJS} + # Default backends, always available + alc/backends/loopback.cpp + alc/backends/loopback.h +- alc/backends/null.cpp ++ + alc/backends/null.h + ) + +--- a/alc/alc.cpp ++++ b/alc/alc.cpp +@@ -216,7 +216,7 @@ struct BackendInfo { + BackendFactory& (*getFactory)(); + }; + +-std::array BackendList{ ++std::array BackendList{ + #if HAVE_PIPEWIRE + BackendInfo{"pipewire", PipeWireBackendFactory::getFactory}, + #endif +@@ -269,7 +269,7 @@ std::array BackendList{ + BackendInfo{"otherio", OtherIOBackendFactory::getFactory}, + #endif + +- BackendInfo{"null", NullBackendFactory::getFactory}, ++ + #if HAVE_WAVE + BackendInfo{"wave", WaveBackendFactory::getFactory}, + #endif diff --git a/subprojects/packagefiles/openal-soft-pic.patch b/subprojects/packagefiles/openal-soft-pic.patch new file mode 100644 index 00000000..abd4b2c3 --- /dev/null +++ b/subprojects/packagefiles/openal-soft-pic.patch @@ -0,0 +1,24 @@ +# Prevents OpenAL Soft's build system from forcibly enabling position-independent code. + +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -1377,7 +1377,7 @@ target_compile_definitions(alsoft.common PRIVATE ${CPP_DEFS}) + target_compile_options(alsoft.common PRIVATE ${C_FLAGS}) + target_link_libraries(alsoft.common PRIVATE alsoft::fmt) + set_target_properties(alsoft.common PROPERTIES ${ALSOFT_STD_VERSION_PROPS} +- POSITION_INDEPENDENT_CODE TRUE) ++ ) + + + unset(HAS_ROUTER) +--- a/fmt-11.1.1/CMakeLists.txt ++++ b/fmt-11.1.1/CMakeLists.txt +@@ -73,7 +73,7 @@ target_include_directories(alsoft.fmt PUBLIC + set_target_properties(alsoft.fmt PROPERTIES ${ALSOFT_STD_VERSION_PROPS} + VERSION ${FMT_VERSION} SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR} + DEBUG_POSTFIX "${ALSOFT_FMT_DEBUG_POSTFIX}" +- POSITION_INDEPENDENT_CODE TRUE ++ + C_VISIBILITY_PRESET hidden + CXX_VISIBILITY_PRESET hidden + EXCLUDE_FROM_ALL TRUE) diff --git a/subprojects/packagefiles/openal-soft-ps3.patch b/subprojects/packagefiles/openal-soft-ps3.patch new file mode 100644 index 00000000..cb97303c --- /dev/null +++ b/subprojects/packagefiles/openal-soft-ps3.patch @@ -0,0 +1,24 @@ +# The PlayStation 3 toolchain appears to be missing some functions from the C++ standard library. This replaces the missing functions with other ones that are available. + +--- a/alc/alu.cpp ++++ b/alc/alu.cpp +@@ -2155,7 +2155,7 @@ void Write(const al::span InBuffer, void *OutBuffer, cons + out[c] = SampleConv(s); + out += ptrdiff_t(FrameStep); + }; +- std::for_each_n(inbuf.cbegin(), SamplesToDo, conv_sample); ++ std::for_each(inbuf.cbegin(), inbuf.cbegin() + SamplesToDo, conv_sample); + ++c; + } + if(const size_t extra{FrameStep - c}) +--- a/alc/effects/reverb.cpp ++++ b/alc/effects/reverb.cpp +@@ -931,7 +931,7 @@ void EarlyReflections::updateLines(const float density_mult, const float diffusi + /* Calculate the gain (coefficient) for the secondary reflections based on + * the average delay and decay time. + */ +- const auto length = std::reduce(EARLY_LINE_LENGTHS.begin(), EARLY_LINE_LENGTHS.end(), 0.0f) ++ const auto length = std::accumulate(EARLY_LINE_LENGTHS.begin(), EARLY_LINE_LENGTHS.end(), 0.0f) + / float{EARLY_LINE_LENGTHS.size()} * density_mult; + Coeff = CalcDecayCoeff(length, decayTime); + diff --git a/subprojects/packagefiles/physfs-devkitppc.patch b/subprojects/packagefiles/physfs-devkitppc.patch deleted file mode 100644 index 32745ec2..00000000 --- a/subprojects/packagefiles/physfs-devkitppc.patch +++ /dev/null @@ -1,143 +0,0 @@ -# devkitPPC does not provide POSIX semaphores, which OpenAL Soft needs. -# However, devkitPPC provides an alternative semaphore implementation in an external library, libogc. -# This patch makes PhysFS use libogc semaphores if POSIX semaphores is not found. - ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -172,11 +172,20 @@ if(PHYSFS_BUILD_STATIC) - set_target_properties(physfs-static PROPERTIES VS_WINRT_COMPONENT True) - set_target_properties(physfs-static PROPERTIES STATIC_LIBRARY_FLAGS "/ignore:4264") - endif() -+ set(CPP_DEFS) -+ set(INC_PATHS) -+ include(CheckSymbolExists) -+ check_symbol_exists(__DEVKITPPC__ "sys/config.h" DEVKITPPC) -+ if(DEVKITPPC) -+ set(CPP_DEFS ${CPP_DEFS} MKXPZ_DEVKITPPC) -+ set(INC_PATHS ${INC_PATHS} "$ENV{DEVKITPRO}/libogc/include") -+ endif() - if(WIN32 OR WINRT OR OS2) - # no dll exports from the static library -- target_compile_definitions(physfs-static PRIVATE "PHYSFS_STATIC") -+ set(CPP_DEFS ${CPP_DEFS} "PHYSFS_STATIC") - endif() -- target_include_directories(physfs-static PUBLIC "$") -+ target_compile_definitions(physfs-static PRIVATE ${CPP_DEFS}) -+ target_include_directories(physfs-static PUBLIC "$" ${INC_PATHS}) - target_link_libraries(physfs-static PRIVATE ${OPTIONAL_LIBRARY_LIBS} ${OTHER_LDFLAGS}) - set(PHYSFS_LIB_TARGET physfs-static) - list(APPEND PHYSFS_INSTALL_TARGETS "physfs-static") ---- a/src/physfs_platform_posix.c -+++ b/src/physfs_platform_posix.c -@@ -19,7 +19,11 @@ - #include - #include - #include --#include -+#ifdef MKXPZ_DEVKITPPC -+# include -+#else -+# include -+#endif - - #include "physfs_internal.h" - -@@ -369,15 +373,23 @@ int __PHYSFS_platformStat(const char *fname, PHYSFS_Stat *st, const int follow) - - typedef struct - { -+#ifdef MKXPZ_DEVKITPPC -+ mutex_t mutex; -+#else - pthread_mutex_t mutex; - pthread_t owner; -+#endif - PHYSFS_uint32 count; - } PthreadMutex; - - - void *__PHYSFS_platformGetThreadID(void) - { -+#ifdef MKXPZ_DEVKITPPC -+ return (void *)42; -+#else - return ( (void *) ((size_t) pthread_self()) ); -+#endif - } /* __PHYSFS_platformGetThreadID */ - - -@@ -386,7 +398,11 @@ void *__PHYSFS_platformCreateMutex(void) - int rc; - PthreadMutex *m = (PthreadMutex *) allocator.Malloc(sizeof (PthreadMutex)); - BAIL_IF(!m, PHYSFS_ERR_OUT_OF_MEMORY, NULL); -+#ifdef MKXPZ_DEVKITPPC -+ rc = LWP_MutexInit(&m->mutex, false); -+#else - rc = pthread_mutex_init(&m->mutex, NULL); -+#endif - if (rc != 0) - { - allocator.Free(m); -@@ -394,7 +410,9 @@ void *__PHYSFS_platformCreateMutex(void) - } /* if */ - - m->count = 0; -+#ifndef MKXPZ_DEVKITPPC - m->owner = (pthread_t) 0xDEADBEEF; -+#endif - return ((void *) m); - } /* __PHYSFS_platformCreateMutex */ - -@@ -403,11 +421,15 @@ void __PHYSFS_platformDestroyMutex(void *mutex) - { - PthreadMutex *m = (PthreadMutex *) mutex; - -+#ifdef MKXPZ_DEVKITPPC -+ LWP_MutexDestroy(m->mutex); -+#else - /* Destroying a locked mutex is a bug, but we'll try to be helpful. */ - if ((m->owner == pthread_self()) && (m->count > 0)) - pthread_mutex_unlock(&m->mutex); - - pthread_mutex_destroy(&m->mutex); -+#endif - allocator.Free(m); - } /* __PHYSFS_platformDestroyMutex */ - -@@ -415,6 +437,10 @@ void __PHYSFS_platformDestroyMutex(void *mutex) - int __PHYSFS_platformGrabMutex(void *mutex) - { - PthreadMutex *m = (PthreadMutex *) mutex; -+#ifdef MKXPZ_DEVKITPPC -+ if (LWP_MutexLock(m->mutex) != 0) -+ return 0; -+#else - pthread_t tid = pthread_self(); - if (m->owner != tid) - { -@@ -422,6 +448,7 @@ int __PHYSFS_platformGrabMutex(void *mutex) - return 0; - m->owner = tid; - } /* if */ -+#endif - - m->count++; - return 1; -@@ -431,6 +458,9 @@ int __PHYSFS_platformGrabMutex(void *mutex) - void __PHYSFS_platformReleaseMutex(void *mutex) - { - PthreadMutex *m = (PthreadMutex *) mutex; -+#ifdef MKXPZ_DEVKITPPC -+ LWP_MutexUnlock(m->mutex); -+#else - assert(m->owner == pthread_self()); /* catch programming errors. */ - assert(m->count > 0); /* catch programming errors. */ - if (m->owner == pthread_self()) -@@ -441,6 +471,7 @@ void __PHYSFS_platformReleaseMutex(void *mutex) - pthread_mutex_unlock(&m->mutex); - } /* if */ - } /* if */ -+#endif - } /* __PHYSFS_platformReleaseMutex */ - - #endif /* PHYSFS_PLATFORM_POSIX */ diff --git a/subprojects/packagefiles/physfs-mkxp-threads.patch b/subprojects/packagefiles/physfs-mkxp-threads.patch new file mode 100644 index 00000000..29f9f229 --- /dev/null +++ b/subprojects/packagefiles/physfs-mkxp-threads.patch @@ -0,0 +1,96 @@ +# This patch makes PhysFS use mkxp-threads.cpp instead of POSIX threads for portability reasons. + +--- a/src/physfs_platform_posix.c ++++ b/src/physfs_platform_posix.c +@@ -19,7 +19,7 @@ + #include + #include + #include +-#include ++#include "../../src/mkxp-threads.h" + + #include "physfs_internal.h" + +@@ -369,15 +369,15 @@ int __PHYSFS_platformStat(const char *fname, PHYSFS_Stat *st, const int follow) + + typedef struct + { +- pthread_mutex_t mutex; +- pthread_t owner; ++ mkxp_mutex_t mutex; ++ mkxp_thread_t owner; + PHYSFS_uint32 count; + } PthreadMutex; + + + void *__PHYSFS_platformGetThreadID(void) + { +- return ( (void *) ((size_t) pthread_self()) ); ++ return ( (void *) ((size_t) mkxp_thread_self()) ); + } /* __PHYSFS_platformGetThreadID */ + + +@@ -386,7 +386,7 @@ void *__PHYSFS_platformCreateMutex(void) + int rc; + PthreadMutex *m = (PthreadMutex *) allocator.Malloc(sizeof (PthreadMutex)); + BAIL_IF(!m, PHYSFS_ERR_OUT_OF_MEMORY, NULL); +- rc = pthread_mutex_init(&m->mutex, NULL); ++ rc = mkxp_mutex_init(&m->mutex, false); + if (rc != 0) + { + allocator.Free(m); +@@ -394,7 +394,7 @@ void *__PHYSFS_platformCreateMutex(void) + } /* if */ + + m->count = 0; +- m->owner = (pthread_t) 0xDEADBEEF; ++ m->owner = (mkxp_thread_t) 0xDEADBEEF; + return ((void *) m); + } /* __PHYSFS_platformCreateMutex */ + +@@ -404,10 +404,10 @@ void __PHYSFS_platformDestroyMutex(void *mutex) + PthreadMutex *m = (PthreadMutex *) mutex; + + /* Destroying a locked mutex is a bug, but we'll try to be helpful. */ +- if ((m->owner == pthread_self()) && (m->count > 0)) +- pthread_mutex_unlock(&m->mutex); ++ if ((m->owner == mkxp_thread_self()) && (m->count > 0)) ++ mkxp_mutex_unlock(&m->mutex); + +- pthread_mutex_destroy(&m->mutex); ++ mkxp_mutex_destroy(&m->mutex); + allocator.Free(m); + } /* __PHYSFS_platformDestroyMutex */ + +@@ -415,10 +415,10 @@ void __PHYSFS_platformDestroyMutex(void *mutex) + int __PHYSFS_platformGrabMutex(void *mutex) + { + PthreadMutex *m = (PthreadMutex *) mutex; +- pthread_t tid = pthread_self(); ++ mkxp_thread_t tid = mkxp_thread_self(); + if (m->owner != tid) + { +- if (pthread_mutex_lock(&m->mutex) != 0) ++ if (mkxp_mutex_lock(&m->mutex) != 0) + return 0; + m->owner = tid; + } /* if */ +@@ -431,14 +431,14 @@ int __PHYSFS_platformGrabMutex(void *mutex) + void __PHYSFS_platformReleaseMutex(void *mutex) + { + PthreadMutex *m = (PthreadMutex *) mutex; +- assert(m->owner == pthread_self()); /* catch programming errors. */ ++ assert(m->owner == mkxp_thread_self()); /* catch programming errors. */ + assert(m->count > 0); /* catch programming errors. */ +- if (m->owner == pthread_self()) ++ if (m->owner == mkxp_thread_self()) + { + if (--m->count == 0) + { +- m->owner = (pthread_t) 0xDEADBEEF; +- pthread_mutex_unlock(&m->mutex); ++ m->owner = (mkxp_thread_t) 0xDEADBEEF; ++ mkxp_mutex_unlock(&m->mutex); + } /* if */ + } /* if */ + } /* __PHYSFS_platformReleaseMutex */ diff --git a/subprojects/physfs.wrap b/subprojects/physfs.wrap index 8925f50e..ff3d2b70 100644 --- a/subprojects/physfs.wrap +++ b/subprojects/physfs.wrap @@ -2,4 +2,4 @@ url = https://github.com/icculus/physfs revision = release-3.2.0 depth = 1 -diff_files = physfs-darwin.patch, physfs-devkitppc.patch, physfs-dir.patch, physfs-unknown-platform.patch +diff_files = physfs-darwin.patch, physfs-dir.patch, physfs-mkxp-threads.patch, physfs-unknown-platform.patch