diff --git a/src/chaos-drop.h b/src/chaos-drop.h index b211cc4..cf633f7 100644 --- a/src/chaos-drop.h +++ b/src/chaos-drop.h @@ -155,6 +155,9 @@ struct game { struct element_mirror *mirror; struct element_plane *plane; struct element_text *text; + /* A dynamic plane y value; mostly redundant from plane->y, used to optimize + away some checks during collisions with the plane */ + num plane_collision[2]; /* Distance traversed within the current level */ num depth; diff --git a/src/main.cc b/src/main.cc index ef8cdd2..871cc47 100644 --- a/src/main.cc +++ b/src/main.cc @@ -459,6 +459,19 @@ int game_update(struct game *g, bool *debug) game_next_level_or_menu(g); } + // Pre-compute plane collision info + + num pc = g->plane ? g->plane->y - g->depth : num(0x7fff); + + if(g->plane->type == ELEMENT_PLANE_INVIS) { + g->plane_collision[0] = num(0x7fff); + g->plane_collision[1] = pc; + } + else { + g->plane_collision[0] = pc; + g->plane_collision[1] = pc; + } + return 0; } @@ -504,6 +517,8 @@ int main(void) g.blank_frames = 0; g.neon_position = 0; g.neon_period = 64; + g.plane_collision[0] = num(0x7fff); + g.plane_collision[1] = num(0x7fff); game_load_menu(&g); game = &g; diff --git a/src/raytracing.cc b/src/raytracing.cc index b547c3b..e686297 100644 --- a/src/raytracing.cc +++ b/src/raytracing.cc @@ -79,16 +79,16 @@ static int cast_ray(struct game const *g, svec3 const &origin, if(hitz && (!hitx || (tz_rx_rz < tx_rx_rz) ^ rx_rz_sign)) { if(hitz == TOP) - *t = num16::div_positive(num16(WORLD_SIZE) - origin.z, rayDir.z); + *t = (num16(WORLD_SIZE) - origin.z) / rayDir.z; else - *t = num16::div_positive(origin.z + num16(WORLD_SIZE), -rayDir.z); + *t = (origin.z + num16(WORLD_SIZE)) / -rayDir.z; hit = hitz; } else if(__builtin_expect(hitx, 1)) { if(hitx == RIGHT) - *t = num16::div_positive(num16(WORLD_SIZE) - origin.x, rayDir.x); + *t = (num16(WORLD_SIZE) - origin.x) / rayDir.x; else - *t = num16::div_positive(origin.x + num16(WORLD_SIZE), -rayDir.x); + *t = (origin.x + num16(WORLD_SIZE)) / -rayDir.x; hit = hitx; } @@ -101,19 +101,16 @@ static int cast_ray(struct game const *g, svec3 const &origin, /* Determine if there is an intersection with the object plane */ - if(__builtin_expect( - g->plane - && (*collision_y > g->plane->y - g->depth) - && (g->plane->type != ELEMENT_PLANE_INVIS || secondary), - 0)) { - num16 plane_y = num16(g->plane->y - g->depth); + num pc = g->plane_collision[secondary]; + if(__builtin_expect(*collision_y > pc, 0)) { + num16 plane_y = num16(pc); num16 plane_t = (plane_y - origin.y) / rayDir.y; num16 plane_x = origin.x + plane_t * rayDir.x; num16 plane_z = origin.z + plane_t * rayDir.z; if(level_plane_collides(plane_x, plane_z, g->plane->shape)) { *t = plane_t; - *collision_y = g->plane->y - g->depth; + *collision_y = pc; return OBJECT_PLANE; } }