diff --git a/include/driver/casedrv.h b/include/driver/casedrv.h index 661927a..1c7e18f 100644 --- a/include/driver/casedrv.h +++ b/include/driver/casedrv.h @@ -14,8 +14,23 @@ typedef struct CaseSetup { s32 priority; //0x58 } CaseSetup; +typedef struct CaseEntry { + u16 flags; //0x0 + u8 pad_2[2]; //0x2 + s32 activeConditionId; //0x4, TODO rename + char hitObjName[0x40]; //0x8 + s32 caseId; //0x48 + u32 swFlag; //0x4C + void* activeFunc; //0x50 + s32 lwData[16]; //0x54 + u8 field_0x94[4]; //0x94 + void* evtCode; //0x98, TODO re-type + s32 priority; //0x9C +} CaseEntry; + void caseInit(void); void caseReInit(void); s32 caseEntry(CaseSetup* setup); void caseDelete(s32 caseId); -void caseMain(void); \ No newline at end of file +void caseMain(void); +CaseEntry* caseCheckHitObj(void* obj); // Takes HitEntry diff --git a/include/koopa_motion.h b/include/koopa_motion.h new file mode 100644 index 0000000..de47b64 --- /dev/null +++ b/include/koopa_motion.h @@ -0,0 +1,2 @@ +void kpa_dash(void); +void kpa_walk(void); diff --git a/include/mario/mario.h b/include/mario/mario.h index 6d8ec9f..7ef4f84 100644 --- a/include/mario/mario.h +++ b/include/mario/mario.h @@ -85,6 +85,29 @@ typedef enum MarioFlags { } MarioFlags; #pragma enumsalwaysint on +#pragma enumsalwaysint off +typedef enum MarioTrigFlags { + MARIO_TRIG_FLAG_IS_STARTING_NEW_MOTION = (1 << 0), + MARIO_TRIG_FLAG_USE_PARTNER = (1 << 1), + MARIO_TRIG_FLAG_SHIP_PLANE_EVT_ON = (1 << 2), + MARIO_TRIG_FLAG_DISP_DIR_CORRECTION = (1 << 8), + MARIO_TRIG_FLAG_DISP_DIR_LEFT = (1 << 9), + MARIO_TRIG_FLAG_DISP_DIR_RIGHT = (1 << 10), + MARIO_TRIG_FLAG_CHG_ANIM = (1 << 12), + MARIO_TRIG_FLAG_CHG_PAPER_ANIM = (1 << 14), + MARIO_TRIG_FLAG_SET_JUMP_PARAMS = (1 << 16), + MARIO_TRIG_FLAG_DISABLE_JUMP_KEMURI = (1 << 17), + MARIO_TRIG_FLAG_JABARA_CHK = (1 << 20), + MARIO_TRIG_FLAG_JABARA_MOVE_CHK = (1 << 21), + MARIO_TRIG_FLAG_START_JABARA_SPIN = (1 << 22), + MARIO_TRIG_FLAG_DISABLE_UNUSED_INPUT = (1 << 24), + MARIO_TRIG_FLAG_DISABLE_TRIGGERS = (1 << 25), + MARIO_TRIG_FLAG_DISABLE_SUB_STICK = (1 << 26), + MARIO_TRIG_FLAG_DISABLE_STICK = (1 << 27), + MARIO_TRIG_FLAG_DISABLE_PARTY_SLIT = (1 << 30) +} MarioTrigFlags; +#pragma enumsalwaysint on + //TODO: US struct is bigger, 0x2F8 vs 0x2E0 typedef struct MarioWork { u32 flags; //0x0 @@ -103,10 +126,13 @@ typedef struct MarioWork { u8 field_0x32[0x3C - 0x32]; //0x32 s8 characterId; //0x3C s8 colorId; //0x3D - u8 field_0x3E[0x44 - 0x3E]; //0x3E + u8 field_0x3E[0x40 - 0x3E]; //0x3E + s8 wMotionTimer; //0x40 + u8 field_0x41[0x44 - 0x41]; //0x41 u32 currSubMotionId; //0x44 u32 multiTimer; //0x48, ??? - u8 field_0x4C[0x50 - 0x4C]; //0x4C + u16 unk4C; // 0x4C + s16 forceMoveTimer; //0x4E s16 airTimer; // 0x50 u8 field_0x52[0x5C - 0x52]; //0x52 s16 unk5C; //0x5C @@ -137,25 +163,38 @@ typedef struct MarioWork { u8 unk160[0x168 - 0x160]; //0x160 s32 unk168; //0x168 s32 unk16C; //0x16C - u8 unk170[0x184 - 0x170]; //0x170 + u8 unk170[0x180 - 0x170]; //0x170 + f32 baseSpeed; // 0x180, same on US f32 mBaseWalkSpeed; //0x184 f32 mBaseDashSpeed; //0x188, same on US - u8 unk18C[0x198 - 0x18C]; //0x18C + u8 unk18C[0x190 - 0x18C]; //0x18C + f32 controlStickSensitivity; //0x190 + f32 controlStickAngle; //0x194 f32 targetYaw; //0x198 - u8 unk19C[0x1A8 - 0x19C]; //0x19C + u8 unk19C[0x1A0 - 0x19C]; //0x19C + f32 directionView; //0x1A0 + f32 forceDirection; //0x1A4 f32 unk1A8; //0x1A8 u8 unk1AC[0x1B4 - 0x1AC]; //0x1AC Vec wPlayerCollisionBox; //0x1B4 JP, 0x1B8 US u8 field_0x1C0[0x1D8 - 0x1C0]; //0x1C0 s32 field_0x1D8; //0x1D8 - u8 field_0x1DC[0x228 - 0x1DC]; //0x1DC + u8 field_0x1DC[0x1E4 - 0x1DC]; //0x1DC + void* hitobjStandOn; //0x1E4, 0x1E8 US HitEntry + void* hitobjJumpFrom; //0x1E8, 0x1EC US HitEntry + void* hitobjPush; //0x1EC JP, 0x1F0 US HitEntry + u8 field_0x1F0[0x224 - 0x1F0]; //0x1F0 + f32 playerGravity; //0x224 JP, 228 US s32 paperAnimGroupId[3]; //0x228 JP, 0x22C US u8 field_0x234[0x23C - 0x234]; //0x234 s32 paperPoseId; //0x23C JP, 0x240 US u8 field_0x240[0x241 - 0x240]; //0x240 s8 currPartySlotId[2]; //0x241 JP, 0x245 US s8 prevPartyMemberId[2]; //0x243 JP, 0x247 US - u8 field_0x245[0x288 - 0x245]; //0x245 + u8 field_0x245[0x24E - 0x245]; //0x245 + u8 wStickDir1; //0x24E JP, 0x252 US + u8 wStickDir2; //0x24F JP, 0x253 US + u8 field_0x250[0x288 - 0x250]; //0x250 void* motStruct; //0x288, motion userdata, TODO rename? u8 field_0x28C[0x2A8 - 0x28C]; //0x28C f32 wCamVal1; //0x2A8, TODO: double check diff --git a/include/mario/mario_cam.h b/include/mario/mario_cam.h index 6b4e18e..db7cd57 100644 --- a/include/mario/mario_cam.h +++ b/include/mario/mario_cam.h @@ -4,3 +4,4 @@ s32 marioGetCamId(void); void marioCamZoomOffReq2(s32); +void marioResetCamFollowRate(void); diff --git a/include/mario/mario_motion.h b/include/mario/mario_motion.h new file mode 100644 index 0000000..d365dcb --- /dev/null +++ b/include/mario/mario_motion.h @@ -0,0 +1,7 @@ +#include "dolphin/types.h" +#include "mario/mario.h" + +void marioChgMot(MarioMotion); +BOOL marioChkItemMotion(void); +BOOL marioChkJump(void); +BOOL marioChkTransform(void); diff --git a/include/mot/mot_slit.h b/include/mot/mot_slit.h new file mode 100644 index 0000000..d007e30 --- /dev/null +++ b/include/mot/mot_slit.h @@ -0,0 +1,5 @@ +#include "dolphin/types.h" + +BOOL marioSlitAbilityChk(void); +s32 marioSlitButton(void); +void motSlitContinue(void); diff --git a/include/mot/mot_walk.h b/include/mot/mot_walk.h new file mode 100644 index 0000000..d416cd6 --- /dev/null +++ b/include/mot/mot_walk.h @@ -0,0 +1,3 @@ +#include "dolphin/types.h" + +f32 marioGetDashSpd(void); diff --git a/include/peach.h b/include/peach.h new file mode 100644 index 0000000..a346bf3 --- /dev/null +++ b/include/peach.h @@ -0,0 +1,2 @@ +void peach_dash(void); +void peach_walk(void); diff --git a/include/pmario_sound.h b/include/pmario_sound.h index 507493f..1718fdc 100644 --- a/include/pmario_sound.h +++ b/include/pmario_sound.h @@ -113,6 +113,7 @@ void psndSFXAllOff(void); void psndSFXOn(const char* name); +void psndSFXOn_3D(const char* name, Vec* position); BOOL psndBGMOff_f_d(s32 flags, u16 fadetime, BOOL someswitch); diff --git a/src/driver/casedrv.c b/src/driver/casedrv.c index f76c221..64aa47a 100644 --- a/src/driver/casedrv.c +++ b/src/driver/casedrv.c @@ -2,20 +2,6 @@ #include "memory.h" #include -typedef struct CaseEntry { - u16 flags; //0x0 - u8 pad_2[2]; //0x2 - s32 activeConditionId; //0x4, TODO rename - char hitObjName[0x40]; //0x8 - s32 caseId; //0x48 - u32 swFlag; //0x4C - void* activeFunc; //0x50 - s32 lwData[16]; //0x54 - u8 field_0x94[4]; //0x94 - void* evtCode; //0x98, TODO re-type - s32 priority; //0x9C -} CaseEntry; - typedef struct CaseWork { s32 count; //0x0 CaseEntry* entries; //0x4 diff --git a/src/motion/mot_walk.c b/src/motion/mot_walk.c new file mode 100644 index 0000000..7453089 --- /dev/null +++ b/src/motion/mot_walk.c @@ -0,0 +1,344 @@ +#include "dolphin/types.h" +#include "driver/hitdrv.h" +#include "pmario_sound.h" +#include "mario/mario.h" +#include "driver/casedrv.h" +#include "mot/mot_slit.h" +#include "mario/mario_cam.h" +#include "mario/mario_motion.h" +#include "koopa_motion.h" +#include "peach.h" +#include "mario/mario_pouch.h" + +extern s32 gp; // m2c + +f32 marioGetDashSpd(void) { + MarioWork* mario; + f32 dashSpeed; + s8 stickDir2; + s8 stickDir1; + + mario = marioGetPtr(); + dashSpeed = mario->mBaseDashSpeed; + if (mario->flags & MARIO_FLAG_PAPER_MODE) { + stickDir1 = mario->wStickDir1; + stickDir2 = mario->wStickDir2; + dashSpeed = mario->mBaseWalkSpeed; + + if ((stickDir1 * stickDir1) + (stickDir2 * stickDir2) <= 0xBD1) { + dashSpeed *= 0.5f; + } + } else if (marioBgmodeChk() == TRUE) { + dashSpeed *= 0.5f; + } + + dashSpeed *= mario->playerGravity; + return dashSpeed; +} + +f32 marioGetWalkSpd(void) { + f32 walkSpeed; + s8 stickDir2; + s8 stickDir1; + MarioWork* mario; + + mario = marioGetPtr(); + walkSpeed = mario->mBaseWalkSpeed; + if (mario->flags & MARIO_FLAG_PAPER_MODE) { + stickDir1 = mario->wStickDir1; + stickDir2 = mario->wStickDir2; + if ((stickDir1 * stickDir1) + (stickDir2 * stickDir2) <= 0xBD1) { + walkSpeed *= 0.5f; + } + } else if (marioBgmodeChk() == TRUE) { + walkSpeed *= 0.5f; + } + + walkSpeed *= mario->playerGravity; + return walkSpeed; +} + +void marioWalkDashSe(HitObj* hitObj, u32 arg1) { + s32 hitAttr; + MarioWork* mario; + + mario = marioGetPtr(); + hitAttr = hitGetAttr(hitObj); + if ((mario->multiTimer % arg1) == 0) { + if (hitAttr & 0x100) { + psndSFXOn_3D((char*)0x143, &mario->position); + return; + } + if (hitAttr & 0x200000) { + psndSFXOn_3D((char*)0x145, &mario->position); + return; + } + if (hitAttr & 0x100000) { + psndSFXOn_3D((char*)0x147, &mario->position); + return; + } + if (hitAttr & 0x1000) { + if (strncmp((char*)(gp + 0x12C), "mri", 3) != 0) { + psndSFXOn_3D((char*)0x149, &mario->position); + return; + } + psndSFXOn_3D((char*)0x143, &mario->position); + return; + } + if (hitAttr & 0x400000) { + psndSFXOn_3D((char*)0x14B, &mario->position); + return; + } + psndSFXOn_3D((char*)0x141, &mario->position); + return; + } + if ((mario->multiTimer % (arg1 >> 1U)) == 0) { + if (hitAttr & 0x100) { + psndSFXOn_3D((char*)0x142, &mario->position); + return; + } + if (hitAttr & 0x200000) { + psndSFXOn_3D((char*)0x144, &mario->position); + return; + } + if (hitAttr & 0x100000) { + psndSFXOn_3D((char*)0x146, &mario->position); + return; + } + if (hitAttr & 0x1000) { + if (strncmp((char*)(gp + 0x12C), "mri", 3) != 0) { + psndSFXOn_3D((char*)0x148, &mario->position); + return; + } + psndSFXOn_3D((char*)0x142, &mario->position); + return; + } + if (hitAttr & 0x400000) { + psndSFXOn_3D((char*)0x14A, &mario->position); + return; + } + psndSFXOn_3D((char*)0x140, &mario->position); + } +} + +void mot_dash(void) { + f32 dashSpeed; + u32 trigFlags; + BOOL unkConditionActive; + s32 unkArgMarioWalkDashSe; + s8 characterId; + s8 stickDir2; + s8 stickDir1; + MarioWork* player; + CaseEntry* caseEntry; + + player = marioGetPtr(); + characterId = player->characterId; + if (characterId == 2) { + kpa_dash(); + return; + } + if (characterId == 1) { + peach_dash(); + return; + } + if (player->hitobjPush == NULL) { + unkConditionActive = FALSE; + } else { + caseEntry = caseCheckHitObj(player->hitobjPush); + if (caseEntry != NULL && caseEntry->activeConditionId == 0xA) { + unkConditionActive = TRUE; + } else { + unkConditionActive = FALSE; + } + } + if (!unkConditionActive && player->hitobjPush == NULL) { + player->flags = player->flags & ~MARIO_FLAG_IS_PUSHING; + if (marioChkPushAnime() && !marioBgmodeChk()) { + marioChgPose("M_R_1"); + } + } + trigFlags = player->trigFlags; + if (trigFlags & MARIO_TRIG_FLAG_IS_STARTING_NEW_MOTION) { + player->trigFlags = trigFlags & ~MARIO_TRIG_FLAG_IS_STARTING_NEW_MOTION; + player->flags = player->flags & ~(MARIO_FLAG_HAS_INPUT_JUMP | MARIO_FLAG_IS_JUMPING | MARIO_FLAG_IS_FALLING | + MARIO_FLAG_IS_STEPPING); + marioResetCamFollowRate(); + if (player->flags & MARIO_FLAG_PAPER_MODE) { + motSlitContinue(); + } + if (player->playerGravity == 1.0f) { + if (player->flags & MARIO_FLAG_IS_PUSHING) { + if (!marioChkPushAnime()) { + marioChgPose("M_O_1"); + } + } else if (!marioBgmodeChk()) { + marioChgPose("M_R_1"); + } + } else if (player->flags & MARIO_FLAG_IS_PUSHING) { + if (!marioChkPushAnime()) { + marioChgPose("M_O_1"); + } + } else { + marioChgPose("M_W_1"); + } + if (player->forceMoveTimer == 0) { + player->baseSpeed = marioGetDashSpd(); + } + } + if (!(player->flags & MARIO_FLAG_IS_CARRYING_BOBBERY) && + (strcmp(player->animName, "M_I_Y") == 0 || player->wMotionTimer > 0xA)) { + marioChgMot(MARIO_MOTION_STAY); + return; + } + if (player->flags & MARIO_FLAG_IS_CARRYING_BOBBERY) { + marioChgMot(MARIO_MOTION_WALK); + return; + } + if (marioSlitAbilityChk() && marioSlitButton() == 1) { + marioChgMot(MARIO_MOTION_SLIT); + return; + } + if (!marioChkItemMotion()) { + marioChkJump(); + marioChkTransform(); + if (player->hitobjStandOn != NULL) { + if (player->playerGravity == 1.0f) { + unkArgMarioWalkDashSe = 0x14; + } else { + unkArgMarioWalkDashSe = 0x28; + } + marioWalkDashSe(player->hitobjStandOn, unkArgMarioWalkDashSe); + } + player->multiTimer = player->multiTimer + 1; + if (!(player->flags & MARIO_FLAG_FORCED_MOVEMENT)) { + stickDir1 = player->wStickDir1; + stickDir2 = player->wStickDir2; + if ((stickDir1 * stickDir1) + (stickDir2 * stickDir2) <= 0xBD1) { + marioChgMot(MARIO_MOTION_WALK); + return; + } + player->directionView = player->controlStickAngle; + if ((player->flags & MARIO_FLAG_IS_PUSHING) && !marioChkPushAnime()) { + marioChgPose("M_O_1"); + } + if (!player->controlStickSensitivity) { + marioChgMot(MARIO_MOTION_STAY); + } + } + } +} + +void mot_walk(void) { + f32 walkSpeed; + s32 trigFlags; + s32 flags; + BOOL unkConditionActive; + s32 unkArgMarioWalkDashSe; + s8 characterId; + s8 stickDir2; + s8 stickDir1; + MarioWork* player; + CaseEntry* caseEntry; + + player = marioGetPtr(); + characterId = player->characterId; + if (characterId == 2) { + kpa_walk(); + return; + } + if (characterId == 1) { + peach_walk(); + return; + } + if (player->flags & MARIO_FLAG_IS_PUSHING) { + if (player->hitobjPush == NULL) { + unkConditionActive = FALSE; + } else { + caseEntry = caseCheckHitObj(player->hitobjPush); + if (caseEntry != NULL && caseEntry->activeConditionId == 0xA) { + unkConditionActive = TRUE; + } else { + unkConditionActive = FALSE; + } + } + if (!unkConditionActive) { + player->flags = player->flags & ~MARIO_FLAG_IS_PUSHING; + if (marioChkPushAnime() && !marioBgmodeChk()) { + marioChgPose("M_W_1"); + } + } + } + trigFlags = player->trigFlags; + if (trigFlags & MARIO_TRIG_FLAG_IS_STARTING_NEW_MOTION) { + player->trigFlags = trigFlags & ~MARIO_TRIG_FLAG_IS_STARTING_NEW_MOTION; + player->flags = player->flags & ~(MARIO_FLAG_HAS_INPUT_JUMP | MARIO_FLAG_IS_JUMPING | MARIO_FLAG_IS_FALLING | + MARIO_FLAG_IS_STEPPING); + marioResetCamFollowRate(); + if (player->flags & MARIO_FLAG_PAPER_MODE) { + motSlitContinue(); + } + if (player->forceMoveTimer == 0) { + player->baseSpeed = marioGetWalkSpd(); + } + flags = player->flags; + if (flags & MARIO_FLAG_IS_CARRYING_BOBBERY) { + marioChgPose("M_W_7"); + } else if (flags & MARIO_FLAG_IS_PUSHING) { + if (!marioChkPushAnime()) { + marioChgPose("M_O_1"); + } + } else if (!marioBgmodeChk()) { + marioChgPose("M_W_1"); + } + if (!(player->dispFlags & (1 << 24))) { + player->currSubMotionId = 0; + } + player->multiTimer = 0; + } + if (!(player->flags & MARIO_FLAG_IS_CARRYING_BOBBERY) && + (strcmp(player->animName, "M_I_Y") == 0 || player->wMotionTimer > 0xA)) { + marioChgMot(MARIO_MOTION_STAY); + return; + } + if (player->flags & MARIO_FLAG_IS_CARRYING_BOBBERY) { + player->directionView = player->controlStickAngle; + if (!player->controlStickSensitivity) { + marioChgMot(MARIO_MOTION_STAY); + } + } else { + if (marioSlitAbilityChk() && marioSlitButton() == 1) { + marioChgMot(MARIO_MOTION_SLIT); + return; + } + if (!marioChkItemMotion()) { + marioChkJump(); + marioChkTransform(); + if (pouchEquipCheckBadge(0x143) == 0) { + stickDir1 = player->wStickDir1; + stickDir2 = player->wStickDir2; + if ((stickDir1 * stickDir1) + (stickDir2 * stickDir2) > 0xBD1) { + marioChgMot(MARIO_MOTION_DASH); + return; + } + } + player->directionView = player->controlStickAngle; + if (player->hitobjStandOn != 0) { + // Redundant, but doesn't match otherwise + if (player->playerGravity == 1.0f) { + unkArgMarioWalkDashSe = 0x28; + } else { + unkArgMarioWalkDashSe = 0x28; + } + marioWalkDashSe(player->hitobjStandOn, unkArgMarioWalkDashSe); + } + player->multiTimer = player->multiTimer + 1; + if (player->flags & MARIO_FLAG_IS_PUSHING && !marioChkPushAnime()) { + marioChgPose("M_O_1"); + } + if (!player->controlStickSensitivity) { + marioChgMot(MARIO_MOTION_STAY); + } + } + } +} diff --git a/src/pmario_sound.c b/src/pmario_sound.c index 71a3723..b9dec26 100644 --- a/src/pmario_sound.c +++ b/src/pmario_sound.c @@ -4571,6 +4571,6 @@ void psndSetPosDirListener(Vec* position, f32 direction) { //1:1 psnd.direction = direction; } -s32 psndSFXOn_3D(const char* name, Vec* position) { +void psndSFXOn_3D(const char* name, Vec* position) { }