migrate to multifiles setup
This commit is contained in:
parent
e1a9ae16c0
commit
14738a1f8d
4
.gdbinit
4
.gdbinit
@ -1,4 +1,4 @@
|
||||
target remote localhost:3333
|
||||
symbol-file /home/arthus/build/pcsx-redux/src/mips/3dcam-bak/3dcam-tri-quads.elf
|
||||
symbol-file /home/arthus/build/pcsx-redux/src/mips/3dcam-bak/main.elf
|
||||
monitor reset shellhalt
|
||||
load /home/arthus/build/pcsx-redux/src/mips/3dcam-bak/3dcam-tri-quads.elf
|
||||
load /home/arthus/build/pcsx-redux/src/mips/3dcam-bak/main.elf
|
||||
|
2877
3dcam-tri-quads.c
2877
3dcam-tri-quads.c
File diff suppressed because it is too large
Load Diff
10
Makefile
10
Makefile
@ -1,7 +1,13 @@
|
||||
TARGET = 3dcam-tri-quads
|
||||
TARGET = main
|
||||
TYPE = ps-exe
|
||||
|
||||
SRCS = 3dcam-tri-quads.c \
|
||||
SRCS = main.c \
|
||||
math.c \
|
||||
camera.c \
|
||||
physics.c \
|
||||
graphics.c \
|
||||
psx.c \
|
||||
space.c \
|
||||
../common/crt0/crt0.s \
|
||||
TIM/home.tim \
|
||||
TIM/cat.tim \
|
||||
|
40
camera.c
Normal file
40
camera.c
Normal file
@ -0,0 +1,40 @@
|
||||
#include "camera.h"
|
||||
#include "math.h"
|
||||
|
||||
void getCameraXZ(int * x, int * z, int actorX, int actorZ, int angle, int distance) {
|
||||
|
||||
// Using Nic's Costable : https://github.com/grumpycoders/Balau/blob/master/tests/test-Handles.cc#L20-L102
|
||||
// https://godbolt.org/z/q6cMcj
|
||||
|
||||
*x = (actorX << 12) + (distance * nsin(angle));
|
||||
|
||||
*z = (actorZ << 12) - (distance * ncos(angle));
|
||||
|
||||
};
|
||||
|
||||
// @Will : you might want to use sin/cos to move the camera in a circle but you could do that by moving it along it’s tangent and then clamping the distance
|
||||
|
||||
void applyCamera( CAMERA * cam ) {
|
||||
|
||||
VECTOR vec; // Vector that holds the output values of the following instructions
|
||||
|
||||
RotMatrix_gte(&cam->rot, &cam->mat); // Convert rotation angle in psx units (360° == 4096) to rotation matrix)
|
||||
|
||||
ApplyMatrixLV(&cam->mat, &cam->pos, &vec); // Multiply matrix by vector pos and output to vec
|
||||
|
||||
TransMatrix(&cam->mat, &vec); // Apply transform vector
|
||||
|
||||
SetRotMatrix(&cam->mat); // Set Rotation matrix
|
||||
|
||||
SetTransMatrix(&cam->mat); // Set Transform matrix
|
||||
|
||||
|
||||
};
|
||||
|
||||
void setCameraPos( CAMERA * camera, VECTOR pos, SVECTOR rot ) {
|
||||
|
||||
camera->pos = pos;
|
||||
|
||||
camera->rot = rot;
|
||||
|
||||
};
|
34
camera.h
Normal file
34
camera.h
Normal file
@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <libgte.h>
|
||||
|
||||
typedef struct{
|
||||
|
||||
int x, xv; // x: current value += xv : new value
|
||||
|
||||
int y, yv; // x,y,z, vx, vy, vz are in PSX units (ONE == 4096)
|
||||
|
||||
int z, zv;
|
||||
|
||||
int pan, panv;
|
||||
|
||||
int tilt, tiltv;
|
||||
|
||||
int rol;
|
||||
|
||||
VECTOR pos;
|
||||
|
||||
SVECTOR rot;
|
||||
|
||||
SVECTOR dvs;
|
||||
|
||||
MATRIX mat;
|
||||
|
||||
} CAMERA;
|
||||
|
||||
void getCameraXZ(int * x, int * z, int actorX, int actorZ, int angle, int distance);
|
||||
|
||||
void applyCamera(CAMERA * cam);
|
||||
|
||||
void setCameraPos(CAMERA * camera, VECTOR pos, SVECTOR rot);
|
120
coridor2.c
120
coridor2.c
@ -1,113 +1,4 @@
|
||||
struct BODY;
|
||||
struct VANIM;
|
||||
struct PRIM;
|
||||
struct MESH;
|
||||
struct CAMPOS;
|
||||
struct CAMPATH;
|
||||
struct CAMANGLE;
|
||||
struct SIBLINGS;
|
||||
struct CHILDREN;
|
||||
struct NODE;
|
||||
struct QUAD;
|
||||
|
||||
typedef struct BODY {
|
||||
VECTOR gForce;
|
||||
VECTOR position;
|
||||
SVECTOR velocity;
|
||||
int mass;
|
||||
int invMass;
|
||||
VECTOR min;
|
||||
VECTOR max;
|
||||
int restitution;
|
||||
} BODY;
|
||||
|
||||
typedef struct VANIM {
|
||||
int nframes; // number of frames e.g 20
|
||||
int nvert; // number of vertices e.g 21
|
||||
int cursor; // anim cursor
|
||||
int lerpCursor; // anim cursor
|
||||
int dir; // playback direction (1 or -1)
|
||||
int interpolate; // use lerp to interpolate keyframes
|
||||
SVECTOR data[]; // vertex pos as SVECTORs e.g 20 * 21 SVECTORS
|
||||
} VANIM;
|
||||
|
||||
typedef struct PRIM {
|
||||
VECTOR order;
|
||||
int code; // Same as POL3/POL4 codes : Code (F3 = 1, FT3 = 2, G3 = 3,
|
||||
// GT3 = 4) Code (F4 = 5, FT4 = 6, G4 = 7, GT4 = 8)
|
||||
} PRIM;
|
||||
|
||||
typedef struct MESH {
|
||||
TMESH * tmesh;
|
||||
PRIM * index;
|
||||
TIM_IMAGE * tim;
|
||||
unsigned long * tim_data;
|
||||
MATRIX * mat;
|
||||
VECTOR * pos;
|
||||
SVECTOR * rot;
|
||||
short * isRigidBody;
|
||||
short * isStaticBody;
|
||||
short * isPrism;
|
||||
short * isAnim;
|
||||
short * isActor;
|
||||
short * isLevel;
|
||||
short * isBG;
|
||||
short * isSprite;
|
||||
long * p;
|
||||
long * OTz;
|
||||
BODY * body;
|
||||
VANIM * anim;
|
||||
struct NODE * node;
|
||||
VECTOR pos2D;
|
||||
} MESH;
|
||||
|
||||
typedef struct QUAD {
|
||||
VECTOR v0, v1;
|
||||
VECTOR v2, v3;
|
||||
} QUAD;
|
||||
|
||||
typedef struct CAMPOS {
|
||||
VECTOR pos;
|
||||
SVECTOR rot;
|
||||
} CAMPOS;
|
||||
|
||||
|
||||
// Blender cam ~= PSX cam with these settings :
|
||||
// NTSC - 320x240, PAL 320x256, pixel ratio 1:1,
|
||||
// cam focal length : perspective 90° ( 16 mm ))
|
||||
// With a FOV of 1/2, camera focal length is ~= 16 mm / 90°
|
||||
// Lower values mean wider angle
|
||||
|
||||
typedef struct CAMANGLE {
|
||||
CAMPOS * campos;
|
||||
TIM_IMAGE * BGtim;
|
||||
unsigned long * tim_data;
|
||||
QUAD bw, fw;
|
||||
int index;
|
||||
MESH * objects[];
|
||||
} CAMANGLE;
|
||||
|
||||
typedef struct CAMPATH {
|
||||
short len, cursor, pos;
|
||||
VECTOR points[];
|
||||
} CAMPATH;
|
||||
|
||||
typedef struct SIBLINGS {
|
||||
int index;
|
||||
struct NODE * list[];
|
||||
} SIBLINGS ;
|
||||
|
||||
typedef struct CHILDREN {
|
||||
int index;
|
||||
MESH * list[];
|
||||
} CHILDREN ;
|
||||
|
||||
typedef struct NODE {
|
||||
MESH * plane;
|
||||
SIBLINGS * siblings;
|
||||
CHILDREN * objects;
|
||||
CHILDREN * rigidbodies;
|
||||
} NODE;
|
||||
#include "coridor2.h"
|
||||
|
||||
CAMPOS camPos_camPath = {
|
||||
{ -205,156,-17 },
|
||||
@ -9803,7 +9694,7 @@ PRIM modelSphere_index[] = {
|
||||
};
|
||||
|
||||
MATRIX modelSphere_matrix = {0};
|
||||
VECTOR modelSphere_pos = {333,-129,-298, 0};
|
||||
VECTOR modelSphere_pos = {-486,-129,-32, 0};
|
||||
SVECTOR modelSphere_rot = {0,0,0};
|
||||
short modelSphere_isRigidBody = 1;
|
||||
short modelSphere_isStaticBody = 0;
|
||||
@ -9817,7 +9708,7 @@ long modelSphere_p = 0;
|
||||
long modelSphere_OTz = 0;
|
||||
BODY modelSphere_body = {
|
||||
{0, 0, 0, 0},
|
||||
333,-129,-298, 0,
|
||||
-486,-129,-32, 0,
|
||||
0,0,0, 0,
|
||||
2,
|
||||
ONE/2,
|
||||
@ -11389,10 +11280,9 @@ NODE nodegnd = {
|
||||
};
|
||||
|
||||
MESH * actorPtr = &meshSphere;
|
||||
MESH * levelPtr = &meshgnd_002;
|
||||
MESH * levelPtr = &meshgnd;
|
||||
MESH * propPtr = &meshSphere_001;
|
||||
|
||||
CAMANGLE * camPtr = &camAngle_camPath_001;
|
||||
|
||||
NODE * curNode = &nodegnd_002;
|
||||
|
||||
NODE * curNode = &nodegnd;
|
||||
|
110
coridor2.h
Normal file
110
coridor2.h
Normal file
@ -0,0 +1,110 @@
|
||||
struct BODY;
|
||||
struct VANIM;
|
||||
struct PRIM;
|
||||
struct MESH;
|
||||
struct CAMPOS;
|
||||
struct CAMPATH;
|
||||
struct CAMANGLE;
|
||||
struct SIBLINGS;
|
||||
struct CHILDREN;
|
||||
struct NODE;
|
||||
struct QUAD;
|
||||
|
||||
typedef struct BODY {
|
||||
VECTOR gForce;
|
||||
VECTOR position;
|
||||
SVECTOR velocity;
|
||||
int mass;
|
||||
int invMass;
|
||||
VECTOR min;
|
||||
VECTOR max;
|
||||
int restitution;
|
||||
} BODY;
|
||||
|
||||
typedef struct VANIM {
|
||||
int nframes; // number of frames e.g 20
|
||||
int nvert; // number of vertices e.g 21
|
||||
int cursor; // anim cursor
|
||||
int lerpCursor; // anim cursor
|
||||
int dir; // playback direction (1 or -1)
|
||||
int interpolate; // use lerp to interpolate keyframes
|
||||
SVECTOR data[]; // vertex pos as SVECTORs e.g 20 * 21 SVECTORS
|
||||
} VANIM;
|
||||
|
||||
typedef struct PRIM {
|
||||
VECTOR order;
|
||||
int code; // Same as POL3/POL4 codes : Code (F3 = 1, FT3 = 2, G3 = 3,
|
||||
// GT3 = 4) Code (F4 = 5, FT4 = 6, G4 = 7, GT4 = 8)
|
||||
} PRIM;
|
||||
|
||||
typedef struct MESH {
|
||||
TMESH * tmesh;
|
||||
PRIM * index;
|
||||
TIM_IMAGE * tim;
|
||||
unsigned long * tim_data;
|
||||
MATRIX * mat;
|
||||
VECTOR * pos;
|
||||
SVECTOR * rot;
|
||||
short * isRigidBody;
|
||||
short * isStaticBody;
|
||||
short * isPrism;
|
||||
short * isAnim;
|
||||
short * isActor;
|
||||
short * isLevel;
|
||||
short * isBG;
|
||||
short * isSprite;
|
||||
long * p;
|
||||
long * OTz;
|
||||
BODY * body;
|
||||
VANIM * anim;
|
||||
struct NODE * node;
|
||||
VECTOR pos2D;
|
||||
} MESH;
|
||||
|
||||
typedef struct QUAD {
|
||||
VECTOR v0, v1;
|
||||
VECTOR v2, v3;
|
||||
} QUAD;
|
||||
|
||||
typedef struct CAMPOS {
|
||||
VECTOR pos;
|
||||
SVECTOR rot;
|
||||
} CAMPOS;
|
||||
|
||||
|
||||
// Blender cam ~= PSX cam with these settings :
|
||||
// NTSC - 320x240, PAL 320x256, pixel ratio 1:1,
|
||||
// cam focal length : perspective 90° ( 16 mm ))
|
||||
// With a FOV of 1/2, camera focal length is ~= 16 mm / 90°
|
||||
// Lower values mean wider angle
|
||||
|
||||
typedef struct CAMANGLE {
|
||||
CAMPOS * campos;
|
||||
TIM_IMAGE * BGtim;
|
||||
unsigned long * tim_data;
|
||||
QUAD bw, fw;
|
||||
int index;
|
||||
MESH * objects[];
|
||||
} CAMANGLE;
|
||||
|
||||
typedef struct CAMPATH {
|
||||
short len, cursor, pos;
|
||||
VECTOR points[];
|
||||
} CAMPATH;
|
||||
|
||||
typedef struct SIBLINGS {
|
||||
int index;
|
||||
struct NODE * list[];
|
||||
} SIBLINGS ;
|
||||
|
||||
typedef struct CHILDREN {
|
||||
int index;
|
||||
MESH * list[];
|
||||
} CHILDREN ;
|
||||
|
||||
typedef struct NODE {
|
||||
MESH * plane;
|
||||
SIBLINGS * siblings;
|
||||
CHILDREN * objects;
|
||||
CHILDREN * rigidbodies;
|
||||
} NODE;
|
25
defines.h
Normal file
25
defines.h
Normal file
@ -0,0 +1,25 @@
|
||||
#define VMODE 0
|
||||
|
||||
#define SCREENXRES 320
|
||||
|
||||
#define SCREENYRES 240
|
||||
|
||||
#define CENTERX SCREENXRES/2
|
||||
|
||||
#define CENTERY SCREENYRES/2
|
||||
|
||||
#define FOV CENTERX
|
||||
|
||||
#define FNT_POS_X 960
|
||||
|
||||
#define FNT_POS_Y 256
|
||||
|
||||
#define OT2LEN 8
|
||||
|
||||
#define OTLEN 256
|
||||
|
||||
#define GRAVITY 10
|
||||
|
||||
#define SCALE 4
|
||||
|
||||
#define PRIMBUFFLEN 4096 * sizeof(POLY_GT4) // Maximum number of POLY_GT3 primitives
|
766
graphics.c
Normal file
766
graphics.c
Normal file
@ -0,0 +1,766 @@
|
||||
#include "graphics.h"
|
||||
#include "math.h"
|
||||
|
||||
void transformMesh(CAMERA * camera, MESH * mesh){
|
||||
|
||||
MATRIX mat;
|
||||
|
||||
// Apply rotation matrix
|
||||
|
||||
RotMatrix_gte(mesh->rot, &mat);
|
||||
|
||||
// Apply translation matrix
|
||||
|
||||
TransMatrix(&mat, mesh->pos);
|
||||
|
||||
// Compose matrix with cam
|
||||
|
||||
CompMatrix(&camera->mat, &mat, &mat);
|
||||
|
||||
// Set default rotation and translation matrices
|
||||
|
||||
SetRotMatrix(&mat);
|
||||
|
||||
SetTransMatrix(&mat);
|
||||
|
||||
//~ }
|
||||
};
|
||||
|
||||
// Drawing
|
||||
|
||||
void drawPoly(MESH * mesh, long * Flag, int atime, int * camMode, char ** nextpri, u_long * ot, char * db, DRAWENV * draw) {
|
||||
|
||||
long nclip, t = 0;
|
||||
|
||||
// mesh is POLY_GT3 ( triangle )
|
||||
|
||||
if (mesh->index[t].code == 4) {
|
||||
|
||||
POLY_GT3 * poly;
|
||||
|
||||
// len member == # vertices, but here it's # of triangle... So, for each tri * 3 vertices ...
|
||||
|
||||
for ( int i = 0; i < (mesh->tmesh->len * 3); i += 3 ) {
|
||||
|
||||
// If mesh is not part of precalculated background, draw them, else, discard
|
||||
|
||||
if ( !( *mesh->isBG ) || *camMode != 2) {
|
||||
|
||||
poly = (POLY_GT3 *)*nextpri;
|
||||
|
||||
// If Vertex Anim flag is set, use it
|
||||
|
||||
if (*mesh->isAnim){
|
||||
|
||||
// If interpolation flag is set, use it
|
||||
|
||||
if(mesh->anim->interpolate){
|
||||
|
||||
// Ping pong
|
||||
|
||||
//~ //if (mesh->anim->cursor > 4096 || mesh->anim->cursor < 0){
|
||||
|
||||
//~ // mesh->anim->dir *= -1;
|
||||
|
||||
//~ //}
|
||||
|
||||
|
||||
// Fixed point math precision
|
||||
|
||||
short precision = 12;
|
||||
|
||||
// Find next keyframe
|
||||
|
||||
if (mesh->anim->cursor > (1 << precision)) {
|
||||
|
||||
// There are still keyframes to interpolate between
|
||||
|
||||
if ( mesh->anim->lerpCursor < mesh->anim->nframes - 1 ) {
|
||||
|
||||
mesh->anim->lerpCursor ++;
|
||||
|
||||
mesh->anim->cursor = 0;
|
||||
|
||||
}
|
||||
|
||||
// We've reached last frame, go back to first frame
|
||||
|
||||
if ( mesh->anim->lerpCursor == mesh->anim->nframes - 1 ) {
|
||||
|
||||
mesh->anim->lerpCursor = 0;
|
||||
|
||||
mesh->anim->cursor = 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Let's lerp between keyframes
|
||||
|
||||
// TODO : Finish lerped animation implementation
|
||||
|
||||
// Vertex 1
|
||||
|
||||
mesh->tmesh->v[ mesh->index[ t ].order.vx ].vx = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vx].vx << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vx].vx << precision, mesh->anim->cursor << precision) >> precision;
|
||||
|
||||
mesh->tmesh->v[ mesh->index[ t ].order.vx ].vz = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vx].vz << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vx].vz << precision, mesh->anim->cursor << precision) >> precision;
|
||||
|
||||
mesh->tmesh->v[ mesh->index[ t ].order.vx ].vy = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vx].vy << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vx].vy << precision, mesh->anim->cursor << precision) >> precision;
|
||||
|
||||
// Vertex 2
|
||||
|
||||
mesh->tmesh->v[ mesh->index[ t ].order.vz ].vx = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vz].vx << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vz].vx << precision, mesh->anim->cursor << precision) >> precision;
|
||||
|
||||
mesh->tmesh->v[ mesh->index[ t ].order.vz ].vz = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vz].vz << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vz].vz << precision, mesh->anim->cursor << precision) >> precision;
|
||||
|
||||
mesh->tmesh->v[ mesh->index[ t ].order.vz ].vy = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vz].vy << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vz].vy << precision, mesh->anim->cursor << precision) >> precision;
|
||||
|
||||
// Vertex 3
|
||||
|
||||
mesh->tmesh->v[ mesh->index[ t ].order.vy ].vx = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vy].vx << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vy].vx << precision, mesh->anim->cursor << precision) >> precision;
|
||||
|
||||
mesh->tmesh->v[ mesh->index[ t ].order.vy ].vz = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vy].vz << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vy].vz << precision, mesh->anim->cursor << precision) >> precision;
|
||||
|
||||
mesh->tmesh->v[ mesh->index[ t ].order.vy ].vy = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vy].vy << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vy].vy << precision, mesh->anim->cursor << precision) >> precision;
|
||||
|
||||
mesh->anim->cursor += 24 * mesh->anim->dir;
|
||||
|
||||
// Coord transformation from world space to screen space
|
||||
|
||||
nclip = RotAverageNclip3(
|
||||
|
||||
&mesh->tmesh->v[ mesh->index[t].order.vx ],
|
||||
|
||||
&mesh->tmesh->v[ mesh->index[t].order.vz ],
|
||||
|
||||
&mesh->tmesh->v[ mesh->index[t].order.vy ],
|
||||
|
||||
( long* ) &poly->x0, ( long* ) &poly->x1, ( long* ) &poly->x2,
|
||||
|
||||
mesh->p,
|
||||
|
||||
mesh->OTz,
|
||||
|
||||
Flag
|
||||
);
|
||||
|
||||
} else {
|
||||
|
||||
// No interpolation
|
||||
|
||||
// Use the pre-calculated vertices coordinates from the animation data
|
||||
|
||||
nclip = RotAverageNclip3(
|
||||
|
||||
&mesh->anim->data[ atime % mesh->anim->nframes * mesh->anim->nvert + mesh->index[t].order.vx ],
|
||||
|
||||
&mesh->anim->data[ atime % mesh->anim->nframes * mesh->anim->nvert + mesh->index[t].order.vz ],
|
||||
|
||||
&mesh->anim->data[ atime % mesh->anim->nframes * mesh->anim->nvert + mesh->index[t].order.vy ],
|
||||
|
||||
( long* ) &poly->x0, ( long* ) &poly->x1, ( long* ) &poly->x2,
|
||||
|
||||
mesh->p,
|
||||
|
||||
mesh->OTz,
|
||||
|
||||
Flag
|
||||
);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// No animation
|
||||
|
||||
// Use model's regular vertex coordinates
|
||||
|
||||
nclip = RotAverageNclip3(
|
||||
|
||||
&mesh->tmesh->v[ mesh->index[t].order.vx ],
|
||||
|
||||
&mesh->tmesh->v[ mesh->index[t].order.vz ],
|
||||
|
||||
&mesh->tmesh->v[ mesh->index[t].order.vy ],
|
||||
|
||||
( long * ) &poly->x0, ( long * ) &poly->x1, ( long * ) &poly->x2,
|
||||
|
||||
mesh->p,
|
||||
|
||||
mesh->OTz,
|
||||
|
||||
Flag
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
// Do not draw invisible meshes
|
||||
|
||||
if ( nclip > 0 && *mesh->OTz > 0 && (*mesh->p < 4096) ) {
|
||||
|
||||
|
||||
SetPolyGT3( poly );
|
||||
|
||||
// If isPrism flag is set, use it
|
||||
|
||||
// FIXME : Doesn't work with pre-rendered BGs
|
||||
|
||||
if ( *mesh->isPrism ) {
|
||||
|
||||
// Transparency effect :
|
||||
|
||||
// Use current DRAWENV clip as TPAGE instead of regular textures
|
||||
|
||||
( (POLY_GT3 *) poly )->tpage = getTPage( mesh->tim->mode&0x3, 0,
|
||||
|
||||
draw->clip.x,
|
||||
|
||||
draw->clip.y
|
||||
);
|
||||
|
||||
// Use projected coordinates (results from RotAverage...) as UV coords and clamp them to 0-255,0-224 Why 224 though ?
|
||||
|
||||
setUV3(poly, (poly->x0 < 0 ? 0 : poly->x0 > 255 ? 255 : poly->x0),
|
||||
|
||||
(poly->y0 < 0 ? 0 : poly->y0 > 240 ? 240 : poly->y0),
|
||||
|
||||
(poly->x1 < 0 ? 0 : poly->x1 > 255 ? 255 : poly->x1),
|
||||
|
||||
(poly->y1 < 0 ? 0 : poly->y1 > 240 ? 240 : poly->y1),
|
||||
|
||||
(poly->x2 < 0 ? 0 : poly->x2 > 255 ? 255 : poly->x2),
|
||||
|
||||
(poly->y2 < 0 ? 0 : poly->y2 > 240 ? 240 : poly->y2)
|
||||
|
||||
);
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
// No transparency effect
|
||||
|
||||
// Use regular TPAGE
|
||||
|
||||
( (POLY_GT3 *) poly )->tpage = getTPage(mesh->tim->mode&0x3, 0,
|
||||
|
||||
mesh->tim->prect->x,
|
||||
|
||||
mesh->tim->prect->y
|
||||
);
|
||||
|
||||
setUV3(poly, mesh->tmesh->u[i].vx , mesh->tmesh->u[i].vy + mesh->tim->prect->y,
|
||||
|
||||
mesh->tmesh->u[i+2].vx, mesh->tmesh->u[i+2].vy + mesh->tim->prect->y,
|
||||
|
||||
mesh->tmesh->u[i+1].vx, mesh->tmesh->u[i+1].vy + mesh->tim->prect->y);
|
||||
}
|
||||
|
||||
// CLUT setup
|
||||
// If tim mode == 0 | 1 (4bits/8bits image), set CLUT coordinates
|
||||
|
||||
if ( (mesh->tim->mode & 0x3 ) < 2){
|
||||
|
||||
setClut(poly,
|
||||
|
||||
mesh->tim->crect->x,
|
||||
|
||||
mesh->tim->crect->y);
|
||||
}
|
||||
|
||||
if (*mesh->isSprite){
|
||||
|
||||
SetShadeTex( poly, 1 );
|
||||
|
||||
}
|
||||
// Defaults depth color to neutral grey
|
||||
|
||||
CVECTOR outCol = { 128,128,128,0 };
|
||||
|
||||
CVECTOR outCol1 = { 128,128,128,0 };
|
||||
|
||||
CVECTOR outCol2 = { 128,128,128,0 };
|
||||
|
||||
NormalColorDpq(&mesh->tmesh->n[ mesh->index[t].order.vx ], &mesh->tmesh->c[ mesh->index[t].order.vx ], *mesh->p, &outCol);
|
||||
|
||||
NormalColorDpq(&mesh->tmesh->n[ mesh->index[t].order.vz ], &mesh->tmesh->c[ mesh->index[t].order.vz ], *mesh->p, &outCol1);
|
||||
|
||||
NormalColorDpq(&mesh->tmesh->n[ mesh->index[t].order.vy ], &mesh->tmesh->c[ mesh->index[t].order.vy ], *mesh->p, &outCol2);
|
||||
|
||||
// If transparent effect is in use, inhibate shadows
|
||||
|
||||
if (*mesh->isPrism){
|
||||
|
||||
// Use un-interpolated (i.e: no light, no fog) colors
|
||||
|
||||
setRGB0(poly, mesh->tmesh->c[i].r, mesh->tmesh->c[i].g, mesh->tmesh->c[i].b);
|
||||
|
||||
setRGB1(poly, mesh->tmesh->c[i+1].r, mesh->tmesh->c[i+1].g, mesh->tmesh->c[i+1].b);
|
||||
|
||||
setRGB2(poly, mesh->tmesh->c[i+2].r, mesh->tmesh->c[i+2].g, mesh->tmesh->c[i+2].b);
|
||||
|
||||
} else {
|
||||
|
||||
setRGB0(poly, outCol.r, outCol.g , outCol.b);
|
||||
|
||||
setRGB1(poly, outCol1.r, outCol1.g, outCol1.b);
|
||||
|
||||
setRGB2(poly, outCol2.r, outCol2.g, outCol2.b);
|
||||
}
|
||||
|
||||
if ( (*mesh->OTz > 0) /*&& (*mesh->OTz < OTLEN)*/ && (*mesh->p < 4096) ) {
|
||||
|
||||
AddPrim(&ot[ *mesh->OTz-2 ], poly);
|
||||
}
|
||||
|
||||
//~ mesh->pos2D.vx = *(&poly->x0);
|
||||
//~ mesh->pos2D.vy = *(&poly->x0 + 1);
|
||||
// mesh->pos2D.vy = poly->x0;
|
||||
// FntPrint("%d %d\n", *(&poly->x0), *(&poly->x0 + 1));
|
||||
|
||||
*nextpri += sizeof(POLY_GT3);
|
||||
}
|
||||
|
||||
t+=1;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// If mesh is quad
|
||||
|
||||
if (mesh->index[t].code == 8) {
|
||||
|
||||
POLY_GT4 * poly4;
|
||||
|
||||
for (int i = 0; i < (mesh->tmesh->len * 4); i += 4) {
|
||||
|
||||
// if mesh is not part of BG, draw them, else, discard
|
||||
|
||||
if ( !(*mesh->isBG) || *camMode != 2 ) {
|
||||
|
||||
poly4 = (POLY_GT4 *)*nextpri;
|
||||
|
||||
// Vertex Anim
|
||||
|
||||
if (*mesh->isAnim){
|
||||
|
||||
// with interpolation
|
||||
|
||||
if ( mesh->anim->interpolate ){
|
||||
|
||||
// ping pong
|
||||
//~ if (mesh->anim->cursor > 4096 || mesh->anim->cursor < 0){
|
||||
//~ mesh->anim->dir *= -1;
|
||||
//~ }
|
||||
|
||||
short precision = 12;
|
||||
|
||||
if ( mesh->anim->cursor > 1<<precision ) {
|
||||
|
||||
if ( mesh->anim->lerpCursor < mesh->anim->nframes - 1 ) {
|
||||
|
||||
mesh->anim->lerpCursor ++;
|
||||
|
||||
mesh->anim->cursor = 0;
|
||||
|
||||
}
|
||||
|
||||
if ( mesh->anim->lerpCursor == mesh->anim->nframes - 1 ) {
|
||||
|
||||
mesh->anim->lerpCursor = 0;
|
||||
|
||||
mesh->anim->cursor = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Vertex 1
|
||||
|
||||
mesh->tmesh->v[ mesh->index[ t ].order.vx ].vx = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vx ].vx << 12 , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vx ].vx << 12, mesh->anim->cursor << 12) >> 12;
|
||||
|
||||
mesh->tmesh->v[ mesh->index[ t ].order.vx ].vz = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vx ].vz << 12 , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vx ].vz << 12, mesh->anim->cursor << 12) >> 12;
|
||||
|
||||
mesh->tmesh->v[ mesh->index[ t ].order.vx ].vy = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vx ].vy << 12 , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vx ].vy << 12, mesh->anim->cursor << 12) >> 12;
|
||||
|
||||
// Vertex 2
|
||||
|
||||
mesh->tmesh->v[ mesh->index[ t ].order.vz ].vx = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vz ].vx << 12 , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vz ].vx << 12, mesh->anim->cursor << 12) >> 12;
|
||||
|
||||
mesh->tmesh->v[ mesh->index[ t ].order.vz ].vz = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vz ].vz << 12 , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vz ].vz << 12, mesh->anim->cursor << 12) >> 12;
|
||||
|
||||
mesh->tmesh->v[ mesh->index[ t ].order.vz ].vy = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vz ].vy << 12 , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vz ].vy << 12, mesh->anim->cursor << 12) >> 12;
|
||||
|
||||
// Vertex 3
|
||||
|
||||
mesh->tmesh->v[ mesh->index[ t ].order.vy ].vx = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vy ].vx << 12 , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vy ].vx << 12, mesh->anim->cursor << 12) >> 12;
|
||||
|
||||
mesh->tmesh->v[ mesh->index[ t ].order.vy ].vz = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vy ].vz << 12 , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vy ].vz << 12, mesh->anim->cursor << 12) >> 12;
|
||||
|
||||
mesh->tmesh->v[ mesh->index[ t ].order.vy ].vy = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vy ].vy << 12 , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vy ].vy << 12, mesh->anim->cursor << 12) >> 12;
|
||||
|
||||
// Vertex 4
|
||||
|
||||
mesh->tmesh->v[ mesh->index[ t ].order.pad ].vx = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.pad ].vx << 12 , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.pad ].vx << 12, mesh->anim->cursor << 12) >> 12;
|
||||
|
||||
mesh->tmesh->v[ mesh->index[ t ].order.pad ].vz = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.pad ].vz << 12 , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.pad ].vz << 12, mesh->anim->cursor << 12) >> 12;
|
||||
|
||||
mesh->tmesh->v[ mesh->index[ t ].order.pad ].vy = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.pad ].vy << 12 , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.pad ].vy << 12, mesh->anim->cursor << 12) >> 12;
|
||||
|
||||
mesh->anim->cursor += 2 * mesh->anim->dir;
|
||||
|
||||
// Coord transformations
|
||||
nclip = RotAverageNclip4(
|
||||
|
||||
&mesh->tmesh->v[ mesh->index[t].order.pad ],
|
||||
|
||||
&mesh->tmesh->v[ mesh->index[t].order.vz],
|
||||
|
||||
&mesh->tmesh->v[ mesh->index[t].order.vx ],
|
||||
|
||||
&mesh->tmesh->v[ mesh->index[t].order.vy ],
|
||||
|
||||
( long* )&poly4->x0, ( long* )&poly4->x1, ( long* )&poly4->x2, ( long* )&poly4->x3,
|
||||
|
||||
mesh->p,
|
||||
|
||||
mesh->OTz,
|
||||
|
||||
Flag
|
||||
|
||||
);
|
||||
|
||||
} else {
|
||||
|
||||
// No interpolation, use all vertices coordinates in anim data
|
||||
|
||||
nclip = RotAverageNclip4(
|
||||
|
||||
&mesh->anim->data[ atime % mesh->anim->nframes * mesh->anim->nvert + mesh->index[t].order.pad ],
|
||||
|
||||
&mesh->anim->data[ atime % mesh->anim->nframes * mesh->anim->nvert + mesh->index[t].order.vz ],
|
||||
|
||||
&mesh->anim->data[ atime % mesh->anim->nframes * mesh->anim->nvert + mesh->index[t].order.vx ],
|
||||
|
||||
&mesh->anim->data[ atime % mesh->anim->nframes * mesh->anim->nvert + mesh->index[t].order.vy ],
|
||||
|
||||
( long* )&poly4->x0, ( long* )&poly4->x1, ( long* )&poly4->x2, ( long* )&poly4->x3,
|
||||
|
||||
mesh->p,
|
||||
|
||||
mesh->OTz,
|
||||
|
||||
Flag
|
||||
);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// No animation
|
||||
// Use regulare vertex coords
|
||||
|
||||
nclip = RotAverageNclip4(
|
||||
|
||||
&mesh->tmesh->v[ mesh->index[t].order.pad ],
|
||||
|
||||
&mesh->tmesh->v[ mesh->index[t].order.vz],
|
||||
|
||||
&mesh->tmesh->v[ mesh->index[t].order.vx ],
|
||||
|
||||
&mesh->tmesh->v[ mesh->index[t].order.vy ],
|
||||
|
||||
(long*)&poly4->x0, (long*)&poly4->x1, (long*)&poly4->x2, (long*)&poly4->x3,
|
||||
|
||||
mesh->p,
|
||||
|
||||
mesh->OTz,
|
||||
|
||||
Flag
|
||||
);
|
||||
}
|
||||
|
||||
if (nclip > 0 && *mesh->OTz > 0 && (*mesh->p < 4096)) {
|
||||
|
||||
SetPolyGT4(poly4);
|
||||
|
||||
// FIXME : Polygon subdiv - is it working ?
|
||||
|
||||
//~ OTc = *mesh->OTz >> 4;
|
||||
//~ FntPrint("OTC:%d", OTc);
|
||||
|
||||
//~ if (OTc < 4) {
|
||||
|
||||
//~ if (OTc > 1) div4.ndiv = 1; else div4.ndiv = 2;
|
||||
|
||||
//~ DivideGT4(
|
||||
//~ // Vertex coord
|
||||
//~ &mesh->tmesh->v[ mesh->index[t].order.pad ],
|
||||
//~ &mesh->tmesh->v[ mesh->index[t].order.vz ],
|
||||
//~ &mesh->tmesh->v[ mesh->index[t].order.vx ],
|
||||
//~ &mesh->tmesh->v[ mesh->index[t].order.vy ],
|
||||
//~ // UV coord
|
||||
//~ mesh->tmesh->u[i+3],
|
||||
//~ mesh->tmesh->u[i+2],
|
||||
//~ mesh->tmesh->u[i+0],
|
||||
//~ mesh->tmesh->u[i+1],
|
||||
|
||||
//~ // Color
|
||||
//~ mesh->tmesh->c[i],
|
||||
//~ mesh->tmesh->c[i+1],
|
||||
//~ mesh->tmesh->c[i+2],
|
||||
//~ mesh->tmesh->c[i+3],
|
||||
|
||||
//~ // Gpu packet
|
||||
//~ poly4,
|
||||
//~ &ot[db][*mesh->OTz],
|
||||
//~ &div4);
|
||||
|
||||
//~ // Increment primitive list pointer
|
||||
//~ *nextpri += ( (sizeof(POLY_GT4) + 3) / 4 ) * (( 1 << ( div4.ndiv )) << ( div4.ndiv ));
|
||||
//~ triCount = ((1<<(div4.ndiv))<<(div4.ndiv));
|
||||
|
||||
//~ } else if (OTc < 48) {
|
||||
|
||||
// Transparency effect
|
||||
|
||||
if (*mesh->isPrism){
|
||||
|
||||
// Use current DRAWENV clip as TPAGE
|
||||
|
||||
( (POLY_GT4 *) poly4)->tpage = getTPage(mesh->tim->mode&0x3, 0,
|
||||
|
||||
draw->clip.x,
|
||||
|
||||
draw->clip.y
|
||||
);
|
||||
|
||||
// Use projected coordinates
|
||||
|
||||
setUV4( poly4,
|
||||
|
||||
(poly4->x0 < 0? 0 : poly4->x0 > 255? 255 : poly4->x0),
|
||||
|
||||
(poly4->y0 < 0? 0 : poly4->y0 > 224? 224 : poly4->y0),
|
||||
|
||||
(poly4->x1 < 0? 0 : poly4->x1 > 255? 255 : poly4->x1),
|
||||
|
||||
(poly4->y1 < 0? 0 : poly4->y1 > 224? 224 : poly4->y1),
|
||||
|
||||
(poly4->x2 < 0? 0 : poly4->x2 > 255? 255 : poly4->x2),
|
||||
|
||||
(poly4->y2 < 0? 0 : poly4->y2 > 224? 224 : poly4->y2),
|
||||
|
||||
(poly4->x3 < 0? 0 : poly4->x3 > 255? 255 : poly4->x3),
|
||||
|
||||
(poly4->y3 < 0? 0 : poly4->y3 > 224? 224 : poly4->y3)
|
||||
);
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
// Use regular TPAGE
|
||||
( (POLY_GT4 *) poly4)->tpage = getTPage(
|
||||
|
||||
mesh->tim->mode&0x3, 0,
|
||||
|
||||
mesh->tim->prect->x,
|
||||
|
||||
mesh->tim->prect->y
|
||||
);
|
||||
|
||||
// Use model UV coordinates
|
||||
|
||||
setUV4( poly4,
|
||||
mesh->tmesh->u[i+3].vx, mesh->tmesh->u[i+3].vy + mesh->tim->prect->y,
|
||||
|
||||
mesh->tmesh->u[i+2].vx, mesh->tmesh->u[i+2].vy + mesh->tim->prect->y,
|
||||
|
||||
mesh->tmesh->u[i+0].vx, mesh->tmesh->u[i+0].vy + mesh->tim->prect->y,
|
||||
|
||||
mesh->tmesh->u[i+1].vx, mesh->tmesh->u[i+1].vy + mesh->tim->prect->y
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
if (*mesh->isSprite){
|
||||
|
||||
SetShadeTex( poly4, 1 );
|
||||
|
||||
}
|
||||
|
||||
// If tim mode == 0 | 1, set CLUT coordinates
|
||||
if ( (mesh->tim->mode & 0x3) < 2 ) {
|
||||
|
||||
setClut(poly4,
|
||||
|
||||
mesh->tim->crect->x,
|
||||
|
||||
mesh->tim->crect->y
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
CVECTOR outCol = {128,128,128,0};
|
||||
|
||||
CVECTOR outCol1 = {128,128,128,0};
|
||||
|
||||
CVECTOR outCol2 = {128,128,128,0};
|
||||
|
||||
CVECTOR outCol3 = {128,128,128,0};
|
||||
|
||||
NormalColorDpq(&mesh->tmesh->n[ mesh->index[t].order.pad ] , &mesh->tmesh->c[ mesh->index[t].order.pad ], *mesh->p, &outCol);
|
||||
|
||||
NormalColorDpq(&mesh->tmesh->n[ mesh->index[t].order.vz ], &mesh->tmesh->c[ mesh->index[t].order.vz ], *mesh->p, &outCol1);
|
||||
|
||||
NormalColorDpq(&mesh->tmesh->n[ mesh->index[t].order.vx ], &mesh->tmesh->c[ mesh->index[t].order.vx ], *mesh->p, &outCol2);
|
||||
|
||||
NormalColorDpq(&mesh->tmesh->n[ mesh->index[t].order.vy ], &mesh->tmesh->c[ mesh->index[t].order.vy ], *mesh->p, &outCol3);
|
||||
|
||||
if (*mesh->isPrism){
|
||||
|
||||
setRGB0(poly4, mesh->tmesh->c[i].r, mesh->tmesh->c[i].g, mesh->tmesh->c[i].b);
|
||||
|
||||
setRGB1(poly4, mesh->tmesh->c[i+1].r, mesh->tmesh->c[i+1].g, mesh->tmesh->c[i+1].b);
|
||||
|
||||
setRGB2(poly4, mesh->tmesh->c[i+2].r, mesh->tmesh->c[i+2].g, mesh->tmesh->c[i+2].b);
|
||||
|
||||
setRGB3(poly4, mesh->tmesh->c[i+3].r, mesh->tmesh->c[i+3].g, mesh->tmesh->c[i+3].b);
|
||||
|
||||
} else {
|
||||
|
||||
setRGB0(poly4, outCol.r, outCol.g , outCol.b);
|
||||
|
||||
setRGB1(poly4, outCol1.r, outCol1.g, outCol1.b);
|
||||
|
||||
setRGB2(poly4, outCol2.r, outCol2.g, outCol2.b);
|
||||
|
||||
setRGB3(poly4, outCol3.r, outCol3.g, outCol3.b);
|
||||
}
|
||||
|
||||
if ( (*mesh->OTz > 0) /*&& (*mesh->OTz < OTLEN)*/ && (*mesh->p < 4096) ) {
|
||||
|
||||
AddPrim( &ot[ *mesh->OTz-3 ], poly4 );
|
||||
}
|
||||
|
||||
*nextpri += sizeof( POLY_GT4 );
|
||||
|
||||
}
|
||||
|
||||
t += 1;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
void drawBG(CAMANGLE * camPtr, char ** nextpri, u_long * otdisc, char * db) {
|
||||
|
||||
// Draw BG image in two SPRT since max width == 256 px
|
||||
|
||||
SPRT * sprt;
|
||||
|
||||
DR_TPAGE * tpage;
|
||||
|
||||
// Left part
|
||||
|
||||
sprt = ( SPRT * ) *nextpri;
|
||||
|
||||
setSprt( sprt );
|
||||
|
||||
setRGB0( sprt, 128, 128, 128 );
|
||||
|
||||
setXY0( sprt, 0, 0 );
|
||||
|
||||
setWH( sprt, 256, SCREENYRES );
|
||||
|
||||
setUV0( sprt, 0, 0 );
|
||||
|
||||
setClut( sprt,
|
||||
|
||||
camPtr->BGtim->crect->x,
|
||||
|
||||
camPtr->BGtim->crect->y
|
||||
|
||||
);
|
||||
|
||||
addPrim( otdisc[ OT2LEN - 1 ], sprt );
|
||||
|
||||
*nextpri += sizeof( SPRT );
|
||||
|
||||
|
||||
// Change TPAGE
|
||||
|
||||
tpage = (DR_TPAGE *) *nextpri;
|
||||
|
||||
setDrawTPage(
|
||||
|
||||
tpage, 0, 1,
|
||||
|
||||
getTPage(
|
||||
|
||||
camPtr->BGtim->mode & 0x3, 0,
|
||||
|
||||
camPtr->BGtim->prect->x,
|
||||
|
||||
camPtr->BGtim->prect->y
|
||||
|
||||
)
|
||||
|
||||
);
|
||||
|
||||
addPrim( otdisc[OT2LEN-1], tpage);
|
||||
|
||||
*nextpri += sizeof(DR_TPAGE);
|
||||
|
||||
|
||||
// Right part
|
||||
|
||||
sprt = ( SPRT * ) *nextpri;
|
||||
|
||||
setSprt( sprt );
|
||||
|
||||
setRGB0( sprt, 128, 128, 128 );
|
||||
|
||||
setXY0( sprt, SCREENXRES - ( SCREENXRES - 256 ), 0 );
|
||||
|
||||
setWH( sprt, SCREENXRES - 256, SCREENYRES );
|
||||
|
||||
setUV0( sprt, 0, 0 );
|
||||
|
||||
setClut( sprt,
|
||||
|
||||
camPtr->BGtim->crect->x,
|
||||
|
||||
camPtr->BGtim->crect->y
|
||||
);
|
||||
|
||||
addPrim( otdisc[ OT2LEN-1 ], sprt );
|
||||
|
||||
*nextpri += sizeof( SPRT );
|
||||
|
||||
tpage = ( DR_TPAGE * ) *nextpri;
|
||||
|
||||
// Change TPAGE
|
||||
|
||||
setDrawTPage(
|
||||
|
||||
tpage, 0, 1,
|
||||
|
||||
getTPage(
|
||||
|
||||
camPtr->BGtim->mode & 0x3, 0,
|
||||
|
||||
// X offset width depends on TIM's mode
|
||||
|
||||
camPtr->BGtim->prect->x + ( 64 << ( camPtr->BGtim->mode & 0x3 ) ),
|
||||
|
||||
camPtr->BGtim->prect->y
|
||||
|
||||
)
|
||||
|
||||
);
|
||||
|
||||
addPrim( otdisc[ OT2LEN-1 ], tpage );
|
||||
|
||||
*nextpri += sizeof( DR_TPAGE );
|
||||
|
||||
};
|
28
graphics.h
Normal file
28
graphics.h
Normal file
@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
//~ #include <sys/types.h>
|
||||
//~ #include <libgte.h>
|
||||
//~ #include <libgpu.h>
|
||||
|
||||
//~ #include "psx.h"
|
||||
#include "camera.h"
|
||||
#include "physics.h"
|
||||
#include "defines.h"
|
||||
|
||||
//~ int camMode = 0;
|
||||
|
||||
//~ #define SCREENXRES 320
|
||||
|
||||
//~ #define SCREENYRES 240
|
||||
|
||||
//~ #define OT2LEN 8
|
||||
|
||||
//~ #define OTLEN 256
|
||||
|
||||
// Drawing
|
||||
|
||||
void transformMesh(CAMERA * camera, MESH * meshes);
|
||||
|
||||
void drawPoly(MESH * mesh, long * Flag, int atime, int * camMode, char ** nextpri, u_long * ot, char * db, DRAWENV * draw);
|
||||
|
||||
void drawBG(CAMANGLE * camPtr, char ** nextpri, u_long * otdisc, char * db);
|
34
macros.h
Normal file
34
macros.h
Normal file
@ -0,0 +1,34 @@
|
||||
// MACROS
|
||||
|
||||
// swap(x, y, buffer)
|
||||
|
||||
#define SWAP(a,b,c) {(c)=(a); (a)=(b); (b)=(c);}
|
||||
|
||||
// dotproduct of two vectors
|
||||
|
||||
#define dotProduct(v0, v1) \
|
||||
(v0).vx * (v1).vx + \
|
||||
(v0).vy * (v1).vy + \
|
||||
(v0).vz * (v1).vz
|
||||
|
||||
// min value
|
||||
|
||||
#define min(a,b) \
|
||||
(a)-(b)>0?(b):(a)
|
||||
// max
|
||||
|
||||
#define max(a,b) \
|
||||
(a)-(b)>0?(a):(b)
|
||||
|
||||
// substract vector
|
||||
|
||||
#define subVector(v0, v1) \
|
||||
(v0).vx - (v1).vx, \
|
||||
(v0).vy - (v1).vy, \
|
||||
(v0).vz - (v1).vz
|
||||
|
||||
|
||||
#define normalizeVector(v) \
|
||||
((v)->vx << 12) >> 8, \
|
||||
((v)->vy << 12) >> 8, \
|
||||
((v)->vz << 12) >> 8
|
267
math.c
Normal file
267
math.c
Normal file
@ -0,0 +1,267 @@
|
||||
#include "math.h"
|
||||
|
||||
// Stolen from grumpycoder
|
||||
|
||||
static int m_cosTable[512]; // precalc costable
|
||||
|
||||
static const unsigned int DC_2PI = 2048; // this is from here : https://github.com/grumpycoders/Balau/blob/master/tests/test-Handles.cc#L20-L102
|
||||
|
||||
static const unsigned int DC_PI = 1024;
|
||||
|
||||
static const unsigned int DC_PI2 = 512;
|
||||
|
||||
// f(n) = cos(n * 2pi / 2048) <- 2048 is == DC_2PI value
|
||||
// f(n) = 2 * f(1) * f(n - 1) - f(n - 2)
|
||||
void generateTable(void){
|
||||
|
||||
m_cosTable[0] = 16777216; // 2^24 * cos(0 * 2pi / 2048) => 2^24 * 1 = 2^24 : here, 2^24 defines the precision we want after the decimal point
|
||||
|
||||
static const long long C = 16777137; // 2^24 * cos(1 * 2pi / 2048) = C = f(1);
|
||||
|
||||
m_cosTable[1] = C;
|
||||
|
||||
for (int i = 2; i < 512; i++){
|
||||
|
||||
m_cosTable[i] = ((C * m_cosTable[i - 1]) >> 23) - m_cosTable[i - 2];
|
||||
|
||||
m_cosTable[511] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
// A few notes on the following code :
|
||||
|
||||
int ncos(unsigned int t) {
|
||||
|
||||
t %= DC_2PI;
|
||||
|
||||
int r;
|
||||
|
||||
if (t < DC_PI2) {
|
||||
|
||||
r = m_cosTable[t];
|
||||
|
||||
} else if (t < DC_PI) {
|
||||
|
||||
r = -m_cosTable[DC_PI - 1 - t];
|
||||
|
||||
} else if (t < (DC_PI + DC_PI2)) {
|
||||
|
||||
r = -m_cosTable[t - DC_PI];
|
||||
|
||||
} else {
|
||||
|
||||
r = m_cosTable[DC_2PI - 1 - t];
|
||||
|
||||
};
|
||||
|
||||
return r >> 12;
|
||||
};
|
||||
|
||||
// sin(x) = cos(x - pi / 2)
|
||||
int nsin(unsigned int t) {
|
||||
|
||||
t %= DC_2PI;
|
||||
|
||||
if (t < DC_PI2){
|
||||
|
||||
return ncos(t + DC_2PI - DC_PI2);
|
||||
|
||||
};
|
||||
|
||||
return ncos(t - DC_PI2);
|
||||
};
|
||||
|
||||
|
||||
|
||||
// https://github.com/Arsunt/TR2Main/blob/411cacb35914c616cb7960c0e677e00c71c7ee88/3dsystem/phd_math.cpp#L432
|
||||
long long patan(long x, long y){
|
||||
|
||||
long long result;
|
||||
|
||||
int swapBuf;
|
||||
|
||||
int flags = 0;
|
||||
|
||||
// if either x or y are 0, return 0
|
||||
|
||||
if( x == 0 && y == 0){
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
if( x < 0 ) {
|
||||
|
||||
flags |= 4;
|
||||
|
||||
x = -x;
|
||||
|
||||
}
|
||||
|
||||
if ( y < 0 ) {
|
||||
|
||||
flags |= 2;
|
||||
|
||||
y = -y;
|
||||
|
||||
}
|
||||
|
||||
if ( y > x ) {
|
||||
|
||||
flags |= 1;
|
||||
|
||||
SWAP(x, y ,swapBuf);
|
||||
|
||||
}
|
||||
|
||||
result = AtanBaseTable[flags] + AtanAngleTable[0x800 * y / x];
|
||||
|
||||
if ( result < 0 ){
|
||||
|
||||
result = -result;
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
u_int psqrt(u_int n){
|
||||
|
||||
u_int result = 0;
|
||||
|
||||
u_int base = 0x40000000;
|
||||
|
||||
u_int basedResult;
|
||||
|
||||
for( ; base != 0; base >>= 2 ) {
|
||||
|
||||
for( ; base != 0; base >>= 2 ) {
|
||||
|
||||
basedResult = base + result;
|
||||
|
||||
result >>= 1;
|
||||
|
||||
if( basedResult > n ) {
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
n -= basedResult;
|
||||
|
||||
result |= base;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
// From : https://github.com/grumpycoders/pcsx-redux/blob/7438e9995833db5bc1e14da735bbf9dc78300f0b/src/mips/shell/math.h
|
||||
int32_t dMul(int32_t a, int32_t b) {
|
||||
|
||||
long long r = a;
|
||||
|
||||
r *= b;
|
||||
|
||||
return r >> 24;
|
||||
|
||||
};
|
||||
|
||||
// standard lerp function
|
||||
// s = source, an arbitrary number up to 2^24
|
||||
// d = destination, an arbitrary number up to 2^24
|
||||
// p = position, a number between 0 and 256, inclusive
|
||||
// p = 0 means output = s
|
||||
// p = 256 means output = d
|
||||
|
||||
uint32_t lerpU(uint32_t start, uint32_t dest, unsigned pos) {
|
||||
|
||||
return (start * (256 - pos) + dest * pos) >> 8;
|
||||
|
||||
};
|
||||
|
||||
int32_t lerpS(int32_t start, int32_t dest, unsigned pos) {
|
||||
|
||||
return (start * (256 - pos) + dest * pos) >> 8;
|
||||
|
||||
};
|
||||
|
||||
// start, dest and pos have to be << x, then the result has to be >> x where x defines precision:
|
||||
// precision = 2^24 - 2^x
|
||||
// << x : 0 < pos < precision
|
||||
// https://discord.com/channels/642647820683444236/646765703143227394/811318550978494505
|
||||
// my angles are between 0 and 2048 (full circle), so 2^11 for the range of angles; with numbers on a 8.24 representation, a 1.0 angle (or 2pi) means it's 2^24, so to "convert" my angles from 8.24 to my internal discrete cos, I only have to shift by 13
|
||||
|
||||
int32_t lerpD(int32_t start, int32_t dest, int32_t pos) {
|
||||
|
||||
return dMul(start, 16777216 - pos) + dMul(dest, pos);
|
||||
|
||||
};
|
||||
|
||||
long long lerpL(long long start, long long dest, long long pos) {
|
||||
|
||||
return dMul( (start << 12), 16777216 - (pos << 12) ) + dMul((dest << 12), (pos << 12) ) >> 12;
|
||||
|
||||
};
|
||||
|
||||
int lerp(int start, int end, int factor){
|
||||
|
||||
// lerp interpolated cam movement
|
||||
// InBetween = Value 1 + ( ( Value2 - Value1 ) * lerpValue ) ;
|
||||
// lerpValue should be a float between 0 and 1.
|
||||
|
||||
|
||||
return ( start ) + (( end - start ) * factor ) >> 12;
|
||||
|
||||
};
|
||||
|
||||
long long easeIn(long long i){
|
||||
|
||||
return ((i << 7) * (i << 7) * (i << 7) / 32 ) >> 19;
|
||||
|
||||
};
|
||||
|
||||
int easeOut(int i){
|
||||
|
||||
return (4096 >> 7) - ((4096 - (i << 7)) * (4096 - (i << 7))) >> 12;
|
||||
|
||||
};
|
||||
|
||||
//~ int easeInOut(int i, int div){
|
||||
|
||||
//~ return lerp(easeIn(i, div), easeOut(i) , i);
|
||||
|
||||
//~ };
|
||||
|
||||
SVECTOR SVlerp(SVECTOR start, SVECTOR end, int factor){
|
||||
|
||||
SVECTOR output = {0,0,0,0};
|
||||
|
||||
output.vx = lerp(start.vx, end.vx, factor);
|
||||
|
||||
output.vy = lerp(start.vy, end.vy, factor);
|
||||
|
||||
output.vz = lerp(start.vz, end.vz, factor);
|
||||
|
||||
return output;
|
||||
|
||||
};
|
||||
|
||||
VECTOR getVectorTo( VECTOR actor, VECTOR target ) {
|
||||
|
||||
VECTOR direction = { subVector(target, actor) };
|
||||
|
||||
VECTOR Ndirection = {0,0,0,0};
|
||||
|
||||
u_int distSq = (direction.vx * direction.vx) + (direction.vz * direction.vz);
|
||||
|
||||
direction.pad = psqrt(distSq);
|
||||
|
||||
VectorNormal(&direction, &Ndirection);
|
||||
|
||||
return Ndirection ;
|
||||
|
||||
};
|
53
math.h
Normal file
53
math.h
Normal file
@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <libgte.h>
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
// Precalculated arctan values
|
||||
|
||||
#include "atan.c"
|
||||
|
||||
// fixed point math
|
||||
|
||||
int32_t dMul(int32_t a, int32_t b);
|
||||
|
||||
uint32_t lerpU(uint32_t start, uint32_t dest, unsigned pos);
|
||||
|
||||
int32_t lerpS(int32_t start, int32_t dest, unsigned pos);
|
||||
|
||||
int32_t lerpD(int32_t start, int32_t dest, int32_t pos);
|
||||
|
||||
long long lerpL(long long start, long long dest, long long pos);
|
||||
|
||||
// Sin/Cos Table
|
||||
|
||||
void generateTable(void);
|
||||
|
||||
int ncos(u_int t);
|
||||
|
||||
int nsin(u_int t);
|
||||
|
||||
// Atan table
|
||||
|
||||
long long patan(long x, long y);
|
||||
|
||||
// Sqrt
|
||||
|
||||
u_int psqrt(u_int n);
|
||||
|
||||
// Lerps
|
||||
|
||||
int lerp(int start, int end, int factor); // FIXME : not working as it should
|
||||
|
||||
SVECTOR SVlerp(SVECTOR start, SVECTOR end, int factor); // FIXME
|
||||
|
||||
long long easeIn(long long i);
|
||||
|
||||
int easeOut(int i);
|
||||
|
||||
//~ int easeInOut(int i, int div);
|
||||
|
||||
VECTOR getVectorTo(VECTOR actor, VECTOR target);
|
313
physics.c
Normal file
313
physics.c
Normal file
@ -0,0 +1,313 @@
|
||||
#include "physics.h"
|
||||
|
||||
short checkLineW( VECTOR * pointA, VECTOR * pointB, MESH * mesh ) {
|
||||
|
||||
long val1 = ( ( mesh->body->position.vx + mesh->body->min.vx ) - pointA->vx ) * ( pointB->vy - pointA->vy ) - ( ( mesh->body->position.vz + mesh->body->min.vy ) - pointA->vy ) * ( pointB->vx - pointA->vx ) ;
|
||||
|
||||
long val2 = ( ( mesh->body->position.vx + mesh->body->max.vx ) - pointA->vx ) * ( pointB->vy - pointA->vy ) - ( ( mesh->body->position.vz + mesh->body->max.vy ) - pointA->vy ) * ( pointB->vx - pointA->vx ) ;
|
||||
|
||||
if ( val1 > 0 && val2 > 0 ) {
|
||||
|
||||
// right
|
||||
return 1;
|
||||
}
|
||||
|
||||
else if ( val1 < 0 && val2 < 0 ) {
|
||||
|
||||
// left
|
||||
return -1;
|
||||
}
|
||||
|
||||
else if ( val1 == 0 && val2 == 0 ) {
|
||||
|
||||
// identical
|
||||
return 0;
|
||||
}
|
||||
|
||||
else if (
|
||||
|
||||
( val1 > 0 && val2 == 0 ) ||
|
||||
|
||||
( val1 == 0 && val2 > 0 )
|
||||
|
||||
) {
|
||||
|
||||
// right
|
||||
return 1;
|
||||
}
|
||||
|
||||
else if (
|
||||
|
||||
( val1 < 0 && val2 == 0 ) ||
|
||||
|
||||
( val1 == 0 && val2 < 0 )
|
||||
|
||||
) {
|
||||
|
||||
// left
|
||||
return -1;
|
||||
}
|
||||
|
||||
else if (
|
||||
|
||||
( val1 < 0 && val2 > 0 ) ||
|
||||
|
||||
( val1 > 0 && val2 < 0 )
|
||||
|
||||
) {
|
||||
|
||||
// intersect
|
||||
return 3;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Screen space variant
|
||||
short checkLineS( VECTOR * pointA, VECTOR * pointB, MESH * mesh ) {
|
||||
|
||||
// FIXME : mesh->body->min.vx is not in screen space
|
||||
|
||||
int val1 = ( ( mesh->pos2D.vx + mesh->body->min.vx ) - pointA->vx ) * ( pointB->vy - pointA->vy ) - ( ( mesh->pos2D.vy + mesh->body->min.vy ) - pointA->vy ) * ( pointB->vx - pointA->vx ) ;
|
||||
|
||||
int val2 = ( ( mesh->pos2D.vx + mesh->body->max.vx ) - pointA->vx ) * ( pointB->vy - pointA->vy ) - ( ( mesh->pos2D.vy + mesh->body->max.vy ) - pointA->vy ) * ( pointB->vx - pointA->vx ) ;
|
||||
|
||||
if ( val1 > 0 && val2 > 0 ) {
|
||||
|
||||
// right
|
||||
return 1;
|
||||
}
|
||||
|
||||
else if ( val1 < 0 && val2 < 0 ) {
|
||||
|
||||
// left
|
||||
return -1;
|
||||
}
|
||||
|
||||
else if ( val1 == 0 && val2 == 0 ) {
|
||||
|
||||
// identical
|
||||
return 2;
|
||||
}
|
||||
|
||||
else if (
|
||||
|
||||
( val1 > 0 && val2 == 0 ) ||
|
||||
|
||||
( val1 == 0 && val2 > 0 )
|
||||
|
||||
) {
|
||||
|
||||
// right
|
||||
return 1;
|
||||
}
|
||||
|
||||
else if (
|
||||
|
||||
( val1 < 0 && val2 == 0 ) ||
|
||||
|
||||
( val1 == 0 && val2 < 0 )
|
||||
|
||||
) {
|
||||
|
||||
// left
|
||||
return -1;
|
||||
}
|
||||
|
||||
else if (
|
||||
|
||||
( val1 < 0 && val2 > 0 ) ||
|
||||
|
||||
( val1 > 0 && val2 < 0 )
|
||||
|
||||
) {
|
||||
|
||||
// intersect
|
||||
return 3;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Physics
|
||||
|
||||
VECTOR getIntCollision(BODY one, BODY two){
|
||||
|
||||
VECTOR d1, d2, col;
|
||||
|
||||
short correction = 50;
|
||||
|
||||
d1.vx = (one.position.vx + one.max.vx) - (two.position.vx + two.min.vx);
|
||||
|
||||
d1.vy = (one.position.vy + one.max.vy) - (two.position.vy + two.min.vy);
|
||||
|
||||
d1.vz = (one.position.vz + one.max.vz) - (two.position.vz + two.min.vz);
|
||||
|
||||
|
||||
d2.vx = (two.position.vx + two.max.vx) - (one.position.vx - one.max.vx);
|
||||
|
||||
d2.vy = (two.position.vy + two.max.vy) - (one.position.vy + one.min.vy);
|
||||
|
||||
d2.vz = (two.position.vz + two.max.vz) - (one.position.vz - one.max.vz);
|
||||
|
||||
|
||||
col.vx = !(d1.vx > 0 && d2.vx > 0);
|
||||
|
||||
col.vy = d1.vy > 0 && d2.vy > 0;
|
||||
|
||||
col.vz = !(d1.vz > 0 && d2.vz > 0);
|
||||
|
||||
return col;
|
||||
|
||||
};
|
||||
|
||||
VECTOR getExtCollision(BODY one, BODY two){
|
||||
|
||||
VECTOR d1, d2, col;
|
||||
|
||||
d1.vx = (one.position.vx + one.max.vx) - (two.position.vx + two.min.vx);
|
||||
|
||||
d1.vy = (one.position.vy + one.max.vy) - (two.position.vy + two.min.vy);
|
||||
|
||||
d1.vz = (one.position.vz + one.max.vz) - (two.position.vz + two.min.vz);
|
||||
|
||||
|
||||
d2.vx = (two.position.vx + two.max.vx) - (one.position.vx + one.min.vx);
|
||||
|
||||
d2.vy = (two.position.vy + two.max.vy) - (one.position.vy + one.min.vy);
|
||||
|
||||
d2.vz = (two.position.vz + two.max.vz) - (one.position.vz + one.min.vz);
|
||||
|
||||
|
||||
col.vx = d1.vx > 0 && d2.vx > 0;
|
||||
|
||||
col.vy = d1.vy > 0 && d2.vy > 0;
|
||||
|
||||
col.vz = d1.vz > 0 && d2.vz > 0;
|
||||
|
||||
|
||||
return col;
|
||||
|
||||
};
|
||||
|
||||
void applyAcceleration(BODY * actor){
|
||||
|
||||
short dt = 1;
|
||||
|
||||
VECTOR acceleration = {actor->invMass * actor->gForce.vx , (actor->invMass * actor->gForce.vy) + (GRAVITY * ONE), actor->invMass * actor->gForce.vz};
|
||||
|
||||
//~ FntPrint("acc: %d %d %d\n", acceleration.vx, acceleration.vy, acceleration.vz );
|
||||
|
||||
actor->velocity.vx += (acceleration.vx * dt) >> 12;
|
||||
|
||||
actor->velocity.vy += (acceleration.vy * dt) >> 12;
|
||||
|
||||
actor->velocity.vz += (acceleration.vz * dt) >> 12;
|
||||
|
||||
//~ FntPrint("acc: %d %d %d\n", acceleration.vx / ONE, acceleration.vy / ONE, acceleration.vz / ONE );
|
||||
|
||||
actor->position.vx += (actor->velocity.vx * dt);
|
||||
|
||||
actor->position.vy += (actor->velocity.vy * dt);
|
||||
|
||||
actor->position.vz += (actor->velocity.vz * dt);
|
||||
|
||||
//~ FntPrint("vel: %d %d %d\n", actor->velocity.vx, actor->velocity.vy, actor->velocity.vz );
|
||||
|
||||
};
|
||||
|
||||
//~ // https://gamedevelopment.tutsplus.com/tutorials/how-to-create-a-custom-2d-physics-engine-the-basics-and-impulse-resolution--gamedev-6331
|
||||
|
||||
void ResolveCollision( BODY * one, BODY * two ){
|
||||
|
||||
//~ FntPrint("rv: %d, %d, %d\n", one->velocity.vx, one->velocity.vy, one->velocity.vz);
|
||||
|
||||
// Calculate relative velocity
|
||||
|
||||
VECTOR rv = { subVector( one->velocity, two->velocity) };
|
||||
|
||||
//~ FntPrint("rv: %d, %d, %d\n", rv.vx,rv.vy,rv.vz);
|
||||
|
||||
// Collision normal
|
||||
|
||||
VECTOR normal = { subVector( two->position, one->position ) };
|
||||
|
||||
// Normalize collision normal
|
||||
|
||||
normal.vx = normal.vx > 0 ? 1 : normal.vx < 0 ? -1 : 0 ;
|
||||
|
||||
normal.vy = normal.vy > 256 ? 1 : normal.vy < -256 ? -1 : 0 ;
|
||||
|
||||
normal.vz = normal.vz > 0 ? 1 : normal.vz < 0 ? -1 : 0 ;
|
||||
|
||||
//~ FntPrint("norm: %d, %d, %d\n", normal.vx,normal.vy,normal.vz);
|
||||
|
||||
// Calculate relative velocity in terms of the normal direction
|
||||
|
||||
long velAlongNormal = dotProduct( rv, normal );
|
||||
|
||||
//~ FntPrint("velN: %d\n", velAlongNormal);
|
||||
|
||||
// Do not resolve if velocities are separating
|
||||
|
||||
if(velAlongNormal > 0)
|
||||
|
||||
return;
|
||||
|
||||
// Calculate restitution
|
||||
long e = min( one->restitution, two->restitution );
|
||||
|
||||
//~ FntPrint("e: %d\n", e);
|
||||
|
||||
//~ // Calculate impulse scalar
|
||||
long j = -(1 + e) * velAlongNormal * ONE;
|
||||
|
||||
j /= one->invMass + two->invMass;
|
||||
//~ j /= ONE;
|
||||
|
||||
//~ FntPrint("j: %d\n", j);
|
||||
|
||||
// Apply impulse
|
||||
applyVector(&normal, j, j, j, *=);
|
||||
|
||||
//~ FntPrint("Cnormal %d %d %d\n",normal.vx,normal.vy,normal.vz);
|
||||
|
||||
VECTOR velOne = normal;
|
||||
|
||||
VECTOR velTwo = normal;
|
||||
|
||||
applyVector(&velOne,one->invMass,one->invMass,one->invMass, *=);
|
||||
|
||||
applyVector(&velTwo,two->invMass,two->invMass,two->invMass, *=);
|
||||
|
||||
//~ FntPrint("V1 %d %d %d\n", velOne.vx/4096,velOne.vy/4096,velOne.vz/4096);
|
||||
//~ FntPrint("V2 %d %d %d\n", velTwo.vx/4096,velTwo.vy/4096,velTwo.vz/4096);
|
||||
|
||||
applyVector(&one->velocity, velOne.vx/4096/4096, velOne.vy/4096/4096, velOne.vz/4096/4096, +=);
|
||||
|
||||
applyVector(&two->velocity, velTwo.vx/4096/4096, velTwo.vy/4096/4096, velTwo.vz/4096/4096, -=);
|
||||
|
||||
//~ FntPrint("V1 %d %d %d\n", velOne.vx/4096/4096,velOne.vy/4096/4096,velOne.vz/4096/4096);
|
||||
//~ FntPrint("V2 %d %d %d\n", velTwo.vx/4096/4096,velTwo.vy/4096/4096,velTwo.vz/4096/4096);
|
||||
|
||||
};
|
||||
|
||||
VECTOR angularMom(BODY body){
|
||||
|
||||
// L = r * p
|
||||
|
||||
// p = m * v
|
||||
|
||||
VECTOR w = {0,0,0,0};
|
||||
|
||||
int r = (body.max.vx - body.min.vx) >> 1;
|
||||
|
||||
w.vx = (r * body.mass * body.velocity.vx) >> 2;
|
||||
|
||||
w.vy = (r * body.mass * body.velocity.vy) >> 2;
|
||||
|
||||
w.vz = (r * body.mass * body.velocity.vz) >> 2;
|
||||
|
||||
//~ FntPrint("v: %d, r:%d, w:%d\n", body.velocity.vz * r, r * r, w.vz);
|
||||
|
||||
return w;
|
||||
|
||||
};
|
27
physics.h
Normal file
27
physics.h
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include <sys/types.h>
|
||||
//~ #include <stddef.h>
|
||||
//~ #include <stdint.h>
|
||||
#include <libgte.h>
|
||||
#include <libgpu.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
#include "coridor2.h"
|
||||
|
||||
short checkLineW( VECTOR * pointA, VECTOR * pointB, MESH * mesh );
|
||||
|
||||
short checkLineS( VECTOR * pointA, VECTOR * pointB, MESH * mesh );
|
||||
|
||||
VECTOR getIntCollision(BODY one, BODY two);
|
||||
|
||||
VECTOR getExtCollision(BODY one, BODY two);
|
||||
|
||||
void ResolveCollision( BODY * one, BODY * two );
|
||||
|
||||
VECTOR angularMom(BODY body);
|
||||
|
||||
void applyAcceleration(BODY * actor);
|
117
psx.c
Normal file
117
psx.c
Normal file
@ -0,0 +1,117 @@
|
||||
#include "psx.h"
|
||||
|
||||
void init(DISPENV disp[2], DRAWENV draw[2], short db, MATRIX * cmat, CVECTOR * BGc, VECTOR * BKc) {
|
||||
|
||||
ResetCallback();
|
||||
|
||||
// Reset the GPU before doing anything and the controller
|
||||
|
||||
ResetGraph(0);
|
||||
|
||||
PadInit(0);
|
||||
|
||||
// Initialize and setup the GTE
|
||||
|
||||
InitGeom();
|
||||
|
||||
SetGeomOffset( CENTERX, CENTERY ); // x, y offset
|
||||
|
||||
SetGeomScreen( FOV ); // Distance between eye and screen - Camera FOV
|
||||
|
||||
// Set the display and draw environments
|
||||
|
||||
SetDefDispEnv(&disp[0], 0, 0 , SCREENXRES, SCREENYRES);
|
||||
|
||||
SetDefDispEnv(&disp[1], 0, SCREENYRES, SCREENXRES, SCREENYRES);
|
||||
|
||||
|
||||
SetDefDrawEnv(&draw[0], 0, SCREENYRES, SCREENXRES, SCREENYRES);
|
||||
|
||||
SetDefDrawEnv(&draw[1], 0, 0, SCREENXRES, SCREENYRES);
|
||||
|
||||
|
||||
// If PAL
|
||||
|
||||
if ( VMODE ) {
|
||||
|
||||
SetVideoMode(MODE_PAL);
|
||||
|
||||
disp[0].screen.y += 8;
|
||||
|
||||
disp[1].screen.y += 8;
|
||||
}
|
||||
|
||||
// Set Draw area color
|
||||
|
||||
setRGB0(&draw[0], BGc->r, BGc->g, BGc->b);
|
||||
|
||||
setRGB0(&draw[1], BGc->r, BGc->g, BGc->b);
|
||||
|
||||
// Set Draw area clear flag
|
||||
|
||||
draw[0].isbg = 1;
|
||||
|
||||
draw[1].isbg = 1;
|
||||
|
||||
// Set the disp and draw env
|
||||
|
||||
PutDispEnv(&disp[db]);
|
||||
|
||||
PutDrawEnv(&draw[db]);
|
||||
|
||||
// Init font system
|
||||
|
||||
FntLoad(FNT_POS_X, FNT_POS_Y);
|
||||
|
||||
FntOpen(16, 90, 240, 180, 0, 512);
|
||||
|
||||
// Lighting setup
|
||||
|
||||
SetColorMatrix(cmat);
|
||||
|
||||
SetBackColor(BKc->vx,BKc->vy,BKc->vz);
|
||||
|
||||
SetFarColor(BGc->r, BGc->g, BGc->b);
|
||||
|
||||
SetFogNearFar(1200, 1600, SCREENXRES);
|
||||
|
||||
};
|
||||
|
||||
void display(DISPENV * disp, DRAWENV * draw, u_long * otdisc, char * primbuff, char ** nextprim, char * db){
|
||||
|
||||
// https://stackoverflow.com/questions/3526503/how-to-set-pointer-reference-through-a-function
|
||||
|
||||
//~ //DrawSync(0);
|
||||
|
||||
VSync(2); // Using VSync 2 insures constant framerate. 0 makes the fr polycount dependant.
|
||||
|
||||
ResetGraph(1);
|
||||
|
||||
PutDispEnv(disp);
|
||||
|
||||
PutDrawEnv(draw);
|
||||
|
||||
SetDispMask(1);
|
||||
|
||||
// Main OT
|
||||
DrawOTag(otdisc + OT2LEN - 1);
|
||||
|
||||
*db = !*db;
|
||||
|
||||
*nextprim = primbuff;
|
||||
|
||||
};
|
||||
|
||||
void LoadTexture(u_long * tim, TIM_IMAGE * tparam){ // This part is from Lameguy64's tutorial series : lameguy64.net/svn/pstutorials/chapter1/3-textures.html login/pw: annoyingmous
|
||||
OpenTIM(tim); // Open the tim binary data, feed it the address of the data in memory
|
||||
ReadTIM(tparam); // This read the header of the TIM data and sets the corresponding members of the TIM_IMAGE structure
|
||||
|
||||
LoadImage(tparam->prect, tparam->paddr); // Transfer the data from memory to VRAM at position prect.x, prect.y
|
||||
DrawSync(0); // Wait for the drawing to end
|
||||
|
||||
if (tparam->mode & 0x8){ // check 4th bit // If 4th bit == 1, TIM has a CLUT
|
||||
LoadImage(tparam->crect, tparam->caddr); // Load it to VRAM at position crect.x, crect.y
|
||||
DrawSync(0); // Wait for drawing to end
|
||||
}
|
||||
|
||||
};
|
18
psx.h
Normal file
18
psx.h
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <libgte.h>
|
||||
#include <libgpu.h>
|
||||
#include <libetc.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
// PSX setup
|
||||
|
||||
void init(DISPENV disp[2], DRAWENV draw[2], short db, MATRIX * cmat, CVECTOR * BG, VECTOR * BK );
|
||||
|
||||
void display(DISPENV * disp, DRAWENV * draw, u_long * otdisc, char * primbuff, char ** nextprim, char * db);
|
||||
|
||||
// Utils
|
||||
|
||||
void LoadTexture(u_long * tim, TIM_IMAGE * tparam);
|
97
space.c
Normal file
97
space.c
Normal file
@ -0,0 +1,97 @@
|
||||
#include "space.h"
|
||||
|
||||
// From 'psyq/addons/graphics/ZIMEN/CLIP.C'
|
||||
|
||||
void worldToScreen( VECTOR * worldPos, VECTOR * screenPos ) {
|
||||
|
||||
int distToScreen; // corresponds to FOV
|
||||
|
||||
MATRIX curRot; // current rotation matrix
|
||||
|
||||
// Get current matrix and projection */
|
||||
|
||||
distToScreen = ReadGeomScreen();
|
||||
|
||||
ReadRotMatrix(&curRot);
|
||||
|
||||
// Get Rotation, Translation coordinates, apply perspective correction
|
||||
|
||||
// Muliply world coordinates vector by current rotation matrix, store in screenPos
|
||||
|
||||
ApplyMatrixLV(&curRot, worldPos, screenPos);
|
||||
|
||||
// Get world translation vectors from rot and add to screenPos vx, vy, vz
|
||||
|
||||
applyVector(screenPos, curRot.t[0], curRot.t[1], curRot.t[2], +=);
|
||||
|
||||
// Correct perspective
|
||||
|
||||
screenPos -> vx = screenPos -> vx * distToScreen / ( screenPos -> vz + 1 ) ; // Add 1 to avoid division by 0
|
||||
|
||||
screenPos -> vy = screenPos -> vy * distToScreen / ( screenPos -> vz + 1 ) ;
|
||||
|
||||
screenPos -> vz = distToScreen ;
|
||||
|
||||
};
|
||||
|
||||
void screenToWorld( VECTOR * screenPos, VECTOR * worldPos ) {
|
||||
|
||||
int distToScreen; // corresponds to FOV
|
||||
|
||||
MATRIX curRot, invRot; // current rotation matrix, transpose matrix
|
||||
|
||||
VECTOR Trans; // working translation vector
|
||||
|
||||
// Get current matrix and projection
|
||||
|
||||
distToScreen = ReadGeomScreen();
|
||||
|
||||
ReadRotMatrix( &curRot );
|
||||
|
||||
PushMatrix(); // Store matrix on the stack (slow!)
|
||||
|
||||
//// worldTrans = invRot * (screenPos - Rot.t)
|
||||
|
||||
// Get world translation
|
||||
|
||||
Trans.vx = screenPos->vx - curRot.t[0]; // Substract world translation from screenpos
|
||||
|
||||
Trans.vy = screenPos->vy - curRot.t[1];
|
||||
|
||||
Trans.vz = screenPos->vz - curRot.t[2];
|
||||
|
||||
|
||||
// We want the inverse of the current rotation matrix.
|
||||
//
|
||||
// Inverse matrix : M^-1 = 1 / detM * T(M)
|
||||
// We know that the determinant of a rotation matrix is 1, thus:
|
||||
// M^-1 = T(M)
|
||||
//
|
||||
// Get transpose of current rotation matrix
|
||||
// > The transpose of a matrix is a new matrix whose rows are the columns of the original.
|
||||
// https://www.quora.com/What-is-the-geometric-interpretation-of-the-transpose-of-a-matrix
|
||||
|
||||
TransposeMatrix( &curRot, &invRot );
|
||||
|
||||
// Multiply the transpose of current rotation matrix by the current translation vector
|
||||
|
||||
ApplyMatrixLV( &invRot, &Trans, worldPos );
|
||||
|
||||
// Get original rotation matrix back
|
||||
|
||||
PopMatrix();
|
||||
|
||||
};
|
||||
|
||||
int cliptest3( short *v1 ) {
|
||||
|
||||
if( v1[0]<0 && v1[2]<0 && v1[4]<0 ) return 0;
|
||||
|
||||
if( v1[1]<0 && v1[3]<0 && v1[5]<0 ) return 0;
|
||||
|
||||
if( v1[0] > SCREENXRES && v1[2] > SCREENXRES && v1[4] > SCREENXRES) return 0;
|
||||
|
||||
if( v1[1] > SCREENYRES && v1[3] > SCREENYRES && v1[5] > SCREENYRES) return 0;
|
||||
|
||||
return 1;
|
||||
};
|
Loading…
Reference in New Issue
Block a user