⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xpol6.c

📁 nucleus 文件系统,内核和彩色图形系统,在小系统上非常好用
💻 C
📖 第 1 页 / 共 3 页
字号:
/*************************************************************************/
/*                                                                       */
/*         Copyright (c) 1997 - 1999 Accelerated Technology, Inc.        */
/*                                                                       */
/* PROPRIETARY RIGHTS of Accelerated Technology are involved in the      */
/* subject matter of this material.  All manufacturing, reproduction,    */
/* use, and sales rights pertaining to this subject matter are governed  */
/* by the license agreement.  The recipient of this software implicitly  */
/* accepts the terms of the license.                                     */
/*                                                                       */
/*************************************************************************/

/*************************************************************************/
/*                                                                       */
/* FILE NAME                                            VERSION          */
/*                                                                       */
/*      XPOL6.c                                          1.9             */
/*                                                                       */
/* COMPONENT                                                             */
/*                                                                       */
/*      All                                                              */
/*                                                                       */
/* DESCRIPTION                                                           */
/*                                                                       */
/*      This file contains the __mwScanEdge, __mwScanEdgeRestart,        */
/* ScanBurst & mwFC functions.                                           */
/*                                                                       */
/* AUTHOR                                                                */
/*                                                                       */
/*      Robert G. Burrill, Accelerated Technology, Inc.                  */
/*                                                                       */
/* DATA STRUCTURES                                                       */
/*                                                                       */
/*      None                                                             */
/*                                                                       */
/* FUNCTIONS                                                             */
/*                                                                       */
/*      None                                                             */
/*                                                                       */
/* DEPENDENCIES                                                          */
/*                                                                       */
/*      None                                                             */
/*                                                                       */
/* HISTORY                                                               */
/*                                                                       */
/*         NAME            DATE                    REMARKS               */
/*                                                                       */
/*         BobB           10/2/98 - correction to keep from overwriting  */
/* blit record                                                           */
/*         BobB           5/12/99      Corrected fo pen size 1,1         */
/*         BobB           11/9/99      Removed unused variable           */
/*                                                                       */
/*************************************************************************/

#include "meta_wnd.h"
#include "metconst.h"    /* MetaWINDOW Constant & Stucture Definitions */
#include "metports.h"    /* MetaWINDOW Port & Bitmap Definitions */
#include "grafdata.h"
#include "metmacs3.h"
#include "xpol_4.h"


/* Structure used to store the state of suspended edge tracing and later
restore it. */
typedef struct _restartStruc{
	byte scanEdgeFirstPass;	/* if this is the first time scanning an edge
								in the restartable scanning code, 0 else */
	byte filler[3];
	long restartVector;		/* case vector to restart routine */
	long restartRemaining;	/* # of scan lines left in suspended edge */
	long restartAE;	/* various registers and variables saved to */
	long restartCE;	/*  restart various routines */
	long restartDE;
	long restartSN;
	long restartBR;
	long restartAdvanceAmt;
	long restartHeight;
} restartStruc;
long vertexListEnd;	/* offset of first location after the last point struc
					in the points array */
int lastPointX;	/* in previous (relative) mode only, the X and Y */
int lastPointY;	/*   coordinates of the last point in the vertex list */


/* Function __mwScanEdge scan converts an edge from (X1, Y1) to (X2, Y2),
not including the point at (X2, Y2). If skipFirst == 1, the point at (X1,
Y1) isn't drawn; if skipFirst == 0, it is. For each scan line, the pixel
closest to the scanned edge without being to the left of the scanned edge
is chosen. Scan-converted X coordinates are stored in the array of rects
pointed to by DI. Uses an all-integer approach for speed & precision.

__mwScanEdge is for use in scanning convex polygon edges for which there
is adequate room in the rect list (don't need to be restarted).

Edges must not go bottom to top.

Updates scanListPtr to next element to set in array of rects */

