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