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

📄 m16b_drv.c

📁 与Nucleus Plus配套的图形库
💻 C
📖 第 1 页 / 共 3 页
字号:


/* Function mwPBAAA16 is a special case optimization for memory
to memory, rectangular clipping with no color translation. */
void mwPBAAA16(blitRcd *blitRec)
{
	int Check_YX_Band_Blit(rect *bandRect, rect *blitRectPtr,
		rect *clipR, int *rectCnt);
	void DrawRectEntryBlitMM16B(blitRcd *blitRec);
	int Set_Up_Clip(blitRcd *clipBlit, rect *clipR, int blitMayOverlap,
				int isLine);
	int Blit_Clip_Region(blitRcd *fcRec, rect *fillRect, rect *sRect);
	void nuResume(grafMap *srcBmap);
	void RepDestM16B(void);
	void OXADestM16B(void);
	void SetDestM16B(void);
	void NotDestSolidM16B(void);
	void InvertDestM16B(void);
	void QuickEnd(void);

	rect clipR;	/* Clip rect */
	rect *rListPtr;	/* list pointer */
	int blitMayOverlap = 1;	/* Set true for region clipping*/
	int isLine = 0;	/* Set false */

	rectCnt =  blitRec->blitCnt;
	rListPtr =  (rect *) blitRec->blitList;
	srcBmap =  blitRec->blitSmap;
	srcPixBytes = srcBmap->pixBytes;

	M_PAUSE(srcBmap);	/* pause the source */

	bkColr16 = (short) blitRec->blitBack;	/* background color */
	pnColr16 = (short) blitRec->blitFore;	/* foreground color */

	dstBmap =  blitRec->blitDmap;
	dstClass = blitRec->blitRop & 0x0f;

	M_PAUSE(dstBmap);

	switch (dstClass)
	{	/* look up the optimization routine */
	  			    /* LCD non-transparent */
	case 0:		/* zREPz   :           src			 */
	case 4:		/* zNREPz  :        (NOT src)		 */
		optPtr = &RepDestM16B;
		break;
	case 1:		/* zORz    :       src OR  dst		 */
	case 2:		/* zXORz   :       src XOR dst		 */
	case 3:		/* zNANDz  :    (NOT src) AND dst	 */
	case 5:		/* zNORz   :    (NOT src) OR  dst	 */
	case 6:		/* zNXORz  :    (NOT src) XOR dst	 */
	case 7:		/* zANDz   :       src AND dst		 */
		optPtr = &OXADestM16B;
		break;
	case 8:		/* zCLEARz :           0's			 */
	case 12:	/* zSETz   :           1's			 */
		optPtr = &SetDestM16B;
		break;
	case 9:		/* zORNz   :     src OR  (NOT dst)	 */
	case 11:	/* zANDNz  :     src AND (NOT dst)	 */
	case 13:	/* zNORNz  : (NOT src) OR  (NOT dst) */
	case 15:	/* zNANDNz : (NOT src) AND (NOT dst) */
		optPtr = &NotDestSolidM16B;
		break;
	case 10:	/* zNOPz   :           dst <NOP>	 */
		optPtr = &QuickEnd;
		break;
	case 14:	/* zINVERTz:        (NOT dst)		 */
		optPtr = &InvertDestM16B;
		break;
	}

	/* modify the pen color as necessary */
	switch (dstClass)
	{
	case 3:	/* zNANDz */
	case 4:	/* zNREPz */
	case 5:	/* zNORz */
	case 6:	/* zNXORz */
	case 13:	/* zNORNz */
	case 15:	/* zNANDNz */
		pnColr16 = -1;	/* this has the effect of notting the
					pen color for all operations during this call */
	case 0:	/* zREPz */
	case 1:	/* zORz */
	case 2:	/* zXORz */
	case 7:	/* zANDz */
	case 9:	/* zORNz */
	case 10:	/* zNOPz */
	case 11:	/* zANDNz */
		pnColr16 = 0;
		break;
	case 8:	/* zCLEARz */
		pnColr16 = 0;	/* sets all source bits to 0 */
		break;
	case 12:	/* zSETz */
	case 14:	/* zINVERTz */
		pnColr16 = -1;	/* sets all source bits to 1 */
	}

	/* set up clipping */
	if (Set_Up_Clip(blitRec, &clipR, blitMayOverlap, isLine))
		goto PB_RTN;

	while (--rectCnt >= 0 )
	{
		sRect = *rListPtr++;
		dRect = *rListPtr++;
		if (clipToRectFlag != 0)	/* do we need to worry about clipping */
		{	/* yes, do trivial reject */
			if (dRect.Xmin < clipR.Xmin)
			{	/* Reset src & dst Xmin clip limit */
				sRect.Xmin -= (dRect.Xmin - clipR.Xmin);
				dRect.Xmin  = clipR.Xmin;
			}
			if (dRect.Ymin < clipR.Ymin)
			{	/* Reset src & dst Ymin clip limit */
				sRect.Ymin -= (dRect.Ymin - clipR.Ymin);
				dRect.Ymin  = clipR.Ymin;
			}
			if (dRect.Xmax > clipR.Xmax)
			{	/* Reset src & dst Xmax clip limit */
				sRect.Xmax -= (dRect.Xmax - clipR.Xmax);
				dRect.Xmax  = clipR.Xmax;
			}
			if (dRect.Ymax > clipR.Ymax)
			{	/* Reset src & dst Ymax clip limit */
				sRect.Ymax -= (dRect.Ymax - clipR.Ymax);
				dRect.Ymax  = clipR.Ymax;
			}
			
			if (dRect.Ymin >= dRect.Ymax)
			{	/* Check to see whether the rectangle was trivially
				clipped because it was fully below the clip rect,
				in which case we can discard the rest of a YX banded
				blitList, or because it was fully above the clip
				rect, in which case we can whiz ahead through a YX
				banded blitList until we run out of rects or find a
				rect that isn't fully above the clip rect. */
				if (Check_YX_Band_Blit(&dRect, rListPtr, &clipR,
					   &rectCnt)) break;
				continue;
			}
			
			if (dRect.Xmin >= dRect.Xmax) continue;

			/* do we need to worry about region clipping? */
			if (clipToRegionFlag != 0)
			{	/* yes */
				FillDrawer = &DrawRectEntryBlitMM16B;
				if (Blit_Clip_Region(blitRec, &dRect, &sRect)
					== 0) break;
				continue;
			}
		}
		
		DrawRectEntryBlitMM16B(blitRec);	/* blit the rectangle */
	}

PB_RTN:
	nuResume(srcBmap);
	nuResume(dstBmap);
	return;
}


