Make freecam work on DX and fix controller
This commit is contained in:
parent
cb21fc1209
commit
9400f9e9ce
|
|
@ -150,6 +150,7 @@ file(GLOB_RECURSE ALL_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
|
|||
"src/enhancements/*.c"
|
||||
"src/enhancements/*.h"
|
||||
"src/enhancements/freecam/*.c"
|
||||
"src/enhancements/freecam/*.cpp"
|
||||
"src/enhancements/freecam/*.h"
|
||||
"src/engine/*.cpp"
|
||||
"src/engine/*.h"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,11 @@
|
|||
#include <libultraship.h>
|
||||
#include <window/Window.h>
|
||||
#include "port/Engine.h"
|
||||
#include "port/Game.h"
|
||||
#include <controller/controldevice/controller/mapping/keyboard/KeyboardScancodes.h>
|
||||
#include <window/Window.h>
|
||||
|
||||
extern "C" {
|
||||
#include <macros.h>
|
||||
#include <defines.h>
|
||||
#include <camera.h>
|
||||
|
|
@ -12,10 +19,10 @@
|
|||
#include "code_80005FD0.h"
|
||||
#include <SDL2/SDL.h>
|
||||
#include "freecam_engine.h"
|
||||
#include "n64_freecam.h"
|
||||
#include "math_util.h"
|
||||
#include "skybox_and_splitscreen.h"
|
||||
#include "freecam.h"
|
||||
}
|
||||
|
||||
#include "engine/Engine.h"
|
||||
#include "engine/courses/Course.h"
|
||||
|
|
@ -123,14 +130,10 @@ void freecam(Camera* camera, Player* player, s8 index) {
|
|||
|
||||
// if ((player->type & PLAYER_START_SEQUENCE)) { return; }
|
||||
|
||||
// Mouse/Keyboard
|
||||
if (gFreecamControllerType == 0) {
|
||||
freecam_calculate_forward_vector_allow_rotation(camera, freeCam.forwardVector);
|
||||
freecam_mouse_manager(camera, freeCam.forwardVector);
|
||||
freecam_keyboard_manager(camera, freeCam.forwardVector);
|
||||
} else { // Stock N64 controller
|
||||
freecam_n64_controller_manager(camera, controller, player);
|
||||
}
|
||||
freecam_calculate_forward_vector_allow_rotation(camera, freeCam.forwardVector);
|
||||
freecam_mouse_manager(camera, freeCam.forwardVector);
|
||||
freecam_keyboard_manager(camera, freeCam.forwardVector);
|
||||
|
||||
if (!fTargetPlayer) {
|
||||
freecam_update(camera, freeCam.forwardVector);
|
||||
}
|
||||
|
|
@ -168,19 +171,23 @@ void freecam_load_state(Camera* camera) {
|
|||
f32 gFreecamRotateSmoothingFactor = 0.85f;
|
||||
|
||||
void freecam_mouse_manager(Camera* camera, Vec3f forwardVector) {
|
||||
int mouseX, mouseY;
|
||||
static int prevMouseX = 0, prevMouseY = 0;
|
||||
Uint32 mouseState = SDL_GetRelativeMouseState(&mouseX, &mouseY);
|
||||
auto wnd = GameEngine::Instance->context->GetWindow();
|
||||
Ship::Coords mouse = wnd->GetMouseDelta();
|
||||
|
||||
mouseX = (mouseX + prevMouseX) / 2;
|
||||
mouseY = (mouseY + prevMouseY) / 2;
|
||||
prevMouseX = mouseX;
|
||||
prevMouseY = mouseY;
|
||||
//Uint32 mouseState = SDL_GetRelativeMouseState(&mouse.x, &mouse.y);
|
||||
|
||||
if (mouseState & SDL_BUTTON(SDL_BUTTON_RIGHT)) {
|
||||
//printf("MOUSE %d %d\n", mouse.x, mouse.y);
|
||||
|
||||
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 = mouseX * MOUSE_SENSITIVITY_X;
|
||||
f32 pitchChange = mouseY * MOUSE_SENSITIVITY_Y;
|
||||
f32 yawChange = mouse.x * MOUSE_SENSITIVITY_X;
|
||||
f32 pitchChange = mouse.y * MOUSE_SENSITIVITY_Y;
|
||||
|
||||
// Smoothly update yaw and pitch
|
||||
camera->rot[1] += (short) (yawChange * 65535.0f / (2 * M_PI)); // Yaw (left/right)
|
||||
|
|
@ -212,13 +219,14 @@ f32 gFreecamSpeed = 3.0f;
|
|||
f32 gFreecamSpeedMultiplier = 2.0f;
|
||||
|
||||
void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) {
|
||||
const uint8_t* keystate = SDL_GetKeyboardState(NULL);
|
||||
auto wnd = GameEngine::Instance->context->GetWindow();
|
||||
float moveSpeed = gFreecamSpeed;
|
||||
Controller* controller = &gControllers[0];
|
||||
|
||||
// Fast movement with Ctrl
|
||||
if (keystate[SDL_SCANCODE_LCTRL] || keystate[SDL_SCANCODE_RCTRL]) {
|
||||
moveSpeed *= gFreecamSpeedMultiplier;
|
||||
}
|
||||
//if (wnd->KeyDown(SDL_SCANCODE_LCTRL) || wnd->KeyDown(SDL_SCANCODE_RCTRL)) {
|
||||
// moveSpeed *= gFreecamSpeedMultiplier;
|
||||
//}
|
||||
|
||||
// Determine movement direction based on keys pressed
|
||||
Vec3f totalMove = { 0.0f, 0.0f, 0.0f };
|
||||
|
|
@ -232,52 +240,153 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) {
|
|||
// fTargetPlayer = false;
|
||||
// }
|
||||
|
||||
// Target next player
|
||||
if (keystate[SDL_SCANCODE_N]) {
|
||||
if (fRankIndex > 0) {
|
||||
fRankIndex--;
|
||||
camera->playerId = fRankIndex;
|
||||
D_800DC5EC->player = &gPlayers[fRankIndex];
|
||||
bool TargetNextPlayer = false, TargetPreviousPlayer = false;
|
||||
bool Forward = false, PanLeft = false, Backward = false, PanRight = false;
|
||||
bool Up = false, Down = false, RSHIFT_Down = false;
|
||||
|
||||
// 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 (controller->buttonPressed & L_CBUTTONS) {
|
||||
TargetNextPlayer = true;
|
||||
}
|
||||
if (controller->buttonPressed & R_CBUTTONS) {
|
||||
TargetPreviousPlayer = true;
|
||||
}
|
||||
if (controller->button & A_BUTTON) {
|
||||
Forward = true;
|
||||
}
|
||||
if (controller->button & B_BUTTON) {
|
||||
Backward = true;
|
||||
}
|
||||
if (controller->button & L_JPAD) {
|
||||
PanLeft = true;
|
||||
}
|
||||
if (controller->button & R_JPAD) {
|
||||
PanLeft = true;
|
||||
}
|
||||
if (controller->button & U_CBUTTONS) {
|
||||
Down = true;
|
||||
}
|
||||
if (controller->button & U_CBUTTONS) {
|
||||
Up = true;
|
||||
}
|
||||
// Keyboard and mouse DX
|
||||
} else if (wnd->GetWindowBackend() == Ship::WindowBackend::FAST3D_DXGI_DX11) {
|
||||
if (GetKeyState('N') & 0x8000) {
|
||||
TargetNextPlayer = true;
|
||||
}
|
||||
if (GetKeyState('M') & 0x8000) {
|
||||
TargetPreviousPlayer = true;
|
||||
}
|
||||
if (GetKeyState('W') & 0x8000) {
|
||||
Forward = true;
|
||||
}
|
||||
if (GetKeyState('S') & 0x8000) {
|
||||
Backward = true;
|
||||
}
|
||||
if (GetKeyState('D') & 0x8000) {
|
||||
PanRight = true;
|
||||
}
|
||||
if (GetKeyState('A') & 0x8000) {
|
||||
PanLeft = true;
|
||||
}
|
||||
if (GetKeyState(VK_SPACE) & 0x8000) {
|
||||
Up = true;
|
||||
}
|
||||
if (GetKeyState(VK_LSHIFT) & 0x8000) {
|
||||
Down = true;
|
||||
}
|
||||
if (GetKeyState(VK_RSHIFT) & 0x8000) {
|
||||
RSHIFT_Down = true;
|
||||
}
|
||||
// Keyboard/mouse OpenGL/SDL
|
||||
} else if (wnd->GetWindowBackend() == Ship::WindowBackend::FAST3D_SDL_OPENGL) {
|
||||
const uint8_t* keystate = SDL_GetKeyboardState(NULL);
|
||||
if (keystate[SDL_SCANCODE_N]) {
|
||||
TargetNextPlayer = true;
|
||||
}
|
||||
if (keystate[SDL_SCANCODE_M]) {
|
||||
TargetPreviousPlayer = true;
|
||||
}
|
||||
if (keystate[SDL_SCANCODE_W]) {
|
||||
Forward = true;
|
||||
}
|
||||
if (keystate[SDL_SCANCODE_S]) {
|
||||
Backward = true;
|
||||
}
|
||||
if (keystate[SDL_SCANCODE_D]) {
|
||||
PanRight = true;
|
||||
}
|
||||
if (keystate[SDL_SCANCODE_A]) {
|
||||
PanLeft = true;
|
||||
}
|
||||
if (keystate[SDL_SCANCODE_SPACE]) {
|
||||
Up = true;
|
||||
}
|
||||
if (keystate[SDL_SCANCODE_LSHIFT]) {
|
||||
Down = true;
|
||||
}
|
||||
if (keystate[SDL_SCANCODE_RSHIFT]) {
|
||||
RSHIFT_Down = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Target next player
|
||||
if (TargetNextPlayer) {
|
||||
if (fRankIndex > 0) {
|
||||
fRankIndex--;
|
||||
camera->playerId = fRankIndex;
|
||||
D_800DC5EC->player = &gPlayers[fRankIndex];
|
||||
}
|
||||
}
|
||||
|
||||
// Target previous player
|
||||
if (keystate[SDL_SCANCODE_M]) {
|
||||
if (fRankIndex < 7) {
|
||||
fRankIndex++;
|
||||
camera->playerId = fRankIndex;
|
||||
D_800DC5EC->player = &gPlayers[fRankIndex];
|
||||
}
|
||||
if (TargetPreviousPlayer) {
|
||||
if (fRankIndex < 7) {
|
||||
fRankIndex++;
|
||||
camera->playerId = fRankIndex;
|
||||
D_800DC5EC->player = &gPlayers[fRankIndex];
|
||||
}
|
||||
}
|
||||
|
||||
// Target camera at chosen player
|
||||
if (fRankIndex != -1) {
|
||||
freecam_target_player(camera, gGPCurrentRacePlayerIdByRank[fRankIndex]);
|
||||
// Don't run the other camera code.
|
||||
return;
|
||||
freecam_target_player(camera, gGPCurrentRacePlayerIdByRank[fRankIndex]);
|
||||
// Don't run the other camera code.
|
||||
return;
|
||||
}
|
||||
|
||||
if (keystate[SDL_SCANCODE_W]) {
|
||||
totalMove[0] += forwardVector[0] * moveSpeed;
|
||||
totalMove[2] += forwardVector[2] * moveSpeed;
|
||||
if (Forward) {
|
||||
totalMove[0] += forwardVector[0] * moveSpeed;
|
||||
totalMove[2] += forwardVector[2] * moveSpeed;
|
||||
}
|
||||
if (keystate[SDL_SCANCODE_S]) {
|
||||
totalMove[0] -= forwardVector[0] * moveSpeed;
|
||||
totalMove[2] -= forwardVector[2] * moveSpeed;
|
||||
if (Backward) {
|
||||
totalMove[0] -= forwardVector[0] * moveSpeed;
|
||||
totalMove[2] -= forwardVector[2] * moveSpeed;
|
||||
}
|
||||
if (keystate[SDL_SCANCODE_D]) {
|
||||
totalMove[0] -= forwardVector[2] * moveSpeed; // Pan right
|
||||
totalMove[2] += forwardVector[0] * moveSpeed;
|
||||
if (PanRight) {
|
||||
totalMove[0] -= forwardVector[2] * moveSpeed; // Pan right
|
||||
totalMove[2] += forwardVector[0] * moveSpeed;
|
||||
}
|
||||
if (keystate[SDL_SCANCODE_A]) {
|
||||
totalMove[0] += forwardVector[2] * moveSpeed; // Pan left
|
||||
totalMove[2] -= forwardVector[0] * moveSpeed;
|
||||
if (PanLeft) {
|
||||
totalMove[0] += forwardVector[2] * moveSpeed; // Pan left
|
||||
totalMove[2] -= forwardVector[0] * moveSpeed;
|
||||
}
|
||||
if (keystate[SDL_SCANCODE_SPACE]) {
|
||||
totalMove[1] += moveSpeed; // Move up
|
||||
if (Up) {
|
||||
totalMove[1] += moveSpeed; // Move up
|
||||
}
|
||||
if (keystate[SDL_SCANCODE_LSHIFT] || keystate[SDL_SCANCODE_RSHIFT]) {
|
||||
totalMove[1] -= moveSpeed; // Move down
|
||||
if (Down || RSHIFT_Down) {
|
||||
totalMove[1] -= moveSpeed; // Move down
|
||||
}
|
||||
freeCam.velocity[0] += totalMove[0];
|
||||
freeCam.velocity[1] += totalMove[1];
|
||||
|
|
@ -288,70 +397,6 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) {
|
|||
camera->lookAt[2] = camera->pos[2] + forwardVector[2];
|
||||
}
|
||||
|
||||
// Control the camera using the n64 controller
|
||||
void freecam_n64_controller_manager(Camera* camera, struct Controller* controller, Player* player) {
|
||||
|
||||
if (controller->buttonPressed & U_JPAD) {
|
||||
fMode = !fMode;
|
||||
}
|
||||
|
||||
// Target a player
|
||||
if (controller->buttonPressed & R_TRIG) {
|
||||
fTargetPlayer = !fTargetPlayer;
|
||||
}
|
||||
|
||||
// Target next player
|
||||
if (controller->buttonPressed & L_CBUTTONS) {
|
||||
if (fRankIndex > 0) {
|
||||
fRankIndex--;
|
||||
camera->playerId = fRankIndex;
|
||||
D_800DC5EC->player = &gPlayers[fRankIndex];
|
||||
}
|
||||
}
|
||||
|
||||
// Target previous player
|
||||
if (controller->buttonPressed & R_CBUTTONS) {
|
||||
if (fRankIndex < 7) {
|
||||
fRankIndex++;
|
||||
camera->playerId = fRankIndex;
|
||||
D_800DC5EC->player = &gPlayers[fRankIndex];
|
||||
}
|
||||
}
|
||||
|
||||
// Target camera at chosen player
|
||||
if (fTargetPlayer) {
|
||||
freecam_target_player(camera, gGPCurrentRacePlayerIdByRank[fRankIndex]);
|
||||
// Don't run the other camera code.
|
||||
return;
|
||||
}
|
||||
|
||||
// Rotation
|
||||
if (!fTargetPlayer) {
|
||||
if (controller->stickDirection != 0) {
|
||||
freecam_n64_update(camera, controller);
|
||||
}
|
||||
}
|
||||
|
||||
// Forward
|
||||
if (controller->button & A_BUTTON) {
|
||||
freecam_n64_move_camera_forward(camera, controller, 3.0f);
|
||||
}
|
||||
|
||||
// Backward B button but not A button.
|
||||
if (controller->button & B_BUTTON && !(controller->button & A_BUTTON)) {
|
||||
freecam_n64_move_camera_forward(camera, controller, -3.0f);
|
||||
}
|
||||
|
||||
// Up
|
||||
if (controller->button & U_CBUTTONS) {
|
||||
freecam_n64_move_camera_up(camera, controller, 2.0f);
|
||||
}
|
||||
// Up
|
||||
if (controller->button & D_CBUTTONS) {
|
||||
freecam_n64_move_camera_up(camera, controller, -2.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void freecam_render_setup(void) {
|
||||
u16 perspNorm;
|
||||
Mat4 matrix;
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
#include <libultraship.h>
|
||||
#include <defines.h>
|
||||
#include <macros.h>
|
||||
#include "code_80057C60.h"
|
||||
#include "code_800029B0.h"
|
||||
#include "code_80005FD0.h"
|
||||
#include "camera.h"
|
||||
#include <common_structs.h>
|
||||
#include "player_controller.h"
|
||||
#include "collision.h"
|
||||
#include "freecam_engine.h"
|
||||
|
||||
#define N64_SENSITIVITY_X 0.0003f
|
||||
#define N64_SENSITIVITY_Y 0.0003f
|
||||
|
||||
// Calculates the forward direction vector based on camera orientation
|
||||
void freecam_n64_calculate_forward_vector(Camera* camera, Vec3f forwardVector) {
|
||||
f32 pitch = (camera->rot[2] / 65535.0f) * 360.0f; // Convert pitch from 0-65535 to degrees
|
||||
f32 yaw = (camera->rot[1] / 65535.0f) * 360.0f; // Convert yaw from 0-65535 to degrees
|
||||
|
||||
// Convert degrees to radians
|
||||
pitch = pitch * M_PI / 180.0f;
|
||||
yaw = yaw * M_PI / 180.0f;
|
||||
|
||||
forwardVector[0] = -sinf(yaw) * cosf(pitch);
|
||||
forwardVector[1] = -sinf(pitch);
|
||||
forwardVector[2] = cosf(yaw) * cosf(pitch);
|
||||
}
|
||||
|
||||
// Function to move the camera forward
|
||||
void freecam_n64_move_camera_forward(Camera* camera, struct Controller* controller, f32 distance) {
|
||||
Vec3f forwardVector;
|
||||
Vec3f rightVector;
|
||||
f32 length;
|
||||
freecam_n64_calculate_forward_vector(camera, forwardVector);
|
||||
|
||||
if (controller->button & Z_TRIG) {
|
||||
distance *= 3;
|
||||
}
|
||||
|
||||
// Normalize the forward vector
|
||||
length = sqrtf(forwardVector[0] * forwardVector[0] + forwardVector[1] * forwardVector[1] +
|
||||
forwardVector[2] * forwardVector[2]);
|
||||
forwardVector[0] /= length;
|
||||
forwardVector[1] /= length;
|
||||
forwardVector[2] /= length;
|
||||
|
||||
// Calculate the right vector by taking the cross product of forward and up
|
||||
rightVector[0] = forwardVector[1] * camera->up[2] - forwardVector[2] * camera->up[1];
|
||||
rightVector[1] = forwardVector[2] * camera->up[0] - forwardVector[0] * camera->up[2];
|
||||
rightVector[2] = forwardVector[0] * camera->up[1] - forwardVector[1] * camera->up[0];
|
||||
|
||||
// Move the camera's position along the forward vector while considering its up vector
|
||||
camera->pos[0] += forwardVector[0] * distance;
|
||||
camera->pos[1] += forwardVector[1] * distance;
|
||||
camera->pos[2] += forwardVector[2] * distance;
|
||||
|
||||
// Optionally, you can also adjust the lookAt point to maintain the same relative position
|
||||
camera->lookAt[0] += forwardVector[0] * distance;
|
||||
camera->lookAt[1] += forwardVector[1] * distance;
|
||||
camera->lookAt[2] += forwardVector[2] * distance;
|
||||
}
|
||||
|
||||
// Function to move the camera forward
|
||||
void freecam_n64_move_camera_up(Camera* camera, struct Controller* controller, f32 distance) {
|
||||
// Check if the Z button is pressed (for faster movement)
|
||||
if (controller->button & Z_TRIG) {
|
||||
distance *= 3;
|
||||
}
|
||||
|
||||
// Move the camera's position along its up vector (Y-axis)
|
||||
camera->pos[1] += distance;
|
||||
|
||||
// Optionally, adjust the lookAt point to maintain the same relative position
|
||||
camera->lookAt[1] += distance;
|
||||
}
|
||||
|
||||
// Update camera rotation and lookAt point based on input
|
||||
void freecam_n64_update(Camera* camera, struct Controller* controller) {
|
||||
// Calculate yaw (horizontal movement)
|
||||
f32 yawChange = controller->rawStickX * N64_SENSITIVITY_X;
|
||||
f32 pitchChange = controller->rawStickY * N64_SENSITIVITY_Y;
|
||||
Vec3f forwardVector;
|
||||
|
||||
check_bounding_collision(&camera->collision, 50, camera->pos[0], camera->pos[1], camera->pos[2]);
|
||||
|
||||
camera->rot[1] += (short) (yawChange * 65535.0f / (2 * M_PI)); // Convert radians to 0-65535 range
|
||||
|
||||
camera->rot[2] += (short) (-pitchChange * 65535.0f / (2 * M_PI)); // Convert radians to 0-65535 range
|
||||
|
||||
if (camera->rot[2] > 15999) {
|
||||
camera->rot[2] = 15999;
|
||||
} else if (camera->rot[2] < -15999) {
|
||||
camera->rot[2] = -15999;
|
||||
}
|
||||
|
||||
// Update the lookAt point based on the new orientation
|
||||
freecam_calculate_forward_vector(camera, forwardVector);
|
||||
camera->lookAt[0] = camera->pos[0] + forwardVector[0];
|
||||
camera->lookAt[1] = camera->pos[1] + forwardVector[1];
|
||||
camera->lookAt[2] = camera->pos[2] + forwardVector[2];
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
#ifndef N64_FREECAM_H
|
||||
#define N64_FREECAM_H
|
||||
|
||||
#include <libultraship.h>
|
||||
|
||||
void freecam_n64_move_camera_up(Camera* camera, struct Controller* controller, f32 distance);
|
||||
void freecam_n64_controller_manager(Camera* camera, struct Controller* controller, Player* player);
|
||||
void freecam_n64_calculate_forward_vector(Camera* camera, Vec3f forwardVector);
|
||||
void freecam_n64_move_camera_forward(Camera* camera, struct Controller* controller, f32 distance);
|
||||
void freecam_n64_update(Camera* camera, struct Controller* controller);
|
||||
|
||||
#endif // N64_FREECAM_H
|
||||
|
|
@ -53,9 +53,9 @@ void FreecamWindow::DrawElement() {
|
|||
const float deltatime = ImGui::GetIO().DeltaTime;
|
||||
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
|
||||
|
||||
ImGui::Text("Freecam: Mouse/Keyboard Requires OpenGL. DX is not supported");
|
||||
ImGui::Text("Controller mode is not configured yet.");
|
||||
|
||||
const char* items[] = { "Mouse/Keyboard", "N64 Controls" };
|
||||
const char* items[] = { "Mouse/Keyboard", "Controller" };
|
||||
static int current_item = 0;
|
||||
if (ImGui::Combo("Dropdown", ¤t_item, items, IM_ARRAYSIZE(items))) {
|
||||
gFreecamControllerType = current_item;
|
||||
|
|
|
|||
Loading…
Reference in New Issue