Merge branch 'develop' into zelda64

This commit is contained in:
KiritoDev 2022-06-13 10:18:38 -05:00 committed by GitHub
commit 8a7aa5fa53
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 1009 additions and 120 deletions

View File

@ -21,7 +21,7 @@
```bash
# Clone the repo
git clone git@github.com:HarbourMasters/ShipWright.git
git clone https://github.com/HarbourMasters/Shipwright.git
cd ShipWright
# Copy the baserom to the OTRExporter folder
cp <path to your ROM> OTRExporter

View File

@ -48,7 +48,22 @@ If you still cannot get the tool to work, join our [Discord Server](https://disc
Launch the game. If the window immediately closes, or if there are visual artifacts, you may have selected the wrong rom in the OTRGui tool.
Currently, DirectX 11 and OpenGL is supported. Change the renderer by opening the `shipofharkinian.ini` configuration file in notepad and add `sdl` to `gfx backend` for OpenGL or leave blank for DirectX.
Default keyboard configuration:
| N64 | A | B | Z | Start | Analog stick | C buttons | D-Pad |
| - | - | - | - | - | - | - | - |
| Keyboard | X | C | Z | Space | WASD | Arrow keys | TFGH |
Other shortcuts:
| Keys | Action |
| - | - |
| F1 | Toggle menubar |
| F5 | Save state |
| F6 | Change state |
| F7 | Load state |
| F10 | Fullscreen (OpenGL) |
| Alt+Enter | Fullscreen (DirectX) |
Currently, DirectX 11 and OpenGL are supported. Change the renderer by opening the `shipofharkinian.ini` configuration file in notepad and add `sdl` to `gfx backend` for OpenGL or leave blank for DirectX.
## Take The Survey
Want to use cartridge readers in tandem with the OTRGui?
@ -63,8 +78,8 @@ Official Discord: https://discord.com/invite/BtBmd55HVH
Refer to the [building instructions](BUILDING.md) to compile SoH.
## Troubleshooting The Exporter
- Affirm that you have an `/assets` folder filled with XMLs in the same directory as OTRGui.exe
- Affirm that `zapd.exe` exists in the `/assets/extractor` folder
- Confirm that you have an `/assets` folder filled with XMLs in the same directory as OTRGui.exe
- Confirm that `zapd.exe` exists in the `/assets/extractor` folder
## Nightly Builds
Nightly builds of Ship of Harkinian are available [here](https://builds.shipofharkinian.com/job/SoH_Multibranch/job/develop)
@ -108,7 +123,7 @@ Nightly builds of Ship of Harkinian are available [here](https://builds.shipofha
## Video Credits
Kenix | Producer / Writer
rainbow_fash | Executive Producer
TheLegendOfXela | Editor
ReveriePass | Editor
MicTheMicrophone | Gwonam / The King
Amphibibro | Link
AceHeart | Zelda

View File

@ -9,7 +9,7 @@
namespace Ship {
ResourceMgr::ResourceMgr(std::shared_ptr<GlobalCtx2> Context, std::string MainPath, std::string PatchesPath) : Context(Context), bIsRunning(false), FileLoadThread(nullptr) {
ResourceMgr::ResourceMgr(std::shared_ptr<GlobalCtx2> Context, const std::string& MainPath, const std::string& PatchesPath) : Context(Context), bIsRunning(false), FileLoadThread(nullptr) {
OTR = std::make_shared<Archive>(MainPath, PatchesPath, false);
gameVersion = OOT_UNKNOWN;
@ -280,7 +280,7 @@ namespace Ship {
}
}
std::shared_ptr<std::vector<std::shared_ptr<ResourcePromise>>> ResourceMgr::CacheDirectoryAsync(std::string SearchMask) {
std::shared_ptr<std::vector<std::shared_ptr<ResourcePromise>>> ResourceMgr::CacheDirectoryAsync(const std::string& SearchMask) {
auto loadedList = std::make_shared<std::vector<std::shared_ptr<ResourcePromise>>>();
auto fileList = OTR->ListFiles(SearchMask);
@ -299,7 +299,7 @@ namespace Ship {
return loadedList;
}
std::shared_ptr<std::vector<std::shared_ptr<Resource>>> ResourceMgr::CacheDirectory(std::string SearchMask) {
std::shared_ptr<std::vector<std::shared_ptr<Resource>>> ResourceMgr::CacheDirectory(const std::string& SearchMask) {
auto PromiseList = CacheDirectoryAsync(SearchMask);
auto LoadedList = std::make_shared<std::vector<std::shared_ptr<Resource>>>();

View File

@ -17,7 +17,7 @@ namespace Ship
// It works with the original game's assets because the entire ROM is 64MB and fits into RAM of any semi-modern PC.
class ResourceMgr {
public:
ResourceMgr(std::shared_ptr<GlobalCtx2> Context, std::string MainPath, std::string PatchesPath);
ResourceMgr(std::shared_ptr<GlobalCtx2> Context, const std::string& MainPath, const std::string& PatchesPath);
~ResourceMgr();
bool IsRunning();
@ -38,8 +38,8 @@ namespace Ship
std::shared_ptr<Resource> LoadResource(const char* FilePath);
std::shared_ptr<Resource> LoadResource(const std::string& FilePath) { return LoadResource(FilePath.c_str()); }
std::variant<std::shared_ptr<Resource>, std::shared_ptr<ResourcePromise>> LoadResourceAsync(const char* FilePath);
std::shared_ptr<std::vector<std::shared_ptr<Resource>>> CacheDirectory(std::string SearchMask);
std::shared_ptr<std::vector<std::shared_ptr<ResourcePromise>>> CacheDirectoryAsync(std::string SearchMask);
std::shared_ptr<std::vector<std::shared_ptr<Resource>>> CacheDirectory(const std::string& SearchMask);
std::shared_ptr<std::vector<std::shared_ptr<ResourcePromise>>> CacheDirectoryAsync(const std::string& SearchMask);
std::shared_ptr<std::vector<std::shared_ptr<Resource>>> DirtyDirectory(std::string SearchMask);
protected:

View File

@ -65,7 +65,7 @@ namespace SohImGui {
bool needs_save = false;
std::vector<const char*> CustomTexts;
int SelectedLanguage = CVar_GetS32("gLanguages", 0); //Default Language to 0=English 1=German 2=French
int SelectedHUD = CVar_GetS32("gHudColors", 1); //Default colors to Gamecube.
int SelectedHUD = CVar_GetS32("gHudColors", 1); //Default colors to GameCube.
ImVec4 hearts_colors;
ImVec4 hearts_dd_colors;
ImVec4 a_btn_colors;
@ -437,6 +437,28 @@ namespace SohImGui {
}
}
void EnhancementCombobox(const char* name, const char* ComboArray[], size_t arraySize, uint8_t FirstTimeValue = 0) {
if (FirstTimeValue <= 0) {
FirstTimeValue = 0;
}
uint8_t selected = CVar_GetS32(name, FirstTimeValue);
uint8_t DefaultValue = selected;
std::string comboName = std::string("##") + std::string(name);
if (ImGui::BeginCombo(comboName.c_str(), ComboArray[DefaultValue])) {
for (uint8_t i = 0; i < arraySize; i++) {
if (strlen(ComboArray[i]) > 1) {
if (ImGui::Selectable(ComboArray[i], i == selected)) {
CVar_SetS32(name, i);
selected = i;
needs_save = true;
}
}
}
ImGui::EndCombo();
}
}
void EnhancementRadioButton(const char* text, const char* cvarName, int id) {
/*Usage :
EnhancementRadioButton("My Visible Name","gMyCVarName", MyID);
@ -808,20 +830,9 @@ namespace SohImGui {
EXPERIMENTAL();
ImGui::Text("Texture Filter (Needs reload)");
EnhancementCombobox("gTextureFilter", filters, 3, 0);
GfxRenderingAPI* gapi = gfx_get_current_rendering_api();
if (ImGui::BeginCombo("##filters", filters[gapi->get_texture_filter()])) {
for (int fId = 0; fId <= FilteringMode::NONE; fId++) {
if (ImGui::Selectable(filters[fId], fId == gapi->get_texture_filter())) {
INFO("New Filter: %s", filters[fId]);
gapi->set_texture_filter((FilteringMode)fId);
CVar_SetS32("gTextureFilter", (int)fId);
needs_save = true;
}
}
ImGui::EndCombo();
}
gapi->set_texture_filter((FilteringMode)CVar_GetS32("gTextureFilter", 0));
overlay->DrawSettings();
ImGui::EndMenu();
}
@ -839,6 +850,7 @@ namespace SohImGui {
{
EnhancementSliderInt("Text Speed: %dx", "##TEXTSPEED", "gTextSpeed", 1, 5, "");
EnhancementSliderInt("King Zora Speed: %dx", "##WEEPSPEED", "gMweepSpeed", 1, 5, "");
EnhancementSliderInt("Vine/Ladder Climb speed +%d", "##CLIMBSPEED", "gClimbSpeed", 0, 12, "");
EnhancementCheckbox("Skip Text", "gSkipText");
Tooltip("Holding down B skips text");
@ -853,10 +865,16 @@ namespace SohImGui {
Tooltip("Allows equiping the tunic and boots to c-buttons");
EnhancementCheckbox("MM Bunny Hood", "gMMBunnyHood");
Tooltip("Wearing the Bunny Hood grants a speed increase like in Majora's Mask");
EnhancementCheckbox("Better Owl", "gBetterOwl");
Tooltip("The default response to Kaepora Gaebora is always that you understood what he said");
EnhancementCheckbox("No Skulltula Freeze", "gSkulltulaFreeze");
Tooltip("Stops the game from freezing the player when picking up Gold Skulltulas");
EnhancementCheckbox("Disable Navi Call Audio", "gDisableNaviCallAudio");
Tooltip("Disables the voice audio when Navi calls you");
EnhancementCheckbox("Fast Chests", "gFastChests");
Tooltip("Kick open every chest");
EnhancementCheckbox("Better Owl", "gBetterOwl");
Tooltip("The default response to Kaepora Gaebora is always that you understood what he said");
EnhancementCheckbox("Link's Cow in Both Time Periods", "gCowOfTime");
Tooltip("Allows the Lon Lon Ranch obstacle course reward to be shared across time periods");
ImGui::EndMenu();
}
@ -904,6 +922,8 @@ namespace SohImGui {
}
EnhancementCheckbox("N64 Mode", "gN64Mode");
Tooltip("Sets aspect ratio to 4:3 and lowers resolution to 240p, the N64's native resolution");
EnhancementCheckbox("Disable Black Bar Letterboxes", "gDisableBlackBars");
Tooltip("Disables Black Bar Letterboxes during cutscenes and Z-targeting\nNote: there may be minor visual glitches that were covered up by the black bars\nPlease disable this setting before reporting a bug");
EnhancementCheckbox("Enable 3D Dropped items", "gNewDrops");
EnhancementCheckbox("Dynamic Wallet Icon", "gDynamicWalletIcon");
Tooltip("Changes the rupee in the wallet icon to match the wallet size you currently have");
@ -917,12 +937,26 @@ namespace SohImGui {
{
EnhancementCheckbox("Fix L&R Pause menu", "gUniformLR");
Tooltip("Makes the L and R buttons in the pause menu the same color");
EnhancementCheckbox("Fix L&Z Page switch in Pause menu", "gNGCKaleidoSwitcher");
Tooltip("Enabling it make L and R be your page switch like on Gamecube\nZ become the button to open Debug Menu");
EnhancementCheckbox("Fix Dungeon entrances", "gFixDungeonMinimapIcon");
Tooltip("Show dungeon entrances icon only when it should be");
EnhancementCheckbox("Fix Two Handed idle animations", "gTwoHandedIdle");
Tooltip("Makes two handed idle animation play, a seemingly finished animation that was disabled on accident in the original game");
EnhancementCheckbox("Fix Deku Nut upgrade", "gDekuNutUpgradeFix");
Tooltip("Prevents the Forest Stage Deku Nut upgrade from becoming unobtainable after receiving the Poacher's Saw");
EnhancementCheckbox("Fix Navi text HUD position", "gNaviTextFix");
Tooltip("Correctly centers the Navi text prompt on the HUD's C-Up button");
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Restoration"))
{
EnhancementCheckbox("Red Ganon blood", "gRedGanonBlood");
Tooltip("Restore the original red blood from NTSC 1.0/1.1. Disable for green blood");
EnhancementCheckbox("Fish while hovering", "gHoverFishing");
Tooltip("Restore a bug from NTSC 1.0 that allows casting the Fishing Rod while using the Hover Boots");
ImGui::EndMenu();
}
@ -971,6 +1005,12 @@ namespace SohImGui {
}
EnhancementCheckbox("Disable LOD", "gDisableLOD");
Tooltip("Turns off the level of detail setting, making models always use their higher poly variants");
EnhancementCheckbox("Disable Draw Distance", "gDisableDrawDistance");
Tooltip("Turns off the objects draw distance, making objects being visible from a longer range");
if (CVar_GetS32("gDisableDrawDistance", 0) == 1) {
EnhancementCheckbox("Kokiri Draw Distance", "gDisableKokiriDrawDistance");
Tooltip("Kokiris are mystical being that appear from a certain distance\nEnable this will remove their draw distance\nNeeds to reload the map to take effect");
}
ImGui::EndMenu();
}
@ -981,8 +1021,8 @@ namespace SohImGui {
EnhancementCheckbox("HUD Margins editor", "gUseMargins");
EnhancementRadioButton("N64 interface", "gHudColors", 0);
Tooltip("Change interface color to N64 style.");
EnhancementRadioButton("Gamecube interface", "gHudColors", 1);
Tooltip("Change interface color to Gamecube style.");
EnhancementRadioButton("GameCube interface", "gHudColors", 1);
Tooltip("Change interface color to GameCube style.");
EnhancementRadioButton("Custom interface", "gHudColors", 2);
Tooltip("Change interface color to your own made style.");
if (CVar_GetS32("gHudColors", 1) == 2) {
@ -1018,6 +1058,10 @@ namespace SohImGui {
Tooltip("Allows you to use any item at any location");
EnhancementCheckbox("Freeze Time", "gFreezeTime");
Tooltip("Freezes the time of day");
EnhancementCheckbox("Drops Don't Despawn", "gDropsDontDie");
Tooltip("Drops from enemies, grass, etc. don't disappear after a set amount of time");
EnhancementCheckbox("Fireproof Deku Shield", "gFireproofDekuShield");
Tooltip("Prevents the Deku Shield from burning on contact with fire");
ImGui::EndMenu();
}
@ -1078,22 +1122,22 @@ namespace SohImGui {
Tooltip("Enable/Disable custom Navi's colors. \nIf disabled you will have original colors for Navi.\nColors are refreshed when Navi goes back in your pockets.");
EnhancementColor("Navi Idle Inner", "gNavi_Idle_Inner_", navi_idle_i_col, ImVec4(255,255,255,255), false);
Tooltip("Inner color for Navi (idle flying around)");
EnhancementColor("Navi Idle Outer", "gNavi_Idle_Outer_", navi_idle_o_col, ImVec4(115,230,255,255), false);
EnhancementColor("Navi Idle Outer", "gNavi_Idle_Outer_", navi_idle_o_col, ImVec4(0,0,255,255), false);
Tooltip("Outer color for Navi (idle flying around)");
ImGui::Separator();
EnhancementColor("Navi NPC Inner", "gNavi_NPC_Inner_", navi_npc_i_col, ImVec4(100,100,255,255), false);
EnhancementColor("Navi NPC Inner", "gNavi_NPC_Inner_", navi_npc_i_col, ImVec4(150,150,255,255), false);
Tooltip("Inner color for Navi (when Navi fly around NPCs)");
EnhancementColor("Navi NPC Outer", "gNavi_NPC_Outer_", navi_npc_o_col, ImVec4(90,90,255,255), false);
EnhancementColor("Navi NPC Outer", "gNavi_NPC_Outer_", navi_npc_o_col, ImVec4(150,150,255,255), false);
Tooltip("Outer color for Navi (when Navi fly around NPCs)");
ImGui::Separator();
EnhancementColor("Navi Enemy Inner", "gNavi_Enemy_Inner_", navi_enemy_i_col, ImVec4(255,255,0,255), false);
Tooltip("Inner color for Navi (when Navi fly around Enemies or Bosses)");
EnhancementColor("Navi Enemy Outer", "gNavi_Enemy_Outer_", navi_enemy_o_col, ImVec4(220,220,0,255), false);
EnhancementColor("Navi Enemy Outer", "gNavi_Enemy_Outer_", navi_enemy_o_col, ImVec4(220,155,0,255), false);
Tooltip("Outer color for Navi (when Navi fly around Enemies or Bosses)");
ImGui::Separator();
EnhancementColor("Navi Prop Inner", "gNavi_Prop_Inner_", navi_prop_i_col, ImVec4(0,255,0,255), false);
Tooltip("Inner color for Navi (when Navi fly around props (signs etc))");
EnhancementColor("Navi Prop Outer", "gNavi_Prop_Outer_", navi_prop_o_col, ImVec4(0,220,0,255), false);
EnhancementColor("Navi Prop Outer", "gNavi_Prop_Outer_", navi_prop_o_col, ImVec4(0,255,0,255), false);
Tooltip("Outer color for Navi (when Navi fly around props (signs etc))");
ImGui::EndTabItem();
}
@ -1128,13 +1172,13 @@ namespace SohImGui {
}
if (ImGui::BeginTabItem("Buttons")) {
EnhancementColor("A Buttons", "gCCABtnPrim", a_btn_colors, ImVec4(90,90,255,255));
Tooltip("A Buttons colors (Green in original Gamecube)\nAffect A buttons colors on interface, in shops, messages boxes, ocarina notes and inventory cursors.");
Tooltip("A Buttons colors (Green in original GameCube)\nAffect A buttons colors on interface, in shops, messages boxes, ocarina notes and inventory cursors.");
EnhancementColor("B Buttons", "gCCBBtnPrim", b_btn_colors, ImVec4(0,150,0,255));
Tooltip("B Button colors (Red in original Gamecube)\nAffect B button colors on interface");
Tooltip("B Button colors (Red in original GameCube)\nAffect B button colors on interface");
EnhancementColor("C Buttons", "gCCCBtnPrim", c_btn_colors, ImVec4(255,160,0,255));
Tooltip("C Buttons colors (Yellowish / Oranges in originals)\nAffect C buttons colors on interface, in inventory and ocarina notes");
EnhancementColor("Start Buttons", "gCCStartBtnPrim", start_btn_colors, ImVec4(120,120,120,255));
Tooltip("Start Button colors (gray in Gamecube)\nAffect Start button colors in inventory");
Tooltip("Start Button colors (gray in GameCube)\nAffect Start button colors in inventory");
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Magic Bar")) {

View File

@ -70,6 +70,7 @@ namespace SohImGui {
void EnhancementButton(const char* text, const char* cvarName);
void EnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format);
void EnhancementSliderFloat(const char* text, const char* id, const char* cvarName, float min, float max, const char* format, float defaultValue, bool isPercentage);
void EnhancementCombobox(const char* name, const char* ComboArray[], size_t arraySize, uint8_t FirstTimeValue);
void EnhancementColor(const char* text, const char* cvarName, ImVec4 ColorRGBA, ImVec4 default_colors, bool allow_rainbow = true, bool has_alpha=false, bool TitleSameLine=false);
void DrawMainMenuAndCalculateGameSize(void);

View File

@ -1,21 +1,21 @@
<Root>
<File Name="object_mag" Segment="6">
<Texture Name="gTitleZeldaShieldLogoMQTex" OutName="title_zelda_shield_logo_mq" Format="rgba32" Width="160" Height="160"/>
<Texture Name="gTitleCopyright19982002Tex" OutName="title_copyright_19982002" Format="ia8" Width="160" Height="16"/>
<Texture Name="gTitleCopyright19982003Tex" OutName="title_copyright_19982003" Format="ia8" Width="160" Height="16"/>
<Texture Name="gTitleDiskTex" OutName="title_disk" Format="ia8" Width="48" Height="16"/>
<Texture Name="gTitleEffectMask00Tex" OutName="title_effect_mask_0_0" Format="i4" Width="64" Height="64"/>
<Texture Name="gTitleEffectMask01Tex" OutName="title_effect_mask_0_1" Format="i4" Width="64" Height="64"/>
<Texture Name="gTitleEffectMask02Tex" OutName="title_effect_mask_0_2" Format="i4" Width="64" Height="64"/>
<Texture Name="gTitleEffectMask10Tex" OutName="title_effect_mask_1_0" Format="i4" Width="64" Height="64"/>
<Texture Name="gTitleEffectMask11Tex" OutName="title_effect_mask_1_1" Format="i4" Width="64" Height="64"/>
<Texture Name="gTitleEffectMask12Tex" OutName="title_effect_mask_1_2" Format="i4" Width="64" Height="64"/>
<Texture Name="gTitleEffectMask20Tex" OutName="title_effect_mask_2_0" Format="i4" Width="64" Height="64"/>
<Texture Name="gTitleEffectMask21Tex" OutName="title_effect_mask_2_1" Format="i4" Width="64" Height="64"/>
<Texture Name="gTitleEffectMask22Tex" OutName="title_effect_mask_2_2" Format="i4" Width="64" Height="64"/>
<Texture Name="gTitleFlameEffectTex" OutName="title_flame_effect" Format="i8" Width="32" Height="32"/>
<Texture Name="gTitleTheLegendOfTextTex" OutName="title_the_legend_of_text" Format="i8" Width="72" Height="8"/>
<Texture Name="gTitleOcarinaOfTimeTMTextTex" OutName="title_ocarina_of_time_tm_text" Format="i8" Width="96" Height="8"/>
<Texture Name="gTitleTitleJPNTex" OutName="title_title_jpn" Format="i8" Width="128" Height="16"/>
<Texture Name="gTitleZeldaShieldLogoMQTex" OutName="title_zelda_shield_logo_mq" Format="rgba32" Width="160" Height="160" Offset="0x0"/>
<Texture Name="gTitleCopyright19982002Tex" OutName="title_copyright_19982002" Format="ia8" Width="160" Height="16" Offset="0x19000"/>
<Texture Name="gTitleCopyright19982003Tex" OutName="title_copyright_19982003" Format="ia8" Width="160" Height="16" Offset="0x19A00"/>
<Texture Name="gTitleDiskTex" OutName="title_disk" Format="ia8" Width="48" Height="16" Offset="0x1A400"/>
<Texture Name="gTitleEffectMask00Tex" OutName="title_effect_mask_0_0" Format="i4" Width="64" Height="64" Offset="0x1A700"/>
<Texture Name="gTitleEffectMask01Tex" OutName="title_effect_mask_0_1" Format="i4" Width="64" Height="64" Offset="0x1AF00"/>
<Texture Name="gTitleEffectMask02Tex" OutName="title_effect_mask_0_2" Format="i4" Width="64" Height="64" Offset="0x1B700"/>
<Texture Name="gTitleEffectMask10Tex" OutName="title_effect_mask_1_0" Format="i4" Width="64" Height="64" Offset="0x1BF00"/>
<Texture Name="gTitleEffectMask11Tex" OutName="title_effect_mask_1_1" Format="i4" Width="64" Height="64" Offset="0x1C700"/>
<Texture Name="gTitleEffectMask12Tex" OutName="title_effect_mask_1_2" Format="i4" Width="64" Height="64" Offset="0x1CF00"/>
<Texture Name="gTitleEffectMask20Tex" OutName="title_effect_mask_2_0" Format="i4" Width="64" Height="64" Offset="0x1D700"/>
<Texture Name="gTitleEffectMask21Tex" OutName="title_effect_mask_2_1" Format="i4" Width="64" Height="64" Offset="0x1DF00"/>
<Texture Name="gTitleEffectMask22Tex" OutName="title_effect_mask_2_2" Format="i4" Width="64" Height="64" Offset="0x1E700"/>
<Texture Name="gTitleFlameEffectTex" OutName="title_flame_effect" Format="i8" Width="32" Height="32" Offset="0x1EF00"/>
<Texture Name="gTitleTheLegendOfTextTex" OutName="title_the_legend_of_text" Format="i8" Width="72" Height="8" Offset="0x1F300"/>
<Texture Name="gTitleOcarinaOfTimeTMTextTex" OutName="title_ocarina_of_time_tm_text" Format="i8" Width="96" Height="8" Offset="0x1F540"/>
<Texture Name="gTitleTitleJPNTex" OutName="title_title_jpn" Format="i8" Width="128" Height="16" Offset="0x1F840"/>
</File>
</Root>

View File

@ -3,6 +3,9 @@
<Scene Name="sasatest_scene" Offset="0x0"/>
</File>
<File Name="sasatest_room_0" Segment="3">
<Array Name="gSasatestRoom0Vtx_00370" Count="289" Offset="0x370">
<Vtx/>
</Array>
<Room Name="sasatest_room_0" Offset="0x0"/>
</File>
</Root>

View File

@ -1,21 +1,21 @@
<Root>
<File Name="object_mag" Segment="6">
<Texture Name="gTitleZeldaShieldLogoMQTex" OutName="title_zelda_shield_logo_mq" Format="rgba32" Width="160" Height="160"/>
<Texture Name="gTitleCopyright19982002Tex" OutName="title_copyright_19982002" Format="ia8" Width="160" Height="16"/>
<Texture Name="gTitleCopyright19982003Tex" OutName="title_copyright_19982003" Format="ia8" Width="160" Height="16"/>
<Texture Name="gTitleDiskTex" OutName="title_disk" Format="ia8" Width="48" Height="16"/>
<Texture Name="gTitleEffectMask00Tex" OutName="title_effect_mask_0_0" Format="i4" Width="64" Height="64"/>
<Texture Name="gTitleEffectMask01Tex" OutName="title_effect_mask_0_1" Format="i4" Width="64" Height="64"/>
<Texture Name="gTitleEffectMask02Tex" OutName="title_effect_mask_0_2" Format="i4" Width="64" Height="64"/>
<Texture Name="gTitleEffectMask10Tex" OutName="title_effect_mask_1_0" Format="i4" Width="64" Height="64"/>
<Texture Name="gTitleEffectMask11Tex" OutName="title_effect_mask_1_1" Format="i4" Width="64" Height="64"/>
<Texture Name="gTitleEffectMask12Tex" OutName="title_effect_mask_1_2" Format="i4" Width="64" Height="64"/>
<Texture Name="gTitleEffectMask20Tex" OutName="title_effect_mask_2_0" Format="i4" Width="64" Height="64"/>
<Texture Name="gTitleEffectMask21Tex" OutName="title_effect_mask_2_1" Format="i4" Width="64" Height="64"/>
<Texture Name="gTitleEffectMask22Tex" OutName="title_effect_mask_2_2" Format="i4" Width="64" Height="64"/>
<Texture Name="gTitleFlameEffectTex" OutName="title_flame_effect" Format="i8" Width="32" Height="32"/>
<Texture Name="gTitleTheLegendOfTextTex" OutName="title_the_legend_of_text" Format="i8" Width="72" Height="8"/>
<Texture Name="gTitleOcarinaOfTimeTMTextTex" OutName="title_ocarina_of_time_tm_text" Format="i8" Width="96" Height="8"/>
<Texture Name="gTitleTitleJPNTex" OutName="title_title_jpn" Format="i8" Width="128" Height="16"/>
<Texture Name="gTitleZeldaShieldLogoMQTex" OutName="title_zelda_shield_logo_mq" Format="rgba32" Width="160" Height="160" Offset="0x0"/>
<Texture Name="gTitleCopyright19982002Tex" OutName="title_copyright_19982002" Format="ia8" Width="160" Height="16" Offset="0x19000"/>
<Texture Name="gTitleCopyright19982003Tex" OutName="title_copyright_19982003" Format="ia8" Width="160" Height="16" Offset="0x19A00"/>
<Texture Name="gTitleDiskTex" OutName="title_disk" Format="ia8" Width="48" Height="16" Offset="0x1A400"/>
<Texture Name="gTitleEffectMask00Tex" OutName="title_effect_mask_0_0" Format="i4" Width="64" Height="64" Offset="0x1A700"/>
<Texture Name="gTitleEffectMask01Tex" OutName="title_effect_mask_0_1" Format="i4" Width="64" Height="64" Offset="0x1AF00"/>
<Texture Name="gTitleEffectMask02Tex" OutName="title_effect_mask_0_2" Format="i4" Width="64" Height="64" Offset="0x1B700"/>
<Texture Name="gTitleEffectMask10Tex" OutName="title_effect_mask_1_0" Format="i4" Width="64" Height="64" Offset="0x1BF00"/>
<Texture Name="gTitleEffectMask11Tex" OutName="title_effect_mask_1_1" Format="i4" Width="64" Height="64" Offset="0x1C700"/>
<Texture Name="gTitleEffectMask12Tex" OutName="title_effect_mask_1_2" Format="i4" Width="64" Height="64" Offset="0x1CF00"/>
<Texture Name="gTitleEffectMask20Tex" OutName="title_effect_mask_2_0" Format="i4" Width="64" Height="64" Offset="0x1D700"/>
<Texture Name="gTitleEffectMask21Tex" OutName="title_effect_mask_2_1" Format="i4" Width="64" Height="64" Offset="0x1DF00"/>
<Texture Name="gTitleEffectMask22Tex" OutName="title_effect_mask_2_2" Format="i4" Width="64" Height="64" Offset="0x1E700"/>
<Texture Name="gTitleFlameEffectTex" OutName="title_flame_effect" Format="i8" Width="32" Height="32" Offset="0x1EF00"/>
<Texture Name="gTitleTheLegendOfTextTex" OutName="title_the_legend_of_text" Format="i8" Width="72" Height="8" Offset="0x1F300"/>
<Texture Name="gTitleOcarinaOfTimeTMTextTex" OutName="title_ocarina_of_time_tm_text" Format="i8" Width="96" Height="8" Offset="0x1F540"/>
<Texture Name="gTitleTitleJPNTex" OutName="title_title_jpn" Format="i8" Width="128" Height="16" Offset="0x1F840"/>
</File>
</Root>

View File

@ -176,6 +176,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="soh\Enhancements\debugger\actorViewer.cpp" />
<ClCompile Include="soh\frame_interpolation.cpp" />
<ClCompile Include="soh\Enhancements\bootcommands.c" />
<ClCompile Include="soh\Enhancements\debugconsole.cpp" />
@ -882,6 +883,7 @@
<ClCompile Include="src\overlays\misc\ovl_map_mark_data\z_map_mark_data.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="soh\Enhancements\debugger\actorViewer.h" />
<ClInclude Include="soh\frame_interpolation.h" />
<ClInclude Include="include\alloca.h" />
<ClInclude Include="include\bgm.h" />

View File

@ -2187,6 +2187,9 @@
<ClCompile Include="soh\Enhancements\debugger\colViewer.cpp">
<Filter>Source Files\soh\Enhancements\debugger</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\debugger\actorViewer.cpp">
<Filter>Source Files\soh\Enhancements\debugger</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\debugger\ImGuiHelpers.cpp">
<Filter>Source Files\soh\Enhancements\debugger</Filter>
</ClCompile>
@ -3752,6 +3755,9 @@
<ClInclude Include="soh\Enhancements\debugger\colViewer.h">
<Filter>Header Files\soh\Enhancements\debugger</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\debugger\actorViewer.h">
<Filter>Header Files\soh\Enhancements\debugger</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\debugger\ImGuiHelpers.h">
<Filter>Header Files\soh\Enhancements\debugger</Filter>
</ClInclude>

View File

@ -25,10 +25,13 @@ void BootCommands_Init()
CVar_RegisterS32("gDebugEnabled", 0);
CVar_RegisterS32("gPauseLiveLink", 0);
CVar_RegisterS32("gMinimalUI", 0);
CVar_RegisterS32("gRedGanonBlood", 0);
CVar_RegisterS32("gHoverFishing", 0);
CVar_RegisterS32("gRumbleEnabled", 0);
CVar_RegisterS32("gUniformLR", 1);
CVar_RegisterS32("gUniformLR", 0);
CVar_RegisterS32("gTwoHandedIdle", 0);
CVar_RegisterS32("gDekuNutUpgradeFix", 1);
CVar_RegisterS32("gDekuNutUpgradeFix", 0);
CVar_RegisterS32("gNaviTextFix", 0);
CVar_RegisterS32("gNewDrops", 0);
CVar_RegisterS32("gVisualAgony", 0);
CVar_RegisterS32("gLanguages", 0); //0 = English / 1 = German / 2 = French

View File

@ -0,0 +1,765 @@
#include "actorViewer.h"
#include "../../util.h"
#include "../libultraship/SohImGuiImpl.h"
#include "ImGuiHelpers.h"
#include <array>
#include <bit>
#include <map>
#include <string>
extern "C" {
#include <z64.h>
#include "z64math.h"
#include "variables.h"
#include "functions.h"
#include "macros.h"
extern GlobalContext* gGlobalCtx;
#include "textures/icon_item_static/icon_item_static.h"
#include "textures/icon_item_24_static/icon_item_24_static.h"
}
typedef struct {
u16 id;
u16 params;
Vec3f pos;
Vec3s rot;
} ActorInfo;
typedef enum {
LIST,
TARGET,
HELD,
INTERACT
} RetrievalMethod;
std::array<const char*, 12> acMapping = {
"Switch",
"Background (Prop type 1)",
"Player",
"Bomb",
"NPC",
"Enemy",
"Prop type 2",
"Item/Action",
"Misc.",
"Boss",
"Door",
"Chest"
};
// https://wiki.cloudmodding.com/oot/Actor_List_(Variables)
std::map<u16, const char*> actorDescriptions = {
{ ACTOR_PLAYER, "Link" },
{ ACTOR_EN_TEST, "Stalfos" },
{ ACTOR_EN_GIRLA, "Shop Items" },
{ ACTOR_EN_PART, "Body Parts" },
{ ACTOR_EN_LIGHT, "Decorative Flames" },
{ ACTOR_EN_DOOR, "Door" },
{ ACTOR_EN_BOX, "Treasure Chest" },
{ ACTOR_BG_DY_YOSEIZO, "Great Fairy" },
{ ACTOR_BG_HIDAN_FIREWALL, "Proximity activated Fire Wall" },
{ ACTOR_EN_POH, "Poe" },
{ ACTOR_EN_OKUTA, "Octorok" },
{ ACTOR_BG_YDAN_SP, "Webs" },
{ ACTOR_EN_BOM, "Bomb" },
{ ACTOR_EN_WALLMAS, "Wallmaster" },
{ ACTOR_EN_DODONGO, "Dodongo" },
{ ACTOR_EN_FIREFLY, "Keese" },
{ ACTOR_EN_HORSE, "Rideable Horse" },
{ ACTOR_EN_ITEM00, "Collectibles" },
{ ACTOR_EN_ARROW, "Arrow" },
{ ACTOR_EN_ELF, "Fairy" },
{ ACTOR_EN_NIW, "Cucco" },
{ ACTOR_EN_TITE, "Tektite" },
{ ACTOR_EN_REEBA, "Leever" },
{ ACTOR_EN_PEEHAT, "Peahat and Larva" },
{ ACTOR_EN_BUTTE, "Butterfly" },
{ ACTOR_EN_INSECT, "Bugs" },
{ ACTOR_EN_FISH, "Fish" },
{ ACTOR_EN_HOLL, "Room changing plane" },
{ ACTOR_EN_SCENE_CHANGE, "ovl_En_Scene_Change (broken)" },
{ ACTOR_EN_ZF, "Lizalfos and Dinolfos" },
{ ACTOR_EN_HATA, "Wooden Flagpole with Red Cloth" },
{ ACTOR_BOSS_DODONGO, "King Dodongo" },
{ ACTOR_BOSS_GOMA, "Gohma" },
{ ACTOR_EN_ZL1, "Child Princess Zelda (at window)" },
{ ACTOR_EN_VIEWER, "Cutscene Actors" },
{ ACTOR_EN_GOMA, "Gohma Larva" },
{ ACTOR_BG_PUSHBOX, "Cube" },
{ ACTOR_EN_BUBBLE, "Shabom" },
{ ACTOR_DOOR_SHUTTER, "Shutter Door" },
{ ACTOR_EN_DODOJR, "Baby Dodongo" },
{ ACTOR_EN_BDFIRE, "Empty" },
{ ACTOR_EN_BOOM, "Boomerang" },
{ ACTOR_EN_TORCH2, "Dark Link" },
{ ACTOR_EN_BILI, "Biri" },
{ ACTOR_EN_TP, "Electric Tailpasaran" },
{ ACTOR_EN_ST, "Skulltula" },
{ ACTOR_EN_BW, "Torch Slug" },
{ ACTOR_EN_A_OBJ, "Gameplay_keep items" },
{ ACTOR_EN_EIYER, "Stinger (Land)" },
{ ACTOR_EN_RIVER_SOUND, "Ambient Sound Effects" },
{ ACTOR_EN_HORSE_NORMAL, "Horse" },
{ ACTOR_EN_OSSAN, "Shopkeeper" },
{ ACTOR_BG_TREEMOUTH, "Great Deku Tree's Jaw" },
{ ACTOR_BG_DODOAGO, "Dodongo's Cavern Mega Dodongo" },
{ ACTOR_BG_HIDAN_DALM, "Megaton Hammer Statue" },
{ ACTOR_BG_HIDAN_HROCK, "Huge stone spike platform (Fire Temple)" },
{ ACTOR_EN_HORSE_GANON, "Ganondorf's Horse" },
{ ACTOR_BG_HIDAN_ROCK, "Stone Blocks (Fire Temple)" },
{ ACTOR_BG_HIDAN_RSEKIZOU, "Spinning Stone Flamethrower (Fire Temple)" },
{ ACTOR_BG_HIDAN_SEKIZOU, "Stationary Flamethrower Statue (Fire Temple)" },
{ ACTOR_BG_HIDAN_SIMA, "Stone Platform (Fire Temple)" },
{ ACTOR_BG_HIDAN_SYOKU, "Stone Elevator (Fire Temple)" },
{ ACTOR_EN_XC, "Sheik" },
{ ACTOR_BG_HIDAN_CURTAIN, "Flame Circle" },
{ ACTOR_BG_SPOT00_HANEBASI, "Drawbridge Objects" },
{ ACTOR_EN_MB, "Moblins" },
{ ACTOR_EN_BOMBF, "Bombflower" },
{ ACTOR_EN_ZL2, "Adult Zelda (Cutscenes)" },
{ ACTOR_BG_HIDAN_FSLIFT, "Hookshot Elevator Platform (Fire Temple)" },
{ ACTOR_EN_OE2, "Unused NPC" },
{ ACTOR_BG_YDAN_HASI, "Deku Tree Puzzle elements" },
{ ACTOR_BG_YDAN_MARUTA, "Rotating Spiked Log (Deku Tree)" },
{ ACTOR_BOSS_GANONDROF, "Phantom Ganon" },
{ ACTOR_EN_AM, "Armos Statue" },
{ ACTOR_EN_DEKUBABA, "Deku Baba" },
{ ACTOR_EN_M_FIRE1, "Thrown Deku Nut" },
{ ACTOR_EN_M_THUNDER, "Spin Attack" },
{ ACTOR_BG_DDAN_JD, "Rising Stone Platform (Dodongo's Cavern)" },
{ ACTOR_BG_BREAKWALL, "Bombable Wall" },
{ ACTOR_EN_JJ, "Lord Jabu-Jabu" },
{ ACTOR_EN_HORSE_ZELDA, "Zelda's Horse" },
{ ACTOR_BG_DDAN_KD, "Stone Stairs (Dodongo's Cavern)" },
{ ACTOR_DOOR_WARP1, "Warp Portal" },
{ ACTOR_OBJ_SYOKUDAI, "Torch" },
{ ACTOR_ITEM_B_HEART, "Heart container" },
{ ACTOR_EN_DEKUNUTS, "Mad Scrub" },
{ ACTOR_BG_MENKURI_KAITEN, "Rotating Stone Ring Platform" },
{ ACTOR_BG_MENKURI_EYE, "Eye Statue" },
{ ACTOR_EN_VALI, "Bari" },
{ ACTOR_BG_MIZU_MOVEBG, "Water Temple Background Actors" },
{ ACTOR_BG_MIZU_WATER, "Water Plane (Water Temple)" },
{ ACTOR_ARMS_HOOK, "Hookshot" },
{ ACTOR_EN_FHG, "Phantom Ganon's Horse" },
{ ACTOR_BG_MORI_HINERI, "Twisted Hallway Rooms" },
{ ACTOR_EN_BB, "Bubble" },
{ ACTOR_BG_TOKI_HIKARI, "Windows (Temple of Time)" },
{ ACTOR_EN_YUKABYUN, "Flying Floor Tile" },
{ ACTOR_BG_TOKI_SWD, "Master Sword" },
{ ACTOR_EN_FHG_FIRE, "Empty" },
{ ACTOR_BG_MJIN, "Warp Song Pad" },
{ ACTOR_BG_HIDAN_KOUSI, "Sliding Metal Gate" },
{ ACTOR_DOOR_TOKI, "Door of Time Collision" },
{ ACTOR_BG_HIDAN_HAMSTEP, "Stone Steps and Platforms (Fire Temple)" },
{ ACTOR_EN_BIRD, "Brown Bird" },
{ ACTOR_EN_WOOD02, "Trees and Bushes" },
{ ACTOR_EN_LIGHTBOX, "Large noisy stone" },
{ ACTOR_EN_PU_BOX, "Stone cube" },
{ ACTOR_EN_TRAP, "Metal Spike Trap" },
{ ACTOR_EN_AROW_TRAP, "Arrow Trap" },
{ ACTOR_EN_VASE, "Orange Pot" },
{ ACTOR_EN_TA, "Talon" },
{ ACTOR_EN_TK, "Dampe (Alive)" },
{ ACTOR_BG_MORI_BIGST, "Large Round Platform (Forest Temple)" },
{ ACTOR_BG_MORI_ELEVATOR, "Elevator (Forest Temple)" },
{ ACTOR_BG_MORI_KAITENKABE, "Rotatable Walls (Forest Temple)" },
{ ACTOR_BG_MORI_RAKKATENJO, "Falling Ceiling (Forest Temple)" },
{ ACTOR_EN_VM, "Beamos" },
{ ACTOR_DEMO_EFFECT, "Spiritual Stones, Medallions, Triforce" },
{ ACTOR_DEMO_KANKYO, "Temple of Time Objects" },
{ ACTOR_BG_HIDAN_FWBIG, "Large Fire Wall (Fire Temple)" },
{ ACTOR_EN_FLOORMAS, "Floormaster" },
{ ACTOR_EN_HEISHI1, "Castle Courtyard Guards" },
{ ACTOR_EN_RD, "Redead and Gibdo" },
{ ACTOR_EN_PO_SISTERS, "Poe Sisters" },
{ ACTOR_BG_HEAVY_BLOCK, "Golden Gauntlets Pillar" },
{ ACTOR_BG_PO_EVENT, "Poe Sisters' Paintings and Puzzle Block" },
{ ACTOR_OBJ_MURE, "Fish, Bugs, Butterflies Group Spawner" },
{ ACTOR_EN_SW, "Skullwalltula and Gold Skulltulas" },
{ ACTOR_BOSS_FD, "Volvagia (Flying)" },
{ ACTOR_OBJECT_KANKYO, "Environmental Effects" },
{ ACTOR_EN_DU, "Darunia" },
{ ACTOR_EN_FD, "Flare Dancer" },
{ ACTOR_EN_HORSE_LINK_CHILD, "Young Epona" },
{ ACTOR_DOOR_ANA, "Grotto Entrance" },
{ ACTOR_BG_SPOT02_OBJECTS, "Graveyard Actors" },
{ ACTOR_BG_HAKA, "Gravestone" },
{ ACTOR_MAGIC_WIND, "Farore's Wind" },
{ ACTOR_MAGIC_FIRE, "Din's Fire" },
{ ACTOR_EN_RU1, "Ruto (Child)" },
{ ACTOR_BOSS_FD2, "Volvagia (Hole Form)" },
{ ACTOR_EN_FD_FIRE, "Flare Dancer Fire Attack" },
{ ACTOR_EN_DH, "Dead Hand" },
{ ACTOR_EN_DHA, "Dead Hand's Hand" },
{ ACTOR_EN_RL, "Rauru" },
{ ACTOR_EN_ENCOUNT1, "Enemy Spawner" },
{ ACTOR_DEMO_DU, "Darunia (Cutscenes)" },
{ ACTOR_DEMO_IM, "Impa (Cutscenes)" },
{ ACTOR_DEMO_TRE_LGT, "Treasure Chest Light" },
{ ACTOR_EN_FW, "Flare Dancer Core" },
{ ACTOR_BG_VB_SIMA, "Volvagia Platform" },
{ ACTOR_EN_VB_BALL, "Volvagia Rocks and Bones" },
{ ACTOR_BG_HAKA_MEGANE, "Shadow Temple Fake Walls" },
{ ACTOR_BG_HAKA_MEGANEBG, "Platforms (Shadow Temple)" },
{ ACTOR_BG_HAKA_SHIP, "River Boat (Shadow Temple)" },
{ ACTOR_BG_HAKA_SGAMI, "Spinning Scythe Trap" },
{ ACTOR_EN_HEISHI2, "Hyrulian Guards" },
{ ACTOR_EN_ENCOUNT2, "Falling Rock Spawner" },
{ ACTOR_EN_FIRE_ROCK, "Falling Burning Rocks" },
{ ACTOR_EN_BROB, "Flobbery Muscle Block (Jabu-Jabu's Belly)" },
{ ACTOR_MIR_RAY, "Reflectable Light Beam" },
{ ACTOR_BG_SPOT09_OBJ, "Gerudo Valley Objects" },
{ ACTOR_BG_SPOT18_OBJ, "Statue (Darunia's Room)" },
{ ACTOR_BOSS_VA, "Barinade" },
{ ACTOR_BG_HAKA_TUBO, "Giant Skull Jar (Shadow Temple)" },
{ ACTOR_BG_HAKA_TRAP, "Shadow Temple Traps" },
{ ACTOR_BG_HAKA_HUTA, "Coffin Lid" },
{ ACTOR_BG_HAKA_ZOU, "Bird Statue and Wall (Shadow Temple)" },
{ ACTOR_BG_SPOT17_FUNEN, "Smoke Cone (Death Mountain Crater)" },
{ ACTOR_EN_SYATEKI_ITM, "Shooting Gallery Game" },
{ ACTOR_EN_SYATEKI_MAN, "Shooting Gallery Man" },
{ ACTOR_EN_TANA, "Shop Shelves" },
{ ACTOR_EN_NB, "Nabooru" },
{ ACTOR_BOSS_MO, "Morpha" },
{ ACTOR_EN_SB, "Shell Blade" },
{ ACTOR_EN_BIGOKUTA, "Big Octo" },
{ ACTOR_EN_KAREBABA, "Withered Deku Baba" },
{ ACTOR_BG_BDAN_OBJECTS, "Inside Jabu-Jabu's Belly Objects" },
{ ACTOR_DEMO_SA, "Saria (Cutscenes)" },
{ ACTOR_DEMO_GO, "Gorons (Cutscene)" },
{ ACTOR_EN_IN, "Ingo" },
{ ACTOR_EN_TR, "Koume and Kotake" },
{ ACTOR_BG_SPOT16_BOMBSTONE, "Dodongo's Cavern Entrance Blocking Rock" },
{ ACTOR_BG_HIDAN_KOWARERUKABE, "Bombable Walls (Fire Temple)" },
{ ACTOR_BG_BOMBWALL, "2D Bombable Wall" },
{ ACTOR_BG_SPOT08_ICEBLOCK, "Ice Platform (Zora's Fountain)" },
{ ACTOR_EN_RU2, "Ruto (Adult)" },
{ ACTOR_OBJ_DEKUJR, "Deku Tree Sprout" },
{ ACTOR_BG_MIZU_UZU, "Water Vortex Effect (Water Temple)" },
{ ACTOR_BG_SPOT06_OBJECTS, "Lake Hylia Objects" },
{ ACTOR_BG_ICE_OBJECTS, "Pushable Ice Block (Ice Cavern)" },
{ ACTOR_BG_HAKA_WATER, "Bottom of the Well Water Level Changer" },
{ ACTOR_EN_MA2, "Malon (Adult, Ingo's Ranch)" },
{ ACTOR_EN_BOM_CHU, "Bombchu" },
{ ACTOR_EN_HORSE_GAME_CHECK, "Horseback Minigames" },
{ ACTOR_BOSS_TW, "Twinrova" },
{ ACTOR_EN_RR, "Like-Like" },
{ ACTOR_EN_BA, "Tentacle (Inside Jabu-Jabu's Belly)" },
{ ACTOR_EN_BX, "Electrified Tentacle (Inside Jabu-Jabu's Belly)" },
{ ACTOR_EN_ANUBICE, "Anubis (Body)" },
{ ACTOR_EN_ANUBICE_FIRE, "Anubis Fire Attack" },
{ ACTOR_BG_MORI_HASHIGO, "Ladder (Forest Temple)" },
{ ACTOR_BG_MORI_HASHIRA4, "Forest Temple Objects" },
{ ACTOR_BG_MORI_IDOMIZU, "Well Water (Forest Temple)" },
{ ACTOR_BG_SPOT16_DOUGHNUT, "Cloud Ring (Death Mountain)" },
{ ACTOR_BG_BDAN_SWITCH, "Switches (Inside Lord Jabu-Jabu)" },
{ ACTOR_EN_MA1, "Malon (Child)" },
{ ACTOR_BOSS_GANON, "Ganondorf" },
{ ACTOR_BOSS_SST, "Bongo Bongo" },
{ ACTOR_EN_NY, "Spike (Enemy)" },
{ ACTOR_EN_FR, "Frog Song Spot and Frogs" },
{ ACTOR_ITEM_SHIELD, "Deku Shield" },
{ ACTOR_BG_ICE_SHELTER, "Red Ice" },
{ ACTOR_EN_ICE_HONO, "Blue Fire Flames" },
{ ACTOR_ITEM_OCARINA, "Ocarina of Time" },
{ ACTOR_MAGIC_DARK, "Nayru's Love" },
{ ACTOR_DEMO_6K, "Sages, Balls of Light (Cutscene)" },
{ ACTOR_EN_ANUBICE_TAG, "Anubis Spawn" },
{ ACTOR_BG_HAKA_GATE, "Truth Spinner Puzzle (Shadow Temple)" },
{ ACTOR_BG_SPOT15_SAKU, "Hyrule Castle Gate" },
{ ACTOR_BG_JYA_GOROIWA, "Rolling Boulder (Spirit Temple)" },
{ ACTOR_BG_JYA_ZURERUKABE, "Sliding, Climbable Brick Wall (Spirit Temple)" },
{ ACTOR_BG_JYA_COBRA, "Rotatable Cobra Mirror (Spirit Temple)" },
{ ACTOR_BG_JYA_KANAAMI, "Climbable Metal Grating Bridge (Spirit Temple)" },
{ ACTOR_FISHING, "Fishing Pond Man and Fish" },
{ ACTOR_OBJ_OSHIHIKI, "Pushable Block" },
{ ACTOR_BG_GATE_SHUTTER, "Gate to Death Mountain Trail" },
{ ACTOR_EFF_DUST, "Dust Effects" },
{ ACTOR_BG_SPOT01_FUSYA, "Windmill Sails (Kakariko Village)" },
{ ACTOR_BG_SPOT01_IDOHASHIRA, "Well Crossbeam (Kakariko Village)" },
{ ACTOR_BG_SPOT01_IDOMIZU, "Well Water (Kakariko Village)" },
{ ACTOR_BG_PO_SYOKUDAI, "Golden Torch (Poe Sisters)" },
{ ACTOR_BG_GANON_OTYUKA, "Falling Platform (Ganondorf Fight)" },
{ ACTOR_BG_SPOT15_RRBOX, "Milk Crate" },
{ ACTOR_BG_UMAJUMP, "Obstacle Fence (Lon Lon Ranch)" },
{ ACTOR_ARROW_FIRE, "Fire Arrow" },
{ ACTOR_ARROW_ICE, "Ice Arrow" },
{ ACTOR_ARROW_LIGHT, "Light Arrow" },
{ ACTOR_ITEM_ETCETERA, "Collectible Items" },
{ ACTOR_OBJ_KIBAKO, "Small Liftable Crate" },
{ ACTOR_OBJ_TSUBO, "Breakable Pot" },
{ ACTOR_EN_WONDER_ITEM, "Invisible Collectible" },
{ ACTOR_EN_IK, "Iron Knuckle" },
{ ACTOR_DEMO_IK, "Iron Knuckle armor pieces (Spirit Temple Nabooru fight)" },
{ ACTOR_EN_SKJ, "Skullkid" },
{ ACTOR_EN_SKJNEEDLE, "Skullkid Needle Attack" },
{ ACTOR_EN_G_SWITCH, "Silver Rupee" },
{ ACTOR_DEMO_EXT, "Magic Vortex" },
{ ACTOR_DEMO_SHD, "Bongo Bongo's Shadow" },
{ ACTOR_EN_DNS, "Business Scrub" },
{ ACTOR_ELF_MSG, "Navi Message" },
{ ACTOR_EN_HONOTRAP, "Stone Eye (Fire Trap) and Flame" },
{ ACTOR_EN_TUBO_TRAP, "Flying Pot" },
{ ACTOR_OBJ_ICE_POLY, "Ice spawned by red ice? frozen actors" },
{ ACTOR_BG_SPOT03_TAKI, "Zora's River Waterfall" },
{ ACTOR_BG_SPOT07_TAKI, "Zora's Domain Waterfall and Ice" },
{ ACTOR_EN_FZ, "Frezzard" },
{ ACTOR_EN_PO_RELAY, "Dampe's Ghost" },
{ ACTOR_BG_RELAY_OBJECTS, "Windmill Objects" },
{ ACTOR_EN_DIVING_GAME, "Zora Diving Game" },
{ ACTOR_EN_KUSA, "Bush/Grass" },
{ ACTOR_OBJ_BEAN, "Bean Plant Spot" },
{ ACTOR_OBJ_BOMBIWA, "Brown Bombable Boulder" },
{ ACTOR_OBJ_SWITCH, "Switches" },
{ ACTOR_OBJ_ELEVATOR, "Huge Stone Elevator" },
{ ACTOR_OBJ_LIFT, "Square Collapsing Platform" },
{ ACTOR_OBJ_HSBLOCK, "Stone Hookshot Target" },
{ ACTOR_EN_OKARINA_TAG, "Ocarina Music Staff Spot" },
{ ACTOR_EN_YABUSAME_MARK, "Horseback Archery Target" },
{ ACTOR_EN_GOROIWA, "Rolling Boulder" },
{ ACTOR_EN_EX_RUPPY, "Sparkling Rupee" },
{ ACTOR_EN_TORYO, "Boss Carpenter" },
{ ACTOR_EN_DAIKU, "Carpenters" },
{ ACTOR_EN_NWC, "Cucco Chick" },
{ ACTOR_EN_BLKOBJ, "Dark Link's Illusion Room" },
{ ACTOR_ITEM_INBOX, "Zelda's Magic to Open Gates" },
{ ACTOR_EN_GE1, "White Clothed Gerudo" },
{ ACTOR_OBJ_BLOCKSTOP, "Pushblock Stop" },
{ ACTOR_EN_SDA, "Dynamic Shadow" },
{ ACTOR_EN_CLEAR_TAG, "Arwing" },
{ ACTOR_EN_NIW_LADY, "Cucco Lady" },
{ ACTOR_EN_GM, "Medigoron" },
{ ACTOR_EN_MS, "Bean Salesman" },
{ ACTOR_EN_HS, "Carpenter's Son" },
{ ACTOR_BG_INGATE, "Ingo's Gates (Lon Lon Ranch)" },
{ ACTOR_EN_KANBAN, "Square Signpost" },
{ ACTOR_EN_HEISHI3, "Hyrule Castle Guard" },
{ ACTOR_EN_SYATEKI_NIW, "Cucco (Minigames)" },
{ ACTOR_EN_ATTACK_NIW, "Cucco (Attacking)" },
{ ACTOR_BG_SPOT01_IDOSOKO, "Stone Blocking Entrance to Bottom of the Well" },
{ ACTOR_EN_SA, "Saria" },
{ ACTOR_EN_WONDER_TALK, "Checkable Spot (Green Navi)" },
{ ACTOR_BG_GJYO_BRIDGE, "Rainbow Bridge to Ganon's Castle" },
{ ACTOR_EN_DS, "Potion Shop Granny" },
{ ACTOR_EN_MK, "Lakeside Professor" },
{ ACTOR_EN_BOM_BOWL_MAN, "Bombchu Bowling Alley Lady" },
{ ACTOR_EN_BOM_BOWL_PIT, "Bombchu Bowling Alley Final Target" },
{ ACTOR_EN_OWL, "Kaepora Gaebora" },
{ ACTOR_EN_ISHI, "Liftable Rock" },
{ ACTOR_OBJ_HANA, "Uninteractable Flowers, Rocks, Grass" },
{ ACTOR_OBJ_LIGHTSWITCH, "Sun Emblem Switch (Spirit Temple)" },
{ ACTOR_OBJ_MURE2, "Rock/Bush groups" },
{ ACTOR_EN_GO, "Gorons 1" },
{ ACTOR_EN_FU, "Windmill Man" },
{ ACTOR_EN_CHANGER, "Treasure Box Shop Minigame" },
{ ACTOR_BG_JYA_MEGAMI, "Statue Face (Spirit Temple)" },
{ ACTOR_BG_JYA_LIFT, "Chain Platform (Spirit Temple)" },
{ ACTOR_BG_JYA_BIGMIRROR, "Large Circular Mirror (Spirt Temple)" },
{ ACTOR_BG_JYA_BOMBCHUIWA, "Light Blocking Rock (Spirit Temple)" },
{ ACTOR_BG_JYA_AMISHUTTER, "Sliding Circular Metal Grate (Spirit Temple)" },
{ ACTOR_BG_JYA_BOMBIWA, "Bombable Rock Wall (Spirit Temple)" },
{ ACTOR_BG_SPOT18_BASKET, "Big Goron Pot" },
{ ACTOR_EN_GANON_ORGAN, "Ganon's Organ and surroundings" },
{ ACTOR_EN_SIOFUKI, "Water Spout" },
{ ACTOR_EN_STREAM, "Water Vortex" },
{ ACTOR_EN_MM, "Running Man (Child Era)" },
{ ACTOR_EN_KO, "Kokiri Children" },
{ ACTOR_EN_KZ, "King Zora" },
{ ACTOR_EN_WEATHER_TAG, "Proximity Weather Effects" },
{ ACTOR_BG_SST_FLOOR, "Bongo Bongo's Drum" },
{ ACTOR_EN_ANI, "Kakariko Village Rooftop Man" },
{ ACTOR_EN_EX_ITEM, "Minigame Displayed Items" },
{ ACTOR_BG_JYA_IRONOBJ, "Iron Knuckles Room Stuff (Spirit Temple)" },
{ ACTOR_EN_JS, "Magic Carpet Man" },
{ ACTOR_EN_JSJUTAN, "Magic Carpet Man Carpet" },
{ ACTOR_EN_CS, "Graveyard Boy" },
{ ACTOR_EN_MD, "Mido" },
{ ACTOR_EN_HY, "Market NPCs" },
{ ACTOR_EN_GANON_MANT, "Ganondorf's Cape" },
{ ACTOR_EN_OKARINA_EFFECT, "Song of Storms Storm Manager" },
{ ACTOR_EN_MAG, "Title Screen Manager" },
{ ACTOR_DOOR_GERUDO, "Cell Door (Gerudo Fortress)" },
{ ACTOR_ELF_MSG2, "Navi Information Spot (Targetable, Green)" },
{ ACTOR_DEMO_GT, "Ganon's Tower Collapsing (Cutscene Objects)" },
{ ACTOR_EN_PO_FIELD, "Big/Small Poe Spawn Point" },
{ ACTOR_EFC_ERUPC, "Lava Particle Fountain (Death Mountain panorama)" },
{ ACTOR_BG_ZG, "Metal Bars (Ganon's Castle)" },
{ ACTOR_EN_HEISHI4, "Hyrule Guard" },
{ ACTOR_EN_ZL3, "Adult Zelda" },
{ ACTOR_BOSS_GANON2, "Ganon" },
{ ACTOR_EN_KAKASI, "Pierre the Scarecrow" },
{ ACTOR_EN_TAKARA_MAN, "Treasure Box Shop Man" },
{ ACTOR_OBJ_MAKEOSHIHIKI, "Push Block Puzzles" },
{ ACTOR_OCEFF_SPOT, "Sun's Song Effect" },
{ ACTOR_END_TITLE, "The End message" },
{ ACTOR_EN_TORCH, "Grotto Treasure Chest" },
{ ACTOR_DEMO_EC, "Credits Revelers in Lon Lon" },
{ ACTOR_SHOT_SUN, "Lake Hylia Sun Hitbox, Big Fairy Spawner" },
{ ACTOR_EN_DY_EXTRA, "Spiral Beams (Great Fairy Fountains)" },
{ ACTOR_EN_WONDER_TALK2, "Dialog Spot" },
{ ACTOR_EN_GE2, "Patrolling Gerudo" },
{ ACTOR_OBJ_ROOMTIMER, "Room Timer" },
{ ACTOR_EN_SSH, "Cursed Skulltula People" },
{ ACTOR_EN_STH, "Uncursed Skulltula People" },
{ ACTOR_OCEFF_WIPE, "Zelda's Lullaby and Song of Time Ocarina Effect" },
{ ACTOR_OCEFF_STORM, "Song of Storm Ocarina Effect" },
{ ACTOR_EN_WEIYER, "Stinger (Water)" },
{ ACTOR_BG_SPOT05_SOKO, "Sacred Forest Meadow Objects" },
{ ACTOR_BG_JYA_1FLIFT, "Stone Elevator (Spirit Temple)" },
{ ACTOR_BG_JYA_HAHENIRON, "Chunks of Iron Knucle Chair and Pillar" },
{ ACTOR_BG_SPOT12_GATE, "Gerudo Fortress Wooden Gate" },
{ ACTOR_BG_SPOT12_SAKU, "Gerudo Fortress Training Area Gate" },
{ ACTOR_EN_HINTNUTS, "Hint Deku Scrubs (Deku Tree)" },
{ ACTOR_EN_NUTSBALL, "Deku Scrub Nut Attack" },
{ ACTOR_BG_SPOT00_BREAK, "Broken Drawbridge, Fences" },
{ ACTOR_EN_SHOPNUTS, "Grounded Sales Scrub" },
{ ACTOR_EN_IT, "Dampe's Minigame Collectibles" },
{ ACTOR_EN_GELDB, "Gerudo Fighter" },
{ ACTOR_OCEFF_WIPE2, "Epona's Song Ocarina Effect" },
{ ACTOR_OCEFF_WIPE3, "Saria's Song Ocarina Effect" },
{ ACTOR_EN_NIW_GIRL, "Girl Chasing Cucco" },
{ ACTOR_EN_DOG, "Dog" },
{ ACTOR_EN_SI, "Gold Skulltula Token" },
{ ACTOR_BG_SPOT01_OBJECTS2, "Kakariko Village Objects" },
{ ACTOR_OBJ_COMB, "Beehive" },
{ ACTOR_BG_SPOT11_BAKUDANKABE, "Destructible Wall (Desert Colossus)" },
{ ACTOR_OBJ_KIBAKO2, "Large Crate" },
{ ACTOR_EN_DNT_DEMO, "Deku Mask Panel Trigger" },
{ ACTOR_EN_DNT_JIJI, "Deku Mask Panel Head Judge" },
{ ACTOR_EN_DNT_NOMAL, "Deku Game?" },
{ ACTOR_EN_GUEST, "Happy Mask Shop Customer" },
{ ACTOR_BG_BOM_GUARD, "Bombchu Bowling Alley Aiming Area" },
{ ACTOR_EN_HS2, "Carpenter's Son (Child Era)" },
{ ACTOR_DEMO_KEKKAI, "Ganon's Tower Magic Barriers" },
{ ACTOR_BG_SPOT08_BAKUDANKABE, "Destructible Wall (Zora's Fountain)" },
{ ACTOR_BG_SPOT17_BAKUDANKABE, "Destructible Wall (Death Mountain Crater)" },
{ ACTOR_OBJ_MURE3, "Rupee Patterns" },
{ ACTOR_EN_TG, "Entwined Lovers (Honey & Darling)" },
{ ACTOR_EN_MU, "Haggling Townspeople" },
{ ACTOR_EN_GO2, "Gorons 2" },
{ ACTOR_EN_WF, "Wolfos" },
{ ACTOR_EN_SKB, "Stalchild" },
{ ACTOR_DEMO_GJ, "Ganon Battle Rubble" },
{ ACTOR_DEMO_GEFF, "Ganon's Tower Rubble Fragment" },
{ ACTOR_BG_GND_FIREMEIRO, "Sinking Lava Platform (Ganon's Castle)" },
{ ACTOR_BG_GND_DARKMEIRO, "Clear block" },
{ ACTOR_BG_GND_SOULMEIRO, "Web-Blocked Ceiling Hole (Inside Ganon's Castle)" },
{ ACTOR_BG_GND_NISEKABE, "Ganon's Castle Fake Walls" },
{ ACTOR_BG_GND_ICEBLOCK, "Pushable Square Ice Block (Inside Ganon's Castle)" },
{ ACTOR_EN_GB, "Poe Collector and Surroundings" },
{ ACTOR_EN_GS, "Gossip Stone" },
{ ACTOR_BG_MIZU_BWALL, "Bombable Stone Wall" },
{ ACTOR_BG_MIZU_SHUTTER, "Metal Gate (Water Temple)" },
{ ACTOR_EN_DAIKU_KAKARIKO, "Carpenters (Kakariko)" },
{ ACTOR_BG_BOWL_WALL, "Bombchu Bowling Alley Wall" },
{ ACTOR_EN_WALL_TUBO, "Bombchu Bowling Alley Bullseyes" },
{ ACTOR_EN_PO_DESERT, "Poe Guide (Desert Wasteland)" },
{ ACTOR_EN_CROW, "Guay" },
{ ACTOR_DOOR_KILLER, "Fake Door" },
{ ACTOR_BG_SPOT11_OASIS, "Oasis (Desert Colossus)" },
{ ACTOR_BG_SPOT18_FUTA, "Goron Jar Lid" },
{ ACTOR_BG_SPOT18_SHUTTER, "Sliding Doors (Goron City)" },
{ ACTOR_EN_MA3, "Malon (Adult, Lon Lon Ranch)" },
{ ACTOR_EN_COW, "Cow" },
{ ACTOR_BG_ICE_TURARA, "Icicles" },
{ ACTOR_BG_ICE_SHUTTER, "Vertical Ice Bars (Ice Cavern)" },
{ ACTOR_EN_KAKASI2, "Pierre the Scarecrow Spawn" },
{ ACTOR_EN_KAKASI3, "Bonooru the Scarecrow" },
{ ACTOR_OCEFF_WIPE4, "Scarecrow's Song Ocarina Effect" },
{ ACTOR_EN_EG, "Void-out Trigger (Tower Collapse)" },
{ ACTOR_BG_MENKURI_NISEKABE, "False Stone Walls (Gerudo Training Grounds)" },
{ ACTOR_EN_ZO, "Zora" },
{ ACTOR_OBJ_MAKEKINSUTA, "Skulltula Sprouting from Bean Spot" },
{ ACTOR_EN_GE3, "Gerudo Fortress Leader" },
{ ACTOR_OBJ_TIMEBLOCK, "Time Block" },
{ ACTOR_OBJ_HAMISHI, "Bronze Boulder" },
{ ACTOR_EN_ZL4, "Zelda (Child)" },
{ ACTOR_EN_MM2, "Running Man (Adult Era)" },
{ ACTOR_BG_JYA_BLOCK, "Silver Block (Child Era)" },
{ ACTOR_OBJ_WARP2BLOCK, "Navi Infospot (Green, Time Block)" }
};
const std::string GetActorDescription(u16 id) {
return actorDescriptions[id];
}
template <typename T> void DrawGroupWithBorder(T&& drawFunc) {
// First group encapsulates the inner portion and border
ImGui::BeginGroup();
ImVec2 padding = ImGui::GetStyle().FramePadding;
ImVec2 p0 = ImGui::GetCursorScreenPos();
ImGui::SetCursorScreenPos(ImVec2(p0.x + padding.x, p0.y + padding.y));
// Second group encapsulates just the inner portion
ImGui::BeginGroup();
drawFunc();
ImGui::Dummy(padding);
ImGui::EndGroup();
ImVec2 p1 = ImGui::GetItemRectMax();
p1.x += padding.x;
ImVec4 borderCol = ImGui::GetStyle().Colors[ImGuiCol_Border];
ImGui::GetWindowDrawList()->AddRect(
p0, p1, IM_COL32(borderCol.x * 255, borderCol.y * 255, borderCol.z * 255, borderCol.w * 255));
ImGui::EndGroup();
}
void PopulateActorDropdown(int i, std::vector<Actor*>& data) {
if (data.size() != 0) {
data.clear();
}
if (gGlobalCtx != nullptr) {
ActorListEntry currList = gGlobalCtx->actorCtx.actorLists[i];
Actor* currAct = currList.head;
if (currAct != nullptr) {
while (currAct != nullptr) {
data.push_back(currAct);
currAct = currAct->next;
}
}
}
}
void DrawActorViewer(bool& open) {
if (!open) {
return;
}
ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver);
if (!ImGui::Begin("Actor Viewer", &open, ImGuiWindowFlags_NoFocusOnAppearing)) {
ImGui::End();
return;
}
static Actor display;
static const Actor empty{};
static Actor* fetch = NULL;
static ActorInfo newActor = {0,0, {0, 0, 0}, {0, 0, 0}};
static ActorOverlay* dispOverlay;
static bool needs_reset = false;
static ImU16 one = 1;
static int actor;
static int category = 0;
static RetrievalMethod rm;
static std::string filler = "Please select";
static std::vector<Actor*> list;
static u16 lastSceneId = 0;
if (gGlobalCtx != nullptr) {
needs_reset = lastSceneId != gGlobalCtx->sceneNum;
if (needs_reset) {
display = empty;
fetch = nullptr;
dispOverlay = nullptr;
newActor = { 0, 0, { 0, 0, 0 }, { 0, 0, 0 } };
actor = category = 0;
filler = "Please Select";
list.clear();
needs_reset = false;
}
lastSceneId = gGlobalCtx->sceneNum;
if (ImGui::BeginCombo("Actor Type", acMapping[category])) {
for (int i = 0; i < acMapping.size(); i++) {
if (ImGui::Selectable(acMapping[i])) {
category = i;
PopulateActorDropdown(category, list);
break;
}
}
ImGui::EndCombo();
}
if (ImGui::BeginCombo("Actor", filler.c_str())) {
if (gGlobalCtx != nullptr && lastSceneId != gGlobalCtx->sceneNum) {
PopulateActorDropdown(category, list);
lastSceneId = gGlobalCtx->sceneNum;
}
for (int i = 0; i < list.size(); i++) {
std::string label = std::to_string(i) + ": " + list[i]->overlayEntry->name;
std::string description = GetActorDescription(list[i]->id);
if (description != "")
label += " (" + description + ")";
if (ImGui::Selectable(label.c_str())) {
rm = LIST;
display = *list[i];
actor = i;
filler = label;
break;
}
}
ImGui::EndCombo();
}
if (ImGui::TreeNode("Selected Actor")) {
dispOverlay = display.overlayEntry;
DrawGroupWithBorder([&]() {
ImGui::Text("Name: %s", dispOverlay != nullptr ? dispOverlay->name : "???");
ImGui::Text("Description: %s", dispOverlay != nullptr ? GetActorDescription(display.id).c_str() : "???");
ImGui::Text("Category: %s", dispOverlay != nullptr ? acMapping[display.category] : "???");
ImGui::Text("ID: %d", display.id);
ImGui::Text("Parameters: %d", display.params);
});
ImGui::PushItemWidth(ImGui::GetFontSize() * 6);
DrawGroupWithBorder([&]() {
ImGui::Text("Actor Position");
ImGui::InputScalar("x pos", ImGuiDataType_Float, &display.world.pos.x);
ImGui::SameLine();
ImGui::InputScalar("y pos", ImGuiDataType_Float, &display.world.pos.y);
ImGui::SameLine();
ImGui::InputScalar("z pos", ImGuiDataType_Float, &display.world.pos.z);
});
DrawGroupWithBorder([&]() {
ImGui::Text("Actor Rotation");
ImGui::InputScalar("x rot", ImGuiDataType_S16, &display.world.rot.x);
ImGui::SameLine();
ImGui::InputScalar("y rot", ImGuiDataType_S16, &display.world.rot.y);
ImGui::SameLine();
ImGui::InputScalar("z rot", ImGuiDataType_S16, &display.world.rot.z);
});
if (display.category == ACTORCAT_BOSS || display.category == ACTORCAT_ENEMY) {
ImGui::InputScalar("Enemy Health", ImGuiDataType_U8, &display.colChkInfo.health);
InsertHelpHoverText("Some actors might not use this!");
}
if (ImGui::Button("Refresh")) {
PopulateActorDropdown(category, list);
switch (rm) {
case INTERACT:
case HELD:
case TARGET:
display = *fetch;
break;
case LIST:
display = *list[actor];
break;
default:
break;
}
}
if (ImGui::Button("Go to Actor")) {
Player* player = GET_PLAYER(gGlobalCtx);
Math_Vec3f_Copy(&player->actor.world.pos, &display.world.pos);
Math_Vec3f_Copy(&player->actor.home.pos, &player->actor.world.pos);
}
if (ImGui::Button("Fetch from Target")) {
Player* player = GET_PLAYER(gGlobalCtx);
fetch = player->targetActor;
if (fetch != NULL) {
display = *fetch;
category = fetch->category;
PopulateActorDropdown(category, list);
rm = TARGET;
}
}
InsertHelpHoverText("Grabs actor with target arrow above it. You might need C-Up for enemies");
if (ImGui::Button("Fetch from Held")) {
Player* player = GET_PLAYER(gGlobalCtx);
fetch = player->heldActor;
if (fetch != NULL) {
display = *fetch;
category = fetch->category;
PopulateActorDropdown(category, list);
rm = HELD;
}
}
InsertHelpHoverText("Grabs actor that Link is holding");
if (ImGui::Button("Fetch from Interaction")) {
Player* player = GET_PLAYER(gGlobalCtx);
fetch = player->interactRangeActor;
if (fetch != NULL) {
display = *fetch;
category = fetch->category;
PopulateActorDropdown(category, list);
rm = INTERACT;
}
}
InsertHelpHoverText("Grabs actor from \"interaction range\"");
ImGui::TreePop();
}
if (ImGui::TreeNode("New...")) {
ImGui::PushItemWidth(ImGui::GetFontSize() * 10);
ImGui::InputScalar("ID", ImGuiDataType_S16, &newActor.id, &one);
ImGui::InputScalar("params", ImGuiDataType_S16, &newActor.params, &one);
ImGui::PushItemWidth(ImGui::GetFontSize() * 6);
DrawGroupWithBorder([&]() {
ImGui::Text("New Actor Position");
ImGui::InputScalar("posX", ImGuiDataType_Float, &newActor.pos.x);
ImGui::SameLine();
ImGui::InputScalar("posY", ImGuiDataType_Float, &newActor.pos.y);
ImGui::SameLine();
ImGui::InputScalar("posZ", ImGuiDataType_Float, &newActor.pos.z);
});
DrawGroupWithBorder([&]() {
ImGui::Text("New Actor Rotation");
ImGui::InputScalar("rotX", ImGuiDataType_S16, &newActor.rot.x);
ImGui::SameLine();
ImGui::InputScalar("rotY", ImGuiDataType_S16, &newActor.rot.y);
ImGui::SameLine();
ImGui::InputScalar("rotZ", ImGuiDataType_S16, &newActor.rot.z);
});
if (ImGui::Button("Fetch from Link")) {
Player* player = GET_PLAYER(gGlobalCtx);
Vec3f newPos = player->actor.world.pos;
Vec3s newRot = player->actor.world.rot;
newActor.pos = newPos;
newActor.rot = newRot;
}
if (ImGui::Button("Spawn")) {
Actor_Spawn(&gGlobalCtx->actorCtx, gGlobalCtx, newActor.id, newActor.pos.x, newActor.pos.y,
newActor.pos.z, newActor.rot.x, newActor.rot.y, newActor.rot.z, newActor.params);
}
if (ImGui::Button("Spawn as Child")) {
Actor* parent = &display;
if (parent != NULL) {
Actor_SpawnAsChild(&gGlobalCtx->actorCtx, parent, gGlobalCtx, newActor.id, newActor.pos.x,
newActor.pos.y, newActor.pos.z, newActor.rot.x, newActor.rot.y, newActor.rot.z,
newActor.params);
}
}
ImGui::TreePop();
}
} else {
ImGui::Text("Global Context needed for actor info!");
if (needs_reset) {
fetch = nullptr;
dispOverlay = nullptr;
newActor = { 0, 0, { 0, 0, 0 }, { 0, 0, 0 } };
actor = category = 0;
filler = "Please Select";
list.clear();
needs_reset = false;
}
}
ImGui::End();
}
void InitActorViewer() {
SohImGui::AddWindow("Developer Tools", "Actor Viewer", DrawActorViewer);
}

View File

@ -0,0 +1,3 @@
#pragma once
void InitActorViewer();

View File

@ -1316,6 +1316,9 @@ void DrawPlayerTab() {
case ITEM_SWORD_BGS:
curSword = "Biggoron's Sword";
break;
case ITEM_FISHING_POLE:
curSword = "Fishing Pole";
break;
case ITEM_NONE:
curSword = "None";
break;
@ -1463,6 +1466,11 @@ void DrawPlayerTab() {
Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_BGS);
}
if (ImGui::Selectable("Fishing Pole")) {
player->currentSwordItem = ITEM_FISHING_POLE;
gSaveContext.equips.buttonItems[0] = ITEM_FISHING_POLE;
Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_MASTER);
}
ImGui::EndCombo();
}

View File

@ -1,12 +1,14 @@
#include "debugger.h"
#include "debugSaveEditor.h"
#include "colViewer.h"
#include "actorViewer.h"
extern "C" {
void Debug_Init(void) {
InitSaveEditor();
InitColViewer();
InitActorViewer();
}
void Debug_Draw(void) {

View File

@ -6,6 +6,10 @@ s32 sShrinkWindowVal = 0;
s32 sShrinkWindowCurrentVal = 0;
void ShrinkWindow_SetVal(s32 value) {
if (CVar_GetS32("gDisableBlackBars", 0)) {
sShrinkWindowVal = 0;
return;
}
if (HREG(80) == 0x13 && HREG(81) == 1) {
osSyncPrintf("shrink_window_setval(%d)\n", value);
}
@ -17,6 +21,10 @@ u32 ShrinkWindow_GetVal(void) {
}
void ShrinkWindow_SetCurrentVal(s32 currentVal) {
if (CVar_GetS32("gDisableBlackBars", 0)) {
sShrinkWindowCurrentVal = 0;
return;
}
if (HREG(80) == 0x13 && HREG(81) == 1) {
osSyncPrintf("shrink_window_setnowval(%d)\n", currentVal);
}

View File

@ -339,19 +339,19 @@ void func_8002BF60(TargetContext* targetCtx, Actor* actor, s32 actorCategory, Gl
if (CVar_GetS32("gUseNaviCol",0) != 1 ) {
if (actorCategory == ACTORCAT_PLAYER) {
naviColor->inner.r = 255; naviColor->inner.g = 255; naviColor->inner.b = 255;
naviColor->outer.r = 115; naviColor->outer.g = 230; naviColor->outer.b = 255;
naviColor->outer.r = 0; naviColor->outer.g = 0; naviColor->outer.b = 255;
}
if (actorCategory == ACTORCAT_NPC) {
naviColor->inner.r = 100; naviColor->inner.g = 100; naviColor->inner.b = 255;
naviColor->outer.r = 90; naviColor->outer.g = 90; naviColor->outer.b = 255;
naviColor->inner.r = 150; naviColor->inner.g = 150; naviColor->inner.b = 255;
naviColor->outer.r = 150; naviColor->outer.g = 150; naviColor->outer.b = 255;
}
if (actorCategory == ACTORCAT_BOSS || actorCategory == ACTORCAT_ENEMY) {
naviColor->inner.r = 255; naviColor->inner.g = 255; naviColor->inner.b = 0;
naviColor->outer.r = 220; naviColor->outer.g = 220; naviColor->outer.b = 0;
naviColor->outer.r = 220; naviColor->outer.g = 155; naviColor->outer.b = 0;
}
if (actorCategory == ACTORCAT_PROP) {
naviColor->inner.r = 0; naviColor->inner.g = 255; naviColor->inner.b = 90;
naviColor->outer.r = 0; naviColor->outer.g = 220; naviColor->outer.b = 0;
naviColor->inner.r = 0; naviColor->inner.g = 255; naviColor->inner.b = 0;
naviColor->outer.r = 0; naviColor->outer.g = 255; naviColor->outer.b = 0;
}
} else {
if (actorCategory == ACTORCAT_PLAYER) {
@ -1163,7 +1163,9 @@ void Actor_Init(Actor* actor, GlobalContext* globalCtx) {
actor->uncullZoneForward = 1000.0f;
actor->uncullZoneScale = 350.0f;
actor->uncullZoneDownward = 700.0f;
if (CVar_GetS32("gDisableDrawDistance", 0) != 0) {
if (CVar_GetS32("gDisableDrawDistance", 0) != 0 && actor->id != ACTOR_EN_TORCH2 && actor->id != ACTOR_EN_BLKOBJ // Extra check for Dark Link and his room
&& actor->id != ACTOR_EN_HORSE // Check for Epona, else if we call her she will spawn at the other side of the map + we can hear her during the title screen sequence
&& actor->id != ACTOR_EN_HORSE_GANON && actor->id != ACTOR_EN_HORSE_ZELDA) { // check for Zelda's and Ganondorf's horses that will always be scene during cinematic whith camera paning
actor->uncullZoneForward = 32767.0f;
actor->uncullZoneScale = 32767.0f;
actor->uncullZoneDownward = 32767.0f;
@ -2690,7 +2692,9 @@ s32 func_800314B0(GlobalContext* globalCtx, Actor* actor) {
s32 func_800314D4(GlobalContext* globalCtx, Actor* actor, Vec3f* arg2, f32 arg3) {
f32 var;
if (CVar_GetS32("gDisableDrawDistance", 0) != 0) {
if (CVar_GetS32("gDisableDrawDistance", 0) != 0 && actor->id != ACTOR_EN_TORCH2 && actor->id != ACTOR_EN_BLKOBJ // Extra check for Dark Link and his room
&& actor->id != ACTOR_EN_HORSE // Check for Epona, else if we call her she will spawn at the other side of the map + we can hear her during the title screen sequence
&& actor->id != ACTOR_EN_HORSE_GANON && actor->id != ACTOR_EN_HORSE_ZELDA) { // check for Zelda's and Ganondorf's horses that will always be scene during cinematic whith camera paning
return true;
}

View File

@ -896,6 +896,9 @@ void EnItem00_Update(Actor* thisx, GlobalContext* globalCtx) {
if (this->unk_15A > 0) {
this->unk_15A--;
if (CVar_GetS32("gDropsDontDie", 0) && (this->unk_154 <= 0)) {
this->unk_15A++;
}
}
if ((this->unk_15A > 0) && (this->unk_15A < 41) && (this->unk_154 <= 0)) {

View File

@ -755,22 +755,23 @@ void Minimap_Draw(GlobalContext* globalCtx) {
if (((globalCtx->sceneNum != SCENE_SPOT01) && (globalCtx->sceneNum != SCENE_SPOT04) &&
(globalCtx->sceneNum != SCENE_SPOT08)) ||
(LINK_AGE_IN_YEARS != YEARS_ADULT)) {
bool Map0 = gMapData->owEntranceIconPosY[sEntranceIconMapIndex] << 2 == 0;
s16 IconSize = 8;
s16 PosX = gMapData->owEntranceIconPosX[sEntranceIconMapIndex]+Right_MM_Margin;
s16 PosY = gMapData->owEntranceIconPosY[sEntranceIconMapIndex]+Bottom_MM_Margin;
s16 PosX = gMapData->owEntranceIconPosX[sEntranceIconMapIndex] + (Map0 ? 0 : Right_MM_Margin);
s16 PosY = gMapData->owEntranceIconPosY[sEntranceIconMapIndex] + (Map0 ? 0 : Bottom_MM_Margin);
//gFixDungeonMinimapIcon fix both Y position of visible icon and hide these non needed.
if (CVar_GetS32("gFixDungeonMinimapIcon", 1) != 0){
if (CVar_GetS32("gFixDungeonMinimapIcon", 0) != 0){
//No idea why and how Original value work but this does actually fix them all.
PosY = PosY+1024;
}
s16 TopLeftX = OTRGetRectDimensionFromRightEdge(PosX) << 2;
s16 TopLeftX = (Map0 ? OTRGetRectDimensionFromLeftEdge(PosX) : OTRGetRectDimensionFromRightEdge(PosX)) << 2;
s16 TopLeftY = PosY << 2;
s16 TopLeftW = OTRGetRectDimensionFromRightEdge(PosX + IconSize) << 2;
s16 TopLeftW = (Map0 ? OTRGetRectDimensionFromLeftEdge(PosX + IconSize) : OTRGetRectDimensionFromRightEdge(PosX + IconSize)) << 2;
s16 TopLeftH = (PosY + IconSize) << 2;
if ((gMapData->owEntranceFlag[sEntranceIconMapIndex] == 0xFFFF) ||
((gMapData->owEntranceFlag[sEntranceIconMapIndex] != 0xFFFF) &&
(gSaveContext.infTable[26] & gBitFlags[gMapData->owEntranceFlag[mapIndex]]))) {
if (gMapData->owEntranceIconPosY[sEntranceIconMapIndex] << 2 != 0 && CVar_GetS32("gFixDungeonMinimapIcon", 1) != 0){
if (!Map0 || !CVar_GetS32("gFixDungeonMinimapIcon", 0)) {
gDPLoadTextureBlock(OVERLAY_DISP++, gMapDungeonEntranceIconTex, G_IM_FMT_RGBA, G_IM_SIZ_16b,
IconSize, IconSize, 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);

View File

@ -2935,7 +2935,7 @@ void Interface_DrawItemButtons(GlobalContext* globalCtx) {
}
const s16 rCUpBtnX = OTRGetRectDimensionFromRightEdge(R_C_UP_BTN_X+Right_HUD_Margin);
const s16 rCUPIconX = OTRGetRectDimensionFromRightEdge(R_C_UP_ICON_X+Right_HUD_Margin);
const s16 rCUPIconX = OTRGetRectDimensionFromRightEdge(R_C_UP_ICON_X+Right_HUD_Margin-!!CVar_GetS32("gNaviTextFix", 0));
if (CVar_GetS32("gHudColors", 1) == 0) {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, R_C_BTN_COLOR(0), R_C_BTN_COLOR(1), R_C_BTN_COLOR(2), temp);
} else if (CVar_GetS32("gHudColors", 1) == 1) {

View File

@ -1209,19 +1209,15 @@ void BossGanon_ShatterWindows(u8 windowShatterState) {
}
void BossGanon_DeathAndTowerCutscene(BossGanon* this, GlobalContext* globalCtx) {
const bool originalBlood = CVar_GetS32("gOriginalBlood", 1);
static Color_RGBA8 bloodPrimColor = { 0, 120, 0, 255 };
static Color_RGBA8 bloodEnvColor = { 0, 120, 0, 255 };
static Color_RGBA8 bloodPrimColor = { 120, 0, 0, 255 };
static Color_RGBA8 bloodEnvColor = { 120, 0, 0, 255 };
if(CVar_GetS32("gRedGanonBlood", 0)) {
bloodPrimColor.r = 120;
bloodPrimColor.g = 0;
if(!originalBlood) {
bloodPrimColor.r = 0;
bloodPrimColor.g = 120;
bloodPrimColor.b = 0;
bloodEnvColor.r = 0;
bloodEnvColor.g = 120;
bloodEnvColor.b = 0;
bloodEnvColor.r = 120;
bloodEnvColor.g = 0;
}
s16 i;

View File

@ -1456,6 +1456,17 @@ void func_80901020(BossGanon2* this, GlobalContext* globalCtx) {
void func_8090109C(BossGanon2* this, GlobalContext* globalCtx) {
u8 i;
static Color_RGBA8 sPrimColor = { 0, 120, 0, 255 };
static Color_RGBA8 sEnvColor = { 0, 120, 0, 255 };
if(CVar_GetS32("gRedGanonBlood", 0)) {
sPrimColor.r = 120;
sPrimColor.g = 0;
sEnvColor.r = 120;
sEnvColor.g = 0;
}
for (i = 0; i < 70; i++) {
Vec3f velocity;
Vec3f accel;

View File

@ -238,10 +238,6 @@ static ColliderJntSphInit sJntSphInit2 = {
sJntSphItemsInit2,
};
static Color_RGBA8 sPrimColor = { 0, 120, 0, 255 };
static Color_RGBA8 sEnvColor = { 0, 120, 0, 255 };
static Vec3f D_8090702C[] = {
{ 10.0f, -10.0f, 0.0f },
{ 0.0f, 0.0f, -60.0f },

View File

@ -118,7 +118,7 @@ void EnCow_Init(Actor* thisx, GlobalContext* globalCtx) {
func_809DEE9C(this);
this->actionFunc = func_809DF96C;
if (globalCtx->sceneNum == SCENE_LINK_HOME) {
if (!LINK_IS_ADULT) {
if (!LINK_IS_ADULT && !CVar_GetS32("gCowOfTime", 0)) {
Actor_Kill(&this->actor);
return;
}

View File

@ -1053,7 +1053,7 @@ void func_80A98CD8(EnKo* this) {
this->actor.targetMode = info->targetMode;
this->lookDist = info->lookDist;
this->lookDist += this->collider.dim.radius;
this->appearDist = info->appearDist;
this->appearDist = CVar_GetS32("gDisableKokiriDrawDistance", 0) != 0 ? 32767 : info->appearDist;
}
// Used to fetch actor animation?

View File

@ -94,7 +94,9 @@ void func_80AFB768(EnSi* this, GlobalContext* globalCtx) {
if (this->collider.base.ocFlags2 & OC2_HIT_PLAYER) {
this->collider.base.ocFlags2 &= ~OC2_HIT_PLAYER;
Item_Give(globalCtx, ITEM_SKULL_TOKEN);
player->actor.freezeTimer = 10;
if (CVar_GetS32("gSkulltulaFreeze", 0) != 1) {
player->actor.freezeTimer = 20;
}
Message_StartTextbox(globalCtx, 0xB4, NULL);
Audio_PlayFanfare(NA_BGM_SMALL_ITEM_GET);
this->actionFunc = func_80AFB950;
@ -116,7 +118,6 @@ void func_80AFB89C(EnSi* this, GlobalContext* globalCtx) {
if (!CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_13)) {
Item_Give(globalCtx, ITEM_SKULL_TOKEN);
player->actor.freezeTimer = 10;
Message_StartTextbox(globalCtx, 0xB4, NULL);
Audio_PlayFanfare(NA_BGM_SMALL_ITEM_GET);
this->actionFunc = func_80AFB950;
@ -126,7 +127,7 @@ void func_80AFB89C(EnSi* this, GlobalContext* globalCtx) {
void func_80AFB950(EnSi* this, GlobalContext* globalCtx) {
Player* player = GET_PLAYER(globalCtx);
if (Message_GetState(&globalCtx->msgCtx) != TEXT_STATE_CLOSING) {
if (Message_GetState(&globalCtx->msgCtx) != TEXT_STATE_CLOSING && CVar_GetS32("gSkulltulaFreeze", 0) != 1) {
player->actor.freezeTimer = 10;
} else {
SET_GS_FLAGS((this->actor.params & 0x1F00) >> 8, this->actor.params & 0xFF);

View File

@ -140,8 +140,9 @@ void OceffStorm_Draw2(Actor* thisx, GlobalContext* globalCtx) {
gSPDisplayList(POLY_XLU_DISP++, sMaterialDL);
gSPDisplayList(POLY_XLU_DISP++, Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, scroll * 8, scroll * 4, 64, 64, 1,
scroll * 4, scroll * 4, 64, 64));
gSPTextureRectangle(POLY_XLU_DISP++, 0, 0, (SCREEN_WIDTH << 2), (SCREEN_HEIGHT << 2), G_TX_RENDERTILE, 0, 0, 140,
(1 << 15) | (31 << 10) | 884);
gSPWideTextureRectangle(POLY_XLU_DISP++, OTRGetRectDimensionFromLeftEdge(0) << 2, 0,
OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH) << 2, 0x03C0, G_TX_RENDERTILE, 0, 0, 0x008C,
-0x008C);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_oceff_storm.c", 477);
}

View File

@ -2779,22 +2779,24 @@ void func_80835F44(GlobalContext* globalCtx, Player* this, s32 item) {
if (actionParam >= PLAYER_AP_BOOTS_KOKIRI) {
u16 bootsValue = actionParam - PLAYER_AP_BOOTS_KOKIRI + 1;
if (CUR_EQUIP_VALUE(EQUIP_BOOTS) == bootsValue) {
Inventory_ChangeEquipment(EQUIP_BOOTS, 1);
Inventory_ChangeEquipment(EQUIP_BOOTS, PLAYER_BOOTS_KOKIRI + 1);
} else {
Inventory_ChangeEquipment(EQUIP_BOOTS, bootsValue);
}
Player_SetEquipmentData(globalCtx, this);
func_808328EC(this, CUR_EQUIP_VALUE(EQUIP_BOOTS) == PLAYER_BOOTS_IRON + 1 ? NA_SE_PL_WALK_HEAVYBOOTS : NA_SE_PL_CHANGE_ARMS);
return;
}
if (actionParam >= PLAYER_AP_TUNIC_KOKIRI) {
u16 tunicValue = actionParam - PLAYER_AP_TUNIC_KOKIRI + 1;
if (CUR_EQUIP_VALUE(EQUIP_TUNIC) == tunicValue) {
Inventory_ChangeEquipment(EQUIP_TUNIC, 1);
Inventory_ChangeEquipment(EQUIP_TUNIC, PLAYER_TUNIC_KOKIRI + 1);
} else {
Inventory_ChangeEquipment(EQUIP_TUNIC, tunicValue);
}
Player_SetEquipmentData(globalCtx, this);
func_808328EC(this, NA_SE_PL_CHANGE_ARMS);
return;
}
@ -3707,7 +3709,7 @@ s32 func_8083816C(s32 arg0) {
}
void func_8083819C(Player* this, GlobalContext* globalCtx) {
if (this->currentShield == PLAYER_SHIELD_DEKU) {
if (this->currentShield == PLAYER_SHIELD_DEKU && (CVar_GetS32("gFireproofDekuShield", 0) == 0)) {
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_ITEM_SHIELD, this->actor.world.pos.x,
this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 1);
Inventory_DeleteEquipment(globalCtx, EQUIP_SHIELD);
@ -5468,8 +5470,8 @@ s32 func_8083C6B8(GlobalContext* globalCtx, Player* this) {
sp24 = this->actor.world.pos;
sp24.y += 50.0f;
if (!(this->actor.bgCheckFlags & 1) || (this->actor.world.pos.z > 1300.0f) ||
BgCheck_SphVsFirstPoly(&globalCtx->colCtx, &sp24, 20.0f)) {
if (CVar_GetS32("gHoverFishing", 0) ? 0 : !(this->actor.bgCheckFlags & 1) ||
(this->actor.world.pos.z > 1300.0f) || BgCheck_SphVsFirstPoly(&globalCtx->colCtx, &sp24, 20.0f)) {
func_80078884(NA_SE_SY_ERROR);
return 0;
}
@ -6179,6 +6181,9 @@ s32 func_8083E5A8(Player* this, GlobalContext* globalCtx) {
if (this->getItemId != GI_NONE) {
GetItemEntry* giEntry = &sGetItemTable[-this->getItemId - 1];
EnBox* chest = (EnBox*)interactedActor;
if(CVar_GetS32("gFastChests", 0) != 0) {
giEntry->gi = -1 * abs(giEntry->gi);
}
if (giEntry->itemId != ITEM_NONE) {
if (((Item_CheckObtainability(giEntry->itemId) == ITEM_NONE) && (giEntry->field & 0x40)) ||
@ -11621,7 +11626,7 @@ void func_8084BF1C(Player* this, GlobalContext* globalCtx) {
phi_f2 = -1.0f;
}
this->skelAnime.playSpeed = phi_f2 * phi_f0;
this->skelAnime.playSpeed = phi_f2 * phi_f0 + phi_f2 * CVar_GetS32("gClimbSpeed", 0);
if (this->unk_850 >= 0) {
if ((this->actor.wallPoly != NULL) && (this->actor.wallBgId != BGCHECK_SCENE)) {

View File

@ -640,9 +640,13 @@ void KaleidoScope_DrawDebugEditor(GlobalContext* globalCtx) {
// Handles exiting the inventory editor with the L button
// The editor is opened with `debugState` set to 1, and becomes closable after a frame once `debugState` is set to 2
s16 Debug_BTN = BTN_L;
if (CVar_GetS32("gNGCKaleidoSwitcher", 0) != 0) {
Debug_BTN = BTN_Z;
}
if (pauseCtx->debugState == 1) {
pauseCtx->debugState = 2;
} else if ((pauseCtx->debugState == 2) && CHECK_BTN_ALL(input->press.button, BTN_L)) {
} else if ((pauseCtx->debugState == 2) && CHECK_BTN_ALL(input->press.button, Debug_BTN)) {
pauseCtx->debugState = 0;
}

View File

@ -930,7 +930,14 @@ void KaleidoScope_SwitchPage(PauseContext* pauseCtx, u8 pt) {
}
void KaleidoScope_HandlePageToggles(PauseContext* pauseCtx, Input* input) {
if (CVar_GetS32("gDebugEnabled", 0) && (pauseCtx->debugState == 0) && CHECK_BTN_ALL(input->press.button, BTN_L)) {
s16 Debug_BTN = BTN_L;
s16 PageLeft_BTN = BTN_Z;
if (CVar_GetS32("gNGCKaleidoSwitcher", 0) != 0) {
Debug_BTN = BTN_Z;
PageLeft_BTN = BTN_L;
}
if (CVar_GetS32("gDebugEnabled", 0) && (pauseCtx->debugState == 0) && CHECK_BTN_ALL(input->press.button, Debug_BTN)) {
pauseCtx->debugState = 1;
return;
}
@ -940,7 +947,7 @@ void KaleidoScope_HandlePageToggles(PauseContext* pauseCtx, Input* input) {
return;
}
if (CHECK_BTN_ALL(input->press.button, BTN_Z)) {
if (CHECK_BTN_ALL(input->press.button, PageLeft_BTN)) {
KaleidoScope_SwitchPage(pauseCtx, 0);
return;
}