diff --git a/data/behavior_data.c b/data/behavior_data.c index 584b4402..344e8f8f 100644 --- a/data/behavior_data.c +++ b/data/behavior_data.c @@ -115,7 +115,7 @@ // Often used to end behavior scripts that do not contain an infinite loop. #define BREAK() \ BC_B(0x0A) - + // Exits the behavior script, unused. #define BREAK_UNUSED() \ BC_B(0x0B) @@ -176,15 +176,15 @@ #define ADD_INT_RAND_RSHIFT(field, min, rshift) \ BC_BBH(0x17, field, min), \ BC_H(rshift) - + // No operation. Unused. #define CMD_NOP_1(field) \ BC_BB(0x18, field) - + // No operation. Unused. #define CMD_NOP_2(field) \ BC_BB(0x19, field) - + // No operation. Unused. #define CMD_NOP_3(field) \ BC_BB(0x1A, field) @@ -5473,7 +5473,11 @@ const BehaviorScript bhvTTCPendulum[] = { const BehaviorScript bhvTTCTreadmill[] = { BEGIN(OBJ_LIST_SURFACE), +#ifdef PLATFORM_DISPLACEMENT_2 + OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE | OBJ_FLAG_VELOCITY_PLATFORM)), +#else OR_INT(oFlags, (OBJ_FLAG_COMPUTE_DIST_TO_MARIO | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), +#endif SET_FLOAT(oCollisionDistance, 750), CALL_NATIVE(bhv_ttc_treadmill_init), DELAY(1), diff --git a/include/object_constants.h b/include/object_constants.h index 17a18c01..ac73b2d5 100644 --- a/include/object_constants.h +++ b/include/object_constants.h @@ -43,10 +43,8 @@ #define OBJ_FLAG_1000 (1 << 12) // 0x00001000 #define OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO (1 << 13) // 0x00002000 #define OBJ_FLAG_PERSISTENT_RESPAWN (1 << 14) // 0x00004000 -#define OBJ_FLAG_8000 (1 << 15) // 0x00008000 -#ifdef AUTO_COLLISION_DISTANCE +#define OBJ_FLAG_VELOCITY_PLATFORM (1 << 15) // 0x00008000 #define OBJ_FLAG_DONT_CALC_COLL_DIST (1 << 16) // 0x00010000 -#endif #define OBJ_FLAG_EMIT_LIGHT (1 << 17) // 0x00020000 #define OBJ_FLAG_HITBOX_WAS_SET (1 << 30) // 0x40000000 diff --git a/src/game/platform_displacement.c b/src/game/platform_displacement.c index 61859bf6..d2556960 100644 --- a/src/game/platform_displacement.c +++ b/src/game/platform_displacement.c @@ -97,15 +97,15 @@ extern s32 gGlobalTimer; * Upscale or downscale a vector by another vector. */ static void scale_vec3f(Vec3f dst, Vec3f src, Vec3f scale, u32 doInverted) { - if (doInverted) { - dst[0] = src[0] / scale[0]; - dst[1] = src[1] / scale[1]; - dst[2] = src[2] / scale[2]; - } else { - dst[0] = src[0] * scale[0]; - dst[1] = src[1] * scale[1]; - dst[2] = src[2] * scale[2]; - } + if (doInverted) { + dst[0] = src[0] / scale[0]; + dst[1] = src[1] / scale[1]; + dst[2] = src[2] / scale[2]; + } else { + dst[0] = src[0] * scale[0]; + dst[1] = src[1] * scale[1]; + dst[2] = src[2] * scale[2]; + } } /** @@ -113,74 +113,74 @@ static void scale_vec3f(Vec3f dst, Vec3f src, Vec3f scale, u32 doInverted) { * platform. */ void apply_platform_displacement(struct PlatformDisplacementInfo *displaceInfo, Vec3f pos, s16 *yaw, struct Object *platform) { - Vec3f platformPos; - Vec3f posDifference; - Vec3f yawVec; - Vec3f scaledPos; - // Determine how much Mario turned on his own since last frame - s16 yawDifference = *yaw - displaceInfo->prevYaw; + Vec3f platformPos; + Vec3f posDifference; + Vec3f yawVec; + Vec3f scaledPos; + // Determine how much Mario turned on his own since last frame + s16 yawDifference = *yaw - displaceInfo->prevYaw; - // Avoid a crash if the platform unloaded its collision while stood on - if (platform->header.gfx.throwMatrix == NULL) return; + // Avoid a crash if the platform unloaded its collision while stood on + if (platform->header.gfx.throwMatrix == NULL) return; - vec3f_copy(platformPos, (*platform->header.gfx.throwMatrix)[3]); + vec3f_copy(platformPos, (*platform->header.gfx.throwMatrix)[3]); - // Determine how far Mario moved on his own since last frame - vec3f_copy(posDifference, pos); - vec3f_sub(posDifference, displaceInfo->prevPos); + // Determine how far Mario moved on his own since last frame + vec3f_copy(posDifference, pos); + vec3f_sub(posDifference, displaceInfo->prevPos); - if ((platform == displaceInfo->prevPlatform) && (gGlobalTimer == displaceInfo->prevTimer + 1)) { - // Transform from relative positions to world positions - scale_vec3f(scaledPos, displaceInfo->prevTransformedPos, platform->header.gfx.scale, FALSE); - linear_mtxf_mul_vec3f(*platform->header.gfx.throwMatrix, pos, scaledPos); + if ((platform == displaceInfo->prevPlatform) && (gGlobalTimer == displaceInfo->prevTimer + 1)) { + // Transform from relative positions to world positions + scale_vec3f(scaledPos, displaceInfo->prevTransformedPos, platform->header.gfx.scale, FALSE); + linear_mtxf_mul_vec3f(*platform->header.gfx.throwMatrix, pos, scaledPos); - // Add on how much Mario moved in the previous frame - vec3f_add(pos, posDifference); + // Add on how much Mario moved in the previous frame + vec3f_add(pos, posDifference); - // Calculate new yaw - linear_mtxf_mul_vec3f(*platform->header.gfx.throwMatrix, yawVec, displaceInfo->prevTransformedYawVec); - *yaw = atan2s(yawVec[2], yawVec[0]) + yawDifference; - } else { - // First frame of standing on the platform, don't calculate a new position - vec3f_sub(pos, platformPos); - } + // Calculate new yaw + linear_mtxf_mul_vec3f(*platform->header.gfx.throwMatrix, yawVec, displaceInfo->prevTransformedYawVec); + *yaw = atan2s(yawVec[2], yawVec[0]) + yawDifference; + } else { + // First frame of standing on the platform, don't calculate a new position + vec3f_sub(pos, platformPos); + } - // Apply displacement specifically for TTC Treadmills - if (platform->behavior == segmented_to_virtual(bhvTTCTreadmill)) { + // Apply velocity-based displacement for certain objects (like the TTC Treadmills) + if (platform->oFlags & OBJ_FLAG_VELOCITY_PLATFORM) { pos[0] += platform->oVelX; pos[1] += platform->oVelY; pos[2] += platform->oVelZ; } - - // Transform from world positions to relative positions for use next frame - linear_mtxf_transpose_mul_vec3f(*platform->header.gfx.throwMatrix, scaledPos, pos); - scale_vec3f(displaceInfo->prevTransformedPos, scaledPos, platform->header.gfx.scale, TRUE); - vec3f_add(pos, platformPos); - // If the object is Mario, set inertia - if (pos == gMarioState->pos) { - vec3f_copy(sMarioAmountDisplaced, pos); - vec3f_sub(sMarioAmountDisplaced, displaceInfo->prevPos); - vec3f_sub(sMarioAmountDisplaced, posDifference); + // Transform from world positions to relative positions for use next frame + linear_mtxf_transpose_mul_vec3f(*platform->header.gfx.throwMatrix, scaledPos, pos); + scale_vec3f(displaceInfo->prevTransformedPos, scaledPos, platform->header.gfx.scale, TRUE); + vec3f_add(pos, platformPos); - // Make sure inertia isn't set on the first frame otherwise the previous value isn't cleared - if ((platform != displaceInfo->prevPlatform) || (gGlobalTimer != displaceInfo->prevTimer + 1)) { - vec3f_set(sMarioAmountDisplaced, 0.f, 0.f, 0.f); - } - } + // If the object is Mario, set inertia + if (pos == gMarioState->pos) { + vec3f_copy(sMarioAmountDisplaced, pos); + vec3f_sub(sMarioAmountDisplaced, displaceInfo->prevPos); + vec3f_sub(sMarioAmountDisplaced, posDifference); - // Update info for next frame - // Update position - vec3f_copy(displaceInfo->prevPos, pos); + // Make sure inertia isn't set on the first frame otherwise the previous value isn't cleared + if ((platform != displaceInfo->prevPlatform) || (gGlobalTimer != displaceInfo->prevTimer + 1)) { + vec3f_set(sMarioAmountDisplaced, 0.f, 0.f, 0.f); + } + } - // Set yaw info - vec3f_set(yawVec, sins(*yaw), 0, coss(*yaw)); - linear_mtxf_transpose_mul_vec3f(*platform->header.gfx.throwMatrix, displaceInfo->prevTransformedYawVec, yawVec); - displaceInfo->prevYaw = *yaw; + // Update info for next frame + // Update position + vec3f_copy(displaceInfo->prevPos, pos); - // Update platform and timer - displaceInfo->prevPlatform = platform; - displaceInfo->prevTimer = gGlobalTimer; + // Set yaw info + vec3f_set(yawVec, sins(*yaw), 0, coss(*yaw)); + linear_mtxf_transpose_mul_vec3f(*platform->header.gfx.throwMatrix, displaceInfo->prevTransformedYawVec, yawVec); + displaceInfo->prevYaw = *yaw; + + // Update platform and timer + displaceInfo->prevPlatform = platform; + displaceInfo->prevTimer = gGlobalTimer; } // Doesn't change in the code, set this to FALSE if you don't want inertia @@ -193,23 +193,23 @@ static u8 sInertiaFirstFrame = FALSE; * Apply inertia based on Mario's last platform. */ static void apply_mario_inertia(void) { - // On the first frame of leaving the ground, boost Mario's y velocity - if (sInertiaFirstFrame) { - gMarioState->vel[1] += sMarioAmountDisplaced[1]; - } + // On the first frame of leaving the ground, boost Mario's y velocity + if (sInertiaFirstFrame) { + gMarioState->vel[1] += sMarioAmountDisplaced[1]; + } - // Apply sideways inertia - gMarioState->pos[0] += sMarioAmountDisplaced[0]; - gMarioState->pos[2] += sMarioAmountDisplaced[2]; + // Apply sideways inertia + gMarioState->pos[0] += sMarioAmountDisplaced[0]; + gMarioState->pos[2] += sMarioAmountDisplaced[2]; - // Drag - sMarioAmountDisplaced[0] *= 0.97f; - sMarioAmountDisplaced[2] *= 0.97f; + // Drag + sMarioAmountDisplaced[0] *= 0.97f; + sMarioAmountDisplaced[2] *= 0.97f; - // Stop applying inertia once Mario has landed, or when ground pounding - if (!(gMarioState->action & ACT_FLAG_AIR) || (gMarioState->action == ACT_GROUND_POUND)) { - sShouldApplyInertia = FALSE; - } + // Stop applying inertia once Mario has landed, or when ground pounding + if (!(gMarioState->action & ACT_FLAG_AIR) || (gMarioState->action == ACT_GROUND_POUND)) { + sShouldApplyInertia = FALSE; + } } /** @@ -220,14 +220,14 @@ void apply_mario_platform_displacement(void) { platform = gMarioPlatform; if (!(gTimeStopState & TIME_STOP_ACTIVE) && gMarioObject != NULL) { - if (platform != NULL) { - apply_platform_displacement(&sMarioDisplacementInfo, gMarioState->pos, &gMarioState->faceAngle[1], platform); - sShouldApplyInertia = TRUE; - sInertiaFirstFrame = TRUE; - } else if (sShouldApplyInertia && gDoInertia) { - apply_mario_inertia(); - sInertiaFirstFrame = FALSE; - } + if (platform != NULL) { + apply_platform_displacement(&sMarioDisplacementInfo, gMarioState->pos, &gMarioState->faceAngle[1], platform); + sShouldApplyInertia = TRUE; + sInertiaFirstFrame = TRUE; + } else if (sShouldApplyInertia && gDoInertia) { + apply_mario_inertia(); + sInertiaFirstFrame = FALSE; + } } } #else @@ -271,9 +271,9 @@ void apply_platform_displacement(u32 isMario, struct Object *platform) { unused1 = rotation[0]; unused2 = rotation[2]; unused3 = platform->oFaceAngleYaw; - if (isMario) { - gMarioStates[0].faceAngle[1] += rotation[1]; - } + if (isMario) { + gMarioStates[0].faceAngle[1] += rotation[1]; + } platformPosX = platform->oPosX; platformPosY = platform->oPosY; platformPosZ = platform->oPosZ;