diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 000000000..fa68703b2 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,99 @@ +pipeline { + + environment { + MSBUILD='C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\Msbuild\\Current\\Bin\\msbuild.exe' + CONFIG='Release' + OTRPLATFORM='x64' + PLATFORM='x86' + ZIP='C:\\Program Files\\7-Zip\\7z.exe' + PYTHON='C:\\Users\\jenkins\\AppData\\Local\\Programs\\Python\\Python310\\python.exe' + TOOLSET='v142' + EMAILTO='' + } + + agent { + label 'SoH-Builders' + } + + options { + timestamps() + timeout(time: 15, unit: 'MINUTES') + skipDefaultCheckout(true) + } + + stages { + + stage ('Checkout') { + steps { + checkout([ + $class: 'GitSCM', + branches: scm.branches, + doGenerateSubmoduleConfigurations: scm.doGenerateSubmoduleConfigurations, + extensions: scm.extensions, + userRemoteConfigs: scm.userRemoteConfigs + ]) + } + } + + stage ('Build OTRExporter') { + steps { + bat """ + + "${env.MSBUILD}" ".\\OTRExporter\\OTRExporter.sln" -t:restore,build -p:Configuration=${env.CONFIG};Platform=${env.OTRPLATFORM};PlatformToolset=${env.TOOLSET};RestorePackagesConfig=true /nodeReuse:false + + """ + } + } + + stage ('Extract assets') { + steps { + bat """ + + xcopy "..\\..\\ZELOOTD.z64" "OTRExporter\\" + + cd "OTRExporter" + "${env.PYTHON}" ".\\extract_assets.py" + cd "${env.WORKSPACE}" + + """ + } + } + + stage ('Build SoH') { + steps { + bat """ + + "${env.MSBUILD}" ".\\soh\\soh.sln" -t:build -p:Configuration=${env.CONFIG};Platform=${env.PLATFORM};PlatformToolset=${env.TOOLSET} /nodeReuse:false + + """ + } + } + + stage ('Archive artifacts') { + steps { + bat """ + + "${env.ZIP}" a "soh.zip" ".\\soh\\Release\\soh.exe" + + """ + + archiveArtifacts allowEmptyArchive: false, + artifacts: 'soh.zip', + caseSensitive: true, + defaultExcludes: true, + fingerprint: false, + onlyIfSuccessful: true + } + } + } + + post { + always { + step([$class: 'Mailer', + notifyEveryUnstableBuild: true, + recipients: "${env.EMAILTO}", + sendToIndividuals: false]) + step([$class: 'WsCleanup']) // Clean workspace + } + } +} diff --git a/ZAPDTR/ZAPD/ZText.cpp b/ZAPDTR/ZAPD/ZText.cpp index 58af61bc9..2e9e0f68a 100644 --- a/ZAPDTR/ZAPD/ZText.cpp +++ b/ZAPDTR/ZAPD/ZText.cpp @@ -12,6 +12,7 @@ REGISTER_ZFILENODE(Text, ZText); ZText::ZText(ZFile* nParent) : ZResource(nParent) { RegisterRequiredAttribute("CodeOffset"); + RegisterOptionalAttribute("LangOffset", "0"); } void ZText::ParseRawData() @@ -20,6 +21,16 @@ void ZText::ParseRawData() const auto& rawData = parent->GetRawData(); uint32_t currentPtr = StringHelper::StrToL(registeredAttributes.at("CodeOffset").value, 16); + uint32_t langPtr = currentPtr; + bool isPalLang = false; + + if (StringHelper::StrToL(registeredAttributes.at("LangOffset").value, 16) != 0) + { + langPtr = StringHelper::StrToL(registeredAttributes.at("LangOffset").value, 16); + + if (langPtr != currentPtr) + isPalLang = true; + } std::vector codeData; @@ -34,8 +45,18 @@ void ZText::ParseRawData() msgEntry.id = BitConverter::ToInt16BE(codeData, currentPtr + 0); msgEntry.textboxType = (codeData[currentPtr + 2] & 0xF0) >> 4; msgEntry.textboxYPos = (codeData[currentPtr + 2] & 0x0F); - msgEntry.segmentId = (codeData[currentPtr + 4]); - msgEntry.msgOffset = BitConverter::ToInt32BE(codeData, currentPtr + 4) & 0x00FFFFFF; + + if (isPalLang) + { + msgEntry.segmentId = (codeData[langPtr + 0]); + msgEntry.msgOffset = BitConverter::ToInt32BE(codeData, langPtr + 0) & 0x00FFFFFF; + } + else + { + msgEntry.segmentId = (codeData[langPtr + 4]); + msgEntry.msgOffset = BitConverter::ToInt32BE(codeData, langPtr + 4) & 0x00FFFFFF; + } + uint32_t msgPtr = msgEntry.msgOffset; unsigned char c = rawData[msgPtr]; @@ -82,6 +103,11 @@ void ZText::ParseRawData() break; currentPtr += 8; + + if (isPalLang) + langPtr += 4; + else + langPtr += 8; } int bp2 = 0; diff --git a/libultraship/libultraship/GameSettings.cpp b/libultraship/libultraship/GameSettings.cpp index 932233eed..62de92f37 100644 --- a/libultraship/libultraship/GameSettings.cpp +++ b/libultraship/libultraship/GameSettings.cpp @@ -1,4 +1,4 @@ -#include "GameSettings.h" +#include "GameSettings.h" // Audio #include @@ -14,6 +14,7 @@ #include "../../soh/include/z64audio.h" #include #include "SohHooks.h" +#include "../../soh/soh/Enhancements/debugconsole.h" #include "Window.h" @@ -34,14 +35,13 @@ namespace Game { void UpdateAudio() { - Audio_SetGameVolume(SEQ_BGM_MAIN, Settings.audio.music_main); - Audio_SetGameVolume(SEQ_BGM_SUB, Settings.audio.music_sub); - Audio_SetGameVolume(SEQ_FANFARE, Settings.audio.fanfare); - Audio_SetGameVolume(SEQ_SFX, Settings.audio.sfx); + Audio_SetGameVolume(SEQ_BGM_MAIN, CVar_GetFloat("gMainMusicVolume", 1)); + Audio_SetGameVolume(SEQ_BGM_SUB, CVar_GetFloat("gSubMusicVolume", 1)); + Audio_SetGameVolume(SEQ_FANFARE, CVar_GetFloat("gSFXMusicVolume", 1)); + Audio_SetGameVolume(SEQ_SFX, CVar_GetFloat("gFanfareVolume", 1)); } void LoadSettings() { - const std::shared_ptr pConf = GlobalCtx2::GetInstance()->GetConfig(); ConfigFile& Conf = *pConf; @@ -50,119 +50,6 @@ namespace Game { Settings.debug.menu_bar = stob(Conf[ConfSection]["menu_bar"]); Settings.debug.soh = stob(Conf[ConfSection]["soh_debug"]); - Settings.debug.n64mode = stob(Conf[ConfSection]["n64_mode"]); - - // Enhancements - Settings.enhancements.skip_text = stob(Conf[EnhancementSection]["skip_text"]); - CVar_SetS32("gSkipText", Settings.enhancements.skip_text); - - Settings.enhancements.text_speed = Ship::stoi(Conf[EnhancementSection]["text_speed"]); - CVar_SetS32("gTextSpeed", Settings.enhancements.text_speed); - - Settings.enhancements.disable_lod = stob(Conf[EnhancementSection]["disable_lod"]); - CVar_SetS32("gDisableLOD", Settings.enhancements.disable_lod); - - Settings.enhancements.animated_pause_menu = stob(Conf[EnhancementSection]["animated_pause_menu"]); - CVar_SetS32("gPauseLiveLink", Settings.enhancements.animated_pause_menu); - - Settings.enhancements.dynamic_wallet_icon = stob(Conf[EnhancementSection]["dynamic_wallet_icon"]); - CVar_SetS32("gDynamicWalletIcon", Settings.enhancements.dynamic_wallet_icon); - - Settings.enhancements.minimal_ui = stob(Conf[EnhancementSection]["minimal_ui"]); - CVar_SetS32("gMinimalUI", Settings.enhancements.minimal_ui); - - Settings.enhancements.visualagony = stob(Conf[EnhancementSection]["visualagony"]); - CVar_SetS32("gVisualAgony", Settings.enhancements.visualagony); - - Settings.enhancements.mm_bunny_hood = stob(Conf[EnhancementSection]["mm_bunny_hood"]); - CVar_SetS32("gMMBunnyHood", Settings.enhancements.mm_bunny_hood); - - Settings.enhancements.uniform_lr = stob(Conf[EnhancementSection]["uniform_lr"]); - //CVar_SetS32("gUniformLR", Settings.enhancements.uniform_lr); - CVar_SetS32("gUniformLR", 1); - - Settings.enhancements.newdrops = stob(Conf[EnhancementSection]["newdrops"]); - CVar_SetS32("gNewDrops", Settings.enhancements.newdrops); - - // Audio - Settings.audio.master = Ship::stof(Conf[AudioSection]["master"]); - CVar_SetFloat("gGameMasterVolume", Settings.audio.master); - - Settings.audio.music_main = Ship::stof(Conf[AudioSection]["music_main"]); - CVar_SetFloat("gMainMusicVolume", Settings.audio.music_main); - - Settings.audio.music_sub = Ship::stof(Conf[AudioSection]["music_sub"]); - CVar_SetFloat("gSubMusicVolume", Settings.audio.music_sub); - - Settings.audio.sfx = Ship::stof(Conf[AudioSection]["sfx"]); - CVar_SetFloat("gSFXMusicVolume", Settings.audio.sfx); - - Settings.audio.fanfare = Ship::stof(Conf[AudioSection]["fanfare"]); - CVar_SetFloat("gFanfareVolume", Settings.audio.fanfare); - - // Controllers - Settings.controller.rumble_enabled = Ship::stof(Conf[ControllerSection]["rumble_enabled"]); - CVar_SetS32("gRumbleEnabled", Settings.controller.rumble_enabled); - - Settings.controller.input_scale = Ship::stof(Conf[ControllerSection]["input_scale"]); - CVar_SetFloat("gInputScale", Settings.controller.input_scale); - - Settings.controller.input_enabled = stob(Conf[ControllerSection]["input_enabled"]); - - CVar_SetS32("gInputEnabled", Settings.controller.input_enabled); - - Settings.controller.dpad_pause_name = stob(Conf[ControllerSection]["dpad_pause_name"]); - CVar_SetS32("gDpadPauseName", Settings.controller.dpad_pause_name); - - Settings.controller.dpad_ocarina_text = stob(Conf[ControllerSection]["dpad_ocarina_text"]); - CVar_SetS32("gDpadOcarinaText", Settings.controller.dpad_ocarina_text); - - Settings.controller.dpad_shop = stob(Conf[ControllerSection]["dpad_shop"]); - CVar_SetS32("gDpadShop", Settings.controller.dpad_shop); - - // Cheats - Settings.cheats.debug_mode = stob(Conf[CheatSection]["debug_mode"]); - CVar_SetS32("gDebugEnabled", Settings.cheats.debug_mode); - - Settings.cheats.infinite_money = stob(Conf[CheatSection]["infinite_money"]); - CVar_SetS32("gInfiniteMoney", Settings.cheats.infinite_money); - - Settings.cheats.infinite_health = stob(Conf[CheatSection]["infinite_health"]); - CVar_SetS32("gInfiniteHealth", Settings.cheats.infinite_health); - - Settings.cheats.infinite_ammo = stob(Conf[CheatSection]["infinite_ammo"]); - CVar_SetS32("gInfiniteAmmo", Settings.cheats.infinite_ammo); - - Settings.cheats.infinite_magic = stob(Conf[CheatSection]["infinite_magic"]); - CVar_SetS32("gInfiniteMagic", Settings.cheats.infinite_magic); - - Settings.cheats.infinite_nayru = stob(Conf[CheatSection]["infinite_nayru"]); - CVar_SetS32("gInfiniteNayru", Settings.cheats.infinite_nayru); - - Settings.cheats.no_clip = stob(Conf[CheatSection]["no_clip"]); - CVar_SetS32("gNoClip", Settings.cheats.no_clip); - - Settings.cheats.climb_everything = stob(Conf[CheatSection]["climb_everything"]); - CVar_SetS32("gClimbEverything", Settings.cheats.climb_everything); - - Settings.cheats.moon_jump_on_l = stob(Conf[CheatSection]["moon_jump_on_l"]); - CVar_SetS32("gMoonJumpOnL", Settings.cheats.moon_jump_on_l); - - Settings.cheats.super_tunic = stob(Conf[CheatSection]["super_tunic"]); - CVar_SetS32("gSuperTunic", Settings.cheats.super_tunic); - - Settings.cheats.ez_isg = stob(Conf[CheatSection]["ez_isg"]); - CVar_SetS32("gEzISG", Settings.cheats.ez_isg); - - Settings.cheats.no_restrict_item = stob(Conf[CheatSection]["no_restrict_item"]); - CVar_SetS32("gNoRestrictItems", Settings.cheats.no_restrict_item); - - Settings.cheats.freeze_time = stob(Conf[CheatSection]["freeze_time"]); - CVar_SetS32("gFreezeTime", Settings.cheats.freeze_time); - - // Per-Controller - LoadPadSettings(); - UpdateAudio(); } @@ -173,10 +60,6 @@ namespace Game { for (const auto& [i, controllers] : Ship::Window::Controllers) { for (const auto& controller : controllers) { if (auto padConfSection = controller->GetPadConfSection()) { - Settings.controller.extra[i].gyro_sensitivity = Ship::stof(Conf[*padConfSection]["gyro_sensitivity"]); - Settings.controller.extra[i].rumble_strength = Ship::stof(Conf[*padConfSection]["rumble_strength"]); - Settings.controller.extra[i].gyro_drift_x = Ship::stof(Conf[*padConfSection]["gyro_drift_x"], 0.0f); - Settings.controller.extra[i].gyro_drift_y = Ship::stof(Conf[*padConfSection]["gyro_drift_y"], 0.0f); } } } @@ -190,60 +73,9 @@ namespace Game { Conf[ConfSection]["console"] = std::to_string(SohImGui::console->opened); Conf[ConfSection]["menu_bar"] = std::to_string(Settings.debug.menu_bar); Conf[ConfSection]["soh_debug"] = std::to_string(Settings.debug.soh); - Conf[ConfSection]["n64_mode"] = std::to_string(Settings.debug.n64mode); - - // Audio - Conf[AudioSection]["master"] = std::to_string(Settings.audio.master); - Conf[AudioSection]["music_main"] = std::to_string(Settings.audio.music_main); - Conf[AudioSection]["music_sub"] = std::to_string(Settings.audio.music_sub); - Conf[AudioSection]["sfx"] = std::to_string(Settings.audio.sfx); - Conf[AudioSection]["fanfare"] = std::to_string(Settings.audio.fanfare); - - // Enhancements - Conf[EnhancementSection]["skip_text"] = std::to_string(Settings.enhancements.skip_text); - Conf[EnhancementSection]["text_speed"] = std::to_string(Settings.enhancements.text_speed); - Conf[EnhancementSection]["disable_lod"] = std::to_string(Settings.enhancements.disable_lod); - Conf[EnhancementSection]["animated_pause_menu"] = std::to_string(Settings.enhancements.animated_pause_menu); - Conf[EnhancementSection]["dynamic_wallet_icon"] = std::to_string(Settings.enhancements.dynamic_wallet_icon); - Conf[EnhancementSection]["minimal_ui"] = std::to_string(Settings.enhancements.minimal_ui); - Conf[EnhancementSection]["newdrops"] = std::to_string(Settings.enhancements.newdrops); - Conf[EnhancementSection]["visualagony"] = std::to_string(Settings.enhancements.visualagony); - Conf[EnhancementSection]["mm_bunny_hood"] = std::to_string(Settings.enhancements.mm_bunny_hood); - Conf[EnhancementSection]["uniform_lr"] = std::to_string(Settings.enhancements.uniform_lr); - - - // Controllers - Conf[ControllerSection]["rumble_enabled"] = std::to_string(Settings.controller.rumble_enabled); - Conf[ControllerSection]["input_scale"] = std::to_string(Settings.controller.input_scale); - Conf[ControllerSection]["input_enabled"] = std::to_string(Settings.controller.input_enabled); - Conf[ControllerSection]["dpad_pause_name"] = std::to_string(Settings.controller.dpad_pause_name); - Conf[ControllerSection]["dpad_ocarina_text"] = std::to_string(Settings.controller.dpad_ocarina_text); - Conf[ControllerSection]["dpad_shop"] = std::to_string(Settings.controller.dpad_shop); - - // Cheats - Conf[CheatSection]["debug_mode"] = std::to_string(Settings.cheats.debug_mode); - Conf[CheatSection]["infinite_money"] = std::to_string(Settings.cheats.infinite_money); - Conf[CheatSection]["infinite_health"] = std::to_string(Settings.cheats.infinite_health); - Conf[CheatSection]["infinite_ammo"] = std::to_string(Settings.cheats.infinite_ammo); - Conf[CheatSection]["infinite_magic"] = std::to_string(Settings.cheats.infinite_magic); - Conf[CheatSection]["no_clip"] = std::to_string(Settings.cheats.no_clip); - Conf[CheatSection]["climb_everything"] = std::to_string(Settings.cheats.climb_everything); - Conf[CheatSection]["moon_jump_on_l"] = std::to_string(Settings.cheats.moon_jump_on_l); - Conf[CheatSection]["super_tunic"] = std::to_string(Settings.cheats.super_tunic); - - // Per-Controller - for (const auto& [i, controllers] : Ship::Window::Controllers) { - for (const auto& controller : controllers) { - if (auto padConfSection = controller->GetPadConfSection()) { - Conf[*padConfSection]["gyro_sensitivity"] = std::to_string(Settings.controller.extra[i].gyro_sensitivity); - Conf[*padConfSection]["rumble_strength"] = std::to_string(Settings.controller.extra[i].rumble_strength); - Conf[*padConfSection]["gyro_drift_x"] = std::to_string(Settings.controller.extra[i].gyro_drift_x); - Conf[*padConfSection]["gyro_drift_y"] = std::to_string(Settings.controller.extra[i].gyro_drift_y); - } - } - } Conf.Save(); + DebugConsole_SaveCVars(); } void InitSettings() { @@ -255,4 +87,4 @@ namespace Game { void SetSeqPlayerVolume(SeqPlayers playerId, float volume) { Audio_SetGameVolume(playerId, volume); } -} +} \ No newline at end of file diff --git a/libultraship/libultraship/GameSettings.h b/libultraship/libultraship/GameSettings.h index 17a9eb86f..947689cd5 100644 --- a/libultraship/libultraship/GameSettings.h +++ b/libultraship/libultraship/GameSettings.h @@ -1,74 +1,23 @@ -#pragma once + +#pragma once struct SoHConfigType { // Debug struct { bool soh = false; - bool n64mode = false; bool menu_bar = false; bool soh_sink = true; } debug; - // Audio - struct { - float master = 1.0f; - float music_main = 1.0f; - float fanfare = 1.0f; - float sfx = 1.0f; - float music_sub = 1.0f; - } audio; - - // Enhancements - struct { - int text_speed = 1; - bool skip_text = false; - bool disable_lod = false; - bool animated_pause_menu = false; - bool dynamic_wallet_icon = false; - bool minimal_ui = false; - bool newdrops = false; - bool visualagony = false; - bool mm_bunny_hood = false; - bool uniform_lr = true; - } enhancements; - - // Controller - struct { - struct { - float gyro_sensitivity = 1.0f; - float rumble_strength = 1.0f; - float gyro_drift_x = 0.0f; - float gyro_drift_y = 0.0f; - } extra[4]; - bool rumble_enabled = true; - float input_scale = 1.0f; - bool input_enabled = false; - bool dpad_pause_name = false; - bool dpad_ocarina_text = false; - bool dpad_shop = false; - } controller; - - // Cheats - struct { - bool debug_mode = false; - bool infinite_money = false; - bool infinite_health = false; - bool infinite_ammo = false; - bool infinite_magic = false; - bool infinite_nayru = false; - bool no_clip = false; - bool climb_everything = false; - bool moon_jump_on_l = false; - bool super_tunic = false; - bool ez_isg = false; - bool no_restrict_item = false; - bool freeze_time = false; - } cheats; - // Graphics struct { bool show = false; } graphics; + + //Interface editor + struct { + bool uiedit = false; + } cosmetics; }; enum SeqPlayers { @@ -93,4 +42,4 @@ namespace Game { void LoadPadSettings(); void SaveSettings(); void SetSeqPlayerVolume(SeqPlayers playerId, float volume); -} +} \ No newline at end of file diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_opengl.cpp b/libultraship/libultraship/Lib/Fast3D/gfx_opengl.cpp index 6f3017c15..6c5f47577 100644 --- a/libultraship/libultraship/Lib/Fast3D/gfx_opengl.cpp +++ b/libultraship/libultraship/Lib/Fast3D/gfx_opengl.cpp @@ -610,6 +610,7 @@ static void gfx_opengl_init(void) { glGenBuffers(1, &opengl_vbo); glBindBuffer(GL_ARRAY_BUFFER, opengl_vbo); + glEnable(GL_DEPTH_CLAMP); glDepthFunc(GL_LEQUAL); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -775,8 +776,13 @@ static std::map, uint16_t> gfx_opengl_get_pixel_depth(in res.emplace(*coordinates.begin(), (depth_stencil_value >> 18) << 2); } else { if (pixel_depth_rb_size < coordinates.size()) { + // Resizing a renderbuffer seems broken with Intel's driver, so recreate one instead. + glBindFramebuffer(GL_FRAMEBUFFER, pixel_depth_fb); + glDeleteRenderbuffers(1, &pixel_depth_rb); + glGenRenderbuffers(1, &pixel_depth_rb); glBindRenderbuffer(GL_RENDERBUFFER, pixel_depth_rb); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, coordinates.size(), 1); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, pixel_depth_rb); glBindRenderbuffer(GL_RENDERBUFFER, 0); pixel_depth_rb_size = coordinates.size(); @@ -813,6 +819,7 @@ static std::map, uint16_t> gfx_opengl_get_pixel_depth(in } glBindFramebuffer(GL_FRAMEBUFFER, current_framebuffer); + return res; } diff --git a/libultraship/libultraship/SDLController.cpp b/libultraship/libultraship/SDLController.cpp index 267607048..50bc5eabb 100644 --- a/libultraship/libultraship/SDLController.cpp +++ b/libultraship/libultraship/SDLController.cpp @@ -5,6 +5,8 @@ #include "spdlog/spdlog.h" #include "stox.h" #include "Window.h" +#include "Cvar.h" +#include extern "C" uint8_t __osMaxControllers; @@ -188,15 +190,15 @@ namespace Ship { if (SDL_GameControllerHasSensor(Cont, SDL_SENSOR_GYRO)) { size_t contNumber = GetControllerNumber(); - float& gyro_drift_x = Game::Settings.controller.extra[contNumber].gyro_drift_x; - float& gyro_drift_y = Game::Settings.controller.extra[contNumber].gyro_drift_y; - const float gyro_sensitivity = Game::Settings.controller.extra[contNumber].gyro_sensitivity; - + float gyroData[3]; SDL_GameControllerGetSensorData(Cont, SDL_SENSOR_GYRO, gyroData, 3); const char* contName = SDL_GameControllerName(Cont); const int isSpecialController = !strcmp("PS5 Controller", contName); + float gyro_drift_x = CVar_GetFloat(StringHelper::Sprintf("gCont%i_GyroDriftX", contNumber).c_str(), 0.0f); + float gyro_drift_y = CVar_GetFloat(StringHelper::Sprintf("gCont%i_GyroDriftY", contNumber).c_str(), 0.0f); + const float gyro_sensitivity = CVar_GetFloat(StringHelper::Sprintf("gCont%i_GyroSensitivity", contNumber).c_str(), 1.0f); if (gyro_drift_x == 0) { gyro_drift_x = gyroData[0]; @@ -211,6 +213,9 @@ namespace Ship { } } + CVar_SetFloat(StringHelper::Sprintf("gCont%i_GyroDriftX", contNumber).c_str(), gyro_drift_x); + CVar_SetFloat(StringHelper::Sprintf("gCont%i_GyroDriftY", contNumber).c_str(), gyro_drift_y); + if (isSpecialController == 1) { wGyroX = gyroData[0] - gyro_drift_x; wGyroY = -gyroData[2] - gyro_drift_y; @@ -344,7 +349,7 @@ namespace Ship { { if (SDL_GameControllerHasRumble(Cont)) { if (controller->rumble > 0) { - float rumble_strength = Game::Settings.controller.extra[GetControllerNumber()].rumble_strength; + float rumble_strength = CVar_GetFloat(StringHelper::Sprintf("gCont%i_RumbleStrength", GetControllerNumber()).c_str(), 1.0f); SDL_GameControllerRumble(Cont, 0xFFFF * rumble_strength, 0xFFFF * rumble_strength, 0); } else { SDL_GameControllerRumble(Cont, 0, 0, 0); @@ -412,11 +417,6 @@ namespace Ship { std::shared_ptr pConf = GlobalCtx2::GetInstance()->GetConfig(); ConfigFile& Conf = *pConf.get(); - Conf[ConfSection]["gyro_sensitivity"] = std::to_string(1.0f); - Conf[ConfSection]["rumble_strength"] = std::to_string(1.0f); - Conf[ConfSection]["gyro_drift_x"] = std::to_string(0.0f); - Conf[ConfSection]["gyro_drift_y"] = std::to_string(0.0f); - Conf.Save(); } diff --git a/libultraship/libultraship/SohImGuiImpl.cpp b/libultraship/libultraship/SohImGuiImpl.cpp index e61608377..f174cbf20 100644 --- a/libultraship/libultraship/SohImGuiImpl.cpp +++ b/libultraship/libultraship/SohImGuiImpl.cpp @@ -56,26 +56,7 @@ namespace SohImGui { Console* console = new Console; bool p_open = false; bool needs_save = false; - float kokiri_col[3] = { 0.118f, 0.41f, 0.106f }; - float goron_col[3] = { 0.392f, 0.078f, 0.0f }; - float zora_col[3] = { 0.0f, 0.235f, 0.392f }; - - float navi_idle_i_col[3] = { 0.0f, 0.0f, 0.0f }; - float navi_idle_o_col[3] = { 0.0f, 0.0f, 0.0f }; - - float navi_npc_i_col[3] = { 0.0f, 0.0f, 0.0f }; - float navi_npc_o_col[3] = { 0.0f, 0.0f, 0.0f }; - - float navi_enemy_i_col[3] = { 0.0f, 0.0f, 0.0f }; - float navi_enemy_o_col[3] = { 0.0f, 0.0f, 0.0f }; - - float navi_prop_i_col[3] = { 0.0f, 0.0f, 0.0f }; - float navi_prop_o_col[3] = { 0.0f, 0.0f, 0.0f }; - - std::map> windowCategories; - std::map customWindows; - - //Custom color menu vars init + int SelectedHUD = CVar_GetS32("gHudColors", 1); //Default colors to Gamecube. float hearts_colors[3] = {0,0,0}; float hearts_dd_colors[3] = {0,0,0}; float a_btn_colors[3] = {0,0,0}; @@ -87,6 +68,20 @@ namespace SohImGui { float magic_use_colors[3] = {0,0,0}; float minimap_colors[3] = {0,0,0}; float rupee_colors[3] = {0,0,0}; + float kokiri_col[3] = { 0.118f, 0.41f, 0.106f }; + float goron_col[3] = { 0.392f, 0.078f, 0.0f }; + float zora_col[3] = { 0.0f, 0.235f, 0.392f }; + float navi_idle_i_col[3] = { 0.0f, 0.0f, 0.0f }; + float navi_idle_o_col[3] = { 0.0f, 0.0f, 0.0f }; + float navi_npc_i_col[3] = { 0.0f, 0.0f, 0.0f }; + float navi_npc_o_col[3] = { 0.0f, 0.0f, 0.0f }; + float navi_enemy_i_col[3] = { 0.0f, 0.0f, 0.0f }; + float navi_enemy_o_col[3] = { 0.0f, 0.0f, 0.0f }; + float navi_prop_i_col[3] = { 0.0f, 0.0f, 0.0f }; + float navi_prop_o_col[3] = { 0.0f, 0.0f, 0.0f }; + + std::map> windowCategories; + std::map customWindows; void ImGuiWMInit() { switch (impl.backend) { @@ -97,6 +92,7 @@ namespace SohImGui { ImGui_ImplWin32_Init(impl.dx11.window); break; } + } void ImGuiBackendInit() { @@ -202,78 +198,6 @@ namespace SohImGui { stbi_image_free(img_data); } - void LoadCosmeticColors(){//This function is necessary as without it IMGui wont load the updated float array. - hearts_colors[0] = (float)CVar_GetS32("gCCHeartsPrimR", 255)/255; - hearts_colors[1] = (float)CVar_GetS32("gCCHeartsPrimG", 10)/255; - hearts_colors[2] = (float)CVar_GetS32("gCCHeartsPrimB", 10)/255; - hearts_dd_colors[0] = (float)CVar_GetS32("gDDCCHeartsPrimR", 255)/255; - hearts_dd_colors[1] = (float)CVar_GetS32("gDDCCHeartsPrimG", 255)/255; - hearts_dd_colors[2] = (float)CVar_GetS32("gDDCCHeartsPrimB", 255)/255; - a_btn_colors[0] = (float)CVar_GetS32("gCCABtnPrimR", 90)/255; - a_btn_colors[1] = (float)CVar_GetS32("gCCABtnPrimG", 90)/255; - a_btn_colors[2] = (float)CVar_GetS32("gCCABtnPrimB", 255)/255; - b_btn_colors[0] = (float)CVar_GetS32("gCCBBtnPrimR", 0)/255; - b_btn_colors[1] = (float)CVar_GetS32("gCCBBtnPrimG", 150)/255; - b_btn_colors[2] = (float)CVar_GetS32("gCCBBtnPrimB", 0)/255; - c_btn_colors[0] = (float)CVar_GetS32("gCCCBtnPrimR", 255)/255; - c_btn_colors[1] = (float)CVar_GetS32("gCCCBtnPrimG", 160)/255; - c_btn_colors[2] = (float)CVar_GetS32("gCCCBtnPrimB", 0)/255; - start_btn_colors[0] = (float)CVar_GetS32("gCCStartBtnPrimR", 120)/255; - start_btn_colors[1] = (float)CVar_GetS32("gCCStartBtnPrimG", 120)/255; - start_btn_colors[2] = (float)CVar_GetS32("gCCStartBtnPrimB", 120)/255; - magic_border_colors[0] = (float)CVar_GetS32("gCCMagicBorderPrimR", 255)/255; - magic_border_colors[1] = (float)CVar_GetS32("gCCMagicBorderPrimG", 255)/255; - magic_border_colors[2] = (float)CVar_GetS32("gCCMagicBorderPrimB", 255)/255; - magic_remaining_colors[0] = (float)CVar_GetS32("gCCMagicPrimR", 250)/255; - magic_remaining_colors[1] = (float)CVar_GetS32("gCCMagicPrimG", 250)/255; - magic_remaining_colors[2] = (float)CVar_GetS32("gCCMagicPrimB", 0)/255; - magic_remaining_colors[0] = (float)CVar_GetS32("gCCMagicUsePrimR", 0)/255; - magic_remaining_colors[1] = (float)CVar_GetS32("gCCMagicUsePrimG", 200)/255; - magic_remaining_colors[2] = (float)CVar_GetS32("gCCMagicUsePrimB", 0)/255; - minimap_colors[0] = (float)CVar_GetS32("gCCMinimapPrimR", 0)/255; - minimap_colors[1] = (float)CVar_GetS32("gCCMinimapPrimG", 255)/255; - minimap_colors[2] = (float)CVar_GetS32("gCCMinimapPrimB", 255)/255; - rupee_colors[0] = (float)CVar_GetS32("gCCRupeePrimR", 120)/255; - rupee_colors[1] = (float)CVar_GetS32("gCCRupeePrimG", 120)/255; - rupee_colors[2] = (float)CVar_GetS32("gCCRupeePrimB", 120)/255; - kokiri_col[0] = (float)CVar_GetS32("gTunic_Kokiri_R", 30)/255; - kokiri_col[1] = (float)CVar_GetS32("gTunic_Kokiri_G", 105)/255; - kokiri_col[2] = (float)CVar_GetS32("gTunic_Kokiri_B", 27)/255; - kokiri_col[1] = (float)CVar_GetS32("gTunic_Kokiri_G", 105)/255; - kokiri_col[2] = (float)CVar_GetS32("gTunic_Kokiri_B", 27)/255; - zora_col[0] = (float)CVar_GetS32("gTunic_Zora_R", 0)/255; - zora_col[1] = (float)CVar_GetS32("gTunic_Zora_G", 60)/255; - zora_col[2] = (float)CVar_GetS32("gTunic_Zora_B", 100)/255; - navi_idle_i_col[0] = (float)CVar_GetS32("gNavi_Idle_Inner_R", 255)/255; - navi_idle_i_col[1] = (float)CVar_GetS32("gNavi_Idle_Inner_G", 255)/255; - navi_idle_i_col[2] = (float)CVar_GetS32("gNavi_Idle_Inner_B", 255)/255; - navi_idle_o_col[0] = (float)CVar_GetS32("gNavi_Idle_Outer_R", 115)/255; - navi_idle_o_col[1] = (float)CVar_GetS32("gNavi_Idle_Outer_G", 230)/255; - navi_idle_o_col[2] = (float)CVar_GetS32("gNavi_Idle_Outer_B", 255)/255; - navi_npc_i_col[0] = (float)CVar_GetS32("gNavi_NPC_Inner_R", 100)/255; - navi_npc_i_col[1] = (float)CVar_GetS32("gNavi_NPC_Inner_G", 100)/255; - navi_npc_i_col[2] = (float)CVar_GetS32("gNavi_NPC_Inner_B", 255)/255; - navi_npc_o_col[0] = (float)CVar_GetS32("gNavi_NPC_Outer_R", 90)/255; - navi_npc_o_col[1] = (float)CVar_GetS32("gNavi_NPC_Outer_G", 90)/255; - navi_npc_o_col[2] = (float)CVar_GetS32("gNavi_NPC_Outer_B", 255)/255; - navi_enemy_i_col[0] = (float)CVar_GetS32("gNavi_Enemy_Inner_R", 255)/255; - navi_enemy_i_col[1] = (float)CVar_GetS32("gNavi_Enemy_Inner_G", 255)/255; - navi_enemy_i_col[2] = (float)CVar_GetS32("gNavi_Enemy_Inner_B", 0)/255; - navi_enemy_o_col[0] = (float)CVar_GetS32("gNavi_Enemy_Outer_R", 220)/255; - navi_enemy_o_col[1] = (float)CVar_GetS32("gNavi_Enemy_Outer_G", 220)/255; - navi_enemy_o_col[2] = (float)CVar_GetS32("gNavi_Enemy_Outer_B", 0)/255; - navi_prop_i_col[0] = (float)CVar_GetS32("gNavi_Prop_Inner_R", 0)/255; - navi_prop_i_col[1] = (float)CVar_GetS32("gNavi_Prop_Inner_G", 255)/255; - navi_prop_i_col[2] = (float)CVar_GetS32("gNavi_Prop_Inner_B", 0)/255; - navi_prop_o_col[0] = (float)CVar_GetS32("gNavi_Prop_Outer_R", 0)/255; - navi_prop_o_col[1] = (float)CVar_GetS32("gNavi_Prop_Outer_G", 220)/255; - navi_prop_o_col[2] = (float)CVar_GetS32("gNavi_Prop_Outer_B", 0)/255; - } - - int ClampFloatToInt(float value, int min, int max){ - return fmin(fmax(value,min),max); - } - void LoadResource(const std::string& name, const std::string& path, const ImVec4& tint) { GfxRenderingAPI* api = gfx_get_current_rendering_api(); const auto res = static_cast(GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(normalize(path)).get()); @@ -318,6 +242,79 @@ namespace SohImGui { DefaultAssets[name] = asset; } + void LoadCosmeticColors(){//This function is necessary as without it IMGui wont load the updated float array. + hearts_colors[0] = (float)CVar_GetS32("gCCHeartsPrimR", 255)/255; + hearts_colors[1] = (float)CVar_GetS32("gCCHeartsPrimG", 10)/255; + hearts_colors[2] = (float)CVar_GetS32("gCCHeartsPrimB", 10)/255; + hearts_dd_colors[0] = (float)CVar_GetS32("gDDCCHeartsPrimR", 255)/255; + hearts_dd_colors[1] = (float)CVar_GetS32("gDDCCHeartsPrimG", 255)/255; + hearts_dd_colors[2] = (float)CVar_GetS32("gDDCCHeartsPrimB", 255)/255; + a_btn_colors[0] = (float)CVar_GetS32("gCCABtnPrimR", 90)/255; + a_btn_colors[1] = (float)CVar_GetS32("gCCABtnPrimG", 90)/255; + a_btn_colors[2] = (float)CVar_GetS32("gCCABtnPrimB", 255)/255; + b_btn_colors[0] = (float)CVar_GetS32("gCCBBtnPrimR", 0)/255; + b_btn_colors[1] = (float)CVar_GetS32("gCCBBtnPrimG", 150)/255; + b_btn_colors[2] = (float)CVar_GetS32("gCCBBtnPrimB", 0)/255; + c_btn_colors[0] = (float)CVar_GetS32("gCCCBtnPrimR", 255)/255; + c_btn_colors[1] = (float)CVar_GetS32("gCCCBtnPrimG", 160)/255; + c_btn_colors[2] = (float)CVar_GetS32("gCCCBtnPrimB", 0)/255; + start_btn_colors[0] = (float)CVar_GetS32("gCCStartBtnPrimR", 120)/255; + start_btn_colors[1] = (float)CVar_GetS32("gCCStartBtnPrimG", 120)/255; + start_btn_colors[2] = (float)CVar_GetS32("gCCStartBtnPrimB", 120)/255; + magic_border_colors[0] = (float)CVar_GetS32("gCCMagicBorderPrimR", 255)/255; + magic_border_colors[1] = (float)CVar_GetS32("gCCMagicBorderPrimG", 255)/255; + magic_border_colors[2] = (float)CVar_GetS32("gCCMagicBorderPrimB", 255)/255; + magic_remaining_colors[0] = (float)CVar_GetS32("gCCMagicPrimR", 250)/255; + magic_remaining_colors[1] = (float)CVar_GetS32("gCCMagicPrimG", 250)/255; + magic_remaining_colors[2] = (float)CVar_GetS32("gCCMagicPrimB", 0)/255; + magic_remaining_colors[0] = (float)CVar_GetS32("gCCMagicUsePrimR", 0)/255; + magic_remaining_colors[1] = (float)CVar_GetS32("gCCMagicUsePrimG", 200)/255; + magic_remaining_colors[2] = (float)CVar_GetS32("gCCMagicUsePrimB", 0)/255; + minimap_colors[0] = (float)CVar_GetS32("gCCMinimapPrimR", 0)/255; + minimap_colors[1] = (float)CVar_GetS32("gCCMinimapPrimG", 255)/255; + minimap_colors[2] = (float)CVar_GetS32("gCCMinimapPrimB", 255)/255; + rupee_colors[0] = (float)CVar_GetS32("gCCRupeePrimR", 120)/255; + rupee_colors[1] = (float)CVar_GetS32("gCCRupeePrimG", 120)/255; + rupee_colors[2] = (float)CVar_GetS32("gCCRupeePrimB", 120)/255; + kokiri_col[0] = (float)CVar_GetS32("gTunic_Kokiri_R", 30)/255; + kokiri_col[1] = (float)CVar_GetS32("gTunic_Kokiri_G", 105)/255; + kokiri_col[2] = (float)CVar_GetS32("gTunic_Kokiri_B", 27)/255; + goron_col[0] = (float)CVar_GetS32("gTunic_Goron_R", 100)/255; + goron_col[1] = (float)CVar_GetS32("gTunic_Goron_G", 20)/255; + goron_col[2] = (float)CVar_GetS32("gTunic_Goron_B", 0)/255; + zora_col[0] = (float)CVar_GetS32("gTunic_Zora_R", 0)/255; + zora_col[1] = (float)CVar_GetS32("gTunic_Zora_G", 60)/255; + zora_col[2] = (float)CVar_GetS32("gTunic_Zora_B", 100)/255; + navi_idle_i_col[0] = (float)CVar_GetS32("gNavi_Idle_Inner_R", 255)/255; + navi_idle_i_col[1] = (float)CVar_GetS32("gNavi_Idle_Inner_G", 255)/255; + navi_idle_i_col[2] = (float)CVar_GetS32("gNavi_Idle_Inner_B", 255)/255; + navi_idle_o_col[0] = (float)CVar_GetS32("gNavi_Idle_Outer_R", 115)/255; + navi_idle_o_col[1] = (float)CVar_GetS32("gNavi_Idle_Outer_G", 230)/255; + navi_idle_o_col[2] = (float)CVar_GetS32("gNavi_Idle_Outer_B", 255)/255; + navi_npc_i_col[0] = (float)CVar_GetS32("gNavi_NPC_Inner_R", 100)/255; + navi_npc_i_col[1] = (float)CVar_GetS32("gNavi_NPC_Inner_G", 100)/255; + navi_npc_i_col[2] = (float)CVar_GetS32("gNavi_NPC_Inner_B", 255)/255; + navi_npc_o_col[0] = (float)CVar_GetS32("gNavi_NPC_Outer_R", 90)/255; + navi_npc_o_col[1] = (float)CVar_GetS32("gNavi_NPC_Outer_G", 90)/255; + navi_npc_o_col[2] = (float)CVar_GetS32("gNavi_NPC_Outer_B", 255)/255; + navi_enemy_i_col[0] = (float)CVar_GetS32("gNavi_Enemy_Inner_R", 255)/255; + navi_enemy_i_col[1] = (float)CVar_GetS32("gNavi_Enemy_Inner_G", 255)/255; + navi_enemy_i_col[2] = (float)CVar_GetS32("gNavi_Enemy_Inner_B", 0)/255; + navi_enemy_o_col[0] = (float)CVar_GetS32("gNavi_Enemy_Outer_R", 220)/255; + navi_enemy_o_col[1] = (float)CVar_GetS32("gNavi_Enemy_Outer_G", 220)/255; + navi_enemy_o_col[2] = (float)CVar_GetS32("gNavi_Enemy_Outer_B", 0)/255; + navi_prop_i_col[0] = (float)CVar_GetS32("gNavi_Prop_Inner_R", 0)/255; + navi_prop_i_col[1] = (float)CVar_GetS32("gNavi_Prop_Inner_G", 255)/255; + navi_prop_i_col[2] = (float)CVar_GetS32("gNavi_Prop_Inner_B", 0)/255; + navi_prop_o_col[0] = (float)CVar_GetS32("gNavi_Prop_Outer_R", 0)/255; + navi_prop_o_col[1] = (float)CVar_GetS32("gNavi_Prop_Outer_G", 220)/255; + navi_prop_o_col[2] = (float)CVar_GetS32("gNavi_Prop_Outer_B", 0)/255; + } + + int ClampFloatToInt(float value, int min, int max){ + return fmin(fmax(value,min),max); + } + void Init(WindowImpl window_impl) { impl = window_impl; Game::LoadSettings(); @@ -331,7 +328,6 @@ namespace SohImGui { console->Init(); ImGuiWMInit(); ImGuiBackendInit(); - LoadCosmeticColors(); //Fill custom colors array for Cosmetics tabs ModInternal::registerHookListener({ GFX_INIT, [](const HookEvent ev) { @@ -351,10 +347,18 @@ namespace SohImGui { LoadTexture("C-Down", "assets/ship_of_harkinian/buttons/CDown.png"); } }); + for (const auto& [i, controllers] : Ship::Window::Controllers) + { + CVar_SetFloat(StringHelper::Sprintf("gCont%i_GyroDriftX", i).c_str(), 0); + CVar_SetFloat(StringHelper::Sprintf("gCont%i_GyroDriftY", i).c_str(), 0); + needs_save = true; + } + ModInternal::registerHookListener({ CONTROLLER_READ, [](const HookEvent ev) { pads = static_cast(ev->baseArgs["cont_pad"]); } }); Game::InitSettings(); + LoadCosmeticColors(); } void Update(EventImpl event) { @@ -367,31 +371,92 @@ namespace SohImGui { #define BindButton(btn, status) ImGui::Image(GetTextureByID(DefaultAssets[btn]->textureId), ImVec2(16.0f * scale, 16.0f * scale), ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, (status) ? 255 : 0)); - void BindAudioSlider(const char* name, const char* key, float* value, SeqPlayers playerId) { - ImGui::Text(name, static_cast(100 * *(value))); - if (ImGui::SliderFloat((std::string("##") + key).c_str(), value, 0.0f, 1.0f, "")) { - const float volume = floorf(*(value) * 100) / 100; + void BindAudioSlider(const char* name, const char* key, float defaultValue, SeqPlayers playerId) + { + float value = CVar_GetFloat(key, defaultValue); + + ImGui::Text(name, static_cast(100 * value)); + if (ImGui::SliderFloat((std::string("##") + key).c_str(), &value, 0.0f, 1.0f, "")) { + const float volume = floorf(value * 100) / 100; CVar_SetFloat(key, volume); needs_save = true; Game::SetSeqPlayerVolume(playerId, volume); } } - void EnhancementColorEdit3(std::string text, std::string cvarName, float ColorRGB[3]) { - if (ImGui::ColorEdit3(text.c_str(), ColorRGB)) { - CVar_SetS32((cvarName+"R").c_str(), ClampFloatToInt(ColorRGB[0]*255,0,255)); - CVar_SetS32((cvarName+"G").c_str(), ClampFloatToInt(ColorRGB[1]*255,0,255)); - CVar_SetS32((cvarName+"B").c_str(), ClampFloatToInt(ColorRGB[2]*255,0,255)); + void EnhancementCheckbox(std::string text, std::string cvarName) + { + bool val = (bool)CVar_GetS32(cvarName.c_str(), 0); + if (ImGui::Checkbox(text.c_str(), &val)) { + CVar_SetS32(cvarName.c_str(), val); needs_save = true; } } - void EnhancementCheckbox(std::string text, std::string cvarName) { - bool val = (bool)CVar_GetS32(cvarName.c_str(), 0); - if (ImGui::Checkbox(text.c_str(), &val)) { + void EnhancementSliderInt(std::string text, std::string id, std::string cvarName, int min, int max, std::string format) + { + int val = CVar_GetS32(cvarName.c_str(), 0); + + ImGui::Text(text.c_str(), val); + + if (ImGui::SliderInt(id.c_str(), &val, min, max, format.c_str())) + { CVar_SetS32(cvarName.c_str(), val); needs_save = true; } + + if (val < min) + { + val = min; + CVar_SetS32(cvarName.c_str(), val); + needs_save = true; + } + + if (val > max) + { + val = max; + CVar_SetS32(cvarName.c_str(), val); + needs_save = true; + } + } + + void EnhancementSliderFloat(std::string text, std::string id, std::string cvarName, float min, float max, std::string format, float defaultValue, bool isPercentage) + { + float val = CVar_GetFloat(cvarName.c_str(), defaultValue); + + if (!isPercentage) + ImGui::Text(text.c_str(), val); + else + ImGui::Text(text.c_str(), static_cast(100 * val)); + + if (ImGui::SliderFloat(id.c_str(), &val, min, max, format.c_str())) + { + CVar_SetFloat(cvarName.c_str(), val); + needs_save = true; + } + + if (val < min) + { + val = min; + CVar_SetFloat(cvarName.c_str(), val); + needs_save = true; + } + + if (val > max) + { + val = max; + CVar_SetFloat(cvarName.c_str(), val); + needs_save = true; + } + } + + void EnhancementColor3(std::string text, std::string cvarName, float ColorRGB[3]) { + if (ImGui::ColorEdit3(text.c_str(), ColorRGB)) { + CVar_SetS32((cvarName+"R").c_str(), ClampFloatToInt(ColorRGB[0]*255,0,255)); + CVar_SetS32((cvarName+"G").c_str(), ClampFloatToInt(ColorRGB[1]*255,0,255)); + CVar_SetS32((cvarName+"B").c_str(), ClampFloatToInt(ColorRGB[2]*255,0,255)); + needs_save = true; + } } void DrawMainMenuAndCalculateGameSize() { @@ -449,224 +514,127 @@ namespace SohImGui { ImGui::Separator(); if (ImGui::BeginMenu("Audio")) { - const float volume = Game::Settings.audio.master; - ImGui::Text("Master Volume: %d %%", static_cast(100 * volume)); - if (ImGui::SliderFloat("##Master_Vol", &Game::Settings.audio.master, 0.0f, 1.0f, "")) { - CVar_SetFloat("gGameMasterVolume", volume); - needs_save = true; - } + EnhancementSliderFloat("Master Volume: %d %%", "##Master_Vol", "gGameMasterVolume", 0.0f, 1.0f, "", 1.0f, true); - BindAudioSlider("Main Music Volume: %d %%", "gMainMusicVolume", &Game::Settings.audio.music_main, SEQ_BGM_MAIN); - BindAudioSlider("Sub Music Volume: %d %%", "gSubMusicVolume", &Game::Settings.audio.music_sub, SEQ_BGM_SUB); - BindAudioSlider("Sound Effects Volume: %d %%", "gSFXMusicVolume", &Game::Settings.audio.sfx, SEQ_SFX); - BindAudioSlider("Fanfare Volume: %d %%", "gFanfareVolume", &Game::Settings.audio.fanfare, SEQ_FANFARE); + BindAudioSlider("Main Music Volume: %d %%", "gMainMusicVolume", 1.0f, SEQ_BGM_MAIN); + BindAudioSlider("Sub Music Volume: %d %%", "gSubMusicVolume", 1.0f, SEQ_BGM_SUB); + BindAudioSlider("Sound Effects Volume: %d %%", "gSFXMusicVolume", 1.0f, SEQ_SFX); + BindAudioSlider("Fanfare Volume: %d %%", "gFanfareVolume", 1.0f, SEQ_FANFARE); ImGui::EndMenu(); } - if (ImGui::BeginMenu("Controller")) { - for (const auto& [i, controllers] : Ship::Window::Controllers) { + if (ImGui::BeginMenu("Controller")) + { + for (const auto& [i, controllers] : Ship::Window::Controllers) + { bool hasPad = std::find_if(controllers.begin(), controllers.end(), [](const auto& c) { return c->HasPadConf() && c->Connected(); - }) != controllers.end(); + }) != controllers.end(); - if (!hasPad) continue; + if (!hasPad) continue; - auto menuLabel = "Controller " + std::to_string(i + 1); - if (ImGui::BeginMenu(menuLabel.c_str())) { - ImGui::Text("Gyro Sensitivity: %d %%", static_cast(100 * Game::Settings.controller.extra[i].gyro_sensitivity)); - if (ImGui::SliderFloat("##GYROSCOPE", &Game::Settings.controller.extra[i].gyro_sensitivity, 0.0f, 1.0f, "")) { - needs_save = true; + auto menuLabel = "Controller " + std::to_string(i + 1); + if (ImGui::BeginMenu(menuLabel.c_str())) + { + EnhancementSliderFloat("Gyro Sensitivity: %d %%", "##GYROSCOPE", StringHelper::Sprintf("gCont%i_GyroSensitivity", i), 0.0f, 1.0f, "", 1.0f, true); + + if (ImGui::Button("Recalibrate Gyro")) + { + CVar_SetFloat(StringHelper::Sprintf("gCont%i_GyroDriftX", i).c_str(), 0); + CVar_SetFloat(StringHelper::Sprintf("gCont%i_GyroDriftY", i).c_str(), 0); + needs_save = true; + } + + ImGui::Separator(); + + EnhancementSliderFloat("Rumble Strength: %d %%", "##RUMBLE", StringHelper::Sprintf("gCont%i_RumbleStrength", i), 0.0f, 1.0f, "", 1.0f, true); + + ImGui::EndMenu(); } - - if (ImGui::Button("Recalibrate Gyro")) { - Game::Settings.controller.extra[i].gyro_drift_x = 0; - Game::Settings.controller.extra[i].gyro_drift_y = 0; - needs_save = true; - } - ImGui::Separator(); - - ImGui::Text("Rumble Strength: %d %%", static_cast(100 * Game::Settings.controller.extra[i].rumble_strength)); - if (ImGui::SliderFloat("##RUMBLE", &Game::Settings.controller.extra[i].rumble_strength, 0.0f, 1.0f, "")) { - needs_save = true; - } - - ImGui::EndMenu(); - } } + EnhancementCheckbox("Show Inputs", "gInputEnabled"); + EnhancementCheckbox("Rumble Enabled", "gRumbleEnabled"); + + EnhancementSliderFloat("Input Scale: %.1f", "##Input", "gInputScale", 1.0f, 3.0f, "", 1.0f, false); + ImGui::Separator(); - if (ImGui::Checkbox("Rumble Enabled", &Game::Settings.controller.rumble_enabled)) { - CVar_SetS32("gRumbleEnabled", Game::Settings.controller.rumble_enabled); - needs_save = true; - } - - if (ImGui::Checkbox("Show Inputs", &Game::Settings.controller.input_enabled)) { - needs_save = true; - } - - ImGui::Text("Input Scale: %.1f", Game::Settings.controller.input_scale); - if (ImGui::SliderFloat("##Input", &Game::Settings.controller.input_scale, 1.0f, 3.0f, "")) { - needs_save = true; - } - - ImGui::Separator(); - - if (ImGui::Checkbox("Dpad Support on Pause and File Select", &Game::Settings.controller.dpad_pause_name)) { - CVar_SetS32("gDpadPauseName", Game::Settings.controller.dpad_pause_name); - needs_save = true; - } - - if (ImGui::Checkbox("DPad Support in Ocarina and Text Choice", &Game::Settings.controller.dpad_ocarina_text)) { - CVar_SetS32("gDpadOcarinaText", Game::Settings.controller.dpad_ocarina_text); - needs_save = true; - } - - if (ImGui::Checkbox("DPad Support for Browsing Shop Items", &Game::Settings.controller.dpad_shop)) { - CVar_SetS32("gDpadShop", Game::Settings.controller.dpad_shop); - needs_save = true; - } + EnhancementCheckbox("Dpad Support on Pause and File Select", "gDpadPauseName"); + EnhancementCheckbox("DPad Support in Ocarina and Text Choice", "gDpadOcarinaText"); + EnhancementCheckbox("DPad Support for Browsing Shop Items", "gDpadShop"); ImGui::EndMenu(); } - if (ImGui::BeginMenu("Enhancements")) { + if (ImGui::BeginMenu("Enhancements")) + { ImGui::Text("Gameplay"); ImGui::Separator(); - ImGui::Text("Text Speed: %dx", Game::Settings.enhancements.text_speed); - if (ImGui::SliderInt("##TEXTSPEED", &Game::Settings.enhancements.text_speed, 1, 5, "")) { - CVar_SetS32("gTextSpeed", Game::Settings.enhancements.text_speed); - needs_save = true; - } + EnhancementSliderInt("Text Speed: %dx", "##TEXTSPEED", "gTextSpeed", 1, 5, ""); - if (ImGui::Checkbox("Skip Text", &Game::Settings.enhancements.skip_text)) { - CVar_SetS32("gSkipText", Game::Settings.enhancements.skip_text); - needs_save = true; - } - - if (ImGui::Checkbox("Minimal UI", &Game::Settings.enhancements.minimal_ui)) { - CVar_SetS32("gMinimalUI", Game::Settings.enhancements.minimal_ui); - needs_save = true; - } - - if (ImGui::Checkbox("MM Bunny Hood", &Game::Settings.enhancements.mm_bunny_hood)) { - CVar_SetS32("gMMBunnyHood", Game::Settings.enhancements.mm_bunny_hood); - needs_save = true; - } - - /*if (ImGui::Checkbox("Fix L&R Pause menu", &Game::Settings.enhancements.uniform_lr)) { - CVar_SetS32("gUniformLR", Game::Settings.enhancements.uniform_lr); - needs_save = true; - }*/ - - if (ImGui::Checkbox("Visual Stone of Agony", &Game::Settings.enhancements.visualagony)) { - CVar_SetS32("gVisualAgony", Game::Settings.enhancements.visualagony); - needs_save = true; - } + EnhancementCheckbox("Skip Text", "gSkipText"); + EnhancementCheckbox("Minimal UI", "gMinimalUI"); + EnhancementCheckbox("MM Bunny Hood", "gMMBunnyHood"); + EnhancementCheckbox("Visual Stone of Agony", "gVisualAgony"); ImGui::Text("Graphics"); ImGui::Separator(); - HOOK(ImGui::Checkbox("N64 Mode", &Game::Settings.debug.n64mode)); + EnhancementCheckbox("N64 Mode", "gN64Mode"); - if (ImGui::Checkbox("Animated Link in Pause Menu", &Game::Settings.enhancements.animated_pause_menu)) { - CVar_SetS32("gPauseLiveLink", Game::Settings.enhancements.animated_pause_menu); - needs_save = true; - } - - if (ImGui::Checkbox("Disable LOD", &Game::Settings.enhancements.disable_lod)) { - CVar_SetS32("gDisableLOD", Game::Settings.enhancements.disable_lod); - needs_save = true; - } - - if (ImGui::Checkbox("Enable 3D Dropped items", &Game::Settings.enhancements.newdrops)) { - CVar_SetS32("gNewDrops", Game::Settings.enhancements.newdrops); - needs_save = true; - } - - if (ImGui::Checkbox("Dynamic Wallet Icon", &Game::Settings.enhancements.dynamic_wallet_icon)) { - CVar_SetS32("gDynamicWalletIcon", Game::Settings.enhancements.dynamic_wallet_icon); - - needs_save = true; - } + EnhancementCheckbox("Animated Link in Pause Menu", "gPauseLiveLink"); + EnhancementCheckbox("Disable LOD", "gDisableLOD"); + EnhancementCheckbox("Enable 3D Dropped items", "gNewDrops"); + EnhancementCheckbox("Dynamic Wallet Icon", "gDynamicWalletIcon"); ImGui::EndMenu(); } - ImGui::EndMenuBar(); - - if (ImGui::BeginMenu("Developer Tools")) { + if (ImGui::BeginMenu("Developer Tools")) + { HOOK(ImGui::MenuItem("Stats", nullptr, &Game::Settings.debug.soh)); HOOK(ImGui::MenuItem("Console", nullptr, &console->opened)); ImGui::Text("Debug"); ImGui::Separator(); - if (ImGui::Checkbox("Debug Mode", &Game::Settings.cheats.debug_mode)) { - CVar_SetS32("gDebugEnabled", Game::Settings.cheats.debug_mode); - needs_save = true; - } + EnhancementCheckbox("Debug Mode", "gDebugEnabled"); ImGui::EndMenu(); } - if (ImGui::BeginMenu("Graphics")) { + if (ImGui::BeginMenu("Graphics")) + { HOOK(ImGui::MenuItem("Anti-aliasing", nullptr, &Game::Settings.graphics.show)); ImGui::EndMenu(); } - if (ImGui::BeginMenu("Cheats")) { + if (ImGui::BeginMenu("Cheats")) + { if (ImGui::BeginMenu("Infinite...")) { - if (ImGui::Checkbox("Money", &Game::Settings.cheats.infinite_money)) { - CVar_SetS32("gInfiniteMoney", Game::Settings.cheats.infinite_money); - needs_save = true; - } + EnhancementCheckbox("Money", "gInfiniteMoney"); + EnhancementCheckbox("Health", "gInfiniteHealth"); + EnhancementCheckbox("Ammo", "gInfiniteAmmo"); + EnhancementCheckbox("Magic", "gInfiniteMagic"); + EnhancementCheckbox("Nayru's Love", "gInfiniteNayru"); - if (ImGui::Checkbox("Health", &Game::Settings.cheats.infinite_health)) { - CVar_SetS32("gInfiniteHealth", Game::Settings.cheats.infinite_health); - needs_save = true; - } - - if (ImGui::Checkbox("Ammo", &Game::Settings.cheats.infinite_ammo)) { - CVar_SetS32("gInfiniteAmmo", Game::Settings.cheats.infinite_ammo); - needs_save = true; - } - - if (ImGui::Checkbox("Magic", &Game::Settings.cheats.infinite_magic)) { - CVar_SetS32("gInfiniteMagic", Game::Settings.cheats.infinite_magic); - needs_save = true; - } - - if (ImGui::Checkbox("Nayru's Love", &Game::Settings.cheats.infinite_nayru)) { - CVar_SetS32("gInfiniteNayru", Game::Settings.cheats.infinite_nayru); - needs_save = true; - } ImGui::EndMenu(); } - if (ImGui::Checkbox("No Clip", &Game::Settings.cheats.no_clip)) { - CVar_SetS32("gNoClip", Game::Settings.cheats.no_clip); - needs_save = true; - } + EnhancementCheckbox("No Clip", "gNoClip"); + EnhancementCheckbox("Climb Everything", "gClimbEverything"); + EnhancementCheckbox("Moon Jump on L", "gMoonJumpOnL"); + EnhancementCheckbox("Super Tunic", "gSuperTunic"); + EnhancementCheckbox("Easy ISG", "gEzISG"); + EnhancementCheckbox("Unrestricted Items", "gNoRestrictItems"); + EnhancementCheckbox("Freeze Time", "gFreezeTime"); - if (ImGui::Checkbox("Climb Everything", &Game::Settings.cheats.climb_everything)) { - CVar_SetS32("gClimbEverything", Game::Settings.cheats.climb_everything); - needs_save = true; - } - - if (ImGui::Checkbox("Moon Jump on L", &Game::Settings.cheats.moon_jump_on_l)) { - CVar_SetS32("gMoonJumpOnL", Game::Settings.cheats.moon_jump_on_l); - needs_save = true; - } - - if (ImGui::Checkbox("Super Tunic", &Game::Settings.cheats.super_tunic)) { - CVar_SetS32("gSuperTunic", Game::Settings.cheats.super_tunic); - needs_save = true; - } + ImGui::EndMenu(); } if (CVar_GetS32("gHudColors", 1) ==0) { @@ -678,23 +646,25 @@ namespace SohImGui { } if (ImGui::BeginMenu("Cosmetics")) { if (ImGui::BeginMenu("Tunics")) { - EnhancementColorEdit3("Kokiri Tunic", "gTunic_Kokiri_", kokiri_col); - EnhancementColorEdit3("Goron Tunic", "gTunic_Goron_", goron_col); - EnhancementColorEdit3("Zora Tunic", "gTunic_Zora_", zora_col); + EnhancementCheckbox("Custom colors on tunics", "gUseTunicsCol"); + EnhancementColor3("Kokiri Tunic", "gTunic_Kokiri_", kokiri_col); + EnhancementColor3("Goron Tunic", "gTunic_Goron_", goron_col); + EnhancementColor3("Zora Tunic", "gTunic_Zora_", zora_col); ImGui::EndMenu(); } if (ImGui::BeginMenu("Navi")) { - EnhancementColorEdit3("Navi Idle Inner", "gNavi_Idle_Inner_", navi_idle_i_col); - EnhancementColorEdit3("Navi Idle Outer", "gNavi_Idle_Outer_", navi_idle_o_col); + EnhancementCheckbox("Custom colors for Navi", "gUseNaviCol"); + EnhancementColor3("Navi Idle Inner", "gNavi_Idle_Inner_", navi_idle_i_col); + EnhancementColor3("Navi Idle Outer", "gNavi_Idle_Outer_", navi_idle_o_col); ImGui::Separator(); - EnhancementColorEdit3("Navi NPC Inner", "gNavi_NPC_Inner_", navi_npc_i_col); - EnhancementColorEdit3("Navi NPC Outer", "gNavi_NPC_Outer_", navi_npc_o_col); + EnhancementColor3("Navi NPC Inner", "gNavi_NPC_Inner_", navi_npc_i_col); + EnhancementColor3("Navi NPC Outer", "gNavi_NPC_Outer_", navi_npc_o_col); ImGui::Separator(); - EnhancementColorEdit3("Navi Enemy Inner", "gNavi_Enemy_Inner_", navi_enemy_i_col); - EnhancementColorEdit3("Navi Enemy Outer", "gNavi_Enemy_Outer_", navi_enemy_o_col); + EnhancementColor3("Navi Enemy Inner", "gNavi_Enemy_Inner_", navi_enemy_i_col); + EnhancementColor3("Navi Enemy Outer", "gNavi_Enemy_Outer_", navi_enemy_o_col); ImGui::Separator(); - EnhancementColorEdit3("Navi Prop Inner", "gNavi_Prop_Inner_", navi_prop_i_col); - EnhancementColorEdit3("Navi Prop Outer", "gNavi_Prop_Outer_", navi_prop_o_col); + EnhancementColor3("Navi Prop Inner", "gNavi_Prop_Inner_", navi_prop_i_col); + EnhancementColor3("Navi Prop Outer", "gNavi_Prop_Outer_", navi_prop_o_col); ImGui::EndMenu(); } if (ImGui::BeginMenu("Interface")) { @@ -703,54 +673,46 @@ namespace SohImGui { EnhancementRadioButton("Custom Colors", "gHudColors", 2); if (ImGui::BeginMenu("Edit HUD Colors")) { if (ImGui::BeginMenu("Hearts")) { - EnhancementColorEdit3("Hearts normals", "gCCHeartsPrim", hearts_colors); - EnhancementColorEdit3("Hearts double def", "gDDCCHeartsPrim", hearts_dd_colors); + EnhancementColor3("Hearts normals", "gCCHeartsPrim", hearts_colors); + EnhancementColor3("Hearts double def", "gDDCCHeartsPrim", hearts_dd_colors); ImGui::EndMenu(); } if (ImGui::BeginMenu("Buttons")) { - EnhancementColorEdit3("A Buttons", "gCCABtnPrim", a_btn_colors); - EnhancementColorEdit3("B Buttons", "gCCBBtnPrim", b_btn_colors); - EnhancementColorEdit3("C Buttons", "gCCCBtnPrim", c_btn_colors); - EnhancementColorEdit3("Start Buttons", "gCCStartBtnPrim", start_btn_colors); + EnhancementColor3("A Buttons", "gCCABtnPrim", a_btn_colors); + EnhancementColor3("B Buttons", "gCCBBtnPrim", b_btn_colors); + EnhancementColor3("C Buttons", "gCCCBtnPrim", c_btn_colors); + EnhancementColor3("Start Buttons", "gCCStartBtnPrim", start_btn_colors); ImGui::EndMenu(); } if (ImGui::BeginMenu("Magic Bar")) { - EnhancementColorEdit3("Magic bar borders", "gCCMagicBorderPrim", magic_border_colors); - EnhancementColorEdit3("Magic bar main color", "gCCMagicPrim", magic_remaining_colors); - EnhancementColorEdit3("Magic bar being used", "gCCMagicUsePrim", magic_use_colors); + EnhancementColor3("Magic bar borders", "gCCMagicBorderPrim", magic_border_colors); + EnhancementColor3("Magic bar main color", "gCCMagicPrim", magic_remaining_colors); + EnhancementColor3("Magic bar being used", "gCCMagicUsePrim", magic_use_colors); ImGui::EndMenu(); } if (ImGui::BeginMenu("Misc")) { - EnhancementColorEdit3("Minimap color", "gCCMinimapPrim", minimap_colors); - EnhancementColorEdit3("Rupee icon color", "gCCRupeePrim", rupee_colors); + EnhancementColor3("Minimap color", "gCCMinimapPrim", minimap_colors); + EnhancementColor3("Rupee icon color", "gCCRupeePrim", rupee_colors); ImGui::EndMenu(); } ImGui::EndMenu(); } + HOOK(ImGui::MenuItem("Interface edit", nullptr, &Game::Settings.cosmetics.uiedit)); ImGui::EndMenu(); } ImGui::EndMenu(); } - if (ImGui::BeginMenu("Developer Tools")) { - HOOK(ImGui::MenuItem("Stats", nullptr, &Game::Settings.debug.soh)); - HOOK(ImGui::MenuItem("Console", nullptr, &console->opened)); - if (ImGui::Checkbox("Easy ISG", &Game::Settings.cheats.ez_isg)) { - CVar_SetS32("gEzISG", Game::Settings.cheats.ez_isg); - needs_save = true; - } - - if (ImGui::Checkbox("Unrestricted Items", &Game::Settings.cheats.no_restrict_item)) { - CVar_SetS32("gNoRestrictItems", Game::Settings.cheats.no_restrict_item); - needs_save = true; - } - - if (ImGui::Checkbox("Freeze Time", &Game::Settings.cheats.freeze_time)) { - CVar_SetS32("gFreezeTime", Game::Settings.cheats.freeze_time); - needs_save = true; - } - - ImGui::EndMenu(); + if (Game::Settings.cosmetics.uiedit) { + ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0)); + ImGui::Begin("Interface modifier", nullptr, ImGuiWindowFlags_None); + EnhancementCheckbox("Use margins", "gHUDMargins"); + EnhancementSliderInt("Top : %dx", "##UIMARGINT", "gHUDMargin_T", -20, 20, ""); + EnhancementSliderInt("Left: %dx", "##UIMARGINL", "gHUDMargin_L", -25, 25, ""); + EnhancementSliderInt("Right: %dx", "##UIMARGINR", "gHUDMargin_R", -25, 25, ""); + EnhancementSliderInt("Bottom: %dx", "##UIMARGINB", "gHUDMargin_B", -20, 20, ""); + ImGui::End(); + ImGui::PopStyleColor(); } for (const auto& category : windowCategories) { @@ -818,7 +780,9 @@ namespace SohImGui { gfx_current_game_window_viewport.y = main_pos.y; gfx_current_game_window_viewport.width = size.x; gfx_current_game_window_viewport.height = size.y; - if (Game::Settings.debug.n64mode) { + + if (CVar_GetS32("gN64Mode", 0)) + { gfx_current_dimensions.width = 320; gfx_current_dimensions.height = 240; const int sw = size.y * 320 / 240; @@ -833,7 +797,7 @@ namespace SohImGui { ImVec2 main_pos = ImGui::GetWindowPos(); ImVec2 size = ImGui::GetContentRegionAvail(); ImVec2 pos = ImVec2(0, 0); - if (Game::Settings.debug.n64mode) { + if (CVar_GetS32("gN64Mode", 0)) { const int sw = size.y * 320 / 240; pos = ImVec2(size.x / 2 - sw / 2, 0); size = ImVec2(sw, size.y); @@ -848,10 +812,10 @@ namespace SohImGui { ImGui::End(); - const float scale = Game::Settings.controller.input_scale; + const float scale = CVar_GetFloat("gInputScale", 1.0f); ImVec2 BtnPos = ImVec2(160 * scale, 85 * scale); - if (Game::Settings.controller.input_enabled) { + if (CVar_GetS32("gInputEnabled", 0)) { ImGui::SetNextWindowSize(BtnPos); ImGui::SetNextWindowPos(ImVec2(main_pos.x + size.x - BtnPos.x - 20, main_pos.y + size.y - BtnPos.y - 20)); @@ -936,4 +900,4 @@ namespace SohImGui { ImTextureID GetTextureByName(const std::string& name) { return GetTextureByID(DefaultAssets[name]->textureId); } -} +} \ No newline at end of file diff --git a/libultraship/libultraship/SohImGuiImpl.h b/libultraship/libultraship/SohImGuiImpl.h index 93750432a..2e7aa773c 100644 --- a/libultraship/libultraship/SohImGuiImpl.h +++ b/libultraship/libultraship/SohImGuiImpl.h @@ -60,10 +60,15 @@ namespace SohImGui { extern Console* console; void Init(WindowImpl window_impl); void Update(EventImpl event); + void EnhancementColorEdit3(std::string text, std::string cvarName, float ColorRGB[3]); - void EnhancementCheckbox(std::string text, std::string cvarName); int ClampFloatToInt(float value, int min, int max); + void EnhancementCheckbox(std::string text, std::string cvarName); + void EnhancementSliderInt(std::string text, std::string id, std::string cvarName, int min, int max, std::string format); + void EnhancementSliderFloat(std::string text, std::string id, std::string cvarName, float min, float max, std::string format, float defaultValue); + void DrawMainMenuAndCalculateGameSize(void); + void DrawFramebufferAndGameInput(void); void Render(void); void CancelFrame(void); diff --git a/libultraship/libultraship/Window.cpp b/libultraship/libultraship/Window.cpp index 2b57c547e..0feb7229f 100644 --- a/libultraship/libultraship/Window.cpp +++ b/libultraship/libultraship/Window.cpp @@ -275,8 +275,11 @@ namespace Ship { WmApi->set_keyboard_callbacks(Window::KeyDown, Window::KeyUp, Window::AllKeysUp); } - void Window::RunCommands(Gfx* Commands) { + void Window::StartFrame() { gfx_start_frame(); + } + + void Window::RunCommands(Gfx* Commands) { gfx_run(Commands); gfx_end_frame(); } diff --git a/libultraship/libultraship/Window.h b/libultraship/libultraship/Window.h index 0d12211b0..b075e496f 100644 --- a/libultraship/libultraship/Window.h +++ b/libultraship/libultraship/Window.h @@ -18,6 +18,7 @@ namespace Ship { ~Window(); void MainLoop(void (*MainFunction)(void)); void Init(); + void StartFrame(); void RunCommands(Gfx* Commands); void SetFrameDivisor(int divisor); void GetPixelDepthPrepare(float x, float y); diff --git a/soh/assets/xml/GC_NMQ_D/text/message_data_static.xml b/soh/assets/xml/GC_NMQ_D/text/message_data_static.xml new file mode 100644 index 000000000..223493596 --- /dev/null +++ b/soh/assets/xml/GC_NMQ_D/text/message_data_static.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/soh/assets/xml/GC_NMQ_D/text/nes_message_data_static.xml b/soh/assets/xml/GC_NMQ_D/text/nes_message_data_static.xml deleted file mode 100644 index e2d39a916..000000000 --- a/soh/assets/xml/GC_NMQ_D/text/nes_message_data_static.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/soh/assets/xml/GC_NMQ_D/text/staff_message_data_static.xml b/soh/assets/xml/GC_NMQ_D/text/staff_message_data_static.xml deleted file mode 100644 index f675929e1..000000000 --- a/soh/assets/xml/GC_NMQ_D/text/staff_message_data_static.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/soh/assets/xml/GC_NMQ_PAL_F/text/message_data_static.xml b/soh/assets/xml/GC_NMQ_PAL_F/text/message_data_static.xml new file mode 100644 index 000000000..400a27e27 --- /dev/null +++ b/soh/assets/xml/GC_NMQ_PAL_F/text/message_data_static.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/soh/assets/xml/GC_NMQ_PAL_F/text/nes_message_data_static.xml b/soh/assets/xml/GC_NMQ_PAL_F/text/nes_message_data_static.xml deleted file mode 100644 index 4cf46d252..000000000 --- a/soh/assets/xml/GC_NMQ_PAL_F/text/nes_message_data_static.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/soh/assets/xml/GC_NMQ_PAL_F/text/staff_message_data_static.xml b/soh/assets/xml/GC_NMQ_PAL_F/text/staff_message_data_static.xml deleted file mode 100644 index 0a7efda81..000000000 --- a/soh/assets/xml/GC_NMQ_PAL_F/text/staff_message_data_static.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/soh/include/functions.h b/soh/include/functions.h index 13e3a7055..01901d5d0 100644 --- a/soh/include/functions.h +++ b/soh/include/functions.h @@ -656,10 +656,12 @@ Vec3s* SurfaceType_GetCamPosData(CollisionContext* colCtx, CollisionPoly* poly, u32 SurfaceType_GetSceneExitIndex(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); u32 func_80041D4C(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); u32 func_80041D70(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +u32 func_80041D94(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); s32 func_80041DB8(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); s32 func_80041DE4(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); s32 func_80041E18(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); s32 func_80041E4C(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +s32 func_80041E80(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); u32 func_80041EA4(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); u32 func_80041EC8(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); u32 SurfaceType_IsHorseBlocked(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); diff --git a/soh/include/macros.h b/soh/include/macros.h index 8563449b1..c57effe02 100644 --- a/soh/include/macros.h +++ b/soh/include/macros.h @@ -126,12 +126,12 @@ extern GraphicsContext* __gfxCtx; -#define WORK_DISP __gfxCtx->work.p -#define POLY_OPA_DISP __gfxCtx->polyOpa.p -#define POLY_XLU_DISP __gfxCtx->polyXlu.p -#define TITLE_CARD_DISP __gfxCtx->titlecard.p -#define POLY_KAL_DISP __gfxCtx->polyKal.p -#define OVERLAY_DISP __gfxCtx->overlay.p +#define WORK_DISP __gfxCtx->work.p +#define POLY_OPA_DISP __gfxCtx->polyOpa.p +#define POLY_XLU_DISP __gfxCtx->polyXlu.p +#define WORLD_OVERLAY_DISP __gfxCtx->worldOverlay.p +#define POLY_KAL_DISP __gfxCtx->polyKal.p +#define OVERLAY_DISP __gfxCtx->overlay.p // __gfxCtx shouldn't be used directly. // Use the DISP macros defined above when writing to display buffers. diff --git a/soh/include/z64.h b/soh/include/z64.h index 92966f239..f0dfba52d 100644 --- a/soh/include/z64.h +++ b/soh/include/z64.h @@ -83,7 +83,7 @@ typedef struct { /* 0x00000 */ u16 headMagic; // GFXPOOL_HEAD_MAGIC /* 0x00008 */ Gfx polyOpaBuffer[0x2FC0]; /* 0x0BF08 */ Gfx polyXluBuffer[0x1000]; - /* 0xXXXXX */ Gfx titlecardBuffer[0x1000]; + /* 0xXXXXX */ Gfx worldOverlayBuffer[0x1000]; /* 0x0BF08 */ Gfx polyKalBuffer[0x1000]; /* 0x0FF08 */ Gfx overlayBuffer[0x800]; /* 0x11F08 */ Gfx workBuffer[0x100]; @@ -131,7 +131,7 @@ typedef struct OSScTask { typedef struct GraphicsContext { /* 0x0000 */ Gfx* polyOpaBuffer; // Pointer to "Zelda 0" /* 0x0004 */ Gfx* polyXluBuffer; // Pointer to "Zelda 1" - /* 0xXXX */ Gfx* titlecardBuffer; // Pointer to "Paris" + /* 0xXXX */ Gfx* worldOverlayBuffer; // Pointer to "Paris" /* 0xXXX */ Gfx* polyKalBuffer; // Pointer to "Rome" /* 0x0008 */ char unk_008[0x08]; // Unused, could this be pointers to "Zelda 2" / "Zelda 3" /* 0x0010 */ Gfx* overlayBuffer; // Pointer to "Zelda 4" @@ -151,7 +151,7 @@ typedef struct GraphicsContext { /* 0x02A8 */ TwoHeadGfxArena overlay; // "Zelda 4" /* 0x02B8 */ TwoHeadGfxArena polyOpa; // "Zelda 0" /* 0x02C8 */ TwoHeadGfxArena polyXlu; // "Zelda 1" - /* 0x0XXX */ TwoHeadGfxArena titlecard; // When in Paris... + /* 0x0XXX */ TwoHeadGfxArena worldOverlay; // When in Paris... /* 0x0XXX */ TwoHeadGfxArena polyKal; // When in Rome... /* 0x02D8 */ u32 gfxPoolIdx; /* 0x02DC */ u16* curFrameBuffer; diff --git a/soh/soh.vcxproj b/soh/soh.vcxproj index d35dd18b3..2bd4380b9 100644 --- a/soh/soh.vcxproj +++ b/soh/soh.vcxproj @@ -175,8 +175,10 @@ + + @@ -922,8 +924,10 @@ + + diff --git a/soh/soh.vcxproj.filters b/soh/soh.vcxproj.filters index c31a78b19..a8455a4c8 100644 --- a/soh/soh.vcxproj.filters +++ b/soh/soh.vcxproj.filters @@ -2184,6 +2184,12 @@ Source Files\soh + + Source Files\soh\Enhancements\debugger + + + Source Files\soh\Enhancements\debugger + @@ -3734,6 +3740,12 @@ Header Files\soh + + Header Files\soh\Enhancements\debugger + + + Header Files\soh\Enhancements\debugger + diff --git a/soh/soh/Enhancements/debugconsole.cpp b/soh/soh/Enhancements/debugconsole.cpp index de8cab260..ff69830e7 100644 --- a/soh/soh/Enhancements/debugconsole.cpp +++ b/soh/soh/Enhancements/debugconsole.cpp @@ -327,9 +327,6 @@ static int CheckVarType(const std::string& input) return result; } -void DebugConsole_LoadCVars(); -void DebugConsole_SaveCVars(); - static bool SetCVarHandler(const std::vector& args) { if (args.size() < 3) return CMD_FAILED; diff --git a/soh/soh/Enhancements/debugconsole.h b/soh/soh/Enhancements/debugconsole.h index 21e0b51f1..581c19acd 100644 --- a/soh/soh/Enhancements/debugconsole.h +++ b/soh/soh/Enhancements/debugconsole.h @@ -1,3 +1,5 @@ #pragma once -void DebugConsole_Init(void); \ No newline at end of file +void DebugConsole_Init(void); +void DebugConsole_LoadCVars(); +void DebugConsole_SaveCVars(); \ No newline at end of file diff --git a/soh/soh/Enhancements/debugger/ImGuiHelpers.cpp b/soh/soh/Enhancements/debugger/ImGuiHelpers.cpp new file mode 100644 index 000000000..6f4f00637 --- /dev/null +++ b/soh/soh/Enhancements/debugger/ImGuiHelpers.cpp @@ -0,0 +1,21 @@ +#include "ImGuiHelpers.h" + +// Adds a text tooltip for the previous ImGui item +void SetLastItemHoverText(const std::string& text) { + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::Text(text.c_str()); + ImGui::EndTooltip(); + } +} + +// Adds a "?" next to the previous ImGui item with a custom tooltip +void InsertHelpHoverText(const std::string& text) { + ImGui::SameLine(); + ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "?"); + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::Text(text.c_str()); + ImGui::EndTooltip(); + } +} diff --git a/soh/soh/Enhancements/debugger/ImGuiHelpers.h b/soh/soh/Enhancements/debugger/ImGuiHelpers.h new file mode 100644 index 000000000..7f01e4580 --- /dev/null +++ b/soh/soh/Enhancements/debugger/ImGuiHelpers.h @@ -0,0 +1,8 @@ +#pragma once +#include "../libultraship/Lib/ImGui/imgui.h" + +#include + +void SetLastItemHoverText(const std::string& text); + +void InsertHelpHoverText(const std::string& text); diff --git a/soh/soh/Enhancements/debugger/colViewer.cpp b/soh/soh/Enhancements/debugger/colViewer.cpp new file mode 100644 index 000000000..ad9d341d4 --- /dev/null +++ b/soh/soh/Enhancements/debugger/colViewer.cpp @@ -0,0 +1,719 @@ +#include "colViewer.h" +#include "../libultraship/SohImGuiImpl.h" +#include "ImGuiHelpers.h" + +#include +#include + +extern "C" { +#include +#include "variables.h" +#include "functions.h" +#include "macros.h" +extern GlobalContext* gGlobalCtx; +} + +enum class ColRenderSetting { + Disabled, + Solid, + Transparent, + NumSettings +}; + +std::string ColRenderSettingNames[] = { + "Disabled", + "Solid", + "Transparent", +}; + +static ColRenderSetting showSceneColSetting = ColRenderSetting::Disabled; +static ColRenderSetting showBgActorSetting = ColRenderSetting::Disabled; +static ColRenderSetting showColCheckSetting = ColRenderSetting::Disabled; +static ColRenderSetting showWaterboxSetting = ColRenderSetting::Disabled; + +static uint32_t sceneColor = 0xFFFFFFFF; +static uint32_t hookshotColor = 0x8080FFFF; +static uint32_t entranceColor = 0x00FF00FF; +static uint32_t specialSurfaceColor = 0xC0FFC0FF; +static uint32_t interactableColor = 0xC000C0FF; +static uint32_t slopeColor = 0xFFFF80FF; +static uint32_t voidColor = 0xFF0000FF; + +static uint32_t ocColor = 0xFFFFFFFF; +static uint32_t acColor = 0x0000FFFF; +static uint32_t atColor = 0xFF0000FF; + +static uint32_t waterboxColor = 0x0000FFFF; + +static bool applyAsDecal = false; +static bool isShaded = false; + +static std::vector opaDl; +static std::vector xluDl; +static std::vector vtxDl; +static std::vector mtxDl; + +// These DLs contain a cylinder/sphere model scaled to 128x (to have less error) +// The idea is to push a model view matrix, then draw the DL, to draw the shape somewhere with a certain size +static std::vector cylinderGfx; +static std::vector cylinderVtx; +static std::vector sphereGfx; +static std::vector sphereVtx; + +// Create a dropdown menu to set a ColRenderSetting +void DrawColRenderSetting(const std::string& name, ColRenderSetting& setting) { + if (ImGui::BeginCombo(name.c_str(), ColRenderSettingNames[static_cast(setting)].c_str())) { + for (int32_t settingIndex = 0; settingIndex < static_cast(ColRenderSetting::NumSettings); settingIndex++) { + if (ImGui::Selectable(ColRenderSettingNames[settingIndex].c_str())) { + setting = static_cast(settingIndex); + } + } + ImGui::EndCombo(); + } +} + +// Draw a color picker box +void DrawColorPicker(const std::string& name, uint32_t& color) { + float colorAsFloat[4]; + colorAsFloat[0] = ((color >> 24) & 0xFF) / 255.0f; + colorAsFloat[1] = ((color >> 16) & 0xFF) / 255.0f; + colorAsFloat[2] = ((color >> 8) & 0xFF) / 255.0f; + colorAsFloat[3] = (color & 0xFF) / 255.0f; + if (ImGui::ColorEdit4(name.c_str(), colorAsFloat, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel)) { + color = static_cast(colorAsFloat[3] * 255) | + static_cast(colorAsFloat[2] * 255) << 8 | + static_cast(colorAsFloat[1] * 255) << 16 | + static_cast(colorAsFloat[0] * 255) << 24; + } + ImGui::SameLine(); + ImGui::Text(name.c_str()); +} + +// Draws the ImGui window for the collision viewer +void DrawColViewerWindow(bool& open) { + if (!open) { + return; + } + + ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver); + if (!ImGui::Begin("Collision Viewer", &open)) { + ImGui::End(); + return; + } + + DrawColRenderSetting("Scene", showSceneColSetting); + DrawColRenderSetting("Bg Actors", showBgActorSetting); + DrawColRenderSetting("Col Check", showColCheckSetting); + DrawColRenderSetting("Waterbox", showWaterboxSetting); + + ImGui::Checkbox("Apply as decal", &applyAsDecal); + InsertHelpHoverText("Applies the collision as a decal display. This can be useful if there is z-fighting occuring " + "with the scene geometry, but can cause other artifacts."); + ImGui::Checkbox("Shaded", &isShaded); + InsertHelpHoverText("Applies the scene's shading to the collision display."); + + // This has to be duplicated in both code paths due to the nature of ImGui::IsItemHovered() + const std::string colorHelpText = "View and change the colors used for collision display."; + if (ImGui::TreeNode("Colors")) { + InsertHelpHoverText(colorHelpText); + + DrawColorPicker("Normal", sceneColor); + DrawColorPicker("Hookshot", hookshotColor); + DrawColorPicker("Entrance", entranceColor); + DrawColorPicker("Special Surface (Grass/Sand/Etc)", specialSurfaceColor); + DrawColorPicker("Interactable (Vines/Crawlspace/Etc)", interactableColor); + DrawColorPicker("Slope", slopeColor); + DrawColorPicker("Void", voidColor); + DrawColorPicker("OC", ocColor); + DrawColorPicker("AC", acColor); + DrawColorPicker("AT", atColor); + DrawColorPicker("Waterbox", waterboxColor); + + ImGui::TreePop(); + } else { + InsertHelpHoverText(colorHelpText); + } + + ImGui::End(); +} + +// Calculates the normal for a triangle at the 3 specified points +void CalcTriNorm(const Vec3f& v1, const Vec3f& v2, const Vec3f& v3, Vec3f& norm) { + norm.x = (v2.y - v1.y) * (v3.z - v1.z) - (v2.z - v1.z) * (v3.y - v1.y); + norm.y = (v2.z - v1.z) * (v3.x - v1.x) - (v2.x - v1.x) * (v3.z - v1.z); + norm.z = (v2.x - v1.x) * (v3.y - v1.y) - (v2.y - v1.y) * (v3.x - v1.x); + float norm_d = sqrtf(norm.x * norm.x + norm.y * norm.y + norm.z * norm.z); + if (norm_d != 0.f) { + norm.x *= 127.f / norm_d; + norm.y *= 127.f / norm_d; + norm.z *= 127.f / norm_d; + } +} + +// Various macros used for creating verticies and rendering that aren't in gbi.h +#define G_CC_MODULATERGB_PRIM_ENVA PRIMITIVE, 0, SHADE, 0, 0, 0, 0, ENVIRONMENT +#define G_CC_PRIMITIVE_ENVA 0, 0, 0, PRIMITIVE, 0, 0, 0, ENVIRONMENT +#define qs105(n) ((int16_t)((n)*0x0020)) +#define gdSPDefVtxN(x, y, z, s, t, nx, ny, nz, ca) \ + { \ + .n = {.ob = { x, y, z }, .tc = { qs105(s), qs105(t) }, .n = { nx, ny, nz }, .a = ca } \ + } + + +void CreateCylinderData() { + constexpr int32_t CYL_DIVS = 12; + cylinderGfx.reserve(5 + CYL_DIVS * 2); + cylinderVtx.reserve(2 + CYL_DIVS * 2); + + cylinderVtx.push_back(gdSPDefVtxN(0, 0, 0, 0, 0, 0, -127, 0, 0xFF)); // Bottom center vertex + cylinderVtx.push_back(gdSPDefVtxN(0, 128, 0, 0, 0, 0, 127, 0, 0xFF)); // Top center vertex + // Create two rings of vertices + for (int i = 0; i < CYL_DIVS; ++i) { + short vtx_x = floorf(0.5f + cosf(2.f * M_PI * i / CYL_DIVS) * 128.f); + short vtx_z = floorf(0.5f - sinf(2.f * M_PI * i / CYL_DIVS) * 128.f); + signed char norm_x = cosf(2.f * M_PI * i / CYL_DIVS) * 127.f; + signed char norm_z = -sinf(2.f * M_PI * i / CYL_DIVS) * 127.f; + cylinderVtx.push_back(gdSPDefVtxN(vtx_x, 0, vtx_z, 0, 0, norm_x, 0, norm_z, 0xFF)); + cylinderVtx.push_back(gdSPDefVtxN(vtx_x, 128, vtx_z, 0, 0, norm_x, 0, norm_z, 0xFF)); + } + + // Draw edges + cylinderGfx.push_back(gsSPSetGeometryMode(G_CULL_BACK | G_SHADING_SMOOTH)); + cylinderGfx.push_back(gsSPVertex((uintptr_t)cylinderVtx.data(), 2 + CYL_DIVS * 2, 0)); + for (int i = 0; i < CYL_DIVS; ++i) { + int p = (i + CYL_DIVS - 1) % CYL_DIVS; + int v[4] = { + 2 + p * 2 + 0, + 2 + i * 2 + 0, + 2 + i * 2 + 1, + 2 + p * 2 + 1, + }; + cylinderGfx.push_back(gsSP2Triangles(v[0], v[1], v[2], 0, v[0], v[2], v[3], 0)); + } + + // Draw top & bottom + cylinderGfx.push_back(gsSPClearGeometryMode(G_SHADING_SMOOTH)); + for (int i = 0; i < CYL_DIVS; ++i) { + int p = (i + CYL_DIVS - 1) % CYL_DIVS; + int v[4] = { + 2 + p * 2 + 0, + 2 + i * 2 + 0, + 2 + i * 2 + 1, + 2 + p * 2 + 1, + }; + cylinderGfx.push_back(gsSP2Triangles(0, v[1], v[0], 0, 1, v[3], v[2], 0)); + } + + cylinderGfx.push_back(gsSPClearGeometryMode(G_CULL_BACK)); + cylinderGfx.push_back(gsSPEndDisplayList()); +} + +// This subdivides a face into four tris by placing new verticies at the midpoints of the sides (Like a triforce!), then blowing up the +// verticies so they are on the unit sphere +void CreateSphereFace(std::vector>& faces, int32_t v0Index, int32_t v1Index, int32_t v2Index) { + size_t nextIndex = sphereVtx.size(); + + size_t v01Index = nextIndex; + size_t v12Index = nextIndex + 1; + size_t v20Index = nextIndex + 2; + + faces.emplace_back(v0Index, v01Index, v20Index); + faces.emplace_back(v1Index, v12Index, v01Index); + faces.emplace_back(v2Index, v20Index, v12Index); + faces.emplace_back(v01Index, v12Index, v20Index); + + const Vtx& v0 = sphereVtx[v0Index]; + const Vtx& v1 = sphereVtx[v1Index]; + const Vtx& v2 = sphereVtx[v2Index]; + + // Create 3 new verticies at the midpoints + Vec3f vs[3] = { + Vec3f((v0.n.ob[0] + v1.n.ob[0]) / 2.0f, (v0.n.ob[1] + v1.n.ob[1]) / 2.0f, (v0.n.ob[2] + v1.n.ob[2]) / 2.0f), + Vec3f((v1.n.ob[0] + v2.n.ob[0]) / 2.0f, (v1.n.ob[1] + v2.n.ob[1]) / 2.0f, (v1.n.ob[2] + v2.n.ob[2]) / 2.0f), + Vec3f((v2.n.ob[0] + v0.n.ob[0]) / 2.0f, (v2.n.ob[1] + v0.n.ob[1]) / 2.0f, (v2.n.ob[2] + v0.n.ob[2]) / 2.0f) + }; + + // Normalize vertex positions so they are on the sphere + for (int32_t vAddIndex = 0; vAddIndex < 3; vAddIndex++) { + Vec3f& v = vs[vAddIndex]; + float mag = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z); + v.x /= mag; + v.y /= mag; + v.z /= mag; + sphereVtx.push_back(gdSPDefVtxN((short)(v.x * 127), (short)(v.y * 127), (short)(v.z * 127), 0, 0, + (signed char)(v.x * 127), (signed char)(v.y * 127), (signed char)(v.z * 127), + 0xFF)); + } +} + +// Creates a sphere following the idea in here: http://blog.andreaskahler.com/2009/06/creating-icosphere-mesh-in-code.html +// Spcifically, create a icosahedron by realizing that the points can be placed on 3 rectangles that are on each unit plane. +// Then, subdividing each face. +void CreateSphereData() { + std::vector base; + + float d = (1.0f + sqrtf(5.0f)) / 2.0f; + + // Create the 12 starting verticies, 4 on each rectangle + base.emplace_back(-1, d, 0); + base.emplace_back(1, d, 0); + base.emplace_back(-1, -d, 0); + base.emplace_back(1, -d, 0); + + base.emplace_back(0, -1, d); + base.emplace_back(0, 1, d); + base.emplace_back(0, -1, -d); + base.emplace_back(0, 1, -d); + + base.emplace_back(d, 0, -1); + base.emplace_back(d, 0, 1); + base.emplace_back(-d, 0, -1); + base.emplace_back(-d, 0, 1); + + // Normalize verticies so they are on the unit sphere + for (Vec3f& v : base) { + float mag = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z); + v.x /= mag; + v.y /= mag; + v.z /= mag; + sphereVtx.push_back(gdSPDefVtxN((short)(v.x * 128), (short)(v.y * 128), (short)(v.z * 128), 0, 0, + (signed char)(v.x * 127), (signed char)(v.y * 127), (signed char)(v.z * 127), + 0xFF)); + } + + std::vector> faces; + + // Subdivide faces + CreateSphereFace(faces, 0, 11, 5); + CreateSphereFace(faces, 0, 5, 1); + CreateSphereFace(faces, 0, 1, 7); + CreateSphereFace(faces, 0, 7, 10); + CreateSphereFace(faces, 0, 10, 11); + + CreateSphereFace(faces, 1, 5, 9); + CreateSphereFace(faces, 5, 11, 4); + CreateSphereFace(faces, 11, 10, 2); + CreateSphereFace(faces, 10, 7, 6); + CreateSphereFace(faces, 7, 1, 8); + + CreateSphereFace(faces, 3, 9, 4); + CreateSphereFace(faces, 3, 4, 2); + CreateSphereFace(faces, 3, 2, 6); + CreateSphereFace(faces, 3, 6, 8); + CreateSphereFace(faces, 3, 8, 9); + + CreateSphereFace(faces, 4, 9, 5); + CreateSphereFace(faces, 2, 4, 11); + CreateSphereFace(faces, 6, 2, 10); + CreateSphereFace(faces, 8, 6, 7); + CreateSphereFace(faces, 9, 8, 1); + + size_t vtxStartIndex = sphereVtx.size(); + sphereVtx.reserve(sphereVtx.size() + faces.size() * 3); + for (int32_t faceIndex = 0; faceIndex < faces.size(); faceIndex++) { + sphereVtx.push_back(sphereVtx[std::get<0>(faces[faceIndex])]); + sphereVtx.push_back(sphereVtx[std::get<1>(faces[faceIndex])]); + sphereVtx.push_back(sphereVtx[std::get<2>(faces[faceIndex])]); + sphereGfx.push_back(gsSPVertex((uintptr_t)(sphereVtx.data() + vtxStartIndex + faceIndex * 3), 3, 0)); + sphereGfx.push_back(gsSP1Triangle(0, 1, 2, 0)); + } + + sphereGfx.push_back(gsSPEndDisplayList()); +} + +void InitColViewer() { + SohImGui::AddWindow("Debug", "Collision Viewer", DrawColViewerWindow); + + CreateCylinderData(); + CreateSphereData(); +} + +// Initializes the display list for a ColRenderSetting +void InitGfx(std::vector& gfx, ColRenderSetting setting) { + uint32_t rm; + uint32_t blc1; + uint32_t blc2; + uint8_t alpha; + uint64_t cm; + uint32_t gm; + + if (setting == ColRenderSetting::Transparent) { + rm = Z_CMP | IM_RD | CVG_DST_FULL | FORCE_BL; + blc1 = GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA); + blc2 = GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA); + alpha = 0x80; + } else { + rm = Z_CMP | Z_UPD | CVG_DST_CLAMP | FORCE_BL; + blc1 = GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1); + blc2 = GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1); + alpha = 0xFF; + } + + if (applyAsDecal) { + rm |= ZMODE_DEC; + } else if (setting == ColRenderSetting::Transparent) { + rm |= ZMODE_XLU; + } else { + rm |= ZMODE_OPA; + } + + gfx.push_back(gsSPTexture(0, 0, 0, G_TX_RENDERTILE, G_OFF)); + gfx.push_back(gsDPSetCycleType(G_CYC_1CYCLE)); + gfx.push_back(gsDPSetRenderMode(rm | blc1, rm | blc2)); + + if (isShaded) { + gfx.push_back(gsDPSetCombineMode(G_CC_MODULATERGB_PRIM_ENVA, G_CC_MODULATERGB_PRIM_ENVA)); + gfx.push_back(gsSPLoadGeometryMode(G_CULL_BACK | G_ZBUFFER | G_LIGHTING)); + } else { + gfx.push_back(gsDPSetCombineMode(G_CC_PRIMITIVE_ENVA, G_CC_PRIMITIVE_ENVA)); + gfx.push_back(gsSPLoadGeometryMode(G_ZBUFFER)); + } + + gfx.push_back(gsDPSetEnvColor(0xFF, 0xFF, 0xFF, alpha)); +} + +// Draws a dynapoly structure (scenes or Bg Actors) +void DrawDynapoly(std::vector& dl, CollisionHeader* col, int32_t bgId) { + uint32_t color = sceneColor; + uint32_t lastColor = color; + dl.push_back(gsDPSetPrimColor(0, 0, (color >> 24) & 0xFF, (color >> 16) & 0xFF, (color >> 8) & 0xFF, + (color >> 0) & 0xFF)); + + // This keeps track of if we have processed a poly, but not drawn it yet so we can batch them. + // This saves several hundred commands in larger scenes + bool previousPoly = false; + + for (int i = 0; i < col->numPolygons; i++) { + CollisionPoly* poly = &col->polyList[i]; + + if (SurfaceType_IsHookshotSurface(&gGlobalCtx->colCtx, poly, bgId)) { + color = hookshotColor; + } else if (func_80041D94(&gGlobalCtx->colCtx, poly, bgId) > 0x01) { + color = interactableColor; + } else if (func_80041E80(&gGlobalCtx->colCtx, poly, bgId) == 0x0C) { + color = voidColor; + } else if (SurfaceType_GetSceneExitIndex(&gGlobalCtx->colCtx, poly, bgId) || + func_80041E80(&gGlobalCtx->colCtx, poly, bgId) == 0x05) { + color = entranceColor; + } else if (func_80041D4C(&gGlobalCtx->colCtx, poly, bgId) != 0 || + SurfaceType_IsWallDamage(&gGlobalCtx->colCtx, poly, bgId)) { + color = specialSurfaceColor; + } else if (SurfaceType_GetSlope(&gGlobalCtx->colCtx, poly, bgId) == 0x01) { + color = slopeColor; + } else { + color = sceneColor; + } + + if (lastColor != color) { + // Color changed, flush previous poly + if (previousPoly) { + dl.push_back(gsSPVertex((uintptr_t)&vtxDl.at(vtxDl.size() - 3), 3, 0)); + dl.push_back(gsSP1Triangle(0, 1, 2, 0)); + previousPoly = false; + } + dl.push_back(gsDPSetPrimColor(0, 0, (color >> 24) & 0xFF, (color >> 16) & 0xFF, (color >> 8) & 0xFF, + (color >> 0) & 0xFF)); + } + lastColor = color; + + Vec3s* va = &col->vtxList[COLPOLY_VTX_INDEX(poly->flags_vIA)]; + Vec3s* vb = &col->vtxList[COLPOLY_VTX_INDEX(poly->flags_vIB)]; + Vec3s* vc = &col->vtxList[COLPOLY_VTX_INDEX(poly->vIC)]; + vtxDl.push_back(gdSPDefVtxN(va->x, va->y, va->z, 0, 0, (signed char)(poly->normal.x / 0x100), + (signed char)(poly->normal.y / 0x100), (signed char)(poly->normal.z / 0x100), + 0xFF)); + vtxDl.push_back(gdSPDefVtxN(vb->x, vb->y, vb->z, 0, 0, (signed char)(poly->normal.x / 0x100), + (signed char)(poly->normal.y / 0x100), (signed char)(poly->normal.z / 0x100), + 0xFF)); + vtxDl.push_back(gdSPDefVtxN(vc->x, vc->y, vc->z, 0, 0, (signed char)(poly->normal.x / 0x100), + (signed char)(poly->normal.y / 0x100), (signed char)(poly->normal.z / 0x100), + 0xFF)); + + if (previousPoly) { + dl.push_back(gsSPVertex((uintptr_t)&vtxDl.at(vtxDl.size() - 6), 6, 0)); + dl.push_back(gsSP2Triangles(0, 1, 2, 0, 3, 4, 5, 0)); + previousPoly = false; + } else { + previousPoly = true; + } + } + + // Flush previous poly if this is the end and there's no more coming + if (previousPoly) { + dl.push_back(gsSPVertex((uintptr_t)&vtxDl.at(vtxDl.size() - 3), 3, 0)); + dl.push_back(gsSP1Triangle(0, 1, 2, 0)); + previousPoly = false; + } +} + +// Draws the scene +void DrawSceneCollision() { + if (showSceneColSetting == ColRenderSetting::Disabled) { + return; + } + + std::vector& dl = (showSceneColSetting == ColRenderSetting::Transparent) ? xluDl : opaDl; + InitGfx(dl, showSceneColSetting); + dl.push_back(gsSPMatrix(&gMtxClear, G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH)); + + DrawDynapoly(dl, gGlobalCtx->colCtx.colHeader, BGCHECK_SCENE); +} + +// Draws all Bg Actors +void DrawBgActorCollision() { + if (showBgActorSetting == ColRenderSetting::Disabled) { + return; + } + + std::vector& dl = (showBgActorSetting == ColRenderSetting::Transparent) ? xluDl : opaDl; + InitGfx(dl, showBgActorSetting); + dl.push_back(gsSPMatrix(&gMtxClear, G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH)); + + for (int32_t bgIndex = 0; bgIndex < BG_ACTOR_MAX; bgIndex++) { + if (gGlobalCtx->colCtx.dyna.bgActorFlags[bgIndex] & 1) { + BgActor& bg = gGlobalCtx->colCtx.dyna.bgActors[bgIndex]; + Mtx m; + MtxF mf; + SkinMatrix_SetTranslateRotateYXZScale(&mf, bg.curTransform.scale.x, bg.curTransform.scale.y, + bg.curTransform.scale.z, bg.curTransform.rot.x, bg.curTransform.rot.y, + bg.curTransform.rot.z, bg.curTransform.pos.x, bg.curTransform.pos.y, + bg.curTransform.pos.z); + guMtxF2L(&mf, &m); + mtxDl.push_back(m); + dl.push_back(gsSPMatrix(&mtxDl.back(), G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_PUSH)); + + DrawDynapoly(dl, bg.colHeader, bgIndex); + + dl.push_back(gsSPPopMatrix(G_MTX_MODELVIEW)); + } + } + +} + +// Draws a quad +void DrawQuad(std::vector& dl, Vec3f& v0, Vec3f& v1, Vec3f& v2, Vec3f& v3) { + Vec3f norm; + CalcTriNorm(v0, v1, v2, norm); + + vtxDl.push_back(gdSPDefVtxN((short)v0.x, (short)v0.y, (short)v0.z, 0, 0, (signed char)norm.x, (signed char)norm.y, + (signed char)norm.z, 0xFF)); + vtxDl.push_back(gdSPDefVtxN((short)v1.x, (short)v1.y, (short)v1.z, 0, 0, (signed char)norm.x, (signed char)norm.y, + (signed char)norm.z, 0xFF)); + vtxDl.push_back(gdSPDefVtxN((short)v2.x, (short)v2.y, (short)v2.z, 0, 0, (signed char)norm.x, (signed char)norm.y, + (signed char)norm.z, 0xFF)); + vtxDl.push_back(gdSPDefVtxN((short)v3.x, (short)v3.y, (short)v3.z, 0, 0, (signed char)norm.x, (signed char)norm.y, + (signed char)norm.z, 0xFF)); + dl.push_back(gsSPVertex((uintptr_t)&vtxDl.at(vtxDl.size() - 4), 4, 0)); + dl.push_back(gsSP2Triangles(0, 1, 2, 0, 0, 2, 3, 0)); +} + +// Draws a list of Col Check objects +void DrawColCheckList(std::vector& dl, Collider** objects, int32_t count) { + for (int32_t colIndex = 0; colIndex < count; colIndex++) { + Collider* col = objects[colIndex]; + switch (col->shape) { + case COLSHAPE_JNTSPH: { + ColliderJntSph* jntSph = (ColliderJntSph*)col; + + for (int32_t sphereIndex = 0; sphereIndex < jntSph->count; sphereIndex++) { + ColliderJntSphElement* sph = &jntSph->elements[sphereIndex]; + + Mtx m; + MtxF mf; + SkinMatrix_SetTranslate(&mf, sph->dim.worldSphere.center.x, sph->dim.worldSphere.center.y, + sph->dim.worldSphere.center.z); + MtxF ms; + int32_t radius = sph->dim.worldSphere.radius == 0 ? 1 : sph->dim.worldSphere.radius; + SkinMatrix_SetScale(&ms, radius / 128.0f, radius / 128.0f, radius / 128.0f); + MtxF dest; + SkinMatrix_MtxFMtxFMult(&mf, &ms, &dest); + guMtxF2L(&dest, &m); + mtxDl.push_back(m); + + dl.push_back(gsSPMatrix(&mtxDl.back(), G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_PUSH)); + dl.push_back(gsSPDisplayList(sphereGfx.data())); + dl.push_back(gsSPPopMatrix(G_MTX_MODELVIEW)); + } + } break; + case COLSHAPE_CYLINDER: { + ColliderCylinder* cyl = (ColliderCylinder*)col; + + Mtx m; + MtxF mt; + SkinMatrix_SetTranslate(&mt, cyl->dim.pos.x, cyl->dim.pos.y, cyl->dim.pos.z); + MtxF ms; + int32_t radius = cyl->dim.radius == 0 ? 1 : cyl->dim.radius; + SkinMatrix_SetScale(&ms, radius / 128.0f, cyl->dim.height / 128.0f, radius / 128.0f); + MtxF dest; + SkinMatrix_MtxFMtxFMult(&mt, &ms, &dest); + guMtxF2L(&dest, &m); + mtxDl.push_back(m); + + dl.push_back(gsSPMatrix(&mtxDl.back(), G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_PUSH)); + dl.push_back(gsSPDisplayList(cylinderGfx.data())); + dl.push_back(gsSPPopMatrix(G_MTX_MODELVIEW)); + } break; + case COLSHAPE_TRIS: { + ColliderTris* tris = (ColliderTris*)col; + for (int32_t triIndex = 0; triIndex < tris->count; triIndex++) { + ColliderTrisElement* tri = &tris->elements[triIndex]; + + vtxDl.push_back(gdSPDefVtxN((short)tri->dim.vtx[0].x, (short)tri->dim.vtx[0].y, + (short)tri->dim.vtx[0].z, 0, 0, (signed char)tri->dim.plane.normal.x, + (signed char)tri->dim.plane.normal.y, + (signed char)tri->dim.plane.normal.z, 0xFF)); + vtxDl.push_back(gdSPDefVtxN((short)tri->dim.vtx[1].x, (short)tri->dim.vtx[1].y, + (short)tri->dim.vtx[1].z, 0, 0, (signed char)tri->dim.plane.normal.x, + (signed char)tri->dim.plane.normal.y, + (signed char)tri->dim.plane.normal.z, 0xFF)); + vtxDl.push_back(gdSPDefVtxN((short)tri->dim.vtx[2].x, (short)tri->dim.vtx[2].y, + (short)tri->dim.vtx[2].z, 0, 0, (signed char)tri->dim.plane.normal.x, + (signed char)tri->dim.plane.normal.y, + (signed char)tri->dim.plane.normal.z, 0xFF)); + dl.push_back(gsSPVertex((uintptr_t)&vtxDl.at(vtxDl.size() - 3), 3, 0)); + dl.push_back(gsSP1Triangle(0, 1, 2, 0)); + } + } break; + case COLSHAPE_QUAD: { + ColliderQuad* quad = (ColliderQuad*)col; + DrawQuad(dl, quad->dim.quad[0], quad->dim.quad[2], quad->dim.quad[3], quad->dim.quad[1]); + } break; + default: + break; + } + } +} + +// Draws all Col Check objects +void DrawColCheckCollision() { + if (showColCheckSetting == ColRenderSetting::Disabled) { + return; + } + + std::vector& dl = (showColCheckSetting == ColRenderSetting::Transparent) ? xluDl : opaDl; + InitGfx(dl, showColCheckSetting); + dl.push_back(gsSPMatrix(&gMtxClear, G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH)); + + CollisionCheckContext& col = gGlobalCtx->colChkCtx; + + dl.push_back(gsDPSetPrimColor(0, 0, (ocColor >> 24) & 0xFF, (ocColor >> 16) & 0xFF, (ocColor >> 8) & 0xFF, + (ocColor >> 0) & 0xFF)); + DrawColCheckList(dl, col.colOC, col.colOCCount); + + dl.push_back(gsDPSetPrimColor(0, 0, (acColor >> 24) & 0xFF, (acColor >> 16) & 0xFF, (acColor >> 8) & 0xFF, + (acColor >> 0) & 0xFF)); + DrawColCheckList(dl, col.colAC, col.colACCount); + + dl.push_back(gsDPSetPrimColor(0, 0, (atColor >> 24) & 0xFF, (atColor >> 16) & 0xFF, (atColor >> 8) & 0xFF, + (atColor >> 0) & 0xFF)); + DrawColCheckList(dl, col.colAT, col.colATCount); +} + +// Draws a waterbox +void DrawWaterbox(std::vector& dl, WaterBox* water, float water_max_depth = -4000.0f) { + // Skip waterboxes that would be disabled in current room + int32_t room = ((water->properties >> 13) & 0x3F); + if ((room != gGlobalCtx->roomCtx.curRoom.num) && (room != 0x3F)) { + return; + } + + Vec3f vtx[] = { + { water->xMin, water->ySurface, water->zMin + water->zLength }, + { water->xMin + water->xLength, water->ySurface, water->zMin + water->zLength }, + { water->xMin + water->xLength, water->ySurface, water->zMin }, + { water->xMin, water->ySurface, water->zMin }, + { water->xMin, water_max_depth, water->zMin + water->zLength }, + { water->xMin + water->xLength, water_max_depth, water->zMin + water->zLength }, + { water->xMin + water->xLength, water_max_depth, water->zMin }, + { water->xMin, water_max_depth, water->zMin }, + }; + DrawQuad(dl, vtx[0], vtx[1], vtx[2], vtx[3]); + DrawQuad(dl, vtx[0], vtx[3], vtx[7], vtx[4]); + DrawQuad(dl, vtx[1], vtx[0], vtx[4], vtx[5]); + DrawQuad(dl, vtx[2], vtx[1], vtx[5], vtx[6]); + DrawQuad(dl, vtx[3], vtx[2], vtx[6], vtx[7]); +} + +extern "C" WaterBox zdWaterBox; +extern "C" f32 zdWaterBoxMinY; + +// Draws all waterboxes +void DrawWaterboxList() { + if (showWaterboxSetting == ColRenderSetting::Disabled) { + return; + } + + std::vector& dl = (showWaterboxSetting == ColRenderSetting::Transparent) ? xluDl : opaDl; + InitGfx(dl, showWaterboxSetting); + dl.push_back(gsSPMatrix(&gMtxClear, G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH)); + dl.push_back(gsDPSetPrimColor(0, 0, (waterboxColor >> 24) & 0xFF, (waterboxColor >> 16) & 0xFF, + (waterboxColor >> 8) & 0xFF, (waterboxColor >> 0) & 0xFF)); + + CollisionHeader* col = gGlobalCtx->colCtx.colHeader; + for (int32_t waterboxIndex = 0; waterboxIndex < col->numWaterBoxes; waterboxIndex++) { + WaterBox* water = &col->waterBoxes[waterboxIndex]; + DrawWaterbox(dl, water); + } + + // Zora's Domain has a special, hard-coded waterbox with a bottom so you can go under the waterfall + if (gGlobalCtx->sceneNum == SCENE_SPOT07) { + DrawWaterbox(dl, &zdWaterBox, zdWaterBoxMinY); + } +} + +// Resets a vector for the next frame and returns the capacity +template +size_t ResetVector(T& vec) { + size_t oldSize = vec.size(); + vec.clear(); + // Reserve slightly more space than last frame to account for variance (such as different amounts of bg actors) + vec.reserve(oldSize * 1.2); + return vec.capacity(); +} + +void DrawColViewer() { + if (gGlobalCtx == nullptr) { + return; + } + + ResetVector(opaDl); + ResetVector(xluDl); + size_t vtxDlCapacity = ResetVector(vtxDl); + size_t mtxDlCapacity = ResetVector(mtxDl); + + DrawSceneCollision(); + DrawBgActorCollision(); + DrawColCheckCollision(); + DrawWaterboxList(); + + // Check if we used up more space than we reserved. If so, redo the drawing with our new sizes. + // This is because we resized the vectors while drawing, invalidating pointers to them. + // This only matters for the Vtx and Mtx vectors. + if ((vtxDl.size() > vtxDlCapacity) || (mtxDl.size() > mtxDlCapacity)) { + ResetVector(opaDl); + ResetVector(xluDl); + vtxDlCapacity = ResetVector(vtxDl); + mtxDlCapacity = ResetVector(mtxDl); + + DrawSceneCollision(); + DrawBgActorCollision(); + DrawColCheckCollision(); + DrawWaterboxList(); + } + + if ((vtxDl.size() > vtxDlCapacity) || (mtxDl.size() > mtxDlCapacity)) { + // If the sizes somehow changed between the two draws, we can't continue because we may be using invalid data + printf("Error drawing collision, vertex/matrix sizes didn't settle.\n"); + return; + } + + OPEN_DISPS(gGlobalCtx->state.gfxCtx, "", 0); + + opaDl.push_back(gsSPEndDisplayList()); + gSPDisplayList(POLY_OPA_DISP++, opaDl.data()); + + xluDl.push_back(gsSPEndDisplayList()); + gSPDisplayList(POLY_XLU_DISP++, xluDl.data()); + + CLOSE_DISPS(gGlobalCtx->state.gfxCtx, "", 0); +} diff --git a/soh/soh/Enhancements/debugger/colViewer.h b/soh/soh/Enhancements/debugger/colViewer.h new file mode 100644 index 000000000..e38da7951 --- /dev/null +++ b/soh/soh/Enhancements/debugger/colViewer.h @@ -0,0 +1,4 @@ +#pragma once + +void InitColViewer(); +void DrawColViewer(); \ No newline at end of file diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp index 2aaac5a1b..e2ed02705 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp @@ -1,6 +1,7 @@ #include "debugSaveEditor.h" #include "../../util.h" #include "../libultraship/SohImGuiImpl.h" +#include "ImGuiHelpers.h" #include #include @@ -224,26 +225,6 @@ std::array songMapping = { { SONG_MAP_ENTRY(QUEST_SONG_PRELUDE, 255, 240, 100), } }; -// Adds a text tooltip for the previous ImGui item -void SetLastItemHoverText(const std::string& text) { - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip(); - ImGui::Text(text.c_str()); - ImGui::EndTooltip(); - } -} - -// Adds a "?" next to the previous ImGui item with a custom tooltip -void InsertHelpHoverText(const std::string& text) { - ImGui::SameLine(); - ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "?"); - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip(); - ImGui::Text(text.c_str()); - ImGui::EndTooltip(); - } -} - // Encapsulates what is drawn by the passed-in function within a border template void DrawGroupWithBorder(T&& drawFunc) { diff --git a/soh/soh/Enhancements/debugger/debugger.cpp b/soh/soh/Enhancements/debugger/debugger.cpp index e493375cd..83e6a94a4 100644 --- a/soh/soh/Enhancements/debugger/debugger.cpp +++ b/soh/soh/Enhancements/debugger/debugger.cpp @@ -1,6 +1,16 @@ #include "debugger.h" #include "debugSaveEditor.h" +#include "colViewer.h" + +extern "C" { void Debug_Init(void) { InitSaveEditor(); + InitColViewer(); +} + +void Debug_Draw(void) { + DrawColViewer(); +} + } diff --git a/soh/soh/Enhancements/debugger/debugger.h b/soh/soh/Enhancements/debugger/debugger.h index 4bc0f985b..bbefd2e21 100644 --- a/soh/soh/Enhancements/debugger/debugger.h +++ b/soh/soh/Enhancements/debugger/debugger.h @@ -1,3 +1,12 @@ #pragma once +#ifdef __cplusplus +extern "C" { +#endif + void Debug_Init(void); +void Debug_Draw(void); + +#ifdef __cplusplus +} +#endif diff --git a/soh/soh/GbiWrap.cpp b/soh/soh/GbiWrap.cpp index c7f69f1a9..9f71f1717 100644 --- a/soh/soh/GbiWrap.cpp +++ b/soh/soh/GbiWrap.cpp @@ -5,6 +5,7 @@ extern "C" { void InitOTR(); void Graph_ProcessFrame(void (*run_one_game_iter)(void)); +void Graph_StartFrame(); void Graph_ProcessGfxCommands(Gfx* commands); void OTRLogString(const char* src); void OTRGfxPrint(const char* str, void* printer, void (*printImpl)(void*, char)); diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index f125437ab..d2bc941cf 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -26,6 +26,7 @@ #include "../soh/Enhancements/debugger/debugger.h" #include "Utils/BitConverter.h" #include "variables.h" +#include OTRGlobals* OTRGlobals::Instance; @@ -91,6 +92,10 @@ extern "C" void Graph_ProcessFrame(void (*run_one_game_iter)(void)) { OTRGlobals::Instance->context->GetWindow()->MainLoop(run_one_game_iter); } +extern "C" void Graph_StartFrame() { + OTRGlobals::Instance->context->GetWindow()->StartFrame(); +} + // C->C++ Bridge extern "C" void Graph_ProcessGfxCommands(Gfx* commands) { OTRGlobals::Instance->context->GetWindow()->SetFrameDivisor(R_UPDATE_RATE); @@ -888,8 +893,11 @@ extern "C" void AudioPlayer_Play(const uint8_t* buf, uint32_t len) { } extern "C" int Controller_ShouldRumble(size_t i) { - for (const auto& controller : Ship::Window::Controllers.at(i)) { - if (controller->CanRumble() && Game::Settings.controller.extra[i].rumble_strength > 0.001f) { + for (const auto& controller : Ship::Window::Controllers.at(i)) + { + float rumble_strength = CVar_GetFloat(StringHelper::Sprintf("gCont%i_RumbleStrength", i).c_str(), 1.0f); + + if (controller->CanRumble() && rumble_strength > 0.001f) { return 1; } } diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index dfb235712..7ce08649a 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -21,6 +21,7 @@ private: #ifndef __cplusplus void InitOTR(); void Graph_ProcessFrame(void (*run_one_game_iter)(void)); +void Graph_StartFrame(); void Graph_ProcessGfxCommands(Gfx* commands); void OTRLogString(const char* src); void OTRGfxPrint(const char* str, void* printer, void (*printImpl)(void*, char)); diff --git a/soh/soh/z_message_OTR.cpp b/soh/soh/z_message_OTR.cpp index 354997e16..ac1f013c2 100644 --- a/soh/soh/z_message_OTR.cpp +++ b/soh/soh/z_message_OTR.cpp @@ -8,27 +8,37 @@ #include extern "C" MessageTableEntry* sNesMessageEntryTablePtr; +extern "C" MessageTableEntry* sGerMessageEntryTablePtr; +extern "C" MessageTableEntry* sFraMessageEntryTablePtr; extern "C" MessageTableEntry* sStaffMessageEntryTablePtr; -//extern "C" MessageTableEntry* _message_0xFFFC_nes; +//extern "C" MessageTableEntry* _message_0xFFFC_nes; + +MessageTableEntry* OTRMessage_LoadTable(const char* filePath, bool isNES) { + auto file = std::static_pointer_cast(OTRGlobals::Instance->context->GetResourceManager()->LoadResource(filePath)); + + if (file == nullptr) + return nullptr; + + MessageTableEntry* table = (MessageTableEntry*)malloc(sizeof(MessageTableEntry) * file->messages.size()); + + for (int i = 0; i < file->messages.size(); i++) { + table[i].textId = file->messages[i].id; + table[i].typePos = (file->messages[i].textboxType << 4) | file->messages[i].textboxYPos; + table[i].segment = file->messages[i].msg.c_str(); + table[i].msgSize = file->messages[i].msg.size(); + + if (isNES && file->messages[i].id == 0xFFFC) + _message_0xFFFC_nes = (char*)file->messages[i].msg.c_str(); + } + + return table; +} extern "C" void OTRMessage_Init() { - auto file = std::static_pointer_cast(OTRGlobals::Instance->context->GetResourceManager()->LoadResource("text/nes_message_data_static/nes_message_data_static")); - - sNesMessageEntryTablePtr = (MessageTableEntry*)malloc(sizeof(MessageTableEntry) * file->messages.size()); - - for (int i = 0; i < file->messages.size(); i++) - { - sNesMessageEntryTablePtr[i].textId = file->messages[i].id; - sNesMessageEntryTablePtr[i].typePos = (file->messages[i].textboxType << 4) | file->messages[i].textboxYPos; - sNesMessageEntryTablePtr[i].segment = file->messages[i].msg.c_str(); - sNesMessageEntryTablePtr[i].msgSize = file->messages[i].msg.size(); - - if (file->messages[i].id == 0xFFFC) - { - _message_0xFFFC_nes = (char*)file->messages[i].msg.c_str(); - } - } + sNesMessageEntryTablePtr = OTRMessage_LoadTable("text/nes_message_data_static/nes_message_data_static", true); + sGerMessageEntryTablePtr = OTRMessage_LoadTable("text/ger_message_data_static/ger_message_data_static", false); + sFraMessageEntryTablePtr = OTRMessage_LoadTable("text/fra_message_data_static/fra_message_data_static", false); auto file2 = std::static_pointer_cast(OTRGlobals::Instance->context->GetResourceManager()->LoadResource("text/staff_message_data_static/staff_message_data_static")); diff --git a/soh/src/code/graph.c b/soh/src/code/graph.c index dbbbb9df1..9f744ec02 100644 --- a/soh/src/code/graph.c +++ b/soh/src/code/graph.c @@ -5,6 +5,7 @@ #include #include "soh/Enhancements/gameconsole.h" +#include "soh/Enhancements/debugger/debugger.h" #define GFXPOOL_HEAD_MAGIC 0x1234 #define GFXPOOL_TAIL_MAGIC 0x5678 @@ -95,14 +96,14 @@ void Graph_InitTHGA(GraphicsContext* gfxCtx) { pool->tailMagic = GFXPOOL_TAIL_MAGIC; THGA_Ct(&gfxCtx->polyOpa, pool->polyOpaBuffer, sizeof(pool->polyOpaBuffer)); THGA_Ct(&gfxCtx->polyXlu, pool->polyXluBuffer, sizeof(pool->polyXluBuffer)); - THGA_Ct(&gfxCtx->titlecard, pool->titlecardBuffer, sizeof(pool->titlecardBuffer)); + THGA_Ct(&gfxCtx->worldOverlay, pool->worldOverlayBuffer, sizeof(pool->worldOverlayBuffer)); THGA_Ct(&gfxCtx->polyKal, pool->polyKalBuffer, sizeof(pool->polyKalBuffer)); THGA_Ct(&gfxCtx->overlay, pool->overlayBuffer, sizeof(pool->overlayBuffer)); THGA_Ct(&gfxCtx->work, pool->workBuffer, sizeof(pool->workBuffer)); gfxCtx->polyOpaBuffer = pool->polyOpaBuffer; gfxCtx->polyXluBuffer = pool->polyXluBuffer; - gfxCtx->titlecardBuffer = pool->titlecardBuffer; + gfxCtx->worldOverlayBuffer = pool->worldOverlayBuffer; gfxCtx->polyKalBuffer = pool->polyKalBuffer; gfxCtx->overlayBuffer = pool->overlayBuffer; gfxCtx->workBuffer = pool->workBuffer; @@ -276,20 +277,19 @@ void Graph_Update(GraphicsContext* gfxCtx, GameState* gameState) { gDPNoOpString(WORK_DISP++, "WORK_DISP 開始", 0); gDPNoOpString(POLY_OPA_DISP++, "POLY_OPA_DISP 開始", 0); gDPNoOpString(POLY_XLU_DISP++, "POLY_XLU_DISP 開始", 0); - gDPNoOpString(TITLE_CARD_DISP++, "TITLE_CARD_DISP 開始", 0);//unsure if needed gDPNoOpString(OVERLAY_DISP++, "OVERLAY_DISP 開始", 0); CLOSE_DISPS(gfxCtx, "../graph.c", 975); GameState_ReqPadData(gameState); GameState_Update(gameState); + Debug_Draw(); OPEN_DISPS(gfxCtx, "../graph.c", 987); gDPNoOpString(WORK_DISP++, "WORK_DISP 終了", 0); gDPNoOpString(POLY_OPA_DISP++, "POLY_OPA_DISP 終了", 0); gDPNoOpString(POLY_XLU_DISP++, "POLY_XLU_DISP 終了", 0); - gDPNoOpString(TITLE_CARD_DISP++, "TITLE_CARD_DISP 終了", 0); gDPNoOpString(OVERLAY_DISP++, "OVERLAY_DISP 終了", 0); CLOSE_DISPS(gfxCtx, "../graph.c", 996); @@ -298,8 +298,8 @@ void Graph_Update(GraphicsContext* gfxCtx, GameState* gameState) { gSPBranchList(WORK_DISP++, gfxCtx->polyOpaBuffer); gSPBranchList(POLY_OPA_DISP++, gfxCtx->polyXluBuffer); - gSPBranchList(POLY_XLU_DISP++, gfxCtx->titlecardBuffer); - gSPBranchList(TITLE_CARD_DISP++, gfxCtx->polyKalBuffer); + gSPBranchList(POLY_XLU_DISP++, gfxCtx->worldOverlayBuffer); + gSPBranchList(WORLD_OVERLAY_DISP++, gfxCtx->polyKalBuffer); gSPBranchList(POLY_KAL_DISP++, gfxCtx->overlayBuffer); gDPPipeSync(OVERLAY_DISP++); gDPFullSync(OVERLAY_DISP++); @@ -474,6 +474,7 @@ static void RunFrame() uint64_t ticksA, ticksB; ticksA = GetPerfCounter(); + Graph_StartFrame(); PadMgr_ThreadEntry(&gPadMgr); diff --git a/soh/src/code/z_actor.c b/soh/src/code/z_actor.c index 9bf802fb3..a11184dde 100644 --- a/soh/src/code/z_actor.c +++ b/soh/src/code/z_actor.c @@ -1022,31 +1022,30 @@ void TitleCard_Draw(GlobalContext* globalCtx, TitleCardContext* titleCtx) { height = (width * height > 0x1000) ? 0x1000 / width : height; titleSecondY = titleY + (height * 4); - //TITLE_CARD_DISP Goes over POLY_XLU_DISP but under POLY_KAL_DISP - TITLE_CARD_DISP = func_80093808(TITLE_CARD_DISP); + // WORLD_OVERLAY_DISP Goes over POLY_XLU_DISP but under POLY_KAL_DISP + WORLD_OVERLAY_DISP = func_80093808(WORLD_OVERLAY_DISP); - gDPSetPrimColor(TITLE_CARD_DISP++, 0, 0, (u8)titleCtx->intensity, (u8)titleCtx->intensity, (u8)titleCtx->intensity, + gDPSetPrimColor(WORLD_OVERLAY_DISP++, 0, 0, (u8)titleCtx->intensity, (u8)titleCtx->intensity, (u8)titleCtx->intensity, (u8)titleCtx->alpha); - gDPLoadTextureBlock(TITLE_CARD_DISP++, (uintptr_t)titleCtx->texture, G_IM_FMT_IA, - + gDPLoadTextureBlock(WORLD_OVERLAY_DISP++, (uintptr_t)titleCtx->texture, G_IM_FMT_IA, G_IM_SIZ_8b, width, height, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); - gSPTextureRectangle(TITLE_CARD_DISP++, titleX, titleY, ((doubleWidth * 2) + titleX) - 4, titleY + (height * 4) - 1, + gSPTextureRectangle(WORLD_OVERLAY_DISP++, titleX, titleY, ((doubleWidth * 2) + titleX) - 4, titleY + (height * 4) - 1, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); height = titleCtx->height - height; // If texture is bigger than 0x1000, display the rest if (height > 0) { - gDPLoadTextureBlock(TITLE_CARD_DISP++, (uintptr_t)titleCtx->texture + 0x1000, + gDPLoadTextureBlock(WORLD_OVERLAY_DISP++, (uintptr_t)titleCtx->texture + 0x1000, G_IM_FMT_IA, G_IM_SIZ_8b, width, height, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); - gSPTextureRectangle(TITLE_CARD_DISP++, titleX, titleSecondY, ((doubleWidth * 2) + titleX) - 4, + gSPTextureRectangle(WORLD_OVERLAY_DISP++, titleX, titleSecondY, ((doubleWidth * 2) + titleX) - 4, titleSecondY + (height * 4) - 1, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); } diff --git a/soh/src/code/z_message_PAL.c b/soh/src/code/z_message_PAL.c index 53e2dcf52..09c69e660 100644 --- a/soh/src/code/z_message_PAL.c +++ b/soh/src/code/z_message_PAL.c @@ -33,47 +33,12 @@ s16 sMessageHasSetSfx = false; u16 sOcarinaSongBitFlags = 0; // ocarina bit flags MessageTableEntry* sNesMessageEntryTablePtr; +MessageTableEntry* sGerMessageEntryTablePtr; +MessageTableEntry* sFraMessageEntryTablePtr; MessageTableEntry* sStaffMessageEntryTablePtr; char* _message_0xFFFC_nes; -//MessageTableEntry sNesMessageEntryTable[] = { -//#define DEFINE_MESSAGE(textId, type, yPos, nesMessage, gerMessage, fraMessage) \ -// { textId, (_SHIFTL(type, 4, 8) | _SHIFTL(yPos, 0, 8)), _message_##textId##_nes }, -//#define DEFINE_MESSAGE_FFFC -//#include "text/message_data.h" -//#undef DEFINE_MESSAGE_FFFC -//#undef DEFINE_MESSAGE -// { 0xFFFF, 0, NULL }, -//}; -// -//const char* sGerMessageEntryTable[] = { -//#define DEFINE_MESSAGE(textId, type, yPos, nesMessage, gerMessage, fraMessage) _message_##textId##_ger, -//#include "text/message_data.h" -//#undef DEFINE_MESSAGE -// NULL, -//}; -// -//const char* sFraMessageEntryTable[] = { -//#define DEFINE_MESSAGE(textId, type, yPos, nesMessage, gerMessage, fraMessage) _message_##textId##_fra, -//#include "text/message_data.h" -//#undef DEFINE_MESSAGE -// NULL, -//}; -// -//MessageTableEntry sStaffMessageEntryTable[] = { -//#define DEFINE_MESSAGE(textId, type, yPos, staffMessage) \ -// { textId, (_SHIFTL(type, 4, 8) | _SHIFTL(yPos, 0, 8)), _message_##textId##_staff }, -//#include "text/message_data_staff.h" -//#undef DEFINE_MESSAGE -// { 0xFFFF, 0, NULL }, -//}; - -//MessageTableEntry* sNesMessageEntryTablePtr = sNesMessageEntryTable; -//const char** sGerMessageEntryTablePtr = sGerMessageEntryTable; -//const char** sFraMessageEntryTablePtr = sFraMessageEntryTable; -//MessageTableEntry* sStaffMessageEntryTablePtr = sStaffMessageEntryTable; - s16 sTextboxBackgroundForePrimColors[][3] = { { 255, 255, 255 }, { 50, 20, 0 }, { 255, 60, 0 }, { 255, 255, 255 }, { 255, 255, 255 }, { 255, 255, 255 }, { 255, 255, 255 }, { 255, 255, 255 }, @@ -235,8 +200,6 @@ void Message_DrawTextChar(GlobalContext* globalCtx, void* textureImage, Gfx** p) s16 x = msgCtx->textPosX; s16 y = msgCtx->textPosY; - //gSPInvalidateTexCache(gfx++, 0); - //gSPInvalidateTexCache(gfx++, msgCtx->textboxSegment); gSPInvalidateTexCache(gfx++, textureImage); gDPPipeSync(gfx++); @@ -310,69 +273,46 @@ void Message_FindMessage(GlobalContext* globalCtx, u16 textId) { Font* font; const char* seg; - - if (gSaveContext.language == LANGUAGE_ENG) { - seg = messageTableEntry->segment; + if (gSaveContext.language == LANGUAGE_GER) + messageTableEntry = sGerMessageEntryTablePtr; + else if (gSaveContext.language == LANGUAGE_FRA) + messageTableEntry = sFraMessageEntryTablePtr; - while (messageTableEntry->textId != 0xFFFF) { - font = &globalCtx->msgCtx.font; + // If PAL languages are not present in the OTR file, default to English + if (messageTableEntry == NULL) + messageTableEntry = sNesMessageEntryTablePtr; - if (messageTableEntry->textId == textId) { - foundSeg = messageTableEntry->segment; - font->charTexBuf[0] = messageTableEntry->typePos; - //messageTableEntry++; - nextSeg = messageTableEntry->segment; - font->msgOffset = messageTableEntry->segment; - font->msgLength = messageTableEntry->msgSize; - // "Message found!!!" - osSyncPrintf(" メッセージが,見つかった!!! = %x " - "(data=%x) (data0=%x) (data1=%x) (data2=%x) (data3=%x)\n", - textId, font->msgOffset, font->msgLength, foundSeg, seg, nextSeg); - return; - } - messageTableEntry++; - } - } else { - //languageSegmentTable = (gSaveContext.language == LANGUAGE_GER) ? sGerMessageEntryTablePtr : sFraMessageEntryTablePtr; // OTRTODO - seg = messageTableEntry->segment; - - while (messageTableEntry->textId != 0xFFFF) { - font = &globalCtx->msgCtx.font; - - if (messageTableEntry->textId == textId) { - foundSeg = *languageSegmentTable; - font->charTexBuf[0] = messageTableEntry->typePos; - languageSegmentTable++; - nextSeg = *languageSegmentTable; - font->msgOffset = foundSeg - seg; - font->msgLength = nextSeg - foundSeg; - // "Message found!!!" - osSyncPrintf(" メッセージが,見つかった!!! = %x " - "(data=%x) (data0=%x) (data1=%x) (data2=%x) (data3=%x)\n", - textId, font->msgOffset, font->msgLength, foundSeg, seg, nextSeg); - return; - } - messageTableEntry++; - languageSegmentTable++; + seg = messageTableEntry->segment; + + while (messageTableEntry->textId != 0xFFFF) { + font = &globalCtx->msgCtx.font; + + if (messageTableEntry->textId == textId) { + foundSeg = messageTableEntry->segment; + font->charTexBuf[0] = messageTableEntry->typePos; + + nextSeg = messageTableEntry->segment; + font->msgOffset = messageTableEntry->segment; + font->msgLength = messageTableEntry->msgSize; + + // "Message found!!!" + osSyncPrintf(" メッセージが,見つかった!!! = %x " + "(data=%x) (data0=%x) (data1=%x) (data2=%x) (data3=%x)\n", + textId, font->msgOffset, font->msgLength, foundSeg, seg, nextSeg); + return; } + messageTableEntry++; } + // "Message not found!!!" osSyncPrintf(" メッセージが,見つからなかった!!! = %x\n", textId); font = &globalCtx->msgCtx.font; messageTableEntry = sNesMessageEntryTablePtr; - if (gSaveContext.language == LANGUAGE_ENG) { - foundSeg = messageTableEntry->segment; - font->charTexBuf[0] = messageTableEntry->typePos; - messageTableEntry++; - nextSeg = messageTableEntry->segment; - } else { - //languageSegmentTable = (gSaveContext.language == LANGUAGE_GER) ? sGerMessageEntryTablePtr : sFraMessageEntryTablePtr; // OTRTODO - foundSeg = *languageSegmentTable; - font->charTexBuf[0] = messageTableEntry->typePos; - languageSegmentTable++; - nextSeg = *languageSegmentTable; - } + foundSeg = messageTableEntry->segment; + font->charTexBuf[0] = messageTableEntry->typePos; + messageTableEntry++; + nextSeg = messageTableEntry->segment; font->msgOffset = foundSeg - seg; font->msgLength = nextSeg - foundSeg; } @@ -391,7 +331,6 @@ void Message_FindCreditsMessage(GlobalContext* globalCtx, u16 textId) { if (messageTableEntry->textId == textId) { foundSeg = messageTableEntry->segment; font->charTexBuf[0] = messageTableEntry->typePos; - //messageTableEntry++; nextSeg = messageTableEntry->segment; font->msgOffset = messageTableEntry->segment; font->msgLength = messageTableEntry->msgSize; @@ -993,7 +932,7 @@ void Message_DrawText(GlobalContext* globalCtx, Gfx** gfxP) { } } i = j - 1; - msgCtx->textDrawPos = i + CVar_GetS32("gTextSpeed", 1); + msgCtx->textDrawPos = i + 1; if (character) {} } @@ -1187,7 +1126,7 @@ void Message_DrawText(GlobalContext* globalCtx, Gfx** gfxP) { } } if (msgCtx->textDelayTimer == 0) { - msgCtx->textDrawPos = i + 1; + msgCtx->textDrawPos = i + CVar_GetS32("gTextSpeed", 1); msgCtx->textDelayTimer = msgCtx->textDelay; } else { msgCtx->textDelayTimer--; @@ -1682,26 +1621,10 @@ void Message_OpenText(GlobalContext* globalCtx, u16 textId) { //DmaMgr_SendRequest1(font->msgBuf, (uintptr_t)(_staff_message_data_staticSegmentRomStart + 4 + font->msgOffset), //font->msgLength, "../z_message_PAL.c", 1954); } else { - if (gSaveContext.language == LANGUAGE_ENG) - { - Message_FindMessage(globalCtx, textId); - msgCtx->msgLength = font->msgLength; - char* src = (uintptr_t)font->msgOffset; - memcpy(font->msgBuf, src, font->msgLength); - } else if (gSaveContext.language == LANGUAGE_GER) { - // OTRTODO - //Message_FindMessage(globalCtx, textId); - //msgCtx->msgLength = font->msgLength; - //DmaMgr_SendRequest1(font->msgBuf, (uintptr_t)(_ger_message_data_staticSegmentRomStart + font->msgOffset), - //font->msgLength, "../z_message_PAL.c", 1978); - } else - { - // OTRTODO - //Message_FindMessage(globalCtx, textId); - //msgCtx->msgLength = font->msgLength; - //DmaMgr_SendRequest1(font->msgBuf, (uintptr_t)(_fra_message_data_staticSegmentRomStart + font->msgOffset), - //font->msgLength, "../z_message_PAL.c", 1990); - } + Message_FindMessage(globalCtx, textId); + msgCtx->msgLength = font->msgLength; + char* src = (uintptr_t)font->msgOffset; + memcpy(font->msgBuf, src, font->msgLength); } msgCtx->textBoxProperties = font->charTexBuf[0]; diff --git a/soh/src/code/z_player_lib.c b/soh/src/code/z_player_lib.c index d96df5e51..a8bd93f43 100644 --- a/soh/src/code/z_player_lib.c +++ b/soh/src/code/z_player_lib.c @@ -743,6 +743,7 @@ void func_8008F470(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, #else gSPSegment(POLY_OPA_DISP++, 0x09, SEGMENTED_TO_VIRTUAL(sMouthTextures[eyeIndex])); #endif + if (CVar_GetS32("gUseTunicsCol",0) != 1) { //Mod is not on bring back original colors. color = &sTunicColors[tunic]; } @@ -1218,7 +1219,7 @@ void Player_DrawHookshotReticle(GlobalContext* globalCtx, Player* this, f32 arg2 if (BgCheck_AnyLineTest3(&globalCtx->colCtx, &sp8C, &sp80, &sp74, &sp9C, 1, 1, 1, 1, &bgId)) { OPEN_DISPS(globalCtx->state.gfxCtx, "../z_player_lib.c", 2572); - OVERLAY_DISP = Gfx_CallSetupDL(OVERLAY_DISP, 0x07); + WORLD_OVERLAY_DISP = Gfx_CallSetupDL(WORLD_OVERLAY_DISP, 0x07); SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->viewProjectionMtxF, &sp74, &sp68, &sp64); @@ -1227,10 +1228,10 @@ void Player_DrawHookshotReticle(GlobalContext* globalCtx, Player* this, f32 arg2 Matrix_Translate(sp74.x, sp74.y, sp74.z, MTXMODE_NEW); Matrix_Scale(sp60, sp60, sp60, MTXMODE_APPLY); - gSPMatrix(OVERLAY_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_player_lib.c", 2587), + gSPMatrix(WORLD_OVERLAY_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_player_lib.c", 2587), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPSegment(OVERLAY_DISP++, 0x06, globalCtx->objectCtx.status[this->actor.objBankIndex].segment); - gSPDisplayList(OVERLAY_DISP++, gLinkAdultHookshotReticleDL); + gSPSegment(WORLD_OVERLAY_DISP++, 0x06, globalCtx->objectCtx.status[this->actor.objBankIndex].segment); + gSPDisplayList(WORLD_OVERLAY_DISP++, gLinkAdultHookshotReticleDL); CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_player_lib.c", 2592); } diff --git a/soh/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c b/soh/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c index fbc707ade..0951da7d7 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c @@ -166,6 +166,10 @@ void BgSpot06Objects_Init(Actor* thisx, GlobalContext* globalCtx) { } } else { this->lakeHyliaWaterLevel = 0.0f; + WaterBox* water_boxes = globalCtx->colCtx.colHeader->waterBoxes; + water_boxes[LHWB_GERUDO_VALLEY_RIVER_LOWER].ySurface = WATER_LEVEL_RIVER_RAISED; + water_boxes[LHWB_MAIN_1].ySurface = WATER_LEVEL_RAISED; + water_boxes[LHWB_MAIN_2].ySurface = WATER_LEVEL_RAISED; this->actionFunc = BgSpot06Objects_DoNothing; } break; diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c index 2848307b5..75a8efa54 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c @@ -1668,9 +1668,9 @@ void KaleidoScope_DrawInfoPanel(GlobalContext* globalCtx) { gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 180, 210, 255, 255); } } - + gSPDisplayList(POLY_KAL_DISP++, gLButtonIconDL); - + if (CVar_GetS32("gUniformLR", 0) == 0) { //Restore the misplace gDPSetPrimColor gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 180, 210, 255, 255); } @@ -4071,8 +4071,6 @@ void KaleidoScope_Update(GlobalContext* globalCtx) R_UPDATE_RATE = 3; R_PAUSE_MENU_MODE = 0; - ResourceMgr_DirtyDirectory("textures/icon_item_24_static*"); - ResourceMgr_DirtyDirectory("textures/icon_item_static*"); CVar_SetS32("gPauseTriforce", 0); func_800981B8(&globalCtx->objectCtx);