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

📄 gfx.cpp

📁 liu7788414
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	
	if( hflip && vflip){
		d_space = -pDes->w + 8;
		pD += ((pDes->w)<<3) - pDes->w + 7; //move to(w-1,h-1)
	} else if( hflip ){
		d_space = pDes->w + 8 ;
		pD += 7; //move to (w-1,0)
	} else if( vflip)
	{
		d_space = -pDes->w - 8 ;
		pD  += ((pDes->w)<<3) - pDes->w; //move to the (0,7)
	} else { //no flip
		d_space = pDes->w - 8;
	}
	
	for(i = 0; i < 8; i++)
	{
		if(!hflip)
		{
			pE = pD;
			while(pD < pE)
			{
				*pD++ = pPal[*pS++];
				*pD++ = pPal[*pS++];
				*pD++ = pPal[*pS++];
				*pD++ = pPal[*pS++];
				*pD++ = pPal[*pS++];
				*pD++ = pPal[*pS++];
				*pD++ = pPal[*pS++];
				*pD++ = pPal[*pS++];
			}
			pE += 8;
			while(pD < pE)
			{
				*pD++ = pPal[*pS++];
			}
		}
		else
		{
			pE = pD;
			while(pD > pE)
			{
				*pD-- = pPal[*pS++];
				*pD-- = pPal[*pS++];
				*pD-- = pPal[*pS++];
				*pD-- = pPal[*pS++];
				*pD-- = pPal[*pS++];
				*pD-- = pPal[*pS++];
				*pD-- = pPal[*pS++];
				*pD-- = pPal[*pS++];
			}
			pE -= 8;
			while(pD > pE)
			{
				*pD-- = pPal[*pS++];
			}
		}
		pS += s_space;
		pD += d_space;
	}
}

//##ModelId=402850A40307
void CGfx::FillRec(int dx, int dy, int w, int h, int color)
{
	GFX_FillRec(m_pVideo, dx, dy, w, h, color);
}

//##ModelId=402850A40300
void CGfx::GFX_FillRec(GFXBMP* pDes, int dx, int dy, int w, int h, int color)
{
	SYS_ASSERT(pDes != NULL);
	
	int invisibleW= 0, invisibleH= 0;
	if( dx < 0 )
	{
		invisibleW= -dx;
		w -= invisibleW;
		dx= 0;
	}
	
	if( dx+w > SCREEN_WIDTH )
	{
		invisibleW= dx+w-SCREEN_WIDTH;
		w -= invisibleW;
	}
	
	if( dy < 0 )
	{
		invisibleH= -dy;
		h -= invisibleH;
		dy= 0;
	}
	
	if( dy+h > SCREEN_HEIGHT )
	{
		invisibleH= dy+h-SCREEN_HEIGHT;
		h -= invisibleH;
	}
	
	unsigned short *pD, *pE;
	int i;
	
	pD = (unsigned short*)(pDes->pData + (pDes->w * dy + dx) * 2);
	for(i = 0; i < h; i++)
	{
		pE = pD + w;
		while(pD < pE)
		{
			*pD++ = color;
		}
		pD += (pDes->w - w);			
	}
}

void CGfx::DrawRect(int dx, int dy, int w, int h, int color)
{
	GFX_DrawRect(m_pVideo, dx, dy, w, h, color);
}

void CGfx::GFX_DrawRect(GFXBMP *pDes, int dx, int dy, int w, int h, int color)
{
	SYS_ASSERT(pDes != NULL);
	GFX_DrawLine(pDes, dx, dy, dx + w, dy, color);
	GFX_DrawLine(pDes, dx, dy, dx, dy + h, color);
	GFX_DrawLine(pDes, dx + w, dy, dx + w, dy + h, color);
	GFX_DrawLine(pDes, dx, dy + h, dx + w, dy + h, color);
}

void CGfx::DrawLine(int startX, int startY, int endX, int endY, short color)	
{
	GFX_DrawLine(m_pVideo, startX, startY, endX, endY, color);
}

