diff --git a/enhancements/no_draw_distance/README.md b/enhancements/no_draw_distance/README.md new file mode 100644 index 00000000..dd890383 --- /dev/null +++ b/enhancements/no_draw_distance/README.md @@ -0,0 +1,10 @@ +# No Draw Distances + +This is a work-in-progress by [wabberz](https://github.com/wabberz) that disables the drawing distance for most objects and enemies. + +**This will crash some levels in the 32-bit version**. + +[Related Push Request](https://github.com/sm64pc/sm64pc/pull/75). + +For instructions on how to apply patches, please refer to [the Wiki](https://github.com/sm64pc/sm64pc/wiki/Patches). + diff --git a/enhancements/no_draw_distance/nodrawdistance.patch b/enhancements/no_draw_distance/nodrawdistance.patch new file mode 100644 index 00000000..b986b1a6 --- /dev/null +++ b/enhancements/no_draw_distance/nodrawdistance.patch @@ -0,0 +1,406 @@ +From c98a263cf40520bf0d131eb2d1a2f90240787c98 Mon Sep 17 00:00:00 2001 +From: uwabami +Date: Tue, 12 May 2020 09:26:16 +0200 +Subject: [PATCH] adding option to disable draw distance + +--- + Makefile | 8 ++++++++ + src/engine/behavior_script.c | 4 ++++ + src/engine/surface_load.c | 4 ++++ + src/game/behaviors/butterfly.inc.c | 3 ++- + src/game/behaviors/chain_chomp.inc.c | 8 ++++++++ + src/game/behaviors/coin.inc.c | 6 ++++++ + src/game/behaviors/fish.inc.c | 4 ++++ + src/game/behaviors/goomba.inc.c | 4 ++++ + src/game/behaviors/heave_ho.inc.c | 4 ++++ + src/game/behaviors/king_bobomb.inc.c | 4 ++++ + src/game/behaviors/pokey.inc.c | 6 ++++++ + src/game/behaviors/snufit.inc.c | 4 ++++ + src/game/behaviors/triplet_butterfly.inc.c | 4 ++++ + src/game/behaviors/water_bomb_cannon.inc.c | 8 ++++++++ + src/game/behaviors/whirlpool.inc.c | 4 ++++ + 15 files changed, 74 insertions(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index d4bd284..efeb63e 100644 +--- a/Makefile ++++ b/Makefile +@@ -27,6 +27,8 @@ COMPILER ?= ido + + # Disable better camera by default + BETTERCAMERA ?= 0 ++# Disable no drawing distance by default ++NODRAWINGDISTANCE ?= 0 + + # Build for Emscripten/WebGL + TARGET_WEB ?= 0 +@@ -449,6 +451,12 @@ CC_CHECK += -DBETTERCAMERA + CFLAGS += -DBETTERCAMERA + endif + ++# Check for no drawing distance option ++ifeq ($(NODRAWINGDISTANCE),1) ++CC_CHECK += -DNODRAWINGDISTANCE ++CFLAGS += -DNODRAWINGDISTANCE ++endif ++ + ASFLAGS := -I include -I $(BUILD_DIR) $(VERSION_ASFLAGS) + + ifeq ($(TARGET_WEB),1) +diff --git a/src/engine/behavior_script.c b/src/engine/behavior_script.c +index edd5247..feb6fef 100644 +--- a/src/engine/behavior_script.c ++++ b/src/engine/behavior_script.c +@@ -987,11 +987,15 @@ void cur_obj_update(void) { + } 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. ++#ifndef NODRAWINGDISTANCE + if (distanceFromMario > gCurrentObject->oDrawingDistance) { + // Out of render distance, hide the object. + gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE; + gCurrentObject->activeFlags |= ACTIVE_FLAG_FAR_AWAY; + } else if (gCurrentObject->oHeldState == HELD_FREE) { ++#else ++ if (distanceFromMario <= gCurrentObject->oDrawingDistance && gCurrentObject->oHeldState == HELD_FREE) { ++#endif + // In render distance (and not being held), show the object. + gCurrentObject->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE; + gCurrentObject->activeFlags &= ~ACTIVE_FLAG_FAR_AWAY; +diff --git a/src/engine/surface_load.c b/src/engine/surface_load.c +index 363f9af..498fae0 100644 +--- a/src/engine/surface_load.c ++++ b/src/engine/surface_load.c +@@ -789,9 +789,13 @@ void load_object_collision_model(void) { + } + } + ++#ifndef NODRAWINGDISTANCE + if (marioDist < gCurrentObject->oDrawingDistance) { ++#endif + gCurrentObject->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE; ++#ifndef NODRAWINGDISTANCE + } else { + gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE; + } ++#endif + } +diff --git a/src/game/behaviors/butterfly.inc.c b/src/game/behaviors/butterfly.inc.c +index d435d8d..9296ed5 100644 +--- a/src/game/behaviors/butterfly.inc.c ++++ b/src/game/behaviors/butterfly.inc.c +@@ -107,6 +107,7 @@ void bhv_butterfly_loop(void) { + butterfly_act_return_home(); + break; + } +- ++#ifndef NODRAWINGDISTANCE + set_object_visibility(o, 3000); ++#endif + } +diff --git a/src/game/behaviors/chain_chomp.inc.c b/src/game/behaviors/chain_chomp.inc.c +index a77c5d5..9b9c342 100644 +--- a/src/game/behaviors/chain_chomp.inc.c ++++ b/src/game/behaviors/chain_chomp.inc.c +@@ -53,7 +53,9 @@ static void chain_chomp_act_uninitialized(void) { + struct ChainSegment *segments; + s32 i; + ++#ifndef NODRAWINGDISTANCE + if (o->oDistanceToMario < 3000.0f) { ++#endif + segments = mem_pool_alloc(gObjectMemoryPool, 5 * sizeof(struct ChainSegment)); + if (segments != NULL) { + // Each segment represents the offset of a chain part to the pivot. +@@ -81,7 +83,9 @@ static void chain_chomp_act_uninitialized(void) { + cur_obj_unhide(); + } + } ++#ifndef NODRAWINGDISTANCE + } ++#endif + } + + /** +@@ -359,10 +363,12 @@ static void chain_chomp_act_move(void) { + f32 maxDistToPivot; + + // Unload chain if mario is far enough ++#ifndef NODRAWINGDISTANCE + if (o->oChainChompReleaseStatus == CHAIN_CHOMP_NOT_RELEASED && o->oDistanceToMario > 4000.0f) { + o->oAction = CHAIN_CHOMP_ACT_UNLOAD_CHAIN; + o->oForwardVel = o->oVelY = 0.0f; + } else { ++#endif + cur_obj_update_floor_and_walls(); + + switch (o->oChainChompReleaseStatus) { +@@ -446,7 +452,9 @@ static void chain_chomp_act_move(void) { + o->oGravity = -4.0f; + o->oChainChompTargetPitch = -0x3000; + } ++#ifndef NODRAWINGDISTANCE + } ++#endif + } + + /** +diff --git a/src/game/behaviors/coin.inc.c b/src/game/behaviors/coin.inc.c +index 913c583..05619b9 100644 +--- a/src/game/behaviors/coin.inc.c ++++ b/src/game/behaviors/coin.inc.c +@@ -184,17 +184,23 @@ void bhv_coin_formation_loop(void) { + s32 bitIndex; + switch (o->oAction) { + case 0: ++#ifndef NODRAWINGDISTANCE + if (o->oDistanceToMario < 2000.0f) { ++#endif + for (bitIndex = 0; bitIndex < 8; bitIndex++) { + if (!(o->oCoinUnkF4 & (1 << bitIndex))) + spawn_coin_in_formation(bitIndex, o->oBehParams2ndByte); + } + o->oAction++; ++#ifndef NODRAWINGDISTANCE + } ++#endif + break; + case 1: ++#ifndef NODRAWINGDISTANCE + if (o->oDistanceToMario > 2100.0f) + o->oAction++; ++#endif + break; + case 2: + o->oAction = 0; +diff --git a/src/game/behaviors/fish.inc.c b/src/game/behaviors/fish.inc.c +index 839ab8d..f652ef4 100644 +--- a/src/game/behaviors/fish.inc.c ++++ b/src/game/behaviors/fish.inc.c +@@ -42,7 +42,9 @@ void fish_act_spawn(void) { + * If the current level is Secret Aquarium, ignore this requirement. + * Fish moves at random with a max-range of 700.0f. + */ ++#ifndef NODRAWINGDISTANCE + if (o->oDistanceToMario < minDistToMario || gCurrLevelNum == LEVEL_SA) { ++#endif + for (i = 0; i < schoolQuantity; i++) { + fishObject = spawn_object(o, model, bhvFish); + fishObject->oBehParams2ndByte = o->oBehParams2ndByte; +@@ -50,7 +52,9 @@ void fish_act_spawn(void) { + obj_translate_xyz_random(fishObject, 700.0f); + } + o->oAction = FISH_ACT_ACTIVE; ++#ifndef NODRAWINGDISTANCE + } ++#endif + } + + /** +diff --git a/src/game/behaviors/goomba.inc.c b/src/game/behaviors/goomba.inc.c +index 2dab2fe..bf47dda 100644 +--- a/src/game/behaviors/goomba.inc.c ++++ b/src/game/behaviors/goomba.inc.c +@@ -78,7 +78,9 @@ void bhv_goomba_triplet_spawner_update(void) { + // If mario is close enough and the goombas aren't currently loaded, then + // spawn them + if (o->oAction == GOOMBA_TRIPLET_SPAWNER_ACT_UNLOADED) { ++#ifndef NODRAWINGDISTANCE + if (o->oDistanceToMario < 3000.0f) { ++#endif + // The spawner is capable of spawning more than 3 goombas, but this + // is not used in the game + dAngle = +@@ -98,11 +100,13 @@ void bhv_goomba_triplet_spawner_update(void) { + } + + o->oAction += 1; ++#ifndef NODRAWINGDISTANCE + } + } else if (o->oDistanceToMario > 4000.0f) { + // If mario is too far away, enter the unloaded action. The goombas + // will detect this and unload themselves + o->oAction = GOOMBA_TRIPLET_SPAWNER_ACT_UNLOADED; ++#endif + } + } + +diff --git a/src/game/behaviors/heave_ho.inc.c b/src/game/behaviors/heave_ho.inc.c +index 662bb0b..2f9da86 100644 +--- a/src/game/behaviors/heave_ho.inc.c ++++ b/src/game/behaviors/heave_ho.inc.c +@@ -73,14 +73,18 @@ void heave_ho_act_3(void) { + + void heave_ho_act_0(void) { + cur_obj_set_pos_to_home(); ++#ifndef NODRAWINGDISTANCE + if (find_water_level(o->oPosX, o->oPosZ) < o->oPosY && o->oDistanceToMario < 4000.0f) { ++#endif + cur_obj_become_tangible(); + cur_obj_unhide(); + o->oAction = 1; ++#ifndef NODRAWINGDISTANCE + } else { + cur_obj_become_intangible(); + cur_obj_hide(); + } ++#endif + } + + void (*sHeaveHoActions[])(void) = { heave_ho_act_0, heave_ho_act_1, heave_ho_act_2, heave_ho_act_3 }; +diff --git a/src/game/behaviors/king_bobomb.inc.c b/src/game/behaviors/king_bobomb.inc.c +index 63a7575..af1cb0a 100644 +--- a/src/game/behaviors/king_bobomb.inc.c ++++ b/src/game/behaviors/king_bobomb.inc.c +@@ -295,10 +295,14 @@ void king_bobomb_move(void) { + cur_obj_move_using_fvel_and_gravity(); + cur_obj_call_action_function(sKingBobombActions); + exec_anim_sound_state(sKingBobombSoundStates); ++#ifndef NODRAWINGDISTANCE + if (o->oDistanceToMario < 5000.0f) ++#endif + cur_obj_enable_rendering(); ++#ifndef NODRAWINGDISTANCE + else + cur_obj_disable_rendering(); ++#endif + } + + void bhv_king_bobomb_loop(void) { +diff --git a/src/game/behaviors/pokey.inc.c b/src/game/behaviors/pokey.inc.c +index df5d11f..cfcc92c 100644 +--- a/src/game/behaviors/pokey.inc.c ++++ b/src/game/behaviors/pokey.inc.c +@@ -151,7 +151,9 @@ static void pokey_act_uninitialized(void) { + s32 i; + s16 partModel; + ++#ifndef NODRAWINGDISTANCE + if (o->oDistanceToMario < 2000.0f) { ++#endif + partModel = MODEL_POKEY_HEAD; + + for (i = 0; i < 5; i++) { +@@ -170,7 +172,9 @@ static void pokey_act_uninitialized(void) { + o->oPokeyNumAliveBodyParts = 5; + o->oPokeyBottomBodyPartSize = 1.0f; + o->oAction = POKEY_ACT_WANDER; ++#ifndef NODRAWINGDISTANCE + } ++#endif + } + + /** +@@ -185,9 +189,11 @@ static void pokey_act_wander(void) { + + if (o->oPokeyNumAliveBodyParts == 0) { + obj_mark_for_deletion(o); ++#ifndef NODRAWINGDISTANCE + } else if (o->oDistanceToMario > 2500.0f) { + o->oAction = POKEY_ACT_UNLOAD_PARTS; + o->oForwardVel = 0.0f; ++#endif + } else { + treat_far_home_as_mario(1000.0f); + cur_obj_update_floor_and_walls(); +diff --git a/src/game/behaviors/snufit.inc.c b/src/game/behaviors/snufit.inc.c +index f3a0c9e..76e78c0 100644 +--- a/src/game/behaviors/snufit.inc.c ++++ b/src/game/behaviors/snufit.inc.c +@@ -180,7 +180,11 @@ void bhv_snufit_loop(void) { + void bhv_snufit_balls_loop(void) { + // If far from Mario or in a different room, despawn. + if ((o->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM) ++#ifndef NODRAWINGDISTANCE + || (o->oTimer != 0 && o->oDistanceToMario > 1500.0f)) { ++#else ++ || (o->oTimer != 0)) { ++#endif + obj_mark_for_deletion(o); + } + +diff --git a/src/game/behaviors/triplet_butterfly.inc.c b/src/game/behaviors/triplet_butterfly.inc.c +index 1c2b926..3d16a9d 100644 +--- a/src/game/behaviors/triplet_butterfly.inc.c ++++ b/src/game/behaviors/triplet_butterfly.inc.c +@@ -54,9 +54,11 @@ static void triplet_butterfly_act_init(void) { + } + + static void triplet_butterfly_act_wander(void) { ++#ifndef NODRAWINGDISTANCE + if (o->oDistanceToMario > 1500.0f) { + obj_mark_for_deletion(o); + } else { ++#endif + approach_f32_ptr(&o->oTripletButterflySpeed, 8.0f, 0.5f); + if (o->oTimer < 60) { + o->oTripletButterflyTargetYaw = cur_obj_angle_to_home(); +@@ -82,7 +84,9 @@ static void triplet_butterfly_act_wander(void) { + + obj_move_pitch_approach(o->oTripletButterflyTargetPitch, 400); + cur_obj_rotate_yaw_toward(o->oTripletButterflyTargetYaw, random_linear_offset(400, 800)); ++#ifndef NODRAWINGDISTANCE + } ++#endif + } + + static void triplet_butterfly_act_activate(void) { +diff --git a/src/game/behaviors/water_bomb_cannon.inc.c b/src/game/behaviors/water_bomb_cannon.inc.c +index 8e9ba33..fb82e43 100644 +--- a/src/game/behaviors/water_bomb_cannon.inc.c ++++ b/src/game/behaviors/water_bomb_cannon.inc.c +@@ -38,19 +38,27 @@ void bhv_bubble_cannon_barrel_loop(void) { + } + + void water_bomb_cannon_act_0(void) { ++#ifndef NODRAWINGDISTANCE + if (o->oDistanceToMario < 2000.0f) { ++#endif + spawn_object(o, MODEL_CANNON_BARREL, bhvCannonBarrelBubbles); + cur_obj_unhide(); + + o->oAction = 1; + o->oMoveAnglePitch = o->oWaterCannonUnkFC = 0x1C00; ++#ifndef NODRAWINGDISTANCE + } ++#endif + } + + void water_bomb_cannon_act_1(void) { ++#ifndef NODRAWINGDISTANCE + if (o->oDistanceToMario > 2500.0f) { + o->oAction = 2; + } else if (o->oBehParams2ndByte == 0) { ++#else ++ if (o->oBehParams2ndByte == 0) { ++#endif + if (o->oWaterCannonUnkF4 != 0) { + o->oWaterCannonUnkF4 -= 1; + } else { +diff --git a/src/game/behaviors/whirlpool.inc.c b/src/game/behaviors/whirlpool.inc.c +index 405e051..5aebebd 100644 +--- a/src/game/behaviors/whirlpool.inc.c ++++ b/src/game/behaviors/whirlpool.inc.c +@@ -35,7 +35,9 @@ void whirpool_orient_graph(void) { + } + + void bhv_whirlpool_loop(void) { ++#ifndef NODRAWINGDISTANCE + if (o->oDistanceToMario < 5000.0f) { ++#endif + o->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE; + + // not sure if actually an array +@@ -52,10 +54,12 @@ void bhv_whirlpool_loop(void) { + whirpool_orient_graph(); + + o->oFaceAngleYaw += 0x1F40; ++#ifndef NODRAWINGDISTANCE + } else { + o->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE; + gEnvFxBubbleConfig[ENVFX_STATE_PARTICLECOUNT] = 0; + } ++#endif + + cur_obj_play_sound_1(SOUND_ENV_WATER); +