From fe775d4e2ee4cd1ad2cb1a5f671f2cd6156bb408 Mon Sep 17 00:00:00 2001 From: gamemasterplc Date: Thu, 7 Mar 2024 14:21:12 -0600 Subject: [PATCH] Decompile board/fortune.c --- config/GMPE01_00/symbols.txt | 16 +- configure.py | 2 +- src/game/board/fortune.c | 409 +++++++++++++++++++++++++++++++++++ src/game/board/lottery.c | 14 +- 4 files changed, 425 insertions(+), 16 deletions(-) create mode 100644 src/game/board/fortune.c diff --git a/config/GMPE01_00/symbols.txt b/config/GMPE01_00/symbols.txt index 2f787f26..8a4b938c 100644 --- a/config/GMPE01_00/symbols.txt +++ b/config/GMPE01_00/symbols.txt @@ -4621,9 +4621,9 @@ lbl_8011DEF0 = .rodata:0x8011DEF0; // type:object size:0x10 data:4byte lbl_8011DF00 = .rodata:0x8011DF00; // type:object size:0x90 data:4byte lbl_8011DF90 = .rodata:0x8011DF90; // type:object size:0x20 data:4byte lbl_8011DFB0 = .rodata:0x8011DFB0; // type:object size:0x20 data:4byte -lbl_8011DFD0 = .rodata:0x8011DFD0; // type:object size:0x20 -lbl_8011DFF0 = .rodata:0x8011DFF0; // type:object size:0x20 -lbl_8011E010 = .rodata:0x8011E010; // type:object size:0x10 +pickSpr = .rodata:0x8011DFD0; // type:object size:0x20 scope:local +handMdl = .rodata:0x8011DFF0; // type:object size:0x20 scope:local +ticketSpr = .rodata:0x8011E010; // type:object size:0x10 scope:local lbl_8011E020 = .rodata:0x8011E020; // type:object size:0x20 data:4byte lbl_8011E040 = .rodata:0x8011E040; // type:object size:0x24 lbl_8011E064 = .rodata:0x8011E064; // type:object size:0x4C @@ -4649,7 +4649,7 @@ lbl_8011E300 = .rodata:0x8011E300; // type:object size:0x24 data:4byte lbl_8011E324 = .rodata:0x8011E324; // type:object size:0x20 data:4byte lbl_8011E344 = .rodata:0x8011E344; // type:object size:0x2C data:4byte lbl_8011E370 = .rodata:0x8011E370; // type:object size:0x10 data:4byte -lbl_8011E380 = .rodata:0x8011E380; // type:object size:0x28 data:4byte +lbl_8011E380 = .rodata:0x8011E380; // type:object size:0x24 data:4byte lbl_8011E3A8 = .rodata:0x8011E3A8; // type:object size:0x24 data:4byte lbl_8011E3D0 = .rodata:0x8011E3D0; // type:object size:0x20 data:4byte lbl_8011E3F0 = .rodata:0x8011E3F0; // type:object size:0x20 data:4byte @@ -5289,7 +5289,7 @@ bombFXTbl = .data:0x8013AA78; // type:object size:0x20 scope:local battleSprPrioTbl = .data:0x8013AA98; // type:object size:0x16 scope:local jumptable_8013AAB0 = .data:0x8013AAB0; // type:object size:0x24 scope:local battleChanceTbl = .data:0x8013AAD4; // type:object size:0x3C scope:local -comFortuneMessTbl = .data:0x8013AB10; // type:object size:0x18 scope:local +comPrizeMessTbl = .data:0x8013AB10; // type:object size:0x18 scope:local booPlayerMotTbl = .data:0x8013AB28; // type:object size:0xC0 scope:local booSfxTbl = .data:0x8013ABE8; // type:object size:0x80 scope:local hostMess = .data:0x8013AC68; // type:object size:0x18 scope:local @@ -6417,7 +6417,7 @@ angleVal = .sbss:0x801D3FFC; // type:object size:0x2 scope:local data:2byte shopPlayer = .sbss:0x801D3FFE; // type:object size:0x1 scope:local data:byte shopMdlPtr = .sbss:0x801D4000; // type:object size:0x4 scope:local data:4byte shopMdlIdx = .sbss:0x801D4004; // type:object size:0x4 scope:local -lotteryProc = .sbss:0x801D4008; // type:object size:0x4 data:4byte +lotteryProc = .sbss:0x801D4008; // type:object size:0x4 scope:local data:4byte comInputDrawP = .sbss:0x801D400C; // type:object size:0x4 scope:local data:4byte lotteryTicketPickObj = .sbss:0x801D4010; // type:object size:0x4 scope:local data:4byte handUpdateF = .sbss:0x801D4014; // type:object size:0x4 scope:local data:4byte @@ -6521,7 +6521,7 @@ explodeObj = .sbss:0x801D4180; // type:object size:0x4 scope:local data:4byte battleCoinPosF = .sbss:0x801D4184; // type:object size:0x4 scope:local data:float battleCoinSpeed = .sbss:0x801D4188; // type:object size:0x4 scope:local data:float totalCoinStr = .sbss:0x801D418C; // type:object size:0x8 scope:local -battleMGIdx = .sbss:0x801D4194; // type:object size:0x1 scope:local data:byte +battleMGIdx = .sbss:0x801D4194; // type:object size:0x2 scope:local data:byte battleCoinIdx = .sbss:0x801D4196; // type:object size:0x1 scope:local data:byte currSpace = .sbss:0x801D4198; // type:object size:0x2 scope:local data:2byte mgChoice = .sbss:0x801D419A; // type:object size:0x1 scope:local data:byte @@ -6531,7 +6531,7 @@ fortuneProc = .sbss:0x801D41A0; // type:object size:0x4 scope:local data:4byte fortunePlatformObj = .sbss:0x801D41A4; // type:object size:0x4 scope:local data:4byte comStar = .sbss:0x801D41A8; // type:object size:0x1 scope:local data:byte comCoin = .sbss:0x801D41A9; // type:object size:0x1 scope:local data:byte -comType = .sbss:0x801D41AA; // type:object size:0x1 scope:local data:byte +comPrize = .sbss:0x801D41AA; // type:object size:0x1 scope:local data:byte comPlayer1 = .sbss:0x801D41AB; // type:object size:0x1 scope:local data:byte comPlayer2 = .sbss:0x801D41AC; // type:object size:0x1 scope:local data:byte currPlayer = .sbss:0x801D41AD; // type:object size:0x1 scope:local data:byte diff --git a/configure.py b/configure.py index c9bf7bd4..09847e08 100644 --- a/configure.py +++ b/configure.py @@ -388,7 +388,7 @@ config.libs = [ Object(Matching, "game/board/item.c"), Object(NonMatching, "game/board/bowser.c"), Object(Matching, "game/board/battle.c"), - Object(NonMatching, "game/board/fortune.c"), + Object(Matching, "game/board/fortune.c"), Object(Matching, "game/board/boo.c"), Object(NonMatching, "game/board/mg_setup.c"), Object(NonMatching, "game/board/boo_house.c"), diff --git a/src/game/board/fortune.c b/src/game/board/fortune.c new file mode 100644 index 00000000..97b3fae0 --- /dev/null +++ b/src/game/board/fortune.c @@ -0,0 +1,409 @@ +#include "game/board/main.h" +#include "game/board/model.h" +#include "game/board/player.h" +#include "game/board/tutorial.h" +#include "game/board/audio.h" +#include "game/board/ui.h" +#include "game/board/space.h" + +#include "game/wipe.h" + +static Vec camTargetFortune; +static Vec camPosFortune; + +typedef struct platform_work { + struct { + u8 kill : 1; + u8 state : 2; + }; + s16 unk02; + s16 model; +} PlatformWork; + +static u32 comPrizeMessTbl[] = { + 0x1C0009, + 0x1C000A, + 0x1C000B, + 0x1C000D, + 0x1C000C, + 0x1C000E +}; + +static s8 currPlayer; +static s8 comPlayer2; +static s8 comPlayer1; +static s8 comPrize; +static s8 comCoin; +static s8 comStar; +static omObjData *fortunePlatformObj; +static Process *fortuneProc; + +static void FortuneExec(void); +static void DestroyFortune(void); +static void FortuneMain(void); +static void FortunePostMG(void); + +static void CreateFortunePlatform(void); +static void ExecFortunePlatform(omObjData *object); + +static void CameraCalcFortune(BoardCameraData *camera); + +static void ExecComFortuneWin(void); + +static void ConfigComFortune(void); + +static void ComFortuneAddStar(s32 player1, s32 player2, s32 max_stars); +static void ComFortuneAddCoin(s32 player1, s32 player2, s32 max_coins); +static void ComFortuneSwapCoin(s32 player1, s32 player2); +static void ComFortuneSwapStar(s32 player1, s32 player2); + +void BoardFortuneExec(s32 player, s32 space) +{ + if(_CheckFlag(0x1000B)) { + HuAudFXPlay(842); + BoardCameraViewSet(2); + BoardPlayerMotBlendSet(player, 0, 15); + while(!BoardPlayerMotBlendCheck(player)) { + HuPrcVSleep(); + } + BoardCameraMotionWait(); + BoardTutorialHookExec(17, 0); + GWPlayer[player].color = 3; + return; + } + if(BoardPlayerSizeGet(player) == 2) { + return; + } + fortuneProc = HuPrcChildCreate(FortuneExec, 8195, 14336, 0, boardMainProc); + HuPrcDestructorSet2(fortuneProc, DestroyFortune); + currPlayer = player; + while(fortuneProc) { + HuPrcVSleep(); + } + GWPlayer[player].color = 3; +} + +static void FortuneExec(void) +{ + BoardAudSeqFadeOut(0, 1000); + if(!_CheckFlag(0x10005)) { + GWPlayer[currPlayer].show_next = 0; + FortuneMain(); + } else { + FortunePostMG(); + } + HuPrcEnd(); +} + +static void DestroyFortune(void) +{ + fortuneProc = NULL; +} + +static void FortuneMain(void) +{ + s32 i; + s32 sp8 = -1; + s32 dir_table[] = { + DATADIR_W01, + DATADIR_W02, + DATADIR_W03, + DATADIR_W04, + DATADIR_W05, + DATADIR_W06, + DATADIR_W10, + DATADIR_W20, + DATADIR_W21 + }; + HuAudFXPlay(842); + BoardPlayerMotBlendSet(currPlayer, 0, 15); + while(!BoardPlayerMotBlendCheck(currPlayer)) { + HuPrcVSleep(); + } + for(i=0; i<4; i++) { + if((int)(GWPlayer[i].team) != 0) { + GWPlayer[i].field08_bit11 = 1; + } else { + GWPlayer[i].field08_bit11 = 0; + } + if(i == currPlayer) { + GWPlayerCfg[i].group = 0; + } else { + GWPlayerCfg[i].group = 1; + } + } + BoardCameraViewSet(3); + BoardCameraMotionWait(); + CreateFortunePlatform(); + omVibrate(currPlayer, 60, 6, 6); + BoardCameraPosCalcFuncSet(CameraCalcFortune); + HuPrcSleep(60); + _SetFlag(0x1001C); + WipeColorSet(255, 255, 255); + WipeCreate(WIPE_MODE_OUT, WIPE_TYPE_NORMAL, -1); + while(WipeStatGet()) { + HuPrcVSleep(); + } + HuAudFXAllStop(); + BoardAudSeqFadeOutAll(); + _SetFlag(0x1000E); + BoardCameraPosCalcFuncSet(NULL); + if(fortunePlatformObj) { + OM_GET_WORK_PTR(fortunePlatformObj, PlatformWork)->kill = 1; + } + while(fortunePlatformObj) { + HuPrcVSleep(); + } + if(GWPlayer[GWSystem.player_curr].com) { + if((int)GWSystem.show_com_mg == 0) { + HuPrcSleep(60); + for(i=0; i<4; i++) { + s32 bit11 = GWPlayer[i].field08_bit11; + GWPlayer[i].team = bit11; + GWPlayerCfg[i].group = bit11; + } + ConfigComFortune(); + FortunePostMG(); + BoardMusStartBoard(); + ExecComFortuneWin(); + return; + } + } + GWMGAvailSet(444); + GWSystem.mg_next = 43; + _SetFlag(0x10005); + BoardNextOvlSet(OVL_M444); +} + +static void FortunePostMG(void) +{ + s16 space; + Vec pos; + BoardStatusItemSet(1); + space = GWPlayer[GWSystem.player_curr].space_curr; + BoardSpacePosGet(0, space, &pos); + BoardPlayerPosSetV(GWSystem.player_curr, &pos); + BoardCameraMoveSet(0); + BoardCameraViewSet(2); + BoardCameraMotionWait(); + BoardCameraMoveSet(1); + GWPlayer[currPlayer].show_next = 1; + WipeCreate(WIPE_MODE_IN, WIPE_TYPE_NORMAL, -1); + while(WipeStatGet()) { + HuPrcVSleep(); + } + _ClearFlag(0x1001C); + HuPrcSleep(12); +} + +static void CreateFortunePlatform(void) +{ + PlayerState *player; + Vec pos, rot; + PlatformWork *work; + fortunePlatformObj = omAddObjEx(boardObjMan, 257, 0, 0, -1, ExecFortunePlatform); + work = OM_GET_WORK_PTR(fortunePlatformObj, PlatformWork); + work->kill = 0; + work->unk02 = 0; + work->model = BoardModelCreate(DATA_MAKE_NUM(DATADIR_BOARD, 3), NULL, 0); + BoardSpacePosGet(0, GWPlayer[currPlayer].space_curr, &pos); + BoardSpaceRotGet(0, GWPlayer[currPlayer].space_curr, &rot); + BoardModelPosSetV(work->model, &pos); + BoardCameraTargetModelSet(work->model); + BoardModelHookSet(work->model, "player", BoardPlayerModelGet(currPlayer)); + BoardModelMotionStart(work->model, 0, 0); + BoardCameraPosGet(&camPosFortune); + BoardCameraTargetGet(&camTargetFortune); + HuAudFXPlay(834); +} + +static void CameraCalcFortune(BoardCameraData *camera) +{ + camera->pos = camPosFortune; + camera->up.x = 0; + camera->up.y = 1; + camera->up.z = 0; + camera->target = camTargetFortune; +} + +static void ExecFortunePlatform(omObjData *object) +{ + PlatformWork *work = OM_GET_WORK_PTR(object, PlatformWork); + if(work->kill || BoardIsKill()) { + Vec pos; + fortunePlatformObj = NULL; + BoardModelHookReset(work->model); + BoardSpacePosGet(0, GWPlayer[currPlayer].space_curr, &pos); + BoardPlayerPosSetV(currPlayer, &pos); + BoardModelKill(work->model); + omDelObjEx(HuPrcCurrentGet(), object); + return; + } + switch(work->state) { + case 0: + { + s16 model; + ModelData *model_ptr; + HsfObject *focus_obj; + if(BoardModelMotionEndCheck(work->model)) { + work->state = 1; + } + model = BoardModelIDGet(work->model); + model_ptr = &Hu3DData[model]; + Hu3DMotionExec(model, model_ptr->unk_08, model_ptr->unk_64, 0); + focus_obj = Hu3DModelObjPtrGet(model, "player"); + BoardModelPosGet(work->model, &camTargetFortune); + camTargetFortune.x += focus_obj->data.curr.pos.x; + camTargetFortune.y += focus_obj->data.curr.pos.y; + camTargetFortune.z += focus_obj->data.curr.pos.z; + } + + break; + + case 1: + break; + + default: + break; + } +} + +static void ExecComFortuneWin(void) +{ + s32 player_curr = GWSystem.player_curr; + u32 mess_player1; + u32 mess_player2; + u32 mess_main; + u32 mess_prize; + + GWSystem.player_curr = -1; + mess_player1 = BoardPlayerGetCharMess(comPlayer1); + mess_player2 = BoardPlayerGetCharMess(comPlayer2); + mess_prize = comPrizeMessTbl[comPrize]; + if(comPrize == 0 || comPrize == 5 || comPrize == 3) { + mess_main = 0x1C0012; + } else { + if(comPrize == 2) { + if(comCoin == 0) { + mess_main = 0x1C0013; + } else { + mess_main = 0x1C0011; + } + } else { + if(comPrize == 1 || comPrize == 4) { + if(comStar == 0) { + mess_main = 0x1C0014; + } else { + mess_main = 0x1C0011; + } + } + } + } + BoardWinCreate(2, mess_main, -1); + BoardWinInsertMesSet(mess_player1, 0); + BoardWinInsertMesSet(mess_prize, 1); + BoardWinInsertMesSet(mess_player2, 2); + BoardWinWait(); + BoardWinKill(); + GWSystem.player_curr = player_curr; +} + +static void ConfigComFortune(void) +{ + s32 type; + s32 random; + s8 prizeTbl[] = { 5, 3, 0, 1, 4 }; + random = BoardRandMod(100); + if(random > 95) { + type = 0; + } else if(random > 60) { + type = 1; + } else { + type = 2; + } + switch(type) { + case 0: + comPrize = prizeTbl[BoardRandMod(2)]; + break; + + case 1: + comPrize = prizeTbl[BoardRandMod(3)+2]; + break; + + case 2: + comPrize = 2; + break; + + default: + break; + } + comPlayer1 = BoardRandMod(4); + comPlayer2 = comPlayer1; + while(comPlayer2 == comPlayer1) { + comPlayer2 = BoardRandMod(4); + } + switch(comPrize) { + case 4: + ComFortuneAddStar(comPlayer1, comPlayer2, 2); + break; + + case 1: + ComFortuneAddStar(comPlayer1, comPlayer2, 1); + break; + + case 2: + ComFortuneAddCoin(comPlayer1, comPlayer2, 20); + break; + + case 3: + ComFortuneSwapCoin(comPlayer1, comPlayer2); + ComFortuneSwapStar(comPlayer1, comPlayer2); + break; + + case 0: + ComFortuneSwapCoin(comPlayer1, comPlayer2); + break; + + case 5: + ComFortuneSwapStar(comPlayer1, comPlayer2); + break; + } +} + +static void ComFortuneAddStar(s32 player1, s32 player2, s32 max_stars) +{ + s32 stars = GWStarsGet(player1); + comStar = stars; + if(stars > max_stars) { + stars = max_stars; + } + BoardPlayerStarsAdd(player1, -stars); + BoardPlayerStarsAdd(player2, stars); +} + +static void ComFortuneAddCoin(s32 player1, s32 player2, s32 max_stars) +{ + s32 stars = BoardPlayerCoinsGet(player1); + comCoin = stars; + if(stars > max_stars) { + stars = max_stars; + } + BoardPlayerCoinsAdd(player1, -stars); + BoardPlayerCoinsAdd(player2, stars); +} + +static void ComFortuneSwapCoin(s32 player1, s32 player2) +{ + s32 temp; + temp = BoardPlayerCoinsGet(player1); + BoardPlayerCoinsSet(player1, BoardPlayerCoinsGet(player2)); + BoardPlayerCoinsSet(player2, temp); +} + +static void ComFortuneSwapStar(s32 player1, s32 player2) +{ + s32 temp; + temp = GWStarsGet(player1); + GWStarsSet(player1, GWStarsGet(player2)); + GWStarsSet(player2, temp); +} \ No newline at end of file diff --git a/src/game/board/lottery.c b/src/game/board/lottery.c index e08f6781..745fd903 100755 --- a/src/game/board/lottery.c +++ b/src/game/board/lottery.c @@ -101,7 +101,7 @@ static s32 handUpdateF; // ... static omObjData *lotteryTicketPickObj; static s8 (*comInputDrawP)[2]; -Process *lotteryProc; +static Process *lotteryProc; static s16 hostMdl = -1; static s16 lotteryMot[4] = { -1, -1, -1, -1 }; @@ -1032,7 +1032,7 @@ static void ExecBallPrize(void) { } } -const s32 lbl_8011DFD0[] = { +static const s32 pickSpr[] = { 0x0007001E, 0x0007001F, 0x00070020, @@ -1043,7 +1043,7 @@ const s32 lbl_8011DFD0[] = { 0x00070025 }; -const s32 lbl_8011DFF0[] = { +static const s32 handMdl[] = { 0x00050009, 0x0005000A, 0x0005000B, @@ -1054,7 +1054,7 @@ const s32 lbl_8011DFF0[] = { 0x00050010 }; -const s32 lbl_8011E010[] = { +static const s32 ticketSpr[] = { 0x0005001D, 0x0005001E, 0x0005001F, @@ -1104,7 +1104,7 @@ static void ExecScratchTicket(s32 arg0) { var_r24 = GWPlayer[GWSystem.player_curr].character; var_r22 = ticketObj[arg0]; temp_r30 = OM_GET_WORK_PTR(var_r22, TicketWork); - lotteryMdl[4] = BoardModelCreate(lbl_8011DFF0[var_r24], NULL, 0); + lotteryMdl[4] = BoardModelCreate(handMdl[var_r24], NULL, 0); BoardModelLayerSet(lotteryMdl[4], 6); BoardModelPassSet(lotteryMdl[4], 0); BoardCameraDirGet(&spC); @@ -1295,7 +1295,7 @@ static void InitScratchSpr(void) { temp_r31->trans.y = 98.0f + 110.0f * (i / 4); temp_r31->rot.x = -56.0f; temp_r31->rot.y = temp_r31->trans.y; - BoardSpriteCreate(lbl_8011E010[ticketPrize[i]], 0x157C, NULL, &sp8); + BoardSpriteCreate(ticketSpr[ticketPrize[i]], 0x157C, NULL, &sp8); HuSprGrpMemberSet(temp_r28, i, sp8); HuSprPosSet(temp_r28, i, temp_r31->rot.x, temp_r31->rot.y); HuSprAttrSet(temp_r28, i, 8); @@ -1417,7 +1417,7 @@ static void InitScratchPick(void) { var_r31->unk00_field0 = 0; var_r31->unk01 = GWPlayer[GWSystem.player_curr].character; var_r31->unk08 = HuSprGrpCreate(1); - BoardSpriteCreate(lbl_8011DFD0[var_r31->unk01], 0x1388, 0, &var_r31->unk06); + BoardSpriteCreate(pickSpr[var_r31->unk01], 0x1388, 0, &var_r31->unk06); HuSprGrpMemberSet(var_r31->unk08, 0, var_r31->unk06); HuSprAttrSet(var_r31->unk08, 0, 8); HuSprPosSet(var_r31->unk08, 0, temp_f31, temp_f30);