diff --git a/src/Core.h b/src/Core.h index ff320b9a2..fa51bc00f 100644 --- a/src/Core.h +++ b/src/Core.h @@ -378,6 +378,7 @@ typedef cc_uint8 cc_bool; #define CC_BUILD_NOMUSIC #define CC_BUILD_NOSOUNDS #define CC_BUILD_SMALLSTACK + #define CC_BUILD_SPLITSCREEN #undef CC_BUILD_RESOURCES #undef CC_BUILD_NETWORKING #undef CC_BUILD_FILESYSTEM diff --git a/src/ExtMath.h b/src/ExtMath.h index 2d4ecdb1b..bfe31e763 100644 --- a/src/ExtMath.h +++ b/src/ExtMath.h @@ -34,6 +34,11 @@ CC_BEGIN_HEADER float Math_Mod1(float x); int Math_AbsI(int x); +static CC_INLINE float Math_SafeDiv(float a, float b) { + if (Math_AbsF(b) < 0.000001f) return MATH_LARGENUM; + return a / b; +} + CC_API double Math_Sin(double x); CC_API double Math_Cos(double x); CC_API float Math_SinF(float x); diff --git a/src/Graphics_N64.c b/src/Graphics_N64.c index 9d34f3772..f4c994b20 100644 --- a/src/Graphics_N64.c +++ b/src/Graphics_N64.c @@ -72,8 +72,15 @@ void Gfx_SetVSync(cc_bool vsync) { void Gfx_OnWindowResize(void) { } -void Gfx_SetViewport(int x, int y, int w, int h) { } -void Gfx_SetScissor (int x, int y, int w, int h) { } +void Gfx_SetViewport(int x, int y, int w, int h) { + glViewport(x, Game.Height - h - y, w, h); +} +void Gfx_SetScissor (int x, int y, int w, int h) { + cc_bool enabled = x != 0 || y != 0 || w != Game.Width || h != Game.Height; + if (enabled) { glEnable(GL_SCISSOR_TEST); } else { glDisable(GL_SCISSOR_TEST); } + + glScissor(x, Game.Height - h - y, w, h); +} void Gfx_BeginFrame(void) { diff --git a/src/Physics.c b/src/Physics.c index 96dccfca4..a377eb4e6 100644 --- a/src/Physics.c +++ b/src/Physics.c @@ -76,9 +76,9 @@ cc_bool Intersection_RayIntersectsRotatedBox(Vec3 origin, Vec3 dir, struct Entit dir = Intersection_InverseRotate(dir, target); Entity_GetPickingBounds(target, &bb); - invDir.x = 1.0f / dir.x; - invDir.y = 1.0f / dir.y; - invDir.z = 1.0f / dir.z; + invDir.x = Math_SafeDiv(1.0f, dir.x); + invDir.y = Math_SafeDiv(1.0f, dir.y); + invDir.z = Math_SafeDiv(1.0f, dir.z); return Intersection_RayIntersectsBox(origin, invDir, bb.Min, bb.Max, tMin, tMax); } diff --git a/src/Picking.c b/src/Picking.c index b2e1b8817..f492e701a 100644 --- a/src/Picking.c +++ b/src/Picking.c @@ -50,18 +50,13 @@ void RayTracer_SetInvalid(struct RayTracer* t) { t->closest = FACE_COUNT; } -static float RayTracer_Div(float a, float b) { - if (Math_AbsF(b) < 0.000001f) return MATH_LARGENUM; - return a / b; -} - void RayTracer_Init(struct RayTracer* t, const Vec3* origin, const Vec3* dir) { IVec3 cellBoundary; t->origin = *origin; t->dir = *dir; - t->invDir.x = RayTracer_Div(1.0f, dir->x); - t->invDir.y = RayTracer_Div(1.0f, dir->y); - t->invDir.z = RayTracer_Div(1.0f, dir->z); + t->invDir.x = Math_SafeDiv(1.0f, dir->x); + t->invDir.y = Math_SafeDiv(1.0f, dir->y); + t->invDir.z = Math_SafeDiv(1.0f, dir->z); /* Rounds the position's X, Y and Z down to the nearest integer values. */ /* The cell in which the ray starts. */ @@ -78,9 +73,9 @@ void RayTracer_Init(struct RayTracer* t, const Vec3* origin, const Vec3* dir) { /* NOTE: we want it so if dir.x = 0, tmax.x = positive infinity Determine how far we can travel along the ray before we hit a voxel boundary. */ - t->tMax.x = RayTracer_Div(cellBoundary.x - origin->x, dir->x); /* Boundary is a plane on the YZ axis. */ - t->tMax.y = RayTracer_Div(cellBoundary.y - origin->y, dir->y); /* Boundary is a plane on the XZ axis. */ - t->tMax.z = RayTracer_Div(cellBoundary.z - origin->z, dir->z); /* Boundary is a plane on the XY axis. */ + t->tMax.x = Math_SafeDiv(cellBoundary.x - origin->x, dir->x); /* Boundary is a plane on the YZ axis. */ + t->tMax.y = Math_SafeDiv(cellBoundary.y - origin->y, dir->y); /* Boundary is a plane on the XZ axis. */ + t->tMax.z = Math_SafeDiv(cellBoundary.z - origin->z, dir->z); /* Boundary is a plane on the XY axis. */ /* Determine how far we must travel along the ray before we have crossed a gridcell. */ t->tDelta.x = (float)t->step.x * t->invDir.x;