630 lines
26 KiB
C
630 lines
26 KiB
C
// 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
|
|
#include "../include/psx.h"
|
|
#include "../include/pad.h"
|
|
#include "../include/math.h"
|
|
#include "../include/camera.h"
|
|
#include "../include/physics.h"
|
|
#include "../include/graphics.h"
|
|
#include "../include/space.h"
|
|
#include "../include/sound.h"
|
|
|
|
#define USECD
|
|
|
|
// START OVERLAY
|
|
extern u_long load_all_overlays_here;
|
|
extern u_long __lvl0_end;
|
|
extern u_long __lvl1_end;
|
|
u_long overlaySize = 0;
|
|
|
|
#include "../levels/level0.h"
|
|
#include "../levels/level1.h"
|
|
|
|
// Levels
|
|
u_char level = 0;
|
|
u_short levelWas = 0;
|
|
u_short levelHasChanged = 0;
|
|
// Overlay
|
|
static char* overlayFile;
|
|
// 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]; // Primitive list // That's our prim buffer
|
|
int primcnt=0; // Primitive counter
|
|
char * nextpri = primbuff[0]; // Primitive counter
|
|
char db = 0; // Current buffer counter
|
|
// Lighting
|
|
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};
|
|
MATRIX rotlgt, light;
|
|
short vs;
|
|
CAMERA camera = {0};
|
|
// Physics
|
|
u_long time = 0;
|
|
u_long timeS = 0;
|
|
//Pads
|
|
Controller_Buffer controllers[2]; // Buffers for reading controllers
|
|
Controller_Data theControllers[8]; // Processed controller data
|
|
int pressed = 0;
|
|
u_short timer = 0;
|
|
// Cam stuff
|
|
int camMode = ACTOR; // Cam mode, see defines.h, l.6
|
|
VECTOR angle = {250,0,0,0};
|
|
VECTOR angleCam = {0,0,0,0};
|
|
VECTOR posToActor = {0, 0, 0, 0}; // position of camera relative to actor
|
|
VECTOR * camAngleToAct; // rotation angles for the camera to point at actor
|
|
int dist = 150;
|
|
int lerping = 0;
|
|
short curCamAngle = 0;
|
|
// Actor's forward vector (used for dualshock)
|
|
VECTOR fVecActor;
|
|
u_long triCount = 0;
|
|
LEVEL curLvl;
|
|
LEVEL * loadLvl;
|
|
// Actor start position
|
|
VECTOR actorStartPos = {0};
|
|
VECTOR actorStartRot = {0};
|
|
NODE * actorStartNode;
|
|
// Prop start position
|
|
VECTOR propStartPos = {0};
|
|
VECTOR propStartRot = {0};
|
|
NODE * propStartNode;
|
|
// Callback function is used for pads
|
|
void callback();
|
|
// variable FPS
|
|
long oldTime = 0;
|
|
long dt = 0;
|
|
// Physics/collisions
|
|
short physics = 1;
|
|
VECTOR col = {0};
|
|
// Animation timing
|
|
// time % timediv == animation time
|
|
// Time divisor
|
|
short timediv = 1;
|
|
// Animation time, see l.206
|
|
int atime = 0;
|
|
// Sound
|
|
// VAG playback
|
|
// Memory management table ; allow MALLOC_MAX calls to SpuMalloc() - libref47.pdf p.1044
|
|
char spu_malloc_rec[SPU_MALLOC_RECSIZ * (2 + MALLOC_MAX + 1)];
|
|
// SPU settings
|
|
SpuCommonAttr spuSettings; // structure for changing common voice attributes
|
|
SpuVoiceAttr voiceAttributes ; // structure for changing individual voice attributes
|
|
// Keep track of XA Sample currently playing
|
|
int sample = -1;
|
|
|
|
int main() {
|
|
// Set matrices pointers to scratchpad
|
|
camera.mat = dc_camMat;
|
|
camera.pos = dc_camPos;
|
|
camera.rot = dc_camRot;
|
|
camAngleToAct = dc_actorRot;
|
|
// Load level file according to level, l.39
|
|
if ( level == 0 ){
|
|
overlayFile = "\\level0.bin;1";
|
|
overlaySize = __lvl0_end;
|
|
loadLvl = &level0;
|
|
} else if ( level == 1) {
|
|
overlayFile = "\\level1.bin;1";
|
|
overlaySize = __lvl1_end;
|
|
//~ loadLvl = &level1;
|
|
}
|
|
// Load overlay from cd
|
|
#ifdef USECD
|
|
CdInit();
|
|
// Load level
|
|
LoadLevelCD(overlayFile, &load_all_overlays_here);
|
|
#endif
|
|
// TODO : Add switch case to get the correct pointers
|
|
// Get needed pointers from level file
|
|
if ( level == 0 ) {
|
|
LvlPtrSet( &curLvl, &level0);
|
|
} else if ( level == 1) {
|
|
//~ 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.BGc, curLvl.BKc, &FC);
|
|
// Init Pads
|
|
InitPAD(controllers[0].pad, 34, controllers[1].pad, 34);
|
|
StartPAD();
|
|
// Generate Cos table
|
|
generateTable();
|
|
// Set function 'callback' on v-sync
|
|
VSyncCallback(callback);
|
|
// Load textures
|
|
for (int k = 0; k < *curLvl.meshes_length ; k++){
|
|
// Check data exists
|
|
if (curLvl.meshes[k]->tim_data){
|
|
LoadTexture(curLvl.meshes[k]->tim_data, curLvl.meshes[k]->tim);
|
|
}
|
|
}
|
|
// Load current BG if exists, and set cam mode accordingly
|
|
if (curLvl.camPtr->tim_data){
|
|
// Switch to proper cam mode and angle
|
|
camMode = FIXED;
|
|
curCamAngle = 1;
|
|
LoadTexture(curLvl.camPtr->tim_data, curLvl.camPtr->BGtim);
|
|
}
|
|
// Polycount
|
|
for (int k = 0; k < *curLvl.meshes_length; k++){
|
|
triCount += curLvl.meshes[k]->tmesh->len;
|
|
}
|
|
// Save actor starting pos
|
|
copyVector(&actorStartPos, &curLvl.actorPtr->body->position);
|
|
copyVector(&actorStartRot, &curLvl.actorPtr->rot);
|
|
actorStartNode = curLvl.curNode;
|
|
// Save prop starting pos
|
|
copyVector(&propStartPos, &curLvl.propPtr->body->position);
|
|
copyVector(&propStartRot, &curLvl.propPtr->rot);
|
|
propStartNode = curLvl.propPtr->node;
|
|
// Set camera starting pos
|
|
setCameraPos(&camera, &curLvl.camPtr->campos->pos, &curLvl.camPtr->campos->rot);
|
|
// Time counter
|
|
oldTime = GetRCnt(RCntCNT1);
|
|
// Sound
|
|
SpuInit();
|
|
// Load level's VAGs to SPU
|
|
setLvlVAG(&curLvl, &spuSettings, &voiceAttributes, spu_malloc_rec);
|
|
// Set XA sample
|
|
sample = 0;
|
|
setLvlXA(&curLvl, sample);
|
|
// Main loop
|
|
//~ while ( VSync(VSYNC) ) {
|
|
while ( 1 ) {
|
|
dt = GetRCnt(RCntCNT1) - oldTime;
|
|
oldTime = GetRCnt(RCntCNT1);
|
|
// XA playback (keep track of playback and loop XA)
|
|
XAplayback(&curLvl, sample, dt);
|
|
// Check if level has changed
|
|
// TODO : Proper level system / loader
|
|
if ( levelWas != level ){
|
|
// If so, load other level
|
|
switch ( level ){
|
|
case 0:
|
|
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";
|
|
loadLvl = &level0;
|
|
break;
|
|
}
|
|
#ifdef USECD
|
|
LoadLevelCD( overlayFile, &load_all_overlays_here );
|
|
#endif
|
|
SwitchLevel( &curLvl, loadLvl);
|
|
// Save actor starting pos
|
|
copyVector(&actorStartPos, &curLvl.actorPtr->body->position);
|
|
copyVector(&actorStartRot, &curLvl.actorPtr->rot);
|
|
actorStartNode = curLvl.curNode;
|
|
// Save prop starting pos
|
|
copyVector(&propStartPos, &curLvl.propPtr->body->position);
|
|
copyVector(&propStartRot, &curLvl.propPtr->rot);
|
|
propStartNode = curLvl.propPtr->node;
|
|
// Set level lighting
|
|
setLightEnv(draw, curLvl.BGc, curLvl.BKc);
|
|
levelWas = level;
|
|
// Load level's VAGs to SPU
|
|
setLvlVAG(&curLvl, &spuSettings, &voiceAttributes, spu_malloc_rec);
|
|
// Set
|
|
setLvlXA(&curLvl, sample);
|
|
}
|
|
//~ FntPrint("Ovl:%s\nLvl : %x\nLvl: %d %d \n%x", overlayFile, &level, level, levelWas, loadLvl);
|
|
// atime is used for animations timing
|
|
timediv = 1;
|
|
// If timediv is > 1, animation time will be slower
|
|
if (time % timediv == 0){
|
|
atime ++;
|
|
}
|
|
// Reset player/prop pos
|
|
if(curLvl.actorPtr->pos.vy >= 200){
|
|
playSFX(&voiceAttributes, curLvl.levelSounds->sounds[6]->VAGsample, curLvl.levelSounds->sounds[6]->volumeL, curLvl.levelSounds->sounds[6]->volumeR);
|
|
respawnMesh(&curLvl, curLvl.actorPtr, &actorStartRot, &actorStartPos, actorStartNode );
|
|
}
|
|
if(curLvl.propPtr->pos.vy >= 200){
|
|
playSFX(&voiceAttributes, curLvl.levelSounds->sounds[3]->VAGsample, curLvl.levelSounds->sounds[3]->volumeL, curLvl.levelSounds->sounds[3]->volumeR);
|
|
respawnMesh(&curLvl, curLvl.propPtr, &propStartRot, &propStartPos, propStartNode );
|
|
}
|
|
// Spatialize Sound
|
|
setSFXdist(&curLvl, &camera, camMode);
|
|
// Spatial partitioning
|
|
if (curLvl.curNode){
|
|
for ( int msh = 0; msh < curLvl.curNode->siblings->index; msh ++ ) {
|
|
// Set Actor node
|
|
// If actor is out of plane's X,Z coordinates...
|
|
if ( !getIntCollision( *curLvl.actorPtr->body , *curLvl.curNode->siblings->list[msh]->plane->body).vx &&
|
|
!getIntCollision( *curLvl.actorPtr->body , *curLvl.curNode->siblings->list[msh]->plane->body).vz )
|
|
{
|
|
// if current node is not already pointing to a sibling
|
|
if ( curLvl.curNode != curLvl.curNode->siblings->list[msh] ) {
|
|
// make it point to siblings
|
|
curLvl.curNode = curLvl.curNode->siblings->list[msh];
|
|
// set current plane
|
|
curLvl.levelPtr = curLvl.curNode->plane;
|
|
}
|
|
}
|
|
// Set Prop node
|
|
if ( !getIntCollision( *curLvl.propPtr->body , *curLvl.curNode->plane->body).vx &&
|
|
!getIntCollision( *curLvl.propPtr->body , *curLvl.curNode->plane->body).vz ) {
|
|
curLvl.propPtr->node = curLvl.curNode;
|
|
}
|
|
}
|
|
}
|
|
// Physics
|
|
if ( physics ) {
|
|
u_char canMove = 1;
|
|
for ( int k = 0; k < *curLvl.meshes_length; k ++ ) {
|
|
if ( curLvl.meshes[k]->isRigidBody == 1 ) {
|
|
applyAcceleration( curLvl.meshes[k]->body, dt);
|
|
// Get col between props and level
|
|
if ( curLvl.meshes[k]->isProp ){
|
|
checkBodyCol( curLvl.meshes[k]->body , curLvl.meshes[k]->node->plane->body );
|
|
for (short obj=0; obj < curLvl.curNode->objects->index; obj++){
|
|
// If isWall, check collision
|
|
if ( curLvl.curNode->objects->list[obj]->isWall ){
|
|
if( getExtCollision( *curLvl.meshes[k]->body, *curLvl.curNode->objects->list[obj]->body ).vz &&
|
|
getExtCollision( *curLvl.meshes[k]->body, *curLvl.curNode->objects->list[obj]->body ).vx) {
|
|
curLvl.meshes[k]->body->position.vz = curLvl.meshes[k]->body->position.vz - curLvl.meshes[k]->body->velocity.vz ;
|
|
curLvl.meshes[k]->body->position.vx = curLvl.meshes[k]->body->position.vx - curLvl.meshes[k]->body->velocity.vx ;
|
|
canMove = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Get col between actor and level
|
|
if ( curLvl.meshes[k]->isActor ){
|
|
// Check col
|
|
checkBodyCol( curLvl.meshes[k]->body , curLvl.levelPtr->body );
|
|
// Get col between actor and current node's walls
|
|
// Loop on current node's objects
|
|
for (short obj=0; obj < curLvl.curNode->objects->index; obj++){
|
|
// If isWall, check collision
|
|
if ( curLvl.curNode->objects->list[obj]->isWall ){
|
|
if( getExtCollision( *curLvl.meshes[k]->body, *curLvl.curNode->objects->list[obj]->body ).vz &&
|
|
getExtCollision( *curLvl.meshes[k]->body, *curLvl.curNode->objects->list[obj]->body ).vx) {
|
|
curLvl.meshes[k]->body->position.vz = curLvl.meshes[k]->body->position.vz - curLvl.meshes[k]->body->velocity.vz ;
|
|
curLvl.meshes[k]->body->position.vx = curLvl.meshes[k]->body->position.vx - curLvl.meshes[k]->body->velocity.vx ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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 && canMove == 1 ) {
|
|
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);
|
|
}
|
|
setVector(&curLvl.meshes[k]->body->velocity, 0, 0, 0);
|
|
}
|
|
}
|
|
|
|
// Clear the main OT
|
|
ClearOTagR(otdisc[db], OT2LEN);
|
|
// Clear Secondary OT
|
|
ClearOTagR(ot[db], OTLEN);
|
|
// Set camera according to mode
|
|
setCameraMode(&curLvl, &camera, &posToActor, &angle, &angleCam, &curCamAngle, camMode, &lerping);
|
|
// Render scene
|
|
renderScene(&curLvl, &camera, &camMode, &nextpri, ot[db], otdisc[db], &db, &draw[db], curCamAngle, atime);
|
|
// Set camera
|
|
// Get position of cam relative to actor
|
|
addVector2(&curLvl.actorPtr->pos, camera.pos, &posToActor);
|
|
// Angle between camera and actor
|
|
applyVector( dc_actorRot,
|
|
(patan(dist, posToActor.vy) >> 4 ) - 256,
|
|
(patan(-posToActor.vx, -posToActor.vz) / 16) + 1024,
|
|
0,
|
|
=
|
|
);
|
|
// Point camera at actor unless camMode == FIXED
|
|
if (camMode != FIXED){ copyVector(dc_camRot, dc_actorRot); }
|
|
//
|
|
applyCamera(&camera);
|
|
|
|
// Find Actor's forward vector
|
|
setVector( &fVecActor,
|
|
curLvl.actorPtr->pos.vx + (nsin(curLvl.actorPtr->rot.vy/2)),
|
|
curLvl.actorPtr->pos.vy,
|
|
curLvl.actorPtr->pos.vz - (ncos(curLvl.actorPtr->rot.vy/2))
|
|
);
|
|
|
|
// Add secondary OT to main OT
|
|
AddPrims(otdisc[db], ot[db] + OTLEN - 1, ot[db]);
|
|
|
|
FntPrint("\n#Tri : %d\n", triCount);
|
|
FntPrint("#RCnt : %d %d\n", VSync(-1), dt);
|
|
//~ FntPrint("Dt : %d %d %d\n", 400/(dt+1), (XA_CDSPEED)/((400/(dt+1))+1), (curLvl.XA->samples[sample].end - curLvl.XA->samples[sample].start)<<12);
|
|
//~ FntPrint("XA : %d\n", (XA_CDSPEED)/((400/(dt+1))+1) );
|
|
//~ FntPrint("XA : %d\n", curLvl.XA->samples[sample].cursor );
|
|
FntPrint("CamAngle : %d\n", curCamAngle);
|
|
FntPrint("XA: %x\n", curLvl.XA);
|
|
FntPrint("Ofst: %d\n", curLvl.XA->banks[0]->offset);
|
|
FntPrint("Vol: %d %d\n", curLvl.levelSounds->sounds[0]->volumeL, curLvl.levelSounds->sounds[0]->volumeR );
|
|
FntPrint("Curanim : %x", curLvl.meshes[1]->currentAnim);
|
|
FntFlush(-1);
|
|
display( &disp[db], &draw[db], otdisc[db], primbuff[db], &nextpri, &db);
|
|
|
|
}
|
|
return 0;
|
|
}
|
|
void callback() {
|
|
// Pad 1
|
|
read_controller( &theControllers[0], &controllers[0].pad[0], 0 ); // Read controllers
|
|
// Pad 2
|
|
read_controller( &theControllers[1], &controllers[1].pad[0], 1 );
|
|
|
|
u_short PAD = ~*((u_short*)(&theControllers[0].button1));
|
|
|
|
static u_short lastPad;
|
|
static int lerpValues[4096 >> 7];
|
|
static short cursor = 0;
|
|
static short angleCamTimer = 0;
|
|
//~ static short forceApplied = 0;
|
|
int div = 32;
|
|
|
|
if( !lerpValues[0] ) {
|
|
for ( long long i = 0; i < div ; i++ ){
|
|
lerpValues[(div-1)-i] = lerp(-24, -264, easeIn(i));
|
|
}
|
|
}
|
|
if( timer ) {
|
|
timer--;
|
|
}
|
|
if (!timer){
|
|
curLvl.actorPtr->body->gForce.vy = 0;
|
|
}
|
|
if( cursor ) {
|
|
cursor--;
|
|
}
|
|
if (angleCam.vy > 2048 || angleCam.vy < -2048) {
|
|
angleCam.vy = 0;
|
|
}
|
|
if ( PAD & PadShldR1 && !(lastPad & PadShldR1) ) {
|
|
// Change camera angle switching mode if using pre-calculated BGs
|
|
if (!curLvl.camPtr->tim_data){
|
|
if(camMode < 5){
|
|
camMode ++;
|
|
lerping = 0;
|
|
} else {
|
|
setCameraPos(&camera, &curLvl.camPtr->campos->pos, &curLvl.camPtr->campos->rot);
|
|
curLvl.camPath->cursor = 0;
|
|
camMode = 0;
|
|
lerping = 0;
|
|
}
|
|
} else {
|
|
if (curCamAngle > 4) {
|
|
curCamAngle = 0;
|
|
}
|
|
if (curCamAngle < 5) {
|
|
curCamAngle++;
|
|
curLvl.camPtr = curLvl.camAngles[ curCamAngle ];
|
|
LoadTexture(curLvl.camPtr->tim_data, curLvl.camPtr->BGtim);
|
|
}
|
|
}
|
|
lastPad = PAD;
|
|
}
|
|
if ( !(PAD & PadShldR1) && lastPad & PadShldR1 ) {
|
|
lastPad = PAD;
|
|
}
|
|
if ( PAD & PadShldL2 ) {
|
|
dc_lgtangp->vy += 32;
|
|
}
|
|
if ( PAD & PadShldL1 ) {
|
|
dc_lgtangp->vz += 32;
|
|
}
|
|
if ( PAD & Triangle && !( lastPad & Triangle ) ){
|
|
if (curLvl.actorPtr->isPrism){
|
|
curLvl.actorPtr->isPrism = 0;
|
|
} else {
|
|
curLvl.actorPtr->isPrism = 1;
|
|
}
|
|
playSFX(&voiceAttributes, curLvl.levelSounds->sounds[0]->VAGsample, curLvl.levelSounds->sounds[0]->volumeL, curLvl.levelSounds->sounds[0]->volumeR );
|
|
//~ timer = 10;
|
|
lastPad = PAD;
|
|
}
|
|
if ( !(PAD & Triangle) && lastPad & Triangle ) {
|
|
lastPad = PAD;
|
|
}
|
|
if ( PAD & Square && !( lastPad & Square ) ){
|
|
playSFX(&voiceAttributes, curLvl.levelSounds->sounds[7]->VAGsample, curLvl.levelSounds->sounds[7]->volumeL, curLvl.levelSounds->sounds[7]->volumeR);
|
|
if ( curLvl.meshes[1]->currentAnim == 0 ||
|
|
curLvl.meshes[1]->currentAnim == curLvl.meshes[1]->anim_tracks->strips[0]
|
|
){
|
|
if (curLvl.meshes[1]->anim_tracks->index > 1) {
|
|
curLvl.meshes[1]->currentAnim = curLvl.meshes[1]->anim_tracks->strips[1];
|
|
}
|
|
} else {
|
|
//~ curLvl.meshes[1]->anim_tracks->strips[0]->interpolate = 1;
|
|
curLvl.meshes[1]->currentAnim = curLvl.meshes[1]->anim_tracks->strips[0];
|
|
}
|
|
//~ sample = 0;
|
|
//~ setXAsample(&XABank.samples[sample], &filter);
|
|
lastPad = PAD;
|
|
}
|
|
if ( !(PAD & Square) && lastPad & Square ) {
|
|
lastPad = PAD;
|
|
}
|
|
if ( PAD & Cross && !(lastPad & Cross) ){
|
|
if (curLvl.actorPtr->body->gForce.vy == 0 && (curLvl.actorPtr->body->position.vy - curLvl.actorPtr->body->min.vy) == curLvl.levelPtr->body->min.vy ){
|
|
// Use delta to find jump force
|
|
curLvl.actorPtr->body->gForce.vy = -200;
|
|
}
|
|
timer = 10;
|
|
playSFX(&voiceAttributes, curLvl.levelSounds->sounds[4]->VAGsample, curLvl.levelSounds->sounds[4]->volumeL, curLvl.levelSounds->sounds[4]->volumeR );
|
|
lastPad = PAD;
|
|
}
|
|
if ( !(PAD & Cross) && lastPad & Cross ) {
|
|
lastPad = PAD;
|
|
}
|
|
if ( PAD & Circle && !(PAD & lastPad) ){
|
|
playSFX(&voiceAttributes, curLvl.levelSounds->sounds[5]->VAGsample, curLvl.levelSounds->sounds[5]->volumeL, curLvl.levelSounds->sounds[5]->volumeR );
|
|
lastPad = PAD;
|
|
}
|
|
if ( !(PAD & Circle) && lastPad & Circle ) {
|
|
lastPad = PAD;
|
|
}
|
|
//~ if ( PAD & PadLeft && !(lastPad & PadLeft) ) {
|
|
|
|
//~ lastPad = PAD;
|
|
//~ }
|
|
//~ if ( !(PAD & PadLeft) && lastPad & PadLeft ) {
|
|
//~ lastPad = PAD;
|
|
//~ }
|
|
if (theControllers[0].type == 0x73){
|
|
// Analog stick L up
|
|
if ( theControllers[0].analog3 >= 0 && theControllers[0].analog3 < (128 - DS_DZ/2)) {
|
|
curLvl.actorPtr->body->gForce.vz = getVectorTo(fVecActor, curLvl.actorPtr->pos).vz * (128 - theControllers[0].analog3 ) >> 13 ;
|
|
curLvl.actorPtr->body->gForce.vx = -getVectorTo(fVecActor, curLvl.actorPtr->pos).vx * (128 - theControllers[0].analog3 ) >> 13 ;
|
|
}
|
|
// Analog stick L down
|
|
if ( theControllers[0].analog3 > (128 + DS_DZ/2) && theControllers[0].analog3 <= 255 ) {
|
|
curLvl.actorPtr->body->gForce.vz = -getVectorTo(fVecActor, curLvl.actorPtr->pos).vz * ( theControllers[0].analog3 - 128 ) >> 13 ;
|
|
curLvl.actorPtr->body->gForce.vx = getVectorTo(fVecActor, curLvl.actorPtr->pos).vx * ( theControllers[0].analog3 - 128 ) >> 13 ;
|
|
}
|
|
// Analog stick L dead zone
|
|
if ( theControllers[0].analog3 > (128 - DS_DZ/2) && theControllers[0].analog3 < (128 + DS_DZ/2) ) {
|
|
curLvl.actorPtr->body->gForce.vz = 0;
|
|
curLvl.actorPtr->body->gForce.vx = 0;
|
|
}
|
|
// Analog stick L left
|
|
if ( theControllers[0].analog2 >= 0 && theControllers[0].analog2 < (128 - DS_DZ/2) ) {
|
|
curLvl.actorPtr->rot.vy -= ( 64 * ( 128 - theControllers[0].analog2 ) ) >> 8 ;
|
|
}
|
|
// Analog stick L right
|
|
if ( theControllers[0].analog2 > (128 + DS_DZ/2) && theControllers[0].analog2 <= 255 ) {
|
|
curLvl.actorPtr->rot.vy += ( 64 * ( theControllers[0].analog2 - 128 ) ) >> 8 ;
|
|
}
|
|
}
|
|
if ( PAD & PadUp ) {
|
|
curLvl.actorPtr->body->gForce.vz = getVectorTo(fVecActor, curLvl.actorPtr->pos).vz >> 6 ;
|
|
curLvl.actorPtr->body->gForce.vx = -getVectorTo(fVecActor, curLvl.actorPtr->pos).vx >> 6;
|
|
lastPad = PAD;
|
|
}
|
|
if ( !(PAD & PadUp) && lastPad & PadUp) {
|
|
curLvl.actorPtr->body->gForce.vz = 0;
|
|
curLvl.actorPtr->body->gForce.vx = 0;
|
|
lastPad = PAD;
|
|
}
|
|
if ( PAD & PadDown ) {
|
|
curLvl.actorPtr->body->gForce.vz = -getVectorTo(fVecActor, curLvl.actorPtr->pos).vz >> 6 ;
|
|
curLvl.actorPtr->body->gForce.vx = getVectorTo(fVecActor, curLvl.actorPtr->pos).vx >> 6 ;
|
|
lastPad = PAD;
|
|
}
|
|
if ( !( PAD & PadDown ) && lastPad & PadDown) {
|
|
curLvl.actorPtr->body->gForce.vz = 0;
|
|
curLvl.actorPtr->body->gForce.vx = 0;
|
|
lastPad = PAD;
|
|
}
|
|
if ( PAD & PadLeft ) {
|
|
curLvl.actorPtr->rot.vy -= 64;
|
|
lastPad = PAD;
|
|
}
|
|
if ( PAD & PadRight ) {
|
|
curLvl.actorPtr->rot.vy += 64;
|
|
lastPad = PAD;
|
|
}
|
|
if ( PAD & PadSelect && !(lastPad & PadSelect) ) {
|
|
//~ if (!levelHasChanged){
|
|
#ifndef USECD
|
|
printf("load:%p:%08x:%s", &load_all_overlays_here, &level, overlayFile);
|
|
//~ PCload( &load_all_overlays_here, &levelHasChanged, overlayFile );
|
|
#endif
|
|
#ifdef USECD
|
|
level = !level;
|
|
//~ levelHasChanged = 1;
|
|
#endif
|
|
//~ }
|
|
timer = 30;
|
|
lastPad = PAD;
|
|
}
|
|
if ( !(PAD & PadSelect) && lastPad & PadSelect ) {
|
|
lastPad = PAD;
|
|
}
|
|
if( theControllers[0].type == 0x73 && camMode == ACTOR){
|
|
// Cam control - horizontal
|
|
if ( theControllers[0].analog0 >= 0 && theControllers[0].analog0 < (128 - DS_DZ/2) ) {
|
|
angleCam.vy += ( 16 * ( 128 - theControllers[0].analog0 ) ) >> 8 ;
|
|
angleCamTimer = 120;
|
|
}
|
|
if ( theControllers[0].analog0 > (128 + DS_DZ/2) && theControllers[0].analog0 <= 255 ) {
|
|
angleCam.vy -= ( 16 * ( theControllers[0].analog0 - 128 ) ) >> 8 ;
|
|
angleCamTimer = 120;
|
|
}
|
|
if ( theControllers[0].analog0 >= 0 && theControllers[0].analog0 < (128 - DS_DZ/2) ) {
|
|
angleCam.vy += ( 16 * ( 128 - theControllers[0].analog0 ) ) >> 8 ;
|
|
angleCamTimer = 120;
|
|
}
|
|
if ( theControllers[0].analog0 > (128 + DS_DZ/2) && theControllers[0].analog0 <= 255) {
|
|
angleCam.vy -= ( 16 * ( theControllers[0].analog0 - 128 ) ) >> 8 ;
|
|
angleCamTimer = 120;
|
|
}
|
|
// Timer to lerp cam back behind actor
|
|
if ( angleCamTimer ){
|
|
angleCamTimer --;
|
|
}
|
|
if (!angleCamTimer && angleCam.vy){
|
|
angleCam.vy += lerp( angleCam.vy, 0, 64 ) == 0 ? 1 : lerp( angleCam.vy, 0, 64 );
|
|
}
|
|
}
|
|
// Print controller infos
|
|
//~ FntPrint( "Pad 1 : %02x\nButtons:%02x %02x, Stick:%02d %02d %02d %02d\n",
|
|
//~ theControllers[0].type, // Controller type : 0x00 == none, 0x41 == standard, 0x73 == analog/dualshock, 0x12 == mouse, 0x23 == steering wheel, 0x63 == gun, 0x53 == analog joystick
|
|
//~ theControllers[0].button1, //
|
|
//~ theControllers[0].button2,
|
|
//~ theControllers[0].analog0, // R3 hor : left: 0 7F right: 7F FF dz 78 83
|
|
//~ theControllers[0].analog1, // R3 vert : up : 0 7F down : 7F FF : dz 83 86
|
|
//~ theControllers[0].analog2, // L3 hor : left : 0 7F right: 7F FF : dz 69 81 68 - 8E
|
|
//~ theControllers[0].analog3 ); // L3 vert : up : 0 7F down : 7F FF : dz 74 8D
|
|
if ( cursor ) {
|
|
//~ curLvl.actorPtr->body->gForce.vy = 0;
|
|
//~ curLvl.actorPtr->body->position.vy = lerpValues[cursor];
|
|
}
|
|
};
|