/* Function DrawRectEntryBlitMM16B blits the rectangle to the memory */
void DrawRectEntryBlitMM16B(blitRcd *blitRec)
{

	lineCntM1 = dRect.Ymax - dRect.Ymin - 1;
	srcBgnByte = sRect.Xmin;
	dstBgnByte = dRect.Xmin;
	byteCntM1 = dRect.Xmax - dRect.Xmin - 1;
	srcNextRow = (srcPixBytes >> 1) - byteCntM1 - 1;
	dstNextRow = (dstBmap->pixBytes >> 1) - byteCntM1 - 1;

	dstPtr16 = (word *) (*(dstBmap->mapTable[0] + dRect.Ymin))
				+ dstBgnByte;
	srcPtr16 = (word *) (*(srcBmap->mapTable[0] + sRect.Ymin))
				+ srcBgnByte;
	optPtr();	/* blit the rectangle */

	return;
}


/* Function NotDestSolidM16B handles memory "not dst" by inverting the
destination first. */
void NotDestSolidM16B(void)
{
	void InvertDestM16B(void);
	void OXADestM16B(void);

	InvertDestM16B();

	OXADestM16B();	/* fill this rectangle */

	return;
}


/* Function RepDestM16B sets the destination pixel data with the
source data. */
void RepDestM16B(void)
{
	word *lclDstPtr, *lclSrcPtr;
	int lclLineCnt, lclByteCnt;

	if ((dstBmap == srcBmap) && ((sRect.Ymin < dRect.Ymin) ||
		((sRect.Ymin == dRect.Ymin) && (sRect.Xmin < dRect.Xmin))))
	{	/* blit bottom to top, right to left */
		lclDstPtr = (word *) (*(dstBmap->mapTable[0] + dRect.Ymax))
			+ dRect.Xmax;
		lclSrcPtr = (word *) (*(dstBmap->mapTable[0] + sRect.Ymax))
			+ sRect.Xmax;
		lclLineCnt = lineCntM1;

		while (lclLineCnt-- >= 0)
		{	/* for each row */
			lclByteCnt = byteCntM1;
			while (lclByteCnt-- >= 0)
			{	/* for each byte in the row */
				*lclDstPtr-- = pnColr16 ^ *lclSrcPtr--;
			}

			lclDstPtr -= dstNextRow;	/* advance to next row */
			lclSrcPtr -= srcNextRow;
		}
	}
	else
	{	/* blit top to bottom, left to right */
		lclDstPtr = dstPtr16;	/* set up local pointers */
		lclSrcPtr = srcPtr16;
		lclLineCnt = lineCntM1;

		while (lclLineCnt-- >= 0)
		{	/* for each row */
			lclByteCnt = byteCntM1;
			while (lclByteCnt-- >= 0)
			{	/* for each byte in the row */
				*lclDstPtr++ = pnColr16 ^ *lclSrcPtr++;
			}

			lclDstPtr += dstNextRow;	/* advance to next row */
			lclSrcPtr += srcNextRow;
		}
	}

	return;
}


