diff --git a/autogen/convert_functions.py b/autogen/convert_functions.py index b5c504b8..d9ab7a85 100644 --- a/autogen/convert_functions.py +++ b/autogen/convert_functions.py @@ -115,7 +115,7 @@ override_disallowed_functions = { "src/pc/lua/utils/smlua_text_utils.h": [ "smlua_text_utils_reset_all" ], "src/pc/lua/utils/smlua_anim_utils.h": [ "smlua_anim_util_reset", "smlua_anim_util_register_animation" ], "src/pc/network/lag_compensation.h": [ "lag_compensation_clear", "lag_compensation_store" ], - "src/game/first_person_cam.h": [ "first_person_update", "get_dest_fov", "get_dest_near" ] + "src/game/first_person_cam.h": [ "first_person_update" ] } override_hide_functions = { diff --git a/autogen/convert_structs.py b/autogen/convert_structs.py index 1f05630c..21ff5d18 100644 --- a/autogen/convert_structs.py +++ b/autogen/convert_structs.py @@ -113,7 +113,8 @@ override_field_immutable = { "ObjectWarpNode": [ "next "], "Animation": [ "length" ], "AnimationTable": [ "count" ], - "Controller": [ "controllerData", "statusData" ] + "Controller": [ "controllerData", "statusData" ], + "FirstPersonCamera": [ "enabled" ], } override_field_version_excludes = { diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua index 1410fe5d..45e48c1a 100644 --- a/autogen/lua_definitions/functions.lua +++ b/autogen/lua_definitions/functions.lua @@ -4016,6 +4016,12 @@ function get_first_person_enabled() -- ... end +--- @param enable boolean +--- @return nil +function set_first_person_enabled(enable) + -- ... +end + --- @return nil function reset_dialog_override_color() -- ... diff --git a/autogen/lua_definitions/structs.lua b/autogen/lua_definitions/structs.lua index 1f661a8d..90036142 100644 --- a/autogen/lua_definitions/structs.lua +++ b/autogen/lua_definitions/structs.lua @@ -595,6 +595,7 @@ --- @field public crouch number --- @field public enabled boolean --- @field public forceRoll boolean +--- @field public fov number --- @field public offset Vec3f --- @field public pitch integer --- @field public yaw integer diff --git a/docs/lua/functions-3.md b/docs/lua/functions-3.md index 83be5612..7b26dbb5 100644 --- a/docs/lua/functions-3.md +++ b/docs/lua/functions-3.md @@ -3322,6 +3322,26 @@
+## [set_first_person_enabled](#set_first_person_enabled) + +### Lua Example +`set_first_person_enabled(enable)` + +### Parameters +| Field | Type | +| ----- | ---- | +| enable | `boolean` | + +### Returns +- None + +### C Prototype +`void set_first_person_enabled(bool enable);` + +[:arrow_up_small:](#) + +
+ --- # functions from ingame_menu.h diff --git a/docs/lua/functions.md b/docs/lua/functions.md index ba1431e8..c12f90d7 100644 --- a/docs/lua/functions.md +++ b/docs/lua/functions.md @@ -803,6 +803,7 @@ - [first_person_check_cancels](functions-3.md#first_person_check_cancels) - [first_person_reset](functions-3.md#first_person_reset) - [get_first_person_enabled](functions-3.md#get_first_person_enabled) + - [set_first_person_enabled](functions-3.md#set_first_person_enabled)
diff --git a/docs/lua/structs.md b/docs/lua/structs.md index b51dfafa..d1c30080 100644 --- a/docs/lua/structs.md +++ b/docs/lua/structs.md @@ -848,8 +848,9 @@ | ----- | ---- | ------ | | centerL | `boolean` | | | crouch | `number` | | -| enabled | `boolean` | | +| enabled | `boolean` | read-only | | forceRoll | `boolean` | | +| fov | `number` | | | offset | [Vec3f](structs.md#Vec3f) | read-only | | pitch | `integer` | | | yaw | `integer` | | diff --git a/src/game/first_person_cam.c b/src/game/first_person_cam.c index adcfbe0c..1dcff1eb 100644 --- a/src/game/first_person_cam.c +++ b/src/game/first_person_cam.c @@ -9,7 +9,6 @@ #include "mario.h" #include "hardcoded.h" #include "save_file.h" -#include "rendering_graph_node.h" #include "engine/math_util.h" @@ -28,6 +27,7 @@ struct FirstPersonCamera gFirstPersonCamera = { .pitch = 0, .yaw = 0, .crouch = 0, + .fov = FIRST_PERSON_DEFAULT_FOV, .offset = { 0, 0, 0 } }; @@ -54,12 +54,9 @@ bool get_first_person_enabled(void) { return gFirstPersonCamera.enabled && !first_person_check_cancels(&gMarioStates[0]); } -f32 get_dest_fov(f32 fov) { - return get_first_person_enabled() ? FIRST_PERSON_DEFAULT_FOV : not_zero(fov, gOverrideFOV); -} - -f32 get_dest_near(f32 near) { - return get_first_person_enabled() ? 1 : not_zero(near, gOverrideNear); +void set_first_person_enabled(bool enable) { + if (gFirstPersonCamera.enabled && !enable) { gFOVState.fov = 45.0f; } + gFirstPersonCamera.enabled = enable; } void first_person_camera_update(void) { @@ -146,6 +143,8 @@ void first_person_camera_update(void) { gLakituState.focHSpeed = 0; gLakituState.focVSpeed = 0; vec3s_set(gLakituState.shakeMagnitude, 0, 0, 0); + + gFOVState.fov = gFirstPersonCamera.fov; } void first_person_update(void) { @@ -193,6 +192,7 @@ void first_person_reset(void) { gFirstPersonCamera.pitch = 0; gFirstPersonCamera.yaw = 0; gFirstPersonCamera.crouch = 0; + gFirstPersonCamera.fov = FIRST_PERSON_DEFAULT_FOV; gFirstPersonCamera.offset[0] = 0; gFirstPersonCamera.offset[1] = 0; gFirstPersonCamera.offset[2] = 0; diff --git a/src/game/first_person_cam.h b/src/game/first_person_cam.h index c5df69b9..64a858d7 100644 --- a/src/game/first_person_cam.h +++ b/src/game/first_person_cam.h @@ -15,6 +15,7 @@ struct FirstPersonCamera { s16 pitch; s16 yaw; f32 crouch; + f32 fov; Vec3f offset; }; @@ -23,9 +24,7 @@ extern struct FirstPersonCamera gFirstPersonCamera; bool first_person_check_cancels(struct MarioState *m); bool get_first_person_enabled(void); - -f32 get_dest_fov(f32 fov); -f32 get_dest_near(f32 near); +void set_first_person_enabled(bool enable); void first_person_update(void); void first_person_reset(void); diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c index 6e529f9b..b12df4d4 100644 --- a/src/game/rendering_graph_node.c +++ b/src/game/rendering_graph_node.c @@ -237,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, get_dest_fov(fovInterpolated), sPerspectiveAspect, get_dest_near(near), not_zero(sPerspectiveNode->far, gOverrideFar), 1.0f); + guPerspective(sPerspectiveMtx, &perspNorm, not_zero(fovInterpolated, gOverrideFOV), sPerspectiveAspect, get_first_person_enabled() ? 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); } @@ -488,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, get_dest_fov(node->prevFov), aspect, get_dest_near(near), not_zero(node->far, gOverrideFar), 1.0f); + guPerspective(mtx, &perspNorm, not_zero(node->prevFov, gOverrideFOV), aspect, get_first_person_enabled() ? 1 : not_zero(near, gOverrideNear), not_zero(node->far, gOverrideFar), 1.0f); sPerspectiveNode = node; sPerspectiveMtx = mtx; @@ -1156,7 +1156,7 @@ static s32 obj_is_in_view(struct GraphNodeObject *node, Mat4 matrix) { // visibly pop in or out at the edge of the screen. // // Half of the fov in in-game angle units instead of degrees. - s16 halfFov = (get_dest_fov(gCurGraphNodeCamFrustum->fov) / 2.0f + 1.0f) * 32768.0f / 180.0f + 0.5f; + s16 halfFov = (not_zero(gCurGraphNodeCamFrustum->fov, gOverrideFOV) / 2.0f + 1.0f) * 32768.0f / 180.0f + 0.5f; f32 divisor = coss(halfFov); if (divisor == 0) { divisor = 1; } diff --git a/src/pc/djui/djui_hud_utils.c b/src/pc/djui/djui_hud_utils.c index 4fa7d553..d88e2659 100644 --- a/src/pc/djui/djui_hud_utils.c +++ b/src/pc/djui/djui_hud_utils.c @@ -20,7 +20,6 @@ #include "game/camera.h" #include "game/hud.h" #include "game/rendering_graph_node.h" -#include "game/first_person_cam.h" #include "engine/math_util.h" @@ -579,7 +578,7 @@ bool djui_hud_world_pos_to_screen_pos(Vec3f pos, Vec3f out) { out[1] *= 256.0f / out[2]; // fov of 45.0 is the default fov - f32 fovDefault = tanf(get_dest_fov(45.0f) * ((f32)M_PI / 360.0f)); + f32 fovDefault = tanf(not_zero(45.0f, gOverrideFOV) * ((f32)M_PI / 360.0f)); f32 fovCurrent = tanf((gFOVState.fov + gFOVState.fovOffset) * ((f32)M_PI / 360.0f)); f32 fovDifference = (fovDefault / fovCurrent) * 1.13f; diff --git a/src/pc/lua/smlua_cobject_autogen.c b/src/pc/lua/smlua_cobject_autogen.c index 3cb29241..8d4caffa 100644 --- a/src/pc/lua/smlua_cobject_autogen.c +++ b/src/pc/lua/smlua_cobject_autogen.c @@ -674,12 +674,13 @@ 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 7 +#define LUA_FIRST_PERSON_CAMERA_FIELD_COUNT 8 static struct LuaObjectField sFirstPersonCameraFields[LUA_FIRST_PERSON_CAMERA_FIELD_COUNT] = { { "centerL", LVT_BOOL, offsetof(struct FirstPersonCamera, centerL), false, LOT_NONE }, { "crouch", LVT_F32, offsetof(struct FirstPersonCamera, crouch), false, LOT_NONE }, - { "enabled", LVT_BOOL, offsetof(struct FirstPersonCamera, enabled), false, LOT_NONE }, + { "enabled", LVT_BOOL, offsetof(struct FirstPersonCamera, enabled), true, LOT_NONE }, { "forceRoll", LVT_BOOL, offsetof(struct FirstPersonCamera, forceRoll), false, LOT_NONE }, + { "fov", LVT_F32, offsetof(struct FirstPersonCamera, fov), false, LOT_NONE }, { "offset", LVT_COBJECT, offsetof(struct FirstPersonCamera, offset), true, LOT_VEC3F }, { "pitch", LVT_S16, offsetof(struct FirstPersonCamera, pitch), false, LOT_NONE }, { "yaw", LVT_S16, offsetof(struct FirstPersonCamera, yaw), false, LOT_NONE }, diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index d6e2db16..12d1adb0 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -13231,6 +13231,23 @@ int smlua_func_get_first_person_enabled(UNUSED lua_State* L) { return 1; } +int smlua_func_set_first_person_enabled(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 1) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "set_first_person_enabled", 1, top); + return 0; + } + + bool enable = smlua_to_boolean(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "set_first_person_enabled"); return 0; } + + set_first_person_enabled(enable); + + return 1; +} + /////////////////// // ingame_menu.h // /////////////////// @@ -32059,6 +32076,7 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "first_person_check_cancels", smlua_func_first_person_check_cancels); smlua_bind_function(L, "first_person_reset", smlua_func_first_person_reset); smlua_bind_function(L, "get_first_person_enabled", smlua_func_get_first_person_enabled); + smlua_bind_function(L, "set_first_person_enabled", smlua_func_set_first_person_enabled); // ingame_menu.h smlua_bind_function(L, "reset_dialog_override_color", smlua_func_reset_dialog_override_color); diff --git a/src/pc/network/network.c b/src/pc/network/network.c index c85c917d..586cf8a9 100644 --- a/src/pc/network/network.c +++ b/src/pc/network/network.c @@ -708,6 +708,7 @@ void network_shutdown(bool sendLeaving, bool exiting, bool popup, bool reconnect cnt->extStickY = 0; gFirstPersonCamera.enabled = false; + gFirstPersonCamera.fov = FIRST_PERSON_DEFAULT_FOV; first_person_reset(); extern void save_file_load_all(UNUSED u8 reload);