{
int i, topidx, botidx, mididx;
int32_t dx, dy, dym;
+ int32_t v01x, v01y, v02x, v02y;
struct g3d_vertex vtmp;
+ /* calculate winding */
+ v01x = verts[1].x - verts[0].x;
+ v01y = verts[1].y - verts[0].y;
+ v02x = verts[2].x - verts[0].x;
+ v02y = verts[2].y - verts[0].y;
+ if(!((v01x * v02y - v02x * v01y) & 0x80000000)) {
+ return;
+ }
+
topidx = botidx = 0;
for(i=1; i<3; i++) {
if(verts[i].y < verts[topidx].y) {
botidx = i;
}
}
- mididx = (topidx + 1) % 3;
- if(mididx == botidx) mididx = (mididx + 1) % 3;
+ mididx = topidx + 1; if(mididx > 2) mididx = 0;
+ if(mididx == botidx) {
+ if(++mididx > 2) mididx = 0;
+ }
dy = verts[botidx].y - verts[topidx].y;
if(dy == 0) return;
static void filltop(struct g3d_vertex *v0, struct g3d_vertex *v1, struct g3d_vertex *v2)
{
struct g3d_vertex *vtmp;
- int x, xn, y, endy, len;
- int32_t xl, xr, dxl, dxr, dxldy, dxrdy, dy;
+ int x, xn, line, lasty, len;
+ int32_t xl, xr, dxl, dxr, slopel, sloper, dy;
+ int32_t y0, y1, yoffs;
unsigned char *fbptr;
if(v1->x > v2->x) {
v2 = vtmp;
}
- y = v0->y >> 8;
- endy = v1->y >> 8;
- if(endy > YRES) endy = YRES;
- x = v0->x >> 8;
-
- fbptr = g3d_fbpixels + y * XRES + x;
-
- xl = xr = v0->x;
dy = v1->y - v0->y;
dxl = v1->x - v0->x;
dxr = v2->x - v0->x;
- dxldy = (dxl << 8) / dy;
- dxrdy = (dxr << 8) / dy;
+ slopel = (dxl << 8) / dy;
+ sloper = (dxr << 8) / dy;
+
+ y0 = (v0->y + 0x100) & 0xffffff00; /* start from the next scanline */
+ yoffs = y0 - v0->y; /* offset of the next scanline */
+ xl = v0->x + ((yoffs * slopel) >> 8);
+ xr = v0->x + ((yoffs * sloper) >> 8);
+
+ line = y0 >> 8;
+ lasty = v1->y >> 8;
+ if(lasty >= YRES) lasty = YRES - 1;
+ x = xl >> 8;
- while(y++ < endy) {
- if(y > 0) {
- len = (xr - xl) >> 8;
+ fbptr = g3d_fbpixels + line * XRES + x;
+
+ while(line <= lasty) {
+ if(line >= 0) {
+ len = ((xr + 0x100) >> 8) - (xl >> 8);
if(len > 0) memset(fbptr, g3d_curcidx, len);
}
- xl += dxldy;
- xr += dxrdy;
+ xl += slopel;
+ xr += sloper;
xn = xl >> 8;
fbptr += XRES + (xn - x);
x = xn;
+ line++;
}
}
static void fillbot(struct g3d_vertex *v0, struct g3d_vertex *v1, struct g3d_vertex *v2)
{
struct g3d_vertex *vtmp;
- int x, xn, y, endy, len;
- int32_t xl, xr, dxl, dxr, dxldy, dxrdy, dy;
+ int x, xn, line, lasty, len;
+ int32_t xl, xr, dxl, dxr, slopel, sloper, dy;
+ int32_t y0, y1, yoffs;
unsigned char *fbptr;
if(v0->x > v1->x) {
v1 = vtmp;
}
- y = v0->y >> 8;
- endy = v2->y >> 8;
- if(endy > YRES) endy = YRES;
- x = v0->x >> 8;
-
- fbptr = g3d_fbpixels + y * XRES + x;
-
- xl = v0->x;
- xr = v1->x;
dy = v2->y - v0->y;
dxl = v2->x - v0->x;
dxr = v2->x - v1->x;
- dxldy = (dxl << 8) / dy;
- dxrdy = (dxr << 8) / dy;
+ slopel = (dxl << 8) / dy;
+ sloper = (dxr << 8) / dy;
+
+ y0 = (v0->y + 0x100) & 0xffffff00; /* start from the next scanline */
+ yoffs = y0 - v0->y; /* offset of the next scanline */
+ xl = v0->x + ((yoffs * slopel) >> 8);
+ xr = v1->x + ((yoffs * sloper) >> 8);
+
+ line = y0 >> 8;
+ lasty = v2->y >> 8;
+ if(lasty >= YRES) lasty = YRES - 1;
+ x = xl >> 8;
+
+ fbptr = g3d_fbpixels + line * XRES + x;
- while(y++ < endy) {
- if(y > 0) {
- len = (xr - xl) >> 8;
+ while(line <= lasty) {
+ if(line >= 0) {
+ len = ((xr + 0x100) >> 8) - (xl >> 8);
if(len > 0) memset(fbptr, g3d_curcidx, len);
}
- xl += dxldy;
- xr += dxrdy;
+ xl += slopel;
+ xr += sloper;
xn = xl >> 8;
fbptr += XRES + (xn - x);
x = xn;
+ line++;
}
}