diff --git a/README.md b/README.md index 4c65396c..a3d96a9f 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ This is a fork of the ultrasm64 repo by CrashOveride which includes the followin - Non-stop stars * - better extended boundaries by anonymous_moose - water surface type patch by thecozies -- platform displacement 2 by arthur. +- platform displacement 2 by arthur * - FPS counter (use the function `print_fps(x,y)` anywhere that runs code every frame) - Automatic console/emulator detection. If emulator is detected, LODs are disabled. * - Rounded corners by Frame, merged by Cheezepin @@ -26,7 +26,7 @@ This is a fork of the ultrasm64 repo by CrashOveride which includes the followin - Increased maximum pole lenght (The game will read bparam1 and bparam2 together as a single value, so you can have a very long pole) * - bparam4 fix (the game no longer uses bparam4 to check if an object is mario and therefore you can safely use it) - Instant warp offset fix (makes the instant warp offset work even when warping to a different area) * -- Global star IDs (disabled by default, toggleable in config.h). This allows you to create an open world (MVC-style) hack. +- Global star IDs (disabled by default, toggleable in config.h). This allows you to create an open world (MVC-style) hack. * - Included `actors/group0.c` in `behavior_data.c` - 16 bit model IDs by someone2639. This means you can have up to 65536 models (lol) - s2dex engine by someone2639! To use it, compile with `make TEXT_ENGINE=s2dex_text_engine` or just set `TEXT_ENGINE` to `s2dex_text_engine` in the makefile. diff --git a/include/config.h b/include/config.h index ef835efa..da37b4df 100644 --- a/include/config.h +++ b/include/config.h @@ -75,6 +75,8 @@ //#define NO_FALL_DAMAGE_SOUND // Number of coins to spawn the "100 coin" star. If you remove the define altogether, then there won't be a 100 coin star at all. #define X_COIN_STAR 100 +// Platform displacement 2 also known as momentum patch. Makes Mario keep the momemtum from moving platforms. Breaks treadmills. +#define PLATFORM_DISPLACEMENT_2 // Stars don't kick you out of the level // #define NON_STOP_STARS // Uncomment this if you want global star IDs (useful for creating an open world hack ala MVC) diff --git a/src/game/behaviors/bowser.inc.c b/src/game/behaviors/bowser.inc.c index 410e612f..965ce660 100644 --- a/src/game/behaviors/bowser.inc.c +++ b/src/game/behaviors/bowser.inc.c @@ -1,3 +1,5 @@ +#include "config.h" + // bowser.c.inc void bowser_tail_anchor_act_0(void) { @@ -972,8 +974,9 @@ s32 bowser_check_fallen_off_stage(void) // bowser off stage? return 0; } +#ifdef PLATFORM_DISPLACEMENT_2 struct PlatformDisplacementInfo sBowserDisplacementInfo; - +#endif void (*sBowserActions[])(void) = { bowser_act_default, bowser_act_thrown_dropped, bowser_act_jump_onto_stage, bowser_act_dance, bowser_act_dead, bowser_act_text_wait, bowser_act_intro_walk, bowser_act_charge_mario, bowser_act_spit_fire_into_sky, bowser_act_spit_fire_onto_floor, bowser_act_hit_edge, bowser_act_turn_from_edge, @@ -1034,9 +1037,14 @@ void bowser_free_update(void) { struct Surface *floor; struct Object *platform; UNUSED f32 floorHeight; +#ifdef PLATFORM_DISPLACEMENT_2 if ((platform = o->platform) != NULL) { apply_platform_displacement(&sBowserDisplacementInfo, &o->oPosX, &o->oFaceAngleYaw, platform); } +#else + if ((platform = o->platform) != NULL) + apply_platform_displacement(FALSE, platform); +#endif o->oBowserUnk10E = 0; cur_obj_update_floor_and_walls(); cur_obj_call_action_function(sBowserActions); diff --git a/src/game/behaviors/tilting_inverted_pyramid.inc.c b/src/game/behaviors/tilting_inverted_pyramid.inc.c index 29136e97..32bdf4a1 100644 --- a/src/game/behaviors/tilting_inverted_pyramid.inc.c +++ b/src/game/behaviors/tilting_inverted_pyramid.inc.c @@ -1,3 +1,5 @@ +#include "config.h" + /** * This is the behavior file for the tilting inverted pyramids in BitFS/LLL. * The object essentially just tilts and moves Mario with it. @@ -131,7 +133,10 @@ void bhv_tilting_inverted_pyramid_loop(void) { mx += posAfterRotation[0] - posBeforeRotation[0]; my += posAfterRotation[1] - posBeforeRotation[1]; mz += posAfterRotation[2] - posBeforeRotation[2]; - //set_mario_pos(mx, my, mz); + + #ifndef PLATFORM_DISPLACEMENT_2 + set_mario_pos(mx, my, mz); + #endif } o->header.gfx.throwMatrix = transform; diff --git a/src/game/platform_displacement.c b/src/game/platform_displacement.c index 1e8cd865..e42f4829 100644 --- a/src/game/platform_displacement.c +++ b/src/game/platform_displacement.c @@ -10,6 +10,8 @@ #include "types.h" #include "sm64.h" +#include "config.h" + u16 D_8032FEC0 = 0; u32 unused_8032FEC4[4] = { 0 }; @@ -84,7 +86,7 @@ void set_mario_pos(f32 x, f32 y, f32 z) { gMarioStates[0].pos[1] = y; gMarioStates[0].pos[2] = z; } - +#ifdef PLATFORM_DISPLACEMENT_2 static struct PlatformDisplacementInfo sMarioDisplacementInfo; static Vec3f sMarioAmountDisplaced; @@ -220,7 +222,96 @@ void apply_mario_platform_displacement(void) { } } } +#else +/** + * Apply one frame of platform rotation to Mario or an object using the given + * platform. If isMario is false, use gCurrentObject. + */ +void apply_platform_displacement(u32 isMario, struct Object *platform) { + f32 x; + f32 y; + f32 z; + f32 platformPosX; + f32 platformPosY; + f32 platformPosZ; + Vec3f currentObjectOffset; + Vec3f relativeOffset; + Vec3f newObjectOffset; + Vec3s rotation; + UNUSED s16 unused1; + UNUSED s16 unused2; + UNUSED s16 unused3; + f32 displaceMatrix[4][4]; + rotation[0] = platform->oAngleVelPitch; + rotation[1] = platform->oAngleVelYaw; + rotation[2] = platform->oAngleVelRoll; + + if (isMario) { + D_8032FEC0 = 0; + get_mario_pos(&x, &y, &z); + } else { + x = gCurrentObject->oPosX; + y = gCurrentObject->oPosY; + z = gCurrentObject->oPosZ; + } + + x += platform->oVelX; + z += platform->oVelZ; + + if (rotation[0] != 0 || rotation[1] != 0 || rotation[2] != 0) { + unused1 = rotation[0]; + unused2 = rotation[2]; + unused3 = platform->oFaceAngleYaw; + if (isMario) { + gMarioStates[0].faceAngle[1] += rotation[1]; + } + platformPosX = platform->oPosX; + platformPosY = platform->oPosY; + platformPosZ = platform->oPosZ; + + currentObjectOffset[0] = x - platformPosX; + currentObjectOffset[1] = y - platformPosY; + currentObjectOffset[2] = z - platformPosZ; + + rotation[0] = platform->oFaceAnglePitch - platform->oAngleVelPitch; + rotation[1] = platform->oFaceAngleYaw - platform->oAngleVelYaw; + rotation[2] = platform->oFaceAngleRoll - platform->oAngleVelRoll; + + mtxf_rotate_zxy_and_translate(displaceMatrix, currentObjectOffset, rotation); + linear_mtxf_transpose_mul_vec3f(displaceMatrix, relativeOffset, currentObjectOffset); + + rotation[0] = platform->oFaceAnglePitch; + rotation[1] = platform->oFaceAngleYaw; + rotation[2] = platform->oFaceAngleRoll; + + mtxf_rotate_zxy_and_translate(displaceMatrix, currentObjectOffset, rotation); + linear_mtxf_mul_vec3f(displaceMatrix, newObjectOffset, relativeOffset); + x = platformPosX + newObjectOffset[0]; + y = platformPosY + newObjectOffset[1]; + z = platformPosZ + newObjectOffset[2]; + } + if (isMario) { + set_mario_pos(x, y, z); + } else { + gCurrentObject->oPosX = x; + gCurrentObject->oPosY = y; + gCurrentObject->oPosZ = z; + } +} + + +/** +* If Mario's platform is not null, apply platform displacement. +*/ +void apply_mario_platform_displacement(void) { + struct Object *platform = gMarioPlatform; + + if (!(gTimeStopState & TIME_STOP_ACTIVE) && gMarioObject != NULL && platform != NULL) { + apply_platform_displacement(TRUE, platform); + } +} +#endif #ifndef VERSION_JP diff --git a/src/game/platform_displacement.h b/src/game/platform_displacement.h index 3609e2d4..6b41c978 100644 --- a/src/game/platform_displacement.h +++ b/src/game/platform_displacement.h @@ -5,19 +5,25 @@ #include "types.h" -struct PlatformDisplacementInfo { - Vec3f prevPos; - Vec3f prevTransformedPos; - Vec3f prevTransformedYawVec; - s16 prevYaw; - struct Object *prevPlatform; - s32 prevTimer; -}; - +#include "config.h" +#ifdef PLATFORM_DISPLACEMENT_2 + struct PlatformDisplacementInfo { + Vec3f prevPos; + Vec3f prevTransformedPos; + Vec3f prevTransformedYawVec; + s16 prevYaw; + struct Object *prevPlatform; + s32 prevTimer; + }; +#endif void update_mario_platform(void); void get_mario_pos(f32 *x, f32 *y, f32 *z); void set_mario_pos(f32 x, f32 y, f32 z); -void apply_platform_displacement(struct PlatformDisplacementInfo *displaceInfo, Vec3f pos, s16 *yaw, struct Object *platform); +#ifdef PLATFORM_DISPLACEMENT_2 + void apply_platform_displacement(struct PlatformDisplacementInfo *displaceInfo, Vec3f pos, s16 *yaw, struct Object *platform); +#else + void apply_platform_displacement(u32 isMario, struct Object *platform); +#endif void apply_mario_platform_displacement(void); #ifndef VERSION_JP void clear_mario_platform(void);