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

📄 seed1.c

📁 与Nucleus Plus配套的图形库
💻 C
📖 第 1 页 / 共 3 页
字号:
	blockPtr = FreeBlocks;	/* point to the list of free blocks */
	if (blockPtr == NULL)
	{	/* see if we can get more from the pool */
		blockPtr = Unallocated;
		Unallocated++;	/* point to the next block of as-yet unallocated
						memory */
		if (blockPtr <= UnallocatedEnd) return(1);	/* okay */
		return(0);	/* out of free memory */
	}

	FreeBlocks = blockPtr->NextBlock;	/*  the new head of the free
										block list */
	return(1);
}


/* Function ScanOutSegList generates a fill segment list for a scan
line (all segments on the current scan line that should be filled,
given the shadow list from the last line).  The sentinel links around
to the first segment, and is also linked to the last segment. If
sentinel is linked to itself, it's not possible to advance in this
direction.  Returns 1 for success, 0 for failure. */
int ScanOutSegList(void)
{
	int qualifyXSave;

	WorkingScanLine = ScanLine;
	blockPtrDN = blockPtrDN->NextBlock;	/* point to first shadow block */
	if (AllocBlock() == NULL) return(0);	/* couldn't do it */

	TempListHead = blockPtr;	/* remember where the head of list is */

	while ((qualifyX = blockPtrDN->sXmin) != 0x7FFF)
	{	/* is the min point fillable? */
		if (Qualify() == 1)
		{	/* scan left to find the start of the fill segment we're
			currently in (begin with the point to the left of the
			shadow left edge, since we already checked the shadow
			left edge point) */
			qualifyXSave = qualifyX;	/* remember scanning start point */
			while (--qualifyX >= lmtR.Xmin)
			{	/* scan left to find the start of the segment or the
				left edge */
				if (Qualify() == 0) break;
			}

			wXmin = qualifyX + 1;
			qualifyX = qualifyXSave;
			goto SOSLSREntry;
		}

		/* min point not fillable; scan right until either qualify
		or this shadow segment runs out */
		if (++qualifyX >= blockPtrDN->sXmax)
		{	/* found right edge */
			blockPtrDN = blockPtrDN->NextBlock;
			continue;
		}

SOSLFindFirstLoop:	/* scan right to find the end of the segment */
		if (Qualify() == 0)
		{
			if (++qualifyX >= blockPtrDN->sXmax)
			{	/* found right edge */
				blockPtrDN = blockPtrDN->NextBlock;
				continue;
			}
			else
			{
				goto SOSLFindFirstLoop;
			}
		}

		wXmin = qualifyX;	/* remember where the left edge of this
								fill segment is */
SOSLSREntry:	/* found right end of segment */
		blockPtrBE = blockPtr;	/* pointer to current last block */
		if (AllocBlock() == NULL) return(0);	/* out of memory? */
		blockPtrBE->NextBlock = blockPtr;	/* add the next block at
											the end of the list */
		blockPtr->sXmin = wXmin;	/*set the left edge of this fill
									segment */
		if (++qualifyX >= lmtR.Xmax)
		{	/* found right edge */
			blockPtr->sXmax = qualifyX;	/* set right edge of fill segment */
			break;	/* we're done, because we can't scan any farther */
		}
		/* scan right to find the end of the segment */
		while (Qualify() == 1)
		{
			if (++qualifyX >= lmtR.Xmax)
			{	/* found right edge */
				blockPtr->sXmax = qualifyX;
				break;
			}
		}

		blockPtr->sXmax = qualifyX;	/* set right edge of fill segment */
		wXmin = qualifyX + 1;	/* point to the first possible start
								pixel for the next fill segment */
		if (wXmin >= lmtR.Xmax) break;	/* at the right edge of the limit now? */
	
		if (wXmin < blockPtrDN->sXmax) goto SOSLFindFirstLoop;	/* continue
												scanning out this shadow */
		do{
			blockPtrDN = blockPtrDN->NextBlock;
		} while (wXmin >= blockPtrDN->sXmax);	/* try the next (this loop
					is guaranteed to terminate because of the sentinel) */

		/* found the next shadow with which to work */
		if (wXmin >= blockPtrDN->sXmin) goto SOSLFindFirstLoop;	/* when X
					is the resume-scanning point, there's no need to scan
					left, because we just came from there */
	}	/* continue scanning out shadow	*/

	/* successfully done! - relink to make the head of the list also the
	sentinel at the end */
	blockPtrBE = TempListHead;	/* return pointer to head of segment */
	blockPtr->NextBlock = blockPtrBE;	/* link the head at the end */
	blockPtrBE->sXmin = 0x7FFF;	/* and make it a sentinel */
	blockPtrBE->sXmax = 0x7FFF;
	blockPtr = blockPtrBE;	/* return pointer to the sentinel */

	return(1);
}


