1 static uint32_t SCANEDGE(struct pvertex *v0, struct pvertex *v1, struct pvertex *edge)
4 int32_t x, dx, dy, slope;
6 int r, g, b, dr, dg, db;
7 int32_t rslope, gslope, bslope;
10 int32_t u, v, du, dv, uslope, vslope;
12 int32_t start_idx, end_idx;
15 struct pvertex *tmp = v0;
23 slope = (dx << 8) / dy;
28 dr = (v1->r << 8) - r;
29 dg = (v1->g << 8) - g;
30 db = (v1->b << 8) - b;
31 rslope = (dr << 8) / dy;
32 gslope = (dg << 8) / dy;
33 bslope = (db << 8) / dy;
40 uslope = (du << 8) / dy;
41 vslope = (dv << 8) / dy;
44 start_idx = v0->y >> 8;
47 for(i=start_idx; i<end_idx; i++) {
51 /* we'll store the color in the edge tables with 8 extra bits of precision */
67 return (uint32_t)start_idx | ((uint32_t)(end_idx - 1) << 16);
70 void POLYFILL(struct pvertex *pv, int nverts)
73 int topidx = 0, botidx = 0, sltop = pimg_fb.height, slbot = 0;
74 struct pvertex *left, *right;
76 /* the following variables are used for interpolating horizontally accros scanlines */
77 #if defined(GOURAUD) || defined(TEXMAP)
81 /* flat version, just pack the color now */
82 color = PACK_RGB16(pv[0].r, pv[0].g, pv[0].b);
85 int32_t r, g, b, dr, dg, db, rslope, gslope, bslope;
88 int32_t u, v, du, dv, uslope, vslope;
91 for(i=1; i<nverts; i++) {
92 if(pv[i].y < pv[topidx].y) topidx = i;
93 if(pv[i].y > pv[botidx].y) botidx = i;
96 left = alloca(pimg_fb.height * sizeof *left);
97 right = alloca(pimg_fb.height * sizeof *right);
99 for(i=0; i<nverts; i++) {
100 int next = NEXTIDX(i);
101 int32_t y0 = pv[i].y;
102 int32_t y1 = pv[next].y;
104 if((y0 >> 8) == (y1 >> 8)) {
107 left[idx].x = pv[i].x < pv[next].x ? pv[i].x : pv[next].x;
108 right[idx].x = pv[i].x < pv[next].x ? pv[next].x : pv[i].x;
111 struct pvertex *edge = y0 > y1 ? left : right;
112 uint32_t res = SCANEDGE(pv + i, pv + next, edge);
113 uint32_t tmp = (res >> 16) & 0xffff;
114 if(tmp > slbot) slbot = tmp;
115 if((tmp = res & 0xffff) < sltop) {
121 /* find the mid-point and calculate slopes for all attributes */
123 #if defined(GOURAUD) || defined(TEXMAP)
124 mid = (sltop + slbot) >> 1;
125 dx = right[mid].x - left[mid].x;
126 if((tmp = right[sltop].x - left[sltop].x) > dx) {
130 if((tmp = right[slbot].x - left[slbot].x) > dx) {
139 dr = right[mid].r - left[mid].r;
140 dg = right[mid].g - left[mid].g;
141 db = right[mid].b - left[mid].b;
142 rslope = (dr << 8) / dx;
143 gslope = (dg << 8) / dx;
144 bslope = (db << 8) / dx;
147 du = right[mid].u - left[mid].u;
148 dv = right[mid].v - left[mid].v;
149 uslope = (du << 8) / dx;
150 vslope = (dv << 8) / dx;
154 for(i=sltop; i<=slbot; i++) {
159 pixptr = pimg_fb.pixels + i * pimg_fb.width + (x >> 8);
161 #if defined(GOURAUD) || defined(TEXMAP)
162 if(!(dx = right[i].x - left[i].x)) dx = 256; /* 1 */
168 dr = right[i].r - left[i].r;
169 dg = right[i].g - left[i].g;
170 db = right[i].b - left[i].b;
171 rslope = (dr << 8) / dx;
172 gslope = (dg << 8) / dx;
173 bslope = (db << 8) / dx;
178 du = right[i].u - left[i].u;
179 dv = right[i].v - left[i].v;
180 uslope = (du << 8) / dx;
181 vslope = (dv << 8) / dx;
184 while(x <= right[i].x) {
186 /* drop the extra 8 bits when packing */
190 color = PACK_RGB16(cr, cg, cb);
201 #ifdef DEBUG_OVERDRAW
202 *pixptr++ += DEBUG_OVERDRAW;