3dcam-headers/main.c

1479 lines
41 KiB
C
Raw Normal View History

2021-04-10 14:22:48 +02:00
// 3dcam
// With huge help from :
// @NicolasNoble : https://discord.com/channels/642647820683444236/646765703143227394/796876392670429204
// @Lameguy64
// @Impiaa
// @paul
/* PSX screen coordinate system
*
* Z+
* /
* /
* +------X+
* /|
* / |
* / Y+
* eye */
// Blender debug mode
// bpy. app. debug = True
2021-04-15 18:18:39 +02:00
#define _WCHAR_T
2021-04-10 14:22:48 +02:00
#include "psx.h"
#include "math.h"
#include "camera.h"
#include "physics.h"
#include "graphics.h"
#include "space.h"
2021-04-14 15:56:14 +02:00
2021-04-16 20:22:03 +02:00
#define USECD
2021-04-10 14:22:48 +02:00
2021-04-13 16:52:48 +02:00
// START OVERLAY
2021-04-10 14:22:48 +02:00
2021-04-15 18:18:39 +02:00
extern u_long load_all_overlays_here;
extern u_long __lvl0_end;
extern u_long __lvl1_end;
2021-04-16 20:22:03 +02:00
//~ #define LLEVEL 0
2021-04-10 14:22:48 +02:00
2021-04-14 15:56:14 +02:00
//#define USE_POINTER
2021-04-10 14:22:48 +02:00
2021-04-16 20:22:03 +02:00
//~ #if LLEVEL == 0
2021-04-15 18:18:39 +02:00
2021-04-16 20:22:03 +02:00
//~ static const char*const overlayFile = "\\level0.bin;1";
2021-04-15 18:18:39 +02:00
2021-04-16 20:22:03 +02:00
//~ #else
2021-04-15 18:18:39 +02:00
2021-04-16 20:22:03 +02:00
//~ static const char*const overlayFile = "\\level1.bin;1";
2021-04-15 18:18:39 +02:00
2021-04-16 20:22:03 +02:00
//~ #endif
2021-04-10 14:22:48 +02:00
2021-04-13 16:52:48 +02:00
//~ #ifdef USE_POINTER
2021-04-10 14:22:48 +02:00
2021-04-14 15:56:14 +02:00
//~ #if LEVEL == 0
2021-04-13 16:52:48 +02:00
//~ #include "levels/level.h"
//~ #else
//~ #include "levels/level1.h"
//~ #endif
2021-04-10 14:22:48 +02:00
2021-04-13 16:52:48 +02:00
//~ #else
2021-04-14 15:56:14 +02:00
//~ #define str (char*)(&__load_start_ovly0)
2021-04-13 16:52:48 +02:00
//~ #endif
2021-04-10 14:22:48 +02:00
2021-04-14 15:56:14 +02:00
// END OVERLAY
2021-04-10 14:22:48 +02:00
2021-04-15 18:18:39 +02:00
#include "levels/level0.h"
2021-04-14 15:56:14 +02:00
#include "levels/level1.h"
2021-04-10 14:22:48 +02:00
2021-04-16 20:22:03 +02:00
short level = 1;
short levelHasChanged = 0;
static char* overlayFile;
2021-04-14 15:56:14 +02:00
2021-04-10 14:22:48 +02:00
// Display and draw environments, double buffered
DISPENV disp[2];
DRAWENV draw[2];
//~ // OT for BG/FG discrimination
u_long otdisc[2][OT2LEN] = {0};
// Main OT
u_long ot[2][OTLEN] = {0}; // Ordering table (contains addresses to primitives)
char primbuff[2][PRIMBUFFLEN] = {0}; // Primitive list // That's our prim buffer
int primcnt=0; // Primitive counter
char * nextpri = primbuff[0]; // Primitive counter
char db = 0; // Current buffer counter
CVECTOR BGc = {50, 50, 75, 0}; // Far color
2021-04-13 16:52:48 +02:00
VECTOR BKc = {128, 128, 128, 0}; // Back color
2021-04-10 14:22:48 +02:00
MATRIX rotlgt;
SVECTOR lgtang = {0, 0, 0};
MATRIX light;
short vs;
CAMERA camera = {0};
// physics
long time = 0;
//~ const int gravity = 10;
int camMode = 2;
//Pad
int pressed = 0;
u_short timer = 0;
// Cam stuff
int lerping = 0;
short curCamAngle = 0;
// Inverted Cam coordinates for Forward Vector calc
VECTOR InvCamPos = {0,0,0,0};
VECTOR fVecActor = {0,0,0,0};
u_long triCount = 0;
2021-04-16 20:22:03 +02:00
// These are set to the corresponding address in the LEVEL struct of current loaded level
2021-04-14 15:56:14 +02:00
2021-04-16 20:22:03 +02:00
MATRIX * cmat, * lgtmat;
2021-04-14 15:56:14 +02:00
2021-04-15 18:18:39 +02:00
MESH * actorPtr, * levelPtr, * propPtr, ** meshes;
2021-04-14 15:56:14 +02:00
2021-04-15 18:18:39 +02:00
int * meshes_length;
2021-04-14 15:56:14 +02:00
2021-04-15 18:18:39 +02:00
NODE * curNode;
2021-04-14 15:56:14 +02:00
2021-04-15 18:18:39 +02:00
CAMPATH * camPath;
2021-04-14 15:56:14 +02:00
2021-04-15 18:18:39 +02:00
CAMANGLE * camPtr, ** camAngles;
2021-04-14 15:56:14 +02:00
2021-04-15 18:18:39 +02:00
// Get rid of those
2021-04-14 15:56:14 +02:00
2021-04-15 18:18:39 +02:00
MESH * meshPlan;
2021-04-14 15:56:14 +02:00
2021-04-15 18:18:39 +02:00
VECTOR * modelPlan_pos;
2021-04-10 14:22:48 +02:00
2021-04-16 20:22:03 +02:00
// Zero level : Initialize everything to 0
MATRIX Zcmat = {0}, Zlgtmat = {0};
MESH ZactorPtr = {0}, ZlevelPtr = {0} , ZpropPtr = {0}, Zmeshes[] = {0};
int Zmeshes_length = 0;
NODE ZcurNode = {0};
CAMPATH ZcamPath = {0};
CAMANGLE ZcamPtr = {0}, ZcamAngles[] = {0};
// Get rid of those
MESH ZmeshPlan = {0};
VECTOR ZmodelPlan_pos = {0};
LEVEL zero = {
&Zcmat,
&Zlgtmat,
&Zmeshes,
&Zmeshes_length,
&ZactorPtr,
&ZlevelPtr,
&ZpropPtr,
&ZcamPtr,
&ZcamPath,
&ZcamAngles,
0,
&ZmeshPlan
};
2021-04-10 14:22:48 +02:00
// Pad
void callback();
int main() {
2021-04-16 20:22:03 +02:00
if ( level == 0 ){
overlayFile = "\\level0.bin;1";
} else if ( level == 1) {
overlayFile = "\\level1.bin;1";
}
// Use Struct to hold level's pointers
//~ LEVEL curLevel = {
//~ cmat,
//~ lgtmat,
//~ meshes,
//~ meshes_length,
//~ actorPtr,
//~ levelPtr,
//~ propPtr,
//~ camPtr,
//~ camPath,
//~ camAngles,
//~ curNode,
//~ meshPlan
//~ };
2021-04-10 14:22:48 +02:00
2021-04-16 20:22:03 +02:00
// Zeroing the level pointers
2021-04-15 18:18:39 +02:00
2021-04-16 20:22:03 +02:00
cmat = zero.cmat;
lgtmat = zero.lgtmat;
meshes = (MESH **)zero.meshes;
meshes_length = zero.meshes_length;
actorPtr = zero.actorPtr;
levelPtr = zero.levelPtr;
propPtr = zero.propPtr;
camPtr = zero.camPtr;
camPath = zero.camPath;
2021-04-15 18:18:39 +02:00
2021-04-16 20:22:03 +02:00
camAngles = (CAMANGLE **)zero.camAngles;
curNode = zero.curNode; // Blank
// Move these to drawPoly()
meshPlan = zero.meshPlan;
// Load overlay
2021-04-14 15:56:14 +02:00
2021-04-15 18:18:39 +02:00
#ifdef USECD
2021-04-14 15:56:14 +02:00
2021-04-15 18:18:39 +02:00
CdInit();
2021-04-14 15:56:14 +02:00
2021-04-15 18:18:39 +02:00
LoadLevel(overlayFile, &load_all_overlays_here);
#endif
2021-04-16 20:22:03 +02:00
// TODO : Add switch case to get the correct pointers
// Get needed pointers from level file
2021-04-13 16:52:48 +02:00
2021-04-16 20:22:03 +02:00
if ( level == 0 ) {
2021-04-14 15:56:14 +02:00
2021-04-16 20:22:03 +02:00
cmat = level0.cmat;
2021-04-14 15:56:14 +02:00
2021-04-15 18:18:39 +02:00
lgtmat = level0.lgtmat;
2021-04-14 15:56:14 +02:00
2021-04-15 18:18:39 +02:00
meshes = (MESH **)level0.meshes;
2021-04-14 15:56:14 +02:00
2021-04-15 18:18:39 +02:00
meshes_length = level0.meshes_length;
2021-04-14 15:56:14 +02:00
2021-04-15 18:18:39 +02:00
actorPtr = level0.actorPtr;
2021-04-13 16:52:48 +02:00
2021-04-15 18:18:39 +02:00
levelPtr = level0.levelPtr;
2021-04-14 15:56:14 +02:00
2021-04-15 18:18:39 +02:00
propPtr = level0.propPtr;
2021-04-14 15:56:14 +02:00
2021-04-15 18:18:39 +02:00
camPtr = level0.camPtr;
2021-04-14 15:56:14 +02:00
2021-04-15 18:18:39 +02:00
camPath = level0.camPath;
2021-04-14 15:56:14 +02:00
2021-04-15 18:18:39 +02:00
camAngles = (CAMANGLE **)level0.camAngles;
2021-04-14 15:56:14 +02:00
2021-04-16 20:22:03 +02:00
curNode = level0.curNode; // Blank
2021-04-14 15:56:14 +02:00
// Move these to drawPoly()
2021-04-15 18:18:39 +02:00
meshPlan = level0.meshPlan;
2021-04-16 20:22:03 +02:00
//~ LvlPtrSet( &curLevel, &level0);
} else if ( level == 1) {
2021-04-13 16:52:48 +02:00
2021-04-15 18:18:39 +02:00
cmat = level1.cmat;
2021-04-13 16:52:48 +02:00
2021-04-15 18:18:39 +02:00
lgtmat = level1.lgtmat;
2021-04-13 16:52:48 +02:00
2021-04-15 18:18:39 +02:00
meshes = (MESH **)level1.meshes;
2021-04-13 16:52:48 +02:00
2021-04-15 18:18:39 +02:00
meshes_length = level1.meshes_length;
2021-04-13 16:52:48 +02:00
2021-04-15 18:18:39 +02:00
actorPtr = level1.actorPtr;
2021-04-14 15:56:14 +02:00
2021-04-15 18:18:39 +02:00
levelPtr = level1.levelPtr;
2021-04-14 15:56:14 +02:00
2021-04-15 18:18:39 +02:00
propPtr = level1.propPtr;
2021-04-14 15:56:14 +02:00
2021-04-15 18:18:39 +02:00
camPtr = level1.camPtr;
2021-04-14 15:56:14 +02:00
2021-04-15 18:18:39 +02:00
camPath = level1.camPath;
2021-04-14 15:56:14 +02:00
2021-04-15 18:18:39 +02:00
camAngles = (CAMANGLE **)level1.camAngles;
2021-04-14 15:56:14 +02:00
2021-04-15 18:18:39 +02:00
curNode = level1.curNode;
2021-04-14 15:56:14 +02:00
// Move these to drawPoly()
2021-04-13 16:52:48 +02:00
2021-04-15 18:18:39 +02:00
meshPlan = level1.meshPlan;
2021-04-14 15:56:14 +02:00
2021-04-15 18:18:39 +02:00
//~ modelPlan_pos = level1_meshPlan->pos;
2021-04-14 15:56:14 +02:00
2021-04-16 20:22:03 +02:00
}
2021-04-14 15:56:14 +02:00
// Overlay
2021-04-10 14:22:48 +02:00
VECTOR sp = {CENTERX,CENTERY,0};
VECTOR wp = {0,0,0};
// FIXME : Poly subdiv
//~ DIVPOLYGON4 div4 = { 0 };
//~ div4.pih = SCREENXRES;
//~ div4.piv = SCREENYRES;
//~ div4.ndiv = 2;
//~ long OTc = 0;
//~ DIVPOLYGON3 div3 = { 0 };
//~ div3.pih = SCREENXRES;
//~ div3.piv = SCREENYRES;
//~ div3.ndiv = 1;
2021-04-13 16:52:48 +02:00
init(disp, draw, db, cmat, &BGc, &BKc);
2021-04-10 14:22:48 +02:00
generateTable();
VSyncCallback(callback);
// Load textures
2021-04-13 16:52:48 +02:00
for (int k = 0; k < *meshes_length ; k++){
2021-04-10 14:22:48 +02:00
LoadTexture(meshes[k]->tim_data, meshes[k]->tim);
}
// Load current BG
if (camPtr->tim_data){
LoadTexture(camPtr->tim_data, camPtr->BGtim);
}
// Physics
short physics = 1;
long dt;
VECTOR col_lvl, col_sphere, col_sphere_act = {0};
// Cam stuff
VECTOR posToActor = {0, 0, 0, 0}; // position of camera relative to actor
VECTOR camAngleToAct = {0, 0, 0, 0}; // rotation angles for the camera to point at actor
// Sprite system
VECTOR posToCam = {0, 0, 0, 0};
VECTOR objAngleToCam = {0, 0, 0, 0};
int angle = 0; //PSX units = 4096 == 360° = 2Pi
int dist = 0; //PSX units
short timediv = 1;
int atime = 0;
// Polycount
2021-04-13 16:52:48 +02:00
for (int k = 0; k < *meshes_length; k++){
2021-04-10 14:22:48 +02:00
triCount += meshes[k]->tmesh->len;
}
// Set camera starting pos
setCameraPos(&camera, camPtr->campos->pos, camPtr->campos->rot);
// Find curCamAngle if using pre-calculated BGs
if (camMode == 2) {
if (camPtr->tim_data){
curCamAngle = 1;
}
}
// Main loop
//~ while (1) {
while ( VSync(1) ) {
2021-04-16 20:22:03 +02:00
if (levelHasChanged){
if ( level == 0 ) {
//~ cmat = zero.cmat;
//~ lgtmat = zero.lgtmat;
//~ meshes = (MESH **)zero.meshes;
//~ meshes_length = zero.meshes_length;
//~ actorPtr = zero.actorPtr;
//~ levelPtr = zero.levelPtr;
//~ propPtr = zero.propPtr;
//~ camPtr = zero.camPtr;
//~ camPath = zero.camPath;
//~ camAngles = (CAMANGLE **)zero.camAngles;
//~ curNode = zero.curNode; // Blank
// Move these to drawPoly()
//~ meshPlan = zero.meshPlan;
ScrRst();
overlayFile = "\\level0.bin;1";
LoadLevel(overlayFile, &load_all_overlays_here);
cmat = level0.cmat;
lgtmat = level0.lgtmat;
meshes = level0.meshes;
meshes_length = level0.meshes_length;
actorPtr = level0.actorPtr;
levelPtr = level0.levelPtr;
propPtr = level0.propPtr;
camPtr = level0.camPtr;
camPath = level0.camPath;
camAngles = level0.camAngles;
curNode = level0.curNode; // Blank
// Move these to drawPoly()
meshPlan = level0.meshPlan;
//~ LvlPtrSet( &curLevel, &level0);
for (int k = 0; k < *meshes_length ; k++){
LoadTexture(meshes[k]->tim_data, meshes[k]->tim);
}
} else if ( level == 1) {
//~ cmat = zero.cmat;
//~ lgtmat = zero.lgtmat;
//~ meshes = (MESH **)zero.meshes;
//~ meshes_length = zero.meshes_length;
//~ actorPtr = zero.actorPtr;
//~ levelPtr = zero.levelPtr;
//~ propPtr = zero.propPtr;
//~ camPtr = zero.camPtr;
//~ camPath = zero.camPath;
//~ camAngles = (CAMANGLE **)zero.camAngles;
//~ curNode = zero.curNode; // Blank
//~ // Move these to drawPoly()
//~ meshPlan = zero.meshPlan;
//~ ScrRst();
overlayFile = "\\level1.bin;1";
LoadLevel(overlayFile, &load_all_overlays_here);
cmat = level1.cmat;
lgtmat = level1.lgtmat;
meshes = level1.meshes;
meshes_length = level1.meshes_length;
actorPtr = level1.actorPtr;
levelPtr = level1.levelPtr;
propPtr = level1.propPtr;
camPtr = level1.camPtr;
camPath = level1.camPath;
camAngles = level1.camAngles;
curNode = level1.curNode;
// Move these to drawPoly()
meshPlan = level1.meshPlan;
//~ modelPlan_pos = level1_meshPlan->pos;
for (int k = 0; k < *meshes_length ; k++){
LoadTexture(meshes[k]->tim_data, meshes[k]->tim);
}
}
levelHasChanged = 0;
}
FntPrint("%x\n", actorPtr->tim);
2021-04-14 15:56:14 +02:00
2021-04-10 14:22:48 +02:00
// Clear the main OT
ClearOTagR(otdisc[db], OT2LEN);
// Clear Secondary OT
ClearOTagR(ot[db], OTLEN);
// timeB = time;
time ++;
// atime is used for animations timing
timediv = 1;
if (time % timediv == 0){
atime ++;
}
// Angle between camera and actor
// using atantable (faster)
camAngleToAct.vy = (patan(-posToActor.vx, -posToActor.vz) / 16) - 3076 ;
camAngleToAct.vx = patan(dist, posToActor.vy) >> 4;
// Sprite system WIP
objAngleToCam.vy = patan( posToCam.vx,posToCam.vz );
objAngleToCam.vx = patan( posToCam.vx,posToCam.vy );
//~ objAngleToCam.vz = patan( posToCam.vz,posToCam.vy );
//~ objAngleToCam.vx = patan( psqrt(posToCam.vx * posToCam.vx + posToCam.vy * posToCam.vy), posToCam.vy );
//~ meshPlan.rot->vx = -( (objAngleToCam.vx >> 4) - 3076 ) ;
//~ meshPlan.rot->vx = (( (objAngleToCam.vx >> 4) - 3076 ) * ( (objAngleToCam.vz >> 4) - 3076 ) >> 12) * (nsin(posToCam.vz) >> 10 < 0 ? -1 : 1);
//~ meshPlan.rot->vx = ( (objAngleToCam.vx >> 4) - 3076 ) * ( (objAngleToCam.vz >> 4) - 3076 ) >> 12 ;
2021-04-15 18:18:39 +02:00
meshPlan->rot.vy = -( (objAngleToCam.vy >> 4) + 1024 ) ;
2021-04-10 14:22:48 +02:00
//~ posToCam = getVectorTo(*meshPlan.pos, camera.pos);
//~ posToCam = getVectorTo(camera.pos, *meshPlan.pos);
2021-04-15 18:18:39 +02:00
posToCam.vx = -camera.pos.vx - meshPlan->pos.vx ;
2021-04-10 14:22:48 +02:00
2021-04-15 18:18:39 +02:00
posToCam.vz = -camera.pos.vz - meshPlan->pos.vz ;
2021-04-10 14:22:48 +02:00
2021-04-15 18:18:39 +02:00
posToCam.vy = -camera.pos.vy - meshPlan->pos.vy ;
2021-04-10 14:22:48 +02:00
//~ psqrt(posToCam.vx * posToCam.vx + posToCam.vy * posToCam.vy);
// Actor Forward vector for 3d relative orientation
2021-04-15 18:18:39 +02:00
fVecActor = actorPtr->pos;
2021-04-10 14:22:48 +02:00
2021-04-15 18:18:39 +02:00
fVecActor.vx = actorPtr->pos.vx + (nsin(actorPtr->rot.vy/2));
2021-04-10 14:22:48 +02:00
2021-04-15 18:18:39 +02:00
fVecActor.vz = actorPtr->pos.vz - (ncos(actorPtr->rot.vy/2));
2021-04-10 14:22:48 +02:00
// Camera modes
if(camMode != 2) {
camera.rot.vy = camAngleToAct.vy;
// using csin/ccos, no need for theta
//~ camera.rot.vy = angle;
camera.rot.vx = camAngleToAct.vx;
}
if(camMode < 4 ) {
lerping = 0;
}
// Camera follows actor with lerp for rotations
if(camMode == 0) {
dist = 150;
camera.pos.vx = -(camera.x/ONE);
//~ camera.pos.vy = -(camera.y/ONE);
camera.pos.vz = -(camera.z/ONE);
//~ InvCamPos.vx = camera.x/ONE;
//~ InvCamPos.vz = camera.z/ONE;
//~ applyVector(&InvCamPos, -1,-1,-1, *=);
2021-04-15 18:18:39 +02:00
angle = -actorPtr->rot.vy / 2;
2021-04-10 14:22:48 +02:00
//~ angle = actorPtr->rot->vy;
2021-04-15 18:18:39 +02:00
getCameraXZ(&camera.x, &camera.z, actorPtr->pos.vx, actorPtr->pos.vz, angle, dist);
2021-04-10 14:22:48 +02:00
// FIXME! camera lerping to pos
//~ angle += lerp(camera.rot.vy, -actorPtr->rot->vy, 128);
//~ angle = lerpD(camera.rot.vy << 12, actorPtr->rot->vy << 12, 1024 << 12) >> 12;
}
// Camera rotates continuously around actor
if (camMode == 1) {
dist = 150;
camera.pos.vx = -(camera.x/ONE);
//~ camera.pos.vy = -(camera.y/ONE);
camera.pos.vz = -(camera.z/ONE);
//~ fVecActor = *actorPtr->pos;
//~ fVecActor.vx = actorPtr->pos->vx + (nsin(actorPtr->rot->vy));
//~ fVecActor.vz = actorPtr->pos->vz - (ncos(actorPtr->rot->vy));
2021-04-15 18:18:39 +02:00
getCameraXZ(&camera.x, &camera.z, actorPtr->pos.vx, actorPtr->pos.vz, angle, dist);
2021-04-10 14:22:48 +02:00
angle += 10;
}
// Fixed Camera with actor tracking
if (camMode == 3) {
// Using precalc sqrt
dist = psqrt( (posToActor.vx * posToActor.vx ) + (posToActor.vz * posToActor.vz) );
camera.pos.vx = 190;
camera.pos.vz = 100;
camera.pos.vy = 180;
}
// Fixed Camera angle
if (camMode == 2) {
// If BG images exist
if (camPtr->tim_data){
checkLineW( &camAngles[ curCamAngle ]->fw.v3, &camAngles[ curCamAngle ]->fw.v2, actorPtr);
if ( camAngles[ curCamAngle ]->fw.v0.vx ) {
//~ FntPrint("BL x : %d, y : %d\n", camAngles[ curCamAngle ]->fw.v3.vx, camAngles[ curCamAngle ]->fw.v3.vy);
//~ FntPrint("BR x : %d, y : %d\n", camAngles[ curCamAngle ]->fw.v2.vx, camAngles[ curCamAngle ]->fw.v2.vy);
//~ FntPrint("Pos : %d\n", checkLineW( &camAngles[ curCamAngle ]->fw.v3, &camAngles[ curCamAngle ]->fw.v2, actorPtr) );
//~ FntPrint("Pos : %d\n", checkLineW( &camAngles[ curCamAngle ]->bw.v2, &camAngles[ curCamAngle ]->bw.v3, actorPtr) );
// If actor in camAngle->fw area of screen
if ( checkLineW( &camAngles[ curCamAngle ]->fw.v3, &camAngles[ curCamAngle ]->fw.v2, actorPtr) == -1 &&
( checkLineW( &camAngles[ curCamAngle ]->bw.v2, &camAngles[ curCamAngle ]->bw.v3, actorPtr) >= 0
)
) {
if (curCamAngle < 5) {
curCamAngle++;
camPtr = camAngles[ curCamAngle ];
LoadTexture(camPtr->tim_data, camPtr->BGtim);
}
}
}
if ( camAngles[ curCamAngle ]->bw.v0.vx ) {
//~ FntPrint("BL x : %d, y : %d\n", camAngles[ curCamAngle ]->bw.v3.vx, camAngles[ curCamAngle ]->bw.v3.vy);
//~ FntPrint("BR x : %d, y : %d\n", camAngles[ curCamAngle ]->bw.v2.vx, camAngles[ curCamAngle ]->bw.v2.vy);
//~ // FntPrint("Pos : %d\n", checkLineW( &camAngles[ curCamAngle ]->bw.v2, &camAngles[ curCamAngle ]->bw.v3, actorPtr) );
// If actor in camAngle->bw area of screen
if ( checkLineW( &camAngles[ curCamAngle ]->fw.v3, &camAngles[ curCamAngle ]->fw.v2, actorPtr) >= 0 &&
checkLineW( &camAngles[ curCamAngle ]->bw.v2, &camAngles[ curCamAngle ]->bw.v3, actorPtr) == -1
) {
if (curCamAngle > 0) {
curCamAngle--;
camPtr = camAngles[ curCamAngle ];
LoadTexture(camPtr->tim_data, camPtr->BGtim);
}
}
}
}
setCameraPos(&camera, camPtr->campos->pos, camPtr->campos->rot);
}
// Flyby mode with LERP from camStart to camEnd
if (camMode == 4) {
// If key pos exist for camera
2021-04-13 16:52:48 +02:00
if (camPath->len) {
2021-04-10 14:22:48 +02:00
// Lerping sequence has not begun
if (!lerping){
// Set cam start position ( first key pos )
2021-04-13 16:52:48 +02:00
camera.pos.vx = camPath->points[camPath->cursor].vx;
2021-04-10 14:22:48 +02:00
2021-04-13 16:52:48 +02:00
camera.pos.vy = camPath->points[camPath->cursor].vy;
2021-04-10 14:22:48 +02:00
2021-04-13 16:52:48 +02:00
camera.pos.vz = camPath->points[camPath->cursor].vz;
2021-04-10 14:22:48 +02:00
// Lerping sequence is starting
lerping = 1;
// Set cam pos index to 0
2021-04-13 16:52:48 +02:00
camPath->pos = 0;
2021-04-10 14:22:48 +02:00
}
// Pre calculated sqrt ( see psqrt() )
dist = psqrt( (posToActor.vx * posToActor.vx ) + (posToActor.vz * posToActor.vz));
// Fixed point precision 2^12 == 4096
int precision = 12;
2021-04-13 16:52:48 +02:00
camera.pos.vx = lerpD(camPath->points[camPath->cursor].vx << precision, camPath->points[camPath->cursor+1].vx << precision, camPath->pos << precision) >> precision;
2021-04-10 14:22:48 +02:00
2021-04-13 16:52:48 +02:00
camera.pos.vy = lerpD(camPath->points[camPath->cursor].vy << precision, camPath->points[camPath->cursor+1].vy << precision, camPath->pos << precision) >> precision;
2021-04-10 14:22:48 +02:00
2021-04-13 16:52:48 +02:00
camera.pos.vz = lerpD(camPath->points[camPath->cursor].vz << precision, camPath->points[camPath->cursor+1].vz << precision, camPath->pos << precision) >> precision;
2021-04-10 14:22:48 +02:00
2021-04-13 16:52:48 +02:00
//~ FntPrint("Cam %d, %d\n", (int32_t)camPath->points[camPath->cursor].vx, camPath->points[camPath->cursor+1].vx);
2021-04-10 14:22:48 +02:00
//~ FntPrint("Cam %d, %d, %d\n", camera.pos.vx, camera.pos.vy, camera.pos.vz);
//~ FntPrint("Theta y: %d x: %d\n", theta.vy, theta.vx);
2021-04-13 16:52:48 +02:00
//~ FntPrint("Pos: %d Cur: %d\nTheta y: %d x: %d\n", camPath->pos, camPath->cursor, theta.vy, theta.vx);
2021-04-10 14:22:48 +02:00
// Linearly increment the lerp factor
2021-04-13 16:52:48 +02:00
camPath->pos += 20;
2021-04-10 14:22:48 +02:00
// If camera has reached next key pos, reset pos index, move cursor to next key pos
2021-04-13 16:52:48 +02:00
if (camPath->pos > (1 << precision) ){
2021-04-10 14:22:48 +02:00
2021-04-13 16:52:48 +02:00
camPath->pos = 0;
2021-04-10 14:22:48 +02:00
2021-04-13 16:52:48 +02:00
camPath->cursor ++;
2021-04-10 14:22:48 +02:00
}
// Last key pos is reached, reset cursor to first key pos, lerping sequence is over
2021-04-13 16:52:48 +02:00
if ( camPath->cursor == camPath->len - 1 ){
2021-04-10 14:22:48 +02:00
lerping = 0;
2021-04-13 16:52:48 +02:00
camPath->cursor = 0;
2021-04-10 14:22:48 +02:00
}
} else {
// if no key pos exists, switch to next camMode
camMode ++; }
}
// Camera "on a rail" - cam is tracking actor, and moving with constraints on all axis
if (camMode == 5) {
// track actor. If theta (actor/cam rotation angle) is above or below an arbitrary angle,
// move cam so that the angle doesn't increase/decrease anymore.
short cameraSpeed = 40;
2021-04-13 16:52:48 +02:00
if (camPath->len) {
2021-04-10 14:22:48 +02:00
// Lerping sequence has not begun
if (!lerping){
// Set cam start position ( first key pos )
2021-04-13 16:52:48 +02:00
camera.pos.vx = camPath->points[camPath->cursor].vx;
2021-04-10 14:22:48 +02:00
2021-04-13 16:52:48 +02:00
camera.pos.vy = camPath->points[camPath->cursor].vy;
2021-04-10 14:22:48 +02:00
2021-04-13 16:52:48 +02:00
camera.pos.vz = camPath->points[camPath->cursor].vz;
2021-04-10 14:22:48 +02:00
// Lerping sequence is starting
lerping = 1;
// Set cam pos index to 0
2021-04-13 16:52:48 +02:00
camPath->pos = 0;
2021-04-10 14:22:48 +02:00
}
// Pre calculated sqrt ( see psqrt() )
dist = psqrt( (posToActor.vx * posToActor.vx ) + (posToActor.vz * posToActor.vz));
// Fixed point precision 2^12 == 4096
short precision = 12;
2021-04-13 16:52:48 +02:00
camera.pos.vx = lerpD(camPath->points[camPath->cursor].vx << precision, camPath->points[camPath->cursor + 1].vx << precision, camPath->pos << precision) >> precision;
2021-04-10 14:22:48 +02:00
2021-04-13 16:52:48 +02:00
camera.pos.vy = lerpD(camPath->points[camPath->cursor].vy << precision, camPath->points[camPath->cursor + 1].vy << precision, camPath->pos << precision) >> precision;
2021-04-10 14:22:48 +02:00
2021-04-13 16:52:48 +02:00
camera.pos.vz = lerpD(camPath->points[camPath->cursor].vz << precision, camPath->points[camPath->cursor + 1].vz << precision, camPath->pos << precision) >> precision;
2021-04-10 14:22:48 +02:00
//~ FntPrint("%d %d %d %d\n", camAngleToAct.vy, camera.pos.vx, camera.rot.vy, dist);
2021-04-13 16:52:48 +02:00
// Ony move cam if position is between first camPath->vx and last camPath->vx
2021-04-10 14:22:48 +02:00
2021-04-13 16:52:48 +02:00
if ( camAngleToAct.vy < -50 && camera.pos.vx > camPath->points[camPath->len - 1].vx ) {
2021-04-10 14:22:48 +02:00
// Clamp camPath position to cameraSpeed
2021-04-13 16:52:48 +02:00
camPath->pos += dist < cameraSpeed ? 0 : cameraSpeed ;
2021-04-10 14:22:48 +02:00
}
2021-04-13 16:52:48 +02:00
if ( camAngleToAct.vy > 50 && camera.pos.vx > camPath->points[camPath->cursor].vx ) {
2021-04-10 14:22:48 +02:00
2021-04-13 16:52:48 +02:00
camPath->pos -= dist < cameraSpeed ? 0 : cameraSpeed;
2021-04-10 14:22:48 +02:00
}
// If camera has reached next key pos, reset pos index, move cursor to next key pos
2021-04-13 16:52:48 +02:00
if (camPath->pos > (1 << precision) ){
2021-04-10 14:22:48 +02:00
2021-04-13 16:52:48 +02:00
camPath->pos = 0;
2021-04-10 14:22:48 +02:00
2021-04-13 16:52:48 +02:00
camPath->cursor ++;
2021-04-10 14:22:48 +02:00
}
2021-04-13 16:52:48 +02:00
if (camPath->pos < -100 ){
2021-04-10 14:22:48 +02:00
2021-04-13 16:52:48 +02:00
camPath->pos = 1 << precision;
2021-04-10 14:22:48 +02:00
2021-04-13 16:52:48 +02:00
camPath->cursor --;
2021-04-10 14:22:48 +02:00
}
// Last key pos is reached, reset cursor to first key pos, lerping sequence is over
2021-04-13 16:52:48 +02:00
if ( camPath->cursor == camPath->len - 1 || camPath->cursor < 0 ){
2021-04-10 14:22:48 +02:00
lerping = 0;
2021-04-13 16:52:48 +02:00
camPath->cursor = 0;
2021-04-10 14:22:48 +02:00
}
} else {
// if no key pos exists, switch to next camMode
camMode ++;
}
}
// Spatial partitioning
2021-04-16 20:22:03 +02:00
if (curNode){
2021-04-10 14:22:48 +02:00
2021-04-16 20:22:03 +02:00
for ( int msh = 0; msh < curNode->siblings->index; msh ++ ) {
2021-04-10 14:22:48 +02:00
2021-04-16 20:22:03 +02:00
// Actor
2021-04-10 14:22:48 +02:00
2021-04-16 20:22:03 +02:00
if ( !getIntCollision( *actorPtr->body , *curNode->siblings->list[msh]->plane->body).vx &&
!getIntCollision( *actorPtr->body , *curNode->siblings->list[msh]->plane->body).vz )
{
2021-04-10 14:22:48 +02:00
2021-04-16 20:22:03 +02:00
if ( curNode != curNode->siblings->list[msh] ) {
curNode = curNode->siblings->list[msh];
2021-04-10 14:22:48 +02:00
2021-04-16 20:22:03 +02:00
levelPtr = curNode->plane;
}
2021-04-10 14:22:48 +02:00
}
2021-04-16 20:22:03 +02:00
// DONTNEED ?
// Moveable prop
//~ if ( !getIntCollision( *propPtr->body , *curNode->siblings->list[msh]->plane->body).vx &&
//~ !getIntCollision( *propPtr->body , *curNode->siblings->list[msh]->plane->body).vz ) {
2021-04-10 14:22:48 +02:00
2021-04-16 20:22:03 +02:00
//~ if ( propPtr->node != curNode->siblings->list[ msh ]){
//~ propPtr->node = curNode->siblings->list[ msh ];
//~ }
2021-04-10 14:22:48 +02:00
//~ }
2021-04-16 20:22:03 +02:00
if ( !getIntCollision( *propPtr->body , *curNode->plane->body).vx &&
!getIntCollision( *propPtr->body , *curNode->plane->body).vz ) {
propPtr->node = curNode;
}
2021-04-10 14:22:48 +02:00
}
}
// Physics
if ( physics ) {
// if(time%1 == 0){
2021-04-13 16:52:48 +02:00
for ( int k = 0; k < *meshes_length; k ++ ) {
2021-04-10 14:22:48 +02:00
//~ for ( int k = 0; k < curNode->objects->index ; k ++){
2021-04-15 18:18:39 +02:00
if ( ( meshes[k]->isRigidBody == 1 ) ) {
2021-04-10 14:22:48 +02:00
//~ if ( ( *curNode->rigidbodies->list[k]->isRigidBody == 1 ) ) {
//~ applyAcceleration(curNode->rigidbodies->list[k]->body);
2021-04-15 18:18:39 +02:00
applyAcceleration( meshes[k]->body );
2021-04-10 14:22:48 +02:00
// Get col with level ( modelgnd_body )
col_lvl = getIntCollision( *meshes[k]->body , *levelPtr->body );
col_sphere = getIntCollision( *propPtr->body, *propPtr->node->plane->body );
// col_sphere = getIntCollision( *propPtr->body, *levelPtr->body );
col_sphere_act = getExtCollision( *actorPtr->body, *propPtr->body );
// If no col with ground, fall off
if ( col_lvl.vy ) {
if ( !col_lvl.vx && !col_lvl.vz ) {
actorPtr->body->position.vy = actorPtr->body->min.vy;
}
}
if (col_sphere.vy){
if ( !col_sphere.vx && !col_sphere.vz ) {
propPtr->body->position.vy = propPtr->body->min.vy;
}
}
if (col_sphere_act.vx && col_sphere_act.vz ) {
propPtr->body->velocity.vx += actorPtr->body->velocity.vx;
propPtr->body->velocity.vz += actorPtr->body->velocity.vz;
if ( propPtr->body->velocity.vx ) {
2021-04-15 18:18:39 +02:00
VECTOR L = angularMom( *propPtr->body );
2021-04-10 14:22:48 +02:00
2021-04-15 18:18:39 +02:00
propPtr->rot.vz -= L.vx;
2021-04-10 14:22:48 +02:00
}
if ( propPtr->body->velocity.vz ) {
VECTOR L = angularMom( *propPtr->body );
2021-04-15 18:18:39 +02:00
propPtr->rot.vx -= L.vz;
2021-04-10 14:22:48 +02:00
}
}
2021-04-15 18:18:39 +02:00
meshes[k]->pos.vx = meshes[k]->body->position.vx;
2021-04-10 14:22:48 +02:00
2021-04-15 18:18:39 +02:00
meshes[k]->pos.vy = meshes[k]->body->position.vy ;
2021-04-10 14:22:48 +02:00
2021-04-15 18:18:39 +02:00
meshes[k]->pos.vz = meshes[k]->body->position.vz;
2021-04-10 14:22:48 +02:00
}
meshes[k]->body->velocity.vy = 0;
meshes[k]->body->velocity.vx = 0;
meshes[k]->body->velocity.vz = 0;
}
// }
}
if ( (camMode == 2) && (camPtr->tim_data ) ) {
2021-04-15 18:18:39 +02:00
worldToScreen( &actorPtr->pos, &actorPtr->pos2D );
2021-04-10 14:22:48 +02:00
}
// Camera setup
// position of cam relative to actor
2021-04-15 18:18:39 +02:00
posToActor.vx = actorPtr->pos.vx + camera.pos.vx;
2021-04-10 14:22:48 +02:00
2021-04-15 18:18:39 +02:00
posToActor.vz = actorPtr->pos.vz + camera.pos.vz;
2021-04-10 14:22:48 +02:00
2021-04-15 18:18:39 +02:00
posToActor.vy = actorPtr->pos.vy + camera.pos.vy;
2021-04-10 14:22:48 +02:00
// Polygon drawing
2021-04-16 20:22:03 +02:00
if (curNode){
static long Flag;
if ( (camMode == 2) && (camPtr->tim_data ) ) {
drawBG(camPtr, &nextpri, otdisc[db], &db);
2021-04-10 14:22:48 +02:00
2021-04-16 20:22:03 +02:00
// Loop on camAngles
for ( int mesh = 0 ; mesh < camAngles[ curCamAngle ]->index; mesh ++ ) {
transformMesh(&camera, camAngles[curCamAngle]->objects[mesh]);
drawPoly(camAngles[curCamAngle]->objects[mesh], &Flag, atime, &camMode, &nextpri, ot[db], &db, &draw[db]);
// int * camMode, char ** nextpri, u_long * ot, char * db, DRAWENV * draw)
}
}
else {
2021-04-10 14:22:48 +02:00
2021-04-16 20:22:03 +02:00
// Draw current node's plane
drawPoly( curNode->plane, &Flag, atime, &camMode, &nextpri, ot[db], &db, &draw[db]);
2021-04-10 14:22:48 +02:00
2021-04-16 20:22:03 +02:00
// Draw surrounding planes
2021-04-10 14:22:48 +02:00
2021-04-16 20:22:03 +02:00
for ( int sibling = 0; sibling < curNode->siblings->index; sibling++ ) {
2021-04-10 14:22:48 +02:00
2021-04-16 20:22:03 +02:00
drawPoly(curNode->siblings->list[ sibling ]->plane, &Flag, atime, &camMode, &nextpri, ot[db], &db, &draw[db]);
}
// Draw adjacent planes's children
for ( int sibling = 0; sibling < curNode->siblings->index; sibling++ ) {
for ( int object = 0; object < curNode->siblings->list[ sibling ]->objects->index; object++ ) {
long t = 0;
transformMesh(&camera, curNode->siblings->list[ sibling ]->objects->list[ object ]);
drawPoly( curNode->siblings->list[ sibling ]->objects->list[ object ], &Flag, atime, &camMode, &nextpri, ot[db], &db, &draw[db]);
}
}
// Draw current plane children
for ( int object = 0; object < curNode->objects->index; object++ ) {
transformMesh(&camera, curNode->objects->list[ object ]);
2021-04-10 14:22:48 +02:00
2021-04-16 20:22:03 +02:00
drawPoly( curNode->objects->list[ object ], &Flag, atime, &camMode, &nextpri, ot[db], &db, &draw[db]);
2021-04-10 14:22:48 +02:00
2021-04-16 20:22:03 +02:00
}
2021-04-10 14:22:48 +02:00
2021-04-16 20:22:03 +02:00
// Draw rigidbodies
for ( int object = 0; object < curNode->rigidbodies->index; object++ ) {
transformMesh(&camera, curNode->rigidbodies->list[ object ]);
2021-04-10 14:22:48 +02:00
2021-04-16 20:22:03 +02:00
drawPoly( curNode->rigidbodies->list[ object ], &Flag, atime, &camMode, &nextpri, ot[db], &db, &draw[db]);
}
2021-04-10 14:22:48 +02:00
2021-04-16 20:22:03 +02:00
}
2021-04-10 14:22:48 +02:00
}
// Find and apply light rotation matrix
RotMatrix(&lgtang, &rotlgt);
2021-04-13 16:52:48 +02:00
MulMatrix0(lgtmat, &rotlgt, &light);
2021-04-10 14:22:48 +02:00
SetLightMatrix(&light);
// Set camera
applyCamera(&camera);
// Add secondary OT to main OT
AddPrims(otdisc[db], ot[db] + OTLEN - 1, ot[db]);
//~ FntPrint("CurNode : %x\nIndex: %d", curNode, curNode->siblings->index);
2021-04-16 20:22:03 +02:00
FntPrint("Time : %d dt :%d\n", VSync(-1) / 60, dt);
2021-04-10 14:22:48 +02:00
//~ FntPrint("%d\n", curCamAngle );
//~ FntPrint("%x\n", primbuff[db]);
//~ FntPrint("Actor : %d %d\n", actorPtr->pos->vx, actorPtr->pos->vy);
//~ FntPrint("%d %d\n", actorPtr->pos->vx, actorPtr->pos->vz);
//~ FntPrint("%d %d\n", actorPtr->pos2D.vx + CENTERX, actorPtr->pos2D.vy + CENTERY);
//~ FntPrint(" %d %d %d\n", wp.vx, wp.vy, wp.vz);
FntFlush(-1);
display( &disp[db], &draw[db], otdisc[db], primbuff[db], &nextpri, &db);
//~ display(disp, draw, otdisc[db], primbuff[db], nextpri, db);
//~ frame = VSync(-1);
}
return 0;
}
void callback() {
u_short pad = PadRead(0);
static u_short lastPad;
static short forceApplied = 0;
int div = 32;
static int lerpValues[4096 >> 7];
static short cursor = 0;
//~ static short curCamAngle = 0;
if( !lerpValues[0] ) {
for ( long long i = 0; i < div ; i++ ){
lerpValues[(div-1)-i] = lerp(-24, -264, easeIn(i));
}
}
if( timer ) {
timer--;
}
if( cursor>0 ) {
cursor--;
}
if ( pad & PADR1 && !timer ) {
if (!camPtr->tim_data){
if(camMode < 6){
camMode ++;
lerping = 0;
} else {
setCameraPos(&camera, camPtr->campos->pos, camPtr->campos->rot);
2021-04-13 16:52:48 +02:00
camPath->cursor = 0;
2021-04-10 14:22:48 +02:00
camMode = 0;
lerping = 0;
}
} else {
if (curCamAngle > 4) {
curCamAngle = 0;
}
if (curCamAngle < 5) {
curCamAngle++;
camPtr = camAngles[ curCamAngle ];
LoadTexture(camPtr->tim_data, camPtr->BGtim);
}
}
lastPad = pad;
timer = 10;
}
if ( !(pad & PADR1) && lastPad & PADR1 ) {
//~ pressed = 0;
}
if ( pad & PADL2 ) {
lgtang.vy += 32;
}
if ( pad & PADL1 ) {
lgtang.vz += 32;
}
if ( pad & PADRup && !timer ){
2021-04-15 18:18:39 +02:00
if (actorPtr->isPrism){
2021-04-10 14:22:48 +02:00
2021-04-15 18:18:39 +02:00
actorPtr->isPrism = 0;
2021-04-10 14:22:48 +02:00
} else {
2021-04-15 18:18:39 +02:00
actorPtr->isPrism = 1;
2021-04-10 14:22:48 +02:00
}
timer = 10;
lastPad = pad;
}
if ( pad & PADRdown && !timer ){
//~ if (actorPtr->body->gForce.vy >= 0 && actorPtr->body->position.vy >= actorPtr->body->min.vy ){
//~ forceApplied -= 150;
//~ }
cursor = div - 15;
timer = 30;
lastPad = pad;
}
if ( !(pad & PADRdown) && lastPad & PADRdown ) {
//~ lastPad = pad;
}
if ( pad & PADRleft && !timer ) {
if (actorPtr->anim->interpolate){
actorPtr->anim->interpolate = 0;
} else {
actorPtr->anim->interpolate = 1;
}
timer = 10;
lastPad = pad;
}
if ( pad & PADLup ) {
2021-04-15 18:18:39 +02:00
actorPtr->body->gForce.vz = getVectorTo(fVecActor, actorPtr->pos).vz >> 8 ;
2021-04-10 14:22:48 +02:00
2021-04-15 18:18:39 +02:00
actorPtr->body->gForce.vx = -getVectorTo(fVecActor, actorPtr->pos).vx >> 8 ;
2021-04-10 14:22:48 +02:00
lastPad = pad;
}
if ( !(pad & PADLup) && lastPad & PADLup) {
actorPtr->body->gForce.vz = 0;
actorPtr->body->gForce.vx = 0;
}
if ( pad & PADLdown ) {
2021-04-15 18:18:39 +02:00
actorPtr->body->gForce.vz = -getVectorTo(fVecActor, actorPtr->pos).vz >> 8 ;
2021-04-10 14:22:48 +02:00
2021-04-15 18:18:39 +02:00
actorPtr->body->gForce.vx = getVectorTo(fVecActor, actorPtr->pos).vx >> 8 ;
2021-04-10 14:22:48 +02:00
lastPad = pad;
}
if ( !(pad & PADLdown) && lastPad & PADLdown) {
actorPtr->body->gForce.vz = 0;
actorPtr->body->gForce.vx = 0;
lastPad = pad;
}
if ( pad & PADLleft ) {
2021-04-15 18:18:39 +02:00
actorPtr->rot.vy -= 32;
2021-04-10 14:22:48 +02:00
lastPad = pad;
}
if ( pad & PADLright ) {
2021-04-15 18:18:39 +02:00
actorPtr->rot.vy += 32;
2021-04-10 14:22:48 +02:00
lastPad = pad;
}
2021-04-16 20:22:03 +02:00
if ( pad & PADselect && !timer ) {
if (!levelHasChanged){
level = !level;
levelHasChanged = 1;
}
timer = 30;
lastPad = pad;
}
FntPrint("level :%d", level);
2021-04-10 14:22:48 +02:00
if ( cursor ) {
actorPtr->body->position.vy = lerpValues[cursor];}
};