void __mwScanEdge(short startX, short endX, short height, point **scanListPtrPtr,
				  int skipFirst)
{
	short errorTerm;
	short advanceAmt;
	short deltaX;
	short advanceX;
	short advanceErrorTerm;
	short i;
	point *scanListPtr;

	scanListPtr = *scanListPtrPtr;	/* get pointer to store data */
	if ((deltaX = endX - startX) == 0)
	{	/* it's a vertical edge--special case it */
		height -= skipFirst;
		if (height == 0) return; /* no scan lines left after skipping 1st */
		for (; height > 0; height--)
		{
			scanListPtr->X = startX;
			scanListPtr += 2;
		}
		*scanListPtrPtr = scanListPtr;	/* update pointer for next time */
		return;
	}

	if (deltaX < 0)
	{	/* move left as we draw */
		errorTerm = -height;
		advanceAmt = -1;
		deltaX = -deltaX;	/* width = abs(deltaX) */
	}
	else
	{
		errorTerm = -1;
		advanceAmt = 1;
	}

	/* Figure out whether the edge is diagonal, X-major (more horizontal),
	or Y-major (more vertical) and handle appropriately.*/
	if (deltaX == height)
	{	/* it's a diagonal edge--special case */
		if (skipFirst == 1)
		{	/* skip the first point */
			startX += advanceAmt;
			height--;
		}
		while (height > 0)
		{
			scanListPtr->X = startX;
			scanListPtr += 2;
			startX += advanceAmt;
			height--;
		}
		*scanListPtrPtr = scanListPtr;	/* update pointer for next time */
		return;
	}

	if (deltaX > height)
	{	/* it's an X-major (more horz) edge */
		i = height;
		advanceX = deltaX / height;
		advanceErrorTerm = deltaX % height;
		if (advanceAmt < 0) advanceX = -advanceX;
		if (skipFirst == 1)
		{	/* skip the first point */
			startX += advanceX;
			errorTerm += advanceErrorTerm;
			if (errorTerm >= 0)
			{	/* time for X coord to advance one extra */
				startX += advanceAmt;
				errorTerm -= height;
			}
			i--;
		}
		while (i > 0)
		{
			scanListPtr->X = startX;
			scanListPtr += 2;
			startX += advanceX;
			errorTerm += advanceErrorTerm;
			if (errorTerm >= 0)
			{	/* time for X coord to advance one extra */
				startX += advanceAmt;
				errorTerm -= height;
			}
			i--;
		}
		*scanListPtrPtr = scanListPtr;	/* update pointer for next time */
		return;
	}

	/* it's a Y-major (more vertical) edge */
	i = height;
	if (skipFirst == 1)
	{	/* skip the first point */
		errorTerm += deltaX;
		if (errorTerm >= 0)
		{	/* time for X coord to advance */
			startX += advanceAmt;
			errorTerm -= height;
		}
		i--;
	}
	while (i > 0)
	{
		scanListPtr->X = startX;
		scanListPtr += 2;
		errorTerm += deltaX;
		if (errorTerm >= 0)
		{	/* time for X coord to advance */
			startX += advanceAmt;
			errorTerm -= height;
		}
		i--;
	}
	*scanListPtrPtr = scanListPtr;	/* update pointer for next time */
	return;
}


/* Function __mwScanEdgeRestart is for use in scanning convex polygon
edges for which there is not adequate room in the rect list (need to
be restarted). This is the entry point the first time such an edge is
scanned; restartVector in the restart structure should be called to
restart the line thereafter.

Edges must not go bottom to top.

Updates scanListPtr to next element to set in array of rects */

