From be79ded91e386cf1117f5934f343bd1ca36aa464 Mon Sep 17 00:00:00 2001 From: Fazana <52551480+FazanaJ@users.noreply.github.com> Date: Thu, 30 Sep 2021 10:31:31 +0100 Subject: [PATCH 1/5] Fix build error with debug_box.c --- src/game/debug_box.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/game/debug_box.c b/src/game/debug_box.c index cc014e1e..cff86906 100644 --- a/src/game/debug_box.c +++ b/src/game/debug_box.c @@ -210,7 +210,6 @@ extern s32 gSurfacesAllocated; void iterate_surfaces_visual(s32 x, s32 z, Vtx *verts) { struct SurfaceNode *node; struct Surface *surf; - s32 cellX, cellZ; s32 i = 0; s32 col[3] = {0xFF, 0x00, 0x00}; @@ -337,7 +336,6 @@ void visual_surface_display(Vtx *verts, s32 iteration) s32 iterate_surface_count(s32 x, s32 z) { struct SurfaceNode *node; - s32 cellX, cellZ; s32 i = 0; s32 j = 0; TerrainData *p = gEnvironmentRegions; @@ -350,8 +348,8 @@ s32 iterate_surface_count(s32 x, s32 z) return 0; } - cellX = GET_CELL_COORD(x); - cellZ = GET_CELL_COORD(z); + s32 cellX = GET_CELL_COORD(x); + s32 cellZ = GET_CELL_COORD(z); for (i = 0; i < 8; i++) { From 4448273b149d1b99db44315076e48068e10a6f2f Mon Sep 17 00:00:00 2001 From: Fazana <52551480+FazanaJ@users.noreply.github.com> Date: Thu, 30 Sep 2021 10:40:37 +0100 Subject: [PATCH 2/5] Move raycasts back to math_util --- src/engine/math_util.c | 162 ++++++++++++++++++++++++++++++++ src/engine/math_util.h | 1 + src/engine/surface_collision.c | 163 --------------------------------- src/engine/surface_collision.h | 1 - 4 files changed, 163 insertions(+), 164 deletions(-) diff --git a/src/engine/math_util.c b/src/engine/math_util.c index a8fc7189..4670ffcc 100644 --- a/src/engine/math_util.c +++ b/src/engine/math_util.c @@ -1116,3 +1116,165 @@ s32 anim_spline_poll(Vec3f result) { return hasEnded; } + +/************************************************** + * RAYCASTING * + **************************************************/ + +#define RAY_OFFSET 30.0f /*How many units to extrapolate surfaces when testing for a raycast*/ +#define RAY_STEPS 4 /*How many steps to do when casting rays, default to quartersteps.*/ + +s32 ray_surface_intersect(Vec3f orig, Vec3f dir, f32 dir_length, struct Surface *surface, Vec3f hit_pos, f32 *length) { + Vec3f v0, v1, v2, e1, e2, h, s, q; + f32 a, f, u, v; + Vec3f add_dir; + Vec3f norm; + // Ignore certain surface types. + if (surface->type == SURFACE_INTANGIBLE || surface->flags & SURFACE_FLAG_NO_CAM_COLLISION) return FALSE; + // Get surface normal and some other stuff + vec3_set(norm, 0, surface->normal.y, 0); + vec3_mul_val(norm, RAY_OFFSET); + vec3_copy(v0, surface->vertex1); + vec3_copy(v1, surface->vertex2); + vec3_copy(v2, surface->vertex3); + vec3_add( v0, norm); + vec3_add( v1, norm); + vec3_add( v2, norm); + vec3_diff(e1, v1, v0); + vec3_diff(e2, v2, v0); + vec3_cross(h, dir, e2); + // Check if we're perpendicular from the surface + a = vec3_dot(e1, h); + if ((a > -NEAR_ZERO) && (a < NEAR_ZERO)) return FALSE; + // Check if we're making contact with the surface + f = 1.0f / a; + vec3_diff(s, orig, v0); + u = f * vec3_dot(s, h); + if ((u < 0.0f) || (u > 1.0f)) return FALSE; + vec3_cross(q, s, e1); + v = f * vec3_dot(dir, q); + if ((v < 0.0f) || ((u + v) > 1.0f)) return FALSE; + // Get the length between our origin and the surface contact point + *length = f * vec3_dot(e2, q); + if (*length <= 0.00001 || *length > dir_length) return FALSE; + // Successful contact + vec3f_copy(add_dir, dir); + vec3_mul_val(add_dir, *length); + vec3_sum(hit_pos, orig, add_dir); + return TRUE; +} + +void find_surface_on_ray_list(struct SurfaceNode *list, Vec3f orig, Vec3f dir, f32 dir_length, struct Surface **hit_surface, Vec3f hit_pos, f32 *max_length) { + s32 hit; + f32 length; + Vec3f chk_hit_pos; + f32 top, bottom; + #if PUPPYPRINT_DEBUG + OSTime first = osGetTime(); + #endif + + // Get upper and lower bounds of ray + if (dir[1] >= 0.0f) { + top = (orig[1] + (dir[1] * dir_length)); + bottom = orig[1]; + } else { + top = orig[1]; + bottom = (orig[1] + (dir[1] * dir_length)); + } + + // Iterate through every surface of the list + for (; list != NULL; list = list->next) { + // Reject surface if out of vertical bounds + if (list->surface->lowerY > top || list->surface->upperY < bottom) continue; + // Check intersection between the ray and this surface + if ((hit = ray_surface_intersect(orig, dir, dir_length, list->surface, chk_hit_pos, &length)) && (length <= *max_length)) { + *hit_surface = list->surface; + vec3f_copy(hit_pos, chk_hit_pos); + *max_length = length; + } + } +#if PUPPYPRINT_DEBUG + collisionTime[perfIteration] += (osGetTime() - first); +#endif +} + +void find_surface_on_ray_cell(s32 cellX, s32 cellZ, Vec3f orig, Vec3f normalized_dir, f32 dir_length, struct Surface **hit_surface, Vec3f hit_pos, f32 *max_length, s32 flags) { + // Skip if OOB + if (cellX >= 0 && cellX <= (NUM_CELLS - 1) && cellZ >= 0 && cellZ <= (NUM_CELLS - 1)) { + // Iterate through each surface in this partition + if ((normalized_dir[1] > -NEAR_ONE) && (flags & RAYCAST_FIND_CEIL)) { + find_surface_on_ray_list(gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length); + find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length); + } + if ((normalized_dir[1] < NEAR_ONE) && (flags & RAYCAST_FIND_FLOOR)) { + find_surface_on_ray_list(gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length); + find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length); + } + if (flags & RAYCAST_FIND_WALL) { + find_surface_on_ray_list(gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length); + find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length); + } + if (flags & RAYCAST_FIND_WATER) { + find_surface_on_ray_list(gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WATER].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length); + find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WATER].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length); + } + } +} + +void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Vec3f hit_pos, s32 flags) { + s32 cellZ, cellX, cellPrevX, cellPrevZ; + f32 fCellZ, fCellX; + Vec3f normalized_dir; + f32 step; + s32 i; + + // Set that no surface has been hit + *hit_surface = NULL; + vec3_sum(hit_pos, orig, dir); + + // Get normalized direction + f32 dir_length = vec3_mag(dir); + f32 max_length = dir_length; + vec3f_copy(normalized_dir, dir); + vec3f_normalize(normalized_dir); + + // Get our cell coordinate + fCellX = (orig[0] + LEVEL_BOUNDARY_MAX) / CELL_SIZE; + fCellZ = (orig[2] + LEVEL_BOUNDARY_MAX) / CELL_SIZE; + cellX = fCellX; + cellZ = fCellZ; + cellPrevX = cellX; + cellPrevZ = cellZ; + + // Don't do DDA if straight down + if (normalized_dir[1] >= 0.99999f || normalized_dir[1] <= -0.99999f) { + find_surface_on_ray_cell(cellX, cellZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length, flags); + return; + } + + // Get cells we cross using DDA + if (ABS(dir[0]) >= ABS(dir[2])) { + step = RAY_STEPS * ABS(dir[0]) / CELL_SIZE; + } else { + step = RAY_STEPS * ABS(dir[2]) / CELL_SIZE; + } + f32 dx = dir[0] / step / CELL_SIZE; + f32 dz = dir[2] / step / CELL_SIZE; + + for (i = 0; i < step && *hit_surface == NULL; i++) { + find_surface_on_ray_cell(cellX, cellZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length, flags); + + // Move cell coordinate + fCellX += dx; + fCellZ += dz; + cellPrevX = cellX; + cellPrevZ = cellZ; + cellX = fCellX; + cellZ = fCellZ; + + if ((cellPrevX != cellX) && (cellPrevZ != cellZ)) { + find_surface_on_ray_cell(cellX, cellPrevZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length, flags); + find_surface_on_ray_cell(cellPrevX, cellZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length, flags); + } + } +} diff --git a/src/engine/math_util.h b/src/engine/math_util.h index c43ea5ce..5098ee3a 100644 --- a/src/engine/math_util.h +++ b/src/engine/math_util.h @@ -530,5 +530,6 @@ void spline_get_weights(Vec4f result, f32 t, UNUSED s32 c); void anim_spline_init(Vec4s *keyFrames); s32 anim_spline_poll(Vec3f result); void mtxf_rot_trans_mul(Vec3s rot, Vec3f trans, Mat4 dest, Mat4 src); +void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Vec3f hit_pos, s32 flags); #endif // MATH_UTIL_H diff --git a/src/engine/surface_collision.c b/src/engine/surface_collision.c index c86a39cb..11524535 100644 --- a/src/engine/surface_collision.c +++ b/src/engine/surface_collision.c @@ -832,166 +832,3 @@ s32 unused_resolve_floor_or_ceil_collisions(s32 checkCeil, f32 *px, f32 *py, f32 return 0; } - -/************************************************** - * RAYCASTING * - **************************************************/ - -#define RAY_OFFSET 30.0f /*How many units to extrapolate surfaces when testing for a raycast*/ -#define RAY_STEPS 4 /*How many steps to do when casting rays, default to quartersteps.*/ - -s32 ray_surface_intersect(Vec3f orig, Vec3f dir, f32 dir_length, struct Surface *surface, Vec3f hit_pos, f32 *length) { - Vec3f v0, v1, v2, e1, e2, h, s, q; - f32 a, f, u, v; - Vec3f add_dir; - Vec3f norm; - // Ignore certain surface types. - if (surface->type == SURFACE_INTANGIBLE || surface->flags & SURFACE_FLAG_NO_CAM_COLLISION) return FALSE; - // Get surface normal and some other stuff - vec3_set(norm, 0, surface->normal.y, 0); - vec3_mul_val(norm, RAY_OFFSET); - vec3_copy(v0, surface->vertex1); - vec3_copy(v1, surface->vertex2); - vec3_copy(v2, surface->vertex3); - vec3_add( v0, norm); - vec3_add( v1, norm); - vec3_add( v2, norm); - vec3_diff(e1, v1, v0); - vec3_diff(e2, v2, v0); - vec3_cross(h, dir, e2); - // Check if we're perpendicular from the surface - a = vec3_dot(e1, h); - if ((a > -NEAR_ZERO) && (a < NEAR_ZERO)) return FALSE; - // Check if we're making contact with the surface - f = 1.0f / a; - vec3_diff(s, orig, v0); - u = f * vec3_dot(s, h); - if ((u < 0.0f) || (u > 1.0f)) return FALSE; - vec3_cross(q, s, e1); - v = f * vec3_dot(dir, q); - if ((v < 0.0f) || ((u + v) > 1.0f)) return FALSE; - // Get the length between our origin and the surface contact point - *length = f * vec3_dot(e2, q); - if (*length <= 0.00001 || *length > dir_length) return FALSE; - // Successful contact - vec3f_copy(add_dir, dir); - vec3_mul_val(add_dir, *length); - vec3_sum(hit_pos, orig, add_dir); - return TRUE; -} - -void find_surface_on_ray_list(struct SurfaceNode *list, Vec3f orig, Vec3f dir, f32 dir_length, struct Surface **hit_surface, Vec3f hit_pos, f32 *max_length) { - s32 hit; - f32 length; - Vec3f chk_hit_pos; - f32 top, bottom; - #if PUPPYPRINT_DEBUG - OSTime first = osGetTime(); - #endif - - // Get upper and lower bounds of ray - if (dir[1] >= 0.0f) { - top = (orig[1] + (dir[1] * dir_length)); - bottom = orig[1]; - } else { - top = orig[1]; - bottom = (orig[1] + (dir[1] * dir_length)); - } - - // Iterate through every surface of the list - for (; list != NULL; list = list->next) { - // Reject surface if out of vertical bounds - if (list->surface->lowerY > top || list->surface->upperY < bottom) continue; - // Check intersection between the ray and this surface - if ((hit = ray_surface_intersect(orig, dir, dir_length, list->surface, chk_hit_pos, &length)) && (length <= *max_length)) { - *hit_surface = list->surface; - vec3f_copy(hit_pos, chk_hit_pos); - *max_length = length; - } - } -#if PUPPYPRINT_DEBUG - collisionTime[perfIteration] += (osGetTime() - first); -#endif -} - -void find_surface_on_ray_cell(s32 cellX, s32 cellZ, Vec3f orig, Vec3f normalized_dir, f32 dir_length, struct Surface **hit_surface, Vec3f hit_pos, f32 *max_length, s32 flags) { - // Skip if OOB - if (cellX >= 0 && cellX <= (NUM_CELLS - 1) && cellZ >= 0 && cellZ <= (NUM_CELLS - 1)) { - // Iterate through each surface in this partition - if ((normalized_dir[1] > -NEAR_ONE) && (flags & RAYCAST_FIND_CEIL)) { - find_surface_on_ray_list(gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length); - find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length); - } - if ((normalized_dir[1] < NEAR_ONE) && (flags & RAYCAST_FIND_FLOOR)) { - find_surface_on_ray_list(gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length); - find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length); - } - if (flags & RAYCAST_FIND_WALL) { - find_surface_on_ray_list(gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length); - find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length); - } - if (flags & RAYCAST_FIND_WATER) { - find_surface_on_ray_list(gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WATER].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length); - find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WATER].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length); - } - } -} - -void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Vec3f hit_pos, s32 flags) { - s32 cellZ, cellX, cellPrevX, cellPrevZ; - f32 fCellZ, fCellX; - Vec3f normalized_dir; - f32 step; - s32 i; - - // Set that no surface has been hit - *hit_surface = NULL; - vec3_sum(hit_pos, orig, dir); - - // Get normalized direction - f32 dir_length = vec3_mag(dir); - f32 max_length = dir_length; - vec3f_copy(normalized_dir, dir); - vec3f_normalize(normalized_dir); - - // Get our cell coordinate - fCellX = (orig[0] + LEVEL_BOUNDARY_MAX) / CELL_SIZE; - fCellZ = (orig[2] + LEVEL_BOUNDARY_MAX) / CELL_SIZE; - cellX = fCellX; - cellZ = fCellZ; - cellPrevX = cellX; - cellPrevZ = cellZ; - - // Don't do DDA if straight down - if (normalized_dir[1] >= 0.99999f || normalized_dir[1] <= -0.99999f) { - find_surface_on_ray_cell(cellX, cellZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length, flags); - return; - } - - // Get cells we cross using DDA - if (ABS(dir[0]) >= ABS(dir[2])) { - step = RAY_STEPS * ABS(dir[0]) / CELL_SIZE; - } else { - step = RAY_STEPS * ABS(dir[2]) / CELL_SIZE; - } - f32 dx = dir[0] / step / CELL_SIZE; - f32 dz = dir[2] / step / CELL_SIZE; - - for (i = 0; i < step && *hit_surface == NULL; i++) { - find_surface_on_ray_cell(cellX, cellZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length, flags); - - // Move cell coordinate - fCellX += dx; - fCellZ += dz; - cellPrevX = cellX; - cellPrevZ = cellZ; - cellX = fCellX; - cellZ = fCellZ; - - if ((cellPrevX != cellX) && (cellPrevZ != cellZ)) { - find_surface_on_ray_cell(cellX, cellPrevZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length, flags); - find_surface_on_ray_cell(cellPrevX, cellZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length, flags); - } - } -} - diff --git a/src/engine/surface_collision.h b/src/engine/surface_collision.h index eb174505..81a2a4bf 100644 --- a/src/engine/surface_collision.h +++ b/src/engine/surface_collision.h @@ -46,6 +46,5 @@ s32 find_water_level_and_floor(s32 x, s32 z, struct Surface **pfloor); s32 find_water_level(s32 x, s32 z); s32 find_poison_gas_level(s32 x, s32 z); void debug_surface_list_info(f32 xPos, f32 zPos); -void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Vec3f hit_pos, s32 flags); #endif // SURFACE_COLLISION_H From d79dd5a51f4980fc9bbbb7296c2ba0f2783bdca8 Mon Sep 17 00:00:00 2001 From: Fazana <52551480+FazanaJ@users.noreply.github.com> Date: Thu, 30 Sep 2021 12:17:54 +0100 Subject: [PATCH 3/5] Make collision build with Ofast :pensive: nothing makes sense anymore. --- Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Makefile b/Makefile index 3ed89661..013a24ed 100644 --- a/Makefile +++ b/Makefile @@ -576,9 +576,7 @@ $(BUILD_DIR)/src/usb/usb.o: OPT_FLAGS := -O0 $(BUILD_DIR)/src/usb/usb.o: CFLAGS += -Wno-unused-variable -Wno-sign-compare -Wno-unused-function $(BUILD_DIR)/src/usb/debug.o: OPT_FLAGS := -O0 $(BUILD_DIR)/src/usb/debug.o: CFLAGS += -Wno-unused-parameter -Wno-maybe-uninitialized -$(BUILD_DIR)/src/engine/surface_collision.o: OPT_FLAGS := -Os $(BUILD_DIR)/src/audio/*.o: OPT_FLAGS := -Os -fno-jump-tables -$(BUILD_DIR)/src/game/*.o: OPT_FLAGS := -Ofast ALL_DIRS := $(BUILD_DIR) $(addprefix $(BUILD_DIR)/,$(SRC_DIRS) asm/debug $(GODDARD_SRC_DIRS) $(LIBZ_SRC_DIRS) $(ULTRA_BIN_DIRS) $(BIN_DIRS) $(TEXTURE_DIRS) $(TEXT_DIRS) $(SOUND_SAMPLE_DIRS) $(addprefix levels/,$(LEVEL_DIRS)) rsp include) $(YAY0_DIR) $(addprefix $(YAY0_DIR)/,$(VERSION)) $(SOUND_BIN_DIR) $(SOUND_BIN_DIR)/sequences/$(VERSION) From a8fd8c517211d4554ffd82a371f749a9db6d4e64 Mon Sep 17 00:00:00 2001 From: Fazana <52551480+FazanaJ@users.noreply.github.com> Date: Thu, 30 Sep 2021 15:24:44 +0100 Subject: [PATCH 4/5] fix memory.c and add ucode_small flag --- include/object_constants.h | 1 + src/boot/memory.c | 9 ++++----- src/engine/behavior_script.c | 10 ++++++++++ src/engine/graph_node.h | 1 + 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/include/object_constants.h b/include/object_constants.h index 7b9a3526..8bfe26dc 100644 --- a/include/object_constants.h +++ b/include/object_constants.h @@ -49,6 +49,7 @@ #define OBJ_FLAG_SILHOUETTE (1 << 19) // 0x00080000 #define OBJ_FLAG_OCCLUDE_SILHOUETTE (1 << 20) // 0x00100000 #define OBJ_FLAG_OPACITY_FROM_CAMERA_DIST (1 << 21) // 0x00200000 +#define OBJ_FLAG_UCODE_SMALL (1 << 22) // 0x00400000 #define OBJ_FLAG_HITBOX_WAS_SET (1 << 30) // 0x40000000 /* oHeldState */ diff --git a/src/boot/memory.c b/src/boot/memory.c index e0914775..7d44ac60 100644 --- a/src/boot/memory.c +++ b/src/boot/memory.c @@ -68,7 +68,6 @@ struct MemoryPool *gEffectsMemoryPool; uintptr_t sSegmentTable[32]; -uintptr_t sSegmentROMTable[32]; u32 sPoolFreeSpace; u8 *sPoolStart; u8 *sPoolEnd; @@ -339,13 +338,13 @@ void *load_segment(s32 segment, u8 *srcStart, u8 *srcEnd, u32 side, u8 *bssStart addr = dynamic_dma_read(srcStart, srcEnd, side, TLB_PAGE_SIZE, (uintptr_t)bssEnd - (uintptr_t)bssStart); if (addr != NULL) { u8 *realAddr = (u8 *)ALIGN((uintptr_t)addr, TLB_PAGE_SIZE); - set_segment_base_addr(segment, realAddr); sSegmentROMTable[segment] = (uintptr_t) srcStart; + set_segment_base_addr(segment, realAddr); mapTLBPages(segment << 24, VIRTUAL_TO_PHYSICAL(realAddr), (srcEnd - srcStart) + ((uintptr_t)bssEnd - (uintptr_t)bssStart), segment); } } else { addr = dynamic_dma_read(srcStart, srcEnd, side, 0, 0); if (addr != NULL) { - set_segment_base_addr(segment, addr); sSegmentROMTable[segment] = (uintptr_t) srcStart; + set_segment_base_addr(segment, addr); } } #if PUPPYPRINT_DEBUG @@ -420,7 +419,7 @@ void *load_segment_decompress(s32 segment, u8 *srcStart, u8 *srcEnd) { decompress(compressed, dest); #endif osSyncPrintf("end decompress\n"); - set_segment_base_addr(segment, dest); sSegmentROMTable[segment] = (uintptr_t) srcStart; + set_segment_base_addr(segment, dest); main_pool_free(compressed); } } @@ -459,7 +458,7 @@ void *load_segment_decompress_heap(u32 segment, u8 *srcStart, u8 *srcEnd) { #elif MIO0 decompress(compressed, gDecompressionHeap); #endif - set_segment_base_addr(segment, gDecompressionHeap); sSegmentROMTable[segment] = (uintptr_t) srcStart; + set_segment_base_addr(segment, gDecompressionHeap); main_pool_free(compressed); } return gDecompressionHeap; diff --git a/src/engine/behavior_script.c b/src/engine/behavior_script.c index 44eb3838..2ea40dad 100644 --- a/src/engine/behavior_script.c +++ b/src/engine/behavior_script.c @@ -920,6 +920,7 @@ void cur_obj_update(void) { f32 distanceFromMario; BhvCommandProc bhvCmdProc; s32 bhvProcResult; + s32 objListIndex; // Calculate the distance from the object to Mario. if (objFlags & OBJ_FLAG_COMPUTE_DIST_TO_MARIO) { @@ -995,6 +996,15 @@ void cur_obj_update(void) { COND_BIT((!(objFlags & OBJ_FLAG_UCODE_LARGE )), gCurrentObject->header.gfx.node.flags, GRAPH_RENDER_UCODE_REJ ); COND_BIT(( objFlags & OBJ_FLAG_SILHOUETTE ), gCurrentObject->header.gfx.node.flags, GRAPH_RENDER_SILHOUETTE ); COND_BIT(( objFlags & OBJ_FLAG_OCCLUDE_SILHOUETTE ), gCurrentObject->header.gfx.node.flags, GRAPH_RENDER_OCCLUDE_SILHOUETTE); + BehaviorScript *bhvScript = segmented_to_virtual(gCurrentObject->behavior); + if ((bhvScript[0] >> 24) == 0) { + objListIndex = (bhvScript[0] >> 16) & 0xFFFF; + } + if (objListIndex == OBJ_LIST_SURFACE && !(objFlags & OBJ_FLAG_UCODE_SMALL)) + { + gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_UCODE_REJ; + gCurrentObject->header.gfx.node.flags |= GRAPH_RENDER_UCODE_ZEX; + } #ifdef OBJ_OPACITY_BY_CAM_DIST if (objFlags & OBJ_FLAG_OPACITY_FROM_CAMERA_DIST) { diff --git a/src/engine/graph_node.h b/src/engine/graph_node.h index cc033f5c..f112dc9f 100644 --- a/src/engine/graph_node.h +++ b/src/engine/graph_node.h @@ -18,6 +18,7 @@ #define GRAPH_RENDER_SILHOUETTE (1 << 6) // 0x0040 #define GRAPH_RENDER_OCCLUDE_SILHOUETTE (1 << 7) // 0x0080 #define GRAPH_RENDER_UCODE_REJ (1 << 8) // 0x0100 +#define GRAPH_RENDER_UCODE_ZEX (1 << 9) // 0x0200 // The amount of bits to use for the above flags out of a s16 variable. // The remaining bits to the left are used for the render layers. From 83e727400e99c8e29bd579901817d2a37ecd0d1b Mon Sep 17 00:00:00 2001 From: Arceveti <73617174+Arceveti@users.noreply.github.com> Date: Thu, 30 Sep 2021 12:35:46 -0700 Subject: [PATCH 5/5] Update src/game/behaviors/king_bobomb.inc.c Co-authored-by: thecozies <79979276+thecozies@users.noreply.github.com> --- src/game/behaviors/king_bobomb.inc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/behaviors/king_bobomb.inc.c b/src/game/behaviors/king_bobomb.inc.c index ce7a0ce8..7114675a 100644 --- a/src/game/behaviors/king_bobomb.inc.c +++ b/src/game/behaviors/king_bobomb.inc.c @@ -224,7 +224,7 @@ void king_bobomb_act_5(void) { // bobomb returns home if (o->oPosY < o->oHomeY) o->oVelY = 100.0f; else { - arc_to_goal_pos(&o->oPosVec, &o->oPosVec, 100.0f, -4.0f); + arc_to_goal_pos(&o->oHomeX, &o->oPosVec, 100.0f, -4.0f); o->oSubAction++; } break;