📄 gfx.cpp
字号:
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 + -