Browse Source

Added controller support with first person controls (including analog!)

master
Nico de Poel 3 years ago
parent
commit
1a4599bf42
  1. 129
      main.c

129
main.c

@ -19,13 +19,14 @@
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#include <psxetc.h> #include <psxetc.h>
#include <psxapi.h>
#include <psxpad.h>
#include <psxgte.h> #include <psxgte.h>
#include <psxgpu.h> #include <psxgpu.h>
#include <inline_c.h> #include <inline_c.h>
#include "ps1mdl.h" #include "ps1mdl.h"
#define OTLEN 256
#define OTLEN 1024
#define SCREENWIDTH 512 #define SCREENWIDTH 512
#define SCREENHEIGHT 240 #define SCREENHEIGHT 240
@ -117,9 +118,11 @@ MATRIX light_dirs = {
// Scale X coordinates to correct the aspect ratio for the chosen resolution // Scale X coordinates to correct the aspect ratio for the chosen resolution
VECTOR aspect_scale = { SCREENWIDTH * ONE / 320 , ONE, ONE }; VECTOR aspect_scale = { SCREENWIDTH * ONE / 320 , ONE, ONE };
VECTOR cam_pos = { 0, 0, 0 };
VECTOR cam_pos = { 0, -400, 100 };
SVECTOR cam_rot = { 0 }; SVECTOR cam_rot = { 0 };
u_char padBuffer[2][34];
void loadModel(const u_long* data, ps1mdl_t *mdl) void loadModel(const u_long* data, ps1mdl_t *mdl)
{ {
const char *bytes = (const char*)data; const char *bytes = (const char*)data;
@ -169,6 +172,12 @@ void loadSkin(const u_long* frontTim, const u_long* backTim, ps1skin_t *skin)
// Init function // Init function
void init(void) void init(void)
{ {
InitPAD(padBuffer[0], 34, padBuffer[1], 34);
padBuffer[0][0] = padBuffer[0][1] = 0xFF;
padBuffer[1][0] = padBuffer[1][1] = 0xFF;
StartPAD();
ChangeClearPAD(1); // Avoid issues with VSync timeouts caused by StartPAD
// This not only resets the GPU but it also installs the library's // This not only resets the GPU but it also installs the library's
// ISR subsystem to the kernel // ISR subsystem to the kernel
ResetGraph(0); ResetGraph(0);
@ -524,8 +533,8 @@ void drawStuff(int counter)
ScaleMatrixL(&proj_matrix, &aspect_scale); // Apply aspect ratio correction for the current resolution ScaleMatrixL(&proj_matrix, &aspect_scale); // Apply aspect ratio correction for the current resolution
MATRIX view_matrix; MATRIX view_matrix;
SVECTOR trot = { 0, 0, 0, 0 }; // TODO: inverse camera rotation (in Quake coordinates)
VECTOR tpos = { 0, 400, -100 }; // TODO: inverse camera position (in Quake coordinates)
SVECTOR trot = { -cam_rot.vx, -cam_rot.vy, -cam_rot.vz, 0 }; // inverse camera rotation (in Quake coordinates)
VECTOR tpos = { -cam_pos.vx, -cam_pos.vy, -cam_pos.vz }; // inverse camera position (in Quake coordinates)
RotMatrix(&trot, &view_matrix); // Set camera rotation part of the view matrix RotMatrix(&trot, &view_matrix); // Set camera rotation part of the view matrix
ApplyMatrixLV(&view_matrix, &tpos, &tpos); // Apply camera rotation to camera position ApplyMatrixLV(&view_matrix, &tpos, &tpos); // Apply camera rotation to camera position
TransMatrix(&view_matrix, &tpos); // Apply transformed position to the translation part of the view matrix TransMatrix(&view_matrix, &tpos); // Apply transformed position to the translation part of the view matrix
@ -539,6 +548,114 @@ void drawStuff(int counter)
drawModel(&view_matrix, &quadModel, &quadSkin, 0); drawModel(&view_matrix, &quadModel, &quadSkin, 0);
} }
void handleInput()
{
const int moveSpeed = 32;
const short rotSpeed = 32;
// Check if we have a connected controller on port 1
if (padBuffer[0][0] != 0)
return;
// Determine direction vectors of the camera
MATRIX cam_mtx;
RotMatrix(&cam_rot, &cam_mtx);
u_short buttons = *((u_short*)(padBuffer[0]+2));
if (!(buttons & PAD_UP))
{
// Move forward
cam_pos.vx += (cam_mtx.m[0][1] * moveSpeed) >> 12;
cam_pos.vy += (cam_mtx.m[1][1] * moveSpeed) >> 12;
cam_pos.vz += (cam_mtx.m[2][1] * moveSpeed) >> 12;
}
if (!(buttons & PAD_DOWN))
{
// Move backward
cam_pos.vx -= (cam_mtx.m[0][1] * moveSpeed) >> 12;
cam_pos.vy -= (cam_mtx.m[1][1] * moveSpeed) >> 12;
cam_pos.vz -= (cam_mtx.m[2][1] * moveSpeed) >> 12;
}
if (!(buttons & PAD_LEFT))
{
// Rotate left
cam_rot.vz += rotSpeed;
}
if (!(buttons & PAD_RIGHT))
{
// Rotate right
cam_rot.vz -= rotSpeed;
}
if (!(buttons & PAD_TRIANGLE))
{
// Move up
cam_pos.vx += (cam_mtx.m[0][2] * moveSpeed) >> 12;
cam_pos.vy += (cam_mtx.m[1][2] * moveSpeed) >> 12;
cam_pos.vz += (cam_mtx.m[2][2] * moveSpeed) >> 12;
}
if (!(buttons & PAD_CROSS))
{
// Move down
cam_pos.vx -= (cam_mtx.m[0][2] * moveSpeed) >> 12;
cam_pos.vy -= (cam_mtx.m[1][2] * moveSpeed) >> 12;
cam_pos.vz -= (cam_mtx.m[2][2] * moveSpeed) >> 12;
}
if (!(buttons & PAD_L1))
{
// Strafe left
cam_pos.vx -= (cam_mtx.m[0][0] * moveSpeed) >> 12;
cam_pos.vy -= (cam_mtx.m[1][0] * moveSpeed) >> 12;
cam_pos.vz -= (cam_mtx.m[2][0] * moveSpeed) >> 12;
}
if (!(buttons & PAD_R1))
{
// Strafe right
cam_pos.vx += (cam_mtx.m[0][0] * moveSpeed) >> 12;
cam_pos.vy += (cam_mtx.m[1][0] * moveSpeed) >> 12;
cam_pos.vz += (cam_mtx.m[2][0] * moveSpeed) >> 12;
}
if (!(buttons & PAD_L2))
{
// Look down
cam_rot.vx -= rotSpeed;
}
if (!(buttons & PAD_R2))
{
// Look up
cam_rot.vx += rotSpeed;
}
// Check for analog controller
u_char padType = padBuffer[0][1] >> 4;
if (padType == 0x5 || padType == 0x7)
{
short rightJoyX = (short)(padBuffer[0][4]) - 0x80;
if (rightJoyX > -0x20 && rightJoyX < 0x20) rightJoyX = 0;
short rightJoyY = (short)(padBuffer[0][5]) - 0x80;
if (rightJoyY > -0x20 && rightJoyY < 0x20) rightJoyY = 0;
short leftJoyX = (short)(padBuffer[0][6]) - 0x80;
if (leftJoyX > -0x20 && leftJoyX < 0x20) leftJoyX = 0;
short leftJoyY = (short)(padBuffer[0][7]) - 0x80;
if (leftJoyY > -0x20 && leftJoyY < 0x20) leftJoyY = 0;
// Move forward/backward
cam_pos.vx -= (cam_mtx.m[0][1] * leftJoyY * moveSpeed) >> 19;
cam_pos.vy -= (cam_mtx.m[1][1] * leftJoyY * moveSpeed) >> 19;
cam_pos.vz -= (cam_mtx.m[2][1] * leftJoyY * moveSpeed) >> 19;
// Strafe left/right
cam_pos.vx += (cam_mtx.m[0][0] * leftJoyX * moveSpeed) >> 19;
cam_pos.vy += (cam_mtx.m[1][0] * leftJoyX * moveSpeed) >> 19;
cam_pos.vz += (cam_mtx.m[2][0] * leftJoyX * moveSpeed) >> 19;
// Rotate left/right
cam_rot.vz -= (rightJoyX * rotSpeed) >> 7;
// Look up/down
cam_rot.vx -= (rightJoyY * rotSpeed) >> 7;
}
}
// Main function, program entrypoint // Main function, program entrypoint
int main(int argc, const char *argv[]) int main(int argc, const char *argv[])
{ {
@ -551,6 +668,8 @@ int main(int argc, const char *argv[])
counter = 0; counter = 0;
while(1) while(1)
{ {
handleInput();
quadModel.rotation.vz = (counter << 5) % ONE; quadModel.rotation.vz = (counter << 5) % ONE;
quadModel.position.vz = (isin(counter << 6) * 32) >> 12; quadModel.position.vz = (isin(counter << 6) * 32) >> 12;

Loading…
Cancel
Save