removed clang-format and clang_complete files from the repo
[dosdemo] / src / 3dgfx / polytmpl.h
1 static uint32_t SCANEDGE(struct pvertex *v0, struct pvertex *v1, struct pvertex *edge)
2 {
3         int i;
4         int32_t x, dx, dy, slope;
5 #ifdef GOURAUD
6         int r, g, b, dr, dg, db;
7         int32_t rslope, gslope, bslope;
8 #ifdef BLEND_ALPHA
9         int32_t a, da, aslope;
10 #endif
11 #endif  /* GOURAUD */
12 #ifdef TEXMAP
13         int32_t u, v, du, dv, uslope, vslope;
14 #endif
15 #ifdef ZBUF
16         int32_t z, dz, zslope;
17 #endif
18         int32_t start_idx, end_idx;
19
20         if(v0->y > v1->y) {
21                 struct pvertex *tmp = v0;
22                 v0 = v1;
23                 v1 = tmp;
24         }
25
26         x = v0->x;
27         dy = v1->y - v0->y;
28         dx = v1->x - v0->x;
29         slope = (dx << 8) / dy;
30 #ifdef GOURAUD
31         r = (v0->r << COLOR_SHIFT);
32         g = (v0->g << COLOR_SHIFT);
33         b = (v0->b << COLOR_SHIFT);
34         dr = (v1->r << COLOR_SHIFT) - r;
35         dg = (v1->g << COLOR_SHIFT) - g;
36         db = (v1->b << COLOR_SHIFT) - b;
37         rslope = (dr << 8) / dy;
38         gslope = (dg << 8) / dy;
39         bslope = (db << 8) / dy;
40 #ifdef BLEND_ALPHA
41         a = (v0->a << COLOR_SHIFT);
42         da = (v1->a << COLOR_SHIFT) - a;
43         aslope = (da << 8) / dy;
44 #endif  /* BLEND_ALPHA */
45 #endif  /* GOURAUD */
46 #ifdef TEXMAP
47         u = v0->u;
48         v = v0->v;
49         du = v1->u - v0->u;
50         dv = v1->v - v0->v;
51         uslope = (du << 8) / dy;
52         vslope = (dv << 8) / dy;
53 #endif
54 #ifdef ZBUF
55         z = v0->z;
56         dz = v1->z - v0->z;
57         zslope = (dz << 8) / dy;
58 #endif
59
60         start_idx = v0->y >> 8;
61         end_idx = v1->y >> 8;
62
63         for(i=start_idx; i<end_idx; i++) {
64                 CHECKEDGE(i);
65                 edge[i].x = x;
66                 x += slope;
67 #ifdef GOURAUD
68                 /* we'll store the color in the edge tables with COLOR_SHIFT extra bits of precision */
69                 edge[i].r = r;
70                 edge[i].g = g;
71                 edge[i].b = b;
72                 r += rslope;
73                 g += gslope;
74                 b += bslope;
75 #ifdef BLEND_ALPHA
76                 edge[i].a = a;
77                 a += aslope;
78 #endif
79 #endif  /* GOURAUD */
80 #ifdef TEXMAP
81                 edge[i].u = u;
82                 edge[i].v = v;
83                 u += uslope;
84                 v += vslope;
85 #endif
86 #ifdef ZBUF
87                 edge[i].z = z;
88                 z += zslope;
89 #endif
90         }
91
92         return (uint32_t)start_idx | ((uint32_t)(end_idx - 1) << 16);
93 }
94
95 void POLYFILL(struct pvertex *pv, int nverts)
96 {
97         int i, winding;
98         int topidx = 0, botidx = 0, sltop = pfill_fb.height, slbot = 0;
99         g3d_pixel color;
100         /* the following variables are used for interpolating horizontally accros scanlines */
101 #if defined(GOURAUD) || defined(TEXMAP) || defined(ZBUF)
102         int mid;
103         int32_t dx, tmp;
104 #endif
105 #ifdef GOURAUD
106         int32_t r, g, b, dr, dg, db, rslope, gslope, bslope;
107 #ifdef BLEND_ALPHA
108         int32_t a, da, aslope;
109 #endif
110 #endif
111 #ifdef TEXMAP
112         int32_t u, v, du, dv, uslope, vslope;
113 #endif
114 #ifdef ZBUF
115         int32_t z, dz, zslope;
116 #endif
117
118 #if !defined(GOURAUD) && !defined(TEXMAP)
119         /* flat version, just pack the color now */
120         color = G3D_PACK_RGB(pv[0].r, pv[0].g, pv[0].b);
121 #endif
122
123         for(i=1; i<nverts; i++) {
124                 if(pv[i].y < pv[topidx].y) topidx = i;
125                 if(pv[i].y > pv[botidx].y) botidx = i;
126         }
127
128         winding = 0;
129         for(i=0; i<nverts; i++) {
130                 int next = NEXTIDX(i);
131                 winding += ((pv[next].x - pv[i].x) >> 4) * ((pv[next].y + pv[i].y) >> 4);
132         }
133
134         for(i=0; i<nverts; i++) {
135                 int next = NEXTIDX(i);
136                 int32_t y0 = pv[i].y;
137                 int32_t y1 = pv[next].y;
138
139                 if((y0 >> 8) == (y1 >> 8)) {
140                         /*if(y0 > y1) {*/
141                                 int i0, i1;
142                                 int idx = y0 >> 8;
143                                 if(pv[i].x < pv[next].x) {
144                                         i0 = i;
145                                         i1 = next;
146                                 } else {
147                                         i0 = next;
148                                         i1 = i;
149                                 }
150                                 CHECKEDGE(idx);
151                                 left[idx].x = pv[i0].x;
152                                 right[idx].x = pv[i1].x;
153 #ifdef GOURAUD
154                                 left[idx].r = pv[i0].r << COLOR_SHIFT;
155                                 left[idx].g = pv[i0].g << COLOR_SHIFT;
156                                 left[idx].b = pv[i0].b << COLOR_SHIFT;
157                                 right[idx].r = pv[i1].r << COLOR_SHIFT;
158                                 right[idx].g = pv[i1].g << COLOR_SHIFT;
159                                 right[idx].b = pv[i1].b << COLOR_SHIFT;
160 #ifdef BLEND_ALPHA
161                                 left[idx].a = pv[i0].a << COLOR_SHIFT;
162                                 right[idx].a = pv[i1].a << COLOR_SHIFT;
163 #endif  /* BLEND_ALPHA */
164 #endif
165 #ifdef TEXMAP
166                                 left[idx].u = pv[i0].u;
167                                 left[idx].v = pv[i0].v;
168                                 right[idx].u = pv[i1].u;
169                                 right[idx].v = pv[i1].v;
170 #endif
171 #ifdef ZBUF
172                                 left[idx].z = pv[i0].z;
173                                 right[idx].z = pv[i1].z;
174 #endif
175                                 CHECKEDGE(idx);
176                                 if(idx > slbot) slbot = idx;
177                                 if(idx < sltop) sltop = idx;
178                         /*}*/
179                 } else {
180                         struct pvertex *edge;
181                         uint32_t res, tmp;
182
183                         if(winding < 0) {
184                                 /* clockwise */
185                                 edge = y0 > y1 ? left : right;
186                         } else {
187                                 /* counter-clockwise */
188                                 edge = y0 > y1 ? right : left;
189                         }
190                         res = SCANEDGE(pv + i, pv + next, edge);
191                         tmp = (res >> 16) & 0xffff;
192                         if(tmp > slbot) slbot = tmp;
193                         if((tmp = res & 0xffff) < sltop) {
194                                 sltop = tmp;
195                         }
196                 }
197         }
198
199         /* calculate the slopes of all attributes across the largest span out
200          * of the three: middle, top, or bottom.
201          */
202 #ifndef HIGH_QUALITY
203 #if defined(GOURAUD) || defined(TEXMAP)
204         mid = (sltop + slbot) >> 1;
205         CHECKEDGE(sltop);
206         CHECKEDGE(slbot);
207         CHECKEDGE(mid);
208         dx = right[mid].x - left[mid].x;
209         if((tmp = right[sltop].x - left[sltop].x) > dx) {
210                 dx = tmp;
211                 mid = sltop;
212         }
213         if((tmp = right[slbot].x - left[slbot].x) > dx) {
214                 dx = tmp;
215                 mid = slbot;
216         }
217         if(!dx) dx = 256;       /* avoid division by zero */
218 #endif
219         CHECKEDGE(idx);
220 #ifdef GOURAUD
221         dr = right[mid].r - left[mid].r;
222         dg = right[mid].g - left[mid].g;
223         db = right[mid].b - left[mid].b;
224         rslope = (dr << 8) / dx;
225         gslope = (dg << 8) / dx;
226         bslope = (db << 8) / dx;
227 #ifdef BLEND_ALPHA
228         da = right[mid].a - left[mid].a;
229         aslope = (da << 8) / dx;
230 #endif  /* BLEND_ALPHA */
231 #endif
232 #ifdef TEXMAP
233         du = right[mid].u - left[mid].u;
234         dv = right[mid].v - left[mid].v;
235         uslope = (du << 8) / dx;
236         vslope = (dv << 8) / dx;
237 #endif
238 #ifdef ZBUF
239         dz = right[mid].z - left[mid].z;
240         zslope = (dz << 8) / dx;
241 #endif
242 #endif  /* !defined(HIGH_QUALITY) */
243
244         /* for each scanline ... */
245         for(i=sltop; i<=slbot; i++) {
246                 g3d_pixel *pixptr;
247                 int32_t x;
248 #ifdef ZBUF
249                 uint16_t *zptr;
250 #endif
251
252                 CHECKEDGE(i);
253                 x = left[i].x;
254                 pixptr = pfill_fb.pixels + i * pfill_fb.width + (x >> 8);
255
256 #ifdef GOURAUD
257                 r = left[i].r;
258                 g = left[i].g;
259                 b = left[i].b;
260 #ifdef BLEND_ALPHA
261                 a = left[i].a;
262 #endif  /* BLEND_ALPHA */
263 #endif
264 #ifdef TEXMAP
265                 u = left[i].u;
266                 v = left[i].v;
267 #endif
268 #ifdef ZBUF
269                 z = left[i].z;
270                 zptr = pfill_zbuf + i * pfill_fb.width + (x >> 8);
271 #endif
272                 CHECKEDGE(i);
273
274 #if defined(HIGH_QUALITY) && (defined(GOURAUD) || defined(TEXMAP) || defined(ZBUF))
275                 if(!(dx = right[i].x - left[i].x)) dx = 256;
276
277                 CHECKEDGE(i);
278 #ifdef GOURAUD
279                 dr = right[i].r - left[i].r;
280                 dg = right[i].g - left[i].g;
281                 db = right[i].b - left[i].b;
282                 rslope = (dr << 8) / dx;
283                 gslope = (dg << 8) / dx;
284                 bslope = (db << 8) / dx;
285 #ifdef BLEND_ALPHA
286                 da = right[i].a - left[i].a;
287                 aslope = (da << 8) / dx;
288 #endif  /* BLEND_ALPHA */
289 #endif  /* GOURAUD */
290 #ifdef TEXMAP
291                 du = right[i].u - left[i].u;
292                 dv = right[i].v - left[i].v;
293                 uslope = (du << 8) / dx;
294                 vslope = (dv << 8) / dx;
295 #endif
296 #ifdef ZBUF
297                 dz = right[i].z - left[i].z;
298                 zslope = (dz << 8) / dx;
299 #endif
300 #endif  /* HIGH_QUALITY */
301                 CHECKEDGE(i);
302
303                 /* go across the scanline interpolating if necessary */
304                 while(x <= right[i].x) {
305                         /*if(x == (180 << 8) && i == 174) {
306                                 asm("int $3");
307                         }*/
308 #if defined(GOURAUD) || defined(TEXMAP) || defined(BLEND_ALPHA) || defined(BLEND_ADD)
309                         int cr, cg, cb;
310 #endif
311 #if defined(BLEND_ALPHA) || defined(BLEND_ADD)
312                         g3d_pixel fbcol;
313 #endif
314 #ifdef BLEND_ALPHA
315                         int alpha, inv_alpha;
316 #endif
317
318 #ifdef ZBUF
319                         int32_t cz = z;
320                         z += zslope;
321
322                         if(z <= *zptr) {
323                                 *zptr++ = z;
324                         } else {
325 #ifdef GOURAUD
326                                 r += rslope;
327                                 g += gslope;
328                                 b += bslope;
329 #ifdef BLEND_ALPHA
330                                 a += aslope;
331 #endif
332 #endif
333 #ifdef TEXMAP
334                                 u += uslope;
335                                 v += vslope;
336 #endif
337                                 /* skip pixel */
338                                 pixptr++;
339                                 zptr++;
340                                 x += 256;
341                                 continue;
342                         }
343 #endif
344
345 #ifdef GOURAUD
346                         /* we upped the color precision to while interpolating the
347                          * edges, now drop the extra bits before packing
348                          */
349                         cr = r < 0 ? 0 : (r >> COLOR_SHIFT);
350                         cg = g < 0 ? 0 : (g >> COLOR_SHIFT);
351                         cb = b < 0 ? 0 : (b >> COLOR_SHIFT);
352                         r += rslope;
353                         g += gslope;
354                         b += bslope;
355 #ifdef BLEND_ALPHA
356                         a += aslope;
357 #else
358                         if(cr > 255) cr = 255;
359                         if(cg > 255) cg = 255;
360                         if(cb > 255) cb = 255;
361 #endif  /* BLEND_ALPHA */
362 #endif  /* GOURAUD */
363 #ifdef TEXMAP
364                         {
365                                 int tx = (u >> (16 - pfill_tex.xshift)) & pfill_tex.xmask;
366                                 int ty = (v >> (16 - pfill_tex.yshift)) & pfill_tex.ymask;
367                                 g3d_pixel texel = pfill_tex.pixels[(ty << pfill_tex.xshift) + tx];
368 #ifdef GOURAUD
369                                 /* This is not correct, should be /255, but it's much faster
370                                  * to shift by 8 (/256), and won't make a huge difference
371                                  */
372                                 cr = (cr * G3D_UNPACK_R(texel)) >> 8;
373                                 cg = (cg * G3D_UNPACK_G(texel)) >> 8;
374                                 cb = (cb * G3D_UNPACK_B(texel)) >> 8;
375 #else
376                                 cr = G3D_UNPACK_R(texel);
377                                 cg = G3D_UNPACK_G(texel);
378                                 cb = G3D_UNPACK_B(texel);
379 #endif
380                         }
381                         u += uslope;
382                         v += vslope;
383 #endif
384
385 #if defined(BLEND_ALPHA) || defined(BLEND_ADD)
386 #if !defined(GOURAUD) && !defined(TEXMAP)
387                         /* flat version: cr,cg,cb are uninitialized so far */
388                         cr = pv[0].r;
389                         cg = pv[0].g;
390                         cb = pv[0].b;
391 #endif
392                         fbcol = *pixptr;
393
394 #ifdef BLEND_ALPHA
395 #ifdef GOURAUD
396                         alpha = a >> COLOR_SHIFT;
397 #else
398                         alpha = pv[0].a;
399 #endif
400                         inv_alpha = 255 - alpha;
401                         cr = (cr * alpha + G3D_UNPACK_R(fbcol) * inv_alpha) >> 8;
402                         cg = (cg * alpha + G3D_UNPACK_G(fbcol) * inv_alpha) >> 8;
403                         cb = (cb * alpha + G3D_UNPACK_B(fbcol) * inv_alpha) >> 8;
404 #else   /* !BLEND_ALPHA (so BLEND_ADD) */
405                         cr += G3D_UNPACK_R(fbcol);
406                         cg += G3D_UNPACK_R(fbcol);
407                         cb += G3D_UNPACK_R(fbcol);
408 #endif
409                         if(cr > 255) cr = 255;
410                         if(cg > 255) cg = 255;
411                         if(cb > 255) cb = 255;
412 #endif  /* BLEND(ALPHA|ADD) */
413
414 #if defined(GOURAUD) || defined(TEXMAP) || defined(BLEND_ALPHA) || defined(BLEND_ADD)
415                         color = G3D_PACK_RGB(cr, cg, cb);
416 #endif
417
418 #ifdef DEBUG_OVERDRAW
419                         *pixptr++ += DEBUG_OVERDRAW;
420 #else
421                         *pixptr++ = color;
422 #endif
423                         x += 256;
424                 }
425         }
426 }
427