Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Enhancements #366

Open
1 of 7 tasks
MegaMech opened this issue Aug 11, 2023 · 3 comments
Open
1 of 7 tasks

Enhancements #366

MegaMech opened this issue Aug 11, 2023 · 3 comments

Comments

@MegaMech
Copy link
Collaborator

MegaMech commented Aug 11, 2023

Enhancements that might be fun. Shouldn't be anything too big here.

  • A to B race mode
  • Equalize stats
  • 200CC
  • Flycam / noclip
  • Water fill station for choo choo
  • Skybox fix
  • Course path renderer

Recording or adding your own staff ghosts?

  • Probably something cool that could be done.
@coco875
Copy link
Contributor

coco875 commented Sep 19, 2023

maybe in the modding part

@coco875
Copy link
Contributor

coco875 commented Sep 19, 2023

if we make a repo for modding

@MegaMech
Copy link
Collaborator Author

MegaMech commented Oct 9, 2023

flycam

#include <ultra64.h>
#include <PR/os.h>
#include <macros.h>
#include <types.h>
#include <defines.h>
#include <camera.h>
#include "main.h"
#include <libc/math.h>
#include <common_structs.h>
#include "racing/collision.h"
#include <variables.h>
#include "player_controller.h"
#include "code_80057C60.h"

// Yaw/pitch rotation sensitivity
#define SENSITIVITY_X 0.0003f
#define SENSITIVITY_Y 0.0003f

u32 isFlycam = FALSE;
u32 fRankIndex = 0;
u32 fTargetPlayer = FALSE;
u32 fMode; // flycam mode should probably be an enum
u32 fModeInit = FALSE;

typedef struct {
    Vec3f pos;
    Vec3f lookAt;
    Vec3s rot; 
} FlycamSaveState;

FlycamSaveState fState;

void flycam_calculate_forward_vector(Camera* camera, Vec3f forwardVector);
void flycam_move_camera_forward(Camera* camera, struct Controller *controller, f32 distance);
void flycam_update(Camera* camera, struct Controller *controller);
void flycam_controller_manager(Camera *camera, struct Controller *controller, Player *player);
void flycam_target_player(Camera *camera, u32 playerIndex);
void flycam_move_camera_up(Camera* camera, struct Controller *controller, f32 distance);
void flycam_save_state(Camera *camera);
void flycam_load_state(Camera *camera);


/**
 * 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 flycam at the player's position
 * Camera mode 2: Enter flycam at previous flycam spot
 * 
*/



void flycam(Camera *camera, Player *player, s8 index) {
    struct Controller *controller = &gControllers[0];
    Vec3f forwardVector;
    f32 dirX;
    f32 dirY;
    f32 dirZ;
    f32 length;
    
    if (controller->buttonPressed & L_TRIG) {
        isFlycam = !isFlycam;

        player->unk_000 ^= PLAYER_CPU; // toggle
        gIsHUDVisible = !gIsHUDVisible;

        if (isFlycam) {

            if (fMode && fModeInit) {
                flycam_load_state(camera);
            } else {
                // !fMode or fMode not initialized
                flycam_target_player(camera, get_player_index_for_player(player));
            }

            return;
        } else {
            if(fMode) {
                flycam_save_state(camera);
            }
        }
    }

    // Driving mode
    if (!isFlycam) {
        // Use normal camera code
        func_8001E45C(camera, &gPlayers[fRankIndex], index);
        return;
    }


    //if (player == gPlayerOne) { return; }

    //player->unk_000 &= ~PLAYER_HUMAN;
    //player->unk_000 |= PLAYER_HUMAN;

    if ((player->unk_000 & PLAYER_START_SEQUENCE)) { return; }
    

    flycam_controller_manager(camera, controller, player);




}

void flycam_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 flycam_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];
}

void flycam_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) {
        flycam_target_player(camera, gGPCurrentRacePlayerIdByRank[fRankIndex]);
        // Don't run the other camera code.
        return;
    }

    // Rotation
    if (!fTargetPlayer) {
        if (controller->stickDirection != 0) {
            flycam_update(camera, controller);
        }
    }

    // Forward
    if (controller->button & A_BUTTON)  {
        flycam_move_camera_forward(camera, controller, 3.0f);
    }

    // Backward     B button but not A button.
    if (controller->button & B_BUTTON && !(controller->button & A_BUTTON))  {
        flycam_move_camera_forward(camera, controller, -3.0f);
    }

    // Up
    if (controller->button & U_CBUTTONS) {
        flycam_move_camera_up(camera, controller, 2.0f);
    }
    // Up
    if (controller->button & D_CBUTTONS) {
        flycam_move_camera_up(camera, controller, -2.0f);
    }
}

// Calculates the forward direction vector based on camera orientation
void flycam_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 flycam_move_camera_forward(Camera* camera, struct Controller *controller, f32 distance) {
    Vec3f forwardVector;
    Vec3f rightVector;
    f32 length;
    flycam_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 flycam_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 flycam_update(Camera* camera, struct Controller *controller) {
    // Calculate yaw (horizontal movement)
    f32 yawChange = controller->rawStickX * SENSITIVITY_X;
    f32 pitchChange = controller->rawStickY * SENSITIVITY_Y;
    Vec3f forwardVector;

    func_802ADDC8(&camera->unk_54, 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
    flycam_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];
}

void flycam_target_player(Camera *camera, u32 playerIndex) {
    Vec3f forwardVector;// = 2.0f;
    Player *player = &gPlayers[playerIndex];

    // 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];

    // Normalize the direction vector (if needed)
    f32 length = sqrtf(dirX * dirX + dirY * dirY + dirZ * dirZ);
    if (length > 0) {
        dirX /= length;
        dirY /= length;
        dirZ /= length;
    }

    // Update the camera's look-at direction
    camera->lookAt[0] = camera->pos[0] + dirX;
    camera->lookAt[1] = camera->pos[1] + dirY;
    camera->lookAt[2] = camera->pos[2] + dirZ;
}

render_courses.c --> load_surface_map

+    if (isFlycam) {
+        func_8029569C();
+       return;
+   }
gSPDisplayList(gDisplayListHead++, gfx[temp_v1]);

main.c --> move func_8001EE98 out of the for loop

code_8001F980.c --> func_8001FB0C

#ifdef FLYCAM
    return 1;
#endif

So the function returns right away.

camera.c --> func_8001EE98

#ifdef FLYCAM
            flycam(camera, player, index);
#else
            func_8001E45C(camera, player, index);
#endif

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants