Puppycamera 2.2

This commit is contained in:
Fazana
2021-08-26 19:47:48 +01:00
parent 8bc9863abe
commit 8705dcf77a
2 changed files with 129 additions and 6 deletions

View File

@@ -1,4 +1,4 @@
///Puppycam 2.1 by Fazana
///Puppycam 2.2 by Fazana
#include <PR/ultratypes.h>
#include <PR/gbi.h>
@@ -198,7 +198,82 @@ void puppycam_activate_cutscene(s32 *scene, s32 lockinput)
gPuppyCam.sceneInput = lockinput;
}
static void newcam_process_cutscene(void)
//If you've read camera.c this will look familiar.
//It takes the next 4 spline points and extrapolates a curvature based positioning of the camera vector that's passed through.
//It's a standard B spline
static void puppycam_evaluate_spline(f32 progress, Vec3s cameraPos, Vec3f spline1, Vec3f spline2, Vec3f spline3, Vec3f spline4)
{
f32 tempP[4];
if (progress > 1.0f) {
progress = 1.0f;
}
tempP[0] = (1.0f - progress) * (1.0f - progress) * (1.0f - progress) / 6.0f;
tempP[1] = progress * progress * progress / 2.0f - progress * progress + 0.6666667f;
tempP[2] = -progress * progress * progress / 2.0f + progress * progress / 2.0f + progress / 2.0f + 0.16666667f;
tempP[3] = progress * progress * progress / 6.0f;
cameraPos[0] = tempP[0] * spline1[0] + tempP[1] * spline2[0] + tempP[2] * spline3[0] + tempP[3] * spline4[0];
cameraPos[1] = tempP[0] * spline1[1] + tempP[1] * spline2[1] + tempP[2] * spline3[1] + tempP[3] * spline4[1];
cameraPos[2] = tempP[0] * spline1[2] + tempP[1] * spline2[2] + tempP[2] * spline3[2] + tempP[3] * spline4[2];
}
s32 puppycam_move_spline(struct sPuppySpline splinePos[], struct sPuppySpline splineFocus[], s32 mode, s32 index)
{
Vec3f tempPoints[4];
f32 tempProgress[2] = {0.0f, 0.0f};
f32 progChange = 0.0f;
s32 i;
Vec3f prevPos;
if (gPuppyCam.splineIndex == 65000)
gPuppyCam.splineIndex = index;
if (splinePos[gPuppyCam.splineIndex].index == -1 || splinePos[gPuppyCam.splineIndex + 1].index == -1 || splinePos[gPuppyCam.splineIndex + 2].index == -1)
return 1;
if (mode == PUPPYSPLINE_FOLLOW)
if (splineFocus[gPuppyCam.splineIndex].index == -1 || splineFocus[gPuppyCam.splineIndex + 1].index == -1 || splineFocus[gPuppyCam.splineIndex + 2].index == -1)
return 1;
vec3f_set(prevPos, gPuppyCam.pos[0], gPuppyCam.pos[1], gPuppyCam.pos[2]);
for (i = 0; i < 4; i++)
vec3f_set(tempPoints[i], splinePos[gPuppyCam.splineIndex + i].pos[0], splinePos[gPuppyCam.splineIndex + i].pos[1], splinePos[gPuppyCam.splineIndex + i].pos[2]);
puppycam_evaluate_spline(gPuppyCam.splineProgress, gPuppyCam.pos, tempPoints[0], tempPoints[1], tempPoints[2], tempPoints[3]);
if (mode == PUPPYSPLINE_FOLLOW)
{
for (i = 0; i < 4; i++)
vec3f_set(tempPoints[i], splineFocus[gPuppyCam.splineIndex + i].pos[0], splineFocus[gPuppyCam.splineIndex + i].pos[1], splineFocus[gPuppyCam.splineIndex + i].pos[2]);
puppycam_evaluate_spline(gPuppyCam.splineProgress, gPuppyCam.focus, tempPoints[0], tempPoints[1], tempPoints[2], tempPoints[3]);
}
if (splinePos[gPuppyCam.splineIndex+1].speed != 0) {
tempProgress[0] = 1.0f / splinePos[gPuppyCam.splineIndex+1].speed;
}
if (splinePos[gPuppyCam.splineIndex+2].speed != 0) {
tempProgress[1] = 1.0f / splinePos[gPuppyCam.splineIndex+2].speed;
}
progChange = (tempProgress[1] - tempProgress[0]) * gPuppyCam.splineProgress + tempProgress[0];
gPuppyCam.splineProgress += progChange;
if (gPuppyCam.splineProgress >= 1.0f)
{
gPuppyCam.splineIndex++;
if (splinePos[gPuppyCam.splineIndex+3].index == -1)
{
gPuppyCam.splineIndex = 0;
gPuppyCam.splineProgress = 0;
return 1;
}
gPuppyCam.splineProgress -=1;
}
return 0;
}
static void puppycam_process_cutscene(void)
{
if (gPuppyCam.cutscene)
{
@@ -446,6 +521,8 @@ void puppycam_reset_values(void)
gPuppyCam.floorY[0] = 0;
gPuppyCam.floorY[1] = 0;
gPuppyCam.terrainPitch = 0;
gPuppyCam.splineIndex = 0;
gPuppyCam.splineProgress = 0;
}
//Set up values. Runs on level load.
@@ -615,7 +692,7 @@ static void puppycam_input_hold_preset2(f32 ivX)
}
//Another alternative control scheme. This one aims to mimic the parallel camera scheme down to the last bit from the original game.
static void puppycam_input_hold_preset3(f32 ivX)
static void puppycam_input_hold_preset3(void)
{
f32 stickMag[2] = {gPlayer1Controller->rawStickX*0.65f, gPlayer1Controller->rawStickY*0.2f};
//Just in case it happens to be nonzero.
@@ -741,7 +818,7 @@ static void puppycam_input_hold(void)
{
default: puppycam_input_hold_preset1(ivX); puppycam_input_pitch(); puppycam_input_zoom(); puppycam_input_centre(); break;
case 1: puppycam_input_hold_preset2(ivX); puppycam_input_pitch(); puppycam_input_zoom(); puppycam_input_centre(); break;
case 2: puppycam_input_hold_preset3(ivX); puppycam_input_centre(); break;
case 2: puppycam_input_hold_preset3(); puppycam_input_centre(); break;
}
}
else
@@ -972,6 +1049,35 @@ static s32 puppycam_check_volume_bounds(struct sPuppyVolume *volume, s32 index)
return FALSE;
}
//Handles wall adjustment when wall kicking.
void puppycam_wall_angle(void)
{
struct Surface *wall;
struct WallCollisionData cData;
s16 wallYaw;
if (!(gMarioState->action & ACT_WALL_KICK_AIR) || ((gMarioState->action & ACT_FLAG_AIR) && ABS(gMarioState->forwardVel) < 16.0f) || !(gMarioState->action & ACT_FLAG_AIR))
return;
cData.x = gPuppyCam.targetObj->oPosX;
cData.y = gPuppyCam.targetObj->oPosY;
cData.z = gPuppyCam.targetObj->oPosZ;
cData.radius = 150.0f;
cData.offsetY = 0;
if (find_wall_collisions(&cData))
wall = cData.walls[cData.numWalls - 1];
else
return;
wallYaw = atan2s(wall->normal.z, wall->normal.x) + 0x4000;
wallYaw -= gPuppyCam.yawTarget;
if (wallYaw % 0x4000)
wallYaw += 0x4000 - wallYaw % 0x4000;
gPuppyCam.yawTarget = approach_s32(gPuppyCam.yawTarget, wallYaw, 0x200, 0x200);
}
void puppycam_projection_behaviours(void)
{
f32 turnRate = 1;
@@ -1081,6 +1187,9 @@ void puppycam_projection_behaviours(void)
//This sets a pseudo tilt offset based on the floor heights in front and behind mario.
puppycam_terrain_angle();
//This will shift the intended yaw when wall kicking, to align with the wall being kicked.
puppycam_wall_angle();
}
else
{
@@ -1386,7 +1495,7 @@ void puppycam_loop(void)
if (gPuppyCam.cutscene)
{
gPuppyCam.opacity = 255;
newcam_process_cutscene();
puppycam_process_cutscene();
}
puppycam_apply();

View File

@@ -25,6 +25,9 @@
#define PUPPYCAM_MODE3_ZOOMED_OUT 0x4
#define PUPPYCAM_MODE3_ENTER_FIRST_PERSON 0x8
#define PUPPYSPLINE_NONE 1 //Will not write to focus at all.
#define PUPPYSPLINE_FOLLOW 2 //Focus will follow a separate spline, but will mirror the speed and progress of the pos.
#include "include/command_macros_base.h"
#define PUPPYVOLUME(x, y, z, length, height, width, yaw, functionptr, anglesptr, addflags, removeflags, flagpersistance, room, shape) \
@@ -94,6 +97,8 @@ struct gPuppyStruct
s32 sceneTimer; //The cutscene timer that goes up during a cutscene.
Vec3s scenePos; //Where the camera is during a cutscene
Vec3s sceneFocus; //Where the camera looks during a cutscene
u16 splineIndex; //Determines which point of the spline it's at.
f32 splineProgress; //Determines how far along the index the spline is.
struct gPuppyOptions options;
@@ -109,6 +114,14 @@ struct sPuppyAngles
s16 zoom;
};
//Structurally, it's exactly the same as CutsceneSplinePoint
struct sPuppySpline
{
s8 index; //The index of the spline. Ends with -1
u8 speed; //The amount of frames it takes to get through this index.
Vec3s pos; //The vector pos of the spline index itself.
};
//A bounding volume for activating puppycamera scripts and angles.
struct sPuppyVolume
{
@@ -172,7 +185,8 @@ extern void puppycam_set_save(void);
extern void puppycam_check_pause_buttons(void);
extern void puppycam_activate_cutscene(s32 *scene, s32 lockinput);
extern void puppycam_render_option_text();
void puppycam_warp(f32 displacementX, f32 displacementY, f32 displacementZ);
extern void puppycam_warp(f32 displacementX, f32 displacementY, f32 displacementZ);
extern s32 puppycam_move_spline(struct sPuppySpline splinePos[], struct sPuppySpline splineFocus[], s32 mode, s32 index);
#endif