From d5c26f28d67f474eaca5ff81239a1619d837983f Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 31 Mar 2024 22:39:50 +0300 Subject: [PATCH 1/4] free for real --- src/client/refresh/soft/sw_main.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/client/refresh/soft/sw_main.c b/src/client/refresh/soft/sw_main.c index 641e1cc9..ff51e55a 100644 --- a/src/client/refresh/soft/sw_main.c +++ b/src/client/refresh/soft/sw_main.c @@ -598,10 +598,7 @@ R_ReallocateMapBuffers (void) if (!r_numallocatedlights || r_outoflights) { - if (!blocklights) - { - free(blocklights); - } + free(blocklights); if (r_outoflights) { @@ -628,10 +625,7 @@ R_ReallocateMapBuffers (void) if (!r_numallocatededges || r_outofedges) { - if (!r_edges) - { - free(r_edges); - } + free(r_edges); if (r_outofedges) { @@ -700,8 +694,9 @@ R_ReallocateMapBuffers (void) r_outoftriangles = false; } - if (r_numallocatedtriangles < vid.height) - r_numallocatedtriangles = vid.height; + // one more for the terminator + if (r_numallocatedtriangles < vid.height+1) + r_numallocatedtriangles = vid.height+1; triangle_spans = malloc(r_numallocatedtriangles * sizeof(spanpackage_t)); if (!triangle_spans) @@ -712,7 +707,7 @@ R_ReallocateMapBuffers (void) } triangles_max = &triangle_spans[r_numallocatedtriangles]; - R_Printf(PRINT_ALL, "Allocated %d triangles.\n", r_numallocatedtriangles); + R_Printf(PRINT_ALL, "Allocated %d triangle spans.\n", r_numallocatedtriangles); } if (!r_numallocatededgebasespans || r_outedgebasespans) From 85b7ae87ef3d517e3bdfd05df0439582bb992f13 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 31 Mar 2024 22:40:29 +0300 Subject: [PATCH 2/4] fix bmodel clipping --- src/client/refresh/soft/sw_bsp.c | 93 ++++++++++++-------------------- 1 file changed, 35 insertions(+), 58 deletions(-) diff --git a/src/client/refresh/soft/sw_bsp.c b/src/client/refresh/soft/sw_bsp.c index 2b98e1aa..acbec98d 100644 --- a/src/client/refresh/soft/sw_bsp.c +++ b/src/client/refresh/soft/sw_bsp.c @@ -58,7 +58,6 @@ R_EntityRotate (vec3_t vec) vec[2] = DotProduct (entity_rotation[2], tvec); } - /* ================ R_RotateBmodel @@ -153,13 +152,10 @@ R_RecursiveClipBPoly(entity_t *currententity, bedge_t *pedges, mnode_t *pnode, m cplane_t *splitplane, tplane; mvertex_t *pvert, *plastvert, *ptvert; mnode_t *pn; - qboolean makeclippededge; - mvertex_t *pfrontenter = bverts, *pfrontexit = bverts; + mvertex_t *prevclipvert = NULL; psideedges[0] = psideedges[1] = NULL; - makeclippededge = false; - // transform the BSP plane into model space // FIXME: cache these? splitplane = pnode->plane; @@ -180,19 +176,15 @@ R_RecursiveClipBPoly(entity_t *currententity, bedge_t *pedges, mnode_t *pnode, m // set the status for the last point as the previous point // FIXME: cache this stuff somehow? plastvert = pedges->v[0]; - lastdist = DotProduct (plastvert->position, tplane.normal) - - tplane.dist; - - if (lastdist > 0) + lastdist = DotProduct (plastvert->position, tplane.normal) - tplane.dist; + if (lastdist >= 0) lastside = 0; else lastside = 1; pvert = pedges->v[1]; - dist = DotProduct (pvert->position, tplane.normal) - tplane.dist; - - if (dist > 0) + if (dist >= 0) side = 0; else side = 1; @@ -221,34 +213,48 @@ R_RecursiveClipBPoly(entity_t *currententity, bedge_t *pedges, mnode_t *pnode, m // split into two edges, one on each side, and remember entering // and exiting points // FIXME: share the clip edge by having a winding direction flag? + if (numbedges + 4 > MAX_BMODEL_EDGES) + { + R_Printf(PRINT_ALL,"Out of edges for bmodel\n"); + return; + } + + // outside: last vert, clip vert ptedge = &bedges[numbedges++]; ptedge->pnext = psideedges[lastside]; psideedges[lastside] = ptedge; ptedge->v[0] = plastvert; ptedge->v[1] = ptvert; + // each two clipped verts we get a clipped-off contour; + // connect the verts by two edges (one per side) + // going in opposite directions + // this fixes surface 0 of model *50 (fan) in mine2: + // teleport 1231 770 -579 + if (prevclipvert) + { + ptedge = &bedges[numbedges++]; + ptedge->pnext = psideedges[lastside]; + psideedges[lastside] = ptedge; + ptedge->v[0] = ptvert; + ptedge->v[1] = prevclipvert; + + ptedge = &bedges[numbedges++]; + ptedge->pnext = psideedges[side]; + psideedges[side] = ptedge; + ptedge->v[0] = prevclipvert; + ptedge->v[1] = ptvert; + + prevclipvert = NULL; + } else + prevclipvert = ptvert; + + // inside: clip vert, current vert ptedge = &bedges[numbedges++]; ptedge->pnext = psideedges[side]; psideedges[side] = ptedge; ptedge->v[0] = ptvert; ptedge->v[1] = pvert; - - if (numbedges >= MAX_BMODEL_EDGES) - { - R_Printf(PRINT_ALL,"Out of edges for bmodel\n"); - return; - } - - if (side == 0) - { - // entering for front, exiting for back - pfrontenter = ptvert; - } - else - { - pfrontexit = ptvert; - } - makeclippededge = true; } else { @@ -258,31 +264,6 @@ R_RecursiveClipBPoly(entity_t *currententity, bedge_t *pedges, mnode_t *pnode, m } } - // if anything was clipped, reconstitute and add the edges along the clip - // plane to both sides (but in opposite directions) - if (makeclippededge && pfrontexit != pfrontenter) - { - bedge_t *ptedge; - - ptedge = &bedges[numbedges++]; - ptedge->pnext = psideedges[0]; - psideedges[0] = ptedge; - ptedge->v[0] = pfrontexit; - ptedge->v[1] = pfrontenter; - - ptedge = &bedges[numbedges++]; - ptedge->pnext = psideedges[1]; - psideedges[1] = ptedge; - ptedge->v[0] = pfrontenter; - ptedge->v[1] = pfrontexit; - - if (numbedges >= MAX_BMODEL_EDGES) - { - R_Printf(PRINT_ALL,"Out of edges for bmodel\n"); - return; - } - } - // draw or recurse further for (i=0 ; i<2 ; i++) { @@ -396,10 +377,6 @@ R_DrawSolidClippedSubmodelPolygons(entity_t *currententity, const model_t *curre if ( !( psurf->texinfo->flags & ( SURF_TRANS66 | SURF_TRANS33 ) )) { - // FIXME: Fan broken in borehole - // teleport: 1231.000000 770.250000 -579.375000 - // map: maps/mine2.bsp - // model texture: textures/e2u1/metal6_1.wal R_RecursiveClipBPoly(currententity, pbedge, topnode, psurf); } else From 6d1ac97a77ed4e56cfc68b471744b78d817dfa62 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 31 Mar 2024 22:45:30 +0300 Subject: [PATCH 3/4] cleanup alias scan conversion --- src/client/refresh/soft/sw_polyset.c | 400 +++++++++++++-------------- 1 file changed, 185 insertions(+), 215 deletions(-) diff --git a/src/client/refresh/soft/sw_polyset.c b/src/client/refresh/soft/sw_polyset.c index 0f77c7da..30fc46c4 100644 --- a/src/client/refresh/soft/sw_polyset.c +++ b/src/client/refresh/soft/sw_polyset.c @@ -24,7 +24,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include typedef struct { - int isflattop; int numleftedges; compactvert_t *pleftedgevert0; compactvert_t *pleftedgevert1; @@ -44,18 +43,18 @@ static int d_xdenom; static edgetable *pedgetable; static edgetable edgetables[12] = { - {0, 1, &r_p0, &r_p2, NULL, 2, &r_p0, &r_p1, &r_p2}, - {0, 2, &r_p1, &r_p0, &r_p2, 1, &r_p1, &r_p2, NULL}, - {1, 1, &r_p0, &r_p2, NULL, 1, &r_p1, &r_p2, NULL}, - {0, 1, &r_p1, &r_p0, NULL, 2, &r_p1, &r_p2, &r_p0}, - {0, 2, &r_p0, &r_p2, &r_p1, 1, &r_p0, &r_p1, NULL}, - {0, 1, &r_p2, &r_p1, NULL, 1, &r_p2, &r_p0, NULL}, - {0, 1, &r_p2, &r_p1, NULL, 2, &r_p2, &r_p0, &r_p1}, - {0, 2, &r_p2, &r_p1, &r_p0, 1, &r_p2, &r_p0, NULL}, - {0, 1, &r_p1, &r_p0, NULL, 1, &r_p1, &r_p2, NULL}, - {1, 1, &r_p2, &r_p1, NULL, 1, &r_p0, &r_p1, NULL}, - {1, 1, &r_p1, &r_p0, NULL, 1, &r_p2, &r_p0, NULL}, - {0, 1, &r_p0, &r_p2, NULL, 1, &r_p0, &r_p1, NULL}, + {1, &r_p0, &r_p2, &r_p2, 2, &r_p0, &r_p1, &r_p2}, + {2, &r_p1, &r_p0, &r_p2, 1, &r_p1, &r_p2, &r_p2}, + {1, &r_p0, &r_p2, &r_p2, 1, &r_p1, &r_p2, &r_p2}, // flat top + {1, &r_p1, &r_p0, &r_p0, 2, &r_p1, &r_p2, &r_p0}, + {2, &r_p0, &r_p2, &r_p1, 1, &r_p0, &r_p1, &r_p1}, + {1, &r_p2, &r_p1, &r_p1, 1, &r_p2, &r_p0, &r_p0}, + {1, &r_p2, &r_p1, &r_p1, 2, &r_p2, &r_p0, &r_p1}, + {2, &r_p2, &r_p1, &r_p0, 1, &r_p2, &r_p0, &r_p0}, + {1, &r_p1, &r_p0, &r_p0, 1, &r_p1, &r_p2, &r_p2}, + {1, &r_p2, &r_p1, &r_p1, 1, &r_p0, &r_p1, &r_p1}, // flat top + {1, &r_p1, &r_p0, &r_p0, 1, &r_p2, &r_p0, &r_p0}, // flat top + {1, &r_p0, &r_p2, &r_p2, 1, &r_p0, &r_p1, &r_p1}, }; // FIXME: some of these can become statics @@ -200,13 +199,6 @@ static void R_PushEdgesSpan(int u, int v, int count, pixel_t* d_ptex, int d_sfrac, int d_tfrac, light3_t d_light, zvalue_t d_zi) { - if (d_pedgespanpackage >= triangles_max) - { - // no space any more - r_outoftriangles = true; - return; - } - d_pedgespanpackage->u = u; d_pedgespanpackage->v = v; d_pedgespanpackage->count = count; @@ -299,6 +291,41 @@ quotient must fit in 32 bits. FIXME: GET RID OF THIS! (FloorDivMod) ==================== */ +#if defined(__i386__) || defined(__amd64__) +// just exclude ARM32 with FPU, e.g. Pi 1 +static void +FloorDivMod(int numer, int denom, int *quo, int *rem) +{ + int q, r; + + q = numer / denom; + r = numer - q * denom; + if (-1/2 || 1/-2 || -1/-2) { + // long live C89 + if (r < 0 && r < denom) { + q += 1; + r -= denom; + } + } else { + // C99 always truncates to 0 + if ((numer ^ denom) < 0 && r != 0) { + q -= 1; + r += denom; + } + } + assert(r == numer - q * denom); + if ((numer < 0) ^ (denom < 0)) + assert(q <= 0); + else + assert(q >= 0); + if (denom < 0) + assert(r > denom && r <= 0); + else + assert(r >= 0 && r < denom); + *quo = q; + *rem = r; +} +#else static void FloorDivMod (float numer, float denom, int *quotient, int *rem) @@ -331,7 +358,7 @@ FloorDivMod (float numer, float denom, int *quotient, *quotient = q; *rem = r; } - +#endif /* =================== @@ -342,20 +369,17 @@ static void R_PolysetSetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv, fixed8_t endvertu, fixed8_t endvertv) { - float tm, tn; - - errorterm = -1; + int tm, tn; tm = endvertu - startvertu; tn = endvertv - startvertv; - FloorDivMod (tm, tn, &ubasestep, &erroradjustup); - + errorterm = -1; erroradjustdown = tn; + + FloorDivMod (tm, tn, &ubasestep, &erroradjustup); } - - /* ================ R_PolysetCalcGradients @@ -492,7 +516,7 @@ R_PolysetDrawSpans8_33(const entity_t *currententity, spanpackage_t *pspanpackag } pspanpackage++; - } while ((pspanpackage < triangles_max) && (pspanpackage->count != INT_MIN)); + } while (pspanpackage->count != INT_MIN); } void @@ -539,7 +563,7 @@ R_PolysetDrawSpansConstant8_33(const entity_t *currententity, spanpackage_t *psp } pspanpackage++; - } while ((pspanpackage < triangles_max) && (pspanpackage->count != INT_MIN)); + } while (pspanpackage->count != INT_MIN); } void @@ -621,7 +645,7 @@ R_PolysetDrawSpans8_66(const entity_t *currententity, spanpackage_t *pspanpackag } pspanpackage++; - } while ((pspanpackage < triangles_max) && (pspanpackage->count != INT_MIN)); + } while (pspanpackage->count != INT_MIN); } void @@ -679,7 +703,7 @@ R_PolysetDrawSpansConstant8_66(const entity_t *currententity, spanpackage_t *psp } pspanpackage++; - } while ((pspanpackage < triangles_max) && (pspanpackage->count != INT_MIN)); + } while (pspanpackage->count != INT_MIN); } void @@ -762,7 +786,79 @@ R_PolysetDrawSpans8_Opaque (const entity_t *currententity, spanpackage_t *pspanp } pspanpackage++; - } while ((pspanpackage < triangles_max) && (pspanpackage->count != INT_MIN)); + } while (pspanpackage->count != INT_MIN); +} + +static void +R_ProcessLeftEdge(compactvert_t *plefttop, compactvert_t *prighttop, + compactvert_t *pleftbottom) +{ + light3_t working_lstepx; + pixel_t *d_ptex; + int u, v; + int s, t; + int height; + int i; + + u = plefttop->u; + v = plefttop->v; + d_aspancount = plefttop->u - prighttop->u; + + s = plefttop->s; + t = plefttop->t; + i = (s >> SHIFT16XYZ) + (t >> SHIFT16XYZ) * r_affinetridesc.skinwidth; + d_ptex = &r_affinetridesc.pskin[i]; + d_sfrac = s & 0xFFFF; + d_tfrac = t & 0xFFFF; + + memcpy(d_light, plefttop->l, sizeof(light3_t)); + d_zi = plefttop->zi; + + height = pleftbottom->v - plefttop->v; + if (height == 1) + { + // skip calculations needed for 2+ spans + R_PushEdgesSpan(u, v, d_aspancount, + d_ptex, d_sfrac, d_tfrac, d_light, d_zi); + return; + } + R_PolysetSetUpForLineScan(plefttop->u, plefttop->v, + pleftbottom->u, pleftbottom->v); + + // for negative steps in x along left edge, bias toward overflow rather than + // underflow (sort of turning the floor () we did in the gradient calcs into + // ceil (), but plus a little bit) + t = ubasestep < 0; + for (i = 0; i < 3; i++) + working_lstepx[i] = r_lstepx[i] - t; + + // base steps for drawers + s = r_sstepy + r_sstepx * ubasestep; + t = r_tstepy + r_tstepx * ubasestep; + d_ptexbasestep = (s >> SHIFT16XYZ) + + (t >> SHIFT16XYZ) * r_affinetridesc.skinwidth; + d_sfracbasestep = s & 0xFFFF; + d_tfracbasestep = t & 0xFFFF; + + for (i = 0; i < 3; i++) + d_lightbasestep[i] = r_lstepy[i] + working_lstepx[i] * ubasestep; + + d_zibasestep = r_zistepy + r_zistepx * ubasestep; + + // extra steps for drawers + s += r_sstepx; + t += r_tstepx; + d_ptexextrastep = (s >> SHIFT16XYZ) + + (t >> SHIFT16XYZ) * r_affinetridesc.skinwidth; + d_sfracextrastep = s & 0xFFFF; + d_tfracextrastep = t & 0xFFFF; + + for (i = 0; i < 3; i++) + d_lightextrastep[i] = d_lightbasestep[i] + working_lstepx[i]; + + d_ziextrastep = d_zibasestep + r_zistepx; + + R_PolysetScanLeftEdge_C(height, d_ptex, u, v); } /* @@ -773,12 +869,14 @@ R_RasterizeAliasPolySmooth static void R_RasterizeAliasPolySmooth(const entity_t *currententity) { - int initialleftheight, initialrightheight; - compactvert_t *plefttop, *prighttop, *pleftbottom, *prightbottom; - light3_t working_lstepx; + compactvert_t *plefttop, *prighttop, *pleftbottom, *prightbottom; + spanpackage_t *pstart; int originalcount; - int u, v; - pixel_t *d_ptex; + int leftheight, rightheight; + + // set the s, t, and light gradients, which are consistent across + // the triangle because being a triangle, things are affine + R_PolysetCalcGradients (r_affinetridesc.skinwidth); plefttop = pedgetable->pleftedgevert0; prighttop = pedgetable->prightedgevert0; @@ -786,204 +884,76 @@ R_RasterizeAliasPolySmooth(const entity_t *currententity) pleftbottom = pedgetable->pleftedgevert1; prightbottom = pedgetable->prightedgevert1; - initialleftheight = pleftbottom->v - plefttop->v; - initialrightheight = prightbottom->v - prighttop->v; - - // - // set the s, t, and light gradients, which are consistent across the triangle - // because being a triangle, things are affine - // - R_PolysetCalcGradients (r_affinetridesc.skinwidth); - // - // rasterize the polygon - // - - // - // scan out the top (and possibly only) part of the left edge - // - d_pedgespanpackage = triangle_spans; - - u = plefttop->u; - v = plefttop->v; - d_aspancount = plefttop->u - prighttop->u; - - d_ptex = r_affinetridesc.pskin + (plefttop->s >> SHIFT16XYZ) + - (plefttop->t >> SHIFT16XYZ) * r_affinetridesc.skinwidth; + // make sure we have enough spans for the full height + // plus 1 more for the list terminator. + // vert2 in the edgetable is always the lowest. + // (this is silly anyway, just allocate vid.height+1) + leftheight = pedgetable->pleftedgevert2->v - plefttop->v; + rightheight = pedgetable->prightedgevert2->v - prighttop->v; + if (leftheight < rightheight) + leftheight = rightheight; + if (&triangle_spans[leftheight] >= triangles_max) { - d_sfrac = plefttop->s & 0xFFFF; - d_tfrac = plefttop->t & 0xFFFF; - } - memcpy(d_light, plefttop->l, sizeof(light3_t)); - d_zi = plefttop->zi; - - if (initialleftheight == 1) - { - R_PushEdgesSpan(u, v, d_aspancount, - d_ptex, d_sfrac, d_tfrac, d_light, d_zi); - } - else - { - int i; - - R_PolysetSetUpForLineScan(plefttop->u, plefttop->v, - pleftbottom->u, pleftbottom->v); - - // TODO: can reuse partial expressions here - - // for negative steps in x along left edge, bias toward overflow rather than - // underflow (sort of turning the floor () we did in the gradient calcs into - // ceil (), but plus a little bit) - if (ubasestep < 0) - { - for(i=0; i<3; i++) - working_lstepx[i] = r_lstepx[i] - 1; - } - else - memcpy(working_lstepx, r_lstepx, sizeof(light3_t)); - - d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> SHIFT16XYZ) + - ((r_tstepy + r_tstepx * ubasestep) >> SHIFT16XYZ) * - r_affinetridesc.skinwidth; - - d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF; - d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF; - - for(i=0; i<3; i++) - d_lightbasestep[i] = r_lstepy[i] + working_lstepx[i] * ubasestep; - - d_zibasestep = r_zistepy + r_zistepx * ubasestep; - - d_ptexextrastep = ((r_sstepy + r_sstepx * (ubasestep + 1)) >> SHIFT16XYZ) + - ((r_tstepy + r_tstepx * (ubasestep + 1)) >> SHIFT16XYZ) * - r_affinetridesc.skinwidth; - - d_sfracextrastep = (r_sstepy + r_sstepx*(ubasestep + 1)) & 0xFFFF; - d_tfracextrastep = (r_tstepy + r_tstepx*(ubasestep + 1)) & 0xFFFF; - - for(i=0; i<3; i++) - d_lightextrastep[i] = d_lightbasestep[i] + working_lstepx[i]; - - d_ziextrastep = d_zibasestep + r_zistepx; - - R_PolysetScanLeftEdge_C(initialleftheight, d_ptex, u, v); - } - - // - // scan out the bottom part of the left edge, if it exists - // - if (pedgetable->numleftedges == 2) - { - int height; - - plefttop = pleftbottom; - pleftbottom = pedgetable->pleftedgevert2; - - height = pleftbottom->v - plefttop->v; - - // TODO: make this a function; modularize this function in general - u = plefttop->u; - v = plefttop->v; - d_aspancount = plefttop->u - prighttop->u; - d_ptex = r_affinetridesc.pskin + (plefttop->s >> SHIFT16XYZ) + - (plefttop->t >> SHIFT16XYZ) * r_affinetridesc.skinwidth; - d_sfrac = 0; - d_tfrac = 0; - memcpy(d_light, plefttop->l, sizeof(light3_t)); - d_zi = plefttop->zi; - - if (height == 1) - { - R_PushEdgesSpan(u, v, d_aspancount, - d_ptex, d_sfrac, d_tfrac, d_light, d_zi); - } - else - { - int i; - - R_PolysetSetUpForLineScan(plefttop->u, plefttop->v, - pleftbottom->u, pleftbottom->v); - - if (ubasestep < 0) - { - for(i=0; i<3; i++) - working_lstepx[i] = r_lstepx[i] - 1; - } - else - memcpy(working_lstepx, r_lstepx, sizeof(light3_t)); - - d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> SHIFT16XYZ) + - ((r_tstepy + r_tstepx * ubasestep) >> SHIFT16XYZ) * - r_affinetridesc.skinwidth; - - d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF; - d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF; - - for(i=0; i<3; i++) - d_lightbasestep[i] = r_lstepy[i] + working_lstepx[i] * ubasestep; - - d_zibasestep = r_zistepy + r_zistepx * ubasestep; - - d_ptexextrastep = ((r_sstepy + r_sstepx * (ubasestep + 1)) >> SHIFT16XYZ) + - ((r_tstepy + r_tstepx * (ubasestep + 1)) >> SHIFT16XYZ) * - r_affinetridesc.skinwidth; - - d_sfracextrastep = (r_sstepy+r_sstepx*(ubasestep + 1)) & 0xFFFF; - d_tfracextrastep = (r_tstepy+r_tstepx*(ubasestep + 1)) & 0xFFFF; - - for(i=0; i<3; i++) - d_lightextrastep[i] = d_lightbasestep[i] + working_lstepx[i]; - d_ziextrastep = d_zibasestep + r_zistepx; - - R_PolysetScanLeftEdge_C(height, d_ptex, u, v); - } - } - - // scan out the top (and possibly only) part of the right edge, updating the - // count field - R_PolysetSetUpForLineScan(prighttop->u, prighttop->v, - prightbottom->u, prightbottom->v); - d_aspancount = 0; - if ((triangle_spans + initialrightheight) >= triangles_max) - { - // we dont have enough triangles for save full height r_outoftriangles = true; return; } - originalcount = triangle_spans[initialrightheight].count; - triangle_spans[initialrightheight].count = INT_MIN; // mark end of the spanpackages + // init span allocation ptr + d_pedgespanpackage = triangle_spans; + + // 1. scan out the top (and possibly only) part of the left edge + R_ProcessLeftEdge(plefttop, prighttop, pleftbottom); + + // 2. scan out the bottom part of the left edge, if it exists + if (pedgetable->numleftedges == 2) + { + plefttop = pleftbottom; + pleftbottom = pedgetable->pleftedgevert2; + + R_ProcessLeftEdge(plefttop, prighttop, pleftbottom); + } + assert(d_pedgespanpackage <= triangles_max); + + // 3. scan out the top (and possibly only) part of the right edge, + // drawing spans that terminate on it + rightheight = prightbottom->v - prighttop->v; + + // reset u delta before drawing the top + d_aspancount = 0; + + // save for step 4 + pstart = &triangle_spans[rightheight]; + originalcount = pstart->count; + // mark end of the spanpackages + pstart->count = INT_MIN; + + R_PolysetSetUpForLineScan(prighttop->u, prighttop->v, + prightbottom->u, prightbottom->v); (*d_pdrawspans) (currententity, triangle_spans); - // scan out the bottom part of the right edge, if it exists + // 4. scan out the bottom part of the right edge, if it exists if (pedgetable->numrightedges == 2) { - int height; - spanpackage_t *pstart; - - pstart = triangle_spans + initialrightheight; + // 4.1 restore the starting span count pstart->count = originalcount; d_aspancount = prightbottom->u - prighttop->u; + // 4.2 shift verts like in step 2 prighttop = prightbottom; prightbottom = pedgetable->prightedgevert2; - height = prightbottom->v - prighttop->v; + // 4.3 increase right height + rightheight += prightbottom->v - prighttop->v; + + // mark end of the spanpackages + triangle_spans[rightheight].count = INT_MIN; R_PolysetSetUpForLineScan(prighttop->u, prighttop->v, - prightbottom->u, prightbottom->v); - - if ((triangle_spans + initialrightheight + height) >= triangles_max) - { - // we dont have enough triangles for save full height - r_outoftriangles = true; - return; - } - triangle_spans[initialrightheight + height].count = INT_MIN; // mark end of the spanpackages + prightbottom->u, prightbottom->v); (*d_pdrawspans) (currententity, pstart); } } - /* ================ R_PolysetSetEdgeTable From 784f35faeda47d2a6bf771629d8c66695cfd1e1d Mon Sep 17 00:00:00 2001 From: Denis Date: Mon, 1 Apr 2024 20:49:40 +0300 Subject: [PATCH 4/4] move ifdef into function --- src/client/refresh/soft/sw_polyset.c | 31 ++++++++++------------------ 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/src/client/refresh/soft/sw_polyset.c b/src/client/refresh/soft/sw_polyset.c index 30fc46c4..a512fb72 100644 --- a/src/client/refresh/soft/sw_polyset.c +++ b/src/client/refresh/soft/sw_polyset.c @@ -291,13 +291,13 @@ quotient must fit in 32 bits. FIXME: GET RID OF THIS! (FloorDivMod) ==================== */ -#if defined(__i386__) || defined(__amd64__) -// just exclude ARM32 with FPU, e.g. Pi 1 static void FloorDivMod(int numer, int denom, int *quo, int *rem) { int q, r; +// just exclude ARM32 with FPU, e.g. Pi 1 +#if defined(__i386__) || defined(__amd64__) q = numer / denom; r = numer - q * denom; if (-1/2 || 1/-2 || -1/-2) { @@ -313,7 +313,6 @@ FloorDivMod(int numer, int denom, int *quo, int *rem) r += denom; } } - assert(r == numer - q * denom); if ((numer < 0) ^ (denom < 0)) assert(q <= 0); else @@ -322,43 +321,35 @@ FloorDivMod(int numer, int denom, int *quo, int *rem) assert(r > denom && r <= 0); else assert(r >= 0 && r < denom); - *quo = q; - *rem = r; -} #else -static void -FloorDivMod (float numer, float denom, int *quotient, - int *rem) -{ - int q, r; + float num = numer, den = denom; float x; - if (numer >= 0.0) + if (numer >= 0) { - x = floor(numer / denom); + x = floor(num / den); q = (int)x; - r = (int)floor(numer - (x * denom)); + r = (int)floor(num - (x * den)); } else { // // perform operations with positive values, and fix mod to make floor-based // - x = floor(-numer / denom); + x = floor(-num / den); q = -(int)x; - r = (int)floor(-numer - (x * denom)); + r = (int)floor(-num - (x * den)); if (r != 0) { q--; - r = (int)denom - r; + r = denom - r; } } - - *quotient = q; +#endif + *quo = q; *rem = r; } -#endif /* ===================