#include <stdio.h>
#include <string.h>
#include "3dgfx.h"
+#include "video.h"
#include "util.h"
static void filltop(struct g3d_vertex *v0, struct g3d_vertex *v1, struct g3d_vertex *v2);
static void fillbot(struct g3d_vertex *v0, struct g3d_vertex *v1, struct g3d_vertex *v2);
+static void fillspan(unsigned char *dest, int x, int len);
void g3d_polyfill(struct g3d_vertex *verts)
{
static void filltop(struct g3d_vertex *v0, struct g3d_vertex *v1, struct g3d_vertex *v2)
{
struct g3d_vertex *vtmp;
- int x, xn, line, lasty, len;
+ int x, line, lasty, len;
int32_t xl, xr, dxl, dxr, slopel, sloper, dy;
int32_t y0, y1, yoffs;
unsigned char *fbptr;
if(lasty >= YRES) lasty = YRES - 1;
x = xl >> 8;
- fbptr = g3d_fbpixels + line * XRES + x;
+ fbptr = g3d_fbpixels + line * (XRES >> 2);
while(line <= lasty) {
if(line >= 0) {
len = ((xr + 0x100) >> 8) - (xl >> 8);
- if(len > 0) memset(fbptr, g3d_curcidx, len);
+ if(len > 0) fillspan(fbptr, x, len);
}
xl += slopel;
xr += sloper;
- xn = xl >> 8;
- fbptr += XRES + (xn - x);
- x = xn;
+ x = xl >> 8;
+ fbptr += XRES >> 2;
line++;
}
}
static void fillbot(struct g3d_vertex *v0, struct g3d_vertex *v1, struct g3d_vertex *v2)
{
struct g3d_vertex *vtmp;
- int x, xn, line, lasty, len;
+ int x, line, lasty, len;
int32_t xl, xr, dxl, dxr, slopel, sloper, dy;
int32_t y0, y1, yoffs;
unsigned char *fbptr;
if(lasty >= YRES) lasty = YRES - 1;
x = xl >> 8;
- fbptr = g3d_fbpixels + line * XRES + x;
+ fbptr = g3d_fbpixels + line * (XRES >> 2);
while(line <= lasty) {
if(line >= 0) {
len = ((xr + 0x100) >> 8) - (xl >> 8);
- if(len > 0) memset(fbptr, g3d_curcidx, len);
+ if(len > 0) fillspan(fbptr, x, len);
}
xl += slopel;
xr += sloper;
- xn = xl >> 8;
- fbptr += XRES + (xn - x);
- x = xn;
+ x = xl >> 8;
+ fbptr += XRES >> 2;
line++;
}
}
+
+static void fillspan(unsigned char *dest, int x, int len)
+{
+ unsigned int mask = 0xf;
+ int align;
+
+ dest += x >> 2;
+
+ if(len < 4) mask >>= 4 - len;
+
+ /* handle the start of the span. The x offset alignment affects:
+ * 1. which bitplane to start from, adjust the plane mask accordingly.
+ * 2. how many pixels we write, adjust remaining length accordingly.
+ */
+ align = x & 3;
+ vid_setmask(mask << align);
+ *dest++ = g3d_curcidx;
+ len -= 4 - align;
+
+ /* the middle part of the span is all written 4 pixels at a time by
+ * enabling all 4 bit planes.
+ */
+ if(len >= 4) {
+ vid_setmask(0xf);
+ while(len >= 4) {
+ *dest++ = g3d_curcidx;
+ len -= 4;
+ }
+ }
+
+ /* handle any leftovers at the end */
+ if(len) {
+ mask = 0xf >> (4 - len);
+ vid_setmask(mask);
+ *dest = g3d_curcidx;
+ }
+}