void __mwScanEdgeRestart(short startX, short endX, short height,
						 point **scanListPtrPtr, int skipFirst,
						 restartStruc *restartStrucPtr, int numScans)
{
#define VerticalRestart	1
#define DiagonalRestart	2
#define XMajorRestart	3
#define YMajorRestart	4
	short errorTerm;
	short advanceAmt;
	short deltaX;
	short advanceX;
	short advanceErrorTerm;
	point *scanListPtr;

	scanListPtr = *scanListPtrPtr;	/* get pointer to store data */
	switch (restartStrucPtr->restartVector)
	{
	/* entry points to load suspended scanning state */
	case VerticalRestart:
		startX = (short) restartStrucPtr->restartSN;
		goto VerticalLoopR;	/* never need to skip first point on restart */

	case DiagonalRestart:
		advanceAmt = (short) restartStrucPtr->restartDE;
		startX = (short) restartStrucPtr->restartSN;
		goto DiagonalLoopR;

	case XMajorRestart:
		advanceAmt = (short) restartStrucPtr->restartAdvanceAmt;
		height = (short) restartStrucPtr->restartHeight;
		advanceX = (short) restartStrucPtr->restartAE;
		errorTerm = (short) restartStrucPtr->restartCE;
		advanceErrorTerm = (short) restartStrucPtr->restartDE;
		startX = (short) restartStrucPtr->restartSN;
		goto XMajorLoopR;

	case YMajorRestart:
		deltaX = (short) restartStrucPtr->restartAE;
		errorTerm = (short) restartStrucPtr->restartCE;
		advanceAmt = (short) restartStrucPtr->restartDE;
		startX = (short) restartStrucPtr->restartSN;
		height = (short) restartStrucPtr->restartBR;
		goto YMajorLoopR;
	
	default:
		goto restartEntry;
	}

restartEntry:
	/* not the first pass after this */
	restartStrucPtr->scanEdgeFirstPass = 0;
	if ((deltaX = endX - startX) == 0)
	{	/* it's a vertical edge--special case it */
		/* restart vector for next time */
		restartStrucPtr->restartVector = VerticalRestart;
		restartStrucPtr->restartSN = startX;	/* this doesn't change
											from one pass to the next */
		numScans -= skipFirst;
		if (numScans == 0) return; /* no scan lines left after skipping 1st */
VerticalLoopR:
		for (; numScans > 0; numScans--)
		{
			scanListPtr->X = startX;
			scanListPtr += 2;
		}
		*scanListPtrPtr = scanListPtr;	/* update pointer for next time */
		return;
	}

	if (deltaX < 0)
	{	/* move left as we draw */
		errorTerm = -height;
		advanceAmt = -1;
		deltaX = -deltaX;	/* width = abs(deltaX) */
	}
	else
	{
		errorTerm = -1;
		advanceAmt = 1;
	}

	/* Figure out whether the edge is diagonal, X-major (more horizontal),
	or Y-major (more vertical) and handle appropriately.*/
	if (deltaX == height)
	{	/* it's a diagonal edge--special case */
		/* restart vector for next time */
		restartStrucPtr->restartVector = DiagonalRestart;
		restartStrucPtr->restartDE = advanceAmt;	/* this doesn't change
											from one pass to the next */
		if (skipFirst == 1)
		{	/* skip the first point */
			startX += advanceAmt;
			numScans--;
		}
DiagonalLoopR:
		while (numScans > 0)
		{
			scanListPtr->X = startX;
			scanListPtr += 2;
			startX += advanceAmt;
			numScans--;
		}
		restartStrucPtr->restartSN = startX;
		*scanListPtrPtr = scanListPtr;	/* update pointer for next time */
		return;
	}

	if (deltaX > height)
	{	/* it's an X-major (more horz) edge */
		/* restart vector for next time */
		restartStrucPtr->restartVector = XMajorRestart;
		restartStrucPtr->restartHeight = height;
		restartStrucPtr->restartAdvanceAmt = advanceAmt;
		advanceX = deltaX / height;
		advanceErrorTerm = deltaX % height;
		if (advanceAmt < 0) advanceX = -advanceX;
		restartStrucPtr->restartAE = advanceX;
		restartStrucPtr->restartDE = advanceErrorTerm;
		if (skipFirst == 1)
		{	/* skip the first point */
			startX += advanceX;
			errorTerm += advanceErrorTerm;
			if (errorTerm >= 0)
			{	/* time for X coord to advance one extra */
				startX += advanceAmt;
				errorTerm -= height;
			}
			numScans--;
		}
XMajorLoopR:
		while (numScans > 0)
		{
			scanListPtr->X = startX;
			scanListPtr += 2;
			startX += advanceX;
			errorTerm += advanceErrorTerm;
			if (errorTerm >= 0)
			{	/* time for X coord to advance one extra */
				startX += advanceAmt;
				errorTerm -= height;
			}
			numScans--;
		}
		restartStrucPtr->restartCE = errorTerm;
		restartStrucPtr->restartSN = startX;
		*scanListPtrPtr = scanListPtr;	/* update pointer for next time */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -