backported g3d changes:
[dosdemo] / src / polyfill.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <assert.h>
5 #if defined(__WATCOMC__) || defined(_MSC_VER) || defined(__DJGPP__)
6 #include <malloc.h>
7 #else
8 #include <alloca.h>
9 #endif
10 #include "polyfill.h"
11 #include "gfxutil.h"
12
13 #define FILL_POLY_BITS  0x03
14
15 /* mode bits: 00-wire 01-flat 10-gouraud 11-reserved
16  *     bit 2: texture
17  *     bit 3: blend
18  */
19 void (*fillfunc[])(struct pvertex*, int) = {
20         polyfill_wire,
21         polyfill_flat,
22         polyfill_gouraud,
23         0,
24         polyfill_tex_wire,
25         polyfill_tex_flat,
26         polyfill_tex_gouraud,
27         0,
28         polyfill_blend_wire,
29         polyfill_blend_flat,
30         polyfill_blend_gouraud,
31         0,
32         polyfill_blend_tex_wire,
33         polyfill_blend_tex_flat,
34         polyfill_blend_tex_gouraud,
35         0
36 };
37
38 struct pimage pfill_fb, pfill_tex;
39
40 void polyfill(int mode, struct pvertex *verts, int nverts)
41 {
42 #ifndef NDEBUG
43         if(!fillfunc[mode]) {
44                 fprintf(stderr, "polyfill mode %d not implemented\n", mode);
45                 abort();
46         }
47 #endif
48
49         fillfunc[mode](verts, nverts);
50 }
51
52 void polyfill_wire(struct pvertex *verts, int nverts)
53 {
54         int i, x0, y0, x1, y1;
55         struct pvertex *v = verts;
56         unsigned short color = ((v->r << 8) & 0xf800) |
57                 ((v->g << 3) & 0x7e0) | ((v->b >> 3) & 0x1f);
58
59         for(i=0; i<nverts - 1; i++) {
60                 x0 = v->x >> 8;
61                 y0 = v->y >> 8;
62                 ++v;
63                 x1 = v->x >> 8;
64                 y1 = v->y >> 8;
65                 if(clip_line(&x0, &y0, &x1, &y1, 0, 0, pfill_fb.width, pfill_fb.height)) {
66                         draw_line(x0, y0, x1, y1, color);
67                 }
68         }
69         x0 = verts[0].x >> 8;
70         y0 = verts[0].y >> 8;
71         if(clip_line(&x1, &y1, &x0, &y0, 0, 0, pfill_fb.width, pfill_fb.height)) {
72                 draw_line(x1, y1, x0, y0, color);
73         }
74 }
75
76 void polyfill_tex_wire(struct pvertex *verts, int nverts)
77 {
78         polyfill_wire(verts, nverts);   /* TODO */
79 }
80
81 void polyfill_blend_wire(struct pvertex *verts, int nverts)
82 {
83         polyfill_wire(verts, nverts);   /* TODO */
84 }
85
86 void polyfill_blend_tex_wire(struct pvertex *verts, int nverts)
87 {
88         polyfill_wire(verts, nverts);   /* TODO */
89 }
90
91 #define NEXTIDX(x) (((x) - 1 + nverts) % nverts)
92 #define PREVIDX(x) (((x) + 1) % nverts)
93
94 /* XXX
95  * When HIGH_QUALITY is defined, the rasterizer calculates slopes for attribute
96  * interpolation on each scanline separately; otherwise the slope for each
97  * attribute would be calculated once for the whole polygon, which is faster,
98  * but produces some slight quantization artifacts, due to the limited precision
99  * of fixed-point calculations.
100  */
101 #define HIGH_QUALITY
102
103 /* extra bits of precision to use when interpolating colors.
104  * try tweaking this if you notice strange quantization artifacts.
105  */
106 #define COLOR_SHIFT     12
107
108
109 #define POLYFILL polyfill_flat
110 #define SCANEDGE scanedge_flat
111 #undef GOURAUD
112 #undef TEXMAP
113 #undef BLEND
114 #include "polytmpl.h"
115 #undef POLYFILL
116 #undef SCANEDGE
117
118 #define POLYFILL polyfill_gouraud
119 #define SCANEDGE scanedge_gouraud
120 #define GOURAUD
121 #undef TEXMAP
122 #undef BLEND
123 #include "polytmpl.h"
124 #undef POLYFILL
125 #undef SCANEDGE
126
127 #define POLYFILL polyfill_tex_flat
128 #define SCANEDGE scanedge_tex_flat
129 #undef GOURAUD
130 #define TEXMAP
131 #undef BLEND
132 #include "polytmpl.h"
133 #undef POLYFILL
134 #undef SCANEDGE
135
136 #define POLYFILL polyfill_tex_gouraud
137 #define SCANEDGE scanedge_tex_gouraud
138 #define GOURAUD
139 #define TEXMAP
140 #undef BLEND
141 #include "polytmpl.h"
142 #undef POLYFILL
143 #undef SCANEDGE
144
145 #define POLYFILL polyfill_blend_flat
146 #define SCANEDGE scanedge_blend_flat
147 #undef GOURAUD
148 #undef TEXMAP
149 #define BLEND
150 #include "polytmpl.h"
151 #undef POLYFILL
152 #undef SCANEDGE
153
154 #define POLYFILL polyfill_blend_gouraud
155 #define SCANEDGE scanedge_blend_gouraud
156 #define GOURAUD
157 #undef TEXMAP
158 #define BLEND
159 #include "polytmpl.h"
160 #undef POLYFILL
161 #undef SCANEDGE
162
163 #define POLYFILL polyfill_blend_tex_flat
164 #define SCANEDGE scanedge_blend_tex_flat
165 #undef GOURAUD
166 #define TEXMAP
167 #define BLEND
168 #include "polytmpl.h"
169 #undef POLYFILL
170 #undef SCANEDGE
171
172 #define POLYFILL polyfill_blend_tex_gouraud
173 #define SCANEDGE scanedge_blend_tex_gouraud
174 #define GOURAUD
175 #define TEXMAP
176 #define BLEND
177 #include "polytmpl.h"
178 #undef POLYFILL
179 #undef SCANEDGE