Implement controller data recording

This commit is contained in:
James Lambert 2022-11-11 09:46:40 -07:00
parent 6ca5cb7908
commit 3826c8612b
6 changed files with 102 additions and 16 deletions

2
.gitignore vendored
View file

@ -17,3 +17,5 @@ portal_pak_modified/
tools/skeletool64
tools/vtf2png
src/controls/controller-data.h

View file

@ -4,6 +4,10 @@
#include "util/memory.h"
#include <sched.h>
#if CONTROLLER_LOG_CONTROLLER_DATA
#include "../debugger/serial.h"
#endif
#define MAX_PLAYERS 4
static u8 validcontrollers = 0;
@ -56,13 +60,8 @@ void controllersInit(void)
osSetEventMesg(OS_EVENT_SI, &gfxFrameMsgQ, (OSMesg)&gControllerMessage);
}
void controllersUpdate(void)
{
for (unsigned i = 0; i < MAX_PLAYERS; ++i) {
gControllerLastDirection[i] = controllerGetDirection(i);
gControllerLastButton[i] = gControllerData[i].button;
}
void controllersReadPendingData(void) {
osContGetReadData(gControllerData);
cntrlReadInProg = 0;
@ -78,6 +77,13 @@ void controllersUpdate(void)
}
}
void controllersSavePreviousState(void) {
for (unsigned i = 0; i < MAX_PLAYERS; ++i) {
gControllerLastDirection[i] = controllerGetDirection(i);
gControllerLastButton[i] = gControllerData[i].button;
}
}
int controllerHasPendingMessage() {
return cntrlReadInProg;
}
@ -138,3 +144,32 @@ enum ControllerDirection controllerGetDirection(int index) {
enum ControllerDirection controllerGetDirectionDown(int index) {
return controllerGetDirection(REMAP_PLAYER_INDEX(index)) & ~gControllerLastDirection[REMAP_PLAYER_INDEX(index)];
}
#if CONTROLLER_LOG_CONTROLLER_DATA
struct ControllerData {
OSContPad contPad;
};
int currentFrame = 0;
#if CONTROLLER_LOG_CONTROLLER_DATA == 2
struct ControllerData gRecordedControllerData[] = {
#include "controller-data.h"
};
#endif
void controllerHandlePlayback() {
#if CONTROLLER_LOG_CONTROLLER_DATA == 1
struct ControllerData data;
data.contPad = gControllerData[0];
gdbSendMessage(GDBDataTypeControllerData, (char*)&data, sizeof(struct ControllerData));
#elif CONTROLLER_LOG_CONTROLLER_DATA == 2
if (currentFrame < sizeof(gRecordedControllerData) / sizeof(*gRecordedControllerData)) {
gControllerData[0] = gRecordedControllerData[currentFrame].contPad;
++currentFrame;
}
#endif
}
#endif

View file

@ -3,8 +3,12 @@
#include <ultra64.h>
// 0 = disable 1 = record 2 = playbakc
#define CONTROLLER_LOG_CONTROLLER_DATA 2
void controllersInit(void);
void controllersUpdate(void);
void controllersReadPendingData(void);
void controllersSavePreviousState(void);
void controllersTriggerRead(void);
enum ControllerDirection {
@ -26,4 +30,8 @@ u16 controllerGetButtonUp(int index, u16 button);
enum ControllerDirection controllerGetDirection(int index);
enum ControllerDirection controllerGetDirectionDown(int index);
#if CONTROLLER_LOG_CONTROLLER_DATA
void controllerHandlePlayback();
#endif
#endif

View file

@ -141,10 +141,13 @@ void cutsceneRunnerStartStep(struct CutsceneRunner* runner) {
{
struct Location* location = &gCurrentLevel->locations[step->openPortal.locationIndex];
struct Ray firingRay;
struct Vector3 transformUp;
firingRay.origin = location->transform.position;
quatMultVector(&location->transform.rotation, &gForward, &firingRay.dir);
quatMultVector(&location->transform.rotation, &gRight, &transformUp);
vector3Negate(&transformUp, &transformUp);
vector3AddScaled(&location->transform.position, &firingRay.dir, -0.1f, &firingRay.origin);
sceneFirePortal(&gScene, &firingRay, &gUp, step->openPortal.portalIndex, location->roomIndex);
sceneFirePortal(&gScene, &firingRay, &transformUp, step->openPortal.portalIndex, location->roomIndex);
break;
}
case CutsceneStepTypeSetSignal:

View file

@ -154,7 +154,7 @@ static void gameProc(void* arg) {
dynamicSceneInit();
contactSolverInit(&gContactSolver);
portalSurfaceCleanupQueueInit();
levelLoad(0);
levelLoad(2);
cutsceneRunnerReset();
controllersInit();
initAudio();
@ -199,6 +199,10 @@ static void gameProc(void* arg) {
controllersTriggerRead();
skReadMessages();
#if CONTROLLER_LOG_CONTROLLER_DATA
controllerHandlePlayback();
#endif
if (inputIgnore) {
--inputIgnore;
} else {
@ -207,6 +211,7 @@ static void gameProc(void* arg) {
}
timeUpdateDelta();
soundPlayerUpdate();
controllersSavePreviousState();
break;
@ -218,7 +223,7 @@ static void gameProc(void* arg) {
pendingGFX += 2;
break;
case SIMPLE_CONTROLLER_MSG:
controllersUpdate();
controllersReadPendingData();
break;
}
}

View file

@ -28,7 +28,22 @@ void planeProjectPoint(struct Plane* plane, struct Vector3* point, struct Vector
vector3AddScaled(point, &plane->normal, distance, output);
}
// TODO figure out what to do when two points are the same
float calculateLerp(struct Vector3* a, struct Vector3* b, struct Vector3* point) {
struct Vector3 v0;
vector3Sub(b, a, &v0);
float denom = vector3MagSqrd(&v0);
if (denom < 0.00000001f) {
return 0.5f;
}
struct Vector3 pointOffset;
vector3Sub(point, a, &pointOffset);
return vector3Dot(&pointOffset, &v0) / denom;
}
void calculateBarycentricCoords(struct Vector3* a, struct Vector3* b, struct Vector3* c, struct Vector3* point, struct Vector3* output) {
struct Vector3 v0;
struct Vector3 v1;
@ -44,9 +59,27 @@ void calculateBarycentricCoords(struct Vector3* a, struct Vector3* b, struct Vec
float d20 = vector3Dot(&v2, &v0);
float d21 = vector3Dot(&v2, &v1);
float denom = 1.0f / (d00 * d11 - d01 * d01);
output->y = (d11 * d20 - d01 * d21) * denom;
output->z = (d00 * d21 - d01 * d20) * denom;
float denom = d00 * d11 - d01 * d01;
if (fabsf(denom) < 0.000001f) {
if (d00 > d11) {
// b is other point
output->y = calculateLerp(a, b, point);
output->x = 1.0 - output->y;
output->z = 0.0f;
} else {
// c is other point
output->z = calculateLerp(a, c, point);
output->x = 1.0f - output->z;
output->z = 0.0f;
}
return;
}
float denomInv = 1.0f / (d00 * d11 - d01 * d01);
output->y = (d11 * d20 - d01 * d21) * denomInv;
output->z = (d00 * d21 - d01 * d20) * denomInv;
output->x = 1.0f - output->y - output->z;
}