#12 - GTE opti: Move all work matrices to scratchpad, use inline GTE

This commit is contained in:
ABelliqueux 2021-07-10 12:08:52 +02:00
parent 6e9ef23a2c
commit dfa903087e
13 changed files with 1367 additions and 1235 deletions

68
include/CPUMAC.H Normal file
View File

@ -0,0 +1,68 @@
/*
** cpumac.h
mike acton
*/
// cpu_ldr(cpu register,data pointer)
// copy 32bit data from dp to r
#define cpu_ldr(r,dp)\
asm(\
"lw %0, 0(%1);"\
: "=r" (r)\
: "r" (dp)\
)
// cpu_gted0(cpu register)
// copy 32bit data from r to gte register 0
#define cpu_gted0(r)\
asm(\
"mtc2 %0, $0;"\
:\
: "r" (r)\
)
// cpu_gted1(cpu register)
// copy 32bit data from r to gte register 1
#define cpu_gted1(r)\
asm(\
"mtc2 %0, $1;"\
:\
: "r" (r)\
)
// cpu_gted2(cpu register)
// copy 32bit data from r to gte register 2
#define cpu_gted2(r)\
asm(\
"mtc2 %0, $2;"\
:\
: "r" (r)\
)
// cpu_gted3(cpu register)
// copy 32bit data from r to gte register 3
#define cpu_gted3(r)\
asm(\
"mtc2 %0, $3;"\
:\
: "r" (r)\
)
// cpu_gted4(cpu register)
// copy 32bit data from r to gte register 4
#define cpu_gted4(r)\
asm(\
"mtc2 %0, $4;"\
:\
: "r" (r)\
)
// cpu_gted5(cpu register)
// copy 32bit data from r to gte register 5
#define cpu_gted5(r)\
asm(\
"mtc2 %0, $5;"\
:\
: "r" (r)\
)

View File

@ -17,14 +17,14 @@ typedef struct{
int pan, panv;
int tilt, tiltv;
int rol;
SVECTOR pos;
SVECTOR rot;
SVECTOR * pos;
SVECTOR * rot;
SVECTOR dvs;
MATRIX mat;
MATRIX * mat;
} CAMERA;
void getCameraXZ(int * x, int * z, int actorX, int actorZ, int angle, int distance);
void getCameraXZY(int * x, int * z, int * y, int actorX, int actorZ, int actorY, int angle, int angleX, int distance);
void getCameraZY( int * z, int * y, int actorZ, int actorY, int angleX, int distance);
void applyCamera(CAMERA * cam);
void setCameraPos(CAMERA * camera, SVECTOR pos, SVECTOR rot);
void setCameraPos(CAMERA * camera, SVECTOR * pos, SVECTOR * rot);

Binary file not shown.

View File

@ -1,5 +1,5 @@
#define VMODE 0 // 0 == NTSC, 1 == PAL
#define VSYNC 0
#define VSYNC 1
#define SCREENXRES 320
#define SCREENYRES 240
#define CENTERX SCREENXRES/2
@ -16,7 +16,7 @@
#define FNT_SCR_X 16
#define FNT_SCR_Y 192
#define FNT_SCR_W 240
#define FNT_SCR_H 32
#define FNT_SCR_H 48
#define FNT_SCR_BG 0
#define FNT_SCR_MAX_CHAR 256
@ -25,6 +25,33 @@
#define OTLEN 4096
#define PRIMBUFFLEN 4096 * sizeof(POLY_GT4) // Maximum number of POLY_GT4 primitives
#define cpu_uldr(r,dp) \
asm(\
"sw %0, 0(%1);" \
: "=r" (r)\
: "r" (dp)\
)
// DCache setup
#define dc_camdirp ((sshort*) getScratchAddr(0))
#define dc_ip ((uchar*) getScratchAddr(1))
#define dc_opzp ((slong*) getScratchAddr(2))
#define dc_wrkmatp ((MATRIX*) getScratchAddr(3))
#define dc_retmatp ((MATRIX*) getScratchAddr(9))
#define dc_lgtmatp ((MATRIX*) getScratchAddr(12))
#define dc_lvllgtmatp ((MATRIX*) getScratchAddr(16))
#define dc_lvlcmatp ((MATRIX*) getScratchAddr(24))
#define dc_lgtangp ((SVECTOR*) getScratchAddr(32))
#define dc_wrklvector ((VECTOR*) getScratchAddr(34))
#define dc_camMat ((MATRIX*) getScratchAddr(38))
#define dc_camRot ((SVECTOR*) getScratchAddr(46))
#define dc_camPos ((SVECTOR*) getScratchAddr(54))
//~ #define dc_sxytbl ((DVECTOR*) getScratchAddr(15)) // 6 DVEC == 12
//~ #define dc_verts ((SVECTOR*) getScratchAddr(27)) // store verts here
//~ #define dc_verts1 ((SVECTOR*) getScratchAddr(35)) // store verts here
//~ #define dc_verts2 ((SVECTOR*) getScratchAddr(43)) // store verts here
// Fog
#define FOG_NEAR 2300
#define FOG_FAR 2600

View File

