You've already forked Microtransactions64
mirror of
https://github.com/Print-and-Panic/Microtransactions64.git
synced 2026-01-21 10:17:19 -08:00
Puppycamera 2.2 + Auto World Render Scale
Puppycam 2.2 introduces splines, with intention to be used for cutscenes.
This commit is contained in:
@@ -21,10 +21,10 @@
|
||||
level boundaries are 4 times as big (-32768 to 32767)
|
||||
Collision calculations remain as fast as vanilla, at the cost of using far more RAM (16 times vanilla).
|
||||
64x64 collision cells.
|
||||
|
||||
|
||||
If you see "SURFACE POOL FULL" or "SURFACE NODE POOL FULL" in game, you should increase
|
||||
SURFACE_POOL_SIZE or SURFACE_NODE_POOL_SIZE, respectively, or reduce the amount of
|
||||
|
||||
If you see "SURFACE POOL FULL" or "SURFACE NODE POOL FULL" in game, you should increase
|
||||
SURFACE_POOL_SIZE or SURFACE_NODE_POOL_SIZE, respectively, or reduce the amount of
|
||||
collision surfaces in your level.
|
||||
*/
|
||||
|
||||
@@ -55,22 +55,18 @@
|
||||
#undef LEVEL_BOUNDARY_MAX // Undefine the old value to avoid compiler warnings
|
||||
#define LEVEL_BOUNDARY_MAX 0x2000L
|
||||
#define CELL_SIZE 0x400
|
||||
#define WORLD_SCALE 1.f
|
||||
#elif EXTENDED_BOUNDS_MODE == 1
|
||||
#undef LEVEL_BOUNDARY_MAX
|
||||
#define LEVEL_BOUNDARY_MAX 0x4000L
|
||||
#define CELL_SIZE 0x400
|
||||
#define WORLD_SCALE 2.f
|
||||
#elif EXTENDED_BOUNDS_MODE == 2
|
||||
#undef LEVEL_BOUNDARY_MAX
|
||||
#define LEVEL_BOUNDARY_MAX 0x2000L
|
||||
#define CELL_SIZE 0x200
|
||||
#define WORLD_SCALE 1.f
|
||||
#elif EXTENDED_BOUNDS_MODE == 3
|
||||
#undef LEVEL_BOUNDARY_MAX
|
||||
#define LEVEL_BOUNDARY_MAX 0x8000L
|
||||
#define CELL_SIZE 0x400
|
||||
#define WORLD_SCALE 4.f
|
||||
#endif
|
||||
|
||||
STATIC_ASSERT(LEVEL_BOUNDARY_MAX != 0, "You must set a valid extended bounds mode!");
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "trig_tables.inc.c"
|
||||
#include "surface_load.h"
|
||||
#include "game/puppyprint.h"
|
||||
#include "game/rendering_graph_node.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
@@ -583,7 +584,7 @@ void mtxf_to_mtx(Mtx *dest, Mat4 src) {
|
||||
|
||||
for( i = 0; i < 4; i++ ) {
|
||||
for( j = 0; j < 3; j++ ) {
|
||||
temp[i][j] = src[i][j] / WORLD_SCALE;
|
||||
temp[i][j] = src[i][j] / gWorldScale;
|
||||
}
|
||||
temp[i][3] = src[i][3];
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ s16 gMatStackIndex;
|
||||
Mat4 gMatStack[32];
|
||||
Mtx *gMatStackFixed[32];
|
||||
f32 aspect;
|
||||
f32 gWorldScale = 1.0f;
|
||||
|
||||
/**
|
||||
* Animation nodes have state in global variables, so this struct captures
|
||||
@@ -259,7 +260,12 @@ static void geo_process_perspective(struct GraphNodePerspective *node) {
|
||||
aspect = 1.33333f;
|
||||
#endif
|
||||
|
||||
guPerspective(mtx, &perspNorm, node->fov, aspect, node->near / WORLD_SCALE, node->far / WORLD_SCALE, 1.0f);
|
||||
if (gCamera)
|
||||
gWorldScale = MAX(((gCamera->pos[0] * gCamera->pos[0]) + (gCamera->pos[1] * gCamera->pos[1]) + (gCamera->pos[2] * gCamera->pos[2]))/67108864, 1.0f);
|
||||
else
|
||||
gWorldScale = 1.0f;
|
||||
|
||||
guPerspective(mtx, &perspNorm, node->fov, aspect, node->near / gWorldScale, node->far / gWorldScale, 1.0f);
|
||||
gSPPerspNormalize(gDisplayListHead++, perspNorm);
|
||||
|
||||
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(mtx), G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH);
|
||||
|
||||
@@ -12,6 +12,7 @@ extern struct GraphNodeCamera *gCurGraphNodeCamera;
|
||||
extern struct GraphNodeObject *gCurGraphNodeObject;
|
||||
extern struct GraphNodeHeldObject *gCurGraphNodeHeldObject;
|
||||
extern u16 gAreaUpdateCounter;
|
||||
extern f32 gWorldScale;
|
||||
|
||||
// after processing an object, the type is reset to this
|
||||
#define ANIM_TYPE_NONE 0
|
||||
|
||||
Reference in New Issue
Block a user