From ec5eb3c1b91514687f1086da9263fb094ba15557 Mon Sep 17 00:00:00 2001 From: MegaMech <7255464+MegaMech@users.noreply.github.com> Date: Sun, 5 Jan 2025 16:29:06 -0700 Subject: [PATCH 01/10] Update lus --- libultraship | 2 +- src/port/Engine.cpp | 60 ++++++++++++++++++++++++-------------- src/port/Engine.h | 8 ++--- src/port/GBIMiddleware.cpp | 8 ++--- 4 files changed, 45 insertions(+), 33 deletions(-) diff --git a/libultraship b/libultraship index 80c2c5e9c..3e46fe77a 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit 80c2c5e9c6a5681428f759100c2428c5e41f333c +Subproject commit 3e46fe77a4581a84f9c0edfab9c3a69a5320fe01 diff --git a/src/port/Engine.cpp b/src/port/Engine.cpp index 6c43b48bb..23c5dbdbe 100644 --- a/src/port/Engine.cpp +++ b/src/port/Engine.cpp @@ -62,10 +62,26 @@ GameEngine::GameEngine() { } } - this->context = Ship::Context::CreateInstance("Spaghettify", "skart64", "spaghettify.cfg.json", OTRFiles, {}, 3, - { 26800, 512, 1100 }); + this->context = + Ship::Context::CreateUninitializedInstance("Spaghetti Kart", "spaghettify", "spaghettify.cfg.json"); + + this->context->InitConfiguration(); // without this line InitConsoleVariables fails at Config::Reload() + this->context->InitConsoleVariables(); // without this line the controldeck constructor failes in ShipDeviceIndexMappingManager::UpdateControllerNamesFromConfig() + + auto controlDeck = std::make_shared(); + + this->context->InitResourceManager(OTRFiles, {}, 3); // without this line InitWindow fails in Gui::Init() + this->context->InitConsole(); // without this line the GuiWindow constructor fails in ConsoleWindow::InitElement() + + auto wnd = std::make_shared(std::vector>({})); + //auto wnd = std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()); + + this->context->Init(OTRFiles, {}, 3, { 26800, 512, 1100 }, wnd, controlDeck); + + + // this->context = Ship::Context::CreateInstance("Spaghettify", "skart64", "spaghettify.cfg.json", OTRFiles, {}, 3, + // { 26800, 512, 1100 }); - auto wnd = std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()); wnd->SetRendererUCode(ucode_f3dex); this->context->InitGfxDebugger(); @@ -84,27 +100,27 @@ GameEngine::GameEngine() { loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "GenericArray", static_cast(SF64::ResourceType::GenericArray), 0); - loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, - "Texture", static_cast(LUS::ResourceType::Texture), 0); - loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, - "Texture", static_cast(LUS::ResourceType::Texture), 1); + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, + "Texture", static_cast(Fast::ResourceType::Texture), 0); + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, + "Texture", static_cast(Fast::ResourceType::Texture), 1); - loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, - "Vertex", static_cast(LUS::ResourceType::Vertex), 0); - loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_XML, "Vertex", - static_cast(LUS::ResourceType::Vertex), 0); + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, + "Vertex", static_cast(Fast::ResourceType::Vertex), 0); + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_XML, "Vertex", + static_cast(Fast::ResourceType::Vertex), 0); - loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, - "DisplayList", static_cast(LUS::ResourceType::DisplayList), 0); - loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_XML, - "DisplayList", static_cast(LUS::ResourceType::DisplayList), 0); + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, + "DisplayList", static_cast(Fast::ResourceType::DisplayList), 0); + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_XML, + "DisplayList", static_cast(Fast::ResourceType::DisplayList), 0); - loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, - "Matrix", static_cast(LUS::ResourceType::Matrix), 0); - loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, - "Blob", static_cast(LUS::ResourceType::Blob), 0); - loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, - "Lights1", static_cast(LUS::ResourceType::Light), 0); + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, + "Matrix", static_cast(Fast::ResourceType::Matrix), 0); + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, + "Blob", static_cast(Ship::ResourceType::Blob), 0); + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, + "Lights1", static_cast(Fast::ResourceType::Light), 0); loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Array", static_cast(MK64::ResourceType::MK_Array), 0); loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, @@ -233,7 +249,7 @@ void GameEngine::EndAudioFrame() { void GameEngine::AudioInit() { const auto resourceMgr = Ship::Context::GetInstance()->GetResourceManager(); - resourceMgr->LoadDirectory("sound"); + resourceMgr->LoadResources("sound"); const auto banksFiles = resourceMgr->GetArchiveManager()->ListFiles("sound/banks/*"); const auto sequences_files = resourceMgr->GetArchiveManager()->ListFiles("sound/sequences/*"); diff --git a/src/port/Engine.h b/src/port/Engine.h index 94f0e4d33..25e61d5c4 100644 --- a/src/port/Engine.h +++ b/src/port/Engine.h @@ -55,11 +55,7 @@ class GameEngine { uint32_t OTRCalculateCenterOfAreaFromRightEdge(int32_t center); uint32_t OTRCalculateCenterOfAreaFromLeftEdge(int32_t center); }; -#endif - -#ifdef __cplusplus -extern "C" { -#endif +#else void GameEngine_ProcessGfxCommands(Gfx* commands); uint32_t GameEngine_GetSampleRate(); uint32_t GameEngine_GetSamplesPerFrame(); @@ -81,4 +77,4 @@ uint32_t OTRGetGameRenderWidth(void); uint32_t OTRGetGameRenderHeight(void); uint32_t OTRCalculateCenterOfAreaFromRightEdge(int32_t center); uint32_t OTRCalculateCenterOfAreaFromLeftEdge(int32_t center); -#endif +#endif // __cplusplus diff --git a/src/port/GBIMiddleware.cpp b/src/port/GBIMiddleware.cpp index 9b3f1e71d..3881453d1 100644 --- a/src/port/GBIMiddleware.cpp +++ b/src/port/GBIMiddleware.cpp @@ -13,7 +13,7 @@ extern "C" void gSPDisplayList(Gfx* pkt, Gfx* dl) { if (GameEngine_OTRSigCheck(imgData)) { auto resource = Ship::Context::GetInstance()->GetResourceManager()->LoadResource(imgData); - auto res = std::static_pointer_cast(resource); + auto res = std::static_pointer_cast(resource); dl = &res->Instructions[0]; } @@ -34,10 +34,10 @@ extern "C" void gSPInvalidateTexCache(Gfx* pkt, uintptr_t texAddr) { if (texAddr != 0 && GameEngine_OTRSigCheck(data)) { const auto res = Ship::Context::GetInstance()->GetResourceManager()->LoadResource(data); - const auto type = static_cast(res->GetInitData()->Type); + const auto type = static_cast(res->GetInitData()->Type); - if (res->GetInitData()->Type == static_cast(LUS::ResourceType::DisplayList)) { - texAddr = reinterpret_cast(&std::static_pointer_cast(res)->Instructions[0]); + if (res->GetInitData()->Type == static_cast(Fast::ResourceType::DisplayList)) { + texAddr = reinterpret_cast(&std::static_pointer_cast(res)->Instructions[0]); } else if (res->GetInitData()->Type == static_cast(MK64::ResourceType::MK_Array)) { texAddr = reinterpret_cast(std::static_pointer_cast(res)->Vertices.data()); } else { From 7e50b7c29ef81e1f3a92ad609f6956287063c979 Mon Sep 17 00:00:00 2001 From: MegaMech <7255464+MegaMech@users.noreply.github.com> Date: Sun, 5 Jan 2025 17:10:38 -0700 Subject: [PATCH 02/10] Disable texture filtering --- src/port/Engine.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/port/Engine.cpp b/src/port/Engine.cpp index 23c5dbdbe..bc942ac90 100644 --- a/src/port/Engine.cpp +++ b/src/port/Engine.cpp @@ -76,6 +76,9 @@ GameEngine::GameEngine() { auto wnd = std::make_shared(std::vector>({})); //auto wnd = std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()); + // Turn off texture filtering because menus are borked with it on + CVarSetInteger("gTextureFilter", 2); + this->context->Init(OTRFiles, {}, 3, { 26800, 512, 1100 }, wnd, controlDeck); From cb21fc1209905b8cd8d1f8d43c28b9dc62c36100 Mon Sep 17 00:00:00 2001 From: MegaMech <7255464+MegaMech@users.noreply.github.com> Date: Sun, 5 Jan 2025 17:23:41 -0700 Subject: [PATCH 03/10] Fix texture filter off --- src/port/Engine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/port/Engine.cpp b/src/port/Engine.cpp index bc942ac90..262cca633 100644 --- a/src/port/Engine.cpp +++ b/src/port/Engine.cpp @@ -77,7 +77,7 @@ GameEngine::GameEngine() { //auto wnd = std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()); // Turn off texture filtering because menus are borked with it on - CVarSetInteger("gTextureFilter", 2); + CVarRegisterInteger("gTextureFilter", 2); this->context->Init(OTRFiles, {}, 3, { 26800, 512, 1100 }, wnd, controlDeck); From 9400f9e9ce6c205ff2f084850f81429875c99c49 Mon Sep 17 00:00:00 2001 From: MegaMech <7255464+MegaMech@users.noreply.github.com> Date: Mon, 6 Jan 2025 17:38:16 -0700 Subject: [PATCH 04/10] Make freecam work on DX and fix controller --- CMakeLists.txt | 1 + .../freecam/{freecam.c => freecam.cpp} | 279 ++++++++++-------- src/enhancements/freecam/n64_freecam.c | 102 ------- src/enhancements/freecam/n64_freecam.h | 12 - src/port/ui/FreecamWindow.cpp | 4 +- 5 files changed, 165 insertions(+), 233 deletions(-) rename src/enhancements/freecam/{freecam.c => freecam.cpp} (59%) delete mode 100644 src/enhancements/freecam/n64_freecam.c delete mode 100644 src/enhancements/freecam/n64_freecam.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d2f8f1d6b..1fa0a5dc8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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" diff --git a/src/enhancements/freecam/freecam.c b/src/enhancements/freecam/freecam.cpp similarity index 59% rename from src/enhancements/freecam/freecam.c rename to src/enhancements/freecam/freecam.cpp index ef9df134c..86c2dd948 100644 --- a/src/enhancements/freecam/freecam.c +++ b/src/enhancements/freecam/freecam.cpp @@ -1,4 +1,11 @@ #include +#include +#include "port/Engine.h" +#include "port/Game.h" +#include +#include + +extern "C" { #include #include #include @@ -12,10 +19,10 @@ #include "code_80005FD0.h" #include #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; diff --git a/src/enhancements/freecam/n64_freecam.c b/src/enhancements/freecam/n64_freecam.c deleted file mode 100644 index 48628507a..000000000 --- a/src/enhancements/freecam/n64_freecam.c +++ /dev/null @@ -1,102 +0,0 @@ -#include -#include -#include -#include "code_80057C60.h" -#include "code_800029B0.h" -#include "code_80005FD0.h" -#include "camera.h" -#include -#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]; -} diff --git a/src/enhancements/freecam/n64_freecam.h b/src/enhancements/freecam/n64_freecam.h deleted file mode 100644 index 17eba53f4..000000000 --- a/src/enhancements/freecam/n64_freecam.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef N64_FREECAM_H -#define N64_FREECAM_H - -#include - -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 diff --git a/src/port/ui/FreecamWindow.cpp b/src/port/ui/FreecamWindow.cpp index 4bbfc9055..de9706c2f 100644 --- a/src/port/ui/FreecamWindow.cpp +++ b/src/port/ui/FreecamWindow.cpp @@ -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; From f20e5108e1b5432125720f161a58199b5bf1744e Mon Sep 17 00:00:00 2001 From: MegaMech <7255464+MegaMech@users.noreply.github.com> Date: Mon, 6 Jan 2025 17:47:30 -0700 Subject: [PATCH 05/10] Add fast move back in --- src/enhancements/freecam/freecam.cpp | 30 ++++++++++++++++------------ 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/enhancements/freecam/freecam.cpp b/src/enhancements/freecam/freecam.cpp index 86c2dd948..84d18a2b8 100644 --- a/src/enhancements/freecam/freecam.cpp +++ b/src/enhancements/freecam/freecam.cpp @@ -223,11 +223,6 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { float moveSpeed = gFreecamSpeed; Controller* controller = &gControllers[0]; - // Fast movement with Ctrl - //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 }; @@ -242,7 +237,8 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { bool TargetNextPlayer = false, TargetPreviousPlayer = false; bool Forward = false, PanLeft = false, Backward = false, PanRight = false; - bool Up = false, Down = false, RSHIFT_Down = false; + bool Up = false, Down = false; + bool FastMove = false; // Use n64 controls for use with a controller //! @todo configure this properly @@ -280,6 +276,9 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { if (controller->button & U_CBUTTONS) { Up = true; } + // if (controller->button ??) { + // FastMove = true; + // } // Keyboard and mouse DX } else if (wnd->GetWindowBackend() == Ship::WindowBackend::FAST3D_DXGI_DX11) { if (GetKeyState('N') & 0x8000) { @@ -303,11 +302,12 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { if (GetKeyState(VK_SPACE) & 0x8000) { Up = true; } - if (GetKeyState(VK_LSHIFT) & 0x8000) { + if (GetKeyState(VK_LSHIFT) & 0x8000 || GetKeyState(VK_RSHIFT) & 0x8000) { Down = true; } - if (GetKeyState(VK_RSHIFT) & 0x8000) { - RSHIFT_Down = true; + // Fast movement with Ctrl + if (GetKeyState(VK_LCONTROL) || GetKeyState(VK_RCONTROL)) { + FastMove = true; } // Keyboard/mouse OpenGL/SDL } else if (wnd->GetWindowBackend() == Ship::WindowBackend::FAST3D_SDL_OPENGL) { @@ -333,11 +333,11 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { if (keystate[SDL_SCANCODE_SPACE]) { Up = true; } - if (keystate[SDL_SCANCODE_LSHIFT]) { + if (keystate[SDL_SCANCODE_LSHIFT] || keystate[SDL_SCANCODE_RSHIFT]) { Down = true; } - if (keystate[SDL_SCANCODE_RSHIFT]) { - RSHIFT_Down = true; + if (keystate[SDL_SCANCODE_LCTRL] || keystate[SDL_SCANCODE_RCTRL]) { + FastMove = true; } } @@ -366,6 +366,10 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { return; } + if (FastMove) { + moveSpeed *= gFreecamSpeedMultiplier; + } + if (Forward) { totalMove[0] += forwardVector[0] * moveSpeed; totalMove[2] += forwardVector[2] * moveSpeed; @@ -385,7 +389,7 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { if (Up) { totalMove[1] += moveSpeed; // Move up } - if (Down || RSHIFT_Down) { + if (Down) { totalMove[1] -= moveSpeed; // Move down } freeCam.velocity[0] += totalMove[0]; From 3ab842aa8931127d908b8694411f622a331a3e5f Mon Sep 17 00:00:00 2001 From: MegaMech <7255464+MegaMech@users.noreply.github.com> Date: Mon, 6 Jan 2025 18:44:09 -0700 Subject: [PATCH 06/10] First fix of target mode --- src/enhancements/freecam/freecam.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/enhancements/freecam/freecam.cpp b/src/enhancements/freecam/freecam.cpp index 84d18a2b8..66a5040af 100644 --- a/src/enhancements/freecam/freecam.cpp +++ b/src/enhancements/freecam/freecam.cpp @@ -105,7 +105,7 @@ void freecam(Camera* camera, Player* player, s8 index) { freecam_load_state(camera); } else { // !fMode or fMode not initialized - freecam_target_player(camera, get_player_index_for_player(player)); + //freecam_target_player(camera, get_player_index_for_player(player)); } return; @@ -134,7 +134,9 @@ void freecam(Camera* camera, Player* player, s8 index) { freecam_mouse_manager(camera, freeCam.forwardVector); freecam_keyboard_manager(camera, freeCam.forwardVector); - if (!fTargetPlayer) { + if (fTargetPlayer) { + freecam_target_player(camera, get_player_index_for_player(player)); + } else { freecam_update(camera, freeCam.forwardVector); } } From 54e7b6de331351156d7d70c558273282cc66c433 Mon Sep 17 00:00:00 2001 From: MegaMech <7255464+MegaMech@users.noreply.github.com> Date: Tue, 7 Jan 2025 10:24:26 -0700 Subject: [PATCH 07/10] More freecam fixes --- src/enhancements/freecam/freecam.cpp | 53 +++++++++++++---------- src/enhancements/freecam/freecam_engine.c | 15 +++++-- src/enhancements/freecam/freecam_engine.h | 4 +- 3 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src/enhancements/freecam/freecam.cpp b/src/enhancements/freecam/freecam.cpp index 66a5040af..83c33a666 100644 --- a/src/enhancements/freecam/freecam.cpp +++ b/src/enhancements/freecam/freecam.cpp @@ -35,8 +35,8 @@ typedef struct { freecamSaveState fState; -u32 fRankIndex = -1; -u32 fTargetPlayer = false; +u32 fRankIndex = 0; +u32 fTargetPlayer = true; u32 fMode; // freecam mode should probably be an enum u32 fModeInit = false; @@ -49,7 +49,7 @@ u32 gFreecamControllerType = 0; // void freecam_calculate_forward_vector(Camera* camera, Vec3f forwardVector); // void freecam_move_camera_forward(Camera* camera, f32 distance); -// void freecam_update(Camera* camera, struct Controller *controller); +// void freecam_tick(Camera* camera, struct Controller *controller); // void freecam_n64_controller_manager(Camera *camera, struct Controller *controller, Player *player); // void freecam_target_player(Camera *camera, u32 playerIndex); // void freecam_move_camera_up(Camera* camera, struct Controller *controller, f32 distance); @@ -135,9 +135,9 @@ void freecam(Camera* camera, Player* player, s8 index) { freecam_keyboard_manager(camera, freeCam.forwardVector); if (fTargetPlayer) { - freecam_target_player(camera, get_player_index_for_player(player)); + freecam_target_player(camera, D_800DC5EC->player); } else { - freecam_update(camera, freeCam.forwardVector); + freecam_tick(camera, freeCam.forwardVector); } } @@ -236,8 +236,8 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { // if (keystate[SDL_SCANCODE_G]) { // fTargetPlayer = false; // } - - bool TargetNextPlayer = false, TargetPreviousPlayer = false; + static bool prevPrev; + bool TargetNextPlayer = false, TargetPreviousPlayer = false; bool prevNext; bool Forward = false, PanLeft = false, Backward = false, PanRight = false; bool Up = false, Down = false; bool FastMove = false; @@ -250,15 +250,15 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { // fMode = !fMode; // } // Target a player - // if (controller->buttonPressed & R_TRIG) { - // fTargetPlayer = !fTargetPlayer; - // } + if (controller->buttonPressed & R_TRIG) { + fTargetPlayer = !fTargetPlayer; + } if (controller->buttonPressed & L_CBUTTONS) { - TargetNextPlayer = true; + TargetPreviousPlayer = true; } if (controller->buttonPressed & R_CBUTTONS) { - TargetPreviousPlayer = true; + TargetNextPlayer = true; } if (controller->button & A_BUTTON) { Forward = true; @@ -283,11 +283,17 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { // } // Keyboard and mouse DX } else if (wnd->GetWindowBackend() == Ship::WindowBackend::FAST3D_DXGI_DX11) { + if (GetKeyState('F') & 0x8000) { + fTargetPlayer = !fTargetPlayer; + } if (GetKeyState('N') & 0x8000) { - TargetNextPlayer = true; + if (!prevPrev) { + prevPrev = true; + TargetPreviousPlayer = true; + } } if (GetKeyState('M') & 0x8000) { - TargetPreviousPlayer = true; + TargetNextPlayer = true; } if (GetKeyState('W') & 0x8000) { Forward = true; @@ -314,11 +320,14 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { // Keyboard/mouse OpenGL/SDL } else if (wnd->GetWindowBackend() == Ship::WindowBackend::FAST3D_SDL_OPENGL) { const uint8_t* keystate = SDL_GetKeyboardState(NULL); + if (keystate[SDL_SCANCODE_F]) { + fTargetPlayer != fTargetPlayer; + } if (keystate[SDL_SCANCODE_N]) { - TargetNextPlayer = true; + TargetPreviousPlayer = true; } if (keystate[SDL_SCANCODE_M]) { - TargetPreviousPlayer = true; + TargetNextPlayer = true; } if (keystate[SDL_SCANCODE_W]) { Forward = true; @@ -343,8 +352,8 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { } } - // Target next player - if (TargetNextPlayer) { + // Target previous player + if (TargetPreviousPlayer) { if (fRankIndex > 0) { fRankIndex--; camera->playerId = fRankIndex; @@ -352,8 +361,8 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { } } - // Target previous player - if (TargetPreviousPlayer) { + // Target next player + if (TargetNextPlayer) { if (fRankIndex < 7) { fRankIndex++; camera->playerId = fRankIndex; @@ -363,9 +372,9 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { // Target camera at chosen player if (fRankIndex != -1) { - freecam_target_player(camera, gGPCurrentRacePlayerIdByRank[fRankIndex]); + //freecam_target_player(camera, gGPCurrentRacePlayerIdByRank[fRankIndex]); // Don't run the other camera code. - return; + //return; } if (FastMove) { diff --git a/src/enhancements/freecam/freecam_engine.c b/src/enhancements/freecam/freecam_engine.c index bcef5380b..8a78917fd 100644 --- a/src/enhancements/freecam/freecam_engine.c +++ b/src/enhancements/freecam/freecam_engine.c @@ -17,7 +17,7 @@ FreeCam freeCam; f32 gDampValue = 0.99f; -void freecam_update(Camera* camera, Vec3f forwardVector) { +void freecam_tick(Camera* camera, Vec3f forwardVector) { // Update FreeCam state camera->pos[0] += freeCam.velocity[0] * gDeltaTime; camera->pos[1] += freeCam.velocity[1] * gDeltaTime; @@ -119,9 +119,18 @@ void freecam_move_camera_down(Camera* camera, f32 distance) { camera->lookAt[1] += distance; } -void freecam_target_player(Camera* camera, u32 playerIndex) { +void freecam_target_player(Camera* camera, Player* player) { Vec3f forwardVector; // = 2.0f; - Player* player = &gPlayers[playerIndex]; + + // Update position + camera->pos[0] += freeCam.velocity[0] * gDeltaTime; + camera->pos[1] += freeCam.velocity[1] * gDeltaTime; + camera->pos[2] += freeCam.velocity[2] * gDeltaTime; + + // Apply damping to velocity + freeCam.velocity[0] *= gDampValue; + freeCam.velocity[1] *= gDampValue; + freeCam.velocity[2] *= gDampValue; // Calculate the direction from the player to the camera f32 dirX = player->pos[0] - camera->pos[0]; diff --git a/src/enhancements/freecam/freecam_engine.h b/src/enhancements/freecam/freecam_engine.h index 18e6d258c..49e79d0ea 100644 --- a/src/enhancements/freecam/freecam_engine.h +++ b/src/enhancements/freecam/freecam_engine.h @@ -25,8 +25,8 @@ void freecam_pan_camera(Camera* camera, f32 moveSpeed); void freecam_calculate_forward_vector_allow_rotation(Camera* camera, Vec3f forwardVector); void freecam_calculate_forward_vector(Camera* camera, Vec3f forwardVector); void freecam_move_camera_forward(Camera* camera, f32 distance, Vec3f forwardVector); -void freecam_target_player(Camera* camera, u32 playerIndex); -void freecam_update(Camera* camera, Vec3f forwardVector); +void freecam_target_player(Camera* camera, Player* player); +void freecam_tick(Camera* camera, Vec3f forwardVector); void freecam_move_camera_up(Camera* camera, f32); void freecam_move_camera_down(Camera* camera, f32); From 1b3e0ab2f68122e0123f8de6fbc3b2f2bb1b3bcf Mon Sep 17 00:00:00 2001 From: MegaMech Date: Tue, 7 Jan 2025 13:05:34 -0700 Subject: [PATCH 08/10] Freecam targetting fixed --- src/enhancements/freecam/freecam.cpp | 145 ++++++++-------------- src/enhancements/freecam/freecam.h | 2 - src/enhancements/freecam/freecam_engine.c | 106 ++++------------ src/enhancements/freecam/freecam_engine.h | 10 +- src/port/ui/FreecamWindow.cpp | 3 +- 5 files changed, 78 insertions(+), 188 deletions(-) diff --git a/src/enhancements/freecam/freecam.cpp b/src/enhancements/freecam/freecam.cpp index 83c33a666..56eb813d9 100644 --- a/src/enhancements/freecam/freecam.cpp +++ b/src/enhancements/freecam/freecam.cpp @@ -44,16 +44,6 @@ int rightMouseButtonDown = 0; // Track if right mouse button is held down u32 gFreecamControllerType = 0; -// 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_calculate_forward_vector(Camera* camera, Vec3f forwardVector); -// void freecam_move_camera_forward(Camera* camera, f32 distance); - -// void freecam_tick(Camera* camera, struct Controller *controller); -// void freecam_n64_controller_manager(Camera *camera, struct Controller *controller, Player *player); -// void freecam_target_player(Camera *camera, u32 playerIndex); -// void freecam_move_camera_up(Camera* camera, struct Controller *controller, f32 distance); - /** * Controls * @@ -77,7 +67,6 @@ u32 gFreecamControllerType = 0; * Camera mode 2: Enter freecam at previous freecam spot * */ - void freecam(Camera* camera, Player* player, s8 index) { struct Controller* controller = &gControllers[0]; f32 dirX; @@ -98,22 +87,6 @@ void freecam(Camera* camera, Player* player, s8 index) { } gIsHUDVisible = !CVarGetInteger("gFreecam", 0); - - if (CVarGetInteger("gFreecam", 0) == 1) { - - if (fMode && fModeInit) { - freecam_load_state(camera); - } else { - // !fMode or fMode not initialized - //freecam_target_player(camera, get_player_index_for_player(player)); - } - - return; - } else { - if (fMode) { - freecam_save_state(camera); - } - } } // Driving mode @@ -123,51 +96,22 @@ void freecam(Camera* camera, Player* player, s8 index) { return; } - // if (player == gPlayerOne) { return; } - - // player->type &= ~PLAYER_HUMAN; - // player->type |= PLAYER_HUMAN; - - // if ((player->type & PLAYER_START_SEQUENCE)) { return; } - + // Calculate forward direction freecam_calculate_forward_vector_allow_rotation(camera, freeCam.forwardVector); - freecam_mouse_manager(camera, freeCam.forwardVector); + + // Adjust camera rotation + if (fTargetPlayer) { + freecam_target_player(camera, freeCam.forwardVector); + } else { + freecam_mouse_manager(camera, freeCam.forwardVector); + } + + // Adjust camera position freecam_keyboard_manager(camera, freeCam.forwardVector); - if (fTargetPlayer) { - freecam_target_player(camera, D_800DC5EC->player); - } else { - freecam_tick(camera, freeCam.forwardVector); - } -} + // Apply final position, velocity, and lookAt + freecam_tick(camera, freeCam.forwardVector); -void freecam_save_state(Camera* camera) { - fState.pos[0] = camera->pos[0]; - fState.pos[1] = camera->pos[1]; - fState.pos[2] = camera->pos[2]; - - fState.lookAt[0] = camera->lookAt[0]; - fState.lookAt[1] = camera->lookAt[1]; - fState.lookAt[2] = camera->lookAt[2]; - - fState.rot[0] = camera->rot[0]; - fState.rot[1] = camera->rot[1]; - fState.rot[2] = camera->rot[2]; - fModeInit = true; -} - -void freecam_load_state(Camera* camera) { - camera->pos[0] = fState.pos[0]; - camera->pos[1] = fState.pos[1]; - camera->pos[2] = fState.pos[2]; - - camera->lookAt[0] = fState.lookAt[0]; - camera->lookAt[1] = fState.lookAt[1]; - camera->lookAt[2] = fState.lookAt[2]; - - camera->rot[0] = fState.rot[0]; - camera->rot[1] = fState.rot[1]; - camera->rot[2] = fState.rot[2]; } f32 gFreecamRotateSmoothingFactor = 0.85f; @@ -203,9 +147,6 @@ void freecam_mouse_manager(Camera* camera, Vec3f forwardVector) { camera->rot[2] = -15999; } - // Calculate the forward vector based on the new yaw and pitch - // freecam_calculate_forward_vector_allow_rotation(camera, forwardVector); - // Smoothly interpolate the lookAt position Vec3f targetLookAt = { camera->pos[0] + forwardVector[0], camera->pos[1] + forwardVector[1], camera->pos[2] + forwardVector[2] }; @@ -219,6 +160,36 @@ void freecam_mouse_manager(Camera* camera, Vec3f forwardVector) { f32 gFreecamSpeed = 3.0f; f32 gFreecamSpeedMultiplier = 2.0f; +bool prevPrev = false; + +#define MAX_KEYS 256 +static bool prevKeyState[MAX_KEYS] = { false }; + +// KeyDown function +bool FreecamKeyDown(int virtualKey) { + auto wnd = GameEngine::Instance->context->GetWindow(); + static bool prevKeyState[256] = { false }; // Store previous key states + bool isDownNow = false; + + if (wnd->GetWindowBackend() == Ship::WindowBackend::FAST3D_SDL_OPENGL) { + // Use SDL to check key states + const uint8_t* keystate = SDL_GetKeyboardState(NULL); + isDownNow = keystate[virtualKey] != 0; + } else if (wnd->GetWindowBackend() == Ship::WindowBackend::FAST3D_DXGI_DX11) { + // Use Windows GetKeyState for DirectX + SHORT keyState = GetKeyState(virtualKey); + isDownNow = (keyState & 0x8000) != 0; + } + + // Determine if this is a new key press + bool isKeyDownEvent = isDownNow && !prevKeyState[virtualKey]; + + // Update the previous state for this key + prevKeyState[virtualKey] = isDownNow; + + return isKeyDownEvent; +} + void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { auto wnd = GameEngine::Instance->context->GetWindow(); @@ -236,7 +207,6 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { // if (keystate[SDL_SCANCODE_G]) { // fTargetPlayer = false; // } - static bool prevPrev; bool TargetNextPlayer = false, TargetPreviousPlayer = false; bool prevNext; bool Forward = false, PanLeft = false, Backward = false, PanRight = false; bool Up = false, Down = false; @@ -253,7 +223,6 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { if (controller->buttonPressed & R_TRIG) { fTargetPlayer = !fTargetPlayer; } - if (controller->buttonPressed & L_CBUTTONS) { TargetPreviousPlayer = true; } @@ -283,16 +252,13 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { // } // Keyboard and mouse DX } else if (wnd->GetWindowBackend() == Ship::WindowBackend::FAST3D_DXGI_DX11) { - if (GetKeyState('F') & 0x8000) { + if (FreecamKeyDown('F')) { fTargetPlayer = !fTargetPlayer; } - if (GetKeyState('N') & 0x8000) { - if (!prevPrev) { - prevPrev = true; - TargetPreviousPlayer = true; - } + if (FreecamKeyDown('N')) { + TargetPreviousPlayer = true; } - if (GetKeyState('M') & 0x8000) { + if (FreecamKeyDown('M')) { TargetNextPlayer = true; } if (GetKeyState('W') & 0x8000) { @@ -320,13 +286,13 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { // Keyboard/mouse OpenGL/SDL } else if (wnd->GetWindowBackend() == Ship::WindowBackend::FAST3D_SDL_OPENGL) { const uint8_t* keystate = SDL_GetKeyboardState(NULL); - if (keystate[SDL_SCANCODE_F]) { - fTargetPlayer != fTargetPlayer; + if (FreecamKeyDown(SDL_SCANCODE_F)) { + fTargetPlayer = !fTargetPlayer; } - if (keystate[SDL_SCANCODE_N]) { + if (FreecamKeyDown(SDL_SCANCODE_N)) { TargetPreviousPlayer = true; } - if (keystate[SDL_SCANCODE_M]) { + if (FreecamKeyDown(SDL_SCANCODE_M)) { TargetNextPlayer = true; } if (keystate[SDL_SCANCODE_W]) { @@ -370,13 +336,6 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { } } - // Target camera at chosen player - if (fRankIndex != -1) { - //freecam_target_player(camera, gGPCurrentRacePlayerIdByRank[fRankIndex]); - // Don't run the other camera code. - //return; - } - if (FastMove) { moveSpeed *= gFreecamSpeedMultiplier; } @@ -406,10 +365,6 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { freeCam.velocity[0] += totalMove[0]; freeCam.velocity[1] += totalMove[1]; freeCam.velocity[2] += totalMove[2]; - - // Update camera's lookAt position - camera->lookAt[0] = camera->pos[0] + forwardVector[0]; - camera->lookAt[2] = camera->pos[2] + forwardVector[2]; } void freecam_render_setup(void) { diff --git a/src/enhancements/freecam/freecam.h b/src/enhancements/freecam/freecam.h index b07edaa06..4eaa45a89 100644 --- a/src/enhancements/freecam/freecam.h +++ b/src/enhancements/freecam/freecam.h @@ -10,8 +10,6 @@ extern "C" { void freecam(Camera*, Player*, s8); void freecam_render_setup(void); -void freecam_save_state(Camera*); -void freecam_load_state(Camera*); void freecam_mouse_manager(Camera*, Vec3f); void freecam_keyboard_manager(Camera*, Vec3f); diff --git a/src/enhancements/freecam/freecam_engine.c b/src/enhancements/freecam/freecam_engine.c index 8a78917fd..1116de60f 100644 --- a/src/enhancements/freecam/freecam_engine.c +++ b/src/enhancements/freecam/freecam_engine.c @@ -33,49 +33,6 @@ void freecam_tick(Camera* camera, Vec3f forwardVector) { camera->lookAt[2] = camera->pos[2] + forwardVector[2]; } -// Function to move the camera forward or backward without changing its height -void freecam_move_camera_forward(Camera* camera, f32 moveSpeed, Vec3f forwardVector) { - // Calculate the forward vector - forwardVector[0] = camera->lookAt[0] - camera->pos[0]; - // forwardVector[1] = 0; // Don't change the height - forwardVector[2] = camera->lookAt[2] - camera->pos[2]; - - // Normalize the forward vector - f32 length = sqrtf(forwardVector[0] * forwardVector[0] + forwardVector[2] * forwardVector[2]); - if (length != 0) { - forwardVector[0] /= length; - forwardVector[2] /= length; - } - - // Update FreeCam velocity - freeCam.velocity[0] = forwardVector[0] * moveSpeed; - freeCam.velocity[2] = forwardVector[2] * moveSpeed; - - camera->lookAt[0] = camera->pos[0] + forwardVector[0]; - camera->lookAt[2] = camera->pos[0] + forwardVector[2]; -} - -void freecam_pan_camera(Camera* camera, f32 moveSpeed) { - Vec3f rightVector; - f32 length; - - // Calculate the right vector for pan movement - rightVector[0] = camera->lookAt[2] - camera->pos[2]; - // rightVector[1] = 0; // Maintain the same height - rightVector[2] = -(camera->lookAt[0] - camera->pos[0]); - - // Normalize the right vector - length = sqrtf(rightVector[0] * rightVector[0] + rightVector[2] * rightVector[2]); - if (length != 0) { - rightVector[0] /= length; - rightVector[2] /= length; - } - - // Update camera's position - freeCam.velocity[0] = rightVector[0] * moveSpeed; - freeCam.velocity[2] = rightVector[2] * moveSpeed; -} - void freecam_calculate_forward_vector_allow_rotation(Camera* camera, Vec3f forwardVector) { // Convert yaw from 0-65535 to degrees f32 pitch = (camera->rot[2] / 65535.0f) * 360.0f; @@ -91,51 +48,16 @@ void freecam_calculate_forward_vector_allow_rotation(Camera* camera, Vec3f forwa forwardVector[2] = cosf(yaw); } -// Calculates the forward direction vector based on camera orientation -void freecam_calculate_forward_vector(Camera* camera, Vec3f forwardVector) { - // Convert yaw from 0-65535 to degrees - f32 yaw = (camera->rot[0] / 65535.0f) * 360.0f; - f32 pitch = (camera->rot[2] / 65535.0f) * 360.0f; - - // Convert degrees to radians - yaw = yaw * M_PI / 180.0f; - pitch = pitch * M_PI / 180.0f; - - // Calculate the forward vector based on yaw and pitch - forwardVector[0] = -sinf(yaw) * cosf(pitch); // x-component - forwardVector[1] = sinf(pitch); // y-component (vertical) - forwardVector[2] = cosf(yaw) * cosf(pitch); // z-component -} - -// Function to move the camera forward -void freecam_move_camera_up(Camera* camera, f32 distance) { - // Update the velocity of the camera in the Y direction - freeCam.velocity[1] += distance; - camera->lookAt[1] += distance; -} -void freecam_move_camera_down(Camera* camera, f32 distance) { - // Update the velocity of the camera in the Y direction - freeCam.velocity[1] += distance; - camera->lookAt[1] += distance; -} - -void freecam_target_player(Camera* camera, Player* player) { - Vec3f forwardVector; // = 2.0f; - - // Update position - camera->pos[0] += freeCam.velocity[0] * gDeltaTime; - camera->pos[1] += freeCam.velocity[1] * gDeltaTime; - camera->pos[2] += freeCam.velocity[2] * gDeltaTime; - +void freecam_target_player(Camera* camera, Vec3f forwardVector) { // Apply damping to velocity freeCam.velocity[0] *= gDampValue; freeCam.velocity[1] *= gDampValue; freeCam.velocity[2] *= gDampValue; // Calculate the direction from the player to the camera - f32 dirX = player->pos[0] - camera->pos[0]; - f32 dirY = player->pos[1] - camera->pos[1]; - f32 dirZ = player->pos[2] - camera->pos[2]; + f32 dirX = gPlayers[fRankIndex].pos[0] - camera->pos[0]; + f32 dirY = gPlayers[fRankIndex].pos[1] - camera->pos[1]; + f32 dirZ = gPlayers[fRankIndex].pos[2] - camera->pos[2]; // Normalize the direction vector (if needed) f32 length = sqrtf(dirX * dirX + dirY * dirY + dirZ * dirZ); @@ -149,4 +71,24 @@ void freecam_target_player(Camera* camera, Player* player) { camera->lookAt[0] = camera->pos[0] + dirX; camera->lookAt[1] = camera->pos[1] + dirY; camera->lookAt[2] = camera->pos[2] + dirZ; + + // Calculate the forward vector based on the updated look-at direction + forwardVector[0] = camera->lookAt[0] - camera->pos[0]; + forwardVector[1] = camera->lookAt[1] - camera->pos[1]; + forwardVector[2] = camera->lookAt[2] - camera->pos[2]; + + // Normalize the forward vector + f32 forwardLength = sqrtf(forwardVector[0] * forwardVector[0] + + forwardVector[1] * forwardVector[1] + + forwardVector[2] * forwardVector[2]); + if (forwardLength > 0.0f) { + forwardVector[0] /= forwardLength; + forwardVector[1] /= forwardLength; + forwardVector[2] /= forwardLength; + } + + // Store or return the forward vector as needed for subsequent movement calculations + freeCam.forwardVector[0] = forwardVector[0]; + freeCam.forwardVector[1] = forwardVector[1]; + freeCam.forwardVector[2] = forwardVector[2]; } diff --git a/src/enhancements/freecam/freecam_engine.h b/src/enhancements/freecam/freecam_engine.h index 49e79d0ea..7c7ecc754 100644 --- a/src/enhancements/freecam/freecam_engine.h +++ b/src/enhancements/freecam/freecam_engine.h @@ -19,16 +19,12 @@ typedef struct { extern FreeCam freeCam; extern f32 gDampValue; +extern u32 fTargetPlayer; +extern u32 fRankIndex; -// void update_camera(Camera *camera, f32 deltaTime); -void freecam_pan_camera(Camera* camera, f32 moveSpeed); void freecam_calculate_forward_vector_allow_rotation(Camera* camera, Vec3f forwardVector); -void freecam_calculate_forward_vector(Camera* camera, Vec3f forwardVector); -void freecam_move_camera_forward(Camera* camera, f32 distance, Vec3f forwardVector); -void freecam_target_player(Camera* camera, Player* player); +void freecam_target_player(Camera* camera, Vec3f forwardVector); void freecam_tick(Camera* camera, Vec3f forwardVector); -void freecam_move_camera_up(Camera* camera, f32); -void freecam_move_camera_down(Camera* camera, f32); extern f32 gDampValue; diff --git a/src/port/ui/FreecamWindow.cpp b/src/port/ui/FreecamWindow.cpp index de9706c2f..fcf532747 100644 --- a/src/port/ui/FreecamWindow.cpp +++ b/src/port/ui/FreecamWindow.cpp @@ -61,8 +61,7 @@ void FreecamWindow::DrawElement() { gFreecamControllerType = current_item; } - ImGui::Text("Move: W,A,S,D\nUp: Space, Down: Shift\nFaster: Ctrl\nLook: Right-mouse button\nTarget previous " - "player: N, Target next player: M"); + ImGui::Text("Move: W,A,S,D\nUp: Space, Down: Shift\nFaster: Ctrl\nLook: Right-mouse button\nTarget Player Mode: F, Next: M, Previous: N"); ImGui::Spacing(); UIWidgets::CVarCheckbox("Enable Flycam", "gFreecam", { .tooltip = "Allows you to fly around the course" }); From 52e21e3750610c1fb5d63b12e789ce2ef9fdf2ec Mon Sep 17 00:00:00 2001 From: MegaMech Date: Tue, 7 Jan 2025 13:18:30 -0700 Subject: [PATCH 09/10] cleanup --- src/camera.c | 2 +- src/enhancements/freecam/freecam.cpp | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/camera.c b/src/camera.c index 8992371d6..ef298f55b 100644 --- a/src/camera.c +++ b/src/camera.c @@ -17,7 +17,7 @@ #include "main.h" #include "spawn_players.h" #include "enhancements/freecam/freecam_engine.h" -#include "freecam.h" +#include "enhancements/freecam/freecam.h" #include "engine/GameAPI.h" #include "port/Game.h" diff --git a/src/enhancements/freecam/freecam.cpp b/src/enhancements/freecam/freecam.cpp index 56eb813d9..0602f9d27 100644 --- a/src/enhancements/freecam/freecam.cpp +++ b/src/enhancements/freecam/freecam.cpp @@ -8,7 +8,6 @@ extern "C" { #include #include -#include #include "main.h" #include #include @@ -89,13 +88,6 @@ void freecam(Camera* camera, Player* player, s8 index) { gIsHUDVisible = !CVarGetInteger("gFreecam", 0); } - // Driving mode - if (CVarGetInteger("gFreecam", 0) == 0) { - // Use normal camera code - func_8001E45C(camera, &gPlayers[fRankIndex], index); - return; - } - // Calculate forward direction freecam_calculate_forward_vector_allow_rotation(camera, freeCam.forwardVector); From 8c79f6c406c08d5dd40284d179b8471a3f2353e2 Mon Sep 17 00:00:00 2001 From: MegaMech Date: Tue, 7 Jan 2025 13:23:46 -0700 Subject: [PATCH 10/10] Fix mistake --- src/port/Engine.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/port/Engine.h b/src/port/Engine.h index 25e61d5c4..4840a437f 100644 --- a/src/port/Engine.h +++ b/src/port/Engine.h @@ -55,7 +55,11 @@ class GameEngine { uint32_t OTRCalculateCenterOfAreaFromRightEdge(int32_t center); uint32_t OTRCalculateCenterOfAreaFromLeftEdge(int32_t center); }; -#else +#endif + +#ifdef __cplusplus +extern "C" { +#endif void GameEngine_ProcessGfxCommands(Gfx* commands); uint32_t GameEngine_GetSampleRate(); uint32_t GameEngine_GetSamplesPerFrame(); @@ -77,4 +81,6 @@ uint32_t OTRGetGameRenderWidth(void); uint32_t OTRGetGameRenderHeight(void); uint32_t OTRCalculateCenterOfAreaFromRightEdge(int32_t center); uint32_t OTRCalculateCenterOfAreaFromLeftEdge(int32_t center); -#endif // __cplusplus +#ifdef __cplusplus +} +#endif \ No newline at end of file