@ -6,19 +6,19 @@
// Drawing
void transformMesh(CAMERA * camera, MESH * meshes);
void enlightMesh(LEVEL * curLvl, MESH * actorPtr, SVECTOR * lgtang);
void drawPoly(MESH * mesh, long * Flag, int atime, int * camMode, char ** nextpri, u_long * ot, char * db, DRAWENV * draw);
void drawPoly(MESH * mesh, int atime, int * camMode, char ** nextpri, u_long * ot, char * db, DRAWENV * draw);
// Tri drawing
long drawTri(MESH * mesh, long * Flag, int atime, int * camMode, char ** nextpri, u_long * ot, char * db, DRAWENV * draw, int t, int i);
long drawTri(MESH * mesh, int atime, int * camMode, char ** nextpri, u_long * ot, char * db, DRAWENV * draw, int t, int i);
void set3VertexLerPos(MESH * mesh, long t);
void set3Prism(POLY_GT3 * poly, MESH * mesh, DRAWENV * draw, char * db, int i);
void set3Tex(POLY_GT3 * poly, MESH * mesh, DRAWENV * draw, long t, int i);
long interpolateTri(POLY_GT3 * poly, MESH * mesh, long t, long * Flag);
long interpolateTri(POLY_GT3 * poly, MESH * mesh, long t);
//Quad drawing
long drawQuad(MESH * mesh, long * Flag, int atime, int * camMode, char ** nextpri, u_long * ot, char * db, DRAWENV * draw, int t, int i);
long drawQuad(MESH * mesh, int atime, int * camMode, char ** nextpri, u_long * ot, char * db, DRAWENV * draw, int t, int i);
void set4VertexLerPos(MESH * mesh, long t);
void set4Prism(POLY_GT4 * poly4, MESH * mesh, DRAWENV * draw, char * db, int i);
void set4Tex(POLY_GT4 * poly4, MESH * mesh, DRAWENV * draw, long t, int i);
int set4Subdiv(MESH * mesh, POLY_GT4 * poly4, u_long * ot, long t, int i, char ** nextpri);
long interpolateQuad(POLY_GT4 * poly4, MESH * mesh, long t, long * Flag);
long interpolateQuad(POLY_GT4 * poly4, MESH * mesh, long t);
//2D drawing
void drawBG(CAMANGLE * camPtr, char ** nextpri, u_long * otdisc, char * db);

BIN
include/macros Normal file

Binary file not shown.

View File

@ -34,17 +34,15 @@
// GTE Macros
#define gte_RotAverageNclip4(r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12) \
{ gte_ldv3(r1,r2,r3); \
gte_rtpt(); \
gte_stflg(r11); \
gte_nclip(); \
gte_stopz(r12); \
gte_stsxy3(r5,r6,r7); \
\
gte_ldv0(r4); \
gte_rtps(); \
gte_stsxy(r8); \
\
gte_stdp(r9); \
gte_avsz4(); \
gte_stotz(r10); }
{ gte_ldv3(r1,r2,r3); \
gte_rtpt(); \
gte_stflg(r11); \
gte_nclip(); \
gte_ldv0(r4); \
gte_stopz(r12); \
gte_stsxy3(r5,r6,r7); \
gte_rtps(); \
gte_stsxy(r8); \
gte_stdp(r9); \
gte_avsz4(); \
gte_stotz(r10); }

View File

@ -6,14 +6,16 @@
#include <libgpu.h>
#include <libapi.h>
#include <libcd.h>
#include <string.h>
#include <inline_n.h>
#include <gtemac.h>
#include "../include/defines.h"
#include "../custom_types.h"
// PSX setup
void setLightEnv(DRAWENV draw[2], CVECTOR * BGc, VECTOR * BKc, MATRIX * cmat);
void init(DISPENV disp[2], DRAWENV draw[2], short db, MATRIX * cmat, CVECTOR * BG, VECTOR * BK, VECTOR * FC );
void setDCLightEnv(MATRIX * curLevelCMat, MATRIX * curLevelLgtMat, SVECTOR * curLevelLgtAng);
void setLightEnv(DRAWENV draw[2], CVECTOR * BGc, VECTOR * BKc);
void init(DISPENV disp[2], DRAWENV draw[2], short db, CVECTOR * BG, VECTOR * BK, VECTOR * FC );
void ScrRst(void);
void display(DISPENV * disp, DRAWENV * draw, u_long * otdisc, char * primbuff, char ** nextprim, char * db);

File diff suppressed because it is too large Load Diff

View File

