This commit was manufactured by cvs2svn to create tag 'd2x-0_1_2'.
[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 #ifdef HAVE_CONFIG_H
20 #include <conf.h>
21 #endif
22
23 #include "u_mem.h"
24 #include "gr.h"
25 #include "grdef.h"
26
27 //#define USE_POLY_CODE 1
28
29 #define  MAX_SCAN_LINES 1200
30
31 #ifdef USE_POLY_CODE 
32
33 int y_edge_list[MAX_SCAN_LINES];
34
35 void gr_upoly(int nverts, int *vert )
36 {           
37         int temp;
38         int startx, stopx;  // X coordinates of both ends of current edge.
39         int firstx, firsty; // Saved copy of the first vertex to connect later.
40         int dx_dy;          // Slope of current edge.
41         int miny, maxy;
42
43         int starty, stopy;  // Y coordinates of both ends of current edge.
44
45         int x1, x2, i;
46
47         // Find the min and max rows to clear out the minimun y_edge_list.
48         // (Is it worth it?)
49         maxy = vert[1];
50         miny = vert[1];
51
52         for (i=3; i<(nverts*2); i+=2 )
53         {
54                 if (vert[i]>maxy) maxy=vert[i];
55                 if (vert[i]<miny) miny=vert[i];
56         }
57
58         miny >>= 16;
59         miny--;             // -1 to be safe
60         maxy >>= 16;
61         maxy++;             // +1 to be safe
62
63         // Clear only the part of the y_edge_list that w will be using
64         if (miny < 0) miny = 0;
65         if (maxy > MAX_SCAN_LINES) maxy = MAX_SCAN_LINES;
66
67         for (i=miny; i<maxy; i++ )
68                 y_edge_list[i] = -1;
69
70         // Save the first vertex so that we can connect to it at the end.
71         firstx = vert[0];
72         firsty = vert[1] >> 16;
73
74         do
75         {
76                 nverts--;
77
78                 // Get the beginning coordinates of the current edge.
79                 startx = vert[0];
80                 starty = vert[1] >> 16;
81
82                 // Get the ending coordinates of the current edge.
83                 if (nverts > 0 ) {
84                         stopx = vert[2];
85                         stopy = vert[3] >> 16;
86                         vert += 2;
87                 } else  {
88                         stopx = firstx;     // Last edge, uses first vertex as endpoint
89                         stopy = firsty;
90                 }
91
92                 if (stopy < starty )    {
93                         temp = stopy;
94                         stopy = starty;
95                         starty = temp;
96                         temp = stopx;
97                         stopx = startx;
98                         startx = temp;
99                 }
100
101                 if (stopy == starty )
102                 {
103                         // Draw a edge going horizontally across screen
104                         x1 = startx>>16;
105                         x2 = stopx>>16;
106
107                         if (x2 > x1 )
108                                 //gr_uscanline( x1, x2-1, stopy );
109                                 gr_uscanline( x1, x2, stopy );
110                         else
111                                 //gr_uscanline( x2, x1-1, stopy );
112                                 gr_uscanline( x2, x1, stopy );
113
114                 } else  {
115
116                         dx_dy = (stopx - startx) / (stopy - starty);
117
118                         for (; starty < stopy; starty++ )
119                         {
120                                 if (y_edge_list[starty]==-1)
121                                         y_edge_list[starty] = startx;
122                                 else    {
123                                         x1 = y_edge_list[starty]>>16;
124                                         x2 = startx>>16;
125
126                                         if (x2 > x1 )
127                                                 //gr_uscanline( x1, x2-1, starty );
128                                                 gr_uscanline( x1, x2, starty );
129                                         else
130                                                 //gr_uscanline( x2, x1-1, starty );
131                                                 gr_uscanline( x2, x1, starty );
132                                 }
133                                 startx += dx_dy;
134                         }
135                 }
136
137
138         } while (nverts > 0);
139 }
140
141
142 void gr_poly(int nverts, int *vert )
143 {
144         int temp;
145         int startx, stopx;  // X coordinates of both ends of current edge.
146         int firstx, firsty; // Saved copy of the first vertex to connect later.
147         int dx_dy;          // Slope of current edge.
148         int miny, maxy;
149
150         int starty, stopy;  // Y coordinates of both ends of current edge.
151
152         int x1, x2, i, j;
153
154         // Find the min and max rows to clear out the minimun y_edge_list.
155         // (Is it worth it?)
156         maxy = vert[1];
157         miny = vert[1];
158
159         j = 0;
160
161         for (i=3; i<(nverts*2); i+=2 )
162         {
163                 if (vert[i]>maxy) {
164                         if ((maxy=vert[i]) > MAXY) j++;
165                         //if (j>1) break;
166                 }
167
168                 if (vert[i]<miny) {
169                         if ((miny=vert[i]) < MINY) j++;
170                         //if (j>1) break;
171                 }
172         }
173
174         miny >>= 16;
175         miny--;         // -1 to be safe
176         maxy >>= 16;
177         maxy++;          // +1 to be safe
178
179         if (miny < MINY) miny = MINY;
180         if (maxy > MAXY) maxy = MAXY+1;
181
182         // Clear only the part of the y_edge_list that w will be using
183         for (i=miny; i<maxy; i++ )
184            y_edge_list[i] = -1;
185
186         // Save the first vertex so that we can connect to it at the end.
187         firstx = vert[0];
188         firsty = vert[1] >> 16;
189
190         do
191         {
192                 nverts--;
193
194                 // Get the beginning coordinates of the current edge.
195                 startx = vert[0];
196                 starty = vert[1] >> 16;
197
198                 // Get the ending coordinates of the current edge.
199                 if (nverts > 0 ) {
200                         stopx = vert[2];
201                         stopy = vert[3] >> 16;
202                         vert += 2;
203                 } else  {
204                         stopx = firstx;     // Last edge, uses first vertex as endpoint
205                         stopy = firsty;
206                 }
207
208
209                 if (stopy < starty )    {
210                         temp = stopy;
211                         stopy = starty;
212                         starty = temp;
213                         temp = stopx;
214                         stopx = startx;
215                         startx = temp;
216                 }
217
218                 if (stopy == starty )
219                 {
220                         // Draw a edge going horizontally across screen
221                         if ((stopy >= MINY) && (stopy <=MAXY )) {
222                                 x1 = startx>>16;
223                                 x2 = stopx>>16;
224
225                                 if (x1 > x2 )   {
226                                         temp = x2;
227                                         x2 = x1;
228                                         x1 = temp;
229                                 }
230
231                                 if ((x1 <= MAXX ) && (x2 >= MINX))
232                                 {
233                                         if (x1 < MINX ) x1 = MINX;
234                                         if (x2 > MAXX ) x2 = MAXX+1;
235                                         //gr_uscanline( x1, x2-1, stopy );
236                                         gr_scanline( x1, x2, stopy );
237                                 }
238                         }
239                 } else  {
240
241                         dx_dy = (stopx - startx) / (stopy - starty);
242
243                         if (starty < MINY ) {
244                                 startx = dx_dy*(MINY-starty)+startx;
245                                 starty = MINY;
246                         }
247
248                         if (stopy > MAXY ) {
249                                 stopx = dx_dy*(MAXY-starty)+startx;
250                                 stopy = MAXY+1;
251                         }
252
253                         for (; starty < stopy; starty++ )
254                         {   if (y_edge_list[starty]==-1)
255                                         y_edge_list[starty] = startx;
256                                 else    {
257                                         x1 = y_edge_list[starty]>>16;
258                                         x2 = startx>>16;
259
260                                         if (x1 > x2 )   {
261                                                 temp = x2;
262                                                 x2 = x1;
263                                                 x1 = temp;
264                                         }
265
266                                         if ((x1 <= MAXX ) && (x2 >= MINX))
267                                         {
268                                                 if (x1 < MINX ) x1 = MINX;
269                                                 if (x2 > MAXX ) x2 = MAXX+1;
270                                                 //gr_uscanline( x1, x2-1, starty );
271                                                 gr_scanline( x1, x2, starty );
272                                         }
273                                 }
274                                 startx += dx_dy;
275                         }
276                 }
277
278
279         } while (nverts > 0);
280 }
281
282 #endif
283