Files
ss/include/d/d_message.h
T
2025-12-05 12:52:22 +01:00

399 lines
11 KiB
C++

#ifndef D_MESSAGE_H
#define D_MESSAGE_H
#include "common.h"
#include "d/d_base.h"
#include "d/d_tag_processor.h"
#include "libms/flowfile.h"
#include "libms/msgfile.h"
#include "sized_string.h"
class dFlowBase_c {
protected:
enum Type_e {
FLOW_NONE,
FLOW_MESSAGE,
FLOW_BRANCH,
FLOW_EVENT,
FLOW_ENTRY,
FLOW_JUMP,
};
public:
virtual ~dFlowBase_c() {}
/* vt 0x0C */ virtual void triggerEntryPoint(s32, s32) = 0;
/* vt 0x10 */ virtual void triggerEntryPoint(const char *) = 0;
/* vt 0x14 */ virtual void advanceFlow() = 0;
/* vt 0x18 */ virtual bool vt_0x18() const = 0;
/* vt 0x1C */ virtual bool handleEventInternal(const MsbFlowInfo *element) = 0;
/* vt 0x20 */ virtual bool handleEvent() = 0;
/* vt 0x24 */ virtual bool handleMessage() = 0;
/* vt 0x28 */ virtual bool handleBranch() = 0;
/* vt 0x2C */ virtual bool handleEntry() = 0;
/* vt 0x30 */ virtual bool handleJump() = 0;
/* vt 0x34 */ virtual void vt_0x34() {}
};
// Ghidra: ActorEventFlowManager
class dFlow_c : dFlowBase_c {
protected:
enum BranchValue_e {
BRANCH_SELECTED_OPTION_0,
BRANCH_SELECTED_OPTION_1,
BRANCH_SELECTED_OPTION_FI,
BRANCH_STORYFLAG,
BRANCH_NONE,
BRANCH_ZONEFLAG,
BRANCH_SCENEFLAG,
BRANCH_EVENT_COUNTER_THRESHOLD_1,
BRANCH_EVENT_COUNTER_THRESHOLD_2,
BRANCH_TEMPFLAG,
BRANCH_CURRENT_RUPEES,
BRANCH_RAND_2,
BRANCH_RAND_3,
BRANCH_RAND_4,
BRANCH_NPC_1, // handled by subclass
BRANCH_NPC_2, // handled by subclass
BRANCH_NPC_3, // handled by subclass
BRANCH_FREE_SPACE_IN_POUCH,
BRANCH_18,
BRANCH_19,
BRANCH_FREE_SPACE_IN_ITEM_CHECK,
BRANCH_TARGET_ACTOR_HAS_KILL_COUNT,
BRANCH_22,
};
enum Event_e {
EVENT_SET_STORYFLAG = 0,
EVENT_UNSET_STORYFLAG = 1,
EVENT_SET_SCENEFLAG = 2,
EVENT_UNSET_SCENEFLAG = 3,
EVENT_SET_ZONEFLAG = 4,
EVENT_UNSET_ZONEFLAG = 5,
EVENT_DELAY = 6,
EVENT_LOAD_FI_FLOW = 7,
EVENT_RUPEES = 8,
EVENT_SET_ITEM = 9,
EVENT_EXIT = 10,
EVENT_12 = 12,
EVENT_COUNTER_THRESHOLD = 23,
EVENT_PLAY_SOUND = 24,
EVENT_ADD_ITEM = 25,
EVENT_SET_TEMPFLAG = 28,
EVENT_UNSET_TEMPFLAG = 29,
EVENT_START_MAP_EVENT = 30,
EVENT_END_MAP_EVENT = 34,
EVENT_SET_STORYFLAG_217 = 37,
EVENT_DEMO_METER_ITEM_SELECT = 38,
EVENT_CAMERA_42 = 42,
EVENT_LYT_MINI_GAME = 44,
EVENT_LYT_MINI_GAME_END = 45,
EVENT_46 = 46,
EVENT_RESET_STORYFLAG = 52,
EVENT_SET_ITEMFLAG = 53,
EVENT_PALETTE = 54,
EVENT_DEMO_DOWSING = 55,
EVENT_DEMO_METER_DOWSING = 56,
EVENT_DEMO_METER_MINUS_BTN = 57,
EVENT_SELECT_STORY_DOWSING = 58,
EVENT_DEMO_COLLECTION_SCREEN = 59,
};
public:
dFlow_c();
virtual ~dFlow_c();
typedef u16 (dFlow_c::*BranchHandler)(const MsbFlowInfo *element) const;
/* vt 0x0C */ virtual void triggerEntryPoint(s32 labelPart1, s32 labelPart2) override;
/* vt 0x10 */ virtual void triggerEntryPoint(const char *) override;
/* vt 0x14 */ virtual void advanceFlow() override;
/* vt 0x18 */ virtual bool vt_0x18() const override;
/* vt 0x1C */ virtual bool handleEventInternal(const MsbFlowInfo *element) override;
/* vt 0x20 */ virtual bool handleEvent() override;
/* vt 0x24 */ virtual bool handleMessage() override;
/* vt 0x28 */ virtual bool handleBranch() override;
/* vt 0x2C */ virtual bool handleEntry() override;
/* vt 0x30 */ virtual bool handleJump() override;
/* vt 0x38 */ virtual bool vt_0x38() const {
return false;
}
/* 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);
static void playSound(u32);
u16 getField_0x44() const;
u16 getNextFiFlow() const;
protected:
static s32 sExitId;
static BranchHandler sBranchHandlers[];
u16 branchHandler00(const MsbFlowInfo *element) const;
u16 branchHandler01(const MsbFlowInfo *element) const;
u16 branchHandler02(const MsbFlowInfo *element) const;
u16 branchHandler03(const MsbFlowInfo *element) const;
u16 branchHandler04(const MsbFlowInfo *element) const;
u16 branchHandler05(const MsbFlowInfo *element) const;
u16 branchHandler06(const MsbFlowInfo *element) const;
u16 branchHandler07(const MsbFlowInfo *element) const;
u16 branchHandler08(const MsbFlowInfo *element) const;
u16 branchHandler09(const MsbFlowInfo *element) const;
u16 branchHandler10(const MsbFlowInfo *element) const;
u16 branchHandler11(const MsbFlowInfo *element) const;
u16 branchHandler12(const MsbFlowInfo *element) const;
u16 branchHandler13(const MsbFlowInfo *element) const;
u16 branchHandler14(const MsbFlowInfo *element) const;
u16 branchHandler15(const MsbFlowInfo *element) const;
u16 branchHandler16(const MsbFlowInfo *element) const;
u16 branchHandler17(const MsbFlowInfo *element) const;
u16 branchHandler18(const MsbFlowInfo *element) const;
u16 branchHandler19(const MsbFlowInfo *element) const;
u16 branchHandler20(const MsbFlowInfo *element) const;
u16 branchHandler21(const MsbFlowInfo *element) const;
u16 branchHandler22(const MsbFlowInfo *element) const;
u16 findEntryPoint(u16 labelPart1, u16 labelPart2);
u16 findEntryPoint(const char *label);
void start(u16 entry);
void clear();
void setNext(u16 next);
void setField0x3C();
bool checkField0x3C() const;
bool shouldHideKillCountForActor(s32 id) const;
void createLytMiniGame();
void clearMinigame();
/* 0x04 */ MsbfInfo *mpMsbf;
/* 0x08 */ s32 mCurrentFlowIndex;
/* 0x0C */ u16 field_0x0C;
/* 0x0E */ u8 field_0x0E;
/* 0x0F */ u8 field_0x0F;
/* 0x10 */ u8 field_0x10;
/* 0x14 */ s32 field_0x14;
/* 0x18 */ s32 mResultFromCounterCheck;
/* 0x1C */ SizedString<32> mCurrentTextLabelName;
/* 0x3C */ u8 field_0x3C;
/* 0x40 */ s32 field_0x40;
/* 0x44 */ u16 field_0x44;
/* 0x46 */ u16 mNextFiFlow;
/* 0x48 */ s32 mDelayTimer;
/* 0x4C */ MsbFlowInfo mFlowInfo;
/* 0x5C */ s32 mFiSpeechArgument;
/* 0x60 */ s32 mFiInfo0;
};
class dMessage_c : public dBase_c {
public:
enum Minigame_e {
MG_THRILL_DIGGER = 0,
MG_BAMBOO_CUTTING,
MG_INSECT_CAPTURE,
MG_ROLLERCOASTER,
MG_PUMPKIN_ARCHERY,
MG_FUN_FUN_ISLAND,
MG_TRIAL_TIME_ATTACK,
MG_BOSS_RUSH,
MG_NONE,
};
public:
dMessage_c();
virtual ~dMessage_c() {
sInstance = nullptr;
}
int create() override;
int doDelete() override;
int execute() override;
int draw() override;
static const char *getLanguageIdentifier();
static dMessage_c *getInstance() {
return sInstance;
}
static dTagProcessor_c *getGlobalTagProcessor() {
return sTagProcessor;
}
void clearLightPillarRelatedArgs();
void init();
void reset();
bool getField_0x329() const {
return field_0x329;
}
s32 getField_0x2FC() const {
return field_0x2FC;
}
void setField_0x2FC(s32 val) {
field_0x2FC = val;
}
bool getInMapEvent() const {
return mInMapEvent;
}
void setInMapEvent(bool val) {
mInMapEvent = val;
}
s32 getMapEvent() const {
return mMapEvent;
}
void setMapEvent(s32 val) {
mMapEvent = val;
}
void setField_0x329(bool v) {
field_0x329 = v;
}
void setField_0x32A(bool v) {
field_0x32A = v;
}
bool getField_0x32A() const {
return field_0x32A;
}
bool getField_0x330() const {
return field_0x330;
}
void setField_0x330(bool v) {
field_0x330 = v;
}
void setMiniGameVariant(s32 v) {
mMinigameVariant = v;
}
s32 getMiniGameVariant() const {
return mMinigameVariant;
}
void setField_0x344(s32 v) {
field_0x344 = v;
}
bool hasSetMinigameResult() const {
return mHasSetMinigameResult;
}
void setHasSetMinigameResult(bool v) {
mHasSetMinigameResult = v;
}
static bool isValidTextLabel(const char *name);
static void loadTextByLabel(const char *label, dTagProcessor_c *tagProcessor, bool, u32, u32);
static s32 getMsbtIndexForLabel(const char *name);
static const char *getMsbtFileName(s32 index);
static MsbfInfo *getMsbfInfoForIndex(s32 index);
static s32 getMsbtIndexForMsbfIndex(s32);
static const char *getArcNameByIndex(s32 idx, bool);
static MsbtInfo *getMsbtInfoForIndex(s32 index);
static const wchar_t *getTextMessageByLabel(const char *label, bool global, wchar_t *dstBuf, u32 maxLen);
static const wchar_t *
getTextMessageByLabel(const char *label, dTagProcessor_c *pTagProcessor, bool global, wchar_t *dstBuf, u32 maxLen);
static const wchar_t *formatText(const wchar_t *text);
void storeLightPillarRelatedArg(u32);
u32 getLightPillarRelatedArg(s32);
s32 getCurrentTextFileNumber() const {
return mCurrentTextFileNumber;
}
void setCurrentTextFileNumber(s32 num) {
mCurrentTextFileNumber = num;
}
private:
static void *sZev0;
static void *sZevStage;
static void *getZev0Internal();
static void *getZevStageInternal();
void executeMinigame();
const wchar_t *formatTextInternal(const wchar_t *text);
const wchar_t *getTextMessageByLabelInternal(
const char *label, dTagProcessor_c *pTagProcessor, bool global, wchar_t *dstBuf, u32 maxLen
);
static s32 getArcIndexForFile(const char *fileName);
bool checkIsValidTextLabel(const char *name);
static void setZevFromMsbArc();
static void setStageZevFromMsbArc();
static s32 getMsbtNumberByIndex(s32 index);
static const char *getMsbfFileName(s32 index);
static s32 getMsbfNumberByIndex(s32 index);
static void *getDataFromMsbArc(s32 number, const char *fileName, bool);
s32 getTextIndexForLabel(const char *label);
s32 getMsbtIndexForLabelInternal(const char *label);
MsbtInfo *getMsbtInfoForIndexInternal(s32 index);
MsbfInfo *getMsbfInfoForIndexInternal(s32 index);
static const char *getArcNameByIndexInternal(s32 idx, bool global);
static dMessage_c *sInstance;
static dTagProcessor_c *sTagProcessor;
/* 0x068 */ MsbtInfo *mpMsgs[82];
/* 0x1B0 */ MsbfInfo *mpFlows[80];
/* 0x2F0 */ SizedString<8> mLanguage;
/* 0x2F8 */ u32 mCurrentTextFileNumber;
/* 0x2FC */ s32 field_0x2FC;
/* 0x300 */ u32 field_0x300[10];
/* 0x328 */ bool mInMapEvent;
/* 0x329 */ bool field_0x329;
/* 0x32A */ bool field_0x32A;
/* 0x32B */ u8 field_0x32B;
/* 0x32C */ s32 mMapEvent;
/* 0x330 */ bool field_0x330;
/* 0x334 */ u32 mMinigameResultPoints;
/* 0x338 */ u32 mMinigameTime;
/* 0x33C */ s32 mMinigameVariant;
/* 0x340 */ bool mHasSetMinigameResult;
/* 0x344 */ s32 field_0x344;
};
#endif