250c152efe5e491dda7c6dceb7b842d5fca47acc
[retroray] / src / gaw / polyfill.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <assert.h>
5 #include "polyfill.h"
6
7 /*#define DEBUG_OVERDRAW        PACK_RGB(10, 10, 10)*/
8
9 #define FILL_POLY_BITS  0x03
10
11
12 /* mode bits: 00-wire 01-flat 10-gouraud 11-reserved
13  *     bit 2: texture
14  *     bit 3-4: blend mode: 00-none 01-alpha 10-additive 11-reserved
15  *     bit 5: zbuffering
16  */
17 void (*fillfunc[])(struct pvertex*, int) = {
18         polyfill_wire,
19         polyfill_flat,
20         polyfill_gouraud,
21         0,
22         polyfill_tex_wire,
23         polyfill_tex_flat,
24         polyfill_tex_gouraud,
25         0,
26         polyfill_alpha_wire,
27         polyfill_alpha_flat,
28         polyfill_alpha_gouraud,
29         0,
30         polyfill_alpha_tex_wire,
31         polyfill_alpha_tex_flat,
32         polyfill_alpha_tex_gouraud,
33         0,
34         polyfill_add_wire,
35         polyfill_add_flat,
36         polyfill_add_gouraud,
37         0,
38         polyfill_add_tex_wire,
39         polyfill_add_tex_flat,
40         polyfill_add_tex_gouraud,
41         0, 0, 0, 0, 0, 0, 0, 0, 0,
42         polyfill_wire,
43         polyfill_flat_zbuf,
44         polyfill_gouraud_zbuf,
45         0,
46         polyfill_tex_wire,
47         polyfill_tex_flat_zbuf,
48         polyfill_tex_gouraud_zbuf,
49         0,
50         polyfill_alpha_wire,
51         polyfill_alpha_flat_zbuf,
52         polyfill_alpha_gouraud_zbuf,
53         0,
54         polyfill_alpha_tex_wire,
55         polyfill_alpha_tex_flat_zbuf,
56         polyfill_alpha_tex_gouraud_zbuf,
57         0,
58         polyfill_add_wire,
59         polyfill_add_flat_zbuf,
60         polyfill_add_gouraud_zbuf,
61         0,
62         polyfill_add_tex_wire,
63         polyfill_add_tex_flat_zbuf,
64         polyfill_add_tex_gouraud_zbuf,
65         0, 0, 0, 0, 0, 0, 0, 0, 0
66 };
67
68 struct pimage pfill_fb, pfill_tex;
69 uint32_t *pfill_zbuf;
70
71 #define EDGEPAD 8
72 static struct pvertex *edgebuf, *left, *right;
73 static int edgebuf_size;
74 static int fbheight;
75
76 /*
77 #define CHECKEDGE(x) \
78         do { \
79                 assert(x >= 0); \
80                 assert(x < fbheight); \
81         } while(0)
82 */
83 #define CHECKEDGE(x)
84
85
86 void polyfill_fbheight(int height)
87 {
88         int newsz = (height * 2 + EDGEPAD * 3) * sizeof *edgebuf;
89
90         if(newsz > edgebuf_size) {
91                 free(edgebuf);
92                 if(!(edgebuf = malloc(newsz))) {
93                         fprintf(stderr, "failed to allocate edge table buffer (%d bytes)\n", newsz);
94                         abort();
95                 }
96                 edgebuf_size = newsz;
97
98                 left = edgebuf + EDGEPAD;
99                 right = edgebuf + height + EDGEPAD * 2;
100
101 #ifndef NDEBUG
102                 memset(edgebuf, 0xaa, EDGEPAD * sizeof *edgebuf);
103                 memset(edgebuf + height + EDGEPAD, 0xaa, EDGEPAD * sizeof *edgebuf);
104                 memset(edgebuf + height * 2 + EDGEPAD * 2, 0xaa, EDGEPAD * sizeof *edgebuf);
105 #endif
106         }
107
108         fbheight = height;
109 }
110
111 void polyfill(int mode, struct pvertex *verts, int nverts)
112 {
113 #ifndef NDEBUG
114         if(!fillfunc[mode]) {
115                 fprintf(stderr, "polyfill mode %d not implemented\n", mode);
116                 abort();
117         }
118 #endif
119
120         fillfunc[mode](verts, nverts);
121 }
122
123 void polyfill_wire(struct pvertex *verts, int nverts)
124 {
125         /*
126         int i, x0, y0, x1, y1;
127         struct pvertex *v = verts;
128         uint32_t color = PACK_RGB(v->r, v->g, v->b);
129
130         for(i=0; i<nverts - 1; i++) {
131                 x0 = v->x >> 8;
132                 y0 = v->y >> 8;
133                 ++v;
134                 x1 = v->x >> 8;
135                 y1 = v->y >> 8;
136                 if(clip_line(&x0, &y0, &x1, &y1, 0, 0, pfill_fb.width, pfill_fb.height)) {
137                         draw_line(x0, y0, x1, y1, color);
138                 }
139         }
140         x0 = verts[0].x >> 8;
141         y0 = verts[0].y >> 8;
142         if(clip_line(&x1, &y1, &x0, &y0, 0, 0, pfill_fb.width, pfill_fb.height)) {
143                 draw_line(x1, y1, x0, y0, color);
144         }
145         */
146 }
147
148 void polyfill_tex_wire(struct pvertex *verts, int nverts)
149 {
150         polyfill_wire(verts, nverts);   /* TODO */
151 }
152
153 void polyfill_alpha_wire(struct pvertex *verts, int nverts)
154 {
155         polyfill_wire(verts, nverts);   /* TODO */
156 }
157
158 void polyfill_alpha_tex_wire(struct pvertex *verts, int nverts)
159 {
160         polyfill_wire(verts, nverts);   /* TODO */
161 }
162
163 void polyfill_add_wire(struct pvertex *verts, int nverts)
164 {
165         polyfill_wire(verts, nverts);   /* TODO */
166 }
167
168 void polyfill_add_tex_wire(struct pvertex *verts, int nverts)
169 {
170         polyfill_wire(verts, nverts);   /* TODO */
171 }
172
173 #define VNEXT(p)        (((p) == vlast) ? varr : (p) + 1)
174 #define VPREV(p)        ((p) == varr ? vlast : (p) - 1)
175 #define VSUCC(p, side)  ((side) == 0 ? VNEXT(p) : VPREV(p))
176
177 /* extra bits of precision to use when interpolating colors.
178  * try tweaking this if you notice strange quantization artifacts.
179  */
180 #define COLOR_SHIFT     12
181
182
183 #define POLYFILL polyfill_flat
184 #undef GOURAUD
185 #undef TEXMAP
186 #undef BLEND_ALPHA
187 #undef BLEND_ADD
188 #undef ZBUF
189 #include "polytmpl.h"
190 #undef POLYFILL
191
192 #define POLYFILL polyfill_gouraud
193 #define GOURAUD
194 #undef TEXMAP
195 #undef BLEND_ALPHA
196 #undef BLEND_ADD
197 #undef ZBUF
198 #include "polytmpl.h"
199 #undef POLYFILL
200
201 #define POLYFILL polyfill_tex_flat
202 #undef GOURAUD
203 #define TEXMAP
204 #undef BLEND_ALPHA
205 #undef BLEND_ADD
206 #undef ZBUF
207 #include "polytmpl.h"
208 #undef POLYFILL
209
210 #define POLYFILL polyfill_tex_gouraud
211 #define GOURAUD
212 #define TEXMAP
213 #undef BLEND_ALPHA
214 #undef BLEND_ADD
215 #undef ZBUF
216 #include "polytmpl.h"
217 #undef POLYFILL
218
219 #define POLYFILL polyfill_alpha_flat
220 #undef GOURAUD
221 #undef TEXMAP
222 #define BLEND_ALPHA
223 #undef BLEND_ADD
224 #undef ZBUF
225 #include "polytmpl.h"
226 #undef POLYFILL
227
228 #define POLYFILL polyfill_alpha_gouraud
229 #define GOURAUD
230 #undef TEXMAP
231 #define BLEND_ALPHA
232 #undef BLEND_ADD
233 #undef ZBUF
234 #include "polytmpl.h"
235 #undef POLYFILL
236
237 #define POLYFILL polyfill_alpha_tex_flat
238 #undef GOURAUD
239 #define TEXMAP
240 #define BLEND_ALPHA
241 #undef BLEND_ADD
242 #undef ZBUF
243 #include "polytmpl.h"
244 #undef POLYFILL
245
246 #define POLYFILL polyfill_alpha_tex_gouraud
247 #define GOURAUD
248 #define TEXMAP
249 #define BLEND_ALPHA
250 #undef BLEND_ADD
251 #undef ZBUF
252 #include "polytmpl.h"
253 #undef POLYFILL
254
255 #define POLYFILL polyfill_add_flat
256 #undef GOURAUD
257 #undef TEXMAP
258 #undef BLEND_ALPHA
259 #define BLEND_ADD
260 #undef ZBUF
261 #include "polytmpl.h"
262 #undef POLYFILL
263
264 #define POLYFILL polyfill_add_gouraud
265 #define GOURAUD
266 #undef TEXMAP
267 #undef BLEND_ALPHA
268 #define BLEND_ADD
269 #undef ZBUF
270 #include "polytmpl.h"
271 #undef POLYFILL
272
273 #define POLYFILL polyfill_add_tex_flat
274 #undef GOURAUD
275 #define TEXMAP
276 #undef BLEND_ALPHA
277 #define BLEND_ADD
278 #undef ZBUF
279 #include "polytmpl.h"
280 #undef POLYFILL
281
282 #define POLYFILL polyfill_add_tex_gouraud
283 #define GOURAUD
284 #define TEXMAP
285 #undef BLEND_ALPHA
286 #define BLEND_ADD
287 #undef ZBUF
288 #include "polytmpl.h"
289 #undef POLYFILL
290
291 /* ---- zbuffer variants ----- */
292
293 #define POLYFILL polyfill_flat_zbuf
294 #undef GOURAUD
295 #undef TEXMAP
296 #undef BLEND_ALPHA
297 #undef BLEND_ADD
298 #define ZBUF
299 #include "polytmpl.h"
300 #undef POLYFILL
301
302 #define POLYFILL polyfill_gouraud_zbuf
303 #define GOURAUD
304 #undef TEXMAP
305 #undef BLEND_ALPHA
306 #undef BLEND_ADD
307 #define ZBUF
308 #include "polytmpl.h"
309 #undef POLYFILL
310
311 #define POLYFILL polyfill_tex_flat_zbuf
312 #undef GOURAUD
313 #define TEXMAP
314 #undef BLEND_ALPHA
315 #undef BLEND_ADD
316 #define ZBUF
317 #include "polytmpl.h"
318 #undef POLYFILL
319
320 #define POLYFILL polyfill_tex_gouraud_zbuf
321 #define GOURAUD
322 #define TEXMAP
323 #undef BLEND_ALPHA
324 #undef BLEND_ADD
325 #define ZBUF
326 #include "polytmpl.h"
327 #undef POLYFILL
328
329 #define POLYFILL polyfill_alpha_flat_zbuf
330 #undef GOURAUD
331 #undef TEXMAP
332 #define BLEND_ALPHA
333 #undef BLEND_ADD
334 #define ZBUF
335 #include "polytmpl.h"
336 #undef POLYFILL
337
338 #define POLYFILL polyfill_alpha_gouraud_zbuf
339 #define GOURAUD
340 #undef TEXMAP
341 #define BLEND_ALPHA
342 #undef BLEND_ADD
343 #define ZBUF
344 #include "polytmpl.h"
345 #undef POLYFILL
346
347 #define POLYFILL polyfill_alpha_tex_flat_zbuf
348 #undef GOURAUD
349 #define TEXMAP
350 #define BLEND_ALPHA
351 #undef BLEND_ADD
352 #define ZBUF
353 #include "polytmpl.h"
354 #undef POLYFILL
355
356 #define POLYFILL polyfill_alpha_tex_gouraud_zbuf
357 #define GOURAUD
358 #define TEXMAP
359 #define BLEND_ALPHA
360 #undef BLEND_ADD
361 #define ZBUF
362 #include "polytmpl.h"
363 #undef POLYFILL
364
365 #define POLYFILL polyfill_add_flat_zbuf
366 #undef GOURAUD
367 #undef TEXMAP
368 #undef BLEND_ALPHA
369 #define BLEND_ADD
370 #define ZBUF
371 #include "polytmpl.h"
372 #undef POLYFILL
373
374 #define POLYFILL polyfill_add_gouraud_zbuf
375 #define GOURAUD
376 #undef TEXMAP
377 #undef BLEND_ALPHA
378 #define BLEND_ADD
379 #define ZBUF
380 #include "polytmpl.h"
381 #undef POLYFILL
382
383 #define POLYFILL polyfill_add_tex_flat_zbuf
384 #undef GOURAUD
385 #define TEXMAP
386 #undef BLEND_ALPHA
387 #define BLEND_ADD
388 #define ZBUF
389 #include "polytmpl.h"
390 #undef POLYFILL
391
392 #define POLYFILL polyfill_add_tex_gouraud_zbuf
393 #define GOURAUD
394 #define TEXMAP
395 #undef BLEND_ALPHA
396 #define BLEND_ADD
397 #define ZBUF
398 #include "polytmpl.h"
399 #undef POLYFILL
400