summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrobojumper <robojumper@gmail.com>2025-05-12 21:35:03 +0200
committerrobojumper <robojumper@gmail.com>2025-05-15 19:05:48 +0200
commit33efdfeec9be71687d07c3a4ab460703c2b7e93a (patch)
tree6e15a79e73cc00e0b7af06e9011b08a845525c89
parentc241dbe301f94839175504f24d70615d67bac8d7 (diff)
More docs
-rw-r--r--config/SOUE01/symbols.txt2
-rw-r--r--include/d/d_message.h26
-rw-r--r--include/toBeSorted/fi_context.h14
-rw-r--r--src/d/d_message.cpp142
-rw-r--r--src/d/lyt/msg_window/d_lyt_msg_window.cpp2
-rw-r--r--src/toBeSorted/fi_context.cpp2
6 files changed, 109 insertions, 79 deletions
diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt
index f11f1d97..a832ccdd 100644
--- a/config/SOUE01/symbols.txt
+++ b/config/SOUE01/symbols.txt
@@ -10897,7 +10897,7 @@ handleJump__7dFlow_cFv = .text:0x801B18D0; // type:function size:0x8
triggerEntryPoint__7dFlow_cFll = .text:0x801B18E0; // type:function size:0x298
triggerEntryPoint__7dFlow_cFPCc = .text:0x801B1B80; // type:function size:0x3C
getField_0x44__7dFlow_cCFv = .text:0x801B1BC0; // type:function size:0x8
-getField_0x46__7dFlow_cCFv = .text:0x801B1BD0; // type:function size:0x8
+getNextFiFlow__7dFlow_cCFv = .text:0x801B1BD0; // type:function size:0x8
triggerEntryPointChecked__7dFlow_cFll = .text:0x801B1BE0; // type:function size:0x80
setField0x3C__7dFlow_cFv = .text:0x801B1C60; // type:function size:0xC
checkField0x3C__7dFlow_cCFv = .text:0x801B1C70; // type:function size:0x14
diff --git a/include/d/d_message.h b/include/d/d_message.h
index 358e7bbc..47c2d84d 100644
--- a/include/d/d_message.h
+++ b/include/d/d_message.h
@@ -38,11 +38,11 @@ public:
// Ghidra: ActorEventFlowManager
class dFlow_c : dFlowBase_c {
enum BranchValue_e {
- BRANCH_00,
- BRANCH_01,
- BRANCH_02,
+ BRANCH_SELECTED_OPTION_0,
+ BRANCH_SELECTED_OPTION_1,
+ BRANCH_SELECTED_OPTION_FI,
BRANCH_STORYFLAG,
- BRANCH_04,
+ BRANCH_NONE,
BRANCH_ZONEFLAG,
BRANCH_SCENEFLAG,
BRANCH_EVENT_COUNTER_THRESHOLD_1,
@@ -52,9 +52,9 @@ class dFlow_c : dFlowBase_c {
BRANCH_RAND_2,
BRANCH_RAND_3,
BRANCH_RAND_4,
- BRANCH_14,
- BRANCH_15,
- BRANCH_16,
+ BRANCH_14, // skipped
+ BRANCH_15, // skipped
+ BRANCH_16, // skipped
BRANCH_FREE_SPACE_IN_POUCH,
BRANCH_18,
BRANCH_19,
@@ -71,7 +71,7 @@ class dFlow_c : dFlowBase_c {
EVENT_SET_ZONEFLAG = 4,
EVENT_UNSET_ZONEFLAG = 5,
EVENT_DELAY = 6,
- EVENT_07 = 7,
+ EVENT_LOAD_FI_FLOW = 7,
EVENT_RUPEES = 8,
EVENT_SET_ITEM = 9,
EVENT_EXIT = 10,
@@ -129,11 +129,15 @@ public:
/* vt 0x3C */ virtual u16 getSwitchChoice(const MsbFlowInfo *element, u16 param) const;
/* vt 0x40 */ virtual bool triggerEntryPointChecked(s32 labelPart1, s32 labelPart2);
+ /**
+ * "Speculatively" evaluate a flow until a given event gets hit, and write
+ * its parameters into the provided pointer. Probably has no side effects.
+ */
bool advanceUntilEvent(s32 searchParam3, s32 *pOutParams1n2);
bool advanceUntil(s32 searchType, s32 searchParam3, s32 *pOutParams1n2);
u16 getField_0x44() const;
- u16 getField_0x46() const;
+ u16 getNextFiFlow() const;
protected:
static s32 sExitId;
@@ -188,10 +192,10 @@ protected:
/* 0x3C */ u8 field_0x3C;
/* 0x40 */ s32 field_0x40;
/* 0x44 */ u16 field_0x44;
- /* 0x46 */ u16 field_0x46;
+ /* 0x46 */ u16 mNextFiFlow;
/* 0x48 */ s32 mDelayTimer;
/* 0x4C */ MsbFlowInfo mFlowInfo;
- /* 0x5C */ s32 field_0x5C;
+ /* 0x5C */ s32 mFiSpeechArgument;
/* 0x60 */ s32 mFiInfo0;
};
diff --git a/include/toBeSorted/fi_context.h b/include/toBeSorted/fi_context.h
index 949c067d..5dde4c4c 100644
--- a/include/toBeSorted/fi_context.h
+++ b/include/toBeSorted/fi_context.h
@@ -63,21 +63,21 @@ public:
static u16 prepareFiHelpIndex();
- bool getDoSpecialFiMenuHandling() const {
- return mDoSpecialFiMenuHandling;
+ bool getIsInFiMainMenu() const {
+ return mIsInFiMainMenu;
}
- static bool getDoSpecialFiMenuHandlingChecked() {
+ static bool getIsInFiMainMenuChecked() {
if (sInstance != nullptr) {
- return sInstance->getDoSpecialFiMenuHandling();
+ return sInstance->getIsInFiMainMenu();
} else {
return false;
}
}
- static void setDoSpecialFiMenuHandling(bool val) {
+ static void setIsInFiMainMenu(bool val) {
if (sInstance != nullptr) {
- sInstance->mDoSpecialFiMenuHandling = val;
+ sInstance->mIsInFiMainMenu = val;
}
}
@@ -203,7 +203,7 @@ private:
/* 0x48 */ bool field_0x48;
/* 0x49 */ bool field_0x49;
/* 0x4A */ bool field_0x4A;
- /* 0x4B */ bool mDoSpecialFiMenuHandling;
+ /* 0x4B */ bool mIsInFiMainMenu;
};
#endif
diff --git a/src/d/d_message.cpp b/src/d/d_message.cpp
index b500ef92..83add314 100644
--- a/src/d/d_message.cpp
+++ b/src/d/d_message.cpp
@@ -58,9 +58,9 @@ dFlow_c::dFlow_c() {
field_0x3C = 0;
field_0x40 = -1;
field_0x44 = -1;
- field_0x46 = -1;
+ mNextFiFlow = -1;
mDelayTimer = 0;
- field_0x5C = -1;
+ mFiSpeechArgument = -1;
}
dFlow_c::~dFlow_c() {}
@@ -265,30 +265,32 @@ bool dFlow_c::handleEventInternal(const MsbFlowInfo *element) {
}
mDelayTimer = 0;
break;
- case EVENT_07:
+ case EVENT_LOAD_FI_FLOW:
if (params1n2 == -1) {
s32 hi, lo;
s32 selectedOption = dLytMsgWindow_c::getInstance()->getTextOptionSelection();
mFiInfo0 = FiContext::getGlobalFiInfo0(selectedOption);
switch (mFiInfo0) {
- case 0: {
+ case FiContext::KEN8_Summary: {
hi = 6;
lo = 1;
- field_0x5C = FiContext::getNaviTableProgressSummary();
+ mFiSpeechArgument = FiContext::getNaviTableProgressSummary();
break;
}
case 11:
+ // TODO: Is this one actually used? It completely duplicates
+ // KEN8_Hint (case 1) down below...
hi = 6;
lo = 100;
- field_0x5C = FiContext::getFiAdviceHintEntry();
+ mFiSpeechArgument = FiContext::getFiAdviceHintEntry();
break;
- case 2: {
+ case FiContext::KEN8_Objective: {
hi = 6;
lo = 200;
- field_0x5C = FiContext::getObjective();
+ mFiSpeechArgument = FiContext::getObjective();
break;
}
- case 3: {
+ case FiContext::KEN8_Analysis: {
FiAnalysisHandle handle = FiContext::getNaviTableEquipmentCheckEntry();
if (handle.isValid()) {
hi = 6;
@@ -297,30 +299,30 @@ bool dFlow_c::handleEventInternal(const MsbFlowInfo *element) {
hi = 6;
lo = 301;
}
- field_0x5C = 5;
+ mFiSpeechArgument = 5;
break;
}
- case 4:
+ case FiContext::KEN8_PlayTime:
hi = 6;
lo = 800;
break;
- case 9:
+ case FiContext::KEN8_Advice:
hi = 6;
lo = 802;
break;
- case 1: {
+ case FiContext::KEN8_Hint: {
hi = 6;
lo = 100;
- field_0x5C = FiContext::getFiAdviceHintEntry();
+ mFiSpeechArgument = FiContext::getFiAdviceHintEntry();
break;
}
- case 5:
+ case FiContext::KEN8_Rumors:
hi = 6;
lo = 900;
break;
}
FiContext::do_setAdviceOptions(FiContext::getGlobalFiInfo0(selectedOption));
- field_0x46 = lo + hi * 1000;
+ mNextFiFlow = lo + hi * 1000;
} else {
triggerEntryPoint((params1n2 >> 16) & 0xFFFF, params1n2 & 0xFFFF);
field_0x0F = 1;
@@ -441,6 +443,7 @@ bool dFlow_c::handleEventInternal(const MsbFlowInfo *element) {
break;
}
case EVENT_LIGHT_PILLAR_34: {
+ // TODO what do these modes do?
if (params1n2 == 1) {
if (!dLytControlGame_c::getInstance()->isNotInStateMap()) {
dLytControlGame_c::getInstance()->fn_802CCD40(true);
@@ -551,24 +554,24 @@ bool dFlow_c::handleMessage() {
if (mCurrentTextLabelName == "KEN0_08") {
// "After winning the race in the Wing Ceremony..."
// Current objective - use value from FiContext::getObjective?
- if (field_0x5C < 0) {
- field_0x5C = 8;
+ if (mFiSpeechArgument < 0) {
+ mFiSpeechArgument = 8;
}
- mCurrentTextLabelName.sprintf("KEN0_%02d", field_0x5C);
+ mCurrentTextLabelName.sprintf("KEN0_%02d", mFiSpeechArgument);
} else if (mCurrentTextLabelName == "KEN1_000") {
// "This is Skyloft..."
// Area analysis - use value from FiContext::???
- if (field_0x5C < 0) {
- field_0x5C = 0;
+ if (mFiSpeechArgument < 0) {
+ mFiSpeechArgument = 0;
}
- mCurrentTextLabelName.sprintf("KEN1_%03d", field_0x5C);
+ mCurrentTextLabelName.sprintf("KEN1_%03d", mFiSpeechArgument);
} else if (mCurrentTextLabelName == "KEN2_000") {
// "To search for Zelda..."
// Hint - use value from FiContext::getFiAdviceHintEntry?
- if (field_0x5C < 0) {
- field_0x5C = 2;
+ if (mFiSpeechArgument < 0) {
+ mFiSpeechArgument = 2;
}
- mCurrentTextLabelName.sprintf("KEN2_%03d", field_0x5C);
+ mCurrentTextLabelName.sprintf("KEN2_%03d", mFiSpeechArgument);
} else if (mCurrentTextLabelName == "KEN3_500") {
// "Master, your current selection of pouch items is..."
// Equipment focus
@@ -730,18 +733,18 @@ bool dFlow_c::handleMessage() {
u16 dFlow_c::getSwitchChoice(const MsbFlowInfo *element, u16 param) const {
u16 result = 0;
- if (param < 14 || param > 16) {
+ if (param < BRANCH_14 || param > BRANCH_16) {
result = (this->*(sBranchHandlers[param]))(element);
}
return result;
}
-inline void setTagProcessorFiArgument(s32 argIdx, s32 btnIdx) {
+inline void syncFiButtonText(s32 argIdx, s32 btnIdx) {
dTagProcessor_c *p = dLytMsgWindow_c::getInstance()->getTagProcessor();
p->setStringArg(FiContext::getMessageForFiInfo(argIdx), btnIdx);
}
-inline void setTagProcessorArgument(s32 textLabel, s32 btnIdx) {
+inline void setFiButtonTextDirectly(s32 textLabel, s32 btnIdx) {
dTagProcessor_c *p = dLytMsgWindow_c::getInstance()->getTagProcessor();
p->setStringArg(FiContext::getButtonText(textLabel), btnIdx);
}
@@ -755,14 +758,18 @@ u16 dFlow_c::branchHandler01(const MsbFlowInfo *element) const {
}
u16 dFlow_c::branchHandler02(const MsbFlowInfo *element) const {
- if (FiContext::getDoSpecialFiMenuHandlingChecked()) {
- if (dLytMsgWindow_c::getInstance()->getTextOptionSelection() == 0 && FiContext::getGlobalFiInfo0(0) == 9) {
+ if (FiContext::getIsInFiMainMenuChecked()) {
+ if (dLytMsgWindow_c::getInstance()->getTextOptionSelection() == 0 &&
+ FiContext::getGlobalFiInfo0(0) == FiContext::KEN8_Advice) {
+ // HACK (?): If the user presses "Advice" on the Fi main menu,
+ // which is known to be button 0, update Fi's buttons since that
+ // menu isn't entirely integrated into the flow
FiContext::do_resetAdviceOptions();
- setTagProcessorFiArgument(0, 0);
- setTagProcessorFiArgument(1, 1);
- setTagProcessorFiArgument(2, 2);
+ syncFiButtonText(0, 0);
+ syncFiButtonText(1, 1);
+ syncFiButtonText(2, 2);
} else {
- FiContext::setDoSpecialFiMenuHandling(false);
+ FiContext::setIsInFiMainMenu(false);
}
}
return dLytMsgWindow_c::getInstance()->getTextOptionSelection();
@@ -938,12 +945,29 @@ u16 dFlow_c::branchHandler22(const MsbFlowInfo *element) const {
}
dFlow_c::BranchHandler dFlow_c::sBranchHandlers[] = {
- &dFlow_c::branchHandler00, &dFlow_c::branchHandler01, &dFlow_c::branchHandler02, &dFlow_c::branchHandler03,
- &dFlow_c::branchHandler04, &dFlow_c::branchHandler05, &dFlow_c::branchHandler06, &dFlow_c::branchHandler07,
- &dFlow_c::branchHandler08, &dFlow_c::branchHandler09, &dFlow_c::branchHandler10, &dFlow_c::branchHandler11,
- &dFlow_c::branchHandler12, &dFlow_c::branchHandler13, &dFlow_c::branchHandler14, &dFlow_c::branchHandler15,
- &dFlow_c::branchHandler16, &dFlow_c::branchHandler17, &dFlow_c::branchHandler18, &dFlow_c::branchHandler19,
- &dFlow_c::branchHandler20, &dFlow_c::branchHandler21, &dFlow_c::branchHandler22,
+ &dFlow_c::branchHandler00, // BRANCH_SELECTED_OPTION_0
+ &dFlow_c::branchHandler01, // BRANCH_SELECTED_OPTION_1
+ &dFlow_c::branchHandler02, // BRANCH_SELECTED_OPTION_FI
+ &dFlow_c::branchHandler03, // BRANCH_STORYFLAG
+ &dFlow_c::branchHandler04, // BRANCH_NONE
+ &dFlow_c::branchHandler05, // BRANCH_ZONEFLAG
+ &dFlow_c::branchHandler06, // BRANCH_SCENEFLAG
+ &dFlow_c::branchHandler07, // BRANCH_EVENT_COUNTER_THRESHOLD_1
+ &dFlow_c::branchHandler08, // BRANCH_EVENT_COUNTER_THRESHOLD_2
+ &dFlow_c::branchHandler09, // BRANCH_TEMPFLAG
+ &dFlow_c::branchHandler10, // BRANCH_CURRENT_RUPEES
+ &dFlow_c::branchHandler11, // BRANCH_RAND_2
+ &dFlow_c::branchHandler12, // BRANCH_RAND_3
+ &dFlow_c::branchHandler13, // BRANCH_RAND_4
+ &dFlow_c::branchHandler14, // BRANCH_14
+ &dFlow_c::branchHandler15, // BRANCH_15
+ &dFlow_c::branchHandler16, // BRANCH_16
+ &dFlow_c::branchHandler17, // BRANCH_FREE_SPACE_IN_POUCH
+ &dFlow_c::branchHandler18, // BRANCH_18
+ &dFlow_c::branchHandler19, // BRANCH_19
+ &dFlow_c::branchHandler20, // BRANCH_FREE_SPACE_IN_ITEM_CHECK
+ &dFlow_c::branchHandler21, // BRANCH_TARGET_ACTOR_HAS_KILL_COUNT
+ &dFlow_c::branchHandler22, // BRANCH_22
};
bool dFlow_c::handleBranch() {
@@ -997,19 +1021,19 @@ void dFlow_c::triggerEntryPoint(s32 labelPart1, s32 labelPart2) {
if (labelPart1 == 6 && labelPart2 == 801) {
// "You called for me, Master?"
FiContext::do_prepareFiCallOptions();
- FiContext::setDoSpecialFiMenuHandling(true);
+ FiContext::setIsInFiMainMenu(true);
FiContext::do_fn_8016CB40();
- setTagProcessorFiArgument(0, 0);
- setTagProcessorFiArgument(1, 1);
- setTagProcessorFiArgument(2, 2);
- setTagProcessorArgument(FiContext::KEN8_Nevermind, 3);
+ syncFiButtonText(0, 0);
+ syncFiButtonText(1, 1);
+ syncFiButtonText(2, 2);
+ setFiButtonTextDirectly(FiContext::KEN8_Nevermind, 3);
} else if (labelPart1 == 6 && labelPart2 == 802) {
// Doesn't seem to exist in the files
- FiContext::setDoSpecialFiMenuHandling(true);
- setTagProcessorFiArgument(0, 0);
- setTagProcessorFiArgument(1, 1);
- setTagProcessorFiArgument(2, 2);
- setTagProcessorArgument(FiContext::KEN8_Nevermind, 3);
+ FiContext::setIsInFiMainMenu(true);
+ syncFiButtonText(0, 0);
+ syncFiButtonText(1, 1);
+ syncFiButtonText(2, 2);
+ setFiButtonTextDirectly(FiContext::KEN8_Nevermind, 3);
}
u16 entry = findEntryPoint(labelPart1, labelPart2);
start(entry);
@@ -1024,8 +1048,8 @@ u16 dFlow_c::getField_0x44() const {
return field_0x44;
}
-u16 dFlow_c::getField_0x46() const {
- return field_0x46;
+u16 dFlow_c::getNextFiFlow() const {
+ return mNextFiFlow;
}
bool dFlow_c::triggerEntryPointChecked(s32 labelPart1, s32 labelPart2) {
@@ -1053,7 +1077,7 @@ void dFlow_c::start(u16 entry) {
field_0x3C = 0;
field_0x40 = -1;
field_0x44 = -1;
- field_0x46 = -1;
+ mNextFiFlow = -1;
mDelayTimer = 0;
std::memset(&mFlowInfo, 0, sizeof(MsbFlowInfo));
CURRENT_ACTOR_EVENT_FLOW_MANAGER = this;
@@ -1087,18 +1111,20 @@ bool dFlow_c::advanceUntil(s32 searchType, s32 searchParam3, s32 *pOutParams1n2)
keepGoing = true;
break;
case FLOW_BRANCH:
- if (element->param3 <= 2) {
+ if (element->param3 <= BRANCH_SELECTED_OPTION_FI) {
+ // Skip evaluating if next branch depends on user input
keepGoing = false;
} else {
+ // Otherwise
keepGoing = handleBranch();
}
break;
case FLOW_EVENT:
switch (element->param3) {
- case 7:
- case 23:
- case 27: keepGoing = handleEvent(); continue;
- case 34:
+ case EVENT_LOAD_FI_FLOW:
+ case EVENT_COUNTER_THRESHOLD:
+ case 27: keepGoing = handleEvent(); continue;
+ case EVENT_LIGHT_PILLAR_34:
if (element->params1n2 == 2) {
keepGoing = false;
continue;
diff --git a/src/d/lyt/msg_window/d_lyt_msg_window.cpp b/src/d/lyt/msg_window/d_lyt_msg_window.cpp
index d7c4efb6..6317e712 100644
--- a/src/d/lyt/msg_window/d_lyt_msg_window.cpp
+++ b/src/d/lyt/msg_window/d_lyt_msg_window.cpp
@@ -515,7 +515,7 @@ void dLytMsgWindow_c::executeState_WaitKeySelectQuestion() {
mTextOptionSelection = selection;
field_0x1220 = 0;
if (FiContext::GetInstance() != nullptr) {
- doFiThing = FiContext::GetInstance()->getDoSpecialFiMenuHandling();
+ doFiThing = FiContext::GetInstance()->getIsInFiMainMenu();
}
if (doFiThing) {
diff --git a/src/toBeSorted/fi_context.cpp b/src/toBeSorted/fi_context.cpp
index 1f5b3647..e20f69c6 100644
--- a/src/toBeSorted/fi_context.cpp
+++ b/src/toBeSorted/fi_context.cpp
@@ -380,7 +380,7 @@ void FiContext::reset() {
mTargetActorId = -1;
mFiHelpIndex = -1;
- mDoSpecialFiMenuHandling = false;
+ mIsInFiMainMenu = false;
}
void FiContext::resetSaveTimeRelated() {