// 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 #define _WCHAR_T #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" #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 = 1; 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] = {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 // 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}; int dist = 150; int lerping = 0; short curCamAngle = 0; // Actor's forward vector (used for dualshock) VECTOR fVecActor = {0,0,0,0}; u_long triCount = 0; 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"; 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(); 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 if (curLvl.camPtr->tim_data){ LoadTexture(curLvl.camPtr->tim_data, curLvl.camPtr->BGtim); } // Physics/collisions short physics = 1; VECTOR col = {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 // Animation timing // time % timediv == animation time // Time divisor short timediv = 1; // Animation time, see l.206 int atime = 0; // Polycount for (int k = 0; k < *curLvl.meshes_length; k++){ triCount += curLvl.meshes[k]->tmesh->len; } // Set camera starting pos 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){ curCamAngle = 1; } } // Main loop while ( VSync(VSYNC) ) { //~ timeS = VSync(-1) / 60; // 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); setLightEnv(draw, curLvl.BGc, curLvl.BKc); levelWas = level; } FntPrint("Ovl:%s\nLvl : %x\nLvl: %d %d \n%x", overlayFile, &level, level, levelWas, loadLvl); // Clear the main OT ClearOTagR(otdisc[db], OT2LEN); // Clear Secondary OT ClearOTagR(ot[db], OTLEN); time ++; // atime is used for animations timing timediv = 1; // If timediv is > 1, animation time will be slower 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; // 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)) ); // Camera modes if(camMode != 2) { camera.rot->vy = camAngleToAct.vy; // using csin/ccos, no need for theta camera.rot->vx = camAngleToAct.vx; } if(camMode < 4 ) { lerping = 0; } // Camera follows actor if(camMode == 0) { dist = 200; 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); getCameraXZ(&camera.x, &camera.z, curLvl.actorPtr->pos.vx, curLvl.actorPtr->pos.vz, angle.vy, dist); } // Camera rotates continuously around actor if (camMode == 1) { // Set distance between cam and actor dist = 150; // Set camera position 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 angle.vy += 10; } // Fixed Camera with actor tracking if (camMode == 3) { // Using precalc sqrt dist = psqrt( (posToActor.vx * posToActor.vx ) + (posToActor.vz * posToActor.vz) ); // Set camera position setVector(camera.pos, 190, 100, 180); } // Fixed Camera angle if (camMode == 2) { // If BG images exist if (curLvl.camPtr->tim_data){ checkLineW( &curLvl.camAngles[ curCamAngle ]->fw.v3, &curLvl.camAngles[ curCamAngle ]->fw.v2, curLvl.actorPtr); if ( curLvl.camAngles[ curCamAngle ]->fw.v0.vx ) { // If actor in camAngle->fw area of screen if ( checkLineW( &curLvl.camAngles[ curCamAngle ]->fw.v3, &curLvl.camAngles[ curCamAngle ]->fw.v2, curLvl.actorPtr) == -1 && ( checkLineW( &curLvl.camAngles[ curCamAngle ]->bw.v2, &curLvl.camAngles[ curCamAngle ]->bw.v3, curLvl.actorPtr) >= 0 ) ) { if (curCamAngle < 5) { curCamAngle++; curLvl.camPtr = curLvl.camAngles[ curCamAngle ]; LoadTexture(curLvl.camPtr->tim_data, curLvl.camPtr->BGtim); } } } if ( curLvl.camAngles[ curCamAngle ]->bw.v0.vx ) { // If actor in camAngle->bw area of screen if ( checkLineW( &curLvl.camAngles[ curCamAngle ]->fw.v3, &curLvl.camAngles[ curCamAngle ]->fw.v2, curLvl.actorPtr) >= 0 && checkLineW( &curLvl.camAngles[ curCamAngle ]->bw.v2, &curLvl.camAngles[ curCamAngle ]->bw.v3, curLvl.actorPtr) == -1 ) { if (curCamAngle > 0) { curCamAngle--; curLvl.camPtr = curLvl.camAngles[ curCamAngle ]; LoadTexture(curLvl.camPtr->tim_data, curLvl.camPtr->BGtim); } } } } setCameraPos(&camera, &curLvl.camPtr->campos->pos, &curLvl.camPtr->campos->rot); } // Flyby mode with LERP from camStart to camEnd if (camMode == 4) { // If key pos exist for camera if (curLvl.camPath->len) { // Lerping sequence has not begun if (!lerping){ // Set cam start position ( first key pos ) copyVector(camera.pos, &curLvl.camPath->points[curLvl.camPath->cursor]); // Lerping sequence is starting lerping = 1; // Set cam pos index to 0 curLvl.camPath->pos = 0; } // Pre calculated sqrt ( see psqrt() ) dist = psqrt( (posToActor.vx * posToActor.vx ) + (posToActor.vz * posToActor.vz)); // Fixed point precision 2^12 == 4096 int precision = 12; 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 ); // Linearly increment the lerp factor curLvl.camPath->pos += 20; // If camera has reached next key pos, reset pos index, move cursor to next key pos if (curLvl.camPath->pos > (1 << precision) ){ curLvl.camPath->pos = 0; curLvl.camPath->cursor ++; } // Last key pos is reached, reset cursor to first key pos, lerping sequence is over if ( curLvl.camPath->cursor == curLvl.camPath->len - 1 ){ lerping = 0; curLvl.camPath->cursor = 0; } } 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; if (curLvl.camPath->len) { // Lerping sequence has not begun if (!lerping){ // Set cam start position ( first key pos ) copyVector(camera.pos, &curLvl.camPath->points[curLvl.camPath->cursor]); // Lerping sequence is starting lerping = 1; // Set cam pos index to 0 curLvl.camPath->pos = 0; } // Pre calculated sqrt ( see psqrt() ) dist = psqrt( (posToActor.vx * posToActor.vx ) + (posToActor.vz * posToActor.vz)); // Fixed point precision 2^12 == 4096 short precision = 12; 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 ) { // 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 ) { curLvl.camPath->pos -= dist < cameraSpeed ? 0 : cameraSpeed; } // If camera has reached next key pos, reset pos index, move cursor to next key pos if (curLvl.camPath->pos > (1 << precision) ){ curLvl.camPath->pos = 0; curLvl.camPath->cursor ++; } if (curLvl.camPath->pos < -100 ){ curLvl.camPath->pos = 1 << precision; curLvl.camPath->cursor --; } // Last key pos is reached, reset cursor to first key pos, lerping sequence is over if ( curLvl.camPath->cursor == curLvl.camPath->len - 1 || curLvl.camPath->cursor < 0 ){ lerping = 0; curLvl.camPath->cursor = 0; } } else { // if no key pos exists, switch to next camMode camMode ++; } } // Spatial partitioning if (curLvl.curNode){ for ( int msh = 0; msh < curLvl.curNode->siblings->index; msh ++ ) { // Actor 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 ( curLvl.curNode != curLvl.curNode->siblings->list[msh] ) { curLvl.curNode = curLvl.curNode->siblings->list[msh]; curLvl.levelPtr = curLvl.curNode->plane; } } 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 ) { // if(time%1 == 0){ for ( int k = 0; k < *curLvl.meshes_length; k ++ ) { if ( curLvl.meshes[k]->isRigidBody == 1 ) { applyAcceleration( curLvl.meshes[k]->body ); // Get col between actor and level if ( curLvl.meshes[k]->isActor ){ checkBodyCol( curLvl.meshes[k]->body , curLvl.levelPtr->body ); } // Get col between props and level if ( curLvl.meshes[k]->isProp ){ checkBodyCol( curLvl.meshes[k]->body , curLvl.meshes[k]->node->plane->body ); } // 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); } setVector(&curLvl.meshes[k]->body->velocity, 0, 0, 0); } } // Get actor's screen coordinates (used with fixed BGs) if ( (camMode == 2) && (curLvl.camPtr->tim_data ) ) { worldToScreen( &curLvl.actorPtr->pos, &curLvl.actorPtr->pos2D ); } // Camera setup // Get position of cam relative to actor addVector2(&curLvl.actorPtr->pos, camera.pos, &posToActor); // Polygon drawing if (curLvl.curNode){ 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], dc_lgtangp); transformMesh(&camera, curLvl.camAngles[curCamAngle]->objects[mesh]); drawPoly(curLvl.camAngles[curCamAngle]->objects[mesh], atime, &camMode, &nextpri, ot[db], &db, &draw[db]); } } else { // Draw current node's plane 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, 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 ], dc_lgtangp); transformMesh(&camera, curLvl.curNode->siblings->list[ sibling ]->objects->list[ object ]); 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 ], dc_lgtangp); transformMesh(&camera, curLvl.curNode->objects->list[ object ]); 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 ], dc_lgtangp); transformMesh(&camera, curLvl.curNode->rigidbodies->list[ object ]); drawPoly( curLvl.curNode->rigidbodies->list[ object ], atime, &camMode, &nextpri, ot[db], &db, &draw[db]); } } } // 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\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); } 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_char PADL = ~theControllers[0].button1; u_char PADR = ~theControllers[0].button2; //~ 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( cursor ) { cursor--; } if (angleCam.vy > 2048 || angleCam.vy < -2048) { angleCam.vy = 0; } if ( PADR & PadShldR1 && !timer ) { if (!curLvl.camPtr->tim_data){ if(camMode < 6){ 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 = PADR; timer = 10; } //~ if ( !(PADR & PadShldR1) && lastPad & PadShldR1 ) { //pressed = 0; //~ } if ( PADR & PadShldL2 ) { dc_lgtangp->vy += 32; } if ( PADR & PadShldL1 ) { dc_lgtangp->vz += 32; } if ( PADR & PadUp && !timer ){ if (curLvl.actorPtr->isPrism){ curLvl.actorPtr->isPrism = 0; } else { curLvl.actorPtr->isPrism = 1; } timer = 10; lastPad = PADR; } if ( PADR & PadDown && !timer ){ if (curLvl.actorPtr->body->gForce.vy >= 0 && curLvl.actorPtr->body->position.vy >= curLvl.actorPtr->body->min.vy ){ forceApplied -= 150; } cursor = div - 15; timer = 30; lastPad = PADR; } if ( !(PADR & PadDown) && lastPad & PadDown ) { //~ lastPad = pad; } if ( PADR & PadLeft && !timer ) { if (curLvl.actorPtr->anim->interpolate){ curLvl.actorPtr->anim->interpolate = 0; } else { curLvl.actorPtr->anim->interpolate = 1; } timer = 10; lastPad = PADR; } 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 ) >> 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 ) >> 14 ; curLvl.actorPtr->body->gForce.vx = getVectorTo(fVecActor, curLvl.actorPtr->pos).vx * ( theControllers[0].analog3 - 128 ) >> 14 ; lastPad = PADL; } // Analog stick L dead zone if ( theControllers[0].analog3 > 108 && theControllers[0].analog3 < 148 ) { curLvl.actorPtr->body->gForce.vz = 0; curLvl.actorPtr->body->gForce.vx = 0; } // Analog stick L left if ( theControllers[0].analog2 >= 0 && theControllers[0].analog2 < 108 ) { curLvl.actorPtr->rot.vy -= ( 40 * ( 128 - theControllers[0].analog2 ) ) >> 7 ; } // Analog stick L right if ( theControllers[0].analog2 > 148 && theControllers[0].analog2 <= 255 ) { curLvl.actorPtr->rot.vy += ( 40 * ( theControllers[0].analog2 - 128 ) ) >> 7 ; } } if ( PADL & PadUp ) { 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) { curLvl.actorPtr->body->gForce.vz = 0; curLvl.actorPtr->body->gForce.vx = 0; lastPad = PADL; } if ( PADL & PadDown ) { 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) { curLvl.actorPtr->body->gForce.vz = 0; curLvl.actorPtr->body->gForce.vx = 0; lastPad = PADL; } if ( PADL & PadLeft ) { curLvl.actorPtr->rot.vy -= 32; lastPad = PADL; } if ( PADL & PadRight ) { curLvl.actorPtr->rot.vy += 32; lastPad = PADL; } if ( PADL & PadSelect && !timer ) { //~ 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 = PADL; } if( theControllers[0].type == 0x73 && camMode == 0){ // Cam control - horizontal if ( theControllers[0].analog0 >= 0 && theControllers[0].analog0 < (128 - DS_DZ/2) ) { angleCam.vy -= ( 16 * ( 128 - theControllers[0].analog0 ) ) >> 7 ; angleCamTimer = 120; } if ( theControllers[0].analog0 > (128 + DS_DZ/2) && theControllers[0].analog0 <= 255 ) { angleCam.vy += ( 16 * ( theControllers[0].analog0 - 128 ) ) >> 7 ; angleCamTimer = 120; } if ( theControllers[0].analog0 >= 0 && theControllers[0].analog0 < (128 - DS_DZ/2) ) { angleCam.vy -= ( 16 * ( 128 - theControllers[0].analog0 ) ) >> 7 ; angleCamTimer = 120; } if ( theControllers[0].analog0 > (128 + DS_DZ/2) && theControllers[0].analog0 <= 255) { angleCam.vy += ( 16 * ( theControllers[0].analog0 - 128 ) ) >> 7 ; 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->position.vy = lerpValues[cursor];} };