//////////////////////////////////////////////////////////////////////////
// draw line function
//////////////////////////////////////////////////////////////////////////

void CGfx::GFX_DrawLine(GFXBMP* g , int x0,int y0, int x1, int y1, short color ) 
{
	// this helper function draws a clipped line
	int *pcxs, *pcys, *pcxe, *pcye;
	// clip and draw each line
	pcxs = &x0;
	pcys = &y0;
	pcxe = &x1;
	pcye = &y1;
	
	// clip the line
	if (Clip_Line(g,pcxs,pcys,pcxe,pcye)){
		Draw_Line(*pcxs, *pcys, *pcxe,*pcye,color,(unsigned short*)g->pData ,g->w);
	}
	
	// return success
	return;
} // end Draw_Clip_Line

///////////////////////////////////////////////////////////
#define CLIP_CODE_C  0x0000
#define CLIP_CODE_N  0x0008
#define CLIP_CODE_S  0x0004
#define CLIP_CODE_E  0x0002
#define CLIP_CODE_W  0x0001

#define CLIP_CODE_NE 0x000a
#define CLIP_CODE_SE 0x0006
#define CLIP_CODE_NW 0x0009 
#define CLIP_CODE_SW 0x0005

#define F_FUNC(a, b, c, d, e) ((int)(*a + ((\
	(fDiv(FP_ONE, FP_TWO))+\
	fDiv(\
	fMul(((b<<FP_FRAC_BITS)-((*c)<<FP_FRAC_BITS)), (((*d)<<FP_FRAC_BITS)-((*a)<<FP_FRAC_BITS))), \
	(((*e)<<FP_FRAC_BITS)-((*c)<<FP_FRAC_BITS)))\
	)>>FP_FRAC_BITS)\
))

