diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua index 925623f9f..e8258f161 100644 --- a/autogen/lua_definitions/functions.lua +++ b/autogen/lua_definitions/functions.lua @@ -2997,6 +2997,12 @@ function position_based_random_float_position() -- ... end +--- @return boolean +--- Checks if the draw distance scalar is infinite +function draw_distance_scalar_is_infinite() + -- ... +end + --- @return number --- Gets the draw distance scalar function draw_distance_scalar() diff --git a/docs/lua/functions-3.md b/docs/lua/functions-3.md index 2aab0ab14..ec32aed47 100644 --- a/docs/lua/functions-3.md +++ b/docs/lua/functions-3.md @@ -139,6 +139,27 @@ Sets the current object's position to random floats between 0.0 and 1.0
+## [draw_distance_scalar_is_infinite](#draw_distance_scalar_is_infinite) + +### Description +Checks if the draw distance scalar is infinite + +### Lua Example +`local booleanValue = draw_distance_scalar_is_infinite()` + +### Parameters +- None + +### Returns +- `boolean` + +### C Prototype +`bool draw_distance_scalar_is_infinite(void);` + +[:arrow_up_small:](#) + +
+ ## [draw_distance_scalar](#draw_distance_scalar) ### Description diff --git a/docs/lua/functions.md b/docs/lua/functions.md index bb2cd05d3..24dc305d0 100644 --- a/docs/lua/functions.md +++ b/docs/lua/functions.md @@ -623,6 +623,7 @@ - [obj_update_gfx_pos_and_angle](functions-3.md#obj_update_gfx_pos_and_angle) - [position_based_random_u16](functions-3.md#position_based_random_u16) - [position_based_random_float_position](functions-3.md#position_based_random_float_position) + - [draw_distance_scalar_is_infinite](functions-3.md#draw_distance_scalar_is_infinite) - [draw_distance_scalar](functions-3.md#draw_distance_scalar)
diff --git a/lang/Czech.ini b/lang/Czech.ini index e025a5e4e..21934b00a 100644 --- a/lang/Czech.ini +++ b/lang/Czech.ini @@ -167,6 +167,7 @@ D1P5X = "1.5x" D3X = "3x" D10X = "10x" D100X = "100x" +INFINITE = "Nekonečno" DRAW_DISTANCE = "Vzdálenost vykreslování" DYNOS_PACKS = "DynOS packy" ANTIALIASING = "Anti-aliasing" diff --git a/lang/Dutch.ini b/lang/Dutch.ini index dc22bb586..3e4cbe5eb 100644 --- a/lang/Dutch.ini +++ b/lang/Dutch.ini @@ -167,6 +167,7 @@ D1P5X = "1.5x" D3X = "3x" D10X = "10x" D100X = "100x" +INFINITE = "Oneindig" DRAW_DISTANCE = "Teken afstand" DYNOS_PACKS = "DynOS Packs" ANTIALIASING = "Anti-aliasing" diff --git a/lang/English.ini b/lang/English.ini index 3a0061d4d..0e51e68d9 100644 --- a/lang/English.ini +++ b/lang/English.ini @@ -167,6 +167,7 @@ D1P5X = "1.5x" D3X = "3x" D10X = "10x" D100X = "100x" +INFINITE = "Infinite" DRAW_DISTANCE = "Draw Distance" DYNOS_PACKS = "DynOS Packs" ANTIALIASING = "Anti-aliasing" diff --git a/lang/French.ini b/lang/French.ini index 863306e82..2f8cf7143 100644 --- a/lang/French.ini +++ b/lang/French.ini @@ -167,6 +167,7 @@ D1P5X = "x1.5" D3X = "x3" D10X = "x10" D100X = "x100" +INFINITE = "Infini" DRAW_DISTANCE = "Distance d'affichage" DYNOS_PACKS = "Packs DynOS" ANTIALIASING = "Anti-aliasing" diff --git a/lang/German.ini b/lang/German.ini index 90127de7b..9a2c3da44 100644 --- a/lang/German.ini +++ b/lang/German.ini @@ -167,6 +167,7 @@ D1P5X = "1.5x" D3X = "3x" D10X = "10x" D100X = "100x" +INFINITE = "Unendlich" DRAW_DISTANCE = "Sichtweite" DYNOS_PACKS = "DynOS-Pakete" ANTIALIASING = "Kantenglättung" diff --git a/lang/Italian.ini b/lang/Italian.ini index 3f75a5686..ee36b2939 100644 --- a/lang/Italian.ini +++ b/lang/Italian.ini @@ -165,6 +165,7 @@ D1P5X = "1.5x" D3X = "3x" D10X = "10x" D100X = "100x" +INFINITE = "Infinito" DRAW_DISTANCE = "Distanza di Simulazione" DYNOS_PACKS = "Pacchetti DynOS" ANTIALIASING = "Anti-aliasing" diff --git a/lang/Japanese.ini b/lang/Japanese.ini index 06a9e2800..e9d1e125b 100644 --- a/lang/Japanese.ini +++ b/lang/Japanese.ini @@ -167,6 +167,7 @@ D1P5X = "1.5x" D3X = "3x" D10X = "10x" D100X = "100x" +INFINITE = "無限" DRAW_DISTANCE = "描画距離" DYNOS_PACKS = "DynOSパック" ANTIALIASING = "アンチエイリアス" diff --git a/lang/Polish.ini b/lang/Polish.ini index 0989080ad..571b35444 100644 --- a/lang/Polish.ini +++ b/lang/Polish.ini @@ -167,6 +167,7 @@ D1P5X = "1,5x" D3X = "3x" D10X = "10x" D100X = "100x" +INFINITE = "Nieskończony" DRAW_DISTANCE = "Odległość Renderowania" DYNOS_PACKS = "Paczki DynOS" ANTIALIASING = "Anti-aliasing" diff --git a/lang/Portuguese.ini b/lang/Portuguese.ini index 750f6cb5c..275ff2b02 100644 --- a/lang/Portuguese.ini +++ b/lang/Portuguese.ini @@ -167,6 +167,7 @@ D1P5X = "1.5x" D3X = "3x" D10X = "10x" D100X = "100x" +INFINITE = "Infinito" DRAW_DISTANCE = "Distância de renderização" DYNOS_PACKS = "Pacotes DynOS" ANTIALIASING = "Antisserrilhamento" diff --git a/lang/Russian.ini b/lang/Russian.ini index f04fdbd49..569f7ee33 100644 --- a/lang/Russian.ini +++ b/lang/Russian.ini @@ -166,6 +166,7 @@ D1P5X = "1.5x" D3X = "3x" D10X = "10x" D100X = "100x" +INFINITE = "Бесконечный" DRAW_DISTANCE = "Дальность прорисовки" DYNOS_PACKS = "Пакеты DynOS" ANTIALIASING = "Анизотропная фильтрация" diff --git a/lang/Spanish.ini b/lang/Spanish.ini index b0129ad60..f525ea49b 100644 --- a/lang/Spanish.ini +++ b/lang/Spanish.ini @@ -167,6 +167,7 @@ D1P5X = "1.5x" D3X = "3x" D10X = "10x" D100X = "100x" +INFINITE = "Infinito" DRAW_DISTANCE = "Distancia de dibujado" DYNOS_PACKS = "Packs DynOS" ANTIALIASING = "Anti-aliasing" diff --git a/src/engine/behavior_script.c b/src/engine/behavior_script.c index 054e773f4..316b5b82d 100644 --- a/src/engine/behavior_script.c +++ b/src/engine/behavior_script.c @@ -1438,7 +1438,9 @@ cur_obj_update_begin:; } else if ((objFlags & OBJ_FLAG_COMPUTE_DIST_TO_MARIO) && gCurrentObject->collisionData == NULL) { if (!(objFlags & OBJ_FLAG_ACTIVE_FROM_AFAR)) { // If the object has a render distance, check if it should be shown. - if (distanceFromMario > gCurrentObject->oDrawingDistance * draw_distance_scalar()) { + if (!draw_distance_scalar_is_infinite() && + distanceFromMario > gCurrentObject->oDrawingDistance * draw_distance_scalar() + ) { // Out of render distance, hide the object. gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE; @@ -1486,6 +1488,13 @@ f32 position_based_random_float_position(void) { return rnd / (double)0x10000; } +bool draw_distance_scalar_is_infinite(void) { + if (!gBehaviorValues.InfiniteRenderDistance) { + return false; + } + return configDrawDistance == 6; // Expecting this to be "Infinite" +} + f32 draw_distance_scalar(void) { if (!gBehaviorValues.InfiniteRenderDistance) { return 1.0f; } diff --git a/src/engine/behavior_script.h b/src/engine/behavior_script.h index c3af4e0ed..43b0769d2 100644 --- a/src/engine/behavior_script.h +++ b/src/engine/behavior_script.h @@ -37,6 +37,8 @@ void obj_update_gfx_pos_and_angle(struct Object *obj); u16 position_based_random_u16(void); /* |description|Sets the current object's position to random floats between 0.0 and 1.0|descriptionEnd| */ f32 position_based_random_float_position(void); +/* |description|Checks if the draw distance scalar is infinite|descriptionEnd| */ +bool draw_distance_scalar_is_infinite(void); /* |description|Gets the draw distance scalar|descriptionEnd| */ f32 draw_distance_scalar(void); diff --git a/src/engine/surface_load.c b/src/engine/surface_load.c index c611750b0..5fbda2faf 100644 --- a/src/engine/surface_load.c +++ b/src/engine/surface_load.c @@ -1045,7 +1045,9 @@ static void load_object_collision_model_internal(bool isSOC) { if (!isSOC) { f32 marioDist = dist_between_objects(gCurrentObject, gMarioStates[0].marioObj); - if (marioDist < gCurrentObject->oDrawingDistance * draw_distance_scalar()) { + if (draw_distance_scalar_is_infinite() || + marioDist < gCurrentObject->oDrawingDistance * draw_distance_scalar() + ) { gCurrentObject->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE; } else { gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE; diff --git a/src/game/behaviors/king_bobomb.inc.c b/src/game/behaviors/king_bobomb.inc.c index 80945aca1..0ff0d7b56 100644 --- a/src/game/behaviors/king_bobomb.inc.c +++ b/src/game/behaviors/king_bobomb.inc.c @@ -230,7 +230,7 @@ void king_bobomb_act_7(void) { void king_bobomb_act_8(void) { if (!(o->header.gfx.node.flags & GRAPH_RENDER_INVISIBLE)) { struct Object *star = NULL; - + create_sound_spawner(SOUND_OBJ_KING_WHOMP_DEATH); cur_obj_hide(); cur_obj_become_intangible(); @@ -367,6 +367,10 @@ void king_bobomb_move(void) { cur_obj_move_using_fvel_and_gravity(); CUR_OBJ_CALL_ACTION_FUNCTION(sKingBobombActions); exec_anim_sound_state(sKingBobombSoundStates, sizeof(sKingBobombSoundStates) / sizeof(struct SoundState)); + if (draw_distance_scalar_is_infinite()) { + cur_obj_enable_rendering(); + return; + } s32 distanceToPlayer = dist_between_objects(o, gMarioStates[0].marioObj); if (distanceToPlayer < 5000.0f * draw_distance_scalar()) cur_obj_enable_rendering(); diff --git a/src/game/behaviors/piranha_plant.inc.c b/src/game/behaviors/piranha_plant.inc.c index 628bfcb01..f986c4eb4 100644 --- a/src/game/behaviors/piranha_plant.inc.c +++ b/src/game/behaviors/piranha_plant.inc.c @@ -375,12 +375,16 @@ void bhv_piranha_plant_loop(void) { CUR_OBJ_CALL_ACTION_FUNCTION(TablePiranhaPlantActions); // In WF, hide all Piranha Plants once high enough up. if (gCurrLevelNum == LEVEL_WF) { - struct Object* player = gMarioStates[0].marioObj; - f32 scalar = max(draw_distance_scalar(), 1.0f); - if (player->oPosY > 3400.0f * scalar) - cur_obj_hide(); - else + if (draw_distance_scalar_is_infinite()) { cur_obj_unhide(); + } else { + struct Object* player = gMarioStates[0].marioObj; + f32 scalar = max(draw_distance_scalar(), 1.0f); + if (player->oPosY > 3400.0f * scalar) + cur_obj_hide(); + else + cur_obj_unhide(); + } } o->oInteractStatus = 0; } diff --git a/src/game/behaviors/whirlpool.inc.c b/src/game/behaviors/whirlpool.inc.c index a5646f0c1..7034e4f0f 100644 --- a/src/game/behaviors/whirlpool.inc.c +++ b/src/game/behaviors/whirlpool.inc.c @@ -44,11 +44,15 @@ void bhv_whirlpool_loop(void) { o->oWhirlpoolTimeout = 30; } - f32 marioDist = dist_between_objects(o, gMarioStates[0].marioObj); - if (marioDist < 5000.0f * draw_distance_scalar()) { + if (draw_distance_scalar_is_infinite()) { o->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE; } else { - o->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE; + f32 marioDist = dist_between_objects(o, gMarioStates[0].marioObj); + if (marioDist < 5000.0f * draw_distance_scalar()) { + o->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE; + } else { + o->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE; + } } // not sure if actually an array diff --git a/src/game/obj_behaviors.c b/src/game/obj_behaviors.c index fc38d0a15..26b04be76 100644 --- a/src/game/obj_behaviors.c +++ b/src/game/obj_behaviors.c @@ -701,6 +701,10 @@ s8 is_point_close_to_object(struct Object *obj, f32 x, f32 y, f32 z, s32 dist) { /* |description|Sets an object as visible if within a certain distance of Mario's graphical position|descriptionEnd| */ void set_object_visibility(struct Object *obj, s32 dist) { if (!obj) { return; } + if (draw_distance_scalar_is_infinite()) { + obj->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE; + return; + } s32 distanceToPlayer = dist_between_objects(obj, gMarioStates[0].marioObj); if (distanceToPlayer < dist * draw_distance_scalar()) { obj->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE; diff --git a/src/game/object_helpers.c b/src/game/object_helpers.c index 3d600d10d..8705b804a 100644 --- a/src/game/object_helpers.c +++ b/src/game/object_helpers.c @@ -3010,7 +3010,9 @@ void cur_obj_if_hit_wall_bounce_away(void) { s32 cur_obj_hide_if_mario_far_away_y(f32 distY) { if (!o) { return 0; } if (!gMarioStates[0].marioObj) { return FALSE; } - if (absf(o->oPosY - gMarioStates[0].marioObj->oPosY) < distY * draw_distance_scalar()) { + if (draw_distance_scalar_is_infinite() || + absf(o->oPosY - gMarioStates[0].marioObj->oPosY) < distY * draw_distance_scalar() + ) { cur_obj_unhide(); return FALSE; } diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c index 07089fea5..82d0da8f7 100644 --- a/src/game/rendering_graph_node.c +++ b/src/game/rendering_graph_node.c @@ -50,6 +50,8 @@ #define DISPLAY_LIST_HEAP_SIZE 32000 +#define MAX_FAR_PLANE_DIST 1000000.f + f32 gProjectionMaxNearValue = 5; s16 gProjectionVanillaNearValue = 100; s16 gProjectionVanillaFarValue = 1000; @@ -310,6 +312,10 @@ void patch_mtx_interpolated(f32 delta) { f32 fovInterpolated = delta_interpolate_f32(sPerspectiveNode->prevFov, sPerspectiveNode->fov, delta); f32 near = get_first_person_enabled() ? 1.f : replace_value_if_not_zero(MIN(sPerspectiveNode->near, gProjectionMaxNearValue), gOverrideNear); f32 far = replace_value_if_not_zero(sPerspectiveNode->far, gOverrideFar); + + // "infinite" draw distance + if (gOverrideFar == 0 && configDrawDistance == 6) { far = max(far, MAX_FAR_PLANE_DIST); } + guPerspective(sPerspectiveMtx, &perspNorm, fovInterpolated, sPerspectiveAspect, near, far, 1.0f); gSPMatrix(sPerspectivePos, VIRTUAL_TO_PHYSICAL(sPerspectiveNode), G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH); } @@ -650,6 +656,10 @@ static void geo_process_perspective(struct GraphNodePerspective *node) { gProjectionVanillaFarValue = node->far; f32 near = get_first_person_enabled() ? 1.f : replace_value_if_not_zero(MIN(node->near, gProjectionMaxNearValue), gOverrideNear); f32 far = replace_value_if_not_zero(node->far, gOverrideFar); + + // "infinite" draw distance + if (gOverrideFar == 0 && configDrawDistance == 6) { far = max(far, MAX_FAR_PLANE_DIST); } + guPerspective(mtx, &perspNorm, node->prevFov, aspect, near, far, 1.0f); sPerspectiveNode = node; @@ -1139,7 +1149,7 @@ static void anim_process(Vec3f translation, Vec3s rotation, Vec3f scale, u8 *ani scale[2] *= ((f32) scaleZ) / 256.0f; } } - + if (gCurAnim->flags & ANIM_FLAG_BONE_TRANS) { *animType = ANIM_TYPE_TRANSLATION; } @@ -1459,7 +1469,7 @@ static s32 obj_is_in_view(struct GraphNodeObject *node, Mat4 matrix) { // makes PU travel safe when the camera is locked on the main map. // If Mario were rendered with a depth over 65536 it would cause overflow // when converting the transformation matrix to a fixed point matrix. - if (matrix[3][2] < -20000.0f - cullingRadius) { + if (configDrawDistance != 6 && matrix[3][2] < -20000.0f - cullingRadius) { return FALSE; } diff --git a/src/pc/configfile.c b/src/pc/configfile.c index 8873966f7..7f210a52c 100644 --- a/src/pc/configfile.c +++ b/src/pc/configfile.c @@ -89,7 +89,7 @@ bool configShowPing = false; enum RefreshRateMode configFramerateMode = RRM_AUTO; unsigned int configFrameLimit = 60; unsigned int configInterpolationMode = 1; -unsigned int configDrawDistance = 4; +unsigned int configDrawDistance = 6; // sound settings unsigned int configMasterVolume = 80; // 0 - MAX_VOLUME unsigned int configMusicVolume = MAX_VOLUME; diff --git a/src/pc/djui/djui_panel_display.c b/src/pc/djui/djui_panel_display.c index fccf76752..d12e0f3ba 100644 --- a/src/pc/djui/djui_panel_display.c +++ b/src/pc/djui/djui_panel_display.c @@ -129,8 +129,16 @@ void djui_panel_display_create(struct DjuiBase* caller) { djui_selectionbox_create(body, DLANG(DISPLAY, ANTIALIASING), msaaChoices, choiceCount, &sMsaaSelection, djui_panel_display_msaa_change); } - char* drawDistanceChoices[6] = { DLANG(DISPLAY, D0P5X), DLANG(DISPLAY, D1X), DLANG(DISPLAY, D1P5X), DLANG(DISPLAY, D3X), DLANG(DISPLAY, D10X), DLANG(DISPLAY, D100X) }; - djui_selectionbox_create(body, DLANG(DISPLAY, DRAW_DISTANCE), drawDistanceChoices, 6, &configDrawDistance, NULL); + char* drawDistanceChoices[] = { + DLANG(DISPLAY, D0P5X), + DLANG(DISPLAY, D1X), + DLANG(DISPLAY, D1P5X), + DLANG(DISPLAY, D3X), + DLANG(DISPLAY, D10X), + DLANG(DISPLAY, D100X), + DLANG(DISPLAY, INFINITE), + }; + djui_selectionbox_create(body, DLANG(DISPLAY, DRAW_DISTANCE), drawDistanceChoices, ARRAY_COUNT(drawDistanceChoices), &configDrawDistance, NULL); djui_button_create(body, DLANG(MENU, BACK), DJUI_BUTTON_STYLE_BACK, djui_panel_menu_back); diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index 86c6d90df..b0c76d8e3 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -9889,6 +9889,21 @@ int smlua_func_position_based_random_float_position(UNUSED lua_State* L) { return 1; } +int smlua_func_draw_distance_scalar_is_infinite(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", "draw_distance_scalar_is_infinite", 0, top); + return 0; + } + + + lua_pushboolean(L, draw_distance_scalar_is_infinite()); + + return 1; +} + int smlua_func_draw_distance_scalar(UNUSED lua_State* L) { if (L == NULL) { return 0; } @@ -37695,6 +37710,7 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "obj_update_gfx_pos_and_angle", smlua_func_obj_update_gfx_pos_and_angle); smlua_bind_function(L, "position_based_random_u16", smlua_func_position_based_random_u16); smlua_bind_function(L, "position_based_random_float_position", smlua_func_position_based_random_float_position); + smlua_bind_function(L, "draw_distance_scalar_is_infinite", smlua_func_draw_distance_scalar_is_infinite); smlua_bind_function(L, "draw_distance_scalar", smlua_func_draw_distance_scalar); // behavior_table.h