From b279ef1884961ed226ad28b8f8c6f2ab3b241764 Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Thu, 27 Jun 2024 18:36:16 -0400 Subject: [PATCH] misc: ios simulator builds, case-insensitive files, TMPDIR env var --- .github/workflows/libserum.yml | 12 ++++--- CMakeLists.txt | 13 +++++-- README.md | 6 ++++ src/serum-decode.cpp | 65 +++++++++++++++++++++++++++------- 4 files changed, 76 insertions(+), 20 deletions(-) diff --git a/.github/workflows/libserum.yml b/.github/workflows/libserum.yml index bfc9875..9c030ae 100644 --- a/.github/workflows/libserum.yml +++ b/.github/workflows/libserum.yml @@ -58,6 +58,9 @@ jobs: - os: macos-latest platform: ios arch: arm64 + - os: macos-latest + platform: ios-simulator + arch: arm64 - os: macos-latest platform: tvos arch: arm64 @@ -125,7 +128,7 @@ jobs: cp build/libserum.so.* tmp cp build/serum_test_s tmp cp build/serum_test tmp - elif [[ "${{ matrix.platform }}" == "ios" || "${{ matrix.platform }}" == "tvos" ]]; then + elif [[ "${{ matrix.platform }}" == "ios" || "${{ matrix.platform }}" == "ios-simulator" || "${{ matrix.platform }}" == "tvos" ]]; then cp build/libserum.a tmp cp build/libserum.*.dylib tmp elif [[ "${{ matrix.platform }}" == "android" ]]; then @@ -137,7 +140,7 @@ jobs: fi echo "artifact_path=${ARTIFACT_PATH}" >> $GITHUB_OUTPUT - name: Upload artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: libserum-${{ needs.version.outputs.tag }}-${{ matrix.platform }}-${{ matrix.arch }} path: ${{ steps.artifacts.outputs.artifact_path }} @@ -147,7 +150,7 @@ jobs: needs: [ version, build ] name: Build libserum-macos steps: - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 - name: Unpack artifacts run: | cd libserum-${{ needs.version.outputs.tag }}-macos-x64 @@ -172,7 +175,7 @@ jobs: cd tmp tar -czvf ../libserum-${{ needs.version.outputs.tag }}-macos.tar.gz * - name: Upload artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: libserum-${{ needs.version.outputs.tag }}-macos path: libserum-${{ needs.version.outputs.tag }}-macos.tar.gz @@ -195,5 +198,6 @@ jobs: libserum-${{ needs.version.outputs.tag }}-linux-x64/libserum-${{ needs.version.outputs.tag }}-linux-x64.tar.gz libserum-${{ needs.version.outputs.tag }}-linux-aarch64/libserum-${{ needs.version.outputs.tag }}-linux-aarch64.tar.gz libserum-${{ needs.version.outputs.tag }}-ios-arm64/libserum-${{ needs.version.outputs.tag }}-ios-arm64.tar.gz + libserum-${{ needs.version.outputs.tag }}-ios-simulator-arm64/libserum-${{ needs.version.outputs.tag }}-ios-simulator-arm64.tar.gz libserum-${{ needs.version.outputs.tag }}-tvos-arm64/libserum-${{ needs.version.outputs.tag }}-tvos-arm64.tar.gz libserum-${{ needs.version.outputs.tag }}-android-arm64-v8a/libserum-${{ needs.version.outputs.tag }}-android-arm64-v8a.tar.gz \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index b55be73..be0d82f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,16 +12,24 @@ message(STATUS "ARCH: ${ARCH}") message(STATUS "BUILD_SHARED: ${BUILD_SHARED}") message(STATUS "BUILD_STATIC: ${BUILD_STATIC}") -if(PLATFORM STREQUAL "ios") +if(PLATFORM STREQUAL "macos") + set(CMAKE_OSX_DEPLOYMENT_TARGET 14.0) +elseif(PLATFORM STREQUAL "ios" OR PLATFORM STREQUAL "ios-simulator") set(CMAKE_SYSTEM_NAME iOS) + if (PLATFORM STREQUAL "ios-simulator") + set(CMAKE_OSX_SYSROOT iphonesimulator) + endif() + set(CMAKE_OSX_DEPLOYMENT_TARGET 17.0) elseif(PLATFORM STREQUAL "tvos") set(CMAKE_SYSTEM_NAME tvOS) + set(CMAKE_OSX_DEPLOYMENT_TARGET 17.0) elseif(PLATFORM STREQUAL "android") set(CMAKE_SYSTEM_NAME Android) set(CMAKE_SYSTEM_VERSION 30) set(CMAKE_ANDROID_ARCH_ABI arm64-v8a) endif() + file(READ src/serum-version.h version) string(REGEX MATCH "SERUM_VERSION_MAJOR[ ]+([0-9]+)" _tmp ${version}) set(VERSION_MAJOR "${CMAKE_MATCH_1}") @@ -38,7 +46,6 @@ if(PLATFORM STREQUAL "win") add_compile_definitions(WIN32) endif() elseif(PLATFORM STREQUAL "macos") - set(CMAKE_OSX_DEPLOYMENT_TARGET 13.0) if (ARCH STREQUAL "arm64") set(CMAKE_OSX_ARCHITECTURES arm64) elseif(ARCH STREQUAL "x64") @@ -46,7 +53,7 @@ elseif(PLATFORM STREQUAL "macos") endif() set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) set(CMAKE_INSTALL_RPATH "@executable_path") -elseif(PLATFORM STREQUAL "ios" OR PLATFORM STREQUAL "tvos") +elseif(PLATFORM STREQUAL "ios" OR PLATFORM STREQUAL "ios-simulator" OR PLATFORM STREQUAL "tvos") set(CMAKE_OSX_DEPLOYMENT_TARGET 16.0) set(CMAKE_OSX_ARCHITECTURES arm64) elseif(PLATFORM STREQUAL "linux" OR PLATFORM STREQUAL "android") diff --git a/README.md b/README.md index 0173cc2..3d4a233 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,12 @@ cmake -DPLATFORM=ios -DARCH=arm64 -DCMAKE_BUILD_TYPE=Release -B build cmake --build build ``` +#### iOS Simulator (arm64) +```shell +cmake -DPLATFORM=ios-simulator -DARCH=arm64 -DCMAKE_BUILD_TYPE=Release -B build +cmake --build build +``` + #### tvOS (arm64) ```shell cmake -DPLATFORM=tvos -DARCH=arm64 -DCMAKE_BUILD_TYPE=Release -B build diff --git a/src/serum-decode.cpp b/src/serum-decode.cpp index a294c0d..ac36fb0 100644 --- a/src/serum-decode.cpp +++ b/src/serum-decode.cpp @@ -8,6 +8,9 @@ #include #include +#include +#include +#include #include "serum-version.h" @@ -15,6 +18,10 @@ #include #endif +#if defined(_WIN32) || defined(_WIN64) +#define strcasecmp _stricmp +#endif + #if not defined(__STDC_LIB_EXT1__) // trivial implementation of the secure string functions if not directly @@ -137,6 +144,29 @@ uint32_t rotationnextabsolutetime[MAX_COLOR_ROTATIONS]; // cumulative time for t Serum_Frame_Struc mySerum; // structure to keep communicate colorization data +std::string to_lower(const std::string& str) +{ + std::string lower_str; + std::transform(str.begin(), str.end(), std::back_inserter(lower_str), [](unsigned char c) { return std::tolower(c); }); + return lower_str; +} + +std::optional find_case_insensitive_file(const std::string& dir_path, const std::string& filename) +{ + if (!std::filesystem::exists(dir_path) || !std::filesystem::is_directory(dir_path)) + return std::nullopt; + + std::string lower_filename = to_lower(filename); + for (const auto& entry : std::filesystem::directory_iterator(dir_path)) { + if (entry.is_regular_file()) { + std::string entry_filename = entry.path().filename().string(); + if (to_lower(entry_filename) == lower_filename) + return entry.path().string(); + } + } + return std::nullopt; +} + void Free_element(void* pElement) { // free a malloc block and set its pointer to NULL @@ -617,7 +647,7 @@ Serum_Frame_Struc* Serum_LoadFilev1(const char* const filename, const uint8_t fl bool uncompressedCROM = false; if ((ext = strrchr(filename, '.')) != NULL) { - if (strcmp(ext, ".cROM") == 0) + if (strcasecmp(ext, ".cROM") == 0) { uncompressedCROM = true; if (strcpy_s(pathbuf, pathbuflen, filename)) return NULL; @@ -628,12 +658,15 @@ Serum_Frame_Struc* Serum_LoadFilev1(const char* const filename, const uint8_t fl if (!uncompressedCROM) { char cromname[pathbuflen]; -#if !(defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) - if (strcpy_s(pathbuf, pathbuflen, filename)) return NULL; -#else - if (strcpy_s(pathbuf, pathbuflen, getenv("TMPDIR"))) return NULL; - if (strcat_s(pathbuf, pathbuflen, "/")) return NULL; -#endif + if (getenv("TMPDIR") != NULL) { + if (strcpy_s(pathbuf, pathbuflen, getenv("TMPDIR"))) return NULL; + size_t len = strlen(pathbuf); + if (len > 0 && pathbuf[len - 1] != '/') { + if (strcat_s(pathbuf, pathbuflen, "/")) return NULL; + } + } + else if (strcpy_s(pathbuf, pathbuflen, filename)) return NULL; + if (!unzip_crz(filename, pathbuf, cromname, pathbuflen)) return NULL; if (strcat_s(pathbuf, pathbuflen, cromname)) return NULL; } @@ -831,15 +864,21 @@ SERUM_API Serum_Frame_Struc* Serum_Load(const char* const altcolorpath, const ch mySerum.rotationsinframe64 = NULL; mySerum.modifiedelements32 = NULL; mySerum.modifiedelements64 = NULL; - char pathbuf[pathbuflen]; - if (strcpy_s(pathbuf, pathbuflen, altcolorpath) || ((pathbuf[strlen(pathbuf) - 1] != '\\') && (pathbuf[strlen(pathbuf) - 1] != '/') && - strcat_s(pathbuf, pathbuflen, "/")) || strcat_s(pathbuf, pathbuflen, romname) || strcat_s(pathbuf, pathbuflen, "/") || - strcat_s(pathbuf, pathbuflen, romname) || strcat_s(pathbuf, pathbuflen, ".cRZ")) - { + + std::string pathbuf = std::string(altcolorpath); + if (pathbuf.back() != '\\' && pathbuf.back() != '/') + pathbuf += '/'; + pathbuf += romname; + pathbuf += '/'; + + std::optional pFoundFile = find_case_insensitive_file(pathbuf, std::string(romname) + ".cROM"); + if (!pFoundFile) + pFoundFile = find_case_insensitive_file(pathbuf, std::string(romname) + ".cRZ"); + if (!pFoundFile) { enabled = false; return NULL; } - return Serum_LoadFilev1(pathbuf, flags); + return Serum_LoadFilev1(pFoundFile->c_str(), flags); } SERUM_API void Serum_Dispose(void)