mirror of
https://github.com/s4Ys369/CHEATERex.git
synced 2025-01-23 08:02:09 -05:00
Better Better Camera by djoslin0
Pull Request #431 of sm64ex https://github.com/sm64pc/sm64ex/pull/431
This commit is contained in:
parent
3305b10ce8
commit
59357c578f
4 changed files with 463 additions and 332 deletions
|
@ -8,7 +8,6 @@
|
|||
#include "surface_collision.h"
|
||||
#include "surface_load.h"
|
||||
#include "math_util.h"
|
||||
#include "game/game_init.h"
|
||||
|
||||
/**************************************************
|
||||
* WALLS *
|
||||
|
@ -59,8 +58,12 @@ static s32 find_wall_collisions_from_list(struct SurfaceNode *surfaceNode,
|
|||
// the fact they are floating point, certain floating point positions
|
||||
// along the seam of two walls may collide with neither wall or both walls.
|
||||
if (surf->flags & SURFACE_FLAG_X_PROJECTION) {
|
||||
w1 = -surf->vertex1[2]; w2 = -surf->vertex2[2]; w3 = -surf->vertex3[2];
|
||||
y1 = surf->vertex1[1]; y2 = surf->vertex2[1]; y3 = surf->vertex3[1];
|
||||
w1 = -surf->vertex1[2];
|
||||
w2 = -surf->vertex2[2];
|
||||
w3 = -surf->vertex3[2];
|
||||
y1 = surf->vertex1[1];
|
||||
y2 = surf->vertex2[1];
|
||||
y3 = surf->vertex3[1];
|
||||
|
||||
if (surf->normal.x > 0.0f) {
|
||||
if ((y1 - y) * (w2 - w1) - (w1 - -pz) * (y2 - y1) > 0.0f) {
|
||||
|
@ -84,8 +87,12 @@ static s32 find_wall_collisions_from_list(struct SurfaceNode *surfaceNode,
|
|||
}
|
||||
}
|
||||
} else {
|
||||
w1 = surf->vertex1[0]; w2 = surf->vertex2[0]; w3 = surf->vertex3[0];
|
||||
y1 = surf->vertex1[1]; y2 = surf->vertex2[1]; y3 = surf->vertex3[1];
|
||||
w1 = surf->vertex1[0];
|
||||
w2 = surf->vertex2[0];
|
||||
w3 = surf->vertex3[0];
|
||||
y1 = surf->vertex1[1];
|
||||
y2 = surf->vertex2[1];
|
||||
y3 = surf->vertex3[1];
|
||||
|
||||
if (surf->normal.z > 0.0f) {
|
||||
if ((y1 - y) * (w2 - w1) - (w1 - px) * (y2 - y1) > 0.0f) {
|
||||
|
@ -225,7 +232,8 @@ s32 find_wall_collisions(struct WallCollisionData *colData) {
|
|||
/**
|
||||
* Iterate through the list of ceilings and find the first ceiling over a given point.
|
||||
*/
|
||||
static struct Surface *find_ceil_from_list(struct SurfaceNode *surfaceNode, s32 x, s32 y, s32 z, f32 *pheight) {
|
||||
static struct Surface *find_ceil_from_list(struct SurfaceNode *surfaceNode, s32 x, s32 y, s32 z,
|
||||
f32 *pheight) {
|
||||
register struct Surface *surf;
|
||||
register s32 x1, z1, x2, z2, x3, z3;
|
||||
struct Surface *ceil = NULL;
|
||||
|
@ -395,44 +403,27 @@ f32 find_floor_height_and_data(f32 xPos, f32 yPos, f32 zPos, struct FloorGeometr
|
|||
return floorHeight;
|
||||
}
|
||||
|
||||
u8 gInterpolatingSurfaces;
|
||||
|
||||
/**
|
||||
* Iterate through the list of floors and find the first floor under a given point.
|
||||
*/
|
||||
static struct Surface *find_floor_from_list(struct SurfaceNode *surfaceNode, s32 x, s32 y, s32 z, f32 *pheight) {
|
||||
static struct Surface *find_floor_from_list(struct SurfaceNode *surfaceNode, s32 x, s32 y, s32 z,
|
||||
f32 *pheight) {
|
||||
register struct Surface *surf;
|
||||
register f32 x1, z1, x2, z2, x3, z3;
|
||||
register s32 x1, z1, x2, z2, x3, z3;
|
||||
f32 nx, ny, nz;
|
||||
f32 oo;
|
||||
f32 height;
|
||||
struct Surface *floor = NULL;
|
||||
s32 interpolate;
|
||||
|
||||
// Iterate through the list of floors until there are no more floors.
|
||||
while (surfaceNode != NULL) {
|
||||
surf = surfaceNode->surface;
|
||||
surfaceNode = surfaceNode->next;
|
||||
interpolate = gInterpolatingSurfaces && surf->modifiedTimestamp == gGlobalTimer;
|
||||
|
||||
x1 = surf->vertex1[0];
|
||||
z1 = surf->vertex1[2];
|
||||
x2 = surf->vertex2[0];
|
||||
z2 = surf->vertex2[2];
|
||||
if (interpolate) {
|
||||
f32 diff = (surf->prevVertex1[0] - x1) * (surf->prevVertex1[0] - x1);
|
||||
diff += (surf->prevVertex1[1] - surf->vertex1[1]) * (surf->prevVertex1[1] - surf->vertex1[1]);
|
||||
diff += (surf->prevVertex1[2] - z1) * (surf->prevVertex1[2] - z1);
|
||||
//printf("%f\n", sqrtf(diff));
|
||||
if (diff > 10000) {
|
||||
interpolate = FALSE;
|
||||
} else {
|
||||
x1 = (surf->prevVertex1[0] + x1) / 2;
|
||||
z1 = (surf->prevVertex1[2] + z1) / 2;
|
||||
x2 = (surf->prevVertex2[0] + x2) / 2;
|
||||
z2 = (surf->prevVertex2[2] + z2) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the point is within the triangle bounds.
|
||||
if ((z1 - z) * (x2 - x1) - (x1 - x) * (z2 - z1) < 0) {
|
||||
|
@ -442,10 +433,6 @@ static struct Surface *find_floor_from_list(struct SurfaceNode *surfaceNode, s32
|
|||
// To slightly save on computation time, set this later.
|
||||
x3 = surf->vertex3[0];
|
||||
z3 = surf->vertex3[2];
|
||||
if (interpolate) {
|
||||
x3 = (surf->prevVertex3[0] + x3) / 2;
|
||||
z3 = (surf->prevVertex3[2] + z3) / 2;
|
||||
}
|
||||
|
||||
if ((z2 - z) * (x3 - x2) - (x2 - x) * (z3 - z2) < 0) {
|
||||
continue;
|
||||
|
@ -465,30 +452,10 @@ static struct Surface *find_floor_from_list(struct SurfaceNode *surfaceNode, s32
|
|||
continue;
|
||||
}
|
||||
|
||||
if (interpolate) {
|
||||
f32 y1, y2, y3;
|
||||
f32 mag;
|
||||
y1 = (surf->prevVertex1[1] + surf->vertex1[1]) / 2;
|
||||
y2 = (surf->prevVertex2[1] + surf->vertex2[1]) / 2;
|
||||
y3 = (surf->prevVertex3[1] + surf->vertex3[1]) / 2;
|
||||
nx = (y2 - y1) * (z3 - z2) - (z2 - z1) * (y3 - y2);
|
||||
ny = (z2 - z1) * (x3 - x2) - (x2 - x1) * (z3 - z2);
|
||||
nz = (x2 - x1) * (y3 - y2) - (y2 - y1) * (x3 - x2);
|
||||
mag = sqrtf(nx * nx + ny * ny + nz * nz);
|
||||
if (mag < 0.0001) {
|
||||
continue;
|
||||
}
|
||||
mag = (f32)(1.0 / mag);
|
||||
nx *= mag;
|
||||
ny *= mag;
|
||||
nz *= mag;
|
||||
oo = -(nx * x1 + ny * y1 + nz * z1);
|
||||
} else {
|
||||
nx = surf->normal.x;
|
||||
ny = surf->normal.y;
|
||||
nz = surf->normal.z;
|
||||
oo = surf->originOffset;
|
||||
}
|
||||
nx = surf->normal.x;
|
||||
ny = surf->normal.y;
|
||||
nz = surf->normal.z;
|
||||
oo = surf->originOffset;
|
||||
|
||||
// If a wall, ignore it. Likely a remnant, should never occur.
|
||||
if (ny == 0.0f) {
|
||||
|
@ -503,15 +470,6 @@ static struct Surface *find_floor_from_list(struct SurfaceNode *surfaceNode, s32
|
|||
}
|
||||
|
||||
*pheight = height;
|
||||
if (interpolate) {
|
||||
static struct Surface s;
|
||||
s.type = surf->type;
|
||||
s.normal.x = nx;
|
||||
s.normal.y = ny;
|
||||
s.normal.z = nz;
|
||||
s.originOffset = oo;
|
||||
return &s;
|
||||
}
|
||||
floor = surf;
|
||||
break;
|
||||
}
|
||||
|
@ -832,45 +790,45 @@ s32 unused_resolve_floor_or_ceil_collisions(s32 checkCeil, f32 *px, f32 *py, f32
|
|||
/**
|
||||
* Raycast functions
|
||||
*/
|
||||
s32 ray_surface_intersect(Vec3f orig, Vec3f dir, f32 dir_length, struct Surface *surface, Vec3f hit_pos, f32 *length)
|
||||
{
|
||||
s32 ray_surface_intersect(Vec3f orig, Vec3f dir, f32 dir_length, struct Surface *surface, Vec3f hit_pos,
|
||||
f32 *length) {
|
||||
Vec3f v0, v1, v2, e1, e2, h, s, q;
|
||||
f32 a, f, u, v;
|
||||
Vec3f add_dir;
|
||||
|
||||
|
||||
// Get surface normal and some other stuff
|
||||
vec3s_to_vec3f(v0, surface->vertex1);
|
||||
vec3s_to_vec3f(v1, surface->vertex2);
|
||||
vec3s_to_vec3f(v2, surface->vertex3);
|
||||
|
||||
|
||||
vec3f_dif(e1, v1, v0);
|
||||
vec3f_dif(e2, v2, v0);
|
||||
|
||||
|
||||
vec3f_cross(h, dir, e2);
|
||||
|
||||
|
||||
// Check if we're perpendicular from the surface
|
||||
a = vec3f_dot(e1, h);
|
||||
if (a > -0.00001f && a < 0.00001f)
|
||||
return FALSE;
|
||||
|
||||
|
||||
// Check if we're making contact with the surface
|
||||
f = 1.0f / a;
|
||||
|
||||
|
||||
vec3f_dif(s, orig, v0);
|
||||
u = f * vec3f_dot(s, h);
|
||||
if (u < 0.0f || u > 1.0f)
|
||||
return FALSE;
|
||||
|
||||
|
||||
vec3f_cross(q, s, e1);
|
||||
v = f * vec3f_dot(dir, q);
|
||||
if (v < 0.0f || u + v > 1.0f)
|
||||
return FALSE;
|
||||
|
||||
|
||||
// Get the length between our origin and the surface contact point
|
||||
*length = f * vec3f_dot(e2, q);
|
||||
if (*length <= 0.00001 || *length > dir_length)
|
||||
return FALSE;
|
||||
|
||||
|
||||
// Successful contact
|
||||
vec3f_copy(add_dir, dir);
|
||||
vec3f_mul(add_dir, *length);
|
||||
|
@ -878,37 +836,37 @@ s32 ray_surface_intersect(Vec3f orig, Vec3f dir, f32 dir_length, struct Surface
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
void find_surface_on_ray_list(struct SurfaceNode *list, Vec3f orig, Vec3f dir, f32 dir_length, struct Surface **hit_surface, Vec3f hit_pos, f32 *max_length)
|
||||
{
|
||||
void find_surface_on_ray_list(struct SurfaceNode *list, Vec3f orig, Vec3f dir, f32 dir_length,
|
||||
struct Surface **hit_surface, Vec3f hit_pos, f32 *max_length) {
|
||||
s32 hit;
|
||||
f32 length;
|
||||
Vec3f chk_hit_pos;
|
||||
f32 top, bottom;
|
||||
|
||||
|
||||
// Get upper and lower bounds of ray
|
||||
if (dir[1] >= 0.0f)
|
||||
{
|
||||
if (dir[1] >= 0.0f) {
|
||||
top = orig[1] + dir[1] * dir_length;
|
||||
bottom = orig[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
top = orig[1];
|
||||
bottom = orig[1] + dir[1] * dir_length;
|
||||
}
|
||||
|
||||
|
||||
// Iterate through every surface of the list
|
||||
for (; list != NULL; list = list->next)
|
||||
{
|
||||
for (; list != NULL; list = list->next) {
|
||||
// Reject surface if out of vertical bounds
|
||||
if (list->surface->lowerY > top || list->surface->upperY < bottom)
|
||||
continue;
|
||||
|
||||
|
||||
// Reject no-cam collision surfaces
|
||||
if (gCheckingSurfaceCollisionsForCamera
|
||||
&& (list->surface->flags & SURFACE_FLAG_NO_CAM_COLLISION))
|
||||
continue;
|
||||
|
||||
// Check intersection between the ray and this surface
|
||||
if ((hit = ray_surface_intersect(orig, dir, dir_length, list->surface, chk_hit_pos, &length)) != 0)
|
||||
{
|
||||
if (length <= *max_length)
|
||||
{
|
||||
if ((hit = ray_surface_intersect(orig, dir, dir_length, list->surface, chk_hit_pos, &length))
|
||||
!= 0) {
|
||||
if (length <= *max_length) {
|
||||
*hit_surface = list->surface;
|
||||
vec3f_copy(hit_pos, chk_hit_pos);
|
||||
*max_length = length;
|
||||
|
@ -917,30 +875,35 @@ void find_surface_on_ray_list(struct SurfaceNode *list, Vec3f orig, Vec3f dir, f
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void find_surface_on_ray_cell(s16 cellX, s16 cellZ, Vec3f orig, Vec3f normalized_dir, f32 dir_length, struct Surface **hit_surface, Vec3f hit_pos, f32 *max_length)
|
||||
{
|
||||
// Skip if OOB
|
||||
if (cellX >= 0 && cellX <= 0xF && cellZ >= 0 && cellZ <= 0xF)
|
||||
{
|
||||
// Iterate through each surface in this partition
|
||||
if (normalized_dir[1] > -0.99f)
|
||||
{
|
||||
find_surface_on_ray_list(gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
|
||||
find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
|
||||
}
|
||||
if (normalized_dir[1] < 0.99f)
|
||||
{
|
||||
find_surface_on_ray_list(gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
|
||||
find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
|
||||
}
|
||||
find_surface_on_ray_list(gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
|
||||
find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
|
||||
}
|
||||
void find_surface_on_ray_cell(s16 cellX, s16 cellZ, Vec3f orig, Vec3f normalized_dir, f32 dir_length,
|
||||
struct Surface **hit_surface, Vec3f hit_pos, f32 *max_length) {
|
||||
// Skip if OOB
|
||||
if (cellX >= 0 && cellX <= 0xF && cellZ >= 0 && cellZ <= 0xF) {
|
||||
// Iterate through each surface in this partition
|
||||
if (normalized_dir[1] > -0.99f) {
|
||||
find_surface_on_ray_list(
|
||||
gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS].next, orig,
|
||||
normalized_dir, dir_length, hit_surface, hit_pos, max_length);
|
||||
find_surface_on_ray_list(
|
||||
gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS].next, orig,
|
||||
normalized_dir, dir_length, hit_surface, hit_pos, max_length);
|
||||
}
|
||||
if (normalized_dir[1] < 0.99f) {
|
||||
find_surface_on_ray_list(
|
||||
gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next, orig,
|
||||
normalized_dir, dir_length, hit_surface, hit_pos, max_length);
|
||||
find_surface_on_ray_list(
|
||||
gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next, orig,
|
||||
normalized_dir, dir_length, hit_surface, hit_pos, max_length);
|
||||
}
|
||||
find_surface_on_ray_list(gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS].next,
|
||||
orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
|
||||
find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS].next,
|
||||
orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
|
||||
}
|
||||
}
|
||||
|
||||
void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Vec3f hit_pos)
|
||||
{
|
||||
void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Vec3f hit_pos) {
|
||||
f32 max_length;
|
||||
s16 cellZ, cellX;
|
||||
f32 fCellZ, fCellX;
|
||||
|
@ -948,47 +911,50 @@ void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Ve
|
|||
Vec3f normalized_dir;
|
||||
f32 step, dx, dz;
|
||||
u32 i;
|
||||
|
||||
|
||||
// Set that no surface has been hit
|
||||
*hit_surface = NULL;
|
||||
vec3f_sum(hit_pos, orig, dir);
|
||||
|
||||
|
||||
// Get normalized direction
|
||||
dir_length = vec3f_length(dir);
|
||||
max_length = dir_length;
|
||||
vec3f_copy(normalized_dir, dir);
|
||||
vec3f_normalize(normalized_dir);
|
||||
|
||||
|
||||
// Get our cell coordinate
|
||||
fCellX = (orig[0] + LEVEL_BOUNDARY_MAX) / CELL_SIZE;
|
||||
fCellZ = (orig[2] + LEVEL_BOUNDARY_MAX) / CELL_SIZE;
|
||||
cellX = (s16)fCellX;
|
||||
cellZ = (s16)fCellZ;
|
||||
|
||||
cellX = (s16) fCellX;
|
||||
cellZ = (s16) fCellZ;
|
||||
|
||||
// Don't do DDA if straight down
|
||||
if (normalized_dir[1] >= 1.0f || normalized_dir[1] <= -1.0f)
|
||||
{
|
||||
find_surface_on_ray_cell(cellX, cellZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length);
|
||||
return;
|
||||
}
|
||||
|
||||
if (normalized_dir[1] >= 1.0f || normalized_dir[1] <= -1.0f) {
|
||||
find_surface_on_ray_cell(cellX, cellZ, orig, normalized_dir, dir_length, hit_surface, hit_pos,
|
||||
&max_length);
|
||||
return;
|
||||
}
|
||||
|
||||
// increase collision checking precision (normally 1)
|
||||
f32 precision = 3;
|
||||
|
||||
// Get cells we cross using DDA
|
||||
if (absx(dir[0]) >= absx(dir[2]))
|
||||
step = absx(dir[0]) / CELL_SIZE;
|
||||
step = precision * absx(dir[0]) / CELL_SIZE;
|
||||
else
|
||||
step = absx(dir[2]) / CELL_SIZE;
|
||||
|
||||
step = precision * absx(dir[2]) / CELL_SIZE;
|
||||
|
||||
dx = dir[0] / step / CELL_SIZE;
|
||||
dz = dir[2] / step / CELL_SIZE;
|
||||
|
||||
for (i = 0; i < step && *hit_surface == NULL; i++)
|
||||
{
|
||||
find_surface_on_ray_cell(cellX, cellZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length);
|
||||
|
||||
|
||||
for (i = 0; i < step && *hit_surface == NULL; i++) {
|
||||
find_surface_on_ray_cell(cellX, cellZ, orig, normalized_dir, dir_length, hit_surface, hit_pos,
|
||||
&max_length);
|
||||
|
||||
// Move cell coordinate
|
||||
fCellX += dx;
|
||||
fCellZ += dz;
|
||||
cellX = (s16)fCellX;
|
||||
cellZ = (s16)fCellZ;
|
||||
cellX = (s16) fCellX;
|
||||
cellZ = (s16) fCellZ;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,31 +10,36 @@
|
|||
#include "engine/surface_collision.h"
|
||||
#include "pc/configfile.h"
|
||||
#include "pc/controller/controller_mouse.h"
|
||||
#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
|
||||
//quick and dirty fix for some older MinGW.org mingwrt
|
||||
|
||||
#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
|
||||
// quick and dirty fix for some older MinGW.org mingwrt
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#define NEW_CAM_BOUNDING_BOX_RAYS 4
|
||||
#define NEW_CAM_BOUNDING_BOX_HRADIUS 250
|
||||
#define NEW_CAM_BOUNDING_BOX_VRADIUS 100
|
||||
|
||||
/**
|
||||
Quick explanation of the camera modes
|
||||
|
||||
NC_MODE_NORMAL: Standard mode, allows dualaxial movement and free control of the camera.
|
||||
NC_MODE_FIXED: Disables control of camera, and the actual position of the camera doesn't update.
|
||||
NC_MODE_2D: Disables horizontal control of the camera and locks Mario's direction to the X axis. NYI though.
|
||||
NC_MODE_8D: 8 directional movement. Similar to standard, except the camera direction snaps to 8 directions.
|
||||
NC_MODE_FIXED_NOMOVE: Disables control and movement of the camera.
|
||||
NC_MODE_NOTURN: Disables horizontal and vertical control of the camera.
|
||||
NC_MODE_2D: Disables horizontal control of the camera and locks Mario's direction to the X axis. NYI
|
||||
though. NC_MODE_8D: 8 directional movement. Similar to standard, except the camera direction snaps to 8
|
||||
directions. NC_MODE_FIXED_NOMOVE: Disables control and movement of the camera. NC_MODE_NOTURN: Disables
|
||||
horizontal and vertical control of the camera.
|
||||
**/
|
||||
|
||||
//!A bunch of developer intended options, to cover every base, really.
|
||||
//#define NEWCAM_DEBUG //Some print values for puppycam. Not useful anymore, but never hurts to keep em around.
|
||||
//#define nosound //If for some reason you hate the concept of audio, you can disable it.
|
||||
//! A bunch of developer intended options, to cover every base, really.
|
||||
//#define NEWCAM_DEBUG //Some print values for puppycam. Not useful anymore, but never hurts to keep em
|
||||
//around. #define nosound //If for some reason you hate the concept of audio, you can disable it.
|
||||
//#define noaccel //Disables smooth movement of the camera with the C buttons.
|
||||
|
||||
//!Hardcoded camera angle stuff. They're essentially area boxes that when Mario is inside, will trigger some view changes.
|
||||
///Don't touch this btw, unless you know what you're doing, this has to be above for religious reasons.
|
||||
//! Hardcoded camera angle stuff. They're essentially area boxes that when Mario is inside, will trigger
|
||||
//! some view changes.
|
||||
/// Don't touch this btw, unless you know what you're doing, this has to be above for religious reasons.
|
||||
struct newcam_hardpos {
|
||||
u8 newcam_hard_levelID;
|
||||
u8 newcam_hard_areaID;
|
||||
|
@ -54,84 +59,133 @@ struct newcam_hardpos {
|
|||
s16 newcam_hard_lookZ;
|
||||
};
|
||||
|
||||
///This is the bit that defines where the angles happen. They're basically environment boxes that dictate camera behaviour.
|
||||
//Permaswap is a boolean that simply determines wether or not when the camera changes at this point it stays changed. 0 means it resets when you leave, and 1 means it stays changed.
|
||||
//The camera position fields accept "32767" as an ignore flag.
|
||||
/// This is the bit that defines where the angles happen. They're basically environment boxes that
|
||||
/// dictate camera behaviour.
|
||||
// Permaswap is a boolean that simply determines wether or not when the camera changes at this point it
|
||||
// stays changed. 0 means it resets when you leave, and 1 means it stays changed. The camera position
|
||||
// fields accept "32767" as an ignore flag.
|
||||
struct newcam_hardpos newcam_fixedcam[] = {
|
||||
{
|
||||
/*Level ID*/ 16,/*Area ID*/ 1,/*Permaswap*/ 0,/*Mode*/ NC_MODE_FIXED_NOMOVE, //Standard params.
|
||||
/*X begin*/ -540,/*Y begin*/ 800,/*Z begin*/ -3500, //Where the activation box begins
|
||||
/*X end*/ 540,/*Y end*/ 2000,/*Z end*/ -1500, //Where the activation box ends.
|
||||
/*Cam X*/ 0,/*Cam Y*/ 1500,/*Cam Z*/ -1000, //The position the camera gets placed for NC_MODE_FIXED and NC_MODE_FIXED_NOMOVE
|
||||
/*Look X*/ 0,/*Look Y*/ 800,/*Look Z*/ -2500 //The position the camera looks at for NC_MODE_FIXED_NOMOVE
|
||||
/*Level ID*/ 16, /*Area ID*/ 1, /*Permaswap*/ 0,
|
||||
/*Mode*/ NC_MODE_FIXED_NOMOVE, // Standard params.
|
||||
/*X begin*/ -540, /*Y begin*/ 800, /*Z begin*/ -3500, // Where the activation box begins
|
||||
/*X end*/ 540, /*Y end*/ 2000, /*Z end*/ -1500, // Where the activation box ends.
|
||||
/*Cam X*/ 0, /*Cam Y*/ 1500, /*Cam Z*/ -1000, // The position the camera gets placed for
|
||||
// NC_MODE_FIXED and NC_MODE_FIXED_NOMOVE
|
||||
/*Look X*/ 0, /*Look Y*/ 800,
|
||||
/*Look Z*/ -2500 // The position the camera looks at for NC_MODE_FIXED_NOMOVE
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
#ifdef noaccel
|
||||
u8 accel = 255;
|
||||
#else
|
||||
u8 accel = 10;
|
||||
u8 accel = 255;
|
||||
#else
|
||||
u8 accel = 10;
|
||||
#endif // noaccel
|
||||
|
||||
s16 newcam_yaw; //Z axis rotation
|
||||
s16 newcam_yaw; // Z axis rotation
|
||||
f32 newcam_yaw_acc;
|
||||
s16 newcam_tilt = 1500; //Y axis rotation
|
||||
s16 newcam_tilt = 1500; // Y axis rotation
|
||||
f32 newcam_tilt_acc;
|
||||
u16 newcam_distance = 750; //The distance the camera stays from the player
|
||||
u16 newcam_distance_target = 750; //The distance the player camera tries to reach.
|
||||
f32 newcam_pos_target[3]; //The position the camera is basing calculations off. *usually* Mario.
|
||||
f32 newcam_pos[3]; //Position the camera is in the world
|
||||
f32 newcam_lookat[3]; //Position the camera is looking at
|
||||
u16 newcam_distance = 750; // The distance the camera stays from the player
|
||||
u16 newcam_distance_target = 750; // The distance the player camera tries to reach.
|
||||
f32 newcam_pos_target[3]; // The position the camera is basing calculations off. *usually* Mario.
|
||||
f32 newcam_pos[3]; // Position the camera is in the world
|
||||
f32 newcam_lookat[3]; // Position the camera is looking at
|
||||
f32 newcam_framessincec[2];
|
||||
f32 newcam_extheight = 125;
|
||||
u8 newcam_centering = 0; // The flag that depicts wether the camera's goin gto try centering.
|
||||
s16 newcam_yaw_target; // The yaw value the camera tries to set itself to when the centre flag is active. Is set to Mario's face angle.
|
||||
f32 newcam_turnwait; // The amount of time to wait after landing before allowing the camera to turn again
|
||||
s16 newcam_yaw_target; // The yaw value the camera tries to set itself to when the centre flag is
|
||||
// active. Is set to Mario's face angle.
|
||||
f32 newcam_turnwait; // The amount of time to wait after landing before allowing the camera to turn
|
||||
// again
|
||||
f32 newcam_pan_x;
|
||||
f32 newcam_pan_z;
|
||||
u8 newcam_cstick_down = 0; //Just a value that triggers true when the player 2 stick is moved in 8 direction move to prevent holding it down.
|
||||
u8 newcam_cstick_down = 0; // Just a value that triggers true when the player 2 stick is moved in 8
|
||||
// direction move to prevent holding it down.
|
||||
u8 newcam_target;
|
||||
s32 newcam_sintimer = 0;
|
||||
s16 newcam_coldist;
|
||||
u8 newcam_xlu = 255;
|
||||
s8 newcam_stick2[2];
|
||||
|
||||
s16 newcam_sensitivityX; //How quick the camera works.
|
||||
s16 newcam_sensitivityX; // How quick the camera works.
|
||||
s16 newcam_sensitivityY;
|
||||
s16 newcam_invertX; //Reverses movement of the camera axis.
|
||||
s16 newcam_invertX; // Reverses movement of the camera axis.
|
||||
s16 newcam_invertY;
|
||||
s16 newcam_panlevel; //How much the camera sticks out a bit in the direction you're looking.
|
||||
s16 newcam_aggression ; //How much the camera tries to centre itself to Mario's facing and movement.
|
||||
s16 newcam_panlevel; // How much the camera sticks out a bit in the direction you're looking.
|
||||
s16 newcam_aggression; // How much the camera tries to centre itself to Mario's facing and movement.
|
||||
s16 newcam_degrade = 1;
|
||||
s16 newcam_analogue = 0; //Wether to accept inputs from a player 2 joystick, and then disables C button input.
|
||||
s16 newcam_distance_values[] = {750,1250,2000};
|
||||
s16 newcam_analogue =
|
||||
0; // Wether to accept inputs from a player 2 joystick, and then disables C button input.
|
||||
s16 newcam_distance_values[] = { 750, 1250, 2000 };
|
||||
u8 newcam_active = 0; // basically the thing that governs if newcam is on.
|
||||
u8 newcam_mouse = 0;
|
||||
u16 newcam_mode;
|
||||
u16 newcam_intendedmode = 0; // which camera mode the camera's going to try to be in when not forced into another.
|
||||
u16 newcam_intendedmode =
|
||||
0; // which camera mode the camera's going to try to be in when not forced into another.
|
||||
u16 newcam_modeflags;
|
||||
|
||||
s16 newcam_saved_mode = -1;
|
||||
s16 newcam_saved_defmode = -1;
|
||||
|
||||
///This is called at every level initialisation.
|
||||
/// This is called at every level initialisation.
|
||||
void newcam_init(struct Camera *c, u8 dv) {
|
||||
newcam_tilt = 1500;
|
||||
newcam_distance_target = newcam_distance_values[dv];
|
||||
newcam_yaw = -c->yaw+0x4000; //Mario and the camera's yaw have this offset between them.
|
||||
newcam_yaw = -c->yaw + 0x4000; // Mario and the camera's yaw have this offset between them.
|
||||
newcam_mode = NC_MODE_NORMAL;
|
||||
///This here will dictate what modes the camera will start in at the beginning of a level. Below are some examples.
|
||||
/// This here will dictate what modes the camera will start in at the beginning of a level. Below
|
||||
/// are some examples.
|
||||
switch (gCurrLevelNum) {
|
||||
case LEVEL_BITDW: newcam_yaw = 0x4000; newcam_mode = NC_MODE_8D; newcam_tilt = 4000; newcam_distance_target = newcam_distance_values[2]; break;
|
||||
case LEVEL_BITFS: newcam_yaw = 0x4000; newcam_mode = NC_MODE_8D; newcam_tilt = 4000; newcam_distance_target = newcam_distance_values[2]; break;
|
||||
case LEVEL_BITS: newcam_yaw = 0x4000; newcam_mode = NC_MODE_8D; newcam_tilt = 4000; newcam_distance_target = newcam_distance_values[2]; break;
|
||||
case LEVEL_WF: newcam_yaw = 0x4000; newcam_tilt = 2000; newcam_distance_target = newcam_distance_values[1]; break;
|
||||
case LEVEL_RR: newcam_yaw = 0x6000; newcam_tilt = 2000; newcam_distance_target = newcam_distance_values[2]; break;
|
||||
case LEVEL_CCM: if (gCurrAreaIndex == 1) {newcam_yaw = -0x4000; newcam_tilt = 2000; newcam_distance_target = newcam_distance_values[1];} else newcam_mode = NC_MODE_SLIDE; break;
|
||||
case LEVEL_WDW: newcam_yaw = 0x2000; newcam_tilt = 3000; newcam_distance_target = newcam_distance_values[1]; break;
|
||||
case 27: newcam_mode = NC_MODE_SLIDE; break;
|
||||
case LEVEL_TTM: if (gCurrAreaIndex == 2) newcam_mode = NC_MODE_SLIDE; break;
|
||||
case LEVEL_BITDW:
|
||||
newcam_yaw = 0x4000;
|
||||
newcam_mode = NC_MODE_8D;
|
||||
newcam_tilt = 4000;
|
||||
newcam_distance_target = newcam_distance_values[2];
|
||||
break;
|
||||
case LEVEL_BITFS:
|
||||
newcam_yaw = 0x4000;
|
||||
newcam_mode = NC_MODE_8D;
|
||||
newcam_tilt = 4000;
|
||||
newcam_distance_target = newcam_distance_values[2];
|
||||
break;
|
||||
case LEVEL_BITS:
|
||||
newcam_yaw = 0x4000;
|
||||
newcam_mode = NC_MODE_8D;
|
||||
newcam_tilt = 4000;
|
||||
newcam_distance_target = newcam_distance_values[2];
|
||||
break;
|
||||
case LEVEL_WF:
|
||||
newcam_yaw = 0x4000;
|
||||
newcam_tilt = 2000;
|
||||
newcam_distance_target = newcam_distance_values[1];
|
||||
break;
|
||||
case LEVEL_RR:
|
||||
newcam_yaw = 0x6000;
|
||||
newcam_tilt = 2000;
|
||||
newcam_distance_target = newcam_distance_values[2];
|
||||
break;
|
||||
case LEVEL_CCM:
|
||||
if (gCurrAreaIndex == 1) {
|
||||
newcam_yaw = -0x4000;
|
||||
newcam_tilt = 2000;
|
||||
newcam_distance_target = newcam_distance_values[1];
|
||||
} else
|
||||
newcam_mode = NC_MODE_SLIDE;
|
||||
break;
|
||||
case LEVEL_WDW:
|
||||
newcam_yaw = 0x2000;
|
||||
newcam_tilt = 3000;
|
||||
newcam_distance_target = newcam_distance_values[1];
|
||||
break;
|
||||
case 27:
|
||||
newcam_mode = NC_MODE_SLIDE;
|
||||
break;
|
||||
case LEVEL_TTM:
|
||||
if (gCurrAreaIndex == 2)
|
||||
newcam_mode = NC_MODE_SLIDE;
|
||||
break;
|
||||
}
|
||||
|
||||
// clear these out when entering a new level to prevent "camera mode buffering"
|
||||
|
@ -177,17 +231,18 @@ void newcam_toggle(bool enabled) {
|
|||
}
|
||||
}
|
||||
|
||||
///These are the default settings for Puppycam. You may change them to change how they'll be set for first timers.
|
||||
/// These are the default settings for Puppycam. You may change them to change how they'll be set for
|
||||
/// first timers.
|
||||
void newcam_init_settings(void) {
|
||||
newcam_sensitivityX = newcam_clamp(configCameraXSens, 1, 100) * 5;
|
||||
newcam_sensitivityY = newcam_clamp(configCameraYSens, 1, 100) * 5;
|
||||
newcam_aggression = newcam_clamp(configCameraAggr, 0, 100);
|
||||
newcam_panlevel = newcam_clamp(configCameraPan, 0, 100);
|
||||
newcam_invertX = (s16)configCameraInvertX;
|
||||
newcam_invertY = (s16)configCameraInvertY;
|
||||
newcam_mouse = (u8)configCameraMouse;
|
||||
newcam_analogue = (s16)configCameraAnalog;
|
||||
newcam_degrade = (f32)configCameraDegrade;
|
||||
newcam_aggression = newcam_clamp(configCameraAggr, 0, 100);
|
||||
newcam_panlevel = newcam_clamp(configCameraPan, 0, 100);
|
||||
newcam_invertX = (s16) configCameraInvertX;
|
||||
newcam_invertY = (s16) configCameraInvertY;
|
||||
newcam_mouse = (u8) configCameraMouse;
|
||||
newcam_analogue = (s16) configCameraAnalog;
|
||||
newcam_degrade = (f32) configCameraDegrade;
|
||||
|
||||
newcam_toggle(configEnableCamera);
|
||||
}
|
||||
|
@ -195,25 +250,25 @@ void newcam_init_settings(void) {
|
|||
/** Mathematic calculations. This stuffs so basic even *I* understand it lol
|
||||
Basically, it just returns a position based on angle */
|
||||
static s16 lengthdir_x(f32 length, s16 dir) {
|
||||
return (s16) (length * coss(dir));
|
||||
return (s16)(length * coss(dir));
|
||||
}
|
||||
static s16 lengthdir_y(f32 length, s16 dir) {
|
||||
return (s16) (length * sins(dir));
|
||||
return (s16)(length * sins(dir));
|
||||
}
|
||||
|
||||
void newcam_diagnostics(void) {
|
||||
print_text_fmt_int(32,192,"Lv %d",gCurrLevelNum);
|
||||
print_text_fmt_int(32,176,"Area %d",gCurrAreaIndex);
|
||||
print_text_fmt_int(32,160,"X %d",gMarioState->pos[0]);
|
||||
print_text_fmt_int(32,144,"Y %d",gMarioState->pos[1]);
|
||||
print_text_fmt_int(32,128,"Z %d",gMarioState->pos[2]);
|
||||
print_text_fmt_int(32,112,"FLAGS %d",newcam_modeflags);
|
||||
print_text_fmt_int(180,112,"INTM %d",newcam_intendedmode);
|
||||
print_text_fmt_int(32,96,"TILT UP %d",newcam_tilt_acc);
|
||||
print_text_fmt_int(32,80,"YAW UP %d",newcam_yaw_acc);
|
||||
print_text_fmt_int(32,64,"YAW %d",newcam_yaw);
|
||||
print_text_fmt_int(32,48,"TILT %d",newcam_tilt);
|
||||
print_text_fmt_int(32,32,"DISTANCE %d",newcam_distance);
|
||||
print_text_fmt_int(32, 192, "Lv %d", gCurrLevelNum);
|
||||
print_text_fmt_int(32, 176, "Area %d", gCurrAreaIndex);
|
||||
print_text_fmt_int(32, 160, "X %d", gMarioState->pos[0]);
|
||||
print_text_fmt_int(32, 144, "Y %d", gMarioState->pos[1]);
|
||||
print_text_fmt_int(32, 128, "Z %d", gMarioState->pos[2]);
|
||||
print_text_fmt_int(32, 112, "FLAGS %d", newcam_modeflags);
|
||||
print_text_fmt_int(180, 112, "INTM %d", newcam_intendedmode);
|
||||
print_text_fmt_int(32, 96, "TILT UP %d", newcam_tilt_acc);
|
||||
print_text_fmt_int(32, 80, "YAW UP %d", newcam_yaw_acc);
|
||||
print_text_fmt_int(32, 64, "YAW %d", newcam_yaw);
|
||||
print_text_fmt_int(32, 48, "TILT %d", newcam_tilt);
|
||||
print_text_fmt_int(32, 32, "DISTANCE %d", newcam_distance);
|
||||
}
|
||||
|
||||
static s16 newcam_adjust_value(f32 var, f32 val, f32 max) {
|
||||
|
@ -262,116 +317,124 @@ static void newcam_rotate_button(void) {
|
|||
f32 intendedXMag;
|
||||
f32 intendedYMag;
|
||||
|
||||
if ((newcam_modeflags & NC_FLAG_8D || newcam_modeflags & NC_FLAG_4D) && newcam_modeflags & NC_FLAG_XTURN) {
|
||||
//8 directional camera rotation input for buttons.
|
||||
if ((newcam_modeflags & NC_FLAG_8D || newcam_modeflags & NC_FLAG_4D)
|
||||
&& newcam_modeflags & NC_FLAG_XTURN) {
|
||||
// 8 directional camera rotation input for buttons.
|
||||
if ((gPlayer1Controller->buttonPressed & L_CBUTTONS) && newcam_analogue == 0) {
|
||||
#ifndef nosound
|
||||
#ifndef nosound
|
||||
play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs);
|
||||
#endif
|
||||
#endif
|
||||
if (newcam_modeflags & NC_FLAG_8D)
|
||||
newcam_yaw_target = newcam_yaw_target+(ivrt(0)*0x2000);
|
||||
newcam_yaw_target = newcam_yaw_target + (ivrt(0) * 0x2000);
|
||||
else
|
||||
newcam_yaw_target = newcam_yaw_target+(ivrt(0)*0x4000);
|
||||
newcam_yaw_target = newcam_yaw_target + (ivrt(0) * 0x4000);
|
||||
newcam_centering = 1;
|
||||
} else if ((gPlayer1Controller->buttonPressed & R_CBUTTONS) && newcam_analogue == 0) {
|
||||
#ifndef nosound
|
||||
#ifndef nosound
|
||||
play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs);
|
||||
#endif
|
||||
#endif
|
||||
if (newcam_modeflags & NC_FLAG_8D)
|
||||
newcam_yaw_target = newcam_yaw_target-(ivrt(0)*0x2000);
|
||||
newcam_yaw_target = newcam_yaw_target - (ivrt(0) * 0x2000);
|
||||
else
|
||||
newcam_yaw_target = newcam_yaw_target-(ivrt(0)*0x4000);
|
||||
newcam_yaw_target = newcam_yaw_target - (ivrt(0) * 0x4000);
|
||||
newcam_centering = 1;
|
||||
}
|
||||
} else if (newcam_modeflags & NC_FLAG_XTURN) {
|
||||
//Standard camera movement
|
||||
} else if (newcam_modeflags & NC_FLAG_XTURN) {
|
||||
// Standard camera movement
|
||||
if ((gPlayer1Controller->buttonDown & L_CBUTTONS) && newcam_analogue == 0) {
|
||||
newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc, -accel, -100);
|
||||
} else if ((gPlayer1Controller->buttonDown & R_CBUTTONS) && newcam_analogue == 0) {
|
||||
newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc, accel, 100);
|
||||
} else if (!newcam_analogue) {
|
||||
#ifdef noaccel
|
||||
#ifdef noaccel
|
||||
newcam_yaw_acc = 0;
|
||||
#else
|
||||
newcam_yaw_acc -= (newcam_yaw_acc*((f32)newcam_degrade/100));
|
||||
#endif
|
||||
#else
|
||||
newcam_yaw_acc -= (newcam_yaw_acc * ((f32) newcam_degrade / 100));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (gPlayer1Controller->buttonDown & U_CBUTTONS && newcam_modeflags & NC_FLAG_YTURN && newcam_analogue == 0) {
|
||||
if (gPlayer1Controller->buttonDown & U_CBUTTONS && newcam_modeflags & NC_FLAG_YTURN
|
||||
&& newcam_analogue == 0) {
|
||||
newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc, accel, 100);
|
||||
} else if (gPlayer1Controller->buttonDown & D_CBUTTONS && newcam_modeflags & NC_FLAG_YTURN && newcam_analogue == 0) {
|
||||
} else if (gPlayer1Controller->buttonDown & D_CBUTTONS && newcam_modeflags & NC_FLAG_YTURN
|
||||
&& newcam_analogue == 0) {
|
||||
newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc, -accel, -100);
|
||||
} else if (!newcam_analogue) {
|
||||
#ifdef noaccel
|
||||
#ifdef noaccel
|
||||
newcam_tilt_acc = 0;
|
||||
#else
|
||||
newcam_tilt_acc -= (newcam_tilt_acc*((f32)newcam_degrade/100));
|
||||
#endif
|
||||
#else
|
||||
newcam_tilt_acc -= (newcam_tilt_acc * ((f32) newcam_degrade / 100));
|
||||
#endif
|
||||
}
|
||||
|
||||
newcam_framessincec[0] ++;
|
||||
newcam_framessincec[1] ++;
|
||||
if ((gPlayer1Controller->buttonPressed & L_CBUTTONS) && newcam_modeflags & NC_FLAG_XTURN && !(newcam_modeflags & NC_FLAG_8D) && newcam_analogue == 0) {
|
||||
newcam_framessincec[0]++;
|
||||
newcam_framessincec[1]++;
|
||||
if ((gPlayer1Controller->buttonPressed & L_CBUTTONS) && newcam_modeflags & NC_FLAG_XTURN
|
||||
&& !(newcam_modeflags & NC_FLAG_8D) && newcam_analogue == 0) {
|
||||
if (newcam_framessincec[0] < 6) {
|
||||
newcam_yaw_target = newcam_yaw+(ivrt(0)*0x3000);
|
||||
newcam_yaw_target = newcam_yaw + (ivrt(0) * 0x3000);
|
||||
newcam_centering = 1;
|
||||
#ifndef nosound
|
||||
#ifndef nosound
|
||||
play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
newcam_framessincec[0] = 0;
|
||||
}
|
||||
if ((gPlayer1Controller->buttonPressed & R_CBUTTONS) && newcam_modeflags & NC_FLAG_XTURN && !(newcam_modeflags & NC_FLAG_8D) && newcam_analogue == 0) {
|
||||
if ((gPlayer1Controller->buttonPressed & R_CBUTTONS) && newcam_modeflags & NC_FLAG_XTURN
|
||||
&& !(newcam_modeflags & NC_FLAG_8D) && newcam_analogue == 0) {
|
||||
if (newcam_framessincec[1] < 6) {
|
||||
newcam_yaw_target = newcam_yaw-(ivrt(0)*0x3000);
|
||||
newcam_yaw_target = newcam_yaw - (ivrt(0) * 0x3000);
|
||||
newcam_centering = 1;
|
||||
#ifndef nosound
|
||||
#ifndef nosound
|
||||
play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
newcam_framessincec[1] = 0;
|
||||
}
|
||||
|
||||
|
||||
//There's not much point in keeping this behind a check, but it wouldn't hurt, just incase any 2player shenanigans ever happen, it makes it easy to disable.
|
||||
// There's not much point in keeping this behind a check, but it wouldn't hurt, just incase any
|
||||
// 2player shenanigans ever happen, it makes it easy to disable.
|
||||
if (newcam_analogue == 1) {
|
||||
//The joystick values cap at 80, so divide by 8 to get the same net result at maximum turn as the button
|
||||
intendedXMag = newcam_stick2[0]*1.25;
|
||||
intendedYMag = newcam_stick2[1]*1.25;
|
||||
// The joystick values cap at 80, so divide by 8 to get the same net result at maximum turn as
|
||||
// the button
|
||||
intendedXMag = newcam_stick2[0] * 1.25;
|
||||
intendedYMag = newcam_stick2[1] * 1.25;
|
||||
|
||||
if (ABS(newcam_stick2[0]) > 20 && newcam_modeflags & NC_FLAG_XTURN) {
|
||||
if (newcam_modeflags & NC_FLAG_8D) {
|
||||
if (newcam_cstick_down == 0) {
|
||||
newcam_cstick_down = 1;
|
||||
newcam_centering = 1;
|
||||
#ifndef nosound
|
||||
#ifndef nosound
|
||||
play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs);
|
||||
#endif
|
||||
#endif
|
||||
if (newcam_stick2[0] > 20) {
|
||||
if (newcam_modeflags & NC_FLAG_8D)
|
||||
newcam_yaw_target = newcam_yaw_target+(ivrt(0)*0x2000);
|
||||
newcam_yaw_target = newcam_yaw_target + (ivrt(0) * 0x2000);
|
||||
else
|
||||
newcam_yaw_target = newcam_yaw_target+(ivrt(0)*0x4000);
|
||||
newcam_yaw_target = newcam_yaw_target + (ivrt(0) * 0x4000);
|
||||
} else {
|
||||
if (newcam_modeflags & NC_FLAG_8D)
|
||||
newcam_yaw_target = newcam_yaw_target-(ivrt(0)*0x2000);
|
||||
newcam_yaw_target = newcam_yaw_target - (ivrt(0) * 0x2000);
|
||||
else
|
||||
newcam_yaw_target = newcam_yaw_target-(ivrt(0)*0x4000);
|
||||
newcam_yaw_target = newcam_yaw_target - (ivrt(0) * 0x4000);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc,newcam_stick2[0]*0.125, intendedXMag);
|
||||
newcam_yaw_acc =
|
||||
newcam_adjust_value(newcam_yaw_acc, newcam_stick2[0] * 0.125, intendedXMag);
|
||||
}
|
||||
} else if (newcam_analogue) {
|
||||
newcam_cstick_down = 0;
|
||||
newcam_yaw_acc -= (newcam_yaw_acc*((f32)newcam_degrade/100));
|
||||
newcam_yaw_acc -= (newcam_yaw_acc * ((f32) newcam_degrade / 100));
|
||||
}
|
||||
|
||||
if (ABS(newcam_stick2[1]) > 20 && newcam_modeflags & NC_FLAG_YTURN)
|
||||
newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc, newcam_stick2[1]*0.125, intendedYMag);
|
||||
newcam_tilt_acc =
|
||||
newcam_adjust_value(newcam_tilt_acc, newcam_stick2[1] * 0.125, intendedYMag);
|
||||
else if (newcam_analogue)
|
||||
newcam_tilt_acc -= (newcam_tilt_acc*((f32)newcam_degrade/100));
|
||||
newcam_tilt_acc -= (newcam_tilt_acc * ((f32) newcam_degrade / 100));
|
||||
}
|
||||
|
||||
if (newcam_mouse == 1) {
|
||||
|
@ -381,7 +444,7 @@ static void newcam_rotate_button(void) {
|
|||
}
|
||||
|
||||
static void newcam_zoom_button(void) {
|
||||
//Smoothly move the camera to the new spot.
|
||||
// Smoothly move the camera to the new spot.
|
||||
if (newcam_distance > newcam_distance_target) {
|
||||
newcam_distance -= 250;
|
||||
if (newcam_distance < newcam_distance_target)
|
||||
|
@ -394,14 +457,16 @@ static void newcam_zoom_button(void) {
|
|||
}
|
||||
|
||||
if ((gPlayer1Controller->buttonDown & L_TRIG) && (newcam_modeflags & NC_FLAG_ZOOM)) {
|
||||
//When you press L, set the flag for centering the camera. Afterwards, start setting the yaw to the Player's yaw at the time.
|
||||
newcam_yaw_target = -gMarioState->faceAngle[1]-0x4000;
|
||||
// When you press L, set the flag for centering the camera. Afterwards, start setting the yaw to
|
||||
// the Player's yaw at the time.
|
||||
newcam_yaw_target = -gMarioState->faceAngle[1] - 0x4000;
|
||||
newcam_centering = 1;
|
||||
} else if (gPlayer1Controller->buttonPressed & R_TRIG && newcam_modeflags & NC_FLAG_XTURN) {
|
||||
//Each time the player presses R, but NOT L the camera zooms out more, until it hits the limit and resets back to close view.
|
||||
#ifndef nosound
|
||||
// Each time the player presses R, but NOT L the camera zooms out more, until it hits the limit and
|
||||
// resets back to close view.
|
||||
#ifndef nosound
|
||||
play_sound(SOUND_MENU_CLICK_CHANGE_VIEW, gDefaultSoundArgs);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (newcam_distance_target == newcam_distance_values[0])
|
||||
newcam_distance_target = newcam_distance_values[1];
|
||||
|
@ -412,7 +477,7 @@ static void newcam_zoom_button(void) {
|
|||
}
|
||||
|
||||
if (newcam_centering && newcam_modeflags & NC_FLAG_XTURN) {
|
||||
newcam_yaw = approach_s16_symmetric(newcam_yaw,newcam_yaw_target,0x800);
|
||||
newcam_yaw = approach_s16_symmetric(newcam_yaw, newcam_yaw_target, 0x800);
|
||||
if (newcam_yaw == newcam_yaw_target)
|
||||
newcam_centering = 0;
|
||||
} else {
|
||||
|
@ -421,13 +486,14 @@ static void newcam_zoom_button(void) {
|
|||
}
|
||||
|
||||
static void newcam_update_values(void) {
|
||||
//For tilt, this just limits it so it doesn't go further than 90 degrees either way. 90 degrees is actually 16384, but can sometimes lead to issues, so I just leave it shy of 90.
|
||||
// For tilt, this just limits it so it doesn't go further than 90 degrees either way. 90 degrees is
|
||||
// actually 16384, but can sometimes lead to issues, so I just leave it shy of 90.
|
||||
u8 waterflag = 0;
|
||||
|
||||
if (newcam_modeflags & NC_FLAG_XTURN)
|
||||
newcam_yaw -= ((newcam_yaw_acc*(newcam_sensitivityX/10))*ivrt(0));
|
||||
newcam_yaw -= ((newcam_yaw_acc * (newcam_sensitivityX / 10)) * ivrt(0));
|
||||
if (((newcam_tilt <= 12000) && (newcam_tilt >= -12000)) && newcam_modeflags & NC_FLAG_YTURN)
|
||||
newcam_tilt += ((newcam_tilt_acc*ivrt(1))*(newcam_sensitivityY/10));
|
||||
newcam_tilt += ((newcam_tilt_acc * ivrt(1)) * (newcam_sensitivityY / 10));
|
||||
|
||||
if (newcam_tilt > 12000)
|
||||
newcam_tilt = 12000;
|
||||
|
@ -439,55 +505,130 @@ static void newcam_update_values(void) {
|
|||
if (newcam_turnwait < 0)
|
||||
newcam_turnwait = 0;
|
||||
} else {
|
||||
if (gMarioState->intendedMag > 0 && gMarioState->vel[1] == 0 && newcam_modeflags & NC_FLAG_XTURN && !(newcam_modeflags & NC_FLAG_8D) && !(newcam_modeflags & NC_FLAG_4D))
|
||||
newcam_yaw = (approach_s16_symmetric(newcam_yaw,-gMarioState->faceAngle[1]-0x4000,((newcam_aggression*(ABS(gPlayer1Controller->rawStickX/10)))*(gMarioState->forwardVel/32))));
|
||||
if (gMarioState->intendedMag > 0 && gMarioState->vel[1] == 0 && newcam_modeflags & NC_FLAG_XTURN
|
||||
&& !(newcam_modeflags & NC_FLAG_8D) && !(newcam_modeflags & NC_FLAG_4D))
|
||||
newcam_yaw =
|
||||
(approach_s16_symmetric(newcam_yaw, -gMarioState->faceAngle[1] - 0x4000,
|
||||
((newcam_aggression * (ABS(gPlayer1Controller->rawStickX / 10)))
|
||||
* (gMarioState->forwardVel / 32))));
|
||||
else
|
||||
newcam_turnwait = 10;
|
||||
}
|
||||
|
||||
if (newcam_modeflags & NC_FLAG_SLIDECORRECT) {
|
||||
switch (gMarioState->action) {
|
||||
case ACT_BUTT_SLIDE: if (gMarioState->forwardVel > 8) waterflag = 1; break;
|
||||
case ACT_STOMACH_SLIDE: if (gMarioState->forwardVel > 8) waterflag = 1; break;
|
||||
case ACT_HOLD_BUTT_SLIDE: if (gMarioState->forwardVel > 8) waterflag = 1; break;
|
||||
case ACT_HOLD_STOMACH_SLIDE: if (gMarioState->forwardVel > 8) waterflag = 1; break;
|
||||
case ACT_BUTT_SLIDE:
|
||||
if (gMarioState->forwardVel > 8)
|
||||
waterflag = 1;
|
||||
break;
|
||||
case ACT_STOMACH_SLIDE:
|
||||
if (gMarioState->forwardVel > 8)
|
||||
waterflag = 1;
|
||||
break;
|
||||
case ACT_HOLD_BUTT_SLIDE:
|
||||
if (gMarioState->forwardVel > 8)
|
||||
waterflag = 1;
|
||||
break;
|
||||
case ACT_HOLD_STOMACH_SLIDE:
|
||||
if (gMarioState->forwardVel > 8)
|
||||
waterflag = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (gMarioState->action) {
|
||||
case ACT_SHOT_FROM_CANNON: waterflag = 1; break;
|
||||
case ACT_FLYING: waterflag = 1; break;
|
||||
case ACT_SHOT_FROM_CANNON:
|
||||
waterflag = 1;
|
||||
break;
|
||||
case ACT_FLYING:
|
||||
waterflag = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (gMarioState->action & ACT_FLAG_SWIMMING) {
|
||||
if (gMarioState->forwardVel > 2)
|
||||
waterflag = 1;
|
||||
waterflag = 1;
|
||||
}
|
||||
|
||||
if (waterflag && newcam_modeflags & NC_FLAG_XTURN) {
|
||||
newcam_yaw = (approach_s16_symmetric(newcam_yaw,-gMarioState->faceAngle[1]-0x4000,(gMarioState->forwardVel*128)));
|
||||
if ((signed)gMarioState->forwardVel > 1)
|
||||
newcam_tilt = (approach_s16_symmetric(newcam_tilt,(-gMarioState->faceAngle[0]*0.8)+3000,(gMarioState->forwardVel*32)));
|
||||
newcam_yaw = (approach_s16_symmetric(newcam_yaw, -gMarioState->faceAngle[1] - 0x4000,
|
||||
(gMarioState->forwardVel * 128)));
|
||||
if ((signed) gMarioState->forwardVel > 1)
|
||||
newcam_tilt =
|
||||
(approach_s16_symmetric(newcam_tilt, (-gMarioState->faceAngle[0] * 0.8) + 3000,
|
||||
(gMarioState->forwardVel * 32)));
|
||||
else
|
||||
newcam_tilt = (approach_s16_symmetric(newcam_tilt,3000,32));
|
||||
newcam_tilt = (approach_s16_symmetric(newcam_tilt, 3000, 32));
|
||||
}
|
||||
}
|
||||
|
||||
static void newcam_bounding_box(void) {
|
||||
Vec3f camdirs[NEW_CAM_BOUNDING_BOX_RAYS] = { 0 };
|
||||
Vec3f raypos[NEW_CAM_BOUNDING_BOX_RAYS] = { 0 };
|
||||
s16 antiYaw = newcam_yaw - 0x4000;
|
||||
|
||||
// sideways ray 1
|
||||
camdirs[0][0] = coss(antiYaw) * NEW_CAM_BOUNDING_BOX_HRADIUS;
|
||||
camdirs[0][2] = sins(antiYaw) * NEW_CAM_BOUNDING_BOX_HRADIUS;
|
||||
|
||||
// sideways ray 2
|
||||
camdirs[1][0] = -coss(antiYaw) * NEW_CAM_BOUNDING_BOX_HRADIUS;
|
||||
camdirs[1][2] = -sins(antiYaw) * NEW_CAM_BOUNDING_BOX_HRADIUS;
|
||||
|
||||
// vertical rays
|
||||
camdirs[2][1] = -NEW_CAM_BOUNDING_BOX_VRADIUS;
|
||||
camdirs[3][1] = NEW_CAM_BOUNDING_BOX_VRADIUS;
|
||||
|
||||
for (int i = 0; i < NEW_CAM_BOUNDING_BOX_RAYS; i++) {
|
||||
struct Surface *surf;
|
||||
Vec3f offset = { 0 };
|
||||
|
||||
Vec3f startpos = { 0 };
|
||||
vec3f_copy(startpos, newcam_pos);
|
||||
vec3f_add(startpos, offset);
|
||||
|
||||
find_surface_on_ray(startpos, camdirs[i], &surf, raypos[i]);
|
||||
if (!surf) {
|
||||
vec3f_copy(raypos[i], startpos);
|
||||
vec3f_add(raypos[i], camdirs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Vec3f avg = { 0 };
|
||||
for (int i = 0; i < NEW_CAM_BOUNDING_BOX_RAYS; i++) {
|
||||
vec3f_add(avg, raypos[i]);
|
||||
}
|
||||
vec3f_mul(avg, 1.0f / ((f32) NEW_CAM_BOUNDING_BOX_RAYS));
|
||||
|
||||
vec3f_copy(newcam_pos, avg);
|
||||
}
|
||||
|
||||
static void newcam_collision(void) {
|
||||
struct Surface *surf;
|
||||
Vec3f camdir;
|
||||
Vec3f hitpos;
|
||||
|
||||
camdir[0] = newcam_pos[0]-newcam_lookat[0];
|
||||
camdir[1] = newcam_pos[1]-newcam_lookat[1];
|
||||
camdir[2] = newcam_pos[2]-newcam_lookat[2];
|
||||
camdir[0] = newcam_pos[0] - newcam_lookat[0];
|
||||
camdir[1] = newcam_pos[1] - newcam_lookat[1];
|
||||
camdir[2] = newcam_pos[2] - newcam_lookat[2];
|
||||
|
||||
find_surface_on_ray(newcam_pos_target, camdir, &surf, hitpos);
|
||||
newcam_coldist = sqrtf((newcam_pos_target[0] - hitpos[0]) * (newcam_pos_target[0] - hitpos[0]) + (newcam_pos_target[1] - hitpos[1]) * (newcam_pos_target[1] - hitpos[1]) + (newcam_pos_target[2] - hitpos[2]) * (newcam_pos_target[2] - hitpos[2]));
|
||||
|
||||
newcam_coldist = sqrtf((newcam_pos_target[0] - hitpos[0]) * (newcam_pos_target[0] - hitpos[0])
|
||||
+ (newcam_pos_target[1] - hitpos[1]) * (newcam_pos_target[1] - hitpos[1])
|
||||
+ (newcam_pos_target[2] - hitpos[2]) * (newcam_pos_target[2] - hitpos[2]));
|
||||
|
||||
if (surf) {
|
||||
// offset the hit pos by the hit normal
|
||||
Vec3f offset = { 0 };
|
||||
offset[0] = surf->normal.x;
|
||||
offset[1] = surf->normal.y;
|
||||
offset[2] = surf->normal.z;
|
||||
vec3f_mul(offset, 5.0f);
|
||||
vec3f_add(hitpos, offset);
|
||||
|
||||
newcam_pos[0] = hitpos[0];
|
||||
newcam_pos[1] = approach_f32(hitpos[1],newcam_pos[1],25,-25);
|
||||
newcam_pos[1] = hitpos[1];
|
||||
newcam_pos[2] = hitpos[2];
|
||||
newcam_pan_x = 0;
|
||||
newcam_pan_z = 0;
|
||||
|
@ -495,17 +636,22 @@ static void newcam_collision(void) {
|
|||
}
|
||||
|
||||
static void newcam_set_pan(void) {
|
||||
//Apply panning values based on Mario's direction.
|
||||
if (gMarioState->action != ACT_HOLDING_BOWSER && gMarioState->action != ACT_SLEEPING && gMarioState->action != ACT_START_SLEEPING) {
|
||||
approach_f32_asymptotic_bool(&newcam_pan_x, lengthdir_x((160*newcam_panlevel)/100, -gMarioState->faceAngle[1]-0x4000), 0.05);
|
||||
approach_f32_asymptotic_bool(&newcam_pan_z, lengthdir_y((160*newcam_panlevel)/100, -gMarioState->faceAngle[1]-0x4000), 0.05);
|
||||
// Apply panning values based on Mario's direction.
|
||||
if (gMarioState->action != ACT_HOLDING_BOWSER && gMarioState->action != ACT_SLEEPING
|
||||
&& gMarioState->action != ACT_START_SLEEPING) {
|
||||
approach_f32_asymptotic_bool(
|
||||
&newcam_pan_x,
|
||||
lengthdir_x((160 * newcam_panlevel) / 100, -gMarioState->faceAngle[1] - 0x4000), 0.05);
|
||||
approach_f32_asymptotic_bool(
|
||||
&newcam_pan_z,
|
||||
lengthdir_y((160 * newcam_panlevel) / 100, -gMarioState->faceAngle[1] - 0x4000), 0.05);
|
||||
} else {
|
||||
approach_f32_asymptotic_bool(&newcam_pan_x, 0, 0.05);
|
||||
approach_f32_asymptotic_bool(&newcam_pan_z, 0, 0.05);
|
||||
}
|
||||
|
||||
newcam_pan_x = newcam_pan_x*(min(newcam_distance/newcam_distance_target,1));
|
||||
newcam_pan_z = newcam_pan_z*(min(newcam_distance/newcam_distance_target,1));
|
||||
newcam_pan_x = newcam_pan_x * (min(newcam_distance / newcam_distance_target, 1));
|
||||
newcam_pan_z = newcam_pan_z * (min(newcam_distance / newcam_distance_target, 1));
|
||||
}
|
||||
|
||||
static void newcam_position_cam(void) {
|
||||
|
@ -514,51 +660,63 @@ static void newcam_position_cam(void) {
|
|||
s16 shakeX;
|
||||
s16 shakeY;
|
||||
|
||||
if (!(gMarioState->action & ACT_FLAG_SWIMMING) && newcam_modeflags & NC_FLAG_FOCUSY && newcam_modeflags & NC_FLAG_POSY)
|
||||
if (!(gMarioState->action & ACT_FLAG_SWIMMING) && newcam_modeflags & NC_FLAG_FOCUSY
|
||||
&& newcam_modeflags & NC_FLAG_POSY)
|
||||
calc_y_to_curr_floor(&floorY, 1.f, 200.f, &floorY2, 0.9f, 200.f);
|
||||
|
||||
newcam_update_values();
|
||||
shakeX = gLakituState.shakeMagnitude[1];
|
||||
shakeY = gLakituState.shakeMagnitude[0];
|
||||
//Fetch Mario's current position. Not hardcoded just for the sake of flexibility, though this specific bit is temp, because it won't always want to be focusing on Mario.
|
||||
// Fetch Mario's current position. Not hardcoded just for the sake of flexibility, though this
|
||||
// specific bit is temp, because it won't always want to be focusing on Mario.
|
||||
newcam_pos_target[0] = gMarioState->pos[0];
|
||||
newcam_pos_target[1] = gMarioState->pos[1]+newcam_extheight;
|
||||
newcam_pos_target[1] = gMarioState->pos[1] + newcam_extheight;
|
||||
newcam_pos_target[2] = gMarioState->pos[2];
|
||||
//These will set the position of the camera to where Mario is supposed to be, minus adjustments for where the camera should be, on top of.
|
||||
// These will set the position of the camera to where Mario is supposed to be, minus adjustments for
|
||||
// where the camera should be, on top of.
|
||||
if (newcam_modeflags & NC_FLAG_POSX)
|
||||
newcam_pos[0] = newcam_pos_target[0]+lengthdir_x(lengthdir_x(newcam_distance,newcam_tilt+shakeX),newcam_yaw+shakeY);
|
||||
newcam_pos[0] =
|
||||
newcam_pos_target[0]
|
||||
+ lengthdir_x(lengthdir_x(newcam_distance, newcam_tilt + shakeX), newcam_yaw + shakeY);
|
||||
if (newcam_modeflags & NC_FLAG_POSZ)
|
||||
newcam_pos[2] = newcam_pos_target[2]+lengthdir_y(lengthdir_x(newcam_distance,newcam_tilt+shakeX),newcam_yaw+shakeY);
|
||||
newcam_pos[2] =
|
||||
newcam_pos_target[2]
|
||||
+ lengthdir_y(lengthdir_x(newcam_distance, newcam_tilt + shakeX), newcam_yaw + shakeY);
|
||||
if (newcam_modeflags & NC_FLAG_POSY)
|
||||
newcam_pos[1] = newcam_pos_target[1]+lengthdir_y(newcam_distance,newcam_tilt+gLakituState.shakeMagnitude[0])+floorY;
|
||||
if ((newcam_modeflags & NC_FLAG_FOCUSX) && (newcam_modeflags & NC_FLAG_FOCUSY) && (newcam_modeflags & NC_FLAG_FOCUSZ))
|
||||
newcam_pos[1] = newcam_pos_target[1]
|
||||
+ lengthdir_y(newcam_distance, newcam_tilt + gLakituState.shakeMagnitude[0])
|
||||
+ floorY;
|
||||
if ((newcam_modeflags & NC_FLAG_FOCUSX) && (newcam_modeflags & NC_FLAG_FOCUSY)
|
||||
&& (newcam_modeflags & NC_FLAG_FOCUSZ))
|
||||
newcam_set_pan();
|
||||
//Set where the camera wants to be looking at. This is almost always the place it's based off, too.
|
||||
// Set where the camera wants to be looking at. This is almost always the place it's based off, too.
|
||||
if (newcam_modeflags & NC_FLAG_FOCUSX)
|
||||
newcam_lookat[0] = newcam_pos_target[0]-newcam_pan_x;
|
||||
newcam_lookat[0] = newcam_pos_target[0] - newcam_pan_x;
|
||||
if (newcam_modeflags & NC_FLAG_FOCUSY)
|
||||
newcam_lookat[1] = newcam_pos_target[1]+floorY2;
|
||||
newcam_lookat[1] = newcam_pos_target[1] + floorY2;
|
||||
if (newcam_modeflags & NC_FLAG_FOCUSZ)
|
||||
newcam_lookat[2] = newcam_pos_target[2]-newcam_pan_z;
|
||||
|
||||
if (newcam_modeflags & NC_FLAG_COLLISION)
|
||||
newcam_collision();
|
||||
newcam_lookat[2] = newcam_pos_target[2] - newcam_pan_z;
|
||||
|
||||
if (newcam_modeflags & NC_FLAG_COLLISION) {
|
||||
newcam_collision();
|
||||
newcam_bounding_box();
|
||||
}
|
||||
}
|
||||
|
||||
//Nested if's baybeeeee
|
||||
// Nested if's baybeeeee
|
||||
static void newcam_find_fixed(void) {
|
||||
u8 i = 0;
|
||||
newcam_mode = newcam_intendedmode;
|
||||
newcam_modeflags = newcam_mode;
|
||||
for (i = 0; i < sizeof(newcam_fixedcam) / sizeof(struct newcam_hardpos); i++) {
|
||||
if (newcam_fixedcam[i].newcam_hard_levelID == gCurrLevelNum && newcam_fixedcam[i].newcam_hard_areaID == gCurrAreaIndex) {
|
||||
if (newcam_fixedcam[i].newcam_hard_levelID == gCurrLevelNum
|
||||
&& newcam_fixedcam[i].newcam_hard_areaID == gCurrAreaIndex) {
|
||||
if ((newcam_pos_target[0] > newcam_fixedcam[i].newcam_hard_X1)
|
||||
&& (newcam_pos_target[0] < newcam_fixedcam[i].newcam_hard_X2)
|
||||
&& (newcam_pos_target[1] > newcam_fixedcam[i].newcam_hard_Y1)
|
||||
&& (newcam_pos_target[1] < newcam_fixedcam[i].newcam_hard_Y2)
|
||||
&& (newcam_pos_target[2] > newcam_fixedcam[i].newcam_hard_Z1)
|
||||
&& (newcam_pos_target[2] < newcam_fixedcam[i].newcam_hard_Z2)) {
|
||||
&& (newcam_pos_target[0] < newcam_fixedcam[i].newcam_hard_X2)
|
||||
&& (newcam_pos_target[1] > newcam_fixedcam[i].newcam_hard_Y1)
|
||||
&& (newcam_pos_target[1] < newcam_fixedcam[i].newcam_hard_Y2)
|
||||
&& (newcam_pos_target[2] > newcam_fixedcam[i].newcam_hard_Z1)
|
||||
&& (newcam_pos_target[2] < newcam_fixedcam[i].newcam_hard_Z2)) {
|
||||
if (newcam_fixedcam[i].newcam_hard_permaswap)
|
||||
newcam_intendedmode = newcam_fixedcam[i].newcam_hard_modeset;
|
||||
newcam_mode = newcam_fixedcam[i].newcam_hard_modeset;
|
||||
|
@ -571,14 +729,18 @@ static void newcam_find_fixed(void) {
|
|||
if (newcam_fixedcam[i].newcam_hard_camZ != 32767 && !(newcam_modeflags & NC_FLAG_POSZ))
|
||||
newcam_pos[2] = newcam_fixedcam[i].newcam_hard_camZ;
|
||||
|
||||
if (newcam_fixedcam[i].newcam_hard_lookX != 32767 && !(newcam_modeflags & NC_FLAG_FOCUSX))
|
||||
if (newcam_fixedcam[i].newcam_hard_lookX != 32767
|
||||
&& !(newcam_modeflags & NC_FLAG_FOCUSX))
|
||||
newcam_lookat[0] = newcam_fixedcam[i].newcam_hard_lookX;
|
||||
if (newcam_fixedcam[i].newcam_hard_lookY != 32767 && !(newcam_modeflags & NC_FLAG_FOCUSY))
|
||||
if (newcam_fixedcam[i].newcam_hard_lookY != 32767
|
||||
&& !(newcam_modeflags & NC_FLAG_FOCUSY))
|
||||
newcam_lookat[1] = newcam_fixedcam[i].newcam_hard_lookY;
|
||||
if (newcam_fixedcam[i].newcam_hard_lookZ != 32767 && !(newcam_modeflags & NC_FLAG_FOCUSZ))
|
||||
if (newcam_fixedcam[i].newcam_hard_lookZ != 32767
|
||||
&& !(newcam_modeflags & NC_FLAG_FOCUSZ))
|
||||
newcam_lookat[2] = newcam_fixedcam[i].newcam_hard_lookZ;
|
||||
|
||||
newcam_yaw = atan2s(newcam_pos[0]-newcam_pos_target[0],newcam_pos[2]-newcam_pos_target[2]);
|
||||
newcam_yaw =
|
||||
atan2s(newcam_pos[0] - newcam_pos_target[0], newcam_pos[2] - newcam_pos_target[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -601,10 +763,10 @@ static void newcam_apply_values(struct Camera *c) {
|
|||
gLakituState.focus[1] = newcam_lookat[1];
|
||||
gLakituState.focus[2] = newcam_lookat[2];
|
||||
|
||||
c->yaw = -newcam_yaw+0x4000;
|
||||
gLakituState.yaw = -newcam_yaw+0x4000;
|
||||
c->yaw = -newcam_yaw + 0x4000;
|
||||
gLakituState.yaw = -newcam_yaw + 0x4000;
|
||||
|
||||
//Adds support for wing mario tower
|
||||
// Adds support for wing mario tower
|
||||
if (gMarioState->floor != NULL) {
|
||||
if (gMarioState->floor->type == SURFACE_LOOK_UP_WARP) {
|
||||
if (save_file_get_total_star_count(gCurrSaveFileNum - 1, 0, 0x18) >= 10) {
|
||||
|
@ -616,11 +778,11 @@ static void newcam_apply_values(struct Camera *c) {
|
|||
}
|
||||
}
|
||||
|
||||
//If puppycam gets too close to its target, start fading it out so you don't see the inside of it.
|
||||
// If puppycam gets too close to its target, start fading it out so you don't see the inside of it.
|
||||
void newcam_fade_target_closeup(void) {
|
||||
if (newcam_coldist <= 250 && (newcam_coldist-150)*2.55f < 255) {
|
||||
if ((newcam_coldist-150)*2.55f > 0)
|
||||
newcam_xlu = (newcam_coldist-150)*2.55f;
|
||||
if (newcam_coldist <= 250 && (newcam_coldist - 150) * 2.55f < 255) {
|
||||
if ((newcam_coldist - 150) * 2.55f > 0)
|
||||
newcam_xlu = (newcam_coldist - 150) * 2.55f;
|
||||
else
|
||||
newcam_xlu = 0;
|
||||
} else {
|
||||
|
@ -628,12 +790,13 @@ void newcam_fade_target_closeup(void) {
|
|||
}
|
||||
}
|
||||
|
||||
//The ingame cutscene system is such a spaghetti mess I actually have to resort to something as stupid as this to cover every base.
|
||||
// The ingame cutscene system is such a spaghetti mess I actually have to resort to something as stupid
|
||||
// as this to cover every base.
|
||||
void newcam_apply_outside_values(struct Camera *c, u8 bit) {
|
||||
if (bit)
|
||||
newcam_yaw = -gMarioState->faceAngle[1]-0x4000;
|
||||
newcam_yaw = -gMarioState->faceAngle[1] - 0x4000;
|
||||
else
|
||||
newcam_yaw = -c->yaw+0x4000;
|
||||
newcam_yaw = -c->yaw + 0x4000;
|
||||
}
|
||||
|
||||
static void newcam_stick_input(void) {
|
||||
|
@ -641,7 +804,7 @@ static void newcam_stick_input(void) {
|
|||
newcam_stick2[1] = gPlayer1Controller->extStickY;
|
||||
}
|
||||
|
||||
//Main loop.
|
||||
// Main loop.
|
||||
void newcam_loop(struct Camera *c) {
|
||||
newcam_stick_input();
|
||||
newcam_rotate_button();
|
||||
|
@ -652,8 +815,9 @@ void newcam_loop(struct Camera *c) {
|
|||
newcam_apply_values(c);
|
||||
newcam_fade_target_closeup();
|
||||
|
||||
//Just some visual information on the values of the camera. utilises ifdef because it's better at runtime.
|
||||
#ifdef NEWCAM_DEBUG
|
||||
// Just some visual information on the values of the camera. utilises ifdef because it's better at
|
||||
// runtime.
|
||||
#ifdef NEWCAM_DEBUG
|
||||
newcam_diagnostics();
|
||||
#endif // NEWCAM_DEBUG
|
||||
}
|
||||
#endif // NEWCAM_DEBUG
|
||||
}
|
|
@ -128,6 +128,7 @@ struct GraphNodeCamera *gCurGraphNodeCamera = NULL;
|
|||
struct GraphNodeObject *gCurGraphNodeObject = NULL;
|
||||
struct GraphNodeHeldObject *gCurGraphNodeHeldObject = NULL;
|
||||
u16 gAreaUpdateCounter = 0;
|
||||
u8 gInterpolatingSurfaces;
|
||||
|
||||
#ifdef F3DEX_GBI_2
|
||||
LookAt lookAt;
|
||||
|
@ -924,7 +925,6 @@ static void geo_process_shadow(struct GraphNodeShadow *node) {
|
|||
gCurGraphNodeObject->prevShadowPosTimestamp = gGlobalTimer;
|
||||
}
|
||||
|
||||
extern u8 gInterpolatingSurfaces;
|
||||
gInterpolatingSurfaces = TRUE;
|
||||
shadowListInterpolated = create_shadow_below_xyz(shadowPosInterpolated[0], shadowPosInterpolated[1],
|
||||
shadowPosInterpolated[2], shadowScale,
|
||||
|
|
|
@ -12,6 +12,7 @@ extern struct GraphNodeCamera *gCurGraphNodeCamera;
|
|||
extern struct GraphNodeObject *gCurGraphNodeObject;
|
||||
extern struct GraphNodeHeldObject *gCurGraphNodeHeldObject;
|
||||
extern u16 gAreaUpdateCounter;
|
||||
extern u8 gInterpolatingSurfaces;
|
||||
|
||||
// after processing an object, the type is reset to this
|
||||
#define ANIM_TYPE_NONE 0
|
||||
|
|
Loading…
Reference in a new issue