From eeff144f1c289c6b943495340ab637d84ebbf770 Mon Sep 17 00:00:00 2001 From: gamemasterplc Date: Tue, 12 Mar 2024 09:48:48 -0500 Subject: [PATCH] Start board/bowser.c --- config/GMPE01_00/symbols.txt | 4 +- include/board_unsplit.h | 2 +- include/game/board/main.h | 3 + include/game/gamework_data.h | 6 +- src/game/board/bowser.c | 486 +++++++++++++++++++++++++++++++++++ src/game/board/main.c | 8 +- src/game/objsub.c | 2 +- 7 files changed, 500 insertions(+), 11 deletions(-) create mode 100644 src/game/board/bowser.c diff --git a/config/GMPE01_00/symbols.txt b/config/GMPE01_00/symbols.txt index 619f7c39..0e457f48 100644 --- a/config/GMPE01_00/symbols.txt +++ b/config/GMPE01_00/symbols.txt @@ -5928,8 +5928,8 @@ jumpMot = .sdata:0x801D3798; // type:object size:0x2 scope:local data:2byte starMdl = .sdata:0x801D379A; // type:object size:0x2 scope:local data:2byte lbl_801D37A0 = .sdata:0x801D37A0; // type:object size:0x8 lbl_801D37A8 = .sdata:0x801D37A8; // type:object size:0x8 -lbl_801D37B0 = .sdata:0x801D37B0; // type:object size:0x2 data:2byte -lbl_801D37B2 = .sdata:0x801D37B2; // type:object size:0x2 data:2byte +jumpMot = .sdata:0x801D37B0; // type:object size:0x2 scope:local data:2byte +scareMot = .sdata:0x801D37B2; // type:object size:0x2 scope:local data:2byte suitItemMdl = .sdata:0x801D37B4; // type:object size:0x2 scope:local data:2byte bowserMdl = .sdata:0x801D37B6; // type:object size:0x2 scope:local data:2byte lbl_801D37B8 = .sdata:0x801D37B8; // type:object size:0x3 data:string diff --git a/include/board_unsplit.h b/include/board_unsplit.h index d6ca8de1..cc378fc7 100644 --- a/include/board_unsplit.h +++ b/include/board_unsplit.h @@ -15,7 +15,7 @@ void BoardBooHouseHostSet(s16); s32 BoardCameraRotGet(Vec*); s32 BoardIsKill(void); -void BoardBowserExec(s32 player, s32 space); +s32 BoardBowserExec(s32 player, s32 space); void BoardFortuneExec(s32 player, s32 space); #endif diff --git a/include/game/board/main.h b/include/game/board/main.h index b58a40d1..22710325 100644 --- a/include/game/board/main.h +++ b/include/game/board/main.h @@ -72,6 +72,8 @@ extern omObjData *boardMainObj; typedef void (*BoardFunc)(void); typedef void (*BoardLightHook)(void); +typedef void (*BoardBowserHook)(s32 beforeF); + typedef void (*BoardCameraPosCalcFunc)(BoardCameraData *camera); typedef void (*BoardTurnStartHook)(s32 player, s32 space); @@ -79,6 +81,7 @@ typedef void (*BoardTurnStartHook)(s32 player, s32 space); extern BoardTurnStartHook boardTurnStartFunc; extern void (*boardStarShowNextHook)(void); extern void (*boardStarGiveHook)(void); +extern BoardBowserHook boardBowserHook; extern BoardFunc boardTurnFunc; extern BoardLightHook boardLightResetHook; extern BoardLightHook boardLightSetHook; diff --git a/include/game/gamework_data.h b/include/game/gamework_data.h index 1ab6b00d..6393b6e3 100644 --- a/include/game/gamework_data.h +++ b/include/game/gamework_data.h @@ -40,8 +40,8 @@ typedef struct system_state { /* 0x10 */ u8 ATTRIBUTE_ALIGN(4) board_data[32]; /* 0x30 */ u8 mess_delay; /* 0x31 */ struct { - u8 field31_bit0 : 4; - u8 field31_bit4 : 4; + u8 bowser_loss : 4; + u8 bowser_event : 4; }; /* 0x32 */ s8 unk_32; /* 0x34 */ u16 mg_next; @@ -98,7 +98,7 @@ typedef struct player_state { /* 0x22 */ s16 coins_max; /* 0x24 */ s16 coins_battle; /* 0x26 */ s16 unk_26; -/* 0x28 */ s16 coins_mg_gain; +/* 0x28 */ s16 coin_gain; /* 0x2A */ s16 stars; /* 0x2C */ s16 stars_max; /* 0x2E */ char unk_2E[2]; diff --git a/src/game/board/bowser.c b/src/game/board/bowser.c new file mode 100644 index 00000000..a0c2f285 --- /dev/null +++ b/src/game/board/bowser.c @@ -0,0 +1,486 @@ +#include "game/board/main.h" +#include "game/board/model.h" +#include "game/board/player.h" +#include "game/board/audio.h" +#include "game/board/window.h" + +#include "game/objsub.h" +#include "game/sprite.h" +#include "game/audio.h" +#include "game/wipe.h" +#include "game/gamework.h" + +static s16 bowserSpr[11]; +static Vec playerPosTemp[4]; + +static s32 scareFxTbl[] = { + 0x128, + 0x168, + 0x1A8, + 0x1E8, + 0x228, + 0x268, + 0x2A8, + 0x2E8 +}; + + +static s8 eventPlayer; +static s8 eventType; +static s16 eventSpace; +static s16 playerMot[4]; +static s16 fireParMan; +static AnimData *fireAnim; +static char coinStealStrAll[8]; +static char coinStealStr[8]; +static omObjData *suitGiveObj; +static omObjData *miniBowserBalloonObj; +static omObjData *bowserEventObj; +static omObjData *miniBowserObj; +static omObjData *bowserObj; +static Process *bowserProc; + +static s16 jumpMot = -1; +static s16 scareMot = -1; +static s16 suitItemMdl = -1; +static s16 bowserMdl = -1; + +static void ExecBowser(void); +static void ExecBowserMain(void); +static void ExecMGReturn(void); +static void DestroyBowser(void); + +static void SquishPlayers(void); +static void ExecBowserSpecial(void); +static void ExecBowserGame(void); +static void DoMGReturnEffect(void); +static void ExecBowserShuffle(void); +static void ExecBowserRevo(void); +static void ExecBowserSuit(void); + +static void CreateBowserObj(void); + +static void SetBowserState(s32 state); +static s32 CheckBowserIdle(void); + +static void CreateBowserEvent(void); +static s32 CheckBowserEvent(void); +static void StopBowserEvent(void); + +static void ConfigBowserEvent(void); + +static void CreateMiniBowser(void); +static s32 CheckMiniBowser(void); + + +static void CreatePlayerMot(void); +static void KillPlayerMot(void); + +static void InitBowserFire(void); +static void KillBowserFire(void); + +static s32 ExecMiniBowserEvent(void); + +s32 BoardBowserExec(s32 player, s32 space) +{ + if(_CheckFlag(0x1000B)) { + HuAudFXPlay(841); + BoardCameraViewSet(2); + BoardPlayerMotBlendSet(player, 0, 15); + while(!BoardPlayerMotBlendCheck(player)) { + HuPrcVSleep(); + } + BoardCameraMotionWait(); + BoardTutorialHookExec(12, 0); + GWPlayer[player].color = 2; + } else { + eventPlayer = player; + eventSpace = space; + playerMot[0] = playerMot[1] = playerMot[2] = playerMot[3] = -1; + bowserProc = HuPrcChildCreate(ExecBowser, 8196, 14336, 0, boardMainProc); + HuPrcDestructorSet2(bowserProc, DestroyBowser); + while(bowserProc) { + HuPrcVSleep(); + } + GWPlayer[player].color = 2; + } +} + +typedef struct bowser_work { + u8 kill : 1; +} BowserWork; + +typedef struct mini_bowser_work { + u8 kill : 1; +} MiniBowserWork; + +typedef struct bowser_event_work { + u8 kill : 1; +} BowserEventWork; + +static void ExecBowser(void) +{ + s32 i; + s32 status; + if(!_CheckFlag(0x10003)) { + HuAudFXPlay(841); + omVibrate(eventPlayer, 12, 4, 2); + if(GWBoardGet() == 5 && boardBowserHook) { + boardBowserHook(1); + } + BoardAudSeqPause(0, 1, 1000); + if(BoardRandMod(100) < 20) { + eventType = 0; + } else { + eventType = 1; + } + } else { + BoardMusStart(1, 6, 127, 0); + } + status = BoardDataDirReadAsync(DATADIR_BKOOPA); + BoardDataAsyncWait(status); + CreatePlayerMot(); + if(!_CheckFlag(0x10003)) { + ExecBowserMain(); + } else { + ExecMGReturn(); + } + for(i=0; i<4; i++) { + if(eventSpace == GWPlayer[i].space_curr) { + BoardPlayerMotionSpeedSet(i, 1.0f); + } + } + BoardAudSeqPause(0, 0, 1000); + if(bowserObj) { + OM_GET_WORK_PTR(bowserObj, BowserWork)->kill = 1; + } + if(miniBowserObj) { + OM_GET_WORK_PTR(miniBowserObj, MiniBowserWork)->kill = 1; + } + if(bowserEventObj) { + OM_GET_WORK_PTR(bowserEventObj, BowserEventWork)->kill = 1; + } + GWPlayer[eventPlayer].show_next = 1; + BoardCameraMotionStartEx(-1, NULL, NULL, 2100.0f, -1.0f, 21); + HuPrcSleep(30); + for(i=0; i<4; i++) { + BoardPlayerIdleSet(i); + } + BoardCameraMotionWait(); + if(GWBoardGet() == 5 && boardBowserHook) { + boardBowserHook(0); + } else { + HuPrcSleep(30); + } + HuPrcEnd(); +} + +static void ExecBowserMain(void) +{ + s32 result = 0; + BoardPlayerMotBlendSet(eventPlayer, 0, 15); + while(!BoardPlayerMotBlendCheck(eventPlayer)) { + HuPrcVSleep(); + } + BoardMusStart(1, 5, 127, 0); + BoardCameraViewSet(3); + BoardFilterFadeInit(30, 160); + BoardCameraMotionWait(); + BoardPlayerMotionShiftSet(eventPlayer, jumpMot, 0.0f, 10.0f, 0x40000001); + BoardPlayerMotionSpeedSet(eventPlayer, 2.0f); + HuPrcSleep(120); + ConfigBowserEvent(); + HuAudFXPlay(scareFxTbl[GWPlayer[eventPlayer].character]); + BoardPlayerMotionShiftSet(eventPlayer, scareMot, 0.0f, 10.0f, 0); + CreateMiniBowser(); + while(!CheckMiniBowser()) { + HuPrcVSleep(); + } + BoardPlayerIdleSet(eventPlayer); + if(eventType) { + result = ExecMiniBowserEvent(); + if(!result) { + return; + } + BoardAudSeqFadeOut(1, 1000); + BoardFilterFadeInit(30, 160); + HuPrcSleep(30); + } + ExecBowserSpecial(); + BoardModelMotionShiftSet(bowserMdl, 3, 0.0f, 8.0f, 0); + HuPrcSleep(8); + HuAudFXPlay(58); + BoardWinCreate(2, 0x3000B, 5); + BoardWinWait(); + BoardWinKill(); + BoardAudSeqFadeOut(1, 1000); + while(!BoardModelMotionEndCheck(bowserMdl)) { + HuPrcVSleep(); + } + SetBowserState(6); + while(!CheckBowserIdle()) { + HuPrcVSleep(); + } + BoardFilterFadeOut(30); +} + +static void ExecMGReturn(void) +{ + s32 i; + s32 player; + BoardStatusItemSet(1); + for(i=0; i<4; i++) { + BoardPlayerPosSetV(i, &playerPosTemp[i]); + } + BoardCameraMoveSet(0); + BoardCameraTargetPlayerSet(eventPlayer); + BoardCameraViewSet(2); + BoardCameraMotionWait(); + CreateBowserObj(); + SquishPlayers(); + BoardPlayerMotBlendSet(eventPlayer, 0, 15); + BoardCameraViewSet(3); + BoardFilterFadeInit(30, 160); + BoardStatusItemSet(0); + BoardCameraMotionWait(); + WipeCreate(WIPE_MODE_IN, WIPE_TYPE_NORMAL, 21); + while(WipeStatGet()) { + HuPrcVSleep(); + } + _ClearFlag(0x1001C); + BoardCameraMoveSet(1); + player = GWSystem.player_curr; + GWSystem.player_curr = -1; + DoMGReturnEffect(); + GWSystem.player_curr = player; + BoardStatusShowSetAll(1); + BoardModelMotionShiftSet(bowserMdl, 3, 0.0f, 8.0f, 0); + HuPrcSleep(8); + HuAudFXPlay(58); + BoardWinCreate(2, 0x3000B, 5); + BoardWinWait(); + BoardWinKill(); + while(!BoardStatusStopCheck(0)) { + HuPrcVSleep(); + } + BoardAudSeqFadeOut(1, 1000); + while(!BoardModelMotionEndCheck(bowserMdl)) { + HuPrcVSleep(); + } + SetBowserState(6); + while(!CheckBowserIdle()) { + HuPrcVSleep(); + } + BoardFilterFadeOut(30); + BoardMusStartBoard(); +} + +static void DestroyBowser(void) +{ + KillPlayerMot(); + HuDataDirClose(DATADIR_BKOOPA); + bowserProc = NULL; +} + +static void SquishPlayers(void) +{ + Vec pos; + Vec pos_space; + s32 i; + BoardPlayerPosGet(eventPlayer, &pos); + if(!_CheckFlag(0x10003)) { + HuAudFXPlay(798); + } + pos.y += 6.0f; + BoardPlayerPosSetV(eventPlayer, &pos); + GWPlayer[eventPlayer].show_next = 0; + BoardPlayerMotionSpeedSet(eventPlayer, 0.0f); + for(i=0; i<4; i++) { + if(eventSpace == GWPlayer[i].space_curr) { + BoardPlayerPosGet(i, &pos); + BoardSpacePosGet(0, eventSpace, &pos_space); + pos.y = pos_space.y+2.5f; + BoardPlayerPosSetV(i, &pos); + BoardPlayerMotionStart(i, playerMot[i], 0); + BoardPlayerMotionTimeSet(i, 50.0f); + BoardPlayerMotionSpeedSet(i, 0.0f); + } + } +} + +static void ExecBowserSpecial(void) +{ + s32 i; + CreateBowserObj(); + while(!CheckBowserIdle()) { + HuPrcVSleep(); + } + SetBowserState(2); + HuAudFXPlay(58); + BoardMusStart(1, 6, 127, 0); + HuPrcSleep(120); + BoardWinCreate(2, 0x30007, 5); + BoardWinWait(); + BoardWinKill(); + HuAudFXPlay(857); + BoardModelMotionShiftSet(bowserMdl, 4, 0.0f, 10.0f, 0); + for(i=0; i<4; i++) { + omVibrate(i, 12, 12, 0); + } + HuPrcSleep(11); + while(!BoardModelMotionEndCheck(bowserMdl)) { + HuPrcVSleep(); + } + CreateBowserEvent(); + HuAudFXPlay(831); + HuAudFXPlay(60); + while(!CheckBowserEvent()) { + HuPrcVSleep(); + } + HuPrcSleep(60); + BoardModelAttrSet(bowserMdl, 0x40000004); + while(!BoardModelMotionEndCheck(bowserMdl)) { + HuPrcVSleep(); + } + BoardModelMotionShiftSet(bowserMdl, 1, 0.0f, 10.0f, 0); + StopBowserEvent(); + switch(GWSystem.bowser_event) { + case 0: + ExecBowserGame(); + break; + + case 2: + ExecBowserRevo(); + break; + + case 1: + ExecBowserShuffle(); + break; + + case 3: + ExecBowserSuit(); + break; + } +} + +static void ExecBowserGame(void) +{ + s32 i; + s16 mgTbl[3] = { + 435, + 436, + 437 + }; + s32 messLoss[3] = { + 0x30009, + 0x3000C, + 0x3000E + }; + s32 mg; + s32 mess; + s32 fx_stat; + for(i=0; i<4; i++) { + BoardPlayerPosGet(i, &playerPosTemp[i]); + } + BoardWinCreate(2, 0x30008, 5); + BoardWinWait(); + mess = messLoss[GWSystem.bowser_loss]; + BoardWinCreate(2, mess, 5); + BoardWinWait(); + BoardWinKill(); + BoardModelMotionShiftSet(bowserMdl, 5, 0.0f, 8.0f, 0); + HuPrcSleep(8); + while(BoardModelMotionTimeGet(bowserMdl) < 80.0f) { + HuPrcVSleep(); + } + fx_stat = HuAudFXPlay(846); + InitBowserFire(); + while(BoardModelMotionTimeGet(bowserMdl) < 200.0f) { + HuPrcVSleep(); + } + BoardAudSeqFadeOut(1, 1000); + BoardMusVolPanSet(0, 0, 1); + BoardAudSeqPause(0, 0, 1); + _SetFlag(0x1000E); + HuAudFXFadeOut(fx_stat, 500); + WipeColorSet(255, 255, 255); + WipeCreate(WIPE_MODE_OUT, WIPE_TYPE_NORMAL, -1); + while(WipeStatGet()) { + HuPrcVSleep(); + } + HuAudFXAllStop(); + _SetFlag(0x1001C); + KillBowserFire(); + HuPrcSleep(60); + BoardModelMotionStart(bowserMdl, 1, 0); + mg = (s16)mgTbl[BoardRandMod(3)]; + GWMGAvailSet(mg); + GWSystem.mg_next = mg-401; + _SetFlag(0x10003); + BoardNextOvlSet(OVL_INST); + BoardFilterFadeOut(30); + HuPrcEnd(); +} + +static void DoMGReturnEffect(void) +{ + s32 messTbl[3] = { + 0x3000A, + 0x3000D, + 0x3000F + }; + s32 player; + s32 coin; + s32 item; + s32 delay; + s32 item_cnt; + s32 mess; + s32 mess_char; + for(player=0; player<4; player++) { + s16 gain = GWPlayer[player].coin_gain; + if(gain == 1) { + break; + } + } + mess = messTbl[GWSystem.bowser_loss]; + mess_char = BoardPlayerGetCharMess(player); + BoardStatusShowSetForce(player); + BoardStatusShowSet(player, 1); + BoardWinCreate(2, mess, 5); + BoardWinInsertMesSet(mess_char, 1); + BoardWinWait(); + while(!BoardStatusStopCheck(player)) { + HuPrcVSleep(); + } + omVibrate(player, 12, 4, 2); + if(GWSystem.bowser_loss == 2) { + item_cnt = BoardPlayerItemCount(player); + for(item=0; item> 1); + } + if(coin >= 50 ) { + delay = 1; + } else if(coin >= 20) { + delay = 3; + } else { + delay = 6; + } + while(coin != 0 && BoardPlayerCoinsGet(player) != 0) { + BoardPlayerCoinsAdd(player, -1); + HuAudFXPlay(14); + HuPrcSleep(delay); + coin--; + } + HuAudFXPlay(15); + } + BoardStatusShowSet(player, 0); + while(!BoardStatusStopCheck(player)) { + HuPrcVSleep(); + } +} \ No newline at end of file diff --git a/src/game/board/main.c b/src/game/board/main.c index 5db7bf48..8ad45315 100644 --- a/src/game/board/main.c +++ b/src/game/board/main.c @@ -33,7 +33,7 @@ static omObjData *last5GfxObj; static omObjData *confettiObj; static omObjData *filterObj; BoardTurnStartHook boardTurnStartFunc; -void *boardBowserHook; +BoardBowserHook boardBowserHook; void (*boardStarShowNextHook)(void); void (*boardStarGiveHook)(void); BoardFunc boardTurnFunc; @@ -288,8 +288,8 @@ void BoardSaveInit(s32 board) GWSystem.star_total = 1; GWSystem.last5_effect = 0; GWSystem.player_curr = -1; - GWSystem.field31_bit0 = 0; - GWSystem.field31_bit4 = 0; + GWSystem.bowser_loss = 0; + GWSystem.bowser_event = 0; GWSystem.unk_32 = 1; GWSystem.mg_next = 0; GWSystem.mg_next_type = 0; @@ -324,7 +324,7 @@ void BoardSaveInit(s32 board) GWPlayer[i].stars_max = 0; GWPlayer[i].coins_battle = 0; GWPlayer[i].unk_26 = 0; - GWPlayer[i].coins_mg_gain = 0; + GWPlayer[i].coin_gain = 0; GWPlayer[i].items[0] = -1; GWPlayer[i].items[1] = -1; GWPlayer[i].items[2] = -1; diff --git a/src/game/objsub.c b/src/game/objsub.c index 157500c3..151a0b87 100644 --- a/src/game/objsub.c +++ b/src/game/objsub.c @@ -1200,7 +1200,7 @@ void omGameSysInit(Process *objman) { for (i = 0; i < 4; i++) { if (_CheckFlag(0x1000C) == 0) { - GWPlayer[i].coins_mg_gain = 0; + GWPlayer[i].coin_gain = 0; } GWPlayer[i].unk_26 = 0;