foo
[dos_low3d] / src / polyfill.c
1 #include <stdio.h>\r
2 #include <string.h>\r
3 #include "3dgfx.h"\r
4 #include "util.h"\r
5 \r
6 static void filltop(struct g3d_vertex *v0, struct g3d_vertex *v1, struct g3d_vertex *v2);\r
7 static void fillbot(struct g3d_vertex *v0, struct g3d_vertex *v1, struct g3d_vertex *v2);\r
8 \r
9 void g3d_polyfill(struct g3d_vertex *verts)\r
10 {\r
11         int i, topidx, botidx, mididx;\r
12         int32_t dx, dy, dym;\r
13         struct g3d_vertex vtmp;\r
14 \r
15         topidx = botidx = 0;\r
16         for(i=1; i<3; i++) {\r
17                 if(verts[i].y < verts[topidx].y) {\r
18                         topidx = i;\r
19                 }\r
20                 if(verts[i].y > verts[botidx].y) {\r
21                         botidx = i;\r
22                 }\r
23         }\r
24         mididx = (topidx + 1) % 3;\r
25         if(mididx == botidx) mididx = (mididx + 1) % 3;\r
26 \r
27         dy = verts[botidx].y - verts[topidx].y;\r
28         if(dy == 0) return;\r
29 \r
30         dx = verts[botidx].x - verts[topidx].x;\r
31         dym = verts[mididx].y - verts[topidx].y;\r
32         vtmp.x = muldiv(dx, dym, dy) + verts[topidx].x; /* dx * dym / dy + vtop.x */\r
33         vtmp.y = verts[mididx].y;\r
34 \r
35         if(verts[topidx].y != verts[mididx].y) {\r
36                 filltop(verts + topidx, verts + mididx, &vtmp);\r
37         }\r
38         if(verts[mididx].y != verts[botidx].y) {\r
39                 fillbot(verts + mididx, &vtmp, verts + botidx);\r
40         }\r
41 }\r
42 \r
43 static void filltop(struct g3d_vertex *v0, struct g3d_vertex *v1, struct g3d_vertex *v2)\r
44 {\r
45         struct g3d_vertex *vtmp;\r
46         int x, xn, y, endy, len;\r
47         int32_t xl, xr, dxl, dxr, dxldy, dxrdy, dy;\r
48         unsigned char *fbptr;\r
49 \r
50         if(v1->x > v2->x) {\r
51                 vtmp = v1;\r
52                 v1 = v2;\r
53                 v2 = vtmp;\r
54         }\r
55 \r
56         y = v0->y >> 8;\r
57         endy = v1->y >> 8;\r
58         x = v0->x >> 8;\r
59 \r
60         fbptr = g3d_fbpixels + y * XRES + x;\r
61 \r
62         xl = xr = v0->x;\r
63         dy = v1->y - v0->y;\r
64         dxl = v1->x - v0->x;\r
65         dxr = v2->x - v0->x;\r
66         dxldy = (dxl << 8) / dy;\r
67         dxrdy = (dxr << 8) / dy;\r
68 \r
69         while(y++ < endy) {\r
70                 len = (xr - xl) >> 8;\r
71                 if(len > 0) memset(fbptr, g3d_curcidx, len);\r
72 \r
73                 xl += dxldy;\r
74                 xr += dxrdy;\r
75                 xn = xl >> 8;\r
76                 fbptr += XRES + (xn - x);\r
77                 x = xn;\r
78         }\r
79 }\r
80 \r
81 static void fillbot(struct g3d_vertex *v0, struct g3d_vertex *v1, struct g3d_vertex *v2)\r
82 {\r
83         struct g3d_vertex *vtmp;\r
84         int x, xn, y, endy, len;\r
85         int32_t xl, xr, dxl, dxr, dxldy, dxrdy, dy;\r
86         unsigned char *fbptr;\r
87 \r
88         if(v0->x > v1->x) {\r
89                 vtmp = v0;\r
90                 v0 = v1;\r
91                 v1 = vtmp;\r
92         }\r
93 \r
94         y = v0->y >> 8;\r
95         endy = v2->y >> 8;\r
96         x = v0->x >> 8;\r
97 \r
98         fbptr = g3d_fbpixels + y * XRES + x;\r
99 \r
100         xl = v0->x;\r
101         xr = v1->x;\r
102         dy = v2->y - v0->y;\r
103         dxl = v2->x - v0->x;\r
104         dxr = v2->x - v1->x;\r
105         dxldy = (dxl << 8) / dy;\r
106         dxrdy = (dxr << 8) / dy;\r
107 \r
108         while(y++ < endy) {\r
109                 len = (xr - xl) >> 8;\r
110                 if(len > 0) memset(fbptr, g3d_curcidx, len);\r
111 \r
112                 xl += dxldy;\r
113                 xr += dxrdy;\r
114                 xn = xl >> 8;\r
115                 fbptr += XRES + (xn - x);\r
116                 x = xn;\r
117         }\r
118 }\r