diff options
Diffstat (limited to 'src/enhancements/freecam/freecam.cpp')
| -rw-r--r-- | src/enhancements/freecam/freecam.cpp | 160 |
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; |
