#include #include #include "layoutlib.h" #include "fileload.h" struct MsgData_Header { u32 magic; u32 msgCount; }; struct MsgData_Entry { u32 number; u32 titleOffset; u32 msgOffset; }; struct dMsgBoxManager_c { // 0x00 int ID; unsigned int Settings; short Type; char Unk_0A; char Unk_0B; char Unk_0C; char Unk_0D; char Unk_0E; char Unk_0F; // 0x10 void *CONNECT_parent; void *CONNECT_child; void *CONNECT_prev; void *CONNECT_next; // 0x20 void *CONNECT_thisObj; void *EXECUTE_prev; void *EXECUTE_next; void *EXECUTE_thisObj; // 0x30 short Unk_30; short Unk_32; void *DRAW_prev; void *DRAW_next; void *DRAW_thisObj; // 0x40 short Unk_40; short Unk_42; void *IDLookup_prev; void *IDLookup_next; void *IDLookup_thisObj; // 0x50 void *Unk_50; int Unk_54; int Unk_58; void *Unk_5C; // 0x60 void *vtable; int Unk_64; // dBase_c starts here char *weirdTypeString; char *actorName; // dMsgBoxManager_c starts here (offset 0x70) Layout *layout; int state; FileHandle msgDataFH; // 0x80 void *msgData; // current allocated class size: 0xD0 }; #define STATE_NULL 0 #define STATE_BOX_APPEAR_WAIT 1 #define STATE_BUTTON_APPEAR_WAIT 2 #define STATE_SHOWN 3 #define STATE_BUTTON_DISAPPEAR_WAIT 4 #define STATE_BOX_DISAPPEAR_WAIT 5 #define animBoxAppear 0 #define animBoxDisappear 1 #define animButtonAppear 2 #define animButtonDisappear 3 extern int MessageBoxIsShowing; dMsgBoxManager_c *CurrentMsgBoxManager; const char *brlan_BoxAppear = "BoxAppear.brlan"; const char *brlan_BoxDisappear = "BoxDisappear.brlan"; const char *brlan_ButtonAppear = "ButtonAppear.brlan"; const char *brlan_ButtonDisappear = "ButtonDisappear.brlan"; const char *group_Box = "G_Box"; const char *group_Button = "G_Button"; bool dMsgBoxManager_c__Create(dMsgBoxManager_c *self) { self->layout = (Layout*)AllocFromGameHeap1(sizeof(Layout)); if (!self->layout) { OSReport("memalloc fail\n"); InfiniteLoop; } EmbeddedLayout_ctor(self->layout); EmbeddedLayout_LoadArc(self->layout, "NewerRes/msgbox.arc"); if (!EmbeddedLayout_Build(self->layout, "MessageBox.brlyt", 0)) { OSReport("build fail\n"); InfiniteLoop; } const char *anims[4] = {brlan_BoxAppear, brlan_BoxDisappear, brlan_ButtonAppear, brlan_ButtonDisappear}; EmbeddedLayout_LoadBrlans(self->layout, anims, 4); const char *groups[4] = {group_Box, group_Box, group_Button, group_Button}; int mappings[4] = {0, 1, 2, 3}; EmbeddedLayout_LoadGroups(self->layout, groups, mappings, 4); EmbeddedLayout_DisableAllAnims(self->layout); for (int i = 0; i < 4; i++) { EmbeddedLayout_ResetAnimToInitialState(self->layout, i, false); } self->msgData = LoadFile(&self->msgDataFH, "/NewerRes/MsgData.bin"); self->state = STATE_NULL; self->layout->drawOrder = 0xA0; CurrentMsgBoxManager = self; return true; } bool dMsgBoxManager_c__Execute(dMsgBoxManager_c *self) { if (self->state == STATE_NULL) return true; switch (self->state) { /**************************************************************************/ case STATE_BOX_APPEAR_WAIT: if (!EmbeddedLayout_CheckIfAnimationIsOn(self->layout, animBoxAppear)) { EmbeddedLayout_EnableNonLoopAnim(self->layout, animButtonAppear, false); self->state = STATE_BUTTON_APPEAR_WAIT; } break; /**************************************************************************/ case STATE_BUTTON_APPEAR_WAIT: if (!EmbeddedLayout_CheckIfAnimationIsOn(self->layout, animButtonAppear)) { self->state = STATE_SHOWN; } break; /**************************************************************************/ case STATE_SHOWN: if (false) { EmbeddedLayout_EnableNonLoopAnim(self->layout, animButtonDisappear, false); self->state = STATE_BUTTON_DISAPPEAR_WAIT; } break; /**************************************************************************/ case STATE_BUTTON_DISAPPEAR_WAIT: if (!EmbeddedLayout_CheckIfAnimationIsOn(self->layout, animButtonDisappear)) { EmbeddedLayout_EnableNonLoopAnim(self->layout, animBoxDisappear, false); self->state = STATE_BOX_DISAPPEAR_WAIT; } break; /**************************************************************************/ case STATE_BOX_DISAPPEAR_WAIT: if (!EmbeddedLayout_CheckIfAnimationIsOn(self->layout, animBoxDisappear)) { self->state = STATE_NULL; EmbeddedLayout_DisableAllAnims(self->layout); for (int i = 0; i < 4; i++) { EmbeddedLayout_ResetAnimToInitialState(self->layout, i, false); } } break; } EmbeddedLayout_Process(self->layout); EmbeddedLayout_UpdateMatrix(self->layout); return true; } bool dMsgBoxManager_c__Draw(dMsgBoxManager_c *self) { if (self->state != STATE_NULL) { EmbeddedLayout_AddToDrawList(self->layout); } return true; } bool dMsgBoxManager_c__Delete(dMsgBoxManager_c *self) { EmbeddedLayout_FreeArc(self->layout); EmbeddedLayout_Free(self->layout); EmbeddedLayout_dtor(self->layout, false); FreeFromGameHeap1(self->layout); CurrentMsgBoxManager = 0; return true; }