summaryrefslogtreecommitdiff
path: root/src/msgbox.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/msgbox.cpp')
-rw-r--r--src/msgbox.cpp576
1 files changed, 386 insertions, 190 deletions
diff --git a/src/msgbox.cpp b/src/msgbox.cpp
index f99f73f..c480070 100644
--- a/src/msgbox.cpp
+++ b/src/msgbox.cpp
@@ -1,227 +1,423 @@
#include <common.h>
#include <game.h>
-#include "layoutlib.h"
-#include "fileload.h"
+// Replaces: EN_LIFT_ROTATION_HALF (Sprite 107; Profile ID 481 @ 80AF96F8)
-struct MsgData_Header {
- u32 magic;
- u32 msgCount;
-};
+class dMsgBoxManager_c : public dStageActor_c {
+ public:
+ void showMessage(int id);
-struct MsgData_Entry {
- u32 number;
- u32 titleOffset;
- u32 msgOffset;
-};
+ dMsgBoxManager_c() : state(this, &StateID_LoadRes) { }
+ int onCreate();
+ int onDelete();
+ int onExecute();
+ int onDraw();
+ int beforeExecute() { return true; }
+ int afterExecute(int) { return true; }
-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
+ m2d::EmbedLayout_c layout;
+ dDvdLoader_c msgDataLoader;
+
+ bool layoutLoaded;
+ bool visible;
+
+ dStateWrapper_c<dMsgBoxManager_c> state;
+
+ USING_STATES(dMsgBoxManager_c);
+ DECLARE_STATE(LoadRes);
+ DECLARE_STATE(Wait);
+ DECLARE_STATE(BoxAppearWait);
+// DECLARE_STATE(ButtonAppearWait);
+ DECLARE_STATE(ShownWait);
+// DECLARE_STATE(ButtonDisappearWait);
+ DECLARE_STATE(BoxDisappearWait);
+
+ static dMsgBoxManager_c *instance;
+ static dMsgBoxManager_c *build();
+
+ private:
+ struct entry_s {
+ u32 id;
+ u32 titleOffset;
+ u32 msgOffset;
+ };
+
+ struct header_s {
+ u32 count;
+ entry_s entry[1];
+ };
};
+dMsgBoxManager_c *dMsgBoxManager_c::instance = 0;
+dMsgBoxManager_c *dMsgBoxManager_c::build() {
+ void *buffer = AllocFromGameHeap1(sizeof(dMsgBoxManager_c));
+ dMsgBoxManager_c *c = new(buffer) dMsgBoxManager_c;
-#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
+ instance = c;
+ return c;
+}
-#define animBoxAppear 0
-#define animBoxDisappear 1
-#define animButtonAppear 2
-#define animButtonDisappear 3
+#define ANIM_BOX_APPEAR 0
+#define ANIM_BOX_DISAPPEAR 1
+//#define ANIM_BUTTON_APPEAR 2
+//#define ANIM_BUTTON_DISAPPEAR 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";
+/*****************************************************************************/
+// Events
+int dMsgBoxManager_c::onCreate() {
+ if (!layoutLoaded) {
+ if (!layout.loadArc("msgbox.arc", false))
+ return false;
-const char *group_Box = "G_Box";
-const char *group_Button = "G_Button";
+ static const char *brlanNames[2] = {
+ "BoxAppear.brlan",
+ "BoxDisappear.brlan",
+// "ButtonAppear.brlan",
+// "ButtonDisappear.brlan"
+ };
-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;
+ static const char *groupNames[2] = {
+ "G_Box", "G_Box",
+// "G_Button", "G_Button"
+ };
+
+ layout.build("MessageBox.brlyt");
+
+ if (IsWideScreen()) {
+ layout.layout.rootPane->scale.x = 0.7711f;
+ }
+
+ layout.loadAnimations(brlanNames, 2);
+ layout.loadGroups(groupNames, (int[2]){0,1}, 2);
+ layout.disableAllAnimations();
+
+ layout.drawOrder = 0xA0;
+
+ layoutLoaded = true;
}
-
-
- 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);
+
+ visible = false;
+
+ return true;
+}
+
+int dMsgBoxManager_c::onExecute() {
+ //OSReport("E: %s\n", state.getCurrentState()->getName());
+ state.execute();
+
+ layout.execAnimations();
+ layout.update();
+
+ return true;
+}
+
+int dMsgBoxManager_c::onDraw() {
+ if (visible) {
+ layout.scheduleForDrawing();
}
- 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);
- }
- }
+int dMsgBoxManager_c::onDelete() {
+ instance = 0;
+
+ return layout.free();
+}
+
+/*****************************************************************************/
+// Load Resources
+CREATE_STATE_E(dMsgBoxManager_c, LoadRes);
+
+void dMsgBoxManager_c::executeState_LoadRes() {
+ OSReport("Trying to load\n");
+ if (msgDataLoader.load("/NewerRes/Messages.bin")) {
+ OSReport(":)\n");
+ state.setState(&StateID_Wait);
+ OSReport("changed\n");
+ } else {
+ OSReport(":(\n");
+ }
+}
+
+/*****************************************************************************/
+// Waiting
+CREATE_STATE_E(dMsgBoxManager_c, Wait);
+
+void dMsgBoxManager_c::executeState_Wait() {
+ // null
+}
+
+/*****************************************************************************/
+// Show Box
+void dMsgBoxManager_c::showMessage(int id) {
+ // get the data file
+ header_s *data = (header_s*)msgDataLoader.buffer;
+
+ const wchar_t *title = 0, *msg = 0;
+
+ for (int i = 0; i < data->count; i++) {
+ if (data->entry[i].id == id) {
+ title = (const wchar_t*)((u32)data + data->entry[i].titleOffset);
+ msg = (const wchar_t*)((u32)data + data->entry[i].msgOffset);
break;
+ }
}
+
+ if (title == 0) {
+ OSReport("WARNING! Tried to show message %x but it could not be found!\n", id);
+ return;
+ }
+
+ layout.findTextBoxByName("T_title")->SetString(title);
+ layout.findTextBoxByName("T_msg")->SetString(msg);
+
+ state.setState(&StateID_BoxAppearWait);
+}
+
+
+CREATE_STATE(dMsgBoxManager_c, BoxAppearWait);
+
+void dMsgBoxManager_c::beginState_BoxAppearWait() {
+ visible = true;
+ MessageBoxIsShowing = true;
+ layout.enableNonLoopAnim(ANIM_BOX_APPEAR);
+ OSReport("Enabling box appear @ %d\n", GlobalTickCount);
+}
+
+void dMsgBoxManager_c::executeState_BoxAppearWait() {
+ if (!layout.isAnimOn(ANIM_BOX_APPEAR)) {
+ OSReport("Box appeared @ %d\n", GlobalTickCount);
+ state.setState(&StateID_ShownWait);
+ }
+}
+
+void dMsgBoxManager_c::endState_BoxAppearWait() { }
+
+/*****************************************************************************/
+// Show Button
+/*CREATE_STATE(dMsgBoxManager_c, ButtonAppearWait);
+
+void dMsgBoxManager_c::beginState_ButtonAppearWait() {
+ layout.enableNonLoopAnim(ANIM_BUTTON_APPEAR);
+ OSReport("Enabling button appear @ %d\n", GlobalTickCount);
+}
+
+void dMsgBoxManager_c::executeState_ButtonAppearWait() {
+ if (!layout.isAnimOn(ANIM_BUTTON_APPEAR)) {
+ OSReport("Button appeared @ %d\n", GlobalTickCount);
+ state.setState(&StateID_ShownWait);
+ }
+}
+
+void dMsgBoxManager_c::endState_ButtonAppearWait() { }*/
+
+/*****************************************************************************/
+// Wait For Player To Finish
+CREATE_STATE(dMsgBoxManager_c, ShownWait);
+
+void dMsgBoxManager_c::beginState_ShownWait() { }
+void dMsgBoxManager_c::executeState_ShownWait() {
+ int nowPressed = Remocon_GetPressed(GetActiveRemocon());
-
- EmbeddedLayout_Process(self->layout);
- EmbeddedLayout_UpdateMatrix(self->layout);
-
+ if (nowPressed & WPAD_TWO) {
+ state.setState(&StateID_BoxDisappearWait);
+ }
+}
+void dMsgBoxManager_c::endState_ShownWait() { }
+
+/*****************************************************************************/
+// Hide Button
+/*CREATE_STATE(dMsgBoxManager_c, ButtonDisappearWait);
+
+void dMsgBoxManager_c::beginState_ButtonDisappearWait() {
+ layout.enableNonLoopAnim(ANIM_BUTTON_DISAPPEAR);
+ OSReport("Enabling button disappear @ %d\n", GlobalTickCount);
+}
+
+void dMsgBoxManager_c::executeState_ButtonDisappearWait() {
+ if (!layout.isAnimOn(ANIM_BUTTON_DISAPPEAR)) {
+ OSReport("Button disappeared @ %d\n", GlobalTickCount);
+ state.setState(&StateID_BoxDisappearWait);
+ }
+}
+
+void dMsgBoxManager_c::endState_ButtonDisappearWait() { }*/
+
+/*****************************************************************************/
+// Hide Box
+CREATE_STATE(dMsgBoxManager_c, BoxDisappearWait);
+
+void dMsgBoxManager_c::beginState_BoxDisappearWait() {
+ layout.enableNonLoopAnim(ANIM_BOX_DISAPPEAR);
+ OSReport("Enabling box disappear @ %d\n", GlobalTickCount);
+}
+
+void dMsgBoxManager_c::executeState_BoxDisappearWait() {
+ if (!layout.isAnimOn(ANIM_BOX_DISAPPEAR)) {
+ OSReport("Box disappeared @ %d\n", GlobalTickCount);
+ state.setState(&StateID_Wait);
+
+ for (int i = 0; i < 2; i++)
+ layout.resetAnim(i);
+ layout.disableAllAnimations();
+ }
+}
+
+void dMsgBoxManager_c::endState_BoxDisappearWait() {
+ visible = false;
+ MessageBoxIsShowing = false;
+}
+
+
+
+/*****************************************************************************/
+/*****************************************************************************/
+/*****************************************************************************/
+// Replaces: EN_BLUR (Sprite 152; Profile ID 603 @ 80ADD890)
+
+
+class daEnMsgBlock_c : public daEnBlockMain_c {
+public:
+ TileRenderer tile;
+ Physics::Info physicsInfo;
+
+ int onCreate();
+ int onDelete();
+ int onExecute();
+
+ void calledWhenUpMoveExecutes();
+ void calledWhenDownMoveExecutes();
+
+ void blockWasHit(bool isDown);
+
+ USING_STATES(daEnMsgBlock_c);
+ DECLARE_STATE(Wait);
+
+ static daEnMsgBlock_c *build();
+};
+
+
+CREATE_STATE(daEnMsgBlock_c, Wait);
+
+
+int daEnMsgBlock_c::onCreate() {
+ OSReport("Creating Block\n");
+ blockInit(pos.y);
+
+ physicsInfo.x1 = -8;
+ physicsInfo.y1 = 16;
+ physicsInfo.x2 = 8;
+ physicsInfo.y2 = 0;
+
+ physicsInfo.otherCallback1 = &daEnBlockMain_c::OPhysicsCallback1;
+ physicsInfo.otherCallback2 = &daEnBlockMain_c::OPhysicsCallback2;
+ physicsInfo.otherCallback3 = &daEnBlockMain_c::OPhysicsCallback3;
+
+ physics.setup(this, &physicsInfo, 3, currentLayerID);
+ physics.flagsMaybe = 0x260;
+ physics.callback1 = &daEnBlockMain_c::PhysicsCallback1;
+ physics.callback2 = &daEnBlockMain_c::PhysicsCallback2;
+ physics.callback3 = &daEnBlockMain_c::PhysicsCallback3;
+ physics.addToList();
+
+ TileRenderer::List *list = dBgGm_c::instance->getTileRendererList(0);
+ list->add(&tile);
+
+ tile.x = pos.x - 8;
+ tile.y = -(16 + pos.y);
+ tile.tileNumber = 0x98;
+
+ doStateChange(&daEnMsgBlock_c::StateID_Wait);
+ OSReport("Created Block\n");
+
+ return true;
+}
+
+
+int daEnMsgBlock_c::onDelete() {
+ TileRenderer::List *list = dBgGm_c::instance->getTileRendererList(0);
+ list->remove(&tile);
+
+ physics.removeFromList();
+
return true;
}
-bool dMsgBoxManager_c__Draw(dMsgBoxManager_c *self) {
- if (self->state != STATE_NULL) {
- EmbeddedLayout_AddToDrawList(self->layout);
+
+int daEnMsgBlock_c::onExecute() {
+ acState.execute();
+ physics.update();
+ blockUpdate();
+
+ tile.setPosition(pos.x-8, -(16+pos.y), pos.z);
+ tile.setVars(scale.x);
+
+ // now check zone bounds based on state
+ if (acState.getCurrentState()->isEqual(&StateID_Wait)) {
+ checkZoneBoundaries(0);
}
-
+
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;
+
+daEnMsgBlock_c *daEnMsgBlock_c::build() {
+ void *buffer = AllocFromGameHeap1(sizeof(daEnMsgBlock_c));
+ return new(buffer) daEnMsgBlock_c;
+}
+
+
+void daEnMsgBlock_c::blockWasHit(bool isDown) {
+ pos.y = initialY;
+
+ dMsgBoxManager_c::instance->showMessage(settings);
+
+ physics.setup(this, &physicsInfo, 3, currentLayerID);
+ physics.addToList();
- return true;
+ doStateChange(&StateID_Wait);
+}
+
+
+
+void daEnMsgBlock_c::calledWhenUpMoveExecutes() {
+ if (initialY >= pos.y)
+ blockWasHit(false);
+}
+
+void daEnMsgBlock_c::calledWhenDownMoveExecutes() {
+ if (initialY <= pos.y)
+ blockWasHit(true);
+}
+
+
+
+void daEnMsgBlock_c::beginState_Wait() {
+}
+
+void daEnMsgBlock_c::endState_Wait() {
+}
+
+void daEnMsgBlock_c::executeState_Wait() {
+ int result = blockResult();
+
+ if (result == 0)
+ return;
+
+ if (result == 1) {
+ doStateChange(&daEnBlockMain_c::StateID_UpMove);
+ anotherFlag = 2;
+ isGroundPound = false;
+ } else {
+ doStateChange(&daEnBlockMain_c::StateID_DownMove);
+ anotherFlag = 1;
+ isGroundPound = true;
+ }
}