/* Function OXADestM16B sets the destination pixel data based on
the logical function "OR", "XOR" or "AND". */
void OXADestM16B(void)
{
	word *lclDstPtr, *lclSrcPtr;
	int lclLineCnt, lclByteCnt;
	int logFnc, locColr;

	if ((dstBmap == srcBmap) && ((sRect.Ymin < dRect.Ymin) ||
		((sRect.Ymin == dRect.Ymin) && (sRect.Xmin < dRect.Xmin))))
	{	/* blit bottom to top, right to left */
		lclDstPtr = (word *) (*(dstBmap->mapTable[0] + dRect.Ymax))
			+ dRect.Xmax;
		lclSrcPtr = (word *) (*(dstBmap->mapTable[0] + sRect.Ymax))
			+ sRect.Xmax;
/* BobB 11/10/99 - removed extra line
		lclLineCnt = lineCntM1; */
		lclLineCnt = lineCntM1;
		logFnc = (dstClass & 3);	/* only two lower bits needed */

		while (lclLineCnt-- >= 0)
		{	/* for each row */
			lclByteCnt = byteCntM1;
			while (lclByteCnt-- >= 0)
			{	/* for each byte in the row */
				locColr = pnColr16 ^ *lclSrcPtr--;
				switch (logFnc)
				{
				case 0:	/* can't happen */
				case 1:	/* "OR" */
					locColr = locColr | *lclDstPtr;
					*lclDstPtr = locColr;
					break;
				case 2:	/* "XOR" */
					locColr = locColr ^ *lclDstPtr;
					*lclDstPtr = locColr;
					break;
				case 3:	/* "AND" */
					locColr = locColr & *lclDstPtr;
					*lclDstPtr = locColr;
					break;
				}

				lclDstPtr--;
			}

			lclDstPtr -= dstNextRow;	/* advance to next row */
			lclSrcPtr -= srcNextRow;
		}
	}
	else
	{	/* blit top to bottom, left to right */
		lclDstPtr = dstPtr16;	/* set up local pointers */
		lclSrcPtr = srcPtr16;
		lclLineCnt = lineCntM1;
		logFnc = (dstClass & 3);	/* only two lower bits needed */

		while (lclLineCnt-- >= 0)
		{	/* for each row */
			lclByteCnt = byteCntM1;
			while (lclByteCnt-- >= 0)
			{	/* for each byte in the row */
				locColr = pnColr16 ^ *lclSrcPtr++;
				switch (logFnc)
				{
				case 0:	/* can't happen */
				case 1:	/* "OR" */
					locColr = locColr | *lclDstPtr;
					*lclDstPtr = locColr;
					break;
				case 2:	/* "XOR" */
					locColr = locColr ^ *lclDstPtr;
					*lclDstPtr = locColr;
					break;
				case 3:	/* "AND" */
					locColr = locColr & *lclDstPtr;
					*lclDstPtr = locColr;
					break;
				}

				lclDstPtr++;
			}

			lclDstPtr += dstNextRow;	/* advance to next row */
			lclSrcPtr += srcNextRow;
		}
	}

	return;
}


