Improve first person and add gFirstPersonCamera

This commit is contained in:
Agent X 2023-11-11 16:49:46 -05:00
parent ae22eaac98
commit e79775aea4
24 changed files with 142 additions and 89 deletions

View file

@ -42,7 +42,8 @@ in_files = [
"include/level_commands.h",
"src/audio/external.h",
"src/game/envfx_snow.h",
"src/pc/mods/mod_storage.h"
"src/pc/mods/mod_storage.h",
"src/game/first_person_cam.h"
]
exclude_constants = {

View file

@ -25,7 +25,8 @@ in_files = [
'src/pc/mods/mod.h',
'src/pc/lua/utils/smlua_audio_utils.h',
'src/game/paintings.h',
'src/pc/djui/djui_types.h'
'src/pc/djui/djui_types.h',
'src/game/first_person_cam.h'
]
out_filename_c = 'src/pc/lua/smlua_cobject_autogen.c'
@ -112,6 +113,7 @@ override_field_immutable = {
"Animation": [ "length" ],
"AnimationTable": [ "count" ],
"Controller": [ "controllerData", "statusData" ],
"FirstPersonCamera": [ "enabled" ],
}
override_field_version_excludes = {

View file

@ -3413,6 +3413,9 @@ DS_MAX = 11
--- @type DialogSound
DS_NONE = 0xff
--- @type integer
FIRST_PERSON_DEFAULT_FOV = 70
--- @type integer
BACKGROUND_ABOVE_CLOUDS = 8

View file

@ -8671,11 +8671,6 @@ function get_environment_region(index)
-- ...
end
--- @return boolean
function get_first_person_camera_enabled()
-- ...
end
--- @param index integer
--- @return integer
function get_fog_color(index)

View file

@ -66,6 +66,10 @@ gPaintingValues = {}
--- @type ServerSettings
gServerSettings = {}
--- @type FirstPersonCamera
--- The struct that contains the values for the first person camera
gFirstPersonCamera = {}
-----------
-- hooks --
-----------

View file

@ -593,6 +593,13 @@
--- @field public g integer
--- @field public r integer
--- @class FirstPersonCamera
--- @field public crouch number
--- @field public enabled boolean
--- @field public fov number
--- @field public pitch integer
--- @field public yaw integer
--- @class FloorGeometry
--- @field public normalX number
--- @field public normalY number

View file

@ -19,6 +19,7 @@
- [envfx_snow.h](#envfx_snowh)
- [external.h](#externalh)
- [enum DialogSound](#enum-DialogSound)
- [first_person_cam.h](#first_person_camh)
- [geo_commands.h](#geo_commandsh)
- [graph_node.h](#graph_nodeh)
- [interaction.c](#interactionc)
@ -1164,6 +1165,13 @@
<br />
## [first_person_cam.h](#first_person_cam.h)
- FIRST_PERSON_DEFAULT_FOV
[:arrow_up_small:](#)
<br />
## [geo_commands.h](#geo_commands.h)
- BACKGROUND_ABOVE_CLOUDS
- BACKGROUND_BELOW_CLOUDS

View file

@ -813,24 +813,6 @@
<br />
## [get_first_person_camera_enabled](#get_first_person_camera_enabled)
### Lua Example
`local booleanValue = get_first_person_camera_enabled()`
### Parameters
- None
### Returns
- `boolean`
### C Prototype
`bool get_first_person_camera_enabled(void);`
[:arrow_up_small:](#)
<br />
## [get_fog_color](#get_fog_color)
### Lua Example

View file

@ -1625,7 +1625,6 @@
- [get_dialog_id](functions-5.md#get_dialog_id)
- [get_envfx](functions-5.md#get_envfx)
- [get_environment_region](functions-5.md#get_environment_region)
- [get_first_person_camera_enabled](functions-5.md#get_first_person_camera_enabled)
- [get_fog_color](functions-5.md#get_fog_color)
- [get_fog_intensity](functions-5.md#get_fog_intensity)
- [get_got_file_coin_hi_score](functions-5.md#get_got_file_coin_hi_score)

View file

@ -30,8 +30,8 @@ The `gActiveMods[]` table is an array that starts at `0`, and contains a [Mod](s
<br />
## [gCharacter](#gCharacter)
The `gCharacter[]` table is an array from `0` to `(CT_MAX - 1)` that contains a [Character](structs.md#Character) struct for each possible character.
## [gCharacters](#gCharacter)
The `gCharacters[]` table is an array from `0` to `(CT_MAX - 1)` that contains a [Character](structs.md#Character) struct for each possible character.
[:arrow_up_small:](#)
@ -65,6 +65,22 @@ The `gGlobalObjectCollisionData` table contains references to object collision d
<br />
## [gServerSettings](#gServerSettings)
`gServerSettings`'s fields are listed in [ServerSettings](structs.md#ServerSettings).
__**NOTE**__: The fields in this struct do not sync well and changing them outside of init in if statements or functions can cause desyncs. Make sure the field gets changed on every player's end if you change it after init.
[:arrow_up_small:](#)
## [gNametagsSettings](#gNametagsSettings)
`gNametagsSettings`'s fields are listed in [NametagsSettings](structs.md#NametagsSettings).
__**NOTE**__: The fields in this struct are not synced and are meant to be changed from Lua. If you want a change to sync for everyone, call it during init outside of any if statements and functions or make sure the field gets changed on every player's end.
[:arrow_up_small:](#)
<br />
## [gLevelValues](#gLevelValues)
`gLevelValues`'s fields are listed in [LevelValues](structs.md#LevelValues).
@ -79,10 +95,15 @@ The `gGlobalObjectCollisionData` table contains references to object collision d
<br />
## [gServerSettings](#gServerSettings)
`gServerSettings`'s fields are listed in [ServerSettings](structs.md#ServerSettings).
## [gPaintingValues](#gPaintingValues)
`gPaintingValues`'s fields are listed in [PaintingValues](structs.md#PaintingValues).
__**NOTE**__: You should only change the fields in this struct on init, and it shouldn't be done inside of if statements or functions. Failing to follow this advice can result in desyncs.
[:arrow_up_small:](#)
<br />
## [gFirstPersonCamera](#gFirstPersonCamera)
`gFirstPersonCamera`'s fields are listed in [FirstPersonCamera](structs.md#FirstPersonCamera).
[:arrow_up_small:](#)

View file

@ -25,6 +25,7 @@
- [DateTime](#DateTime)
- [DjuiColor](#DjuiColor)
- [ExclamationBoxContents](#ExclamationBoxContents)
- [FirstPersonCamera](#FirstPersonCamera)
- [FloorGeometry](#FloorGeometry)
- [GlobalObjectAnimations](#GlobalObjectAnimations)
- [GlobalObjectCollisionData](#GlobalObjectCollisionData)
@ -856,6 +857,20 @@
<br />
## [FirstPersonCamera](#FirstPersonCamera)
| Field | Type | Access |
| ----- | ---- | ------ |
| crouch | `number` | |
| enabled | `boolean` | read-only |
| fov | `number` | |
| pitch | `integer` | |
| yaw | `integer` | |
[:arrow_up_small:](#)
<br />
## [FloorGeometry](#FloorGeometry)
| Field | Type | Access |

View file

@ -3495,8 +3495,8 @@ void reset_camera(struct Camera *c) {
unused8033B30C = 0;
unused8033B310 = 0;
if (gFirstPersonEnabled) {
gFirstPersonYaw = gMarioStates[0].faceAngle[1] + 0x8000;
if (gFirstPersonCamera.enabled) {
gFirstPersonCamera.yaw = gMarioStates[0].faceAngle[1] + 0x8000;
}
}

View file

@ -19,10 +19,13 @@
#define CLAMP(_val, _min, _max) MAX(MIN((_val), _max), _min)
bool gFirstPersonEnabled = false;
s16 gFirstPersonYaw = 0;
static s16 sFirstPersonPitch = 0;
static f32 sFirstPersonCrouch = 0;
struct FirstPersonCamera gFirstPersonCamera = {
.enabled = false,
.pitch = 0,
.yaw = 0,
.crouch = 0,
.fov = FIRST_PERSON_DEFAULT_FOV
};
extern s16 gMenuMode;
@ -38,14 +41,14 @@ void update_first_person_camera(void) {
if (gMenuMode == -1) {
// update pitch
sFirstPersonPitch -= sensY * (invY * m->controller->extStickY - 1.5f * mouse_y);
sFirstPersonPitch = CLAMP(sFirstPersonPitch, -0x3F00, 0x3F00);
gFirstPersonCamera.pitch -= sensY * (invY * m->controller->extStickY - 1.5f * mouse_y);
gFirstPersonCamera.pitch = CLAMP(gFirstPersonCamera.pitch, -0x3F00, 0x3F00);
// update yaw
if (m->controller->buttonPressed & L_TRIG) {
gFirstPersonYaw = m->faceAngle[1] + 0x8000;
gFirstPersonCamera.yaw = m->faceAngle[1] + 0x8000;
} else {
gFirstPersonYaw += sensX * (invX * m->controller->extStickX - 1.5f * mouse_x);
gFirstPersonCamera.yaw += sensX * (invX * m->controller->extStickX - 1.5f * mouse_x);
}
gDjuiHudLockMouse = true;
@ -56,51 +59,51 @@ void update_first_person_camera(void) {
// fix yaw for some specific actions
// if the left stick is held, use Mario's yaw to set the camera's yaw
// otherwise, set Mario's yaw to the camera's yaw
u32 actions[] = { ACT_FLYING, ACT_HOLDING_BOWSER, ACT_TORNADO_TWIRLING, ACT_FLAG_ON_POLE, ACT_FLAG_SWIMMING };
u32 actions[] = { ACT_HOLDING_BOWSER, ACT_TORNADO_TWIRLING, ACT_FLAG_ON_POLE, ACT_FLAG_SWIMMING, ACT_FLAG_SWIMMING_OR_FLYING };
for (s32 i = 0; i < 4; i++) {
u32 flag = actions[i];
if ((m->action & flag) == flag) {
if (ABS(m->controller->stickX) > 4) {
gFirstPersonYaw = m->faceAngle[1] + 0x8000;
gFirstPersonCamera.yaw = m->faceAngle[1] + 0x8000;
} else {
m->faceAngle[1] = gFirstPersonYaw - 0x8000;
m->faceAngle[1] = gFirstPersonCamera.yaw - 0x8000;
}
break;
}
}
if (m->action == ACT_LEDGE_GRAB) {
gFirstPersonYaw = m->faceAngle[1] + 0x8000;
gFirstPersonCamera.yaw = m->faceAngle[1] + 0x8000;
}
gLakituState.yaw = gFirstPersonYaw;
m->area->camera->yaw = gFirstPersonYaw;
gLakituState.yaw = gFirstPersonCamera.yaw;
m->area->camera->yaw = gFirstPersonCamera.yaw;
// update crouch
if (m->action == ACT_START_CROUCHING || m->action == ACT_CROUCHING || m->action == ACT_STOP_CROUCHING ||
m->action == ACT_START_CRAWLING || m->action == ACT_CRAWLING || m->action == ACT_STOP_CRAWLING ||
m->action == ACT_CROUCH_SLIDE || m->action == ACT_LEDGE_GRAB) {
f32 inc = 10 * (m->controller->buttonDown & Z_TRIG) != 0 || m->action == ACT_CROUCH_SLIDE || m->action == ACT_LEDGE_GRAB ? 1 : -1;
sFirstPersonCrouch = CLAMP(sFirstPersonCrouch + inc, 0, MARIO_HEAD_POS - MARIO_HEAD_POS_SHORT);
gFirstPersonCamera.crouch = CLAMP(gFirstPersonCamera.crouch + inc, 0, MARIO_HEAD_POS - MARIO_HEAD_POS_SHORT);
} else {
sFirstPersonCrouch = CLAMP(sFirstPersonCrouch - 10, 0, MARIO_HEAD_POS - MARIO_HEAD_POS_SHORT);
gFirstPersonCamera.crouch = CLAMP(gFirstPersonCamera.crouch - 10, 0, MARIO_HEAD_POS - MARIO_HEAD_POS_SHORT);
}
if (m->action == ACT_LEDGE_GRAB) {
sFirstPersonCrouch = MARIO_HEAD_POS - MARIO_HEAD_POS_SHORT;
gFirstPersonCamera.crouch = MARIO_HEAD_POS - MARIO_HEAD_POS_SHORT;
}
// update pos
gLakituState.pos[0] = m->pos[0] + coss(sFirstPersonPitch) * sins(gFirstPersonYaw);
gLakituState.pos[1] = m->pos[1] + sins(sFirstPersonPitch) + (MARIO_HEAD_POS - sFirstPersonCrouch);
gLakituState.pos[2] = m->pos[2] + coss(sFirstPersonPitch) * coss(gFirstPersonYaw);
gLakituState.pos[0] = m->pos[0] + coss(gFirstPersonCamera.pitch) * sins(gFirstPersonCamera.yaw);
gLakituState.pos[1] = m->pos[1] + sins(gFirstPersonCamera.pitch) + (MARIO_HEAD_POS - gFirstPersonCamera.crouch);
gLakituState.pos[2] = m->pos[2] + coss(gFirstPersonCamera.pitch) * coss(gFirstPersonCamera.yaw);
vec3f_copy(m->area->camera->pos, gLakituState.pos);
vec3f_copy(gLakituState.curPos, gLakituState.pos);
vec3f_copy(gLakituState.goalPos, gLakituState.pos);
// update focus
gLakituState.focus[0] = m->pos[0] - 100 * coss(sFirstPersonPitch) * sins(gFirstPersonYaw);
gLakituState.focus[1] = m->pos[1] - 100 * sins(sFirstPersonPitch) + (MARIO_HEAD_POS - sFirstPersonCrouch);
gLakituState.focus[2] = m->pos[2] - 100 * coss(sFirstPersonPitch) * coss(gFirstPersonYaw);
gLakituState.focus[0] = m->pos[0] - 100 * coss(gFirstPersonCamera.pitch) * sins(gFirstPersonCamera.yaw);
gLakituState.focus[1] = m->pos[1] - 100 * sins(gFirstPersonCamera.pitch) + (MARIO_HEAD_POS - gFirstPersonCamera.crouch);
gLakituState.focus[2] = m->pos[2] - 100 * coss(gFirstPersonCamera.pitch) * coss(gFirstPersonCamera.yaw);
vec3f_copy(m->area->camera->focus, gLakituState.focus);
vec3f_copy(gLakituState.curFocus, gLakituState.focus);
vec3f_copy(gLakituState.goalFocus, gLakituState.focus);
@ -112,11 +115,11 @@ void update_first_person_camera(void) {
gLakituState.focVSpeed = 0;
vec3s_set(gLakituState.shakeMagnitude, 0, 0, 0);
gFOVState.fov = FIRST_PERSON_FOV;
gFOVState.fov = gFirstPersonCamera.fov;
}
bool update_first_person(void) {
if (gFirstPersonEnabled && !gDjuiInMainMenu) {
if (gFirstPersonCamera.enabled && !gDjuiInMainMenu) {
if (gCurrActNum == 99) {
return false;
}
@ -139,7 +142,7 @@ bool update_first_person(void) {
}
if (m->action == ACT_SHOT_FROM_CANNON && m->area->camera->mode == CAMERA_MODE_INSIDE_CANNON) {
gFirstPersonYaw = m->faceAngle[1] + 0x8000;
gFirstPersonCamera.yaw = m->faceAngle[1] + 0x8000;
m->area->camera->mode = CAMERA_MODE_FREE_ROAM;
}

View file

@ -4,10 +4,17 @@
#include <stdbool.h>
#include <PR/ultratypes.h>
#define FIRST_PERSON_FOV 70
#define FIRST_PERSON_DEFAULT_FOV 70
extern bool gFirstPersonEnabled;
extern s16 gFirstPersonYaw;
struct FirstPersonCamera {
bool enabled;
s16 pitch;
s16 yaw;
f32 crouch;
f32 fov;
};
extern struct FirstPersonCamera gFirstPersonCamera;
bool update_first_person(void);

View file

@ -1572,7 +1572,7 @@ void update_mario_joystick_inputs(struct MarioState *m) {
if (m->intendedMag > 0.0f) {
if (gLakituState.mode != CAMERA_MODE_NEWCAM) {
m->intendedYaw = atan2s(-controller->stickY, controller->stickX) + m->area->camera->yaw;
} else if (gFirstPersonEnabled) {
} else if (gFirstPersonCamera.enabled) {
m->intendedYaw = atan2s(-controller->stickY, controller->stickX) + gLakituState.yaw;
} else {
m->intendedYaw = atan2s(-controller->stickY, controller->stickX) - newcam_yaw + 0x4000;

View file

@ -15,7 +15,8 @@
#include "pc/utils/misc.h"
#include "pc/debuglog.h"
#include "game/skybox.h"
#include "include/course_table.h"
#include "game/first_person_cam.h"
#include "course_table.h"
/**
* This file contains the code that processes the scene graph for rendering.
@ -236,7 +237,7 @@ void patch_mtx_interpolated(f32 delta) {
u16 perspNorm;
f32 fovInterpolated = delta_interpolate_f32(sPerspectiveNode->prevFov, sPerspectiveNode->fov, delta);
f32 near = MIN(sPerspectiveNode->near, gProjectionMaxNearValue);
guPerspective(sPerspectiveMtx, &perspNorm, not_zero(fovInterpolated, gOverrideFOV), sPerspectiveAspect, not_zero(near, gOverrideNear), not_zero(sPerspectiveNode->far, gOverrideFar), 1.0f);
guPerspective(sPerspectiveMtx, &perspNorm, not_zero(fovInterpolated, gOverrideFOV), sPerspectiveAspect, gFirstPersonCamera.enabled && !gDjuiInMainMenu ? 1 : not_zero(near, gOverrideNear), not_zero(sPerspectiveNode->far, gOverrideFar), 1.0f);
gSPMatrix(sPerspectivePos, VIRTUAL_TO_PHYSICAL(sPerspectiveNode), G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH);
}
@ -487,7 +488,7 @@ static void geo_process_perspective(struct GraphNodePerspective *node) {
gProjectionVanillaNearValue = node->near;
gProjectionVanillaFarValue = node->far;
f32 near = MIN(node->near, gProjectionMaxNearValue);
guPerspective(mtx, &perspNorm, not_zero(node->prevFov, gOverrideFOV), aspect, not_zero(near, gOverrideNear), not_zero(node->far, gOverrideFar), 1.0f);
guPerspective(mtx, &perspNorm, not_zero(node->prevFov, gOverrideFOV), aspect, gFirstPersonCamera.enabled && !gDjuiInMainMenu ? 1 : not_zero(near, gOverrideNear), not_zero(node->far, gOverrideFar), 1.0f);
sPerspectiveNode = node;
sPerspectiveMtx = mtx;

View file

@ -3,6 +3,7 @@
#include "game/level_update.h"
#include "game/area.h"
#include "game/mario.h"
#include "game/first_person_cam.h"
#include "game/hardcoded.h"
#include "game/scroll_targets.h"
#include "audio/external.h"
@ -646,6 +647,11 @@ void smlua_cobject_init_globals(void) {
smlua_push_object(L, LOT_PAINTINGVALUES, &gPaintingValues);
lua_setglobal(L, "gPaintingValues");
}
{
smlua_push_object(L, LOT_FIRSTPERSONCAMERA, &gFirstPersonCamera);
lua_setglobal(L, "gFirstPersonCamera");
}
}
void smlua_cobject_init_per_file_globals(const char* path) {

View file

@ -21,6 +21,7 @@
#include "src/pc/lua/utils/smlua_audio_utils.h"
#include "src/game/paintings.h"
#include "src/pc/djui/djui_types.h"
#include "src/game/first_person_cam.h"
#include "include/object_fields.h"
@ -673,6 +674,15 @@ static struct LuaObjectField sDjuiColorFields[LUA_DJUI_COLOR_FIELD_COUNT] = {
{ "r", LVT_U8, offsetof(struct DjuiColor, r), false, LOT_NONE },
};
#define LUA_FIRST_PERSON_CAMERA_FIELD_COUNT 5
static struct LuaObjectField sFirstPersonCameraFields[LUA_FIRST_PERSON_CAMERA_FIELD_COUNT] = {
{ "crouch", LVT_F32, offsetof(struct FirstPersonCamera, crouch), false, LOT_NONE },
{ "enabled", LVT_BOOL, offsetof(struct FirstPersonCamera, enabled), true, LOT_NONE },
{ "fov", LVT_F32, offsetof(struct FirstPersonCamera, fov), false, LOT_NONE },
{ "pitch", LVT_S16, offsetof(struct FirstPersonCamera, pitch), false, LOT_NONE },
{ "yaw", LVT_S16, offsetof(struct FirstPersonCamera, yaw), false, LOT_NONE },
};
#define LUA_FLOOR_GEOMETRY_FIELD_COUNT 4
static struct LuaObjectField sFloorGeometryFields[LUA_FLOOR_GEOMETRY_FIELD_COUNT] = {
{ "normalX", LVT_F32, offsetof(struct FloorGeometry, normalX), false, LOT_NONE },
@ -2410,6 +2420,7 @@ struct LuaObjectTable sLuaObjectAutogenTable[LOT_AUTOGEN_MAX - LOT_AUTOGEN_MIN]
{ LOT_CUTSCENEVARIABLE, sCutsceneVariableFields, LUA_CUTSCENE_VARIABLE_FIELD_COUNT },
{ LOT_DATETIME, sDateTimeFields, LUA_DATE_TIME_FIELD_COUNT },
{ LOT_DJUICOLOR, sDjuiColorFields, LUA_DJUI_COLOR_FIELD_COUNT },
{ LOT_FIRSTPERSONCAMERA, sFirstPersonCameraFields, LUA_FIRST_PERSON_CAMERA_FIELD_COUNT },
{ LOT_FLOORGEOMETRY, sFloorGeometryFields, LUA_FLOOR_GEOMETRY_FIELD_COUNT },
{ LOT_GLOBALOBJECTANIMATIONS, sGlobalObjectAnimationsFields, LUA_GLOBAL_OBJECT_ANIMATIONS_FIELD_COUNT },
{ LOT_GLOBALOBJECTCOLLISIONDATA, sGlobalObjectCollisionDataFields, LUA_GLOBAL_OBJECT_COLLISION_DATA_FIELD_COUNT },

View file

@ -27,6 +27,7 @@ enum LuaObjectAutogenType {
LOT_CUTSCENEVARIABLE,
LOT_DATETIME,
LOT_DJUICOLOR,
LOT_FIRSTPERSONCAMERA,
LOT_FLOORGEOMETRY,
LOT_GLOBALOBJECTANIMATIONS,
LOT_GLOBALOBJECTCOLLISIONDATA,

View file

@ -1345,6 +1345,7 @@ char gSmluaConstants[] = ""
"DS_MAX = 11\n"
"DS_NONE = 0xff\n"
"DS_DIFF = DS_TUXIE\n"
"FIRST_PERSON_DEFAULT_FOV = 70\n"
"BACKGROUND_OCEAN_SKY = 0\n"
"BACKGROUND_FLAMING_SKY = 1\n"
"BACKGROUND_UNDERWATER_CITY = 2\n"

View file

@ -28670,21 +28670,6 @@ int smlua_func_get_environment_region(lua_State* L) {
return 1;
}
int smlua_func_get_first_person_camera_enabled(UNUSED lua_State* L) {
if (L == NULL) { return 0; }
int top = lua_gettop(L);
if (top != 0) {
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "get_first_person_camera_enabled", 0, top);
return 0;
}
lua_pushboolean(L, get_first_person_camera_enabled());
return 1;
}
int smlua_func_get_fog_color(lua_State* L) {
if (L == NULL) { return 0; }
@ -32772,7 +32757,6 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "get_dialog_id", smlua_func_get_dialog_id);
smlua_bind_function(L, "get_envfx", smlua_func_get_envfx);
smlua_bind_function(L, "get_environment_region", smlua_func_get_environment_region);
smlua_bind_function(L, "get_first_person_camera_enabled", smlua_func_get_first_person_camera_enabled);
smlua_bind_function(L, "get_fog_color", smlua_func_get_fog_color);
smlua_bind_function(L, "get_fog_intensity", smlua_func_get_fog_intensity);
smlua_bind_function(L, "get_got_file_coin_hi_score", smlua_func_get_got_file_coin_hi_score);

View file

@ -628,13 +628,9 @@ void set_override_envfx(s32 envfx) {
///
bool get_first_person_camera_enabled(void) {
return gFirstPersonEnabled;
}
void set_first_person_camera_enabled(bool enable) {
if (gFirstPersonEnabled && !enable) { gFOVState.fov = 45.0f; }
gFirstPersonEnabled = enable;
if (gFirstPersonCamera.enabled && !enable) { gFOVState.fov = 45.0f; }
gFirstPersonCamera.enabled = enable;
}
///

View file

@ -155,7 +155,6 @@ struct DateTime* get_date_and_time(void);
u16 get_envfx(void);
void set_override_envfx(s32 envfx);
bool get_first_person_camera_enabled(void);
void set_first_person_camera_enabled(bool enable);
const char* get_os_name(void);

View file

@ -28,6 +28,7 @@
#include "game/level_geo.h"
#include "menu/intro_geo.h"
#include "game/ingame_menu.h"
#include "game/first_person_cam.h"
#ifdef DISCORD_SDK
#include "pc/discord/discord.h"
@ -701,6 +702,12 @@ void network_shutdown(bool sendLeaving, bool exiting, bool popup, bool reconnect
cnt->extStickX = 0;
cnt->extStickY = 0;
gFirstPersonCamera.enabled = false;
gFirstPersonCamera.pitch = 0;
gFirstPersonCamera.yaw = 0;
gFirstPersonCamera.crouch = 0;
gFirstPersonCamera.fov = FIRST_PERSON_DEFAULT_FOV;
extern void save_file_load_all(UNUSED u8 reload);
save_file_load_all(TRUE);
extern void save_file_set_using_backup_slot(bool usingBackupSlot);