summaryrefslogtreecommitdiff
path: root/src/enhancements/freecam/freecam.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/enhancements/freecam/freecam.cpp')
-rw-r--r--src/enhancements/freecam/freecam.cpp160
1 files changed, 93 insertions, 67 deletions
diff --git a/src/enhancements/freecam/freecam.cpp b/src/enhancements/freecam/freecam.cpp
index 00d8ee84a..dd92d9c2a 100644
--- a/src/enhancements/freecam/freecam.cpp
+++ b/src/enhancements/freecam/freecam.cpp
@@ -33,6 +33,8 @@ typedef struct {
freecamSaveState fState;
+Controller fController;
+
u32 fRankIndex = 0;
u32 fTargetPlayer = false;
u32 fMode; // freecam mode should probably be an enum
@@ -40,7 +42,7 @@ u32 fModeInit = false;
int rightMouseButtonDown = 0; // Track if right mouse button is held down
-u32 gFreecamControllerType = 0;
+u32 bFreecamUseController = false;
/**
* Controls
@@ -66,25 +68,43 @@ u32 gFreecamControllerType = 0;
*
*/
void freecam(Camera* camera, Player* player, s8 index) {
- struct Controller* controller = &gControllers[0];
f32 dirX;
f32 dirY;
f32 dirZ;
f32 length;
+ static bool enabled = false; // Tracks previous activation state
+ bool freecamEnabled = CVarGetInteger("gFreecam", 0);
+
+ if (freecamEnabled && !enabled) {
+ enabled = true; // Mark that freecam was activated
+ on_freecam();
+ } else if (!freecamEnabled && enabled) {
+ off_freecam();
+ enabled = false; // Reset when freecam is turned off
+ }
- if (controller->buttonPressed & L_TRIG) {
- // Toggle freecam
- CVarSetInteger("gFreecam", !CVarGetInteger("gFreecam", 0));
+ // Freecam mode is enabled
+ if (enabled) {
+ freecam_loop(camera, player, index);
+ } else {
+ func_8001E45C(camera, player, index);
+ }
+}
- // Don't use `bool = !bool` here as the game code can swap these on you.
- // Which will confuse the code. This forces it to always be correct
- if (CVarGetInteger("gFreecam", 0) == 1) {
- player->type |= PLAYER_KART_AI;
- } else {
- player->type &= PLAYER_KART_AI;
- }
+void on_freecam(void) {
+ gIsHUDVisible = false;
+ gPlayerOne->type |= PLAYER_KART_AI;
+}
+
+void off_freecam(void) {
+ gIsHUDVisible = true;
+ gPlayerOne->type &= ~PLAYER_KART_AI;
+}
- gIsHUDVisible = !CVarGetInteger("gFreecam", 0);
+void freecam_loop(Camera* camera, Player* player, s8 index) {
+ if ((fController.buttonPressed & L_TRIG) && (fController.buttonPressed & R_TRIG)) {
+ // Toggle freecam
+ CVarSetInteger("gFreecam", !CVarGetInteger("gFreecam", 0));
}
// Calculate forward direction
@@ -104,47 +124,39 @@ void freecam(Camera* camera, Player* player, s8 index) {
freecam_tick(camera, freeCam.forwardVector);
}
-f32 gFreecamRotateSmoothingFactor = 0.85f;
-
void freecam_mouse_manager(Camera* camera, Vec3f forwardVector) {
- static int prevMouseX = 0, prevMouseY = 0;
auto wnd = GameEngine::Instance->context->GetWindow();
Ship::Coords mouse = wnd->GetMouseDelta();
- // Uint32 mouseState = SDL_GetRelativeMouseState(&mouse.x, &mouse.y);
+ f32 yawChange = 0.0f;
+ f32 pitchChange = 0.0f;
- // printf("MOUSE %d %d\n", mouse.x, mouse.y);
+ if (bFreecamUseController) {
+ // Controller controls
+ f32 stickX = ((f32)fController.rightRawStickX);
+ f32 stickY = ((f32)fController.rightRawStickY);
- mouse.x = (mouse.x + prevMouseX) / 2;
- mouse.y = (mouse.y + prevMouseY) / 2;
- prevMouseX = mouse.x;
- prevMouseY = mouse.y;
-
- if (wnd->GetMouseState(Ship::LUS_MOUSE_BTN_RIGHT)) {
- // Calculate yaw (left/right) and pitch (up/down) changes
- f32 yawChange = mouse.x * MOUSE_SENSITIVITY_X;
- f32 pitchChange = mouse.y * MOUSE_SENSITIVITY_Y;
+ // Sensitivity multipliers
+ float controllerSensitivityX = 5.0f; // Adjust as needed
+ float controllerSensitivityY = 3.0f;
- // Smoothly update yaw and pitch
- camera->rot[1] += (short) (yawChange * 65535.0f / (2 * M_PI)); // Yaw (left/right)
- camera->rot[2] += (short) (pitchChange * 65535.0f / (2 * M_PI)); // Pitch (up/down)
+ // Deadzone handling (ignore tiny stick movements)
+ const float deadzone = 0.1f;
+ if (fabs(stickX) < deadzone) stickX = 0.0f;
+ if (fabs(stickY) < deadzone) stickY = 0.0f;
- // Clamp pitch to avoid extreme values
- if (camera->rot[2] > 15999) {
- camera->rot[2] = 15999;
- }
- if (camera->rot[2] < -15999) {
- camera->rot[2] = -15999;
+ // Instead of adding, directly set rotation velocity (so holding gives a steady rotation)
+ freeCam.rotVelocity[1] += stickX * controllerSensitivityX; // Yaw (left/right)
+ freeCam.rotVelocity[2] += stickY * controllerSensitivityY; // Pitch (up/down)
+ } else { // Mouse controls
+ // Calculate yaw (left/right) and pitch (up/down) changes
+ if (wnd->GetMouseState(Ship::LUS_MOUSE_BTN_RIGHT)) {
+ yawChange = mouse.x * MOUSE_SENSITIVITY_X;
+ pitchChange = mouse.y * MOUSE_SENSITIVITY_Y;
}
-
- // Smoothly interpolate the lookAt position
- Vec3f targetLookAt = { camera->pos[0] + forwardVector[0], camera->pos[1] + forwardVector[1],
- camera->pos[2] + forwardVector[2] };
-
- // Smoothing
- camera->lookAt[0] += (targetLookAt[0] - camera->lookAt[0]) * gFreecamRotateSmoothingFactor;
- camera->lookAt[1] += (targetLookAt[1] - camera->lookAt[1]) * gFreecamRotateSmoothingFactor;
- camera->lookAt[2] += (targetLookAt[2] - camera->lookAt[2]) * gFreecamRotateSmoothingFactor;
+ // Update rotational velocity based on mouse movement
+ freeCam.rotVelocity[1] += yawChange * 65535.0f / (2 * M_PI); // Yaw (left/right)
+ freeCam.rotVelocity[2] += pitchChange * 65535.0f / (2 * M_PI); // Pitch (up/down)
}
}
@@ -186,7 +198,6 @@ bool FreecamKeyDown(int virtualKey) {
void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) {
auto wnd = GameEngine::Instance->context->GetWindow();
float moveSpeed = gFreecamSpeed;
- Controller* controller = &gControllers[0];
// Determine movement direction based on keys pressed
Vec3f totalMove = { 0.0f, 0.0f, 0.0f };
@@ -207,44 +218,42 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) {
// Use n64 controls for use with a controller
//! @todo configure this properly
- if (gFreecamControllerType == 1) {
- // Targeting /fMode is broken
- // if (controller->buttonPressed & U_JPAD) {
- // fMode = !fMode;
- // }
- // Target a player
- if (controller->buttonPressed & R_TRIG) {
- fTargetPlayer = !fTargetPlayer;
+ if (bFreecamUseController) {
+ if (fController.buttonDepressed & R_TRIG) {
+ fTargetPlayer = true;
+ }
+ if (fController.buttonDepressed & L_TRIG) {
+ fTargetPlayer = false;
}
- if (controller->buttonPressed & L_CBUTTONS) {
+ if (fController.buttonPressed & L_JPAD) {
TargetPreviousPlayer = true;
}
- if (controller->buttonPressed & R_CBUTTONS) {
+ if (fController.buttonPressed & R_JPAD) {
TargetNextPlayer = true;
}
- if (controller->button & A_BUTTON) {
+ if (fController.rawStickY > 10) {
Forward = true;
}
- if (controller->button & B_BUTTON) {
+ if (fController.rawStickY < -10) {
Backward = true;
}
- if (controller->button & L_JPAD) {
- PanLeft = true;
+ if (fController.rawStickX > 10) {
+ PanRight = true;
}
- if (controller->button & R_JPAD) {
+ if (fController.rawStickX < -10) {
PanLeft = true;
}
- if (controller->button & U_CBUTTONS) {
+ if (fController.button & B_BUTTON) {
Down = true;
}
- if (controller->button & U_CBUTTONS) {
+ if (fController.button & A_BUTTON) {
Up = true;
}
- // if (controller->button ??) {
- // FastMove = true;
- // }
- // Keyboard and mouse DX
+ if (fController.button & Z_TRIG) {
+ FastMove = true;
+ }
}
+ // Keyboard and mouse DX
#ifdef _WIN32
else if (wnd->GetWindowBackend() == Ship::WindowBackend::FAST3D_DXGI_DX11) {
if (FreecamKeyDown('F')) {
@@ -364,6 +373,23 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) {
freeCam.velocity[2] += totalMove[2];
}
+void freecam_update_controller(void) {
+ fController.rawStickX = gControllerPads[0].stick_x;
+ fController.rawStickY = gControllerPads[0].stick_y;
+
+ fController.rightRawStickX = gControllerPads[0].right_stick_x;
+ fController.rightRawStickY = gControllerPads[0].right_stick_y;
+
+ if ((gControllerPads[0].button & 4) != 0) {
+ gControllerPads[0].button |= Z_TRIG;
+ }
+ fController.buttonPressed = gControllerPads[0].button & (gControllerPads[0].button ^ fController.button);
+ fController.buttonDepressed = fController.button & (gControllerPads[0].button ^ fController.button);
+ fController.button = gControllerPads[0].button;
+
+ // Note that D Pad as stick code has been removed. So if it's needed, it needs to be put back in.
+}
+
void freecam_render_setup(void) {
u16 perspNorm;
Mat4 matrix;