/* Function mwWRIMA16 is a special case optimization for WriteImage,
16 bit per pixel, interleaved or linear. Also passes through 1->16Bit
WriteImage to mwWRIMMA16. */
void mwWRIMA16(blitRcd *blitRec)
{
	void mwWRIMMA16(blitRcd *blitRec);
	int Set_Up_Clip(blitRcd *clipBlit, rect *clipR, int blitMayOverlap,
				int isLine);
    int Blit_Clip_Region(blitRcd *fcRec, rect *fillRect, rect *sRect);
	void DrawRectEntryImg16B(blitRcd *blitRec);
	void nuResume(grafMap *dstBmap);
	void RepDestM16B(void);
	void OXADestM16B(void);
	void SetDestM16B(void);
	void NotDestSolidM16B(void);
	void InvertDestM16B(void);
	void QuickEnd(void);

	rect *rListPtr;	/* list pointer */
	int blitMayOverlap = 0;	/* Set false for region clipping*/
	int isLine = 0;	/* Set false */

	srcImag = (image *) blitRec->blitSmap; 
	srcBmap = 0;

	if(srcImag->imBits == 1) /*is this a monochrome image?  */
	{
		mwWRIMMA16(blitRec);/* Let the 1->8 bit handler handle  */
		return;
	}

	if((srcImag->imWidth <= 0) || (srcImag->imHeight <= 0))
		return;

	sRect.Ymin = 0;
	sRect.Xmin = srcImag->imAlign;
	srcPixBytes = srcImag->imBytes;
	rListPtr =  (rect *) blitRec->blitList;

	dstBmap =  blitRec->blitDmap;
	dstClass = blitRec->blitRop & 0x0f;

	M_PAUSE(dstBmap);

	switch (dstClass)
	{	/* look up the optimization routine */
	  			    /* Memory non-transparent */
	case 0:		/* zREPz   :           src			 */
	case 4:		/* zNREPz  :        (NOT src)		 */
		optPtr = &RepDestM16B;
		break;
	case 1:		/* zORz    :       src OR  dst		 */
	case 2:		/* zXORz   :       src XOR dst		 */
	case 3:		/* zNANDz  :    (NOT src) AND dst	 */
	case 5:		/* zNORz   :    (NOT src) OR  dst	 */
	case 6:		/* zNXORz  :    (NOT src) XOR dst	 */
	case 7:		/* zANDz   :       src AND dst		 */
		optPtr = &OXADestM16B;
		break;
	case 8:		/* zCLEARz :           0's			 */
	case 12:	/* zSETz   :           1's			 */
		optPtr = &SetDestM16B;
		break;
	case 9:		/* zORNz   :     src OR  (NOT dst)	 */
	case 11:	/* zANDNz  :     src AND (NOT dst)	 */
	case 13:	/* zNORNz  : (NOT src) OR  (NOT dst) */
	case 15:	/* zNANDNz : (NOT src) AND (NOT dst) */
		optPtr = &NotDestSolidM16B;
		break;
	case 10:	/* zNOPz   :           dst <NOP>	 */
		optPtr = &QuickEnd;
		break;
	case 14:	/* zINVERTz:        (NOT dst)		 */
		optPtr = &InvertDestM16B;
		break;
	}

	/* modify the pen color as necessary */
	switch (dstClass)
	{
	case 3:	/* zNANDz */
	case 4:	/* zNREPz */
	case 5:	/* zNORz */
	case 6:	/* zNXORz */
	case 13:	/* zNORNz */
	case 15:	/* zNANDNz */
		pnColr16 = -1;	/* this has the effect of notting the
					pen color for all operations during this call */
	case 0:	/* zREPz */
	case 1:	/* zORz */
	case 2:	/* zXORz */
	case 7:	/* zANDz */
	case 9:	/* zORNz */
	case 10:	/* zNOPz */
	case 11:	/* zANDNz */
		pnColr16 = 0;
		break;
	case 8:	/* zCLEARz */
		pnColr16 = 0;	/* sets all source bits to 0 */
		break;
	case 12:	/* zSETz */
	case 14:	/* zINVERTz */
		pnColr16 = -1;	/* sets all source bits to 1 */
	}

	/* set up clipping */
	if (Set_Up_Clip(blitRec, &cRect, blitMayOverlap, isLine))
		goto WI_RTN;

	dRect = *rListPtr;
/* See if the destination is too wide  */
	if((dRect.Xmax - dRect.Xmin) > srcImag->imWidth)
		dRect.Xmax = dRect.Xmin + srcImag->imWidth;
/* sXmax not adjusted because not used  */

/* See if the destination is too high  */
	if((dRect.Ymax - dRect.Ymin) > srcImag->imHeight)
		dRect.Ymax = dRect.Ymin + srcImag->imHeight;
/* sYmax not adjusted because not used  */

/* do we need to worry about clipping */
	if(clipToRectFlag != 0)
	{
		if (dRect.Xmin < cRect.Xmin)
		{	/* Reset src & dst Xmin clip limit */
			sRect.Xmin -= (dRect.Xmin - cRect.Xmin);
			dRect.Xmin  = cRect.Xmin;
		}
		if (dRect.Ymin < cRect.Ymin)
		{	/* Reset src & dst Ymin clip limit */
			sRect.Ymin -= (dRect.Ymin - cRect.Ymin);
			dRect.Ymin  = cRect.Ymin;
		}
		if (dRect.Xmax > cRect.Xmax)
		{	/* Reset src & dst Xmax clip limit */
			dRect.Xmax  = cRect.Xmax;
			/* sXmax not altered because not used  */
		}
		if (dRect.Ymax > cRect.Ymax)
		{	/* Reset src & dst Ymax clip limit */
			dRect.Ymax  = cRect.Ymax;
		  /* sYmax not altered because not used  */
		}
		if ((dRect.Xmin >= dRect.Xmax) || (dRect.Ymin >= dRect.Ymax))
			return;
	/* do we need to worry about region clipping?  */
		if (clipToRegionFlag != 0)
		{	/* yes, go do it  */
			FillDrawer = &DrawRectEntryImg16B;
			Blit_Clip_Region(blitRec, &dRect, &sRect);
			goto WI_RTN;
		}
	}
	
	DrawRectEntryImg16B(blitRec);
WI_RTN:
	nuResume(dstBmap);
	return;
}


/* Draw the image */
void DrawRectEntryImg16B(blitRcd *blitRec)
{

	lineCntM1 = dRect.Ymax - dRect.Ymin - 1;
	dstBgnByte = dRect.Xmin;
	byteCntM1 = dRect.Xmax - dRect.Xmin - 1;
	dstNextRow = (dstBmap->pixBytes >> 1) - byteCntM1 - 1;
	srcNextRow = (srcPixBytes >> 1) - byteCntM1 - 1;

⌨️ 快捷键说明

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