@ -21,14 +21,14 @@ void getCameraZY( int * z, int * y, int actorZ, int actorY, int angleX, int dist
};
// @Will : you might want to use sin/cos to move the camera in a circle but you could do that by moving it along its 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)
gte_ApplyMatrix(&cam->mat, &cam->pos, &vec); // Multiply matrix by vector pos and output to vec
TransMatrix(&cam->mat, &vec); // Apply transform vector
gte_SetRotMatrix(&cam->mat); // Set Rotation matrix
gte_SetTransMatrix(&cam->mat); // Set Transform matrix
//~ VECTOR vec; // Vector that holds the output values of the following instructions
RotMatrix_gte(dc_camRot, dc_camMat); // Convert rotation angle in psx units (360° == 4096) to rotation matrix)
gte_ApplyMatrix(dc_camMat, dc_camPos, dc_wrklvector); // Multiply matrix by vector pos and output to vec
TransMatrix(dc_camMat, dc_wrklvector); // Apply transform vector
gte_SetRotMatrix(dc_camMat); // Set Rotation matrix
gte_SetTransMatrix(dc_camMat); // Set Transform matrix
};
void setCameraPos( CAMERA * camera, SVECTOR pos, SVECTOR rot ) {
camera->pos = pos;
camera->rot = rot;
void setCameraPos( CAMERA * camera, SVECTOR * pos, SVECTOR * rot ) {
copyVector(camera->pos, pos);
copyVector(camera->rot, rot);
};

View File

@ -1,41 +1,66 @@
#include "../include/psx.h"
#include "../include/graphics.h"
#include "../include/math.h"
#include "../include/CPUMAC.H"
// Declare registers 16 19 23
//~ register ulong ur0 asm("$16");
//~ register ulong ur1 asm("$19");
//~ register ulong ur2 asm("$20");
//~ register ulong ur3 asm("$23");
//~ register ulong ur4 asm("$21");
//~ register ulong ur5 asm("$22");
void enlightMesh(LEVEL * curLvl, MESH * mesh, SVECTOR * lgtang){
// Update light rotation on actor
MATRIX rotlgt, rotmesh, light;
//~ MATRIX rotlgt, rotmesh, light;
// Find rotmat from actor angle
RotMatrix_gte(&mesh->rot, &rotmesh);
RotMatrix_gte(lgtang, &rotlgt);
gte_MulMatrix0(&rotmesh, &rotlgt, &rotlgt);
gte_MulMatrix0(curLvl->lgtmat, &rotlgt, &light);
gte_SetLightMatrix(&light);
RotMatrix_gte(&mesh->rot, dc_wrkmatp);
RotMatrix_gte(lgtang, dc_retmatp);
gte_MulMatrix0(dc_wrkmatp, dc_retmatp, dc_retmatp);
gte_MulMatrix0(curLvl->lgtmat, dc_retmatp, dc_retmatp);
gte_SetLightMatrix(dc_retmatp);
};
void transformMesh(CAMERA * camera, MESH * mesh){
MATRIX mat;
//~ MATRIX mat;
// Find rotation matrix
RotMatrix_gte(&mesh->rot, &mat);
RotMatrix_gte(&mesh->rot, dc_wrkmatp);
// Find translation matrix
TransMatrix(&mat, &mesh->pos);
TransMatrix(dc_wrkmatp, &mesh->pos);
// Compose matrix with cam
gte_CompMatrix(&camera->mat, &mat, &mat);
gte_CompMatrix(dc_camMat, dc_wrkmatp, dc_wrkmatp);
//gte_MulMatrix0(&camera->mat, &mat, &mat);
//~ gte_SetRotMatrix(&camera->mat);
//~ gte_ldclmv(&mat);
//~ gte_rtir();
//~ gte_stclmv(&mat);
//~ gte_ldclmv((char*)&mat+2);
//~ gte_rtir();
//~ gte_stclmv((char*)&mat+2);
//~ gte_ldclmv((char*)&mat+4);
//~ gte_rtir();
//~ gte_stclmv((char*)&mat+4);
//~ //
//~ gte_SetTransMatrix(&camera->mat);
//~ gte_ldlv0((char*)&mat+20);
//~ gte_rt();
//~ gte_stlvnl((char*)&mat+20);
// Set default rotation and translation matrices
gte_SetRotMatrix(&mat);
gte_SetTransMatrix(&mat);
gte_SetRotMatrix(dc_wrkmatp);
gte_SetTransMatrix(dc_wrkmatp);
//~ }
};
void drawPoly(MESH * mesh, long * Flag, int atime, int * camMode, char ** nextpri, u_long * ot, char * db, DRAWENV * draw) {
long nclip, t = 0;
void drawPoly(MESH * mesh, int atime, int * camMode, char ** nextpri, u_long * ot, char * db, DRAWENV * draw) {
long t = 0;
// mesh is POLY_GT3 ( triangle )
for (int i = 0; i < (mesh->totalVerts) && (mesh->totalVerts - i) > 2;) {
if (mesh->index[t].code == 4) {
t = drawTri(mesh, Flag, atime, camMode, nextpri, ot, db, draw, t, i);
t = drawTri(mesh, atime, camMode, nextpri, ot, db, draw, t, i);
i += 3;
}
// If mesh is quad
if (mesh->index[t].code == 8) {
t = drawQuad(mesh, Flag, atime, camMode, nextpri, ot, db, draw, t, i);
t = drawQuad(mesh, atime, camMode, nextpri, ot, db, draw, t, i);
i += 4;
}
}
@ -81,8 +106,8 @@ void set4VertexLerPos(MESH * mesh, long t){
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 << precision , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.pad ].vy << precision, mesh->anim->cursor << precision) >> precision;
mesh->anim->cursor += 2 * mesh->anim->dir;
}
long interpolateTri(POLY_GT3 * poly, MESH * mesh, long t, long * Flag){
long nclip = 0;
long interpolateTri(POLY_GT3 * poly, MESH * mesh, long t){
long Flag, nclip = 0;
// Ping pong
//~ //if (mesh->anim->cursor > 4096 || mesh->anim->cursor < 0){
//~ // mesh->anim->dir *= -1;
@ -115,8 +140,8 @@ long interpolateTri(POLY_GT3 * poly, MESH * mesh, long t, long * Flag){
);
return nclip;
};
long interpolateQuad(POLY_GT4 * poly4, MESH * mesh, long t, long * Flag){
long nclip = 0;
long interpolateQuad(POLY_GT4 * poly4, MESH * mesh, long t){
long Flag, nclip = 0;
// ping pong
//~ if (mesh->anim->cursor > 4096 || mesh->anim->cursor < 0){
//~ mesh->anim->dir *= -1;
@ -297,8 +322,8 @@ int set4Subdiv(MESH * mesh, POLY_GT4 * poly4, u_long * ot, long t, int i, char *
//~ }
return 0;
};
long drawQuad(MESH * mesh, long * Flag, int atime, int * camMode, char ** nextpri, u_long * ot, char * db, DRAWENV * draw, int t, int i) {
long nclip = 0;
long drawQuad(MESH * mesh, int atime, int * camMode, char ** nextpri, u_long * ot, char * db, DRAWENV * draw, int t, int i) {
long Flag, nclip = 0;
int subSkip = 0;
// If mesh is quad
POLY_GT4 * poly4;
@ -311,7 +336,7 @@ long drawQuad(MESH * mesh, long * Flag, int atime, int * camMode, char ** nextpr
if (mesh->isAnim){
// with interpolation
if ( mesh->anim->interpolate ){
interpolateQuad(poly4, mesh, t, Flag);
interpolateQuad(poly4, mesh, t);
} else {
// No interpolation, use all vertices coordinates in anim data
gte_RotAverageNclip4(
@ -338,7 +363,6 @@ long drawQuad(MESH * mesh, long * Flag, int atime, int * camMode, char ** nextpr
gte_SetRotMatrix(&invRot);
}
// Use regular vertex coords
gte_RotAverageNclip4(
&mesh->tmesh->v[ mesh->index[t].order.pad ],
&mesh->tmesh->v[ mesh->index[t].order.vz],
@ -382,8 +406,8 @@ long drawQuad(MESH * mesh, long * Flag, int atime, int * camMode, char ** nextpr
}
//~ }
};
long drawTri(MESH * mesh, long * Flag, int atime, int * camMode, char ** nextpri, u_long * ot, char * db, DRAWENV * draw, int t, int i) {
long nclip = 0;
long drawTri(MESH * mesh, int atime, int * camMode, char ** nextpri, u_long * ot, char * db, DRAWENV * draw, int t, int i) {
long Flag, nclip = 0;
// mesh is POLY_GT3 ( triangle )
POLY_GT3 * poly;
// len member == # vertices, but here it's # of triangle... So, for each tri * 3 vertices ...
@ -395,7 +419,7 @@ long drawTri(MESH * mesh, long * Flag, int atime, int * camMode, char ** nextpri
if (mesh->isAnim){
// If interpolation flag is set, use it
if(mesh->anim->interpolate){
nclip = interpolateTri(poly, mesh, t, Flag);
nclip = interpolateTri(poly, mesh, t);
} else {
// No interpolation
// Use the pre-calculated vertices coordinates from the animation data
@ -414,22 +438,24 @@ long drawTri(MESH * mesh, long * Flag, int atime, int * camMode, char ** nextpri
// No animation
if (mesh->isSprite){
// Find inverse rotation matrix so that sprite always faces camera
MATRIX rot, invRot;
gte_ReadRotMatrix(&rot);
TransposeMatrix(&rot, &invRot);
//~ MATRIX rot, invRot;
// Use scratchpad dc_wrkmatp and dc_retmatp
gte_ReadRotMatrix(dc_wrkmatp);
TransposeMatrix(dc_wrkmatp, dc_retmatp);
//~ SetMulRotMatrix(&invRot);
gte_MulMatrix0(&rot, &invRot, &invRot);
gte_SetRotMatrix(&invRot);
gte_MulMatrix0(dc_wrkmatp, dc_retmatp, dc_retmatp);
gte_SetRotMatrix(dc_retmatp);
}
// Use model's regular vertex coordinates
nclip = RotAverageNclip3(
gte_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
&Flag,
&nclip
);
}
// Do not draw invisible meshes
@ -454,7 +480,7 @@ long drawTri(MESH * mesh, long * Flag, int atime, int * camMode, char ** nextpri
set3Tex(poly, mesh, draw, t, i);
}
if ( (mesh->OTz > 0) /*&& (*mesh->OTz < OTLEN)*/ && (mesh->p < 4096) ) {
AddPrim(&ot[ mesh->OTz-2 ], poly);
AddPrim(&ot[ mesh->OTz-4 ], poly);
}
*nextpri += sizeof(POLY_GT3);
}

View File

@ -25,7 +25,7 @@
#include "../include/graphics.h"
#include "../include/space.h"
#define USECD
//~ #define USECD
// START OVERLAY
extern u_long load_all_overlays_here;
@ -37,7 +37,7 @@ u_long overlaySize = 0;
#include "../levels/level1.h"
// Levels
volatile u_char level = 1;
u_char level = 1;
u_short levelWas = 0;
u_short levelHasChanged = 0;
// Overlay
@ -57,7 +57,7 @@ char db = 0; // Current buffer counter
CVECTOR BGc = {128, 128, 128, 0}; // Default Far color - This can be set in each level.
VECTOR BKc = {128, 128, 128, 0}; // Back color
VECTOR FC = FOG_COLOR; // Far (Fog) color
SVECTOR lgtang = {0, 0, 0};
SVECTOR lgtang = {0, 0, 0};
MATRIX rotlgt, light;
short vs;
CAMERA camera = {0};
@ -76,37 +76,24 @@ VECTOR angleCam = {0,0,0,0};
int dist = 150;
int lerping = 0;
short curCamAngle = 0;
// Inverted Cam coordinates for Forward Vector calc
VECTOR InvCamPos = {0,0,0,0};
// Actor's forward vector (used for dualshock)
VECTOR fVecActor = {0,0,0,0};
u_long triCount = 0;
// Default level : Initialize everything to 0
MATRIX cmat = {0}, lgtmat = {0};
MESH actorPtr = {0}, levelPtr = {0} , propPtr = {0}, meshes[] = {0};
int meshes_length = 0;
NODE curNode = {0};
CAMPATH camPath = {0};
CAMANGLE camPtr = {0}, camAngles[] = {0};
LEVEL curLvl = {
&BGc,
&BKc,
&cmat,
&lgtmat,
(MESH **)&meshes,
&meshes_length,
&actorPtr,
&levelPtr,
&propPtr,
&camPtr,
&camPath,
(CAMANGLE **)&camAngles,
&curNode
};
LEVEL curLvl = {0};
LEVEL * loadLvl;
// Callback variables
u_short lastPad;
int lerpValues[4096 >> 7];
short cursor = 0;
short angleCamTimer = 0;
short forceApplied = 0;
// Callback function is used for pads
void callback();
int main() {
// Set matrices pointers to scratchpad
camera.mat = dc_camMat;
camera.pos = dc_camPos;
camera.rot = dc_camRot;
// Load level file according to level, l.39
if ( level == 0 ){
overlayFile = "\\level0.bin;1";
@ -130,8 +117,10 @@ int main() {
LvlPtrSet( &curLvl, &level1);
}
levelWas = level;
// Copy light matrices / vector to scratchpad
setDCLightEnv(curLvl.cmat, curLvl.lgtmat, &lgtang);
// Init dislay, Gte..
init(disp, draw, db, curLvl.cmat, curLvl.BGc, curLvl.BKc, &FC);
init(disp, draw, db, curLvl.BGc, curLvl.BKc, &FC);
// Init Pads
InitPAD(controllers[0].pad, 34, controllers[1].pad, 34);
StartPAD();
@ -167,7 +156,7 @@ int main() {
triCount += curLvl.meshes[k]->tmesh->len;
}
// Set camera starting pos
setCameraPos(&camera, curLvl.camPtr->campos->pos, curLvl.camPtr->campos->rot);
setCameraPos(&camera, &curLvl.camPtr->campos->pos, &curLvl.camPtr->campos->rot);
// Find curCamAngle if using pre-calculated BGs
if (camMode == 2) {
if (curLvl.camPtr->tim_data){
@ -176,7 +165,7 @@ int main() {
}
// Main loop
while ( VSync(VSYNC) ) {
timeS = VSync(-1) / 60;
//~ timeS = VSync(-1) / 60;
// Check if level has changed
// TODO : Proper level system / loader
if ( levelWas != level ){
@ -186,11 +175,14 @@ int main() {
overlayFile = "\\level0.bin;1";
overlaySize = __lvl0_end;
loadLvl = &level0;
// Copy light matrices / vector to scratchpad
break;
case 1:
overlayFile = "\\level1.bin;1";
overlaySize = __lvl1_end;
loadLvl = &level1;
// Copy light matrices / vector to scratchpad
break;
default:
overlayFile = "\\level0.bin;1";
@ -201,7 +193,7 @@ int main() {
LoadLevelCD( overlayFile, &load_all_overlays_here );
#endif
SwitchLevel( &curLvl, loadLvl);
setLightEnv(draw, curLvl.BGc, curLvl.BKc, curLvl.cmat);
setLightEnv(draw, curLvl.BGc, curLvl.BKc);
levelWas = level;
}
FntPrint("Ovl:%s\nLvl : %x\nLvl: %d %d \n%x", overlayFile, &level, level, levelWas, loadLvl);
@ -228,9 +220,9 @@ int main() {
);
// Camera modes
if(camMode != 2) {
camera.rot.vy = camAngleToAct.vy;
camera.rot->vy = camAngleToAct.vy;
// using csin/ccos, no need for theta
camera.rot.vx = camAngleToAct.vx;
camera.rot->vx = camAngleToAct.vx;
}
if(camMode < 4 ) {
lerping = 0;
@ -238,7 +230,7 @@ int main() {
// Camera follows actor
if(camMode == 0) {
dist = 200;
setVector(&camera.pos, -(camera.x/ONE), -(camera.y/ONE), -(camera.z/ONE));
setVector(camera.pos, -(camera.x/ONE), -(camera.y/ONE), -(camera.z/ONE));
angle.vy = -(curLvl.actorPtr->rot.vy / 2) + angleCam.vy;
// Camera horizontal and vertical position
getCameraZY(&camera.z, &camera.y, curLvl.actorPtr->pos.vz, curLvl.actorPtr->pos.vy, angle.vx, dist);
@ -249,7 +241,7 @@ int main() {
// Set distance between cam and actor
dist = 150;
// Set camera position
setVector(&camera.pos, -(camera.x/ONE), 100, -(camera.z/ONE));
setVector(camera.pos, -(camera.x/ONE), 100, -(camera.z/ONE));
// Find new camera position
getCameraXZ(&camera.x, &camera.z, curLvl.actorPtr->pos.vx, curLvl.actorPtr->pos.vz, angle.vy, dist);
// Set rotation amount
@ -260,7 +252,7 @@ int main() {
// Using precalc sqrt
dist = psqrt( (posToActor.vx * posToActor.vx ) + (posToActor.vz * posToActor.vz) );
// Set camera position
setVector(&camera.pos, 190, 100, 180);
setVector(camera.pos, 190, 100, 180);
}
// Fixed Camera angle
if (camMode == 2) {
@ -293,7 +285,7 @@ int main() {
}
}
}
setCameraPos(&camera, curLvl.camPtr->campos->pos, curLvl.camPtr->campos->rot);
setCameraPos(&camera, &curLvl.camPtr->campos->pos, &curLvl.camPtr->campos->rot);
}
// Flyby mode with LERP from camStart to camEnd
if (camMode == 4) {
@ -302,7 +294,7 @@ int main() {
// Lerping sequence has not begun
if (!lerping){
// Set cam start position ( first key pos )
copyVector(&camera.pos, &curLvl.camPath->points[curLvl.camPath->cursor]);
copyVector(camera.pos, &curLvl.camPath->points[curLvl.camPath->cursor]);
// Lerping sequence is starting
lerping = 1;
// Set cam pos index to 0
@ -312,7 +304,7 @@ int main() {
dist = psqrt( (posToActor.vx * posToActor.vx ) + (posToActor.vz * posToActor.vz));
// Fixed point precision 2^12 == 4096
int precision = 12;
setVector( &camera.pos,
setVector( camera.pos,
lerpD(curLvl.camPath->points[curLvl.camPath->cursor].vx << precision, curLvl.camPath->points[curLvl.camPath->cursor+1].vx << precision, curLvl.camPath->pos << precision) >> precision,
lerpD(curLvl.camPath->points[curLvl.camPath->cursor].vy << precision, curLvl.camPath->points[curLvl.camPath->cursor+1].vy << precision, curLvl.camPath->pos << precision) >> precision,
lerpD(curLvl.camPath->points[curLvl.camPath->cursor].vz << precision, curLvl.camPath->points[curLvl.camPath->cursor+1].vz << precision, curLvl.camPath->pos << precision) >> precision
@ -342,7 +334,7 @@ int main() {
// Lerping sequence has not begun
if (!lerping){
// Set cam start position ( first key pos )
copyVector(&camera.pos, &curLvl.camPath->points[curLvl.camPath->cursor]);
copyVector(camera.pos, &curLvl.camPath->points[curLvl.camPath->cursor]);
// Lerping sequence is starting
lerping = 1;
// Set cam pos index to 0
@ -352,17 +344,17 @@ int main() {
dist = psqrt( (posToActor.vx * posToActor.vx ) + (posToActor.vz * posToActor.vz));
// Fixed point precision 2^12 == 4096
short precision = 12;
setVector( &camera.pos,
setVector( camera.pos,
lerpD(curLvl.camPath->points[curLvl.camPath->cursor].vx << precision, curLvl.camPath->points[curLvl.camPath->cursor+1].vx << precision, curLvl.camPath->pos << precision) >> precision,
lerpD(curLvl.camPath->points[curLvl.camPath->cursor].vy << precision, curLvl.camPath->points[curLvl.camPath->cursor+1].vy << precision, curLvl.camPath->pos << precision) >> precision,
lerpD(curLvl.camPath->points[curLvl.camPath->cursor].vz << precision, curLvl.camPath->points[curLvl.camPath->cursor+1].vz << precision, curLvl.camPath->pos << precision) >> precision
);
// Ony move cam if position is between first curLvl.camPath->vx and last curLvl.camPath->vx
if ( camAngleToAct.vy < -50 && camera.pos.vx > curLvl.camPath->points[curLvl.camPath->len - 1].vx ) {
if ( camAngleToAct.vy < -50 && camera.pos->vx > curLvl.camPath->points[curLvl.camPath->len - 1].vx ) {
// Clamp curLvl.camPath position to cameraSpeed
curLvl.camPath->pos += dist < cameraSpeed ? 0 : cameraSpeed ;
}
if ( camAngleToAct.vy > 50 && camera.pos.vx > curLvl.camPath->points[curLvl.camPath->cursor].vx ) {
if ( camAngleToAct.vy > 50 && camera.pos->vx > curLvl.camPath->points[curLvl.camPath->cursor].vx ) {
curLvl.camPath->pos -= dist < cameraSpeed ? 0 : cameraSpeed;
}
// If camera has reached next key pos, reset pos index, move cursor to next key pos
@ -416,16 +408,20 @@ int main() {
if ( curLvl.meshes[k]->isProp ){
checkBodyCol( curLvl.meshes[k]->body , curLvl.meshes[k]->node->plane->body );
}
// Get col between actor and props
col = getExtCollision( *curLvl.meshes[k]->body, *curLvl.propPtr->body );
if (col.vx && col.vz ) {
setVector( &curLvl.propPtr->body->velocity,
curLvl.meshes[k]->body->velocity.vx,
0,
curLvl.meshes[k]->body->velocity.vz
);
// If prop is spherical, make it roll
applyAngMom(curLvl);
// Only evaluate collision if actor is on same plane as prop
if ( curLvl.curNode == curLvl.propPtr->node ){
// Get col between actor and props
col = getExtCollision( *curLvl.meshes[k]->body, *curLvl.propPtr->body );
if (col.vx && col.vz ) {
setVector( &curLvl.propPtr->body->velocity,
curLvl.meshes[k]->body->velocity.vx,
0,
curLvl.meshes[k]->body->velocity.vz
);
// If prop is spherical, make it roll
applyAngMom(curLvl);
}
}
// Synchronize mesh to body position
copyVector(&curLvl.meshes[k]->pos, &curLvl.meshes[k]->body->position);
@ -439,59 +435,60 @@ int main() {
}
// Camera setup
// Get position of cam relative to actor
addVector2(&curLvl.actorPtr->pos, &camera.pos, &posToActor);
addVector2(&curLvl.actorPtr->pos, camera.pos, &posToActor);
// Polygon drawing
if (curLvl.curNode){
static long Flag;
if ( (camMode == 2) && (curLvl.camPtr->tim_data ) ) {
drawBG(curLvl.camPtr, &nextpri, otdisc[db], &db);
// Loop on camAngles
for ( int mesh = 0 ; mesh < curLvl.camAngles[ curCamAngle ]->index; mesh ++ ) {
enlightMesh(&curLvl, curLvl.camAngles[curCamAngle]->objects[mesh], &lgtang);
enlightMesh(&curLvl, curLvl.camAngles[curCamAngle]->objects[mesh], dc_lgtangp);
transformMesh(&camera, curLvl.camAngles[curCamAngle]->objects[mesh]);
drawPoly(curLvl.camAngles[curCamAngle]->objects[mesh], &Flag, atime, &camMode, &nextpri, ot[db], &db, &draw[db]);
drawPoly(curLvl.camAngles[curCamAngle]->objects[mesh], atime, &camMode, &nextpri, ot[db], &db, &draw[db]);
}
}
else {
// Draw current node's plane
drawPoly( curLvl.curNode->plane, &Flag, atime, &camMode, &nextpri, ot[db], &db, &draw[db]);
drawPoly( curLvl.curNode->plane, atime, &camMode, &nextpri, ot[db], &db, &draw[db]);
// Draw surrounding planes
for ( int sibling = 0; sibling < curLvl.curNode->siblings->index; sibling++ ) {
drawPoly(curLvl.curNode->siblings->list[ sibling ]->plane, &Flag, atime, &camMode, &nextpri, ot[db], &db, &draw[db]);
drawPoly(curLvl.curNode->siblings->list[ sibling ]->plane, atime, &camMode, &nextpri, ot[db], &db, &draw[db]);
}
// Draw adjacent planes's children
for ( int sibling = 0; sibling < curLvl.curNode->siblings->index; sibling++ ) {
for ( int object = 0; object < curLvl.curNode->siblings->list[ sibling ]->objects->index; object++ ) {
long t = 0;
enlightMesh(&curLvl, curLvl.curNode->siblings->list[ sibling ]->objects->list[ object ], &lgtang);
enlightMesh(&curLvl, curLvl.curNode->siblings->list[ sibling ]->objects->list[ object ], dc_lgtangp);
transformMesh(&camera, curLvl.curNode->siblings->list[ sibling ]->objects->list[ object ]);
drawPoly( curLvl.curNode->siblings->list[ sibling ]->objects->list[ object ], &Flag, atime, &camMode, &nextpri, ot[db], &db, &draw[db]);
drawPoly( curLvl.curNode->siblings->list[ sibling ]->objects->list[ object ], atime, &camMode, &nextpri, ot[db], &db, &draw[db]);
}
}
// Draw current plane children
for ( int object = 0; object < curLvl.curNode->objects->index; object++ ) {
enlightMesh(&curLvl, curLvl.curNode->objects->list[ object ], &lgtang);
enlightMesh(&curLvl, curLvl.curNode->objects->list[ object ], dc_lgtangp);
transformMesh(&camera, curLvl.curNode->objects->list[ object ]);
drawPoly( curLvl.curNode->objects->list[ object ], &Flag, atime, &camMode, &nextpri, ot[db], &db, &draw[db]);
drawPoly( curLvl.curNode->objects->list[ object ], atime, &camMode, &nextpri, ot[db], &db, &draw[db]);
}
// Draw rigidbodies
for ( int object = 0; object < curLvl.curNode->rigidbodies->index; object++ ) {
enlightMesh(&curLvl, curLvl.curNode->rigidbodies->list[ object ], &lgtang);
enlightMesh(&curLvl, curLvl.curNode->rigidbodies->list[ object ], dc_lgtangp);
transformMesh(&camera, curLvl.curNode->rigidbodies->list[ object ]);
drawPoly( curLvl.curNode->rigidbodies->list[ object ], &Flag, atime, &camMode, &nextpri, ot[db], &db, &draw[db]);
drawPoly( curLvl.curNode->rigidbodies->list[ object ], atime, &camMode, &nextpri, ot[db], &db, &draw[db]);
}
}
}
// Update global light matrix
RotMatrix_gte(&lgtang, &rotlgt);
MulMatrix0(curLvl.lgtmat, &rotlgt, &light);
SetLightMatrix(&light);
// Update global light matrix - use scratchpad
RotMatrix_gte(dc_lgtangp, dc_lgtmatp);
gte_MulMatrix0(dc_lvllgtmatp, dc_lgtmatp, dc_lgtmatp);
gte_SetLightMatrix(dc_lgtmatp);
// Set camera
applyCamera(&camera);
// Add secondary OT to main OT
AddPrims(otdisc[db], ot[db] + OTLEN - 1, ot[db]);
FntPrint("Time : %d", timeS);
FntPrint("Time : %d\n", time);
FntPrint("#Tri : %d\n", triCount);
FntPrint("# : %d %d\n", sizeof(VECTOR), sizeof(CAMERA) );
FntFlush(-1);
display( &disp[db], &draw[db], otdisc[db], primbuff[db], &nextpri, &db);
}
@ -504,12 +501,13 @@ void callback() {
read_controller( &theControllers[1], &controllers[1].pad[0], 1 );
u_char PADL = ~theControllers[0].button1;
u_char PADR = ~theControllers[0].button2;
static u_short lastPad;
static short forceApplied = 0;
//~ static u_short lastPad;
//~ static int lerpValues[4096 >> 7];
//~ static short cursor = 0;
//~ static short angleCamTimer = 0;
//~ static short forceApplied = 0;
int div = 32;
static int lerpValues[4096 >> 7];
static short cursor = 0;
static short angleCamTimer = 0;
if( !lerpValues[0] ) {
for ( long long i = 0; i < div ; i++ ){
lerpValues[(div-1)-i] = lerp(-24, -264, easeIn(i));
@ -530,7 +528,7 @@ void callback() {
camMode ++;
lerping = 0;
} else {
setCameraPos(&camera, curLvl.camPtr->campos->pos, curLvl.camPtr->campos->rot);
setCameraPos(&camera, &curLvl.camPtr->campos->pos, &curLvl.camPtr->campos->rot);
curLvl.camPath->cursor = 0;
camMode = 0;
lerping = 0;
@ -552,10 +550,10 @@ void callback() {
//pressed = 0;
//~ }
if ( PADR & PadShldL2 ) {
lgtang.vy += 32;
dc_lgtangp->vy += 32;
}
if ( PADR & PadShldL1 ) {
lgtang.vz += 32;
dc_lgtangp->vz += 32;
}
if ( PADR & PadUp && !timer ){
if (curLvl.actorPtr->isPrism){
@ -589,14 +587,14 @@ void callback() {
if (theControllers[0].type == 0x73){
// Analog stick L up
if ( theControllers[0].analog3 >= 0 && theControllers[0].analog3 < 108 ) {
curLvl.actorPtr->body->gForce.vz = getVectorTo(fVecActor, curLvl.actorPtr->pos).vz * (128 - theControllers[0].analog3 ) >> 15 ;
curLvl.actorPtr->body->gForce.vx = -getVectorTo(fVecActor, curLvl.actorPtr->pos).vx * (128 - theControllers[0].analog3 ) >> 15 ;
curLvl.actorPtr->body->gForce.vz = getVectorTo(fVecActor, curLvl.actorPtr->pos).vz * (128 - theControllers[0].analog3 ) >> 14 ;
curLvl.actorPtr->body->gForce.vx = -getVectorTo(fVecActor, curLvl.actorPtr->pos).vx * (128 - theControllers[0].analog3 ) >> 14 ;
lastPad = PADL;
}
// Analog stick L down
if ( theControllers[0].analog3 > 168 && theControllers[0].analog3 <= 255 ) {
curLvl.actorPtr->body->gForce.vz = -getVectorTo(fVecActor, curLvl.actorPtr->pos).vz * ( theControllers[0].analog3 - 128 ) >> 15 ;
curLvl.actorPtr->body->gForce.vx = getVectorTo(fVecActor, curLvl.actorPtr->pos).vx * ( theControllers[0].analog3 - 128 ) >> 15 ;
curLvl.actorPtr->body->gForce.vz = -getVectorTo(fVecActor, curLvl.actorPtr->pos).vz * ( theControllers[0].analog3 - 128 ) >> 14 ;
curLvl.actorPtr->body->gForce.vx = getVectorTo(fVecActor, curLvl.actorPtr->pos).vx * ( theControllers[0].analog3 - 128 ) >> 14 ;
lastPad = PADL;
}
// Analog stick L dead zone
@ -614,8 +612,8 @@ void callback() {
}
}
if ( PADL & PadUp ) {
curLvl.actorPtr->body->gForce.vz = getVectorTo(fVecActor, curLvl.actorPtr->pos).vz >> 8 ;
curLvl.actorPtr->body->gForce.vx = -getVectorTo(fVecActor, curLvl.actorPtr->pos).vx >> 8 ;
curLvl.actorPtr->body->gForce.vz = getVectorTo(fVecActor, curLvl.actorPtr->pos).vz >> 7 ;
curLvl.actorPtr->body->gForce.vx = -getVectorTo(fVecActor, curLvl.actorPtr->pos).vx >> 7;
lastPad = PADL;
}
if ( !(PADL & PadUp) && lastPad & PadUp) {
@ -624,8 +622,8 @@ void callback() {
lastPad = PADL;
}
if ( PADL & PadDown ) {
curLvl.actorPtr->body->gForce.vz = -getVectorTo(fVecActor, curLvl.actorPtr->pos).vz >> 8 ;
curLvl.actorPtr->body->gForce.vx = getVectorTo(fVecActor, curLvl.actorPtr->pos).vx >> 8 ;
curLvl.actorPtr->body->gForce.vz = -getVectorTo(fVecActor, curLvl.actorPtr->pos).vz >> 7 ;
curLvl.actorPtr->body->gForce.vx = getVectorTo(fVecActor, curLvl.actorPtr->pos).vx >> 7 ;
lastPad = PADL;
}
if ( !( PADL & PadDown ) && lastPad & PadDown) {

View File

@ -1,6 +1,13 @@
#include "../include/psx.h"
void setLightEnv(DRAWENV draw[2], CVECTOR * BGc, VECTOR * BKc, MATRIX * cmat){
void setDCLightEnv(MATRIX * curLevelCMat, MATRIX * curLevelLgtMat, SVECTOR * curLevelLgtAng){
memcpy( dc_lvlcmatp, curLevelCMat, sizeof(MATRIX));
memcpy( dc_lvllgtmatp, curLevelLgtMat, sizeof(MATRIX));
memcpy( dc_lgtangp, curLevelLgtAng, sizeof(SVECTOR));
};
void setLightEnv(DRAWENV draw[2], CVECTOR * BGc, VECTOR * BKc){
// Set Draw area color
setRGB0(&draw[0], BGc->r, BGc->g, BGc->b);
setRGB0(&draw[1], BGc->r, BGc->g, BGc->b);
@ -9,10 +16,10 @@ void setLightEnv(DRAWENV draw[2], CVECTOR * BGc, VECTOR * BKc, MATRIX * cmat){
// Set Ambient color
SetBackColor( BKc->vx, BKc->vy, BKc->vz );
// Set Light matrix
SetColorMatrix(cmat);
SetColorMatrix(dc_lvlcmatp);
};
void init(DISPENV disp[2], DRAWENV draw[2], short db, MATRIX * cmat, CVECTOR * BGc, VECTOR * BKc, VECTOR * FC) {
void init(DISPENV disp[2], DRAWENV draw[2], short db, CVECTOR * BGc, VECTOR * BKc, VECTOR * FC) {
ResetCallback();
// Init pad
//~ PadInit(0);
@ -23,7 +30,9 @@ void init(DISPENV disp[2], DRAWENV draw[2], short db, MATRIX * cmat, CVECTOR * B
// Initialize and setup the GTE
InitGeom();
SetGeomOffset( CENTERX, CENTERY ); // x, y offset
SetGeomScreen( FOV ); // Distance between eye and screen - Camera FOV
SetGeomScreen( FOV ); // Distance between eye and screen - Camera FOV
SetDispMask(1);
// Set the display and draw environments
SetDefDispEnv(&disp[0], 0, 0 , SCREENXRES, SCREENYRES);
SetDefDispEnv(&disp[1], 0, SCREENYRES, SCREENXRES, SCREENYRES);
@ -36,7 +45,7 @@ void init(DISPENV disp[2], DRAWENV draw[2], short db, MATRIX * cmat, CVECTOR * B
disp[1].screen.y += 8;
}
// Set Draw area color
setLightEnv(draw, BGc, BKc, cmat);
setLightEnv(draw, BGc, BKc);
// Set Draw area clear flag
draw[0].isbg = 1;
draw[1].isbg = 1;
@ -73,7 +82,7 @@ void display(DISPENV * disp, DRAWENV * draw, u_long * otdisc, char * primbuff, c
ResetGraph(1);
PutDispEnv(disp);
PutDrawEnv(draw);
SetDispMask(1);
//~ SetDispMask(1);
// Main OT
DrawOTag(otdisc + OT2LEN - 1);
*db = !*db;
@ -118,6 +127,10 @@ void SwitchLevel( LEVEL * curLevel, LEVEL * loadLevel ){
if (curLevel->camPtr->tim_data){
LoadTexture(curLevel->camPtr->tim_data, curLevel->camPtr->BGtim);
}
// TODO : per-level lgtang
SVECTOR lgtang = {0,0,0,0};
// Light environment
setDCLightEnv(curLevel->cmat, curLevel->lgtmat, &lgtang);
};
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