summaryrefslogtreecommitdiff
path: root/mm/2s2h/DeveloperTools/DeveloperTools.cpp
diff options
context:
space:
mode:
authorArchez <Archez@users.noreply.github.com>2025-03-31 11:30:47 -0400
committerGitHub <noreply@github.com>2025-03-31 10:30:47 -0500
commit60e7d5d5c31a3a9b4f921df7df35ce2c49010656 (patch)
tree7d156c7c3a5eb58a311475e08c51757aeaa65906 /mm/2s2h/DeveloperTools/DeveloperTools.cpp
parent0de405af1e1e11a176e2a4881a6f2a1f0e586a03 (diff)
ShipInit DevTools and WarpPoint improvements (#1075)
* shipinit developer tools * shipinit warppoint and rework menu rendering
Diffstat (limited to 'mm/2s2h/DeveloperTools/DeveloperTools.cpp')
-rw-r--r--mm/2s2h/DeveloperTools/DeveloperTools.cpp215
1 files changed, 113 insertions, 102 deletions
diff --git a/mm/2s2h/DeveloperTools/DeveloperTools.cpp b/mm/2s2h/DeveloperTools/DeveloperTools.cpp
index 5dd04fe61..2130b6eec 100644
--- a/mm/2s2h/DeveloperTools/DeveloperTools.cpp
+++ b/mm/2s2h/DeveloperTools/DeveloperTools.cpp
@@ -2,6 +2,7 @@
#include "BenPort.h"
#include <libultraship/libultraship.h>
#include "2s2h/GameInteractor/GameInteractor.h"
+#include "2s2h/ShipInit.hpp"
extern "C" {
#include "macros.h"
@@ -18,125 +19,119 @@ void Inventory_SetWorldMapCloudVisibility(s16 tingleIndex);
extern u16 sPersistentCycleWeekEventRegs[ARRAY_COUNT(gSaveContext.save.saveInfo.weekEventReg)];
}
-void RegisterDebugSaveCreate() {
- static HOOK_ID hookId = 0;
- if (hookId != 0) {
- GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnSaveInit>(hookId);
- hookId = 0;
- }
+#define CVAR_DEBUG_MODE_NAME "gDeveloperTools.DebugEnabled"
+#define CVAR_DEBUG_MODE CVarGetInteger(CVAR_DEBUG_MODE_NAME, 0)
- if (CVarGetInteger("gDeveloperTools.DebugSaveFileMode", DEBUG_SAVE_INFO_NONE) != DEBUG_SAVE_INFO_NONE) {
- hookId = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSaveInit>([](s16 fileNum) {
- u8 playerName[8];
+#define CVAR_SAVE_FILE_MODE_NAME "gDeveloperTools.DebugSaveFileMode"
+#define CVAR_SAVE_FILE_MODE CVarGetInteger(CVAR_SAVE_FILE_MODE_NAME, DEBUG_SAVE_INFO_NONE)
- // Copy player name and set back after debug save init
- memcpy(playerName, gSaveContext.save.saveInfo.playerData.playerName, sizeof(playerName));
+void SetSaveFileInfo() {
+ u8 playerName[8];
- Sram_InitDebugSave();
+ // Copy player name and set back after debug save init
+ memcpy(playerName, gSaveContext.save.saveInfo.playerData.playerName, sizeof(playerName));
- memcpy(gSaveContext.save.saveInfo.playerData.playerName, playerName, sizeof(playerName));
+ Sram_InitDebugSave();
- // Place link at entrance from clock tower
- gSaveContext.save.entrance = ENTRANCE(SOUTH_CLOCK_TOWN, 0);
- gSaveContext.save.cutsceneIndex = 0;
- gSaveContext.save.saveInfo.checksum = 1;
+ memcpy(gSaveContext.save.saveInfo.playerData.playerName, playerName, sizeof(playerName));
- // Prevent first Song of Time reset from forcing Deku Link and having to learn Song of Healing
- gSaveContext.save.saveInfo.playerData.threeDayResetCount = 1;
+ // Place link at entrance from clock tower
+ gSaveContext.save.entrance = ENTRANCE(SOUTH_CLOCK_TOWN, 0);
+ gSaveContext.save.cutsceneIndex = 0;
+ gSaveContext.save.saveInfo.checksum = 1;
- if (CVarGetInteger("gDeveloperTools.DebugSaveFileMode", DEBUG_SAVE_INFO_NONE) == DEBUG_SAVE_INFO_COMPLETE) {
- gSaveContext.save.saveInfo.playerData.doubleDefense = true;
- gSaveContext.save.saveInfo.playerData.health = 20 * 0x10;
- gSaveContext.save.saveInfo.playerData.healthCapacity = 20 * 0x10;
- gSaveContext.save.saveInfo.playerData.isDoubleMagicAcquired = true;
- gSaveContext.save.saveInfo.playerData.magicLevel = 2;
- gSaveContext.save.saveInfo.playerData.magic = MAGIC_DOUBLE_METER;
- gSaveContext.save.saveInfo.playerData.owlActivationFlags = (1 << (OWL_WARP_STONE_TOWER + 1)) - 1;
- gSaveContext.save.saveInfo.playerData.unk_20 = OWL_WARP_CLOCK_TOWN;
+ // Prevent first Song of Time reset from forcing Deku Link and having to learn Song of Healing
+ gSaveContext.save.saveInfo.playerData.threeDayResetCount = 1;
- gSaveContext.save.saveInfo.inventory.defenseHearts = 20;
- gSaveContext.save.saveInfo.regionsVisited = (1 << REGION_MAX) - 1;
- gSaveContext.magicCapacity = MAGIC_DOUBLE_METER;
+ if (CVAR_SAVE_FILE_MODE == DEBUG_SAVE_INFO_COMPLETE) {
+ gSaveContext.save.saveInfo.playerData.doubleDefense = true;
+ gSaveContext.save.saveInfo.playerData.health = 20 * 0x10;
+ gSaveContext.save.saveInfo.playerData.healthCapacity = 20 * 0x10;
+ gSaveContext.save.saveInfo.playerData.isDoubleMagicAcquired = true;
+ gSaveContext.save.saveInfo.playerData.magicLevel = 2;
+ gSaveContext.save.saveInfo.playerData.magic = MAGIC_DOUBLE_METER;
+ gSaveContext.save.saveInfo.playerData.owlActivationFlags = (1 << (OWL_WARP_STONE_TOWER + 1)) - 1;
+ gSaveContext.save.saveInfo.playerData.unk_20 = OWL_WARP_CLOCK_TOWN;
- Inventory_ChangeUpgrade(UPG_WALLET, 2);
- Inventory_ChangeUpgrade(UPG_BOMB_BAG, 3);
- Inventory_ChangeUpgrade(UPG_QUIVER, 3);
+ gSaveContext.save.saveInfo.inventory.defenseHearts = 20;
+ gSaveContext.save.saveInfo.regionsVisited = (1 << REGION_MAX) - 1;
+ gSaveContext.magicCapacity = MAGIC_DOUBLE_METER;
- for (int32_t i = 0; i < TINGLE_MAP_MAX; i++) {
- Inventory_SetWorldMapCloudVisibility(i);
- }
+ Inventory_ChangeUpgrade(UPG_WALLET, 2);
+ Inventory_ChangeUpgrade(UPG_BOMB_BAG, 3);
+ Inventory_ChangeUpgrade(UPG_QUIVER, 3);
- gSaveContext.save.saveInfo.playerData.rupees = CUR_CAPACITY(UPG_WALLET);
- AMMO(ITEM_BOW) = CUR_CAPACITY(UPG_QUIVER);
- AMMO(ITEM_BOMB) = AMMO(ITEM_BOMBCHU) = CUR_CAPACITY(UPG_BOMB_BAG);
- AMMO(ITEM_DEKU_STICK) = CUR_CAPACITY(UPG_DEKU_STICKS);
- AMMO(ITEM_DEKU_NUT) = CUR_CAPACITY(UPG_DEKU_NUTS);
- AMMO(ITEM_MAGIC_BEANS) = 20;
- AMMO(ITEM_POWDER_KEG) = 1;
-
- SET_EQUIP_VALUE(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_MIRROR);
- SET_EQUIP_VALUE(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_GILDED);
- BUTTON_ITEM_EQUIP(0, EQUIP_SLOT_B) = ITEM_SWORD_GILDED;
-
- for (int32_t i = SLOT_BOTTLE_1; i <= SLOT_BOTTLE_6; i++) {
- if (gSaveContext.save.saveInfo.inventory.items[i] == ITEM_NONE) {
- gSaveContext.save.saveInfo.inventory.items[i] = ITEM_BOTTLE;
- }
- }
+ for (int32_t i = 0; i < TINGLE_MAP_MAX; i++) {
+ Inventory_SetWorldMapCloudVisibility(i);
+ }
- for (int32_t i = QUEST_REMAINS_ODOLWA; i <= QUEST_BOMBERS_NOTEBOOK; i++) {
- if (i != QUEST_SHIELD && i != QUEST_SWORD && i != QUEST_SONG_SARIA && i != QUEST_SONG_SUN) {
- SET_QUEST_ITEM(i);
- }
- }
+ gSaveContext.save.saveInfo.playerData.rupees = CUR_CAPACITY(UPG_WALLET);
+ AMMO(ITEM_BOW) = CUR_CAPACITY(UPG_QUIVER);
+ AMMO(ITEM_BOMB) = AMMO(ITEM_BOMBCHU) = CUR_CAPACITY(UPG_BOMB_BAG);
+ AMMO(ITEM_DEKU_STICK) = CUR_CAPACITY(UPG_DEKU_STICKS);
+ AMMO(ITEM_DEKU_NUT) = CUR_CAPACITY(UPG_DEKU_NUTS);
+ AMMO(ITEM_MAGIC_BEANS) = 20;
+ AMMO(ITEM_POWDER_KEG) = 1;
+
+ SET_EQUIP_VALUE(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_MIRROR);
+ SET_EQUIP_VALUE(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_GILDED);
+ BUTTON_ITEM_EQUIP(0, EQUIP_SLOT_B) = ITEM_SWORD_GILDED;
- // Use the persistent cycle events to set what a 100% save would normally keep
- for (int32_t i = 0; i < ARRAY_COUNT(sPersistentCycleWeekEventRegs); i++) {
- u16 isPersistentBits = sPersistentCycleWeekEventRegs[i];
-
- // Force all bits on
- gSaveContext.save.saveInfo.weekEventReg[i] = 0xFF;
-
- // Then unset any bits that aren't persistent
- for (int32_t j = 0; j < 8; j++) {
- if (!(isPersistentBits & 3)) {
- gSaveContext.save.saveInfo.weekEventReg[i] =
- gSaveContext.save.saveInfo.weekEventReg[i] & (0xFF ^ (1 << j));
- }
- isPersistentBits >>= 2;
- }
+ for (int32_t i = SLOT_BOTTLE_1; i <= SLOT_BOTTLE_6; i++) {
+ if (gSaveContext.save.saveInfo.inventory.items[i] == ITEM_NONE) {
+ gSaveContext.save.saveInfo.inventory.items[i] = ITEM_BOTTLE;
+ }
+ }
+
+ for (int32_t i = QUEST_REMAINS_ODOLWA; i <= QUEST_BOMBERS_NOTEBOOK; i++) {
+ if (i != QUEST_SHIELD && i != QUEST_SWORD && i != QUEST_SONG_SARIA && i != QUEST_SONG_SUN) {
+ SET_QUEST_ITEM(i);
+ }
+ }
+
+ // Use the persistent cycle events to set what a 100% save would normally keep
+ for (int32_t i = 0; i < ARRAY_COUNT(sPersistentCycleWeekEventRegs); i++) {
+ u16 isPersistentBits = sPersistentCycleWeekEventRegs[i];
+
+ // Force all bits on
+ gSaveContext.save.saveInfo.weekEventReg[i] = 0xFF;
+
+ // Then unset any bits that aren't persistent
+ for (int32_t j = 0; j < 8; j++) {
+ if (!(isPersistentBits & 3)) {
+ gSaveContext.save.saveInfo.weekEventReg[i] =
+ gSaveContext.save.saveInfo.weekEventReg[i] & (0xFF ^ (1 << j));
}
+ isPersistentBits >>= 2;
}
- });
+ }
}
}
-void RegisterPreventActorUpdateHooks() {
- static HOOK_ID hookId = 0;
- if (hookId != 0) {
- GameInteractor::Instance->UnregisterGameHook<GameInteractor::ShouldActorUpdate>(hookId);
- hookId = 0;
- }
+void RegisterDebugSaveCreate() {
+ COND_HOOK(OnSaveInit, CVAR_SAVE_FILE_MODE != DEBUG_SAVE_INFO_NONE && CVAR_DEBUG_MODE,
+ [](s16 fileNum) { SetSaveFileInfo(); });
+}
- if (CVarGetInteger("gDeveloperTools.PreventActorUpdate", 0)) {
- hookId = GameInteractor::Instance->RegisterGameHook<GameInteractor::ShouldActorUpdate>(
- [](Actor* actor, bool* result) { *result = false; });
- }
+#define CVAR_PREVENT_ACTOR_UPDATE_NAME "gDeveloperTools.PreventActorUpdate"
+#define CVAR_PREVENT_ACTOR_UPDATE CVarGetInteger(CVAR_PREVENT_ACTOR_UPDATE_NAME, 0)
+
+void RegisterPreventActorUpdateHooks() {
+ COND_HOOK(ShouldActorUpdate, CVAR_PREVENT_ACTOR_UPDATE && CVAR_DEBUG_MODE,
+ [](Actor* actor, bool* result) { *result = false; });
}
-void RegisterPreventActorDrawHooks() {
- static HOOK_ID hookId = 0;
- if (hookId != 0) {
- GameInteractor::Instance->UnregisterGameHook<GameInteractor::ShouldActorDraw>(hookId);
- hookId = 0;
- }
+#define CVAR_PREVENT_ACTOR_DRAW_NAME "gDeveloperTools.PreventActorDraw"
+#define CVAR_PREVENT_ACTOR_DRAW CVarGetInteger(CVAR_PREVENT_ACTOR_DRAW_NAME, 0)
- if (CVarGetInteger("gDeveloperTools.PreventActorDraw", 0)) {
- hookId = GameInteractor::Instance->RegisterGameHook<GameInteractor::ShouldActorDraw>(
- [](Actor* actor, bool* result) { *result = false; });
- }
+void RegisterPreventActorDrawHooks() {
+ COND_HOOK(ShouldActorDraw, CVAR_PREVENT_ACTOR_DRAW && CVAR_DEBUG_MODE,
+ [](Actor* actor, bool* result) { *result = false; });
}
+#define CVAR_PREVENT_ACTOR_INIT_NAME "gDeveloperTools.PreventActorInit"
+#define CVAR_PREVENT_ACTOR_INIT CVarGetInteger(CVAR_PREVENT_ACTOR_INIT_NAME, 0)
+
void RegisterPreventActorInitHooks() {
static HOOK_ID hookId = 0;
if (hookId != 0) {
@@ -144,16 +139,32 @@ void RegisterPreventActorInitHooks() {
hookId = 0;
}
- if (CVarGetInteger("gDeveloperTools.PreventActorInit", 0)) {
+ if (CVAR_PREVENT_ACTOR_INIT && CVAR_DEBUG_MODE) {
hookId = GameInteractor::Instance->RegisterGameHookForFilter<GameInteractor::ShouldActorInit>(
GameInteractor::HookFilter::SActorNotPlayer, [](Actor* actor, bool* result) { *result = false; });
}
}
-void InitDeveloperTools() {
- RegisterDebugSaveCreate();
- RegisterPreventActorUpdateHooks();
- RegisterPreventActorDrawHooks();
- RegisterPreventActorInitHooks();
- RegisterWarpPoint();
+void RegisterDebugMode() {
+ // Disable various debug options when toggled off
+ if (!CVAR_DEBUG_MODE) {
+ CVarSetInteger(CVAR_SAVE_FILE_MODE_NAME, DEBUG_SAVE_INFO_NONE);
+ CVarSetInteger(CVAR_PREVENT_ACTOR_UPDATE_NAME, 0);
+ CVarSetInteger(CVAR_PREVENT_ACTOR_DRAW_NAME, 0);
+ CVarSetInteger(CVAR_PREVENT_ACTOR_INIT_NAME, 0);
+ CVarSetInteger("gDeveloperTools.DisableObjectDependency", 0);
+
+ if (gPlayState != NULL) {
+ gPlayState->frameAdvCtx.enabled = false;
+ }
+ }
}
+
+RegisterShipInitFunc initFuncDebugMode(RegisterDebugMode, { CVAR_DEBUG_MODE_NAME });
+RegisterShipInitFunc initFuncSaveFile(RegisterDebugSaveCreate, { CVAR_SAVE_FILE_MODE_NAME, CVAR_DEBUG_MODE_NAME });
+RegisterShipInitFunc initFuncActorUpdate(RegisterPreventActorUpdateHooks,
+ { CVAR_PREVENT_ACTOR_UPDATE_NAME, CVAR_DEBUG_MODE_NAME });
+RegisterShipInitFunc initFuncActorDraw(RegisterPreventActorDrawHooks,
+ { CVAR_PREVENT_ACTOR_DRAW_NAME, CVAR_DEBUG_MODE_NAME });
+RegisterShipInitFunc initFuncActorInit(RegisterPreventActorInitHooks,
+ { CVAR_PREVENT_ACTOR_INIT_NAME, CVAR_DEBUG_MODE_NAME });