Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

misc: ios simulator builds, case-insensitive files, TMPDIR env var #54

Merged
merged 1 commit into from
Jun 30, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions .github/workflows/libserum.yml
Original file line number Diff line number Diff line change
@@ -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
13 changes: 10 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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,15 +46,14 @@ 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")
set(CMAKE_OSX_ARCHITECTURES x86_64)
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")
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -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
65 changes: 52 additions & 13 deletions src/serum-decode.cpp
Original file line number Diff line number Diff line change
@@ -8,13 +8,20 @@
#include <string.h>

#include <chrono>
#include <filesystem>
#include <algorithm>
#include <optional>

#include "serum-version.h"

#if defined(__APPLE__)
#include <TargetConditionals.h>
#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

static 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;
}

static std::optional<std::string> 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<std::string> 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)