Skip to content

Instantly share code, notes, and snippets.

@Wowfunhappy
Last active May 27, 2024 16:26
Show Gist options
  • Save Wowfunhappy/ab459b4bf7c070f31300894c42c427a4 to your computer and use it in GitHub Desktop.
Save Wowfunhappy/ab459b4bf7c070f31300894c42c427a4 to your computer and use it in GitHub Desktop.
Build Ship of Harkinian for Mac OS X 10.9
Last used with this commit: https://github.com/HarbourMasters/Shipwright/commit/ad0e17383e72c652541e6a90367ab720c6a18723
1. sudo port install libsdl2 libpng glew ninja cmake libzip nlohmann-json boost legacy-support clang-17 macports-libcxx tinyxml2
2. git clone --recursive https://github.com/HarbourMasters/Shipwright.git
3. Place compatible Ocarina of Time rom in OTRExporter
4 Change/add in cmakelists.txt: (We want to use the MacPorts LegacySupport Library, and the macports-libcxx cpp standard library.)
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum OS X deployment version")
set(CMAKE_C_FLAGS "-Wno-gnu-include-next")
set(CMAKE_CXX_FLAGS "-Wno-gnu-include-next -nostdinc++ -I/opt/local/include/libcxx/v1")
include_directories(/opt/local/include/LegacySupport)
link_libraries("-L/opt/local/lib/libcxx /opt/local/lib/libMacportsLegacySupport.a")
5. Change related blocks in libultraship/src/cmakelists.txt to match: (Deleting Metal & AVFoundation support.)
if (False)
list(FILTER Source_Files__Graphic EXCLUDE REGEX "graphic/Fast3D/gfx_metal*")
endif()
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR CMAKE_SYSTEM_NAME STREQUAL "iOS")
find_Library(OSX_FOUNDATION Foundation)
find_library(QUARTZCORE QuartzCore)
target_link_libraries(libultraship PRIVATE ${OSX_FOUNDATION} ${QUARTZCORE} ${CMAKE_DL_LIBS})
endif()
6. Comment out blocks in libultraship/cmake/dependencies/mac.cmake: (Deleting Metal support.)
#=================== Metal-cpp ===================
FetchContent_Declare(
metalcpp
GIT_REPOSITORY https://github.com/briaguya-ai/single-header-metal-cpp.git
GIT_TAG macOS13_iOS16
)
FetchContent_MakeAvailable(metalcpp)
list(APPEND ADDITIONAL_LIB_INCLUDES ${metalcpp_SOURCE_DIR})
${imgui_SOURCE_DIR}/backends/imgui_impl_metal.mm
target_include_directories(ImGui PRIVATE ${metalcpp_SOURCE_DIR})
target_compile_definitions(ImGui PUBLIC IMGUI_IMPL_METAL_CPP)
7. Change related block in soh/cmakelists.txt to match: (Don't use 10.15-only AVFoundation speech synthesizer.)
# handle speechsynthesizer removals
list(FILTER soh__Enhancements EXCLUDE REGEX "soh/Enhancements/speechsynthesizer/(Darwin|SAPI).*")
8. In all of the below files, change `#ifdef __APPLE__` to `#if 0`:
• libultraship/src/graphic/Fast3D/gfx_metal_shader.cpp
• libultraship/src/graphic/Fast3D/gfx_metal.cpp
• libultraship/src/graphic/Fast3D/Fast3dWindow.cpp
• libultraship/src/config/Config.cpp
• soh/soh/OTRGlobals.cpp
> Only the block related to SpeechSynthesizer. Leave the others.
9. In soh/soh/Enhancements/speechsynthesizer/SpeechSynthesizer.h, comment out:
#include "DarwinSpeechSynthesizer.h"
10. Change related blocks in soh/soh/Enhancements/game-interactor/GameInteractor.h to match: (For reasons I don't entirely understand, the code won't build if we use an unordered map. I changed it to a vector, and had ChatGPT write code to make that work seamlessly.)
template <typename H> struct RegisteredGameHooks { inline static std::vector<std::pair<uint32_t, typename H::fn>> functions; };
template <typename H> uint32_t RegisterGameHook(typename H::fn h) {
// Ensure hook id is unique and not 0, which is reserved for invalid hooks
if (this->nextHookId == 0 || this->nextHookId >= UINT32_MAX) this->nextHookId = 1;
auto iter = std::find_if(RegisteredGameHooks<H>::functions.begin(), RegisteredGameHooks<H>::functions.end(),
[&](const std::pair<uint32_t, typename H::fn>& pair) { return pair.first == this->nextHookId; });
while (iter != RegisteredGameHooks<H>::functions.end()) {
this->nextHookId++;
iter = std::find_if(RegisteredGameHooks<H>::functions.begin(), RegisteredGameHooks<H>::functions.end(),
[&](const std::pair<uint32_t, typename H::fn>& pair) { return pair.first == this->nextHookId; });
}
RegisteredGameHooks<H>::functions.push_back({this->nextHookId, h});
return this->nextHookId++;
}
template <typename H, typename... Args> void ExecuteHooks(Args&&... args) {
RegisteredGameHooks<H>::functions.erase(
std::remove_if(
RegisteredGameHooks<H>::functions.begin(),
RegisteredGameHooks<H>::functions.end(),
[&](const std::pair<uint32_t, typename H::fn>& pair) {
return std::find(HooksToUnregister<H>::hooks.begin(), HooksToUnregister<H>::hooks.end(), pair.first) != HooksToUnregister<H>::hooks.end();
}),
RegisteredGameHooks<H>::functions.end());
HooksToUnregister<H>::hooks.clear();
for (auto& hook : RegisteredGameHooks<H>::functions) {
hook.second(std::forward<Args>(args)...);
}
}
11. Comment out all of the below blocks in libultraship/src/window/gui/Gui.cpp: (Deleting Metal support.)
#include "graphic/Fast3D/gfx_metal.h"
#include <imgui_impl_metal.h>
#ifdef __APPLE__
case WindowBackend::SDL_METAL:
Metal_Init(mImpl.Metal.Renderer);
break;
#endif
#ifdef __APPLE__
case WindowBackend::SDL_METAL:
Metal_NewFrame(mImpl.Metal.Renderer);
break;
#endif
#ifdef __APPLE__
if (Context::GetInstance()->GetWindow()->GetWindowBackend() == WindowBackend::SDL_METAL) {
return gfx_metal_get_texture_by_id(id);
}
#endif
#ifdef __APPLE__
case WindowBackend::SDL_METAL:
Metal_RenderDrawData(data);
break;
#endif
12. cmake -H. -Bbuild-cmake -GNinja -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_C_COMPILER=/opt/local/bin/clang-mp-17 -DCMAKE_CXX_COMPILER=/opt/local/bin/clang++-mp-17
13. cmake --build build-cmake --target ExtractAssets
14. cmake --build build-cmake --config Release
15. cd build-cmake && cpack
16. In soh.app/Contents/info.plist, change `LSMinimumSystemVersion` to `10.9`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment