Massive refactor
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
#include <math.h>
|
||||
|
||||
#include "../engine/math_util.h"
|
||||
#include "../engine/surface_collision.h"
|
||||
#include "level_update.h"
|
||||
#include "../include/object_fields.h"
|
||||
#include "object_stuff.h"
|
||||
#include "platform_displacement.h"
|
||||
#include "../shim.h"
|
||||
|
||||
struct SurfaceObjectTransform *gMarioPlatform = NULL;
|
||||
|
||||
#define absfx( x ) ( (x) < 0.0f ? -(x) : (x) )
|
||||
|
||||
/**
|
||||
* Determine if Mario is standing on a platform object, meaning that he is
|
||||
* within 4 units of the floor. Set his referenced platform object accordingly.
|
||||
*/
|
||||
void update_mario_platform(void) {
|
||||
struct Surface *floor;
|
||||
UNUSED u32 unused;
|
||||
f32 marioX;
|
||||
f32 marioY;
|
||||
f32 marioZ;
|
||||
f32 floorHeight;
|
||||
u32 awayFromFloor;
|
||||
|
||||
if (gMarioObject == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
//! If Mario moves onto a rotating platform in a PU, the find_floor call
|
||||
// will detect the platform and he will end up receiving a large amount
|
||||
// of displacement since he is considered to be far from the platform's
|
||||
// axis of rotation.
|
||||
|
||||
marioX = gMarioObject->oPosX;
|
||||
marioY = gMarioObject->oPosY;
|
||||
marioZ = gMarioObject->oPosZ;
|
||||
floorHeight = find_floor(marioX, marioY, marioZ, &floor);
|
||||
|
||||
if (absfx(marioY - floorHeight) < 4.0f) {
|
||||
awayFromFloor = 0;
|
||||
} else {
|
||||
awayFromFloor = 1;
|
||||
}
|
||||
|
||||
switch (awayFromFloor) {
|
||||
case 1:
|
||||
gMarioPlatform = NULL;
|
||||
gMarioObject->platform = NULL;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
if (floor != NULL && floor->object != NULL) {
|
||||
gMarioPlatform = (struct SurfaceObjectTransform *)floor->object;
|
||||
gMarioObject->platform = floor->object;
|
||||
} else {
|
||||
gMarioPlatform = NULL;
|
||||
gMarioObject->platform = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Mario's position and store it in x, y, and z.
|
||||
*/
|
||||
static void get_mario_pos(f32 *x, f32 *y, f32 *z) {
|
||||
*x = gMarioState->pos[0];
|
||||
*y = gMarioState->pos[1];
|
||||
*z = gMarioState->pos[2];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Mario's position.
|
||||
*/
|
||||
static void set_mario_pos(f32 x, f32 y, f32 z) {
|
||||
gMarioState->pos[0] = x;
|
||||
gMarioState->pos[1] = y;
|
||||
gMarioState->pos[2] = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 SurfaceObjectTransform *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->aAngleVelPitch;
|
||||
rotation[1] = platform->aAngleVelYaw;
|
||||
rotation[2] = platform->aAngleVelRoll;
|
||||
|
||||
// if (isMario) {
|
||||
// D_8032FEC0 = 0;
|
||||
get_mario_pos(&x, &y, &z);
|
||||
// } else {
|
||||
// x = gCurrentObject->aPosX;
|
||||
// y = gCurrentObject->aPosY;
|
||||
// z = gCurrentObject->aPosZ;
|
||||
// }
|
||||
|
||||
x += platform->aVelX;
|
||||
z += platform->aVelZ;
|
||||
|
||||
if (rotation[0] != 0 || rotation[1] != 0 || rotation[2] != 0) {
|
||||
unused1 = rotation[0];
|
||||
unused2 = rotation[2];
|
||||
unused3 = platform->aFaceAngleYaw;
|
||||
|
||||
if (isMario) {
|
||||
gMarioState->faceAngle[1] += rotation[1];
|
||||
}
|
||||
|
||||
platformPosX = platform->aPosX;
|
||||
platformPosY = platform->aPosY;
|
||||
platformPosZ = platform->aPosZ;
|
||||
|
||||
currentObjectOffset[0] = x - platformPosX;
|
||||
currentObjectOffset[1] = y - platformPosY;
|
||||
currentObjectOffset[2] = z - platformPosZ;
|
||||
|
||||
rotation[0] = platform->aFaceAnglePitch - platform->aAngleVelPitch;
|
||||
rotation[1] = platform->aFaceAngleYaw - platform->aAngleVelYaw;
|
||||
rotation[2] = platform->aFaceAngleRoll - platform->aAngleVelRoll;
|
||||
|
||||
mtxf_rotate_zxy_and_translate(displaceMatrix, currentObjectOffset, rotation);
|
||||
linear_mtxf_transpose_mul_vec3f(displaceMatrix, relativeOffset, currentObjectOffset);
|
||||
|
||||
rotation[0] = platform->aFaceAnglePitch;
|
||||
rotation[1] = platform->aFaceAngleYaw;
|
||||
rotation[2] = platform->aFaceAngleRoll;
|
||||
|
||||
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 SurfaceObjectTransform *platform = gMarioPlatform;
|
||||
|
||||
if (gMarioObject != NULL && platform != NULL) {
|
||||
apply_platform_displacement(TRUE, platform);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Mario's platform to NULL.
|
||||
*/
|
||||
void clear_mario_platform(void) {
|
||||
gMarioPlatform = NULL;
|
||||
}
|
||||
Reference in New Issue
Block a user