284 lines
5.9 KiB
C
284 lines
5.9 KiB
C
/*
|
|
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.
|
|
*
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <conf.h>
|
|
#endif
|
|
|
|
#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]<miny) miny=vert[i];
|
|
}
|
|
|
|
miny >>= 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<maxy; i++ )
|
|
y_edge_list[i] = -1;
|
|
|
|
// Save the first vertex so that we can connect to it at the end.
|
|
firstx = vert[0];
|
|
firsty = vert[1] >> 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]<miny) {
|
|
if ((miny=vert[i]) < MINY) j++;
|
|
//if (j>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<maxy; i++ )
|
|
y_edge_list[i] = -1;
|
|
|
|
// Save the first vertex so that we can connect to it at the end.
|
|
firstx = vert[0];
|
|
firsty = vert[1] >> 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
|
|
|