mirror of
https://github.com/HarbourMasters/SpaghettiKart
synced 2026-09-03 02:33:55 -04:00
@@ -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
-1
Submodule libultraship updated: 80c2c5e9c6...3e46fe77a4
+1
-1
@@ -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"
|
||||
|
||||
@@ -1,374 +0,0 @@
|
||||
#include <libultraship.h>
|
||||
#include <macros.h>
|
||||
#include <defines.h>
|
||||
#include <camera.h>
|
||||
#include "main.h"
|
||||
#include <libc/math.h>
|
||||
#include <common_structs.h>
|
||||
#include "racing/collision.h"
|
||||
#include "player_controller.h"
|
||||
#include "code_80057C60.h"
|
||||
#include "code_800029B0.h"
|
||||
#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"
|
||||
|
||||
typedef struct {
|
||||
Vec3f pos;
|
||||
Vec3f lookAt;
|
||||
Vec3s rot;
|
||||
} freecamSaveState;
|
||||
|
||||
freecamSaveState fState;
|
||||
|
||||
u32 fRankIndex = -1;
|
||||
u32 fTargetPlayer = false;
|
||||
u32 fMode; // freecam mode should probably be an enum
|
||||
u32 fModeInit = false;
|
||||
|
||||
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_update(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
|
||||
*
|
||||
* Forward: A
|
||||
* Backward: B
|
||||
*
|
||||
* Go faster: Z
|
||||
*
|
||||
* Up: C-up
|
||||
* Down: C-down
|
||||
*
|
||||
* Targets players based on rank position
|
||||
*
|
||||
* Target player: R-trig
|
||||
* Target next player: C-right
|
||||
* Target previous player: C-left
|
||||
*
|
||||
* Switch camera modes: D-pad left
|
||||
*
|
||||
* Camera mode 1: Enter freecam at the player's position
|
||||
* Camera mode 2: Enter freecam at previous freecam spot
|
||||
*
|
||||
*/
|
||||
|
||||
void freecam(Camera* camera, Player* player, s8 index) {
|
||||
struct Controller* controller = &gControllers[0];
|
||||
f32 dirX;
|
||||
f32 dirY;
|
||||
f32 dirZ;
|
||||
f32 length;
|
||||
|
||||
if (controller->buttonPressed & L_TRIG) {
|
||||
// Toggle freecam
|
||||
CVarSetInteger("gFreecam", !CVarGetInteger("gFreecam", 0));
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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
|
||||
if (CVarGetInteger("gFreecam", 0) == 0) {
|
||||
// Use normal camera code
|
||||
func_8001E45C(camera, &gPlayers[fRankIndex], index);
|
||||
return;
|
||||
}
|
||||
|
||||
// if (player == gPlayerOne) { return; }
|
||||
|
||||
// player->type &= ~PLAYER_HUMAN;
|
||||
// player->type |= PLAYER_HUMAN;
|
||||
|
||||
// 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);
|
||||
}
|
||||
if (!fTargetPlayer) {
|
||||
freecam_update(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;
|
||||
|
||||
void freecam_mouse_manager(Camera* camera, Vec3f forwardVector) {
|
||||
int mouseX, mouseY;
|
||||
static int prevMouseX = 0, prevMouseY = 0;
|
||||
Uint32 mouseState = SDL_GetRelativeMouseState(&mouseX, &mouseY);
|
||||
|
||||
mouseX = (mouseX + prevMouseX) / 2;
|
||||
mouseY = (mouseY + prevMouseY) / 2;
|
||||
prevMouseX = mouseX;
|
||||
prevMouseY = mouseY;
|
||||
|
||||
if (mouseState & SDL_BUTTON(SDL_BUTTON_RIGHT)) {
|
||||
// Calculate yaw (left/right) and pitch (up/down) changes
|
||||
f32 yawChange = mouseX * MOUSE_SENSITIVITY_X;
|
||||
f32 pitchChange = mouseY * MOUSE_SENSITIVITY_Y;
|
||||
|
||||
// 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)
|
||||
|
||||
// Clamp pitch to avoid extreme values
|
||||
if (camera->rot[2] > 15999) {
|
||||
camera->rot[2] = 15999;
|
||||
}
|
||||
if (camera->rot[2] < -15999) {
|
||||
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] };
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
f32 gFreecamSpeed = 3.0f;
|
||||
f32 gFreecamSpeedMultiplier = 2.0f;
|
||||
|
||||
void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) {
|
||||
const uint8_t* keystate = SDL_GetKeyboardState(NULL);
|
||||
float moveSpeed = gFreecamSpeed;
|
||||
|
||||
// Fast movement with Ctrl
|
||||
if (keystate[SDL_SCANCODE_LCTRL] || keystate[SDL_SCANCODE_RCTRL]) {
|
||||
moveSpeed *= gFreecamSpeedMultiplier;
|
||||
}
|
||||
|
||||
// Determine movement direction based on keys pressed
|
||||
Vec3f totalMove = { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
// if (keystate[SDL_SCANCODE_F]) {
|
||||
// fMode = true;
|
||||
// }
|
||||
|
||||
// // Target a player
|
||||
// if (keystate[SDL_SCANCODE_G]) {
|
||||
// fTargetPlayer = false;
|
||||
// }
|
||||
|
||||
// Target next player
|
||||
if (keystate[SDL_SCANCODE_N]) {
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
// Target camera at chosen player
|
||||
if (fRankIndex != -1) {
|
||||
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 (keystate[SDL_SCANCODE_S]) {
|
||||
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 (keystate[SDL_SCANCODE_A]) {
|
||||
totalMove[0] += forwardVector[2] * moveSpeed; // Pan left
|
||||
totalMove[2] -= forwardVector[0] * moveSpeed;
|
||||
}
|
||||
if (keystate[SDL_SCANCODE_SPACE]) {
|
||||
totalMove[1] += moveSpeed; // Move up
|
||||
}
|
||||
if (keystate[SDL_SCANCODE_LSHIFT] || keystate[SDL_SCANCODE_RSHIFT]) {
|
||||
totalMove[1] -= moveSpeed; // Move down
|
||||
}
|
||||
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];
|
||||
}
|
||||
|
||||
// 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;
|
||||
init_rdp();
|
||||
func_802A53A4();
|
||||
init_rdp();
|
||||
func_80057FC4(0);
|
||||
gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_SHADING_SMOOTH);
|
||||
gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK | G_CULL_BOTH | G_CULL_FRONT);
|
||||
guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], gScreenAspect, CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f);
|
||||
gSPPerspNormalize(gDisplayListHead++, perspNorm);
|
||||
gSPMatrix(gDisplayListHead++, (&gGfxPool->mtxPersp[0]), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);
|
||||
guLookAt(&gGfxPool->mtxLookAt[0], camera1->pos[0], camera1->pos[1], camera1->pos[2], camera1->lookAt[0],
|
||||
camera1->lookAt[1], camera1->lookAt[2], camera1->up[0], camera1->up[1], camera1->up[2]);
|
||||
gSPMatrix(gDisplayListHead++, (&gGfxPool->mtxLookAt[0]), G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
|
||||
mtxf_identity(matrix);
|
||||
gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK);
|
||||
render_set_position(matrix, 0);
|
||||
init_rdp();
|
||||
}
|
||||
@@ -0,0 +1,381 @@
|
||||
#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 "main.h"
|
||||
#include <libc/math.h>
|
||||
#include <common_structs.h>
|
||||
#include "racing/collision.h"
|
||||
#include "player_controller.h"
|
||||
#include "code_80057C60.h"
|
||||
#include "code_800029B0.h"
|
||||
#include "code_80005FD0.h"
|
||||
#include <SDL2/SDL.h>
|
||||
#include "freecam_engine.h"
|
||||
#include "math_util.h"
|
||||
#include "skybox_and_splitscreen.h"
|
||||
#include "freecam.h"
|
||||
}
|
||||
|
||||
#include "engine/Engine.h"
|
||||
#include "engine/courses/Course.h"
|
||||
|
||||
typedef struct {
|
||||
Vec3f pos;
|
||||
Vec3f lookAt;
|
||||
Vec3s rot;
|
||||
} freecamSaveState;
|
||||
|
||||
freecamSaveState fState;
|
||||
|
||||
u32 fRankIndex = 0;
|
||||
u32 fTargetPlayer = true;
|
||||
u32 fMode; // freecam mode should probably be an enum
|
||||
u32 fModeInit = false;
|
||||
|
||||
int rightMouseButtonDown = 0; // Track if right mouse button is held down
|
||||
|
||||
u32 gFreecamControllerType = 0;
|
||||
|
||||
/**
|
||||
* Controls
|
||||
*
|
||||
* Forward: A
|
||||
* Backward: B
|
||||
*
|
||||
* Go faster: Z
|
||||
*
|
||||
* Up: C-up
|
||||
* Down: C-down
|
||||
*
|
||||
* Targets players based on rank position
|
||||
*
|
||||
* Target player: R-trig
|
||||
* Target next player: C-right
|
||||
* Target previous player: C-left
|
||||
*
|
||||
* Switch camera modes: D-pad left
|
||||
*
|
||||
* Camera mode 1: Enter freecam at the player's position
|
||||
* Camera mode 2: Enter freecam at previous freecam spot
|
||||
*
|
||||
*/
|
||||
void freecam(Camera* camera, Player* player, s8 index) {
|
||||
struct Controller* controller = &gControllers[0];
|
||||
f32 dirX;
|
||||
f32 dirY;
|
||||
f32 dirZ;
|
||||
f32 length;
|
||||
|
||||
if (controller->buttonPressed & L_TRIG) {
|
||||
// Toggle freecam
|
||||
CVarSetInteger("gFreecam", !CVarGetInteger("gFreecam", 0));
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
gIsHUDVisible = !CVarGetInteger("gFreecam", 0);
|
||||
}
|
||||
|
||||
// Calculate forward direction
|
||||
freecam_calculate_forward_vector_allow_rotation(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);
|
||||
|
||||
// Apply final position, velocity, and lookAt
|
||||
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);
|
||||
|
||||
//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 = 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)
|
||||
camera->rot[2] += (short) (pitchChange * 65535.0f / (2 * M_PI)); // Pitch (up/down)
|
||||
|
||||
// Clamp pitch to avoid extreme values
|
||||
if (camera->rot[2] > 15999) {
|
||||
camera->rot[2] = 15999;
|
||||
}
|
||||
if (camera->rot[2] < -15999) {
|
||||
camera->rot[2] = -15999;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
float moveSpeed = gFreecamSpeed;
|
||||
Controller* controller = &gControllers[0];
|
||||
|
||||
// Determine movement direction based on keys pressed
|
||||
Vec3f totalMove = { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
// if (keystate[SDL_SCANCODE_F]) {
|
||||
// fMode = true;
|
||||
// }
|
||||
|
||||
// // Target a player
|
||||
// if (keystate[SDL_SCANCODE_G]) {
|
||||
// fTargetPlayer = false;
|
||||
// }
|
||||
bool TargetNextPlayer = false, TargetPreviousPlayer = false; bool prevNext;
|
||||
bool Forward = false, PanLeft = false, Backward = false, PanRight = false;
|
||||
bool Up = false, Down = false;
|
||||
bool FastMove = 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) {
|
||||
TargetPreviousPlayer = true;
|
||||
}
|
||||
if (controller->buttonPressed & R_CBUTTONS) {
|
||||
TargetNextPlayer = 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;
|
||||
}
|
||||
// if (controller->button ??) {
|
||||
// FastMove = true;
|
||||
// }
|
||||
// Keyboard and mouse DX
|
||||
} else if (wnd->GetWindowBackend() == Ship::WindowBackend::FAST3D_DXGI_DX11) {
|
||||
if (FreecamKeyDown('F')) {
|
||||
fTargetPlayer = !fTargetPlayer;
|
||||
}
|
||||
if (FreecamKeyDown('N')) {
|
||||
TargetPreviousPlayer = true;
|
||||
}
|
||||
if (FreecamKeyDown('M')) {
|
||||
TargetNextPlayer = 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 || GetKeyState(VK_RSHIFT) & 0x8000) {
|
||||
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) {
|
||||
const uint8_t* keystate = SDL_GetKeyboardState(NULL);
|
||||
if (FreecamKeyDown(SDL_SCANCODE_F)) {
|
||||
fTargetPlayer = !fTargetPlayer;
|
||||
}
|
||||
if (FreecamKeyDown(SDL_SCANCODE_N)) {
|
||||
TargetPreviousPlayer = true;
|
||||
}
|
||||
if (FreecamKeyDown(SDL_SCANCODE_M)) {
|
||||
TargetNextPlayer = 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] || keystate[SDL_SCANCODE_RSHIFT]) {
|
||||
Down = true;
|
||||
}
|
||||
if (keystate[SDL_SCANCODE_LCTRL] || keystate[SDL_SCANCODE_RCTRL]) {
|
||||
FastMove = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Target previous player
|
||||
if (TargetPreviousPlayer) {
|
||||
if (fRankIndex > 0) {
|
||||
fRankIndex--;
|
||||
camera->playerId = fRankIndex;
|
||||
D_800DC5EC->player = &gPlayers[fRankIndex];
|
||||
}
|
||||
}
|
||||
|
||||
// Target next player
|
||||
if (TargetNextPlayer) {
|
||||
if (fRankIndex < 7) {
|
||||
fRankIndex++;
|
||||
camera->playerId = fRankIndex;
|
||||
D_800DC5EC->player = &gPlayers[fRankIndex];
|
||||
}
|
||||
}
|
||||
|
||||
if (FastMove) {
|
||||
moveSpeed *= gFreecamSpeedMultiplier;
|
||||
}
|
||||
|
||||
if (Forward) {
|
||||
totalMove[0] += forwardVector[0] * moveSpeed;
|
||||
totalMove[2] += forwardVector[2] * moveSpeed;
|
||||
}
|
||||
if (Backward) {
|
||||
totalMove[0] -= forwardVector[0] * moveSpeed;
|
||||
totalMove[2] -= forwardVector[2] * moveSpeed;
|
||||
}
|
||||
if (PanRight) {
|
||||
totalMove[0] -= forwardVector[2] * moveSpeed; // Pan right
|
||||
totalMove[2] += forwardVector[0] * moveSpeed;
|
||||
}
|
||||
if (PanLeft) {
|
||||
totalMove[0] += forwardVector[2] * moveSpeed; // Pan left
|
||||
totalMove[2] -= forwardVector[0] * moveSpeed;
|
||||
}
|
||||
if (Up) {
|
||||
totalMove[1] += moveSpeed; // Move up
|
||||
}
|
||||
if (Down) {
|
||||
totalMove[1] -= moveSpeed; // Move down
|
||||
}
|
||||
freeCam.velocity[0] += totalMove[0];
|
||||
freeCam.velocity[1] += totalMove[1];
|
||||
freeCam.velocity[2] += totalMove[2];
|
||||
}
|
||||
|
||||
void freecam_render_setup(void) {
|
||||
u16 perspNorm;
|
||||
Mat4 matrix;
|
||||
init_rdp();
|
||||
func_802A53A4();
|
||||
init_rdp();
|
||||
func_80057FC4(0);
|
||||
gSPSetGeometryMode(gDisplayListHead++, G_ZBUFFER | G_SHADE | G_SHADING_SMOOTH);
|
||||
gSPClearGeometryMode(gDisplayListHead++, G_CULL_BACK | G_CULL_BOTH | G_CULL_FRONT);
|
||||
guPerspective(&gGfxPool->mtxPersp[0], &perspNorm, gCameraZoom[0], gScreenAspect, CourseManager_GetProps()->NearPersp, CourseManager_GetProps()->FarPersp, 1.0f);
|
||||
gSPPerspNormalize(gDisplayListHead++, perspNorm);
|
||||
gSPMatrix(gDisplayListHead++, (&gGfxPool->mtxPersp[0]), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);
|
||||
guLookAt(&gGfxPool->mtxLookAt[0], camera1->pos[0], camera1->pos[1], camera1->pos[2], camera1->lookAt[0],
|
||||
camera1->lookAt[1], camera1->lookAt[2], camera1->up[0], camera1->up[1], camera1->up[2]);
|
||||
gSPMatrix(gDisplayListHead++, (&gGfxPool->mtxLookAt[0]), G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
|
||||
mtxf_identity(matrix);
|
||||
gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK);
|
||||
render_set_position(matrix, 0);
|
||||
init_rdp();
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -33,49 +33,6 @@ void freecam_update(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,42 +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, u32 playerIndex) {
|
||||
Vec3f forwardVector; // = 2.0f;
|
||||
Player* player = &gPlayers[playerIndex];
|
||||
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);
|
||||
@@ -140,4 +71,24 @@ void freecam_target_player(Camera* camera, u32 playerIndex) {
|
||||
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];
|
||||
}
|
||||
|
||||
@@ -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, u32 playerIndex);
|
||||
void freecam_update(Camera* camera, Vec3f forwardVector);
|
||||
void freecam_move_camera_up(Camera* camera, f32);
|
||||
void freecam_move_camera_down(Camera* camera, f32);
|
||||
void freecam_target_player(Camera* camera, Vec3f forwardVector);
|
||||
void freecam_tick(Camera* camera, Vec3f forwardVector);
|
||||
|
||||
extern f32 gDampValue;
|
||||
|
||||
|
||||
@@ -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
|
||||
+41
-22
@@ -62,10 +62,29 @@ 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<LUS::ControlDeck>();
|
||||
|
||||
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<Fast::Fast3dWindow>(std::vector<std::shared_ptr<Ship::GuiWindow>>({}));
|
||||
//auto wnd = std::dynamic_pointer_cast<Fast::Fast3dWindow>(Ship::Context::GetInstance()->GetWindow());
|
||||
|
||||
// Turn off texture filtering because menus are borked with it on
|
||||
CVarRegisterInteger("gTextureFilter", 2);
|
||||
|
||||
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<Fast::Fast3dWindow>(Ship::Context::GetInstance()->GetWindow());
|
||||
|
||||
wnd->SetRendererUCode(ucode_f3dex);
|
||||
this->context->InitGfxDebugger();
|
||||
@@ -84,27 +103,27 @@ GameEngine::GameEngine() {
|
||||
loader->RegisterResourceFactory(std::make_shared<SF64::ResourceFactoryBinaryGenericArrayV0>(),
|
||||
RESOURCE_FORMAT_BINARY, "GenericArray",
|
||||
static_cast<uint32_t>(SF64::ResourceType::GenericArray), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryTextureV0>(), RESOURCE_FORMAT_BINARY,
|
||||
"Texture", static_cast<uint32_t>(LUS::ResourceType::Texture), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryTextureV1>(), RESOURCE_FORMAT_BINARY,
|
||||
"Texture", static_cast<uint32_t>(LUS::ResourceType::Texture), 1);
|
||||
loader->RegisterResourceFactory(std::make_shared<Fast::ResourceFactoryBinaryTextureV0>(), RESOURCE_FORMAT_BINARY,
|
||||
"Texture", static_cast<uint32_t>(Fast::ResourceType::Texture), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<Fast::ResourceFactoryBinaryTextureV1>(), RESOURCE_FORMAT_BINARY,
|
||||
"Texture", static_cast<uint32_t>(Fast::ResourceType::Texture), 1);
|
||||
|
||||
loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryVertexV0>(), RESOURCE_FORMAT_BINARY,
|
||||
"Vertex", static_cast<uint32_t>(LUS::ResourceType::Vertex), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryXMLVertexV0>(), RESOURCE_FORMAT_XML, "Vertex",
|
||||
static_cast<uint32_t>(LUS::ResourceType::Vertex), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<Fast::ResourceFactoryBinaryVertexV0>(), RESOURCE_FORMAT_BINARY,
|
||||
"Vertex", static_cast<uint32_t>(Fast::ResourceType::Vertex), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<Fast::ResourceFactoryXMLVertexV0>(), RESOURCE_FORMAT_XML, "Vertex",
|
||||
static_cast<uint32_t>(Fast::ResourceType::Vertex), 0);
|
||||
|
||||
loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryDisplayListV0>(), RESOURCE_FORMAT_BINARY,
|
||||
"DisplayList", static_cast<uint32_t>(LUS::ResourceType::DisplayList), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryXMLDisplayListV0>(), RESOURCE_FORMAT_XML,
|
||||
"DisplayList", static_cast<uint32_t>(LUS::ResourceType::DisplayList), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<Fast::ResourceFactoryBinaryDisplayListV0>(), RESOURCE_FORMAT_BINARY,
|
||||
"DisplayList", static_cast<uint32_t>(Fast::ResourceType::DisplayList), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<Fast::ResourceFactoryXMLDisplayListV0>(), RESOURCE_FORMAT_XML,
|
||||
"DisplayList", static_cast<uint32_t>(Fast::ResourceType::DisplayList), 0);
|
||||
|
||||
loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryMatrixV0>(), RESOURCE_FORMAT_BINARY,
|
||||
"Matrix", static_cast<uint32_t>(LUS::ResourceType::Matrix), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryBlobV0>(), RESOURCE_FORMAT_BINARY,
|
||||
"Blob", static_cast<uint32_t>(LUS::ResourceType::Blob), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryLightV0>(), RESOURCE_FORMAT_BINARY,
|
||||
"Lights1", static_cast<uint32_t>(LUS::ResourceType::Light), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<Fast::ResourceFactoryBinaryMatrixV0>(), RESOURCE_FORMAT_BINARY,
|
||||
"Matrix", static_cast<uint32_t>(Fast::ResourceType::Matrix), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<Ship::ResourceFactoryBinaryBlobV0>(), RESOURCE_FORMAT_BINARY,
|
||||
"Blob", static_cast<uint32_t>(Ship::ResourceType::Blob), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<Fast::ResourceFactoryBinaryLightV0>(), RESOURCE_FORMAT_BINARY,
|
||||
"Lights1", static_cast<uint32_t>(Fast::ResourceType::Light), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryArrayV0>(), RESOURCE_FORMAT_BINARY,
|
||||
"Array", static_cast<uint32_t>(MK64::ResourceType::MK_Array), 0);
|
||||
loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryKartAIV0>(), RESOURCE_FORMAT_BINARY,
|
||||
@@ -233,7 +252,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/*");
|
||||
|
||||
|
||||
@@ -84,3 +84,4 @@ uint32_t OTRCalculateCenterOfAreaFromLeftEdge(int32_t center);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -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<LUS::DisplayList>(resource);
|
||||
auto res = std::static_pointer_cast<Fast::DisplayList>(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<LUS::ResourceType>(res->GetInitData()->Type);
|
||||
const auto type = static_cast<Fast::ResourceType>(res->GetInitData()->Type);
|
||||
|
||||
if (res->GetInitData()->Type == static_cast<uint32_t>(LUS::ResourceType::DisplayList)) {
|
||||
texAddr = reinterpret_cast<uintptr_t>(&std::static_pointer_cast<LUS::DisplayList>(res)->Instructions[0]);
|
||||
if (res->GetInitData()->Type == static_cast<uint32_t>(Fast::ResourceType::DisplayList)) {
|
||||
texAddr = reinterpret_cast<uintptr_t>(&std::static_pointer_cast<Fast::DisplayList>(res)->Instructions[0]);
|
||||
} else if (res->GetInitData()->Type == static_cast<uint32_t>(MK64::ResourceType::MK_Array)) {
|
||||
texAddr = reinterpret_cast<uintptr_t>(std::static_pointer_cast<MK64::Array>(res)->Vertices.data());
|
||||
} else {
|
||||
|
||||
@@ -53,16 +53,15 @@ 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;
|
||||
}
|
||||
|
||||
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" });
|
||||
|
||||
|
||||
Reference in New Issue
Block a user