int CGfx::Clip_Line(GFXBMP *g ,int *px1,int *py1,int *px2, int *py2)
{
	int  min_clip_x  =0;        
	int  max_clip_x  =g->w-1;
	int  min_clip_y  =0;
	int  max_clip_y  =g->h-1;
	
	// this function clips the sent line using the globally defined clipping
	// region
	
	// internal clipping codes
	
	int xc1=*px1, 
		yc1=*py1, 
		xc2=*px2, 
		yc2=*py2;
	
	int p1_code=0, 
		p2_code=0;
	
	// determine codes for p1 and p2
	if (*py1 < min_clip_y)
		p1_code|=CLIP_CODE_N;
	else
	{
		if (*py1 > max_clip_y)
			p1_code|=CLIP_CODE_S;
	}
	
	if (*px1 < min_clip_x)
		p1_code|=CLIP_CODE_W;
	else
	{
		if (*px1 > max_clip_x)
			p1_code|=CLIP_CODE_E;
	}
	if (*py2 < min_clip_y)
		p2_code|=CLIP_CODE_N;
	else
	{
		if (*py2 > max_clip_y)
			p2_code|=CLIP_CODE_S;
	}
	if (*px2 < min_clip_x)
		p2_code|=CLIP_CODE_W;
	else
	{
		if (*px2 > max_clip_x)
			p2_code|=CLIP_CODE_E;
	}					
	// try and trivially reject
	if ((p1_code & p2_code)) 
		return(0);
	
	// test for totally visible, if so leave points untouched
	if (p1_code==0 && p2_code==0)
		return(1);
	
	// determine end clip point for p1
	switch(p1_code)
	{
	case CLIP_CODE_C: break;
		
	case CLIP_CODE_N:
		{
			yc1 = min_clip_y;
			xc1 = F_FUNC(px1, min_clip_y, py1, px2, py2);
		} break;
	case CLIP_CODE_S:
		{
			yc1 = max_clip_y;
			//xc1 = (int)(*px1 + 0.5+(max_clip_y-*py1)*(*px2-*px1)/(*py2-*py1));
			xc1 = F_FUNC(px1, max_clip_y, py1, px2, py2);
		} break;
		
	case CLIP_CODE_W:
		{
			xc1 = min_clip_x;
			//yc1 = (int)(*py1 + 0.5+(min_clip_x-*px1)*(*py2-*py1)/(*px2-*px1));
			yc1 = F_FUNC(py1, min_clip_x, px1, py2, px2);
		} break;
		
	case CLIP_CODE_E:
		{
			xc1 = max_clip_x;
			//yc1 = (int)(*py1 + 0.5+(max_clip_x-*px1)*(*py2-*py1)/(*px2-*px1));
			yc1 = F_FUNC(py1, max_clip_x, px1, py2, px2);
		} break;
		
		// these cases are more complex, must compute 2 intersections
	case CLIP_CODE_NE:
		{
			// north hline intersection
			yc1 = min_clip_y;
			//xc1 = (int)(*px1 + 0.5+(min_clip_y-*py1)*(*px2-*px1)/(*py2-*py1));
			xc1 = F_FUNC(px1, min_clip_y, py1, px2, py2);
			
			// test if intersection is valid, of so then done, else compute next
			if (xc1 < min_clip_x || xc1 > max_clip_x)
			{
				// east vline intersection
				xc1 = max_clip_x;
				//yc1 =(int)( *py1 + 0.5+(max_clip_x-*px1)*(*py2-*py1)/(*px2-*px1) );
				yc1 = F_FUNC(py1, max_clip_x, px1, py2, px2);
			} // end if
			
		} break;
		
	case CLIP_CODE_SE:
		{
			// south hline intersection
			yc1 = max_clip_y;
			//xc1 = (int)(*px1 + 0.5+(max_clip_y-*py1)*(*px2-*px1)/(*py2-*py1));	
			xc1 = F_FUNC(px1, max_clip_y, py1, px2, py2);
			
			// test if intersection is valid, of so then done, else compute next
			if (xc1 < min_clip_x || xc1 > max_clip_x)
			{
				// east vline intersection
				xc1 = max_clip_x;
				//yc1 = (int)(*py1 + 0.5+(max_clip_x-*px1)*(*py2-*py1)/(*px2-*px1));
				yc1 = F_FUNC(py1, max_clip_x, px1, py2, px2);
			} // end if
			
		} break;
		
	case CLIP_CODE_NW: 
		{
			// north hline intersection
			yc1 = min_clip_y;
			//xc1 =(int)( *px1 + 0.5+(min_clip_y-*py1)*(*px2-*px1)/(*py2-*py1));
			xc1 = F_FUNC(px1, min_clip_y, py1, px2, py2);
			
			// test if intersection is valid, of so then done, else compute next
			if (xc1 < min_clip_x || xc1 > max_clip_x)
			{
				xc1 = min_clip_x;
				//yc1 = (int)(*py1 + 0.5+(min_clip_x-*px1)*(*py2-*py1)/(*px2-*px1));	
				yc1 = F_FUNC(py1, min_clip_x, px1, py2, px2);
			} // end if
			
		} break;
		
	case CLIP_CODE_SW:
		{
			// south hline intersection
			yc1 = max_clip_y;
			//xc1 = (int)(*px1 + 0.5+(max_clip_y-*py1)*(*px2-*px1)/(*py2-*py1));	
			xc1 = F_FUNC(px1, max_clip_y, py1, px2, py2);
			
			// test if intersection is valid, of so then done, else compute next
			if (xc1 < min_clip_x || xc1 > max_clip_x)
			{
				xc1 = min_clip_x;
				//yc1 =(int)( *py1 + 0.5+(min_clip_x-*px1)*(*py2-*py1)/(*px2-*px1));	
				yc1 = F_FUNC(py1, min_clip_x, px1, py2, px2);
			} // end if
			
		} break;
		
	default:break;
		
	} // end switch
	
	// determine clip point for p2
	switch(p2_code)
	{
	case CLIP_CODE_C: break;
		
	case CLIP_CODE_N:
		{
			yc2 = min_clip_y;
			xc2 = *px2 + (min_clip_y-*py2)*(*px1-*px2)/(*py1-*py2);
		} break;
		
	case CLIP_CODE_S:
		{
			yc2 = max_clip_y;
			xc2 = *px2 + (max_clip_y-*py2)*(*px1-*px2)/(*py1-*py2);
		} break;
		
	case CLIP_CODE_W:
		{
			xc2 = min_clip_x;
			yc2 = *py2 + (min_clip_x-*px2)*(*py1-*py2)/(*px1-*px2);
		} break;
		
	case CLIP_CODE_E:
		{
			xc2 = max_clip_x;
			yc2 = *py2 + (max_clip_x-*px2)*(*py1-*py2)/(*px1-*px2);
		} break;
		
		// these cases are more complex, must compute 2 intersections
	case CLIP_CODE_NE:
		{
			// north hline intersection
			yc2 = min_clip_y;
			//xc2 =(int)( *px2 + 0.5+(min_clip_y-*py2)*(*px1-*px2)/(*py1-*py2));
			xc2 = F_FUNC(px2, min_clip_y, py2, px1, py1);
			
			// test if intersection is valid, of so then done, else compute next
			if (xc2 < min_clip_x || xc2 > max_clip_x)
			{
				// east vline intersection
				xc2 = max_clip_x;
				//yc2 =(int)( *py2 + 0.5+(max_clip_x-*px2)*(*py1-*py2)/(*px1-*px2));
				yc2 = F_FUNC(py2, max_clip_x, px2, py1, px1);
			} // end if
			
		} break;
		
	case CLIP_CODE_SE:
		{
			// south hline intersection
			yc2 = max_clip_y;
			//xc2 =(int)( *px2 + 0.5+(max_clip_y-*py2)*(*px1-*px2)/(*py1-*py2));	
			xc2 = F_FUNC(px2, max_clip_y, py2, px1, py1);
			
			// test if intersection is valid, of so then done, else compute next
			if (xc2 < min_clip_x || xc2 > max_clip_x)
			{
				// east vline intersection
				xc2 = max_clip_x;
				//yc2 =(int)( *py2 + 0.5+(max_clip_x-*px2)*(*py1-*py2)/(*px1-*px2));
				yc2 = F_FUNC(py2, max_clip_x, px2, py1, px1);
			} // end if
			
		} break;
		
	case CLIP_CODE_NW: 
		{
			// north hline intersection
			yc2 = min_clip_y;
			//xc2 =(int)( *px2 + 0.5+(min_clip_y-*py2)*(*px1-*px2)/(*py1-*py2));
			xc2 = F_FUNC(px2, min_clip_y, py2, px1, py1);
			
			// test if intersection is valid, of so then done, else compute next
			if (xc2 < min_clip_x || xc2 > max_clip_x)
			{
				xc2 = min_clip_x;
				//yc2 =(int)( *py2 + 0.5+(min_clip_x-*px2)*(*py1-*py2)/(*px1-*px2));	
				yc2 = F_FUNC(py2, min_clip_x, px2, py1, px1);
			} // end if
			
		} break;
		
	case CLIP_CODE_SW:
		{
			// south hline intersection
			yc2 = max_clip_y;
			//xc2 = (int)(*px2 + 0.5+(max_clip_y-*py2)*(*px1-*px2)/(*py1-*py2));	
			xc2 = F_FUNC(px2, max_clip_y, py2, px1, py1);
			
			// test if intersection is valid, of so then done, else compute next
			if (xc2 < min_clip_x || xc2 > max_clip_x)
			{
				xc2 = min_clip_x;
				//yc2 = (int)(*py2 + 0.5+(min_clip_x-*px2)*(*py1-*py2)/(*px1-*px2));	
				yc2 = F_FUNC(py2, min_clip_x, px2, py1, px1);
			} // end if
			
		} break;
		
	default:break;
		
	} // end switch
	
	// do bounds check
	if ((xc1 < min_clip_x) || (xc1 > max_clip_x) ||
		(yc1 < min_clip_y) || (yc1 > max_clip_y) ||
		(xc2 < min_clip_x) || (xc2 > max_clip_x) ||
		(yc2 < min_clip_y) || (yc2 > max_clip_y) )
	{
		return(0);
	} // end if

⌨️ 快捷键说明

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