]> icculus.org git repositories - btb/d2x.git/blob - 2d/poly.c
svgalib support
[btb/d2x.git] / 2d / poly.c
1 /*
2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
11 COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
12 */
13 /*
14  *
15  * Graphical routines for drawing polygons.
16  *
17  */
18
19 #include <conf.h>
20 #include "u_mem.h"
21 #include "gr.h"
22 #include "grdef.h"
23
24 //#define USE_POLY_CODE 1
25
26 #define  MAX_SCAN_LINES 1200
27
28 #ifdef USE_POLY_CODE 
29
30 int y_edge_list[MAX_SCAN_LINES];
31
32 void gr_upoly(int nverts, int *vert )
33 {           
34         int temp;
35         int startx, stopx;  // X coordinates of both ends of current edge.
36         int firstx, firsty; // Saved copy of the first vertex to connect later.
37         int dx_dy;          // Slope of current edge.
38         int miny, maxy;
39
40         int starty, stopy;  // Y coordinates of both ends of current edge.
41
42         int x1, x2, i;
43
44         // Find the min and max rows to clear out the minimun y_edge_list.
45         // (Is it worth it?)
46         maxy = vert[1];
47         miny = vert[1];
48
49         for (i=3; i<(nverts*2); i+=2 )
50         {
51                 if (vert[i]>maxy) maxy=vert[i];
52                 if (vert[i]<miny) miny=vert[i];
53         }
54
55         miny >>= 16;
56         miny--;             // -1 to be safe
57         maxy >>= 16;
58         maxy++;             // +1 to be safe
59
60         // Clear only the part of the y_edge_list that w will be using
61         if (miny < 0) miny = 0;
62         if (maxy > MAX_SCAN_LINES) maxy = MAX_SCAN_LINES;
63
64         for (i=miny; i<maxy; i++ )
65                 y_edge_list[i] = -1;
66
67         // Save the first vertex so that we can connect to it at the end.
68         firstx = vert[0];
69         firsty = vert[1] >> 16;
70
71         do
72         {
73                 nverts--;
74
75                 // Get the beginning coordinates of the current edge.
76                 startx = vert[0];
77                 starty = vert[1] >> 16;
78
79                 // Get the ending coordinates of the current edge.
80                 if (nverts > 0 ) {
81                         stopx = vert[2];
82                         stopy = vert[3] >> 16;
83                         vert += 2;
84                 } else  {
85                         stopx = firstx;     // Last edge, uses first vertex as endpoint
86                         stopy = firsty;
87                 }
88
89                 if (stopy < starty )    {
90                         temp = stopy;
91                         stopy = starty;
92                         starty = temp;
93                         temp = stopx;
94                         stopx = startx;
95                         startx = temp;
96                 }
97
98                 if (stopy == starty )
99                 {
100                         // Draw a edge going horizontally across screen
101                         x1 = startx>>16;
102                         x2 = stopx>>16;
103
104                         if (x2 > x1 )
105                                 //gr_uscanline( x1, x2-1, stopy );
106                                 gr_uscanline( x1, x2, stopy );
107                         else
108                                 //gr_uscanline( x2, x1-1, stopy );
109                                 gr_uscanline( x2, x1, stopy );
110
111                 } else  {
112
113                         dx_dy = (stopx - startx) / (stopy - starty);
114
115                         for (; starty < stopy; starty++ )
116                         {
117                                 if (y_edge_list[starty]==-1)
118                                         y_edge_list[starty] = startx;
119                                 else    {
120                                         x1 = y_edge_list[starty]>>16;
121                                         x2 = startx>>16;
122
123                                         if (x2 > x1 )
124                                                 //gr_uscanline( x1, x2-1, starty );
125                                                 gr_uscanline( x1, x2, starty );
126                                         else
127                                                 //gr_uscanline( x2, x1-1, starty );
128                                                 gr_uscanline( x2, x1, starty );
129                                 }
130                                 startx += dx_dy;
131                         }
132                 }
133
134
135         } while (nverts > 0);
136 }
137
138
139 void gr_poly(int nverts, int *vert )
140 {
141         int temp;
142         int startx, stopx;  // X coordinates of both ends of current edge.
143         int firstx, firsty; // Saved copy of the first vertex to connect later.
144         int dx_dy;          // Slope of current edge.
145         int miny, maxy;
146
147         int starty, stopy;  // Y coordinates of both ends of current edge.
148
149         int x1, x2, i, j;
150
151         // Find the min and max rows to clear out the minimun y_edge_list.
152         // (Is it worth it?)
153         maxy = vert[1];
154         miny = vert[1];
155
156         j = 0;
157
158         for (i=3; i<(nverts*2); i+=2 )
159         {
160                 if (vert[i]>maxy) {
161                         if ((maxy=vert[i]) > MAXY) j++;
162                         //if (j>1) break;
163                 }
164
165                 if (vert[i]<miny) {
166                         if ((miny=vert[i]) < MINY) j++;
167                         //if (j>1) break;
168                 }
169         }
170
171         miny >>= 16;
172         miny--;         // -1 to be safe
173         maxy >>= 16;
174         maxy++;          // +1 to be safe
175
176         if (miny < MINY) miny = MINY;
177         if (maxy > MAXY) maxy = MAXY+1;
178
179         // Clear only the part of the y_edge_list that w will be using
180         for (i=miny; i<maxy; i++ )
181            y_edge_list[i] = -1;
182
183         // Save the first vertex so that we can connect to it at the end.
184         firstx = vert[0];
185         firsty = vert[1] >> 16;
186
187         do
188         {
189                 nverts--;
190
191                 // Get the beginning coordinates of the current edge.
192                 startx = vert[0];
193                 starty = vert[1] >> 16;
194
195                 // Get the ending coordinates of the current edge.
196                 if (nverts > 0 ) {
197                         stopx = vert[2];
198                         stopy = vert[3] >> 16;
199                         vert += 2;
200                 } else  {
201                         stopx = firstx;     // Last edge, uses first vertex as endpoint
202                         stopy = firsty;
203                 }
204
205
206                 if (stopy < starty )    {
207                         temp = stopy;
208                         stopy = starty;
209                         starty = temp;
210                         temp = stopx;
211                         stopx = startx;
212                         startx = temp;
213                 }
214
215                 if (stopy == starty )
216                 {
217                         // Draw a edge going horizontally across screen
218                         if ((stopy >= MINY) && (stopy <=MAXY )) {
219                                 x1 = startx>>16;
220                                 x2 = stopx>>16;
221
222                                 if (x1 > x2 )   {
223                                         temp = x2;
224                                         x2 = x1;
225                                         x1 = temp;
226                                 }
227
228                                 if ((x1 <= MAXX ) && (x2 >= MINX))
229                                 {
230                                         if (x1 < MINX ) x1 = MINX;
231                                         if (x2 > MAXX ) x2 = MAXX+1;
232                                         //gr_uscanline( x1, x2-1, stopy );
233                                         gr_scanline( x1, x2, stopy );
234                                 }
235                         }
236                 } else  {
237
238                         dx_dy = (stopx - startx) / (stopy - starty);
239
240                         if (starty < MINY ) {
241                                 startx = dx_dy*(MINY-starty)+startx;
242                                 starty = MINY;
243                         }
244
245                         if (stopy > MAXY ) {
246                                 stopx = dx_dy*(MAXY-starty)+startx;
247                                 stopy = MAXY+1;
248                         }
249
250                         for (; starty < stopy; starty++ )
251                         {   if (y_edge_list[starty]==-1)
252                                         y_edge_list[starty] = startx;
253                                 else    {
254                                         x1 = y_edge_list[starty]>>16;
255                                         x2 = startx>>16;
256
257                                         if (x1 > x2 )   {
258                                                 temp = x2;
259                                                 x2 = x1;
260                                                 x1 = temp;
261                                         }
262
263                                         if ((x1 <= MAXX ) && (x2 >= MINX))
264                                         {
265                                                 if (x1 < MINX ) x1 = MINX;
266                                                 if (x2 > MAXX ) x2 = MAXX+1;
267                                                 //gr_uscanline( x1, x2-1, starty );
268                                                 gr_scanline( x1, x2, starty );
269                                         }
270                                 }
271                                 startx += dx_dy;
272                         }
273                 }
274
275
276         } while (nverts > 0);
277 }
278
279 #endif
280