diff --git a/qmath.h b/qmath.h index 4b2ac13..9193510 100644 --- a/qmath.h +++ b/qmath.h @@ -17,4 +17,11 @@ INLINE short m_pointPlaneDist2(const VECTOR point2, const SVECTOR normal12, int return (short)(x + y + z - dist2); } +INLINE void m_lightColor(const CVECTOR *color, short light, CVECTOR *outColor) +{ + outColor->r = (uint8_t)((light * color->r) >> 8); + outColor->g = (uint8_t)((light * color->g) >> 8); + outColor->b = (uint8_t)((light * color->b) >> 8); +} + #endif // __QMATH_H__ diff --git a/test.ps1bsp b/test.ps1bsp index 3173adb..fd79596 100755 Binary files a/test.ps1bsp and b/test.ps1bsp differ diff --git a/world.c b/world.c index 05dc884..6ae41b6 100644 --- a/world.c +++ b/world.c @@ -22,6 +22,8 @@ static CVECTOR colors[] = }; static const int numColors = sizeof(colors) / sizeof(CVECTOR); +CVECTOR color_white = { 255, 255, 255 }; + // Set data pointers directly from an in-memory byte buffer #define LOAD_CHUNK(type, dst, num, src, entry) \ dst = (type*)((src) + (entry).offset); \ @@ -49,7 +51,7 @@ void world_load(const u_long *data, world_t *world) LOAD_CHUNK(u_char, world->visData, world->numVisData, bytes, header->visData); } -static INLINE void drawface_triangle_fan(const ps1bsp_face_t *face, SVECTOR *vecs) +static INLINE void drawface_triangle_fan(const ps1bsp_face_t *face, SVECTOR *vecs, CVECTOR *color) { int p; @@ -80,16 +82,16 @@ static INLINE void drawface_triangle_fan(const ps1bsp_face_t *face, SVECTOR *vec setPolyG3(poly); gte_stsxy3_g3(poly); - poly->r0 = poly->g0 = poly->b0 = (uint8_t)v0->pad; - poly->r1 = poly->g1 = poly->b1 = (uint8_t)v1->pad; - poly->r2 = poly->g2 = poly->b2 = (uint8_t)v2->pad; + m_lightColor(color, v0->pad, (CVECTOR*)&poly->r0); + m_lightColor(color, v1->pad, (CVECTOR*)&poly->r1); + m_lightColor(color, v2->pad, (CVECTOR*)&poly->r2); addPrim(curOT + depth, poly); ++polyCount; } } -static INLINE void drawface_triangle_strip(const ps1bsp_face_t *face, SVECTOR *vecs) +static INLINE void drawface_triangle_strip(const ps1bsp_face_t *face, SVECTOR *vecs, CVECTOR *color) { int p; @@ -136,16 +138,16 @@ static INLINE void drawface_triangle_strip(const ps1bsp_face_t *face, SVECTOR *v setPolyG3(poly); gte_stsxy3_g3(poly); - poly->r0 = poly->g0 = poly->b0 = (uint8_t)v0->pad; - poly->r1 = poly->g1 = poly->b1 = (uint8_t)v1->pad; - poly->r2 = poly->g2 = poly->b2 = (uint8_t)v2->pad; + m_lightColor(color, v0->pad, (CVECTOR*)&poly->r0); + m_lightColor(color, v1->pad, (CVECTOR*)&poly->r1); + m_lightColor(color, v2->pad, (CVECTOR*)&poly->r2); addPrim(curOT + depth, poly); ++polyCount; } } -static INLINE void drawface_quad_strip(const ps1bsp_face_t *face, SVECTOR *vecs) +static INLINE void drawface_quad_strip(const ps1bsp_face_t *face, SVECTOR *vecs, CVECTOR *color) { int p; @@ -193,10 +195,10 @@ static INLINE void drawface_quad_strip(const ps1bsp_face_t *face, SVECTOR *vecs) gte_rtps(); gte_stsxy(&poly->x3); - poly->r0 = poly->g0 = poly->b0 = (uint8_t)v0->pad; - poly->r1 = poly->g1 = poly->b1 = (uint8_t)v1->pad; - poly->r2 = poly->g2 = poly->b2 = (uint8_t)v2->pad; - poly->r3 = poly->g3 = poly->b3 = (uint8_t)v3->pad; + m_lightColor(color, v0->pad, (CVECTOR*)&poly->r0); + m_lightColor(color, v1->pad, (CVECTOR*)&poly->r1); + m_lightColor(color, v2->pad, (CVECTOR*)&poly->r2); + m_lightColor(color, v3->pad, (CVECTOR*)&poly->r3); addPrim(curOT + depth, poly); ++polyCount; @@ -237,6 +239,16 @@ static void world_drawface(const world_t *world, const ps1bsp_face_t *face) if ((dot >= 0) ^ face->side) return; + // Experimenting with tessellation levels + dot = abs(dot) / center.pad;// for a more stable albeit less accurate result, divide by a fixed value of 160 + char tess; + if (dot < 4) + tess = 0; + else if (dot < 12) + tess = 1; + else + tess = 2; + SVECTOR *vecs = (SVECTOR*)(scratchpad + 256); // Copy this face's vertices into scratch RAM for fast reuse @@ -250,9 +262,9 @@ static void world_drawface(const world_t *world, const ps1bsp_face_t *face) } if (face->numFaceVertices == 3) // Special case: draw single triangles using the simplest method - drawface_triangle_fan(face, vecs); + drawface_triangle_fan(face, vecs, &colors[tess]); else - drawface_quad_strip(face, vecs); + drawface_quad_strip(face, vecs, &colors[tess]); } static void world_drawnode(const world_t *world, short nodeIdx, u_char *pvs)