/* THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. */ /* * * Graphical routines for drawing polygons. * */ #include #include "u_mem.h" #include "gr.h" #include "grdef.h" //#define USE_POLY_CODE 1 #define MAX_SCAN_LINES 1200 #ifdef USE_POLY_CODE int y_edge_list[MAX_SCAN_LINES]; void gr_upoly(int nverts, int *vert ) { int temp; int startx, stopx; // X coordinates of both ends of current edge. int firstx, firsty; // Saved copy of the first vertex to connect later. int dx_dy; // Slope of current edge. int miny, maxy; int starty, stopy; // Y coordinates of both ends of current edge. int x1, x2, i; // Find the min and max rows to clear out the minimun y_edge_list. // (Is it worth it?) maxy = vert[1]; miny = vert[1]; for (i=3; i<(nverts*2); i+=2 ) { if (vert[i]>maxy) maxy=vert[i]; if (vert[i]>= 16; miny--; // -1 to be safe maxy >>= 16; maxy++; // +1 to be safe // Clear only the part of the y_edge_list that w will be using if (miny < 0) miny = 0; if (maxy > MAX_SCAN_LINES) maxy = MAX_SCAN_LINES; for (i=miny; i> 16; do { nverts--; // Get the beginning coordinates of the current edge. startx = vert[0]; starty = vert[1] >> 16; // Get the ending coordinates of the current edge. if (nverts > 0 ) { stopx = vert[2]; stopy = vert[3] >> 16; vert += 2; } else { stopx = firstx; // Last edge, uses first vertex as endpoint stopy = firsty; } if (stopy < starty ) { temp = stopy; stopy = starty; starty = temp; temp = stopx; stopx = startx; startx = temp; } if (stopy == starty ) { // Draw a edge going horizontally across screen x1 = startx>>16; x2 = stopx>>16; if (x2 > x1 ) //gr_uscanline( x1, x2-1, stopy ); gr_uscanline( x1, x2, stopy ); else //gr_uscanline( x2, x1-1, stopy ); gr_uscanline( x2, x1, stopy ); } else { dx_dy = (stopx - startx) / (stopy - starty); for (; starty < stopy; starty++ ) { if (y_edge_list[starty]==-1) y_edge_list[starty] = startx; else { x1 = y_edge_list[starty]>>16; x2 = startx>>16; if (x2 > x1 ) //gr_uscanline( x1, x2-1, starty ); gr_uscanline( x1, x2, starty ); else //gr_uscanline( x2, x1-1, starty ); gr_uscanline( x2, x1, starty ); } startx += dx_dy; } } } while (nverts > 0); } void gr_poly(int nverts, int *vert ) { int temp; int startx, stopx; // X coordinates of both ends of current edge. int firstx, firsty; // Saved copy of the first vertex to connect later. int dx_dy; // Slope of current edge. int miny, maxy; int starty, stopy; // Y coordinates of both ends of current edge. int x1, x2, i, j; // Find the min and max rows to clear out the minimun y_edge_list. // (Is it worth it?) maxy = vert[1]; miny = vert[1]; j = 0; for (i=3; i<(nverts*2); i+=2 ) { if (vert[i]>maxy) { if ((maxy=vert[i]) > MAXY) j++; //if (j>1) break; } if (vert[i]1) break; } } miny >>= 16; miny--; // -1 to be safe maxy >>= 16; maxy++; // +1 to be safe if (miny < MINY) miny = MINY; if (maxy > MAXY) maxy = MAXY+1; // Clear only the part of the y_edge_list that w will be using for (i=miny; i> 16; do { nverts--; // Get the beginning coordinates of the current edge. startx = vert[0]; starty = vert[1] >> 16; // Get the ending coordinates of the current edge. if (nverts > 0 ) { stopx = vert[2]; stopy = vert[3] >> 16; vert += 2; } else { stopx = firstx; // Last edge, uses first vertex as endpoint stopy = firsty; } if (stopy < starty ) { temp = stopy; stopy = starty; starty = temp; temp = stopx; stopx = startx; startx = temp; } if (stopy == starty ) { // Draw a edge going horizontally across screen if ((stopy >= MINY) && (stopy <=MAXY )) { x1 = startx>>16; x2 = stopx>>16; if (x1 > x2 ) { temp = x2; x2 = x1; x1 = temp; } if ((x1 <= MAXX ) && (x2 >= MINX)) { if (x1 < MINX ) x1 = MINX; if (x2 > MAXX ) x2 = MAXX+1; //gr_uscanline( x1, x2-1, stopy ); gr_scanline( x1, x2, stopy ); } } } else { dx_dy = (stopx - startx) / (stopy - starty); if (starty < MINY ) { startx = dx_dy*(MINY-starty)+startx; starty = MINY; } if (stopy > MAXY ) { stopx = dx_dy*(MAXY-starty)+startx; stopy = MAXY+1; } for (; starty < stopy; starty++ ) { if (y_edge_list[starty]==-1) y_edge_list[starty] = startx; else { x1 = y_edge_list[starty]>>16; x2 = startx>>16; if (x1 > x2 ) { temp = x2; x2 = x1; x1 = temp; } if ((x1 <= MAXX ) && (x2 >= MINX)) { if (x1 < MINX ) x1 = MINX; if (x2 > MAXX ) x2 = MAXX+1; //gr_uscanline( x1, x2-1, starty ); gr_scanline( x1, x2, starty ); } } startx += dx_dy; } } } while (nverts > 0); } #endif