From d379314e8398657ee825373b02e5b353aa9c77de Mon Sep 17 00:00:00 2001 From: Fazana <52551480+FazanaJ@users.noreply.github.com> Date: Tue, 17 Aug 2021 16:44:33 +0100 Subject: [PATCH 1/2] small camera speed change and a classic mode fix --- src/game/puppycam2.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/game/puppycam2.c b/src/game/puppycam2.c index 237a3ab7..314c01c5 100644 --- a/src/game/puppycam2.c +++ b/src/game/puppycam2.c @@ -503,7 +503,7 @@ void puppycam_input_pitch(void) if (gPlayer1Controller->buttonDown & D_CBUTTONS || gPuppyCam.stick2[1] != 0) gPuppyCam.pitchAcceleration += 50*(gPuppyCam.options.sensitivityY/100.f); else - gPuppyCam.pitchAcceleration = approach_f32_asymptotic(gPuppyCam.pitchAcceleration, 0, DECELERATION); + gPuppyCam.pitchAcceleration = 0; gPuppyCam.pitchAcceleration = CLAMP(gPuppyCam.pitchAcceleration, -100, 100); @@ -531,7 +531,7 @@ void puppycam_input_zoom(void) void puppycam_input_centre(void) { s32 inputDefault = L_TRIG; - if (gPuppyCam.options.inputType == 3) + if (gPuppyCam.options.inputType == 2) inputDefault = R_TRIG; //Handles L button centering. if (gPlayer1Controller->buttonPressed & inputDefault && gPuppyCam.flags & PUPPYCAM_BEHAVIOUR_YAW_ROTATION && @@ -559,17 +559,17 @@ static void puppycam_input_hold_preset1(f32 ivX) if ((gPlayer1Controller->buttonDown & L_CBUTTONS && !gPuppyCam.options.analogue) || gPuppyCam.stick2[0] != 0) { - gPuppyCam.yawAcceleration -= 50*(gPuppyCam.options.sensitivityX/100.f); + gPuppyCam.yawAcceleration -= 75*(gPuppyCam.options.sensitivityX/100.f); gPuppyCam.framesSinceC[0] = 0; } else if ((gPlayer1Controller->buttonDown & R_CBUTTONS && !gPuppyCam.options.analogue) || gPuppyCam.stick2[0] != 0) { - gPuppyCam.yawAcceleration += 50*(gPuppyCam.options.sensitivityX/100.f); + gPuppyCam.yawAcceleration += 75*(gPuppyCam.options.sensitivityX/100.f); gPuppyCam.framesSinceC[1] = 0; } else - gPuppyCam.yawAcceleration = approach_f32_asymptotic(gPuppyCam.yawAcceleration, 0, DECELERATION); + gPuppyCam.yawAcceleration = 0; } //An alternative control scheme, hold the button down to turn the camera, or press it once to turn it quickly. @@ -604,15 +604,15 @@ static void puppycam_input_hold_preset2(f32 ivX) //Handles continuous movement as normal, as long as the button's held. if (gPlayer1Controller->buttonDown & L_CBUTTONS) { - gPuppyCam.yawAcceleration -= 10*(gPuppyCam.options.sensitivityX/100.f); + gPuppyCam.yawAcceleration -= 75*(gPuppyCam.options.sensitivityX/100.f); } else if (gPlayer1Controller->buttonDown & R_CBUTTONS) { - gPuppyCam.yawAcceleration += 10*(gPuppyCam.options.sensitivityX/100.f); + gPuppyCam.yawAcceleration += 75*(gPuppyCam.options.sensitivityX/100.f); } else - gPuppyCam.yawAcceleration = approach_f32_asymptotic(gPuppyCam.yawAcceleration, 0, DECELERATION); + gPuppyCam.yawAcceleration = 0; } //Another alternative control scheme. This one aims to mimic the parallel camera scheme down to the last bit from the original game. @@ -636,7 +636,7 @@ static void puppycam_input_hold_preset3(f32 ivX) gPuppyCam.yawAcceleration -= (gPuppyCam.options.sensitivityX/100.f)*stickMag[0]; } else - gPuppyCam.yawAcceleration = approach_f32_asymptotic(gPuppyCam.yawAcceleration, 0, DECELERATION); + gPuppyCam.yawAcceleration = 0; if (ABS(gPlayer1Controller->rawStickY) > DEADZONE) { From 7cf370cf28560c3dcb29189c89827b4bce175ffe Mon Sep 17 00:00:00 2001 From: Fazana <52551480+FazanaJ@users.noreply.github.com> Date: Tue, 17 Aug 2021 18:02:04 +0100 Subject: [PATCH 2/2] Puppycam raycasting improvements It now can distinguish collision surfaces by type, which will be handy for anyone using it only searching for specific surfaces. --- src/game/puppycam2.c | 47 ++++++++++++++++++++++++++------------------ src/game/puppycam2.h | 9 ++++++++- 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/src/game/puppycam2.c b/src/game/puppycam2.c index 314c01c5..2f04b9cc 100644 --- a/src/game/puppycam2.c +++ b/src/game/puppycam2.c @@ -1029,37 +1029,44 @@ void find_surface_on_ray_list(struct SurfaceNode *list, Vec3f orig, Vec3f dir, f } } - -void find_surface_on_ray_cell(s16 cellX, s16 cellZ, Vec3f orig, Vec3f normalized_dir, f32 dir_length, struct Surface **hit_surface, Vec3f hit_pos, f32 *max_length) +void find_surface_on_ray_cell(s16 cellX, s16 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] > -0.99999f) + if (normalized_dir[1] > -0.99999f && 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] < 0.99999f) + if (normalized_dir[1] < 0.99999f && 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); } - 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_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) +void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Vec3f hit_pos, s32 flags) { f32 max_length; - s16 cellZ, cellX, cellPrevX, cellPrevZ; + s32 cellZ, cellX, cellPrevX, cellPrevZ; f32 fCellZ, fCellX; f32 dir_length; Vec3f normalized_dir; f32 step, dx, dz; - u32 i; + s32 i; // Set that no surface has been hit *hit_surface = NULL; @@ -1074,13 +1081,15 @@ void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Ve // Get our cell coordinate fCellX = (orig[0] + LEVEL_BOUNDARY_MAX) / CELL_SIZE; fCellZ = (orig[2] + LEVEL_BOUNDARY_MAX) / CELL_SIZE; - cellX = (s16)fCellX; - cellZ = (s16)fCellZ; + 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); + find_surface_on_ray_cell(cellX, cellZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length, flags); return; } @@ -1095,20 +1104,20 @@ void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Ve 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); + 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 = (s16)fCellX; - cellZ = (s16)fCellZ; + 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); - find_surface_on_ray_cell(cellPrevX, cellZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length); + 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); } } } @@ -1475,8 +1484,8 @@ static void puppycam_collision(void) camdir[1][1] = camdir[0][1]; camdir[1][2] = camdir[0][2]; - find_surface_on_ray(target[0], camdir[0], &surf[0], hitpos[0]); - find_surface_on_ray(target[1], camdir[1], &surf[1], hitpos[1]); + find_surface_on_ray(target[0], camdir[0], &surf[0], hitpos[0], RAYCAST_FIND_FLOOR | RAYCAST_FIND_CEIL | RAYCAST_FIND_WALL); + find_surface_on_ray(target[1], camdir[1], &surf[1], hitpos[1], RAYCAST_FIND_FLOOR | RAYCAST_FIND_CEIL | RAYCAST_FIND_WALL); resolve_and_return_wall_collisions(hitpos[0], 0.0f, 25.0f); resolve_and_return_wall_collisions(hitpos[1], 0.0f, 25.0f); dist[0] = ((target[0][0] - hitpos[0][0]) * (target[0][0] - hitpos[0][0]) + (target[0][1] - hitpos[0][1]) * (target[0][1] - hitpos[0][1]) + (target[0][2] - hitpos[0][2]) * (target[0][2] - hitpos[0][2])); diff --git a/src/game/puppycam2.h b/src/game/puppycam2.h index 3f030aa9..c3648c91 100644 --- a/src/game/puppycam2.h +++ b/src/game/puppycam2.h @@ -25,6 +25,13 @@ #define PUPPYCAM_MODE3_ZOOMED_OUT 0x4 #define PUPPYCAM_MODE3_ENTER_FIRST_PERSON 0x8 +#define RAYCAST_FIND_FLOOR (0x1) +#define RAYCAST_FIND_WALL (0x2) +#define RAYCAST_FIND_CEIL (0x4) +#define RAYCAST_FIND_WATER (0x8) +#define RAYCAST_FIND_ALL (0xFFFFFFFF) + + #include "include/command_macros_base.h" #define PUPPYVOLUME(x, y, z, length, height, width, yaw, functionptr, anglesptr, addflags, removeflags, flagpersistance, room, shape) \ @@ -166,7 +173,7 @@ extern void puppycam_boot(void); extern void puppycam_init(void); extern void puppycam_loop(void); extern void puppycam_shake(s16 x, s16 y, s16 z); -extern void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Vec3f hit_pos); +extern void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Vec3f hit_pos, s32 flags); extern f32 approach_f32_asymptotic(f32 current, f32 target, f32 multiplier); extern void puppycam_default_config(void); extern s16 LENCOS(s16 length, s16 direction);