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;
|
||||
|
||||
};
|
||||
|
||||