From ea1ffdd041651e3cf7caca70459891ff38465156 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Wed, 28 Feb 2024 19:04:44 -0700 Subject: [PATCH 01/15] Adds messageboxes to `no_ui` handling so they don't show if you have it on. (#3977) --- soh/src/code/z_message_PAL.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/soh/src/code/z_message_PAL.c b/soh/src/code/z_message_PAL.c index 7bb3803fc..87cff43da 100644 --- a/soh/src/code/z_message_PAL.c +++ b/soh/src/code/z_message_PAL.c @@ -8,6 +8,7 @@ #include "textures/message_static/message_static.h" #include "textures/message_texture_static/message_texture_static.h" #include "soh/Enhancements/cosmetics/cosmeticsTypes.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/OTRGlobals.h" @@ -3069,7 +3070,9 @@ void Message_Draw(PlayState* play) { POLY_OPA_DISP = plusOne; } plusOne = Graph_GfxPlusOne(polyOpaP = POLY_OPA_DISP); - gSPDisplayList(OVERLAY_DISP++, plusOne); + if (!GameInteractor_NoUIActive()) { + gSPDisplayList(OVERLAY_DISP++, plusOne); + } Message_DrawMain(play, &plusOne); gSPEndDisplayList(plusOne++); Graph_BranchDlist(polyOpaP, plusOne); From 358dd47da7542efdc4fa7f768a4b1fe9be350368 Mon Sep 17 00:00:00 2001 From: Archez Date: Wed, 28 Feb 2024 22:03:08 -0500 Subject: [PATCH 02/15] remove zapd extraction from mac launch script (#3981) --- soh/macosx/soh-macos.sh.in | 234 ------------------------------------- 1 file changed, 234 deletions(-) diff --git a/soh/macosx/soh-macos.sh.in b/soh/macosx/soh-macos.sh.in index 0983f63b1..217496cf1 100755 --- a/soh/macosx/soh-macos.sh.in +++ b/soh/macosx/soh-macos.sh.in @@ -7,68 +7,6 @@ export RESPATH="${SNAME%/MacOS*}/Resources" export LIBPATH="${SNAME%/MacOS*}/Frameworks" export DYLD_FALLBACK_LIBRARY_PATH="$LIBPATH" -remap_hashes () -{ - # Remap v64 and n64 hashes to their z64 hash equivalent - # ZAPD will handle converting the data into z64 format - case "$ROMHASH" in - a9059b56e761c9034fbe02fe4c24985aaa835dac) # v64 - ROMHASH=cee6bc3c2a634b41728f2af8da54d9bf8cc14099 - ;; - 24708102dc504d3f375a37f4ae4e149c167dc515) # n64 - ROMHASH=cee6bc3c2a634b41728f2af8da54d9bf8cc14099 - ;; - 580dd0bd1b6d2c51cc20a764eece84dba558964c) # v64 - ROMHASH=0227d7c0074f2d0ac935631990da8ec5914597b4 - ;; - d6342c59007e57c1194661ec6880b2f078403f4e) # n64 - ROMHASH=0227d7c0074f2d0ac935631990da8ec5914597b4 - ;; - d0bdc2eb320668b4ba6893b9aefe4040a73123ff) # v64 - ROMHASH=328a1f1beba30ce5e178f031662019eb32c5f3b5 - ;; - 4946ab250f6ac9b32d76b21f309ebb8ebc8103d2) # n64 - ROMHASH=328a1f1beba30ce5e178f031662019eb32c5f3b5 - ;; - 663c34f1b2c05a09e5beffe4d0dcd440f7d49dc7) # v64 - ROMHASH=cfbb98d392e4a9d39da8285d10cbef3974c2f012 - ;; - 24c73d378b0620a380ce5ef9f2b186c6c157a68b) # n64 - ROMHASH=cfbb98d392e4a9d39da8285d10cbef3974c2f012 - ;; - 8ebf2e29313f44f2d49e5b4191971d09919e8e48) # v64 - ROMHASH=f46239439f59a2a594ef83cf68ef65043b1bffe2 - ;; - 4264bf7b875737b8fae77d52322a5099d051fc11) # n64 - ROMHASH=f46239439f59a2a594ef83cf68ef65043b1bffe2 - ;; - 973bc6fe56010a8d646166a1182a81b4f13b8cf9) # v64 - ROMHASH=50bebedad9e0f10746a52b07239e47fa6c284d03 - ;; - d327752c46edc70ff3668b9514083dbbee08927c) # v64 - ROMHASH=50bebedad9e0f10746a52b07239e47fa6c284d03 - ;; - ecdeb1747560834e079c22243febea7f6f26ba3b) # v64 - ROMHASH=079b855b943d6ad8bd1eb026c0ed169ecbdac7da - ;; - f19f8662ec7abee29484a272a6fda53e39efe0f1) # n64 - ROMHASH=079b855b943d6ad8bd1eb026c0ed169ecbdac7da - ;; - ab519ce04a33818ce2c39b3c514a751d807a494a) # v64 - ROMHASH=cfecfdc58d650e71a200c81f033de4e6d617a9f6 - ;; - c19a34f7646305e1755249fca2071e178bd7cd00) # n64 - ROMHASH=cfecfdc58d650e71a200c81f033de4e6d617a9f6 - ;; - 25e8ae79ea0839ca5c984473f7460d8040c36f9c) # v64 - ROMHASH=517bd9714c73cb96c21e7c2ef640d7b55186102f - ;; - 166c02770d67fcc3954c443eb400a6a3573d3fc0) # n64 - ROMHASH=517bd9714c73cb96c21e7c2ef640d7b55186102f - ;; - esac -} - if [ ! -e "$SHIP_HOME" ]; then mkdir "$SHIP_HOME"; fi if [ ! -e "$SHIP_HOME"/mods ]; then @@ -76,178 +14,6 @@ if [ ! -e "$SHIP_HOME"/mods ]; then touch "$SHIP_HOME"/mods/custom_otr_files_go_here.txt fi -# If either OTR doesn't exist kick off the OTR gen process -if [ ! -e "$SHIP_HOME"/oot.otr ] || [ ! -e "$SHIP_HOME"/oot-mq.otr ]; then - - # If no ROMs exist kick off the file selection prompts - while [ ! -e "$SHIP_HOME"/*.*64 ] && [ ! -e "$SHIP_HOME"/oot*.otr ]; do - - SHOULD_PROMPT_FOR_ROM=1 - while [ $SHOULD_PROMPT_FOR_ROM -eq 1 ]; do - SHOULD_PROMPT_FOR_ROM=0 - # Use osascript to prompt the user to chose a file - DROPROM=`osascript <<-EOF - set romFile to choose file of type {"b64","n64","v64","z64"} with prompt "Please select your ROM:" - return POSIX path of romFile - EOF` - - # If no rom was selected, the user cancelled, so exit - if [[ -z $DROPROM ]] && [[ -z "$UPLOAD_ANOTHER_RESULT" ]]; then - echo "No ROM selected. Exiting..." - exit 1 - elif [[ -z $DROPROM ]]; then - break; - fi - - # If an invalid rom was selected, let the user know and ask to try again - ROMHASH="$(shasum "$DROPROM" | awk '{ print $1 }')" - - remap_hashes - - case "$ROMHASH" in - cee6bc3c2a634b41728f2af8da54d9bf8cc14099) - ROM_TYPE=0;; - 0227d7c0074f2d0ac935631990da8ec5914597b4) - ROM_TYPE=0;; - 328a1f1beba30ce5e178f031662019eb32c5f3b5) - ROM_TYPE=0;; - cfbb98d392e4a9d39da8285d10cbef3974c2f012) - ROM_TYPE=0;; - f46239439f59a2a594ef83cf68ef65043b1bffe2) - ROM_TYPE=1;; - 50bebedad9e0f10746a52b07239e47fa6c284d03) - ROM_TYPE=1;; - 079b855b943d6ad8bd1eb026c0ed169ecbdac7da) - ROM_TYPE=1;; - cfecfdc58d650e71a200c81f033de4e6d617a9f6) - ROM_TYPE=1;; - 517bd9714c73cb96c21e7c2ef640d7b55186102f) - ROM_TYPE=1;; - *) - TRY_AGAIN_RESULT=`osascript <<-EOF - set alertText to "Incompatible ROM hash" - set alertMessage to "Incompatible ROM provided, would you like to try again?" - return display alert alertText \ - message alertMessage \ - as critical \ - buttons {"Cancel", "Try Again"} - EOF` - if [[ "$TRY_AGAIN_RESULT" == "button returned:Try Again" ]]; then - SHOULD_PROMPT_FOR_ROM=1 - continue; - else - echo "No ROM selected. Exiting..." - exit 1 - fi - esac - - cp "$DROPROM" "$SHIP_HOME" - - # Ask user if they would also like to select the other variant (MQ/Vanilla) - if [ $ROM_TYPE -eq 0 ] && [[ -z "$UPLOAD_ANOTHER_RESULT" ]]; then - UPLOAD_ANOTHER_RESULT=`osascript <<-EOF - set alertText to "Success" - set alertMessage to "Would you also like to provide a Master Quest ROM?" - return display alert alertText \ - message alertMessage \ - buttons {"No", "Yes"} - EOF` - elif [[ -z "$UPLOAD_ANOTHER_RESULT" ]]; then - UPLOAD_ANOTHER_RESULT=`osascript <<-EOF - set alertText to "Success" - set alertMessage to "Would you also like to provide a Vanilla (Non Master Quest) ROM?" - return display alert alertText \ - message alertMessage \ - buttons {"No", "Yes"} - EOF` - fi - - if [[ "$UPLOAD_ANOTHER_RESULT" == "button returned:Yes" ]]; then - UPLOAD_ANOTHER_RESULT="button returned:No" - SHOULD_PROMPT_FOR_ROM=1 - continue; - fi - break - done - done - - # At this point we should now have 1 or more valid roms in $SHIP_HOME directory - - # Prepare tmp dir - for ROMPATH in "$SHIP_HOME"/*.*64 - do - ASSETDIR="$(mktemp -d /tmp/assets-XXXXX)" - export ASSETDIR - cp -r "$RESPATH/assets" "$ASSETDIR" - mkdir -p "$ASSETDIR"/tmp - cp "$ROMPATH" "$ASSETDIR"/tmp/rom.z64 - cd "$ASSETDIR" || return - - # If an invalid rom was detected, let the user know - ROMHASH="$(shasum "$ASSETDIR"/tmp/rom.z64 | awk '{ print $1 }')" - - remap_hashes - - case "$ROMHASH" in - cee6bc3c2a634b41728f2af8da54d9bf8cc14099) - ROM=GC_NMQ_D - OTRNAME="oot.otr";; - 0227d7c0074f2d0ac935631990da8ec5914597b4) - ROM=GC_NMQ_PAL_F - OTRNAME="oot.otr";; - 328a1f1beba30ce5e178f031662019eb32c5f3b5) - ROM=N64_PAL_10 - OTRNAME="oot.otr";; - cfbb98d392e4a9d39da8285d10cbef3974c2f012) - ROM=N64_PAL_11 - OTRNAME="oot.otr";; - f46239439f59a2a594ef83cf68ef65043b1bffe2) - ROM=GC_MQ_PAL_F - OTRNAME="oot-mq.otr";; - 50bebedad9e0f10746a52b07239e47fa6c284d03) - ROM=GC_MQ_D - OTRNAME="oot-mq.otr";; - 079b855b943d6ad8bd1eb026c0ed169ecbdac7da) - ROM=GC_MQ_D - OTRNAME="oot-mq.otr";; - cfecfdc58d650e71a200c81f033de4e6d617a9f6) - ROM=GC_MQ_D - OTRNAME="oot-mq.otr";; - 517bd9714c73cb96c21e7c2ef640d7b55186102f) - ROM=GC_MQ_D - OTRNAME="oot-mq.otr";; - *) - osascript -e 'display notification "One or more invalid ROM provided" with title "Ship Of Harkinian"' - rm -r "$ASSETDIR" - cd "$SNAME" - continue; - esac - - # Only generate OTR if we don't have on of this type yet - if [ -e "$SHIP_HOME"/"$OTRNAME" ]; then - rm -r "$ASSETDIR" - cd "$SNAME" - continue; - fi - - osascript -e 'display notification "Generating OTR..." with title "Ship Of Harkinian"' - assets/extractor/ZAPD.out ed -i assets/extractor/xmls/"${ROM}" -b tmp/rom.z64 -fl assets/extractor/filelists -o placeholder -osf placeholder -gsf 1 -rconf assets/extractor/Config_"${ROM}".xml -se OTR --portVer "@CMAKE_PROJECT_VERSION@" - if [ -e "$ASSETDIR"/oot.otr ]; then - osascript -e 'display notification "OTR successfully generated" with title "Ship Of Harkinian"' - cp "$ASSETDIR"/oot.otr "$SHIP_HOME"/"$OTRNAME" - rm -r "$ASSETDIR" - cd "$SNAME" - fi - done - - if [ ! -e "$SHIP_HOME"/oot*.otr ]; then - osascript -e 'display notification "OTR failed to generate" with title "Ship Of Harkinian"' - exit 1; - fi -fi - -cd "$SNAME" - arch_name="$(uname -m)" launch_arch="arm64" if [ "${arch_name}" = "x86_64" ] && [ "$(sysctl -in sysctl.proc_translated)" != "1" ]; then From b26f2b21da3768b4caca370d5b3e6165849b4478 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Wed, 28 Feb 2024 20:12:23 -0700 Subject: [PATCH 03/15] [UX Improvement] Catch save loading errors and notify user (#3979) * Add `SohModalWindow` and `SohModal`. Runs as window, always "visible", but not drawing if no popups are registered. Adds error catching for save file corruption (malformed json) that renames the file in question to prevent future loading issues and uses `SohModalWindow` to inform the user of the error. * Apply suggestions from code review --------- Co-authored-by: briaguya <70942617+briaguya-ai@users.noreply.github.com> --- soh/soh/SaveManager.cpp | 100 ++++++++++++++++++++++++---------------- soh/soh/SohGui.cpp | 9 ++++ soh/soh/SohGui.hpp | 2 + soh/soh/SohModals.cpp | 54 ++++++++++++++++++++++ soh/soh/SohModals.h | 15 ++++++ 5 files changed, 139 insertions(+), 41 deletions(-) create mode 100644 soh/soh/SohModals.cpp create mode 100644 soh/soh/SohModals.h diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index e61cf9223..10d40396f 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -9,6 +9,7 @@ #include #include "soh/Enhancements/boss-rush/BossRush.h" #include +#include "SohGui.hpp" #define NOGDI // avoid various windows defines that conflict with things in z64.h #include @@ -1023,53 +1024,70 @@ void SaveManager::SaveGlobal() { output << std::setw(4) << globalBlock << std::endl; } + void SaveManager::LoadFile(int fileNum) { SPDLOG_INFO("Load File - fileNum: {}", fileNum); - assert(std::filesystem::exists(GetFileName(fileNum))); + std::filesystem::path fileName = GetFileName(fileNum); + assert(std::filesystem::exists(fileName)); InitFile(false); - std::ifstream input(GetFileName(fileNum)); - - saveBlock = nlohmann::json::object(); - input >> saveBlock; - if (!saveBlock.contains("version")) { - SPDLOG_ERROR("Save at " + GetFileName(fileNum).string() + " contains no version"); - assert(false); - } - switch (saveBlock["version"].get()) { - case 1: - for (auto& block : saveBlock["sections"].items()) { - int sectionVersion = block.value()["version"]; - std::string sectionName = block.key(); - if (!sectionLoadHandlers.contains(sectionName)) { - // Unloadable sections aren't necessarily errors, they are probably mods that were unloaded - // TODO report in a more noticeable manner - SPDLOG_WARN("Save " + GetFileName(fileNum).string() + " contains unloadable section " + sectionName); - continue; - } - SectionLoadHandler& handler = sectionLoadHandlers[sectionName]; - if (!handler.contains(sectionVersion)) { - // A section that has a loader without a handler for the specific version means that the user has a mod - // at an earlier version than the save has. In this case, the user probably wants to load the save. - // Report the error so that the user can rectify the error. - // TODO report in a more noticeable manner - SPDLOG_ERROR("Save " + GetFileName(fileNum).string() + " contains section " + sectionName + - " with an unloadable version " + std::to_string(sectionVersion)); - assert(false); - continue; - } - currentJsonContext = &block.value()["data"]; - handler[sectionVersion](); - } - break; - default: - SPDLOG_ERROR("Unrecognized save version " + std::to_string(saveBlock["version"].get()) + " in " + - GetFileName(fileNum).string()); + std::ifstream input(fileName); + + try { + saveBlock = nlohmann::json::object(); + input >> saveBlock; + if (!saveBlock.contains("version")) { + SPDLOG_ERROR("Save at " + fileName.string() + " contains no version"); assert(false); - break; + } + switch (saveBlock["version"].get()) { + case 1: + for (auto& block : saveBlock["sections"].items()) { + int sectionVersion = block.value()["version"]; + std::string sectionName = block.key(); + if (!sectionLoadHandlers.contains(sectionName)) { + // Unloadable sections aren't necessarily errors, they are probably mods that were unloaded + // TODO report in a more noticeable manner + SPDLOG_WARN("Save " + GetFileName(fileNum).string() + " contains unloadable section " + + sectionName); + continue; + } + SectionLoadHandler& handler = sectionLoadHandlers[sectionName]; + if (!handler.contains(sectionVersion)) { + // A section that has a loader without a handler for the specific version means that the user + // has a mod at an earlier version than the save has. In this case, the user probably wants to + // load the save. Report the error so that the user can rectify the error. + // TODO report in a more noticeable manner + SPDLOG_ERROR("Save " + GetFileName(fileNum).string() + " contains section " + sectionName + + " with an unloadable version " + std::to_string(sectionVersion)); + assert(false); + continue; + } + currentJsonContext = &block.value()["data"]; + handler[sectionVersion](); + } + break; + default: + SPDLOG_ERROR("Unrecognized save version " + std::to_string(saveBlock["version"].get()) + " in " + + GetFileName(fileNum).string()); + assert(false); + break; + } + InitMeta(fileNum); + GameInteractor::Instance->ExecuteHooks(fileNum); + } catch (const std::exception& e) { + input.close(); + std::filesystem::path newFile(LUS::Context::GetPathRelativeToAppDirectory("Save") + ("/file" + std::to_string(fileNum + 1) + ".bak")); +#if defined(__SWITCH__) || defined(__WIIU__) + copy_file(fileName.c_str(), newFile.c_str()); +#else + std::filesystem::copy_file(fileName, newFile); +#endif + + std::filesystem::remove(fileName); + SohGui::RegisterPopup("Error loading save file", "A problem occurred loading the save in slot " + std::to_string(fileNum + 1) + ".\nSave file corruption is suspected.\n" + + "The file has been renamed to prevent further issues."); } - InitMeta(fileNum); - GameInteractor::Instance->ExecuteHooks(fileNum); } void SaveManager::ThreadPoolWait() { diff --git a/soh/soh/SohGui.cpp b/soh/soh/SohGui.cpp index 94b9e690d..90f6e59e5 100644 --- a/soh/soh/SohGui.cpp +++ b/soh/soh/SohGui.cpp @@ -125,6 +125,7 @@ namespace SohGui { std::shared_ptr mItemTrackerSettingsWindow; std::shared_ptr mItemTrackerWindow; std::shared_ptr mRandomizerSettingsWindow; + std::shared_ptr mModalWindow; void SetupGuiElements() { auto gui = LUS::Context::GetInstance()->GetWindow()->GetGui(); @@ -183,9 +184,13 @@ namespace SohGui { gui->AddGuiWindow(mItemTrackerSettingsWindow); mRandomizerSettingsWindow = std::make_shared("gRandomizerSettingsEnabled", "Randomizer Settings"); gui->AddGuiWindow(mRandomizerSettingsWindow); + mModalWindow = std::make_shared("gOpenWindows.modalWindowEnabled", "Modal Window"); + gui->AddGuiWindow(mModalWindow); + mModalWindow->Show(); } void Destroy() { + mModalWindow = nullptr; mRandomizerSettingsWindow = nullptr; mItemTrackerWindow = nullptr; mItemTrackerSettingsWindow = nullptr; @@ -205,4 +210,8 @@ namespace SohGui { mConsoleWindow = nullptr; mSohMenuBar = nullptr; } + + void RegisterPopup(std::string title, std::string message, std::string button1, std::string button2, std::function button1callback, std::function button2callback) { + mModalWindow->RegisterPopup(title, message, button1, button2, button1callback, button2callback); + } } diff --git a/soh/soh/SohGui.hpp b/soh/soh/SohGui.hpp index 59333fd42..dead44b51 100644 --- a/soh/soh/SohGui.hpp +++ b/soh/soh/SohGui.hpp @@ -22,6 +22,7 @@ #include "Enhancements/randomizer/randomizer_entrance_tracker.h" #include "Enhancements/randomizer/randomizer_item_tracker.h" #include "Enhancements/randomizer/randomizer_settings_window.h" +#include "SohModals.h" #ifdef __cplusplus extern "C" { @@ -37,6 +38,7 @@ namespace SohGui { void SetupGuiElements(); void Draw(); void Destroy(); + void RegisterPopup(std::string title, std::string message, std::string button1 = "OK", std::string button2 = "", std::function button1callback = nullptr, std::function button2callback = nullptr); } #endif /* SohGui_hpp */ diff --git a/soh/soh/SohModals.cpp b/soh/soh/SohModals.cpp new file mode 100644 index 000000000..087bc8ab1 --- /dev/null +++ b/soh/soh/SohModals.cpp @@ -0,0 +1,54 @@ +#include "SohModals.h" +#include "ImGui/imgui.h" +#include +#include +#include +#include +#include "UIWidgets.hpp" +#include "OTRGlobals.h" +#include "z64.h" + +extern "C" PlayState* gPlayState; +struct SohModal { + std::string title_; + std::string message_; + std::string button1_; + std::string button2_; + std::function button1callback_; + std::function button2callback_; +}; +std::vector modals; + +void SohModalWindow::DrawElement() { + if (modals.size() > 0) { + SohModal curModal = modals.at(0); + if (!ImGui::IsPopupOpen(curModal.title_.c_str())) { + ImGui::OpenPopup(curModal.title_.c_str()); + } + if (ImGui::BeginPopupModal(curModal.title_.c_str(), NULL, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings)) { + ImGui::Text(curModal.message_.c_str()); + if (ImGui::Button(curModal.button1_.c_str())) { + if (curModal.button1callback_ != nullptr) { + curModal.button1callback_(); + } + ImGui::CloseCurrentPopup(); + modals.erase(modals.begin()); + } + ImGui::SameLine(); + if (curModal.button2_ != "") { + if (ImGui::Button(curModal.button2_.c_str())) { + if (curModal.button2callback_ != nullptr) { + curModal.button2callback_(); + } + ImGui::CloseCurrentPopup(); + modals.erase(modals.begin()); + } + } + } + ImGui::EndPopup(); + } +} + +void SohModalWindow::RegisterPopup(std::string title, std::string message, std::string button1, std::string button2, std::function button1callback, std::function button2callback) { + modals.push_back({ title, message, button1, button2, button1callback, button2callback }); +} \ No newline at end of file diff --git a/soh/soh/SohModals.h b/soh/soh/SohModals.h new file mode 100644 index 000000000..6f5acb2c0 --- /dev/null +++ b/soh/soh/SohModals.h @@ -0,0 +1,15 @@ +#pragma once + +#include +#include "window/gui/GuiMenuBar.h" +#include "window/gui/GuiElement.h" + +class SohModalWindow : public LUS::GuiWindow { + public: + using LUS::GuiWindow::GuiWindow; + + void InitElement() override {}; + void DrawElement() override; + void UpdateElement() override {}; + void RegisterPopup(std::string title, std::string message, std::string button1 = "OK", std::string button2 = "", std::function button1callback = nullptr, std::function button2callback = nullptr); +}; \ No newline at end of file From fb6ea4256072b75e6d70a24948fd2120c47e247e Mon Sep 17 00:00:00 2001 From: Archez Date: Wed, 28 Feb 2024 22:33:51 -0500 Subject: [PATCH 04/15] prevent remember save location in dungeons/boss rooms (#3983) --- .../randomizer/randomizer_entrance.c | 5 + soh/soh/SohMenuBar.cpp | 2 +- soh/src/code/z_sram.c | 117 +++++++++--------- .../ovl_file_choose/z_file_choose.c | 6 +- 4 files changed, 67 insertions(+), 63 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance.c b/soh/soh/Enhancements/randomizer/randomizer_entrance.c index e6ec3fef3..eda976473 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_entrance.c +++ b/soh/soh/Enhancements/randomizer/randomizer_entrance.c @@ -398,6 +398,11 @@ void Entrance_SetSavewarpEntrance(void) { gSaveContext.entranceIndex = 0x0486; // Gerudo Fortress -> Thieve's Hideout spawn 0 } else if (scene == SCENE_LINKS_HOUSE) { gSaveContext.entranceIndex = Entrance_OverrideNextIndex(LINK_HOUSE_SAVEWARP_ENTRANCE); + } else if (CVarGetInteger("gRememberSaveLocation", 0) && scene != SCENE_FAIRYS_FOUNTAIN && scene != SCENE_GROTTOS && + // Use the saved entrance value with remember save location, except when in grottos/fairy fountains or if + // the entrance index is -1 (new save) + gSaveContext.entranceIndex != -1) { + return; } else if (LINK_IS_CHILD) { gSaveContext.entranceIndex = Entrance_OverrideNextIndex(LINK_HOUSE_SAVEWARP_ENTRANCE); // Child Overworld Spawn } else { diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index 2f654c04f..0917b0c6d 100644 --- a/soh/soh/SohMenuBar.cpp +++ b/soh/soh/SohMenuBar.cpp @@ -558,7 +558,7 @@ void DrawEnhancementsMenu() { UIWidgets::Tooltip("Pierre appears when Ocarina is pulled out. Requires learning scarecrow song."); UIWidgets::PaddedEnhancementCheckbox("Remember Save Location", "gRememberSaveLocation", true, false); UIWidgets::Tooltip("When loading a save, places Link at the last entrance he went through.\n" - "This doesn't work if the save was made in a grotto."); + "This doesn't work if the save was made in grottos/fairy fountains or dungeons."); UIWidgets::PaddedEnhancementCheckbox("Skip Magic Arrow Equip Animation", "gSkipArrowAnimation", true, false); UIWidgets::PaddedEnhancementCheckbox("Skip save confirmation", "gSkipSaveConfirmation", true, false); UIWidgets::Tooltip("Skip the \"Game saved.\" confirmation screen"); diff --git a/soh/src/code/z_sram.c b/soh/src/code/z_sram.c index 1ce20abc3..0152ecf2e 100644 --- a/soh/src/code/z_sram.c +++ b/soh/src/code/z_sram.c @@ -59,65 +59,68 @@ void Sram_OpenSave() { Save_LoadFile(); - if (!CVarGetInteger("gRememberSaveLocation", 0) || gSaveContext.savedSceneNum == SCENE_FAIRYS_FOUNTAIN || - gSaveContext.savedSceneNum == SCENE_GROTTOS) { - switch (gSaveContext.savedSceneNum) { - case SCENE_DEKU_TREE: - case SCENE_DODONGOS_CAVERN: - case SCENE_JABU_JABU: - case SCENE_FOREST_TEMPLE: - case SCENE_FIRE_TEMPLE: - case SCENE_WATER_TEMPLE: - case SCENE_SPIRIT_TEMPLE: - case SCENE_SHADOW_TEMPLE: - case SCENE_BOTTOM_OF_THE_WELL: - case SCENE_ICE_CAVERN: - case SCENE_GANONS_TOWER: - case SCENE_GERUDO_TRAINING_GROUND: - case SCENE_THIEVES_HIDEOUT: - case SCENE_INSIDE_GANONS_CASTLE: - gSaveContext.entranceIndex = dungeonEntrances[gSaveContext.savedSceneNum]; - break; - case SCENE_DEKU_TREE_BOSS: - gSaveContext.entranceIndex = 0; - break; - case SCENE_DODONGOS_CAVERN_BOSS: - gSaveContext.entranceIndex = 4; - break; - case SCENE_JABU_JABU_BOSS: - gSaveContext.entranceIndex = 0x28; - break; - case SCENE_FOREST_TEMPLE_BOSS: - gSaveContext.entranceIndex = 0x169; - break; - case SCENE_FIRE_TEMPLE_BOSS: - gSaveContext.entranceIndex = 0x165; - break; - case SCENE_WATER_TEMPLE_BOSS: - gSaveContext.entranceIndex = 0x10; - break; - case SCENE_SPIRIT_TEMPLE_BOSS: - gSaveContext.entranceIndex = 0x82; - break; - case SCENE_SHADOW_TEMPLE_BOSS: - gSaveContext.entranceIndex = 0x37; - break; - case SCENE_GANONS_TOWER_COLLAPSE_INTERIOR: - case SCENE_INSIDE_GANONS_CASTLE_COLLAPSE: - case SCENE_GANONDORF_BOSS: - case SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR: - case SCENE_GANON_BOSS: - gSaveContext.entranceIndex = 0x41B; - break; + switch (gSaveContext.savedSceneNum) { + case SCENE_DEKU_TREE: + case SCENE_DODONGOS_CAVERN: + case SCENE_JABU_JABU: + case SCENE_FOREST_TEMPLE: + case SCENE_FIRE_TEMPLE: + case SCENE_WATER_TEMPLE: + case SCENE_SPIRIT_TEMPLE: + case SCENE_SHADOW_TEMPLE: + case SCENE_BOTTOM_OF_THE_WELL: + case SCENE_ICE_CAVERN: + case SCENE_GANONS_TOWER: + case SCENE_GERUDO_TRAINING_GROUND: + case SCENE_THIEVES_HIDEOUT: + case SCENE_INSIDE_GANONS_CASTLE: + gSaveContext.entranceIndex = dungeonEntrances[gSaveContext.savedSceneNum]; + break; + case SCENE_DEKU_TREE_BOSS: + gSaveContext.entranceIndex = 0; + break; + case SCENE_DODONGOS_CAVERN_BOSS: + gSaveContext.entranceIndex = 4; + break; + case SCENE_JABU_JABU_BOSS: + gSaveContext.entranceIndex = 0x28; + break; + case SCENE_FOREST_TEMPLE_BOSS: + gSaveContext.entranceIndex = 0x169; + break; + case SCENE_FIRE_TEMPLE_BOSS: + gSaveContext.entranceIndex = 0x165; + break; + case SCENE_WATER_TEMPLE_BOSS: + gSaveContext.entranceIndex = 0x10; + break; + case SCENE_SPIRIT_TEMPLE_BOSS: + gSaveContext.entranceIndex = 0x82; + break; + case SCENE_SHADOW_TEMPLE_BOSS: + gSaveContext.entranceIndex = 0x37; + break; + case SCENE_GANONS_TOWER_COLLAPSE_INTERIOR: + case SCENE_INSIDE_GANONS_CASTLE_COLLAPSE: + case SCENE_GANONDORF_BOSS: + case SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR: + case SCENE_GANON_BOSS: + gSaveContext.entranceIndex = 0x41B; + break; - default: - if (gSaveContext.savedSceneNum != SCENE_LINKS_HOUSE) { - gSaveContext.entranceIndex = (LINK_AGE_IN_YEARS == YEARS_CHILD) ? 0xBB : 0x5F4; - } else { - gSaveContext.entranceIndex = 0xBB; - } + default: + // Use the saved entrance value with remember save location, except when in grottos/fairy fountains + if (CVarGetInteger("gRememberSaveLocation", 0) && gSaveContext.savedSceneNum != SCENE_FAIRYS_FOUNTAIN && + gSaveContext.savedSceneNum != SCENE_GROTTOS) { break; - } + } + + if (gSaveContext.savedSceneNum != SCENE_LINKS_HOUSE) { + gSaveContext.entranceIndex = (LINK_AGE_IN_YEARS == YEARS_CHILD) ? 0xBB : 0x5F4; + } else { + gSaveContext.entranceIndex = 0xBB; + } + break; } osSyncPrintf("scene_no = %d\n", gSaveContext.entranceIndex); diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c index bb8dd14d4..59b6367f9 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c +++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c @@ -3036,11 +3036,7 @@ void FileChoose_LoadGame(GameState* thisx) { Entrance_Init(); // Handle randomized spawn positions after the save context has been setup from load - // When remeber save location is on, set save warp if the save was in an a grotto, or - // the entrance index is -1 from shuffle overwarld spawn - if (Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES) && ((!CVarGetInteger("gRememberSaveLocation", 0) || - gSaveContext.savedSceneNum == SCENE_FAIRYS_FOUNTAIN || gSaveContext.savedSceneNum == SCENE_GROTTOS) || - (CVarGetInteger("gRememberSaveLocation", 0) && Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS) && gSaveContext.entranceIndex == -1))) { + if (Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) { Entrance_SetSavewarpEntrance(); } } From ed9cb1dfd257712dda6fc304b361f2c862321788 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Wed, 28 Feb 2024 20:45:16 -0700 Subject: [PATCH 05/15] Fix CVar evaluation for scummed checks being hidden. (#3985) --- soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 39418485f..b9ca97a9b 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -1337,7 +1337,7 @@ void DrawLocation(RandomizerCheckObject rcObj) { CVarGetColor("gCheckTrackerSeenMainColor", Color_Main_Default); extraColor = CVarGetColor("gCheckTrackerSeenExtraColor", Color_Seen_Extra_Default); } else if (status == RCSHOW_SCUMMED) { - if (!showHidden && CVarGetInteger("gCheckTrackerKnownHide", 0)) { + if (!showHidden && CVarGetInteger("gCheckTrackerScummedHide", 0)) { return; } mainColor = !IsHeartPiece(rcObj.ogItemId) && !IS_RANDO ? CVarGetColor("gCheckTrackerScummedExtraColor", Color_Scummed_Extra_Default) : From 368a9015ac3610f68d9ddd4d18ac0d7573788581 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Wed, 28 Feb 2024 20:46:32 -0700 Subject: [PATCH 06/15] Add Unix timestamp to renamed corrupted file to prevent trying to copy over existing file. (#3984) --- soh/soh/SaveManager.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index 10d40396f..d8003988f 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -1024,7 +1024,6 @@ void SaveManager::SaveGlobal() { output << std::setw(4) << globalBlock << std::endl; } - void SaveManager::LoadFile(int fileNum) { SPDLOG_INFO("Load File - fileNum: {}", fileNum); std::filesystem::path fileName = GetFileName(fileNum); @@ -1077,7 +1076,7 @@ void SaveManager::LoadFile(int fileNum) { GameInteractor::Instance->ExecuteHooks(fileNum); } catch (const std::exception& e) { input.close(); - std::filesystem::path newFile(LUS::Context::GetPathRelativeToAppDirectory("Save") + ("/file" + std::to_string(fileNum + 1) + ".bak")); + std::filesystem::path newFile(LUS::Context::GetPathRelativeToAppDirectory("Save") + ("/file" + std::to_string(fileNum + 1) + "-" + std::to_string(GetUnixTimestamp()) + ".bak")); #if defined(__SWITCH__) || defined(__WIIU__) copy_file(fileName.c_str(), newFile.c_str()); #else From 612da023f0f9da864c2830d2539e49b660ed2ff4 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Thu, 29 Feb 2024 03:46:55 +0000 Subject: [PATCH 07/15] Bump version to MacReady Foxtrot 8.0.5 (#3982) --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c3b85024b..2c8644af4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,8 +5,8 @@ set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use") set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version") -project(Ship VERSION 8.0.4 LANGUAGES C CXX) -set(PROJECT_BUILD_NAME "MacReady Echo" CACHE STRING "") +project(Ship VERSION 8.0.5 LANGUAGES C CXX) +set(PROJECT_BUILD_NAME "MacReady Foxtrot" CACHE STRING "") set(PROJECT_TEAM "github.com/harbourmasters" CACHE STRING "") set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT soh) From ebde648c5976f39c8f1aabcc1d0ce1190404b6f5 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Sat, 2 Mar 2024 20:51:32 -0500 Subject: [PATCH 08/15] `.o2r` support (#3955) --- .github/workflows/apt-deps.txt | 2 +- .github/workflows/generate-builds.yml | 42 ++++++++++++++++++-- .github/workflows/macports-deps.txt | 2 +- .github/workflows/test-builds-on-distros.yml | 16 ++++---- CMakeLists.txt | 2 +- docs/BUILDING.md | 16 ++++---- libultraship | 2 +- soh/soh/OTRGlobals.cpp | 9 +++-- 8 files changed, 65 insertions(+), 26 deletions(-) diff --git a/.github/workflows/apt-deps.txt b/.github/workflows/apt-deps.txt index 43286f69e..e9f7e07e1 100644 --- a/.github/workflows/apt-deps.txt +++ b/.github/workflows/apt-deps.txt @@ -1 +1 @@ -libusb-dev libusb-1.0-0-dev libsdl2-dev libsdl2-net-dev libpng-dev libglew-dev ninja-build +libusb-dev libusb-1.0-0-dev libsdl2-dev libsdl2-net-dev libpng-dev libglew-dev libzip-dev zipcmp zipmerge ziptool ninja-build diff --git a/.github/workflows/generate-builds.yml b/.github/workflows/generate-builds.yml index 582022dbd..c449585bf 100644 --- a/.github/workflows/generate-builds.yml +++ b/.github/workflows/generate-builds.yml @@ -92,14 +92,19 @@ jobs: if [ -d /opt/local/ ]; then echo "MacPorts already installed" else - wget https://github.com/macports/macports-base/releases/download/v2.7.2/MacPorts-2.7.2-12-Monterey.pkg - sudo installer -pkg ./MacPorts-2.7.2-12-Monterey.pkg -target / + wget https://github.com/macports/macports-base/releases/download/v2.9.1/MacPorts-2.9.1-12-Monterey.pkg + sudo installer -pkg ./MacPorts-2.9.1-12-Monterey.pkg -target / fi echo "/opt/local/bin:/opt/local/sbin" >> $GITHUB_PATH + - name: Update MacPorts + if: ${{ !vars.MAC_RUNNER }} + run: | + sudo port selfupdate + sudo port upgrade outdated - name: Install dependencies if: ${{ !vars.MAC_RUNNER }} run: | - brew uninstall --ignore-dependencies libpng + brew uninstall --ignore-dependencies libpng libzip sudo port install $(cat .github/workflows/macports-deps.txt) brew install ninja - name: Download soh.otr @@ -175,6 +180,21 @@ jobs: make -j 10 sudo make install sudo cp -av /usr/local/lib/libSDL* /lib/x86_64-linux-gnu/ + - name: Install latest libzip + if: ${{ (matrix.os == 'ubuntu-20.04' && !vars.LINUX_COMPATIBILITY_RUNNER) }} + run: | + sudo apt-get remove libzip-dev zipcmp zipmerge ziptool + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + if [ ! -d "libzip-1.10.1" ]; then + wget https://libzip.org/download/libzip-1.10.1.tar.gz + tar -xzvf libzip-1.10.1.tar.gz + fi + cd libzip-1.10.1 + mkdir build + cd build + cmake .. + make + sudo make install - name: Install latest SDL_net if: ${{ (matrix.os == 'ubuntu-20.04' && !vars.LINUX_COMPATIBILITY_RUNNER) || (matrix.os == 'ubuntu-22.04' && !vars.LINUX_PERFORMANCE_RUNNER) }} run: | @@ -224,6 +244,14 @@ jobs: sudo apt-get remove -y cmake wget https://github.com/Kitware/CMake/releases/download/v3.28.3/cmake-3.28.3-linux-x86_64.sh -O /tmp/cmake.sh sudo sh /tmp/cmake.sh --prefix=/usr/local/ --exclude-subdir + wget https://libzip.org/download/libzip-1.10.1.tar.gz + tar -xzvf libzip-1.10.1.tar.gz + cd libzip-1.10.1 + mkdir build + cd build + cmake -H.. -B. -DCMAKE_TOOLCHAIN_FILE=/opt/devkitpro/cmake/Switch.cmake + make + make install - name: Fix dubious ownership error if: ${{ vars.LINUX_RUNNER }} run: git config --global --add safe.directory '*' @@ -270,6 +298,14 @@ jobs: sudo apt-get remove -y cmake wget https://github.com/Kitware/CMake/releases/download/v3.28.3/cmake-3.28.3-linux-x86_64.sh -O /tmp/cmake.sh sudo sh /tmp/cmake.sh --prefix=/usr/local/ --exclude-subdir + wget https://libzip.org/download/libzip-1.10.1.tar.gz + tar -xzvf libzip-1.10.1.tar.gz + cd libzip-1.10.1 + mkdir build + cd build + cmake -H.. -B. -DCMAKE_TOOLCHAIN_FILE=/opt/devkitpro/cmake/WiiU.cmake + make + make install - uses: actions/checkout@v3 with: submodules: true diff --git a/.github/workflows/macports-deps.txt b/.github/workflows/macports-deps.txt index 6f5948557..084428d16 100644 --- a/.github/workflows/macports-deps.txt +++ b/.github/workflows/macports-deps.txt @@ -1 +1 @@ -libsdl2 +universal libsdl2_net +universal libpng +universal glew +universal +libsdl2 +universal libsdl2_net +universal libpng +universal glew +universal libzip +universal \ No newline at end of file diff --git a/.github/workflows/test-builds-on-distros.yml b/.github/workflows/test-builds-on-distros.yml index fd8b3c929..190599a44 100644 --- a/.github/workflows/test-builds-on-distros.yml +++ b/.github/workflows/test-builds-on-distros.yml @@ -23,31 +23,31 @@ jobs: if: ${{ matrix.image == 'archlinux:base' }} run: | echo arch - echo pacman -S ${{ matrix.cc }} git cmake ninja lsb-release sdl2 libpng sdl2_net boost + echo pacman -S ${{ matrix.cc }} git cmake ninja lsb-release sdl2 libpng libzip sdl2_net boost pacman -Syu --noconfirm - pacman -S --noconfirm ${{ matrix.cc }} git cmake ninja lsb-release sdl2 libpng sdl2_net boost + pacman -S --noconfirm ${{ matrix.cc }} git cmake ninja lsb-release sdl2 libpng libzip sdl2_net boost - name: Install dependencies (dnf) if: ${{ matrix.image == 'fedora:39' }} run: | echo fedora - echo dnf install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} git cmake ninja-build lsb_release SDL2-devel libpng-devel boost-devel + echo dnf install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} git cmake ninja-build lsb_release SDL2-devel libpng-devel libzip-devel libzip-tools boost-devel dnf -y upgrade - dnf -y install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} git cmake ninja-build lsb_release SDL2-devel libpng-devel boost-devel + dnf -y install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} git cmake ninja-build lsb_release SDL2-devel libpng-devel libzip-devel libzip-tools boost-devel - name: Install dependencies (apt) if: ${{ matrix.image == 'ubuntu:mantic' || matrix.image == 'debian:bookworm' }} run: | echo debian based - echo apt-get install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'g++') || '' }} git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libboost-dev libopengl-dev + echo apt-get install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'g++') || '' }} git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libzip-dev zipcmp zipmerge ziptool libboost-dev libopengl-dev apt-get update apt-get -y full-upgrade - apt-get -y install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'g++') || '' }} git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libboost-dev libopengl-dev + apt-get -y install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'g++') || '' }} git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libzip-dev zipcmp zipmerge ziptool libboost-dev libopengl-dev - name: Install dependencies (zypper) if: ${{ matrix.image == 'opensuse/tumbleweed:latest' }} run: | echo openSUSE - echo zypper in ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} ${{ matrix.cc == 'clang' && 'libstdc++-devel' || '' }} git cmake ninja SDL2-devel libpng16-devel + echo zypper in ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} ${{ matrix.cc == 'clang' && 'libstdc++-devel' || '' }} git cmake ninja SDL2-devel libpng16-devel libzip-devel libzip-tools zypper --non-interactive dup - zypper --non-interactive in ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} ${{ matrix.cc == 'clang' && 'libstdc++-devel' || '' }} git cmake ninja SDL2-devel libpng16-devel + zypper --non-interactive in ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} ${{ matrix.cc == 'clang' && 'libstdc++-devel' || '' }} git cmake ninja SDL2-devel libpng16-devel libzip-devel libzip-tools - uses: actions/checkout@v3 with: submodules: true diff --git a/CMakeLists.txt b/CMakeLists.txt index 9669c5f0c..4f1d3b225 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows") set(VCPKG_TARGET_TRIPLET x64-windows-static) vcpkg_bootstrap() - vcpkg_install_packages(zlib bzip2 libpng sdl2 sdl2-net glew glfw3) + vcpkg_install_packages(zlib bzip2 libzip libpng sdl2 sdl2-net glew glfw3) if (CMAKE_C_COMPILER_LAUNCHER MATCHES "ccache|sccache") set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT Embedded) diff --git a/docs/BUILDING.md b/docs/BUILDING.md index eabc18ec8..d4ba07f3c 100644 --- a/docs/BUILDING.md +++ b/docs/BUILDING.md @@ -88,34 +88,34 @@ cd "build/x64" #### Debian/Ubuntu ```sh # using gcc -apt-get install gcc g++ git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libboost-dev libopengl-dev +apt-get install gcc g++ git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libzip-dev zipcmp zipmerge ziptool libboost-dev libopengl-dev # or using clang -apt-get install clang git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libboost-dev libopengl-dev +apt-get install clang git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libzip-dev zipcmp zipmerge ziptool libboost-dev libopengl-dev ``` #### Arch ```sh # using gcc -pacman -S gcc git cmake ninja lsb-release sdl2 libpng sdl2_net boost +pacman -S gcc git cmake ninja lsb-release sdl2 libpng libzip sdl2_net boost # or using clang -pacman -S clang git cmake ninja lsb-release sdl2 libpng sdl2_net boost +pacman -S clang git cmake ninja lsb-release sdl2 libpng libzip sdl2_net boost ``` #### Fedora ```sh # using gcc -dnf install gcc gcc-c++ git cmake ninja-build lsb_release SDL2-devel libpng-devel boost-devel +dnf install gcc gcc-c++ git cmake ninja-build lsb_release SDL2-devel libpng-devel libzip-devel libzip-tools boost-devel # or using clang -dnf install clang git cmake ninja-build lsb_release SDL2-devel libpng-devel boost-devel +dnf install clang git cmake ninja-build lsb_release SDL2-devel libpng-devel libzip-devel libzip-tools boost-devel ``` #### openSUSE ```sh # using gcc -zypper in gcc gcc-c++ git cmake ninja SDL2-devel libpng16-devel boost +zypper in gcc gcc-c++ git cmake ninja SDL2-devel libpng16-devel libzip-devel libzip-tools # or using clang -zypper in clang libstdc++-devel git cmake ninja SDL2-devel libpng16-devel boost +zypper in clang libstdc++-devel git cmake ninja SDL2-devel libpng16-devel libzip-devel libzip-tools ``` ### Build diff --git a/libultraship b/libultraship index a516b66ce..be3a87eef 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit a516b66ce0c89fe4e33c55b1fbfbde845d0bf129 +Subproject commit be3a87eefc4b0637adf6fff1a3fa5cc9b8265196 diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 4d82de6bc..38fc5afd7 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -265,7 +265,10 @@ OTRGlobals::OTRGlobals() { if (patchesPath.length() > 0 && std::filesystem::exists(patchesPath)) { if (std::filesystem::is_directory(patchesPath)) { for (const auto& p : std::filesystem::recursive_directory_iterator(patchesPath, std::filesystem::directory_options::follow_directory_symlink)) { - if (StringHelper::IEquals(p.path().extension().string(), ".otr")) { + if (StringHelper::IEquals(p.path().extension().string(), ".otr") || + StringHelper::IEquals(p.path().extension().string(), ".mpq") || + StringHelper::IEquals(p.path().extension().string(), ".o2r") || + StringHelper::IEquals(p.path().extension().string(), ".zip")) { patchOTRs.push_back(p.path().generic_string()); } } @@ -866,7 +869,7 @@ OTRVersion ReadPortVersionFromOTR(std::string otrPath) { // Use a temporary archive instance to load the otr and read the version file auto archive = LUS::OtrArchive(otrPath); - if (archive.LoadRaw()) { + if (archive.Open()) { auto t = archive.LoadFileRaw("portVersion"); if (t != nullptr && t->IsLoaded) { auto stream = std::make_shared(t->Buffer->data(), t->Buffer->size()); @@ -877,7 +880,7 @@ OTRVersion ReadPortVersionFromOTR(std::string otrPath) { version.minor = reader->ReadUInt16(); version.patch = reader->ReadUInt16(); } - archive.UnloadRaw(); + archive.Close(); } return version; From 375349e4f72ce4e4609dc88c6ff8e6a4d69d681c Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Mon, 4 Mar 2024 23:36:23 -0500 Subject: [PATCH 09/15] Support font as resource LUS changes (#3993) --- libultraship | 2 +- soh/soh/GbiWrap.cpp | 2 -- soh/soh/OTRGlobals.cpp | 18 ------------------ soh/soh/OTRGlobals.h | 2 -- soh/soh/z_scene_otr.cpp | 11 ----------- 5 files changed, 1 insertion(+), 34 deletions(-) diff --git a/libultraship b/libultraship index be3a87eef..ec01bc798 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit be3a87eefc4b0637adf6fff1a3fa5cc9b8265196 +Subproject commit ec01bc79860c55fe3562dafb4b4cb0aa2ce50a21 diff --git a/soh/soh/GbiWrap.cpp b/soh/soh/GbiWrap.cpp index 46f4c877c..2399051f5 100644 --- a/soh/soh/GbiWrap.cpp +++ b/soh/soh/GbiWrap.cpp @@ -14,8 +14,6 @@ void OTRGetPixelDepthPrepare(float x, float y); uint16_t OTRGetPixelDepth(float x, float y); int32_t OTRGetLastScancode(); void ResourceMgr_LoadDirectory(const char* resName); -void ResourceMgr_LoadFile(const char* resName); -char* ResourceMgr_LoadFileFromDisk(const char* filePath); uint16_t ResourceMgr_LoadTexWidthByName(char* texPath); uint16_t ResourceMgr_LoadTexHeightByName(char* texPath); size_t ResourceGetTexSizeByName(const char* name); diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 38fc5afd7..61f0e2b93 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -1581,10 +1581,6 @@ extern "C" void ResourceMgr_UnloadOriginalWhenAltExists(const char* resName) { } } -extern "C" void ResourceMgr_LoadFile(const char* resName) { - LUS::Context::GetInstance()->GetResourceManager()->LoadResource(resName); -} - std::shared_ptr GetResourceByNameHandlingMQ(const char* path) { std::string Path = path; if (ResourceMgr_IsGameMasterQuest()) { @@ -1606,20 +1602,6 @@ extern "C" char* GetResourceDataByNameHandlingMQ(const char* path) { return (char*)res->GetRawPointer(); } -extern "C" char* ResourceMgr_LoadFileFromDisk(const char* filePath) { - FILE* file = fopen(filePath, "r"); - fseek(file, 0, SEEK_END); - int fSize = ftell(file); - fseek(file, 0, SEEK_SET); - - char* data = (char*)malloc(fSize); - fread(data, 1, fSize, file); - - fclose(file); - - return data; -} - extern "C" uint8_t ResourceMgr_TexIsRaw(const char* texPath) { auto res = std::static_pointer_cast(GetResourceByNameHandlingMQ(texPath)); return res->Flags & TEX_FLAG_LOAD_AS_RAW; diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index db42341c2..a4af676e0 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -95,8 +95,6 @@ uint8_t ResourceMgr_FileExists(const char* resName); uint8_t ResourceMgr_FileAltExists(const char* resName); void ResourceMgr_UnloadOriginalWhenAltExists(const char* resName); char* GetResourceDataByNameHandlingMQ(const char* path); -void ResourceMgr_LoadFile(const char* resName); -char* ResourceMgr_LoadFileFromDisk(const char* filePath); uint8_t ResourceMgr_TexIsRaw(const char* texPath); uint8_t ResourceMgr_ResourceIsBackground(char* texPath); char* ResourceMgr_LoadJPEG(char* data, size_t dataSize); diff --git a/soh/soh/z_scene_otr.cpp b/soh/soh/z_scene_otr.cpp index 3d7889807..0b9ba98f9 100644 --- a/soh/soh/z_scene_otr.cpp +++ b/soh/soh/z_scene_otr.cpp @@ -39,17 +39,6 @@ extern "C" s32 Object_Spawn(ObjectContext* objectCtx, s16 objectId); extern "C" RomFile sNaviMsgFiles[]; s32 OTRScene_ExecuteCommands(PlayState* play, SOH::Scene* scene); -std::shared_ptr ResourceMgr_LoadFile(const char* path) { - std::string Path = path; - if (IsGameMasterQuest()) { - size_t pos = 0; - if ((pos = Path.find("/nonmq/", 0)) != std::string::npos) { - Path.replace(pos, 7, "/mq/"); - } - } - return LUS::Context::GetInstance()->GetResourceManager()->LoadFile(Path.c_str()); -} - // Forward Declaration of function declared in OTRGlobals.cpp std::shared_ptr GetResourceByNameHandlingMQ(const char* path); From 402a4db5934d713e71c44364846e73cb0c0f0107 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Mon, 4 Mar 2024 23:56:26 -0500 Subject: [PATCH 10/15] Bump LUS (#3996) --- libultraship | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libultraship b/libultraship index ec01bc798..d70fd7de2 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit ec01bc79860c55fe3562dafb4b4cb0aa2ce50a21 +Subproject commit d70fd7de2315388c9a99742fd6c634b2cd8be138 From 9fb2f26f1b76e0ce7f2126e8b140448506d0ca07 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Tue, 5 Mar 2024 22:21:15 -0500 Subject: [PATCH 11/15] tts: use `RawJson` resource + add `SpeechLogger` (#3998) * moved `tts.cpp` away from using `LoadFileRaw` by creating a new `RawJson` resource type * added `SpeechLogger` --- .../speechsynthesizer/SpeechLogger.cpp | 16 +++++++++ .../speechsynthesizer/SpeechLogger.h | 17 +++++++++ .../speechsynthesizer/SpeechSynthesizer.h | 2 ++ soh/soh/Enhancements/tts/tts.cpp | 35 +++++++++---------- soh/soh/OTRGlobals.cpp | 5 +++ soh/soh/resource/importer/RawJsonFactory.cpp | 19 ++++++++++ soh/soh/resource/importer/RawJsonFactory.h | 11 ++++++ soh/soh/resource/type/RawJson.cpp | 14 ++++++++ soh/soh/resource/type/RawJson.h | 20 +++++++++++ soh/soh/resource/type/SohResourceType.h | 1 + 10 files changed, 122 insertions(+), 18 deletions(-) create mode 100644 soh/soh/Enhancements/speechsynthesizer/SpeechLogger.cpp create mode 100644 soh/soh/Enhancements/speechsynthesizer/SpeechLogger.h create mode 100644 soh/soh/resource/importer/RawJsonFactory.cpp create mode 100644 soh/soh/resource/importer/RawJsonFactory.h create mode 100644 soh/soh/resource/type/RawJson.cpp create mode 100644 soh/soh/resource/type/RawJson.h diff --git a/soh/soh/Enhancements/speechsynthesizer/SpeechLogger.cpp b/soh/soh/Enhancements/speechsynthesizer/SpeechLogger.cpp new file mode 100644 index 000000000..a47a61d62 --- /dev/null +++ b/soh/soh/Enhancements/speechsynthesizer/SpeechLogger.cpp @@ -0,0 +1,16 @@ +#include "SpeechLogger.h" +#include + +SpeechLogger::SpeechLogger() { +} + +void SpeechLogger::Speak(const char* text, const char* language) { + lusprintf(__FILE__, __LINE__, 2, "Spoken Text (%s): %s", language, text); +} + +bool SpeechLogger::DoInit() { + return true; +} + +void SpeechLogger::DoUninitialize() { +} diff --git a/soh/soh/Enhancements/speechsynthesizer/SpeechLogger.h b/soh/soh/Enhancements/speechsynthesizer/SpeechLogger.h new file mode 100644 index 000000000..3be27945f --- /dev/null +++ b/soh/soh/Enhancements/speechsynthesizer/SpeechLogger.h @@ -0,0 +1,17 @@ +#ifndef SOHSpeechLogger_h +#define SOHSpeechLogger_h + +#include "SpeechSynthesizer.h" + +class SpeechLogger : public SpeechSynthesizer { + public: + SpeechLogger(); + + void Speak(const char* text, const char* language); + + protected: + bool DoInit(void); + void DoUninitialize(void); +}; + +#endif diff --git a/soh/soh/Enhancements/speechsynthesizer/SpeechSynthesizer.h b/soh/soh/Enhancements/speechsynthesizer/SpeechSynthesizer.h index b08aab05c..29d209b5f 100644 --- a/soh/soh/Enhancements/speechsynthesizer/SpeechSynthesizer.h +++ b/soh/soh/Enhancements/speechsynthesizer/SpeechSynthesizer.h @@ -36,3 +36,5 @@ class SpeechSynthesizer { #elif defined(__APPLE__) #include "DarwinSpeechSynthesizer.h" #endif + +#include "SpeechLogger.h" diff --git a/soh/soh/Enhancements/tts/tts.cpp b/soh/soh/Enhancements/tts/tts.cpp index ff78fd0ab..f4b498815 100644 --- a/soh/soh/Enhancements/tts/tts.cpp +++ b/soh/soh/Enhancements/tts/tts.cpp @@ -11,6 +11,8 @@ #include "message_data_static.h" #include "overlays/gamestates/ovl_file_choose/file_choose.h" #include "soh/Enhancements/boss-rush/BossRush.h" +#include "soh/resource/type/SohResourceType.h" +#include "soh/resource/type/RawJson.h" extern "C" { extern MapData* gMapData; @@ -1037,25 +1039,22 @@ void InitTTSBank() { break; } - auto sceneFile = LUS::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->LoadFileRaw("accessibility/texts/scenes" + languageSuffix); - if (sceneFile != nullptr) { - sceneMap = nlohmann::json::parse(*sceneFile->Buffer.get(), nullptr, true, true); - } + auto initData = std::make_shared(); + initData->Format = RESOURCE_FORMAT_BINARY; + initData->Type = static_cast(SOH::ResourceType::SOH_RawJson); + initData->ResourceVersion = 0; - auto miscFile = LUS::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->LoadFileRaw("accessibility/texts/misc" + languageSuffix); - if (miscFile != nullptr) { - miscMap = nlohmann::json::parse(*miscFile->Buffer.get(), nullptr, true, true); - } - - auto kaleidoFile = LUS::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->LoadFileRaw("accessibility/texts/kaleidoscope" + languageSuffix); - if (kaleidoFile != nullptr) { - kaleidoMap = nlohmann::json::parse(*kaleidoFile->Buffer.get(), nullptr, true, true); - } - - auto fileChooseFile = LUS::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->LoadFileRaw("accessibility/texts/filechoose" + languageSuffix); - if (fileChooseFile != nullptr) { - fileChooseMap = nlohmann::json::parse(*fileChooseFile->Buffer.get(), nullptr, true, true); - } + sceneMap = std::static_pointer_cast( + LUS::Context::GetInstance()->GetResourceManager()->LoadResource("accessibility/texts/scenes" + languageSuffix, true, initData))->Data; + + miscMap = std::static_pointer_cast( + LUS::Context::GetInstance()->GetResourceManager()->LoadResource("accessibility/texts/misc" + languageSuffix, true, initData))->Data; + + kaleidoMap = std::static_pointer_cast( + LUS::Context::GetInstance()->GetResourceManager()->LoadResource("accessibility/texts/kaleidoscope" + languageSuffix, true, initData))->Data; + + fileChooseMap = std::static_pointer_cast( + LUS::Context::GetInstance()->GetResourceManager()->LoadResource("accessibility/texts/filechoose" + languageSuffix, true, initData))->Data; } void RegisterOnSetGameLanguageHook() { diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 61f0e2b93..405335738 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -118,6 +118,7 @@ GameInteractorSail* GameInteractorSail::Instance; #include "soh/resource/importer/SkeletonLimbFactory.h" #include "soh/resource/importer/TextFactory.h" #include "soh/resource/importer/BackgroundFactory.h" +#include "soh/resource/importer/RawJsonFactory.h" #include "soh/config/ConfigUpdaters.h" @@ -341,6 +342,7 @@ OTRGlobals::OTRGlobals() { loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "AudioSoundFont", static_cast(SOH::ResourceType::SOH_AudioSoundFont), 2); loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "AudioSequence", static_cast(SOH::ResourceType::SOH_AudioSequence), 2); loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Background", static_cast(SOH::ResourceType::SOH_Background), 0); + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "RawJson", static_cast(SOH::ResourceType::SOH_RawJson), 0); gSaveStateMgr = std::make_shared(); gRandomizer = std::make_shared(); @@ -1109,6 +1111,9 @@ extern "C" void InitOTR() { #elif defined(_WIN32) SpeechSynthesizer::Instance = new SAPISpeechSynthesizer(); SpeechSynthesizer::Instance->Init(); +#else + SpeechSynthesizer::Instance = new SpeechLogger(); + SpeechSynthesizer::Instance->Init(); #endif #ifdef ENABLE_REMOTE_CONTROL diff --git a/soh/soh/resource/importer/RawJsonFactory.cpp b/soh/soh/resource/importer/RawJsonFactory.cpp new file mode 100644 index 000000000..4978f6f96 --- /dev/null +++ b/soh/soh/resource/importer/RawJsonFactory.cpp @@ -0,0 +1,19 @@ +#include "soh/resource/importer/RawJsonFactory.h" +#include "soh/resource/type/RawJson.h" +#include "spdlog/spdlog.h" + +namespace SOH { +std::shared_ptr ResourceFactoryBinaryRawJsonV0::ReadResource(std::shared_ptr file) { + if (!FileHasValidFormatAndReader(file)) { + return nullptr; + } + + auto rawJson = std::make_shared(file->InitData); + auto reader = std::get>(file->Reader); + + rawJson->DataSize = file->Buffer->size(); + rawJson->Data = nlohmann::json::parse(reader->ReadCString(), nullptr, true, true); + + return rawJson; +} +} // namespace SOH diff --git a/soh/soh/resource/importer/RawJsonFactory.h b/soh/soh/resource/importer/RawJsonFactory.h new file mode 100644 index 000000000..d5fa656b6 --- /dev/null +++ b/soh/soh/resource/importer/RawJsonFactory.h @@ -0,0 +1,11 @@ +#pragma once + +#include "resource/Resource.h" +#include "resource/ResourceFactoryBinary.h" + +namespace SOH { +class ResourceFactoryBinaryRawJsonV0 : public LUS::ResourceFactoryBinary { + public: + std::shared_ptr ReadResource(std::shared_ptr file) override; +}; +}; // namespace SOH diff --git a/soh/soh/resource/type/RawJson.cpp b/soh/soh/resource/type/RawJson.cpp new file mode 100644 index 000000000..3022a67ef --- /dev/null +++ b/soh/soh/resource/type/RawJson.cpp @@ -0,0 +1,14 @@ +#include "RawJson.h" + +namespace SOH { +RawJson::RawJson() : Resource(std::shared_ptr()) { +} + +void* RawJson::GetPointer() { + return &Data; +} + +size_t RawJson::GetPointerSize() { + return DataSize * sizeof(char); +} +} // namespace SOH diff --git a/soh/soh/resource/type/RawJson.h b/soh/soh/resource/type/RawJson.h new file mode 100644 index 000000000..47e0323cc --- /dev/null +++ b/soh/soh/resource/type/RawJson.h @@ -0,0 +1,20 @@ +#pragma once + +#include "resource/Resource.h" +#include + +namespace SOH { + +class RawJson : public LUS::Resource { + public: + using Resource::Resource; + + RawJson(); + + void* GetPointer() override; + size_t GetPointerSize() override; + + nlohmann::json Data; + size_t DataSize; +}; +}; // namespace SOH diff --git a/soh/soh/resource/type/SohResourceType.h b/soh/soh/resource/type/SohResourceType.h index fdf39031e..3ef4163fe 100644 --- a/soh/soh/resource/type/SohResourceType.h +++ b/soh/soh/resource/type/SohResourceType.h @@ -17,5 +17,6 @@ enum class ResourceType { SOH_AudioSequence = 0x4F534551, // OSEQ SOH_Background = 0x4F424749, // OBGI SOH_SceneCommand = 0x4F52434D, // ORCM + SOH_RawJson = 0x4A534F4E, // JSON }; } // namespace SOH From ef690e2ceb7bbc8698cda7e8a4646bb76d13a350 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Tue, 5 Mar 2024 23:09:05 -0500 Subject: [PATCH 12/15] support `LUS::Archive::LoadFileRaw` no longer being exposed (#3999) --- libultraship | 2 +- soh/soh/OTRGlobals.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libultraship b/libultraship index d70fd7de2..f79b19a73 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit d70fd7de2315388c9a99742fd6c634b2cd8be138 +Subproject commit f79b19a73293c572867eb816377d14c3dbded6e8 diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 405335738..6d025ab6f 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -872,7 +872,7 @@ OTRVersion ReadPortVersionFromOTR(std::string otrPath) { // Use a temporary archive instance to load the otr and read the version file auto archive = LUS::OtrArchive(otrPath); if (archive.Open()) { - auto t = archive.LoadFileRaw("portVersion"); + auto t = archive.LoadFile("portVersion", std::make_shared()); if (t != nullptr && t->IsLoaded) { auto stream = std::make_shared(t->Buffer->data(), t->Buffer->size()); auto reader = std::make_shared(stream); From c162af818d55d7e7e75c6931dcf5b8ab1ba4734b Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Wed, 20 Mar 2024 18:24:58 -0400 Subject: [PATCH 13/15] Fix keysanity Any Dungeon setting. (#4020) Due to a typo a few months ago, it was accidentally being ignored and treated as Anywhere. Own Dungeon may have also been doing weird things, but I'm not entirely sure. --- soh/soh/Enhancements/randomizer/3drando/fill.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/fill.cpp b/soh/soh/Enhancements/randomizer/3drando/fill.cpp index 7f424f758..a23636c91 100644 --- a/soh/soh/Enhancements/randomizer/3drando/fill.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/fill.cpp @@ -893,7 +893,7 @@ static void RandomizeDungeonItems() { std::vector overworldItems; for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { - if (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OWN_DUNGEON)) { + if (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANY_DUNGEON)) { auto dungeonKeys = FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i){return (i == dungeon->GetSmallKey()) || (i == dungeon->GetKeyRing());}); AddElementsToPool(anyDungeonItems, dungeonKeys); } else if (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OVERWORLD)) { From 0f43d5de2d5535d941f2239e71470826360d9479 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Wed, 3 Apr 2024 22:16:17 -0400 Subject: [PATCH 14/15] bump lus (gfx refactor) (#4031) --- libultraship | 2 +- soh/soh/OTRGlobals.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libultraship b/libultraship index f79b19a73..c3a699403 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit f79b19a73293c572867eb816377d14c3dbded6e8 +Subproject commit c3a699403793c9ac97733179fe078d2e2f271ee1 diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 6d025ab6f..c9cb36130 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -306,6 +306,7 @@ OTRGlobals::OTRGlobals() { context = LUS::Context::CreateUninitializedInstance("Ship of Harkinian", appShortName, "shipofharkinian.json"); context->InitLogging(); + context->InitGfxDebugger(); context->InitConfiguration(); context->InitConsoleVariables(); From fb29c827adf965016186e1919e62882624ac50bd Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Wed, 3 Apr 2024 22:17:32 -0400 Subject: [PATCH 15/15] Update BUILDING.md (#4029) --- docs/BUILDING.md | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/docs/BUILDING.md b/docs/BUILDING.md index d4ba07f3c..6c9222242 100644 --- a/docs/BUILDING.md +++ b/docs/BUILDING.md @@ -123,34 +123,27 @@ zypper in clang libstdc++-devel git cmake ninja SDL2-devel libpng16-devel libzip _Note: If you're using Visual Studio Code, the [CMake Tools plugin](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools) makes it very easy to just press run and debug._ ```bash -# Clone the repo +# Clone the repo and enter the directory git clone https://github.com/HarbourMasters/Shipwright.git cd Shipwright + # Clone the submodules git submodule update --init -# Copy the baserom to the OTRExporter folder -cp OTRExporter + # Generate Ninja project cmake -H. -Bbuild-cmake -GNinja # -DCMAKE_BUILD_TYPE:STRING=Release (if you're packaging) -DPython3_EXECUTABLE=$(which python3) (if you are using non-standard Python installations such as PyEnv) -# Extract assets & generate OTR (run this anytime you need to regenerate OTR) -cmake --build build-cmake --target ExtractAssets + +# Generate soh.otr +cmake --build build-cmake --target GenerateSohOtr + # Compile the project cmake --build build-cmake # --config Release (if you're packaging) # Now you can run the executable in ./build-cmake/soh/soh.elf # To develop the project open the repository in VSCode (or your preferred editor) - -# If you need to clean the project you can run -cmake --build build-cmake --target clean - -# If you need to regenerate the asset headers to check them into source -cmake --build build-cmake --target ExtractAssetHeaders - -# If you need a newer soh.otr only -cmake --build build-cmake --target GenerateSohOtr ``` -### Generating a distributable +### Generate a distributable After compiling the project you can generate a distributable by running of the following: ```bash # Go to build folder @@ -161,6 +154,20 @@ cpack -G ZIP cpack -G External (creates appimage) ``` +### Additional CMake Targets +#### Clean +```bash +# If you need to clean the project you can run +cmake --build build-cmake --target clean +``` + +#### Regenerate Asset Headers +```bash +# If you need to regenerate the asset headers to check them into source +cp OTRExporter +cmake --build build-cmake --target ExtractAssetHeaders +``` + ## macOS Requires Xcode (or xcode-tools) && `sdl2, libpng, glew, ninja, cmake` (can be installed via homebrew, macports, etc)