/* Function PopState pops a scanning state from the scanning state stack.
Returns 1 for success, 0 for state stack empty, popped shadow in blockPtrDN
as well as in pShadow[br]. Also restores ForwardLimit, FLimitPtr,
BackwardLimit, BLimitPtr, ScanLine, and reverses sDirection. */
int PopState(void)
{

	if (StateStackPtr == NULL) return(0);	/* is it empty? */

	sDirection = -sDirection;	/* reverse direction */
	BackwardLimit = ForwardLimit;	/* forward limit becomes backward limit */
	BLimitPtr = FLimitPtr;	/* ditto */
	blockPtrCE = FreeBlocks;	/* link in the two blocks we're about to
								free & blockPtrCE points to head */
	FreeBlocks = StateStackPtr;
	ForwardLimit = StateStackPtr->sXmin;	/* pushed forward limit */
	FLimitPtr = (SBlock *) StateStackPtr->sXmax;	/* pushed forward limit
													pointer */
	StateStackPtr = StateStackPtr->NextBlock;	/* other half of info is
												in this block */
	ScanLine = StateStackPtr->sXmin;	/* pushed scan line */
	pShadow = (SBlock *) StateStackPtr->sXmax;	/* pushed shadow pointer */
	blockPtrDN = StateStackPtr->NextBlock;	/* new top of stack */
	StateStackPtr->NextBlock = blockPtrCE;	/* link to the rest of the
											free block list */
	StateStackPtr = blockPtrDN;
	blockPtrDN = pShadow;

	return(1);
}


/* Function PushState pushes a scanning state onto the scanning state
stack.  Preserves ForwardLimit, FLimitPtr, ScanLine, and the pointer
to a segment list in blockPtrDN.  Returns 1 for success, 0 for out of
memory.  */
int PushState(void)
{

	if (AllocBlock() == NULL) return(0);	/* out of memory */

	blockPtrCE = StateStackPtr;	/* point state stack to the new block */
	StateStackPtr = blockPtr;
	blockPtr->sXmin = ForwardLimit;	/* push forward limit */
	blockPtr->sXmax = (long) FLimitPtr;	/* push backward limit */

	blockPtrBE = blockPtr;
	if (AllocBlock() == NULL) return(0);	/* out of memory */
	blockPtrBE->NextBlock = blockPtr;	/* other half of info is in
										this block */
	blockPtr->sXmin = ScanLine;	/* push scan line */
	blockPtr->sXmax = (long) blockPtrDN;	/* push shadow pointer */

	blockPtr->NextBlock = blockPtrCE;	/* link to the rest of the free
										block */

	return(1);
}


/* Function FreeList frees up the linked list of blocks pointed to by
blockPtrDN, by adding it to the free list.  List at blockPtrDN must be
terminated with a 7FFF sentinel. */
void FreeList(void)
{

	blockPtrST = FreeBlocks;	/* get the current pointer to the start
							of the free block list */
	FreeBlocks = blockPtrDN;	/* put the new list at the start of the
								free block list */
	while (blockPtrDN->sXmin != 0x7FFF)
	{
		blockPtrDN = blockPtrDN->NextBlock;
	}

	blockPtrDN->NextBlock = blockPtrST;	/* link the old free blocks at
										the end of the new list */

	return;
}


/* Function Setup1 sets up stuff common to flood and boundary fill.
Sets up limit rect (in global coords, clipped to bitmap), blitRcd, and
primitive GetPixel and Fill vectors. Converts the seed point to global
coords, stores it in (SeedX,ScanLine), checks that it's inside the limit
rect, and returns it in (localFeedX,localFeedY).  Returns 1 for success,
0 for failure (seed point outside limit rect or limit rect fully clipped) */
int Setup1(void)
{
	
	blitRecord = grafBlit;	/* copy the default blit record over */
	blitRecord.blitCnt = 0;	/* no rectangles in blitList yet */

	/* convert seed point to global coords */
    if (globalLevel > 0)
	{	/* convert from user to global */
		U2GP(localFeedX, localFeedY, &localFeedX, &localFeedY, 1);
	}

	SeedX = localFeedX;	/* initial X coordinate */
	ScanLine = localFeedY;	/* initial scan line */

	/* now get the limit rect and clip it to the bitmap (or use the
	bitmap limits if the limit rect pointer is NULL) */
	if (LimitPtr == NULL)
	{	/* just use the bitmap limits */
		lmtR.Xmin = 0;
		lmtR.Ymin = 0;
/* BobB 10/6/98 - corrected the following lines for max width and height
		lmtR.Xmax = blitRecord.blitDmap->pixWidth;
		lmtR.Ymax = blitRecord.blitDmap->pixHeight; */
/* BobB 10/22/99 - corrected the correction
		lmtR.Xmax = blitRecord.blitDmap->pixWidth - 1;
		lmtR.Ymax = blitRecord.blitDmap->pixHeight - 1; */
		lmtR.Xmax = blitRecord.blitDmap->pixWidth;
		lmtR.Ymax = blitRecord.blitDmap->pixHeight;
	}
	else
	{
		lmtR = *LimitPtr;	/* get the limit rect */

		/* convert limit rect to global coords */
	    if (globalLevel > 0)
		{	/* convert from user to global */
			U2GR(lmtR, &lmtR, 0);
		}

		/* and clip it to the bitmap limits */
		if (lmtR.Xmin < 0) lmtR.Xmin = 0;
		if (lmtR.Ymin < 0) lmtR.Ymin = 0;
/* BobB 10/6/98 - corrected the following lines for max width and height
		if (lmtR.Xmax > blitRecord.blitDmap->pixWidth)
			lmtR.Xmax = blitRecord.blitDmap->pixWidth;
		if (lmtR.Ymax > blitRecord.blitDmap->pixHeight)
			lmtR.Ymax = blitRecord.blitDmap->pixHeight; */
/* BobB 10/22/99 - corrected the correction
		if (lmtR.Xmax >= blitRecord.blitDmap->pixWidth)
			lmtR.Xmax = blitRecord.blitDmap->pixWidth - 1;
		if (lmtR.Ymax >= blitRecord.blitDmap->pixHeight)
			lmtR.Ymax = blitRecord.blitDmap->pixHeight - 1; */
		if (lmtR.Xmax > blitRecord.blitDmap->pixWidth)
			lmtR.Xmax = blitRecord.blitDmap->pixWidth;
		if (lmtR.Ymax > blitRecord.blitDmap->pixHeight)
			lmtR.Ymax = blitRecord.blitDmap->pixHeight;

		if (lmtR.Xmin >= lmtR.Xmax) return(0);	/* trivial reject in x? */
		if (lmtR.Ymin >= lmtR.Ymax) return(0);	/* trivial reject in y? */
	}

	/* make sure the pixel is within the working limit rect */
	if ((SeedX < lmtR.Xmin) || (SeedX >= lmtR.Xmax) ||
		(ScanLine < lmtR.Ymin) ||(ScanLine >= lmtR.Ymax)) return(0);

	/* pixel is within the limit rect set up the GetPixel & Fill
	primitive vectors */
	GetPixelPrimitive = blitRecord.blitDmap->prGetPx;
	FillPrimitive = blitRecord.blitDmap->prFill;

	return(1);
}

⌨️ 快捷键说明

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