950 lines
40 KiB
C
950 lines
40 KiB
C
/**************************************************************************************
|
|
|
|
DRAW.CPP
|
|
|
|
***************************************************************************************/
|
|
|
|
#include "tde.h"
|
|
|
|
/**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~**
|
|
a_lTableMM : Min-max array
|
|
contains :
|
|
| X_l | X_r | X_t_l | Y_t_l | X_t_r | Y_t_r | blank | blank |
|
|
|
|
**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~**/
|
|
TDE_tdl1616 a_lTableMM[768][8];
|
|
|
|
/**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~**
|
|
Semi-transparency masks for 16 bits
|
|
Force to 0 each component's last bit
|
|
**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~**/
|
|
unsigned short sMask_565 = 0xF7DE; // 1111 0111 1101 1110
|
|
unsigned short sMask_655 = 0xFBDE; // 1111 1011 1101 1110
|
|
unsigned short sMask_556 = 0xF7BE; // 1111 0111 1011 1110
|
|
unsigned short sMask_555 = 0x7BDE; // 0111 1011 1101 1110
|
|
|
|
/**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~**
|
|
NAME : TDE_vDrawSuperObject16
|
|
VERSION : 2.0 / Valérie
|
|
1.0 / Franck
|
|
|
|
AIM : Display a super object (for sprites)
|
|
**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~**/
|
|
|
|
void TDE_vDrawSuperObject16(GLD_tdpstViewportAttributes p_stViewAttrib,
|
|
TDE_tdsSuperObject *p_stSuperObject)
|
|
{
|
|
TDE_tdxValue xScaledSpriteW, xScaledSpriteH, xSpriteCenterX, xSpriteCenterY,
|
|
xSpriteCornerX, xSpriteCornerY, xScaledSourceW, xScaledSourceH,
|
|
xSourceCornerX, xSourceCornerY;
|
|
long lPitchDest, lPitchSrc, lViewPortW, lViewPortH;
|
|
short si;
|
|
TDE_tdsRect stSrcRect, stDestRect;
|
|
TDE_tdsSprite *p_stSprite = p_stSuperObject->p_stSprite;
|
|
|
|
stSrcRect.lPitch = lPitchSrc = ((long)(p_stSprite->stPicture.xSrcPitch))>>C_TDEDEC;
|
|
stDestRect.lPitch = lPitchDest = (p_stViewAttrib->lPitch)>>C_TDEDEC;
|
|
lViewPortW = p_stViewAttrib->dwWidth;
|
|
lViewPortH = p_stViewAttrib->dwHeight;
|
|
|
|
// xValues
|
|
xScaledSpriteW = TDE_M_Mul(lViewPortW , p_stSprite->stDim.xX);
|
|
xScaledSpriteH = TDE_M_Mul(lViewPortH , p_stSprite->stDim.xY);
|
|
xSpriteCenterX = TDE_M_Mul(lViewPortW , p_stSuperObject->stModifiedMatrix.stTranslateVertex.xX);
|
|
xSpriteCenterY = TDE_M_Mul(lViewPortH , p_stSuperObject->stModifiedMatrix.stTranslateVertex.xY);
|
|
xSpriteCornerX = xSpriteCenterX - TDE_M_Div(xScaledSpriteW,2);
|
|
xSpriteCornerY = xSpriteCenterY - TDE_M_Div(xScaledSpriteH,2);
|
|
xSourceCornerX = TDE_M_Mul(p_stSprite->stPicture.xWidth , p_stSprite->stSourceOrigin.xX);
|
|
xSourceCornerY = TDE_M_Mul(p_stSprite->stPicture.xHeight , p_stSprite->stSourceOrigin.xY);
|
|
xScaledSourceW = TDE_M_Mul(p_stSprite->stPicture.xWidth , p_stSprite->stDim.xX);
|
|
xScaledSourceH = TDE_M_Mul(p_stSprite->stPicture.xHeight , p_stSprite->stDim.xY);
|
|
|
|
// Destination rectangle
|
|
iTDE_vFillsRect(&stDestRect, xSpriteCornerX - xSpriteCenterX, xSpriteCornerY - xSpriteCenterY,
|
|
xScaledSpriteW, xScaledSpriteH);
|
|
|
|
// Transformation
|
|
for (si=0; si<4; si++)
|
|
{
|
|
TDE_vMulMatrixByVertex(&(p_stSuperObject->stModifiedMatrix.a4_xS), &(stDestRect.tdsSommet[si]), &(stDestRect.tdsSommet[si]));
|
|
stDestRect.tdsSommet[si].xX += xSpriteCenterX;
|
|
stDestRect.tdsSommet[si].xY += xSpriteCenterY;
|
|
}
|
|
|
|
// Source rectangle
|
|
iTDE_vFillsRect(&stSrcRect, xSourceCornerX, xSourceCornerY, xScaledSourceW, xScaledSourceH);
|
|
|
|
stDestRect.p_usPointer = (TDE_tdxPixel *)(p_stViewAttrib->p_cVirtualScreen);
|
|
stSrcRect.p_usPointer = (TDE_tdxPixel *)(p_stSprite->stPicture.lp_Data);
|
|
|
|
if (!p_stSprite->cSemiTransparent)
|
|
{ iTDE_vBlit(&stSrcRect, &stDestRect); }
|
|
else
|
|
{ iTDE_vBlit_Transparency(&stSrcRect, &stDestRect, p_stSprite->alpha); }
|
|
}
|
|
|
|
|
|
/**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~**
|
|
NAME : TDE_vDrawSuperObjectFast16
|
|
VERSION : 2.0 / Valérie
|
|
1.0 / Franck
|
|
|
|
AIM : Display a super object (for sprites) without stretch
|
|
**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~**/
|
|
|
|
void TDE_vDrawSuperObjectFast16(GLD_tdpstViewportAttributes p_stViewAttrib,
|
|
TDE_tdsSuperObject *p_stSuperObject)
|
|
{
|
|
TDE_tdxValue xScaledSpriteW, xScaledSpriteH, xSpriteCenterX, xSpriteCenterY,
|
|
xSpriteCornerX, xSpriteCornerY, xScaledSourceW, xScaledSourceH,
|
|
xSourceCornerX, xSourceCornerY;
|
|
long lPitchDest, lPitchSrc, lViewPortW, lViewPortH;
|
|
short si;
|
|
TDE_tdsRect stSrcRect, stDestRect;
|
|
TDE_tdsSprite *p_stSprite = p_stSuperObject->p_stSprite;
|
|
|
|
stSrcRect.lPitch = lPitchSrc = ((long)(p_stSprite->stPicture.xSrcPitch))>>C_TDEDEC;
|
|
stDestRect.lPitch = lPitchDest = (p_stViewAttrib->lPitch)>>C_TDEDEC;
|
|
lViewPortW = p_stViewAttrib->dwWidth;
|
|
lViewPortH = p_stViewAttrib->dwHeight;
|
|
|
|
// xValues
|
|
xSourceCornerX = TDE_M_Mul(p_stSprite->stPicture.xWidth , p_stSprite->stSourceOrigin.xX);
|
|
xSourceCornerY = TDE_M_Mul(p_stSprite->stPicture.xHeight , p_stSprite->stSourceOrigin.xY);
|
|
xScaledSourceW = TDE_M_Mul(p_stSprite->stPicture.xWidth , p_stSprite->stDim.xX);
|
|
xScaledSourceH = TDE_M_Mul(p_stSprite->stPicture.xHeight , p_stSprite->stDim.xY);
|
|
xScaledSpriteW = xScaledSourceW;
|
|
xScaledSpriteH = xScaledSourceH;
|
|
xSpriteCenterX = TDE_M_Mul(lViewPortW , p_stSuperObject->stModifiedMatrix.stTranslateVertex.xX);
|
|
xSpriteCenterY = TDE_M_Mul(lViewPortH , p_stSuperObject->stModifiedMatrix.stTranslateVertex.xY);
|
|
xSpriteCornerX = xSpriteCenterX - TDE_M_Div(xScaledSpriteW,2);
|
|
xSpriteCornerY = xSpriteCenterY - TDE_M_Div(xScaledSpriteH,2);
|
|
|
|
// Destination rectangle
|
|
iTDE_vFillsRect(&stDestRect, xSpriteCornerX - xSpriteCenterX, xSpriteCornerY - xSpriteCenterY,
|
|
xScaledSpriteW, xScaledSpriteH);
|
|
|
|
for (si=0; si<4; si++)
|
|
{
|
|
stDestRect.tdsSommet[si].xX += xSpriteCenterX;
|
|
stDestRect.tdsSommet[si].xY += xSpriteCenterY;
|
|
}
|
|
|
|
// Source rectangle
|
|
iTDE_vFillsRect(&stSrcRect, xSourceCornerX, xSourceCornerY, xScaledSourceW, xScaledSourceH);
|
|
|
|
stDestRect.p_usPointer = (TDE_tdxPixel *)(p_stViewAttrib->p_cVirtualScreen);
|
|
stSrcRect.p_usPointer = (TDE_tdxPixel *)(p_stSprite->stPicture.lp_Data);
|
|
|
|
iTDE_vBlitFast(&stSrcRect, &stDestRect);
|
|
}
|
|
|
|
|
|
/**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~**
|
|
NAME : TDE_vFastDrawMemorySpriteAbsolute
|
|
VERSION : 2.0 / Valérie
|
|
1.0 / Franck
|
|
|
|
AIM : Display a sprite stored in memory
|
|
! ATTENTION ! : The sprite has to be defined with absolute coordinates
|
|
**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~**/
|
|
void TDE_vFastDrawMemorySpriteAbsolute(GLD_tdpstViewportAttributes p_stViewAttrib,
|
|
TDE_tdsSuperObject *p_stSuperObject,
|
|
TDE_tdsRect *p_stScreenRect)
|
|
{
|
|
TDE_tdxValue xScaledSpriteW, xScaledSpriteH, xSpriteCenterX, xSpriteCenterY,
|
|
xSpriteCornerX, xSpriteCornerY;
|
|
long lPitchDest, lViewPortW, lViewPortH;
|
|
TDE_tdsRect stDestRect, stClippedDestRect;
|
|
TDE_tdsMemZone stSource;
|
|
TDE_tdsSprite *p_stSprite = p_stSuperObject->p_stSprite;
|
|
// clipping value 0->no clipped, 1->clipped to screen rect, 2->clipped to SO clipping rectangle
|
|
char clipped = 0;
|
|
|
|
stDestRect.lPitch = lPitchDest = (p_stViewAttrib->lPitch)>>C_TDEDEC;
|
|
lViewPortW = p_stViewAttrib->dwWidth;
|
|
lViewPortH = p_stViewAttrib->dwHeight;
|
|
|
|
// xValues
|
|
xScaledSpriteW = p_stSprite->stDim.xX; // absolute dimensions
|
|
xScaledSpriteH = p_stSprite->stDim.xY;
|
|
xSpriteCenterX = p_stSuperObject->stModifiedMatrix.stTranslateVertex.xX;
|
|
xSpriteCenterY = p_stSuperObject->stModifiedMatrix.stTranslateVertex.xY;
|
|
xSpriteCornerX = xSpriteCenterX - TDE_M_Div(xScaledSpriteW, 2) + 0.5;
|
|
xSpriteCornerY = xSpriteCenterY - TDE_M_Div(xScaledSpriteH, 2) + 0.5;
|
|
|
|
// Destination rectangle
|
|
iTDE_vFillsRect(&stDestRect, xSpriteCornerX, xSpriteCornerY, xScaledSpriteW, xScaledSpriteH);
|
|
|
|
// Out of screen ?
|
|
if ( (long)(stDestRect.tdsSommet[0].xX)>p_stScreenRect->tdsSommet[1].xX) return;
|
|
if ( (long)(stDestRect.tdsSommet[2].xX)<p_stScreenRect->tdsSommet[0].xX) return;
|
|
if ( (long)(stDestRect.tdsSommet[0].xY)>p_stScreenRect->tdsSommet[3].xY) return;
|
|
if ( (long)(stDestRect.tdsSommet[2].xY)<p_stScreenRect->tdsSommet[0].xY) return;
|
|
|
|
// Clipped ?
|
|
if ( ( (long)(stDestRect.tdsSommet[0].xX)<p_stScreenRect->tdsSommet[0].xX) ||
|
|
( (long)(stDestRect.tdsSommet[1].xX)>p_stScreenRect->tdsSommet[1].xX) ||
|
|
( (long)(stDestRect.tdsSommet[0].xY)<p_stScreenRect->tdsSommet[0].xY) ||
|
|
( (long)(stDestRect.tdsSommet[3].xY)>p_stScreenRect->tdsSommet[3].xY) )
|
|
{
|
|
clipped = 1;
|
|
}
|
|
|
|
if (p_stSuperObject->p_stSOClipRect)
|
|
clipped = 2;
|
|
|
|
if (clipped)
|
|
{
|
|
//iTDE_vAdjustScreenRectForClip(&stDestRect, &stClippedDestRect, lViewPortW, lViewPortH);
|
|
if ( clipped == 1)
|
|
iTDE_vAdjustScreenRectToClipRect(&stDestRect, &stClippedDestRect, p_stScreenRect);
|
|
else if ( clipped == 2)
|
|
iTDE_vAdjustScreenRectToClipRect(&stDestRect, &stClippedDestRect, p_stSuperObject->p_stSOClipRect);
|
|
|
|
stClippedDestRect.p_usPointer = (TDE_tdxPixel *)(p_stViewAttrib->p_cVirtualScreen);
|
|
|
|
stSource.p_usPointer = p_stSprite->v_pData + // recal
|
|
TDE_M_ValueToLong (
|
|
( TDE_M_ValueToLong(stClippedDestRect.tdsSommet[0].xY) - TDE_M_ValueToLong(stDestRect.tdsSommet[0].xY) )*xScaledSpriteW ) +
|
|
( TDE_M_ValueToLong(stClippedDestRect.tdsSommet[0].xX) - TDE_M_ValueToLong(stDestRect.tdsSommet[0].xX) );
|
|
|
|
stSource.stDim.xX = xScaledSpriteW;
|
|
stSource.stDim.xY = xScaledSpriteH;
|
|
stSource.xMagicColor = p_stSprite->xMagicColor;
|
|
|
|
if (p_stSprite->c_NZ)
|
|
{ iTDE_vBlitClipMemory_NZ(&stSource, &stClippedDestRect); }
|
|
else
|
|
{ iTDE_vBlitClipMemory(&stSource, &stClippedDestRect); }
|
|
}
|
|
else
|
|
{
|
|
stDestRect.p_usPointer = (TDE_tdxPixel *)(p_stViewAttrib->p_cVirtualScreen);
|
|
stSource.p_usPointer = (TDE_tdxPixel *)(p_stSprite->v_pData);
|
|
stSource.stDim.xX = xScaledSpriteW;
|
|
stSource.stDim.xY = xScaledSpriteH;
|
|
stSource.xMagicColor = p_stSprite->xMagicColor;
|
|
|
|
if (p_stSprite->c_NZ)
|
|
{ iTDE_vBlitFastMemory_NZ(&stSource, &stDestRect); }
|
|
else
|
|
{ iTDE_vBlitFastMemory(&stSource, &stDestRect); }
|
|
}
|
|
}
|
|
|
|
/**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~**
|
|
NAME : TDE_vFastDrawMemorySpriteAbsoluteInvert
|
|
VERSION : 2.0 / Valérie
|
|
1.0 / Franck
|
|
|
|
AIM : Display a sprite stored in memory
|
|
! ATTENTION ! : The sprite has to be defined with absolute coordinates
|
|
**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~**/
|
|
void TDE_vFastDrawMemorySpriteAbsoluteInvert(GLD_tdpstViewportAttributes p_stViewAttrib,
|
|
TDE_tdsSuperObject *p_stSuperObject,
|
|
TDE_tdsRect *p_stScreenRect)
|
|
{
|
|
TDE_tdxValue xScaledSpriteW, xScaledSpriteH, xSpriteCenterX, xSpriteCenterY,
|
|
xSpriteCornerX, xSpriteCornerY;
|
|
long lPitchDest, lViewPortW, lViewPortH;
|
|
TDE_tdsRect stDestRect, stClippedDestRect;
|
|
TDE_tdsMemZone stSource;
|
|
TDE_tdsSprite *p_stSprite = p_stSuperObject->p_stSprite;
|
|
char clipped = 0;
|
|
|
|
stDestRect.lPitch = lPitchDest = (p_stViewAttrib->lPitch)>>C_TDEDEC;
|
|
lViewPortW = p_stViewAttrib->dwWidth;
|
|
lViewPortH = p_stViewAttrib->dwHeight;
|
|
|
|
// xValues
|
|
xScaledSpriteW = p_stSprite->stDim.xX; // absolute dimensions
|
|
xScaledSpriteH = p_stSprite->stDim.xY;
|
|
xSpriteCenterX = p_stSuperObject->stModifiedMatrix.stTranslateVertex.xX;
|
|
xSpriteCenterY = p_stSuperObject->stModifiedMatrix.stTranslateVertex.xY;
|
|
xSpriteCornerX = xSpriteCenterX - TDE_M_Div(xScaledSpriteW, 2) + 0.5;
|
|
xSpriteCornerY = xSpriteCenterY - TDE_M_Div(xScaledSpriteH, 2) + 0.5;
|
|
|
|
// Destination rectangle
|
|
/*
|
|
iTDE_vFillsRect(&stDestRect, xSpriteCornerX - xSpriteCenterX, xSpriteCornerY - xSpriteCenterY,
|
|
xScaledSpriteW, xScaledSpriteH);
|
|
|
|
for (si=0; si<4; si++)
|
|
{
|
|
stDestRect.tdsSommet[si].xX += xSpriteCenterX;
|
|
stDestRect.tdsSommet[si].xY += xSpriteCenterY;
|
|
}
|
|
*/
|
|
iTDE_vFillsRect(&stDestRect, xSpriteCornerX, xSpriteCornerY, xScaledSpriteW, xScaledSpriteH);
|
|
|
|
// Out of screen ?
|
|
if ( (long)(stDestRect.tdsSommet[0].xX)>p_stScreenRect->tdsSommet[1].xX) return;
|
|
if ( (long)(stDestRect.tdsSommet[2].xX)<p_stScreenRect->tdsSommet[0].xX) return;
|
|
if ( (long)(stDestRect.tdsSommet[0].xY)>p_stScreenRect->tdsSommet[3].xY) return;
|
|
if ( (long)(stDestRect.tdsSommet[2].xY)<p_stScreenRect->tdsSommet[0].xY) return;
|
|
|
|
// Clipped ?
|
|
if ( ( (long)(stDestRect.tdsSommet[0].xX)<p_stScreenRect->tdsSommet[0].xX) ||
|
|
( (long)(stDestRect.tdsSommet[1].xX)>p_stScreenRect->tdsSommet[1].xX) ||
|
|
( (long)(stDestRect.tdsSommet[0].xY)<p_stScreenRect->tdsSommet[0].xY) ||
|
|
( (long)(stDestRect.tdsSommet[3].xY)>p_stScreenRect->tdsSommet[3].xY) )
|
|
{
|
|
clipped = 1;
|
|
}
|
|
|
|
if (p_stSuperObject->p_stSOClipRect)
|
|
clipped = 2;
|
|
|
|
if ( clipped == 1 )
|
|
{
|
|
//iTDE_vAdjustScreenRectForClip(&stDestRect, &stClippedDestRect, lViewPortW, lViewPortH);
|
|
if ( clipped == 1)
|
|
iTDE_vAdjustScreenRectToClipRect(&stDestRect, &stClippedDestRect, p_stScreenRect);
|
|
else if ( clipped == 2)
|
|
iTDE_vAdjustScreenRectToClipRect(&stDestRect, &stClippedDestRect, p_stSuperObject->p_stSOClipRect);
|
|
|
|
stClippedDestRect.p_usPointer = (TDE_tdxPixel *)(p_stViewAttrib->p_cVirtualScreen);
|
|
|
|
stSource.p_usPointer = p_stSprite->v_pData + // recal
|
|
TDE_M_ValueToLong (
|
|
( TDE_M_ValueToLong(stClippedDestRect.tdsSommet[0].xY) - TDE_M_ValueToLong(stDestRect.tdsSommet[0].xY) )*xScaledSpriteW ) +
|
|
( TDE_M_ValueToLong(stClippedDestRect.tdsSommet[0].xX) - TDE_M_ValueToLong(stDestRect.tdsSommet[0].xX) );
|
|
|
|
stSource.stDim.xX = xScaledSpriteW;
|
|
stSource.stDim.xY = xScaledSpriteH;
|
|
stSource.xMagicColor = p_stSprite->xMagicColor;
|
|
|
|
if (p_stSprite->c_NZ)
|
|
{ iTDE_vBlitClipMemory_Invert_NZ(&stSource, &stClippedDestRect); }
|
|
else
|
|
{ iTDE_vBlitClipMemory_Invert(&stSource, &stClippedDestRect); }
|
|
}
|
|
else
|
|
{
|
|
stDestRect.p_usPointer = (TDE_tdxPixel *)(p_stViewAttrib->p_cVirtualScreen);
|
|
stSource.p_usPointer = (TDE_tdxPixel *)(p_stSprite->v_pData);
|
|
stSource.stDim.xX = xScaledSpriteW;
|
|
stSource.stDim.xY = xScaledSpriteH;
|
|
stSource.xMagicColor = p_stSprite->xMagicColor;
|
|
|
|
if (p_stSprite->c_NZ)
|
|
{ iTDE_vBlitFastMemory_Invert_NZ(&stSource, &stDestRect); }
|
|
else
|
|
{ iTDE_vBlitFastMemory_Invert(&stSource, &stDestRect); }
|
|
}
|
|
}
|
|
|
|
|
|
void TDE_vFastDrawBackGround(GLD_tdpstViewportAttributes p_stViewAttrib,
|
|
TDE_tdsSuperObject *p_stSuperObject)
|
|
{
|
|
TDE_tdsSprite *p_stSprite = p_stSuperObject->p_stSprite;
|
|
TDE_tdxPixel *src, *dest;
|
|
|
|
dest = (TDE_tdxPixel *)(p_stViewAttrib->p_cVirtualScreen);
|
|
src = p_stSprite->v_pData;
|
|
|
|
//iTDE_vBackground((long *)src, (long *)dest);
|
|
}
|
|
|
|
|
|
/**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~**
|
|
NAME : TDE_vDrawSuperObjectClipped16
|
|
VERSION : 2.0 / Valérie
|
|
1.0 / Franck
|
|
|
|
AIM : Display a super object with clipping (for sprites)
|
|
**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~**/
|
|
|
|
void TDE_vDrawSuperObjectClipped16(GLD_tdpstViewportAttributes p_stViewAttrib,
|
|
TDE_tdsSuperObject *p_stSuperObject)
|
|
{
|
|
TDE_tdxValue xScaledSpriteW, xScaledSpriteH, xSpriteCenterX, xSpriteCenterY,
|
|
xSpriteCornerX, xSpriteCornerY, xSourceCornerX, xSourceCornerY,
|
|
xScaledSourceW, xScaledSourceH;
|
|
long lPitchDest, lPitchSrc, lViewPortW, lViewPortH;
|
|
short si;
|
|
TDE_tdsRect stSrcRect, stDestRect, stClippedDestRect,
|
|
stSrcFlippedRect, stSrcClippedRect;
|
|
TDE_tdsSprite *p_stSprite = p_stSuperObject->p_stSprite;
|
|
|
|
stSrcRect.lPitch = lPitchSrc = ((long)(p_stSprite->stPicture.xSrcPitch))>>C_TDEDEC;
|
|
stDestRect.lPitch = lPitchDest = (p_stViewAttrib->lPitch)>>C_TDEDEC;
|
|
lViewPortW = p_stViewAttrib->dwWidth;
|
|
lViewPortH = p_stViewAttrib->dwHeight;
|
|
|
|
// xValues
|
|
xScaledSpriteW = TDE_M_Mul(lViewPortW , p_stSprite->stDim.xX);
|
|
xScaledSpriteH = TDE_M_Mul(lViewPortH , p_stSprite->stDim.xY);
|
|
xSpriteCenterX = TDE_M_Mul(lViewPortW , p_stSuperObject->stModifiedMatrix.stTranslateVertex.xX);
|
|
xSpriteCenterY = TDE_M_Mul(lViewPortH , p_stSuperObject->stModifiedMatrix.stTranslateVertex.xY);
|
|
xSpriteCornerX = xSpriteCenterX - TDE_M_Div(xScaledSpriteW,2);
|
|
xSpriteCornerY = xSpriteCenterY - TDE_M_Div(xScaledSpriteH,2);
|
|
xSourceCornerX = TDE_M_Mul(p_stSprite->stPicture.xWidth , p_stSprite->stSourceOrigin.xX);
|
|
xSourceCornerY = TDE_M_Mul(p_stSprite->stPicture.xHeight , p_stSprite->stSourceOrigin.xY);
|
|
xScaledSourceW = TDE_M_Mul(p_stSprite->stPicture.xWidth , p_stSprite->stDim.xX);
|
|
xScaledSourceH = TDE_M_Mul(p_stSprite->stPicture.xHeight , p_stSprite->stDim.xY);
|
|
|
|
// Screen rectangle
|
|
iTDE_vFillsRect(&stDestRect, xSpriteCornerX - xSpriteCenterX, xSpriteCornerY - xSpriteCenterY,
|
|
xScaledSpriteW, xScaledSpriteH);
|
|
|
|
// Transformation
|
|
for ( si=0; si<4; si++ )
|
|
{
|
|
TDE_vMulMatrixByVertex(&(p_stSuperObject->stModifiedMatrix.a4_xS), &(stDestRect.tdsSommet[si]), &(stDestRect.tdsSommet[si]));
|
|
stDestRect.tdsSommet[si].xX += xSpriteCenterX;
|
|
stDestRect.tdsSommet[si].xY += xSpriteCenterY;
|
|
}
|
|
|
|
// Out of screen
|
|
if ( (long)(stDestRect.tdsSommet[0].xX)>lViewPortW ) return;
|
|
if ( (long)(stDestRect.tdsSommet[2].xX)<0 ) return;
|
|
if ( (long)(stDestRect.tdsSommet[0].xY)>lViewPortH ) return;
|
|
if ( (long)(stDestRect.tdsSommet[2].xY)<0 ) return;
|
|
|
|
// Adjust destination rectangle for clipping
|
|
iTDE_vAdjustScreenRectForClip(&stDestRect, &stClippedDestRect, lViewPortW, lViewPortH);
|
|
|
|
stClippedDestRect.p_usPointer = (TDE_tdxPixel *)(p_stViewAttrib->p_cVirtualScreen);
|
|
|
|
// Source rectangle
|
|
iTDE_vFillsRect(&stSrcRect, xSourceCornerX, xSourceCornerY, xScaledSourceW, xScaledSourceH);
|
|
stSrcRect.p_usPointer = (TDE_tdxPixel *)(p_stSprite->stPicture.lp_Data);
|
|
|
|
// Adjust source rectangle for flip
|
|
iTDE_vAdjustRectToFlip(&stSrcRect, &stSrcFlippedRect, p_stSprite->cFlip);
|
|
|
|
// Adjust source rectangle for clip
|
|
iTDE_vAdjustSourceRectForClip(&stDestRect, &stSrcFlippedRect, &stSrcClippedRect, lViewPortW, lViewPortH);
|
|
|
|
// Drawing loop
|
|
if ( !p_stSprite->cSemiTransparent )
|
|
{ iTDE_vBlit(&stSrcClippedRect, &stClippedDestRect); }
|
|
else
|
|
{ iTDE_vBlit_Transparency(&stSrcClippedRect, &stClippedDestRect, p_stSprite->alpha); }
|
|
}
|
|
|
|
|
|
/**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~**
|
|
NAME : TDE_vCalculateIntermediateVertex
|
|
VERSION : 2.0 / Valérie
|
|
1.0 / Franck
|
|
|
|
AIM : Calculate the clipped vertex between two points
|
|
**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~**/
|
|
|
|
void TDE_vCalculateIntermediateVertex(TDE_tdsClippedVertex1616 *Result_Point, TDE_tdsClippedVertex1616 *Point1, TDE_tdsClippedVertex1616 *Point2, TDE_tdl1616 lValue1, TDE_tdl1616 lValue2, TDE_tdl1616 lInterValue)
|
|
{
|
|
TDE_tdl1616 lInvert;
|
|
|
|
lInvert = TDE_DIV ( (lInterValue-lValue2) , (lValue1-lValue2) );
|
|
Result_Point->Point.lX = Point2->Point.lX + TDE_MUL( (Point1->Point.lX) - (Point2->Point.lX), lInvert ) ;
|
|
Result_Point->Point.lY = Point2->Point.lY + TDE_MUL( (Point1->Point.lY) - (Point2->Point.lY), lInvert ) ;
|
|
Result_Point->TexPoint.lX = Point2->TexPoint.lX + TDE_MUL( Point1->TexPoint.lX - Point2->TexPoint.lX, lInvert );
|
|
Result_Point->TexPoint.lY = Point2->TexPoint.lY + TDE_MUL( Point1->TexPoint.lY - Point2->TexPoint.lY, lInvert );
|
|
}
|
|
|
|
|
|
/**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~**
|
|
NAME : TDE_lClipPolygon
|
|
VERSION : 2.0 / Valérie
|
|
1.0 / Franck
|
|
|
|
AIM : Clip a polygon
|
|
**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~**/
|
|
|
|
long TDE_cClipPolygon(char cNB_SOMMETS, TDE_tdsClippedVertex1616 *p_stClipped_Line, long lWidth, long lHeight)
|
|
{
|
|
char cNB_SOMMETS2, cIndix, cVertexIndix, cClipped_NB_Sommets, cOver;
|
|
TDE_tdl1616 lYemin1616, lYemax1616, lXemin1616, lXemax1616;
|
|
TDE_tdsClippedVertex1616 *p_stCLineInter1, *p_stCLineInter2, *p_stCLine2Inter, p_stClipped_Line_2[20];
|
|
|
|
lYemin1616 = 1<<16;
|
|
lYemax1616 = (lHeight-1)<<16;
|
|
lXemin1616 = 1<<16;
|
|
lXemax1616 = (lWidth-1)<<16;
|
|
|
|
// Top cutting
|
|
cVertexIndix = (char)(cNB_SOMMETS-1);
|
|
cClipped_NB_Sommets = 0;
|
|
|
|
p_stCLineInter2 = &p_stClipped_Line[cVertexIndix];
|
|
p_stCLineInter1 = &p_stClipped_Line[0];
|
|
p_stCLine2Inter = &p_stClipped_Line_2[0];
|
|
for (cIndix=0; cIndix<cNB_SOMMETS; cIndix++)
|
|
{
|
|
cOver = 0;
|
|
if (p_stCLineInter1->Point.lY>=lYemin1616) cOver = 1;
|
|
if (p_stCLineInter2->Point.lY>=lYemin1616) cOver |= 2;
|
|
switch (cOver&3) {
|
|
case 3:
|
|
*(p_stCLine2Inter++) = *p_stCLineInter1;
|
|
cClipped_NB_Sommets++;
|
|
break;
|
|
case 1:
|
|
TDE_vCalculateIntermediateVertex(p_stCLine2Inter++, p_stCLineInter1, p_stCLineInter2, p_stCLineInter1->Point.lY, p_stCLineInter2->Point.lY, lYemin1616);
|
|
*(p_stCLine2Inter++) = *p_stCLineInter1;
|
|
cClipped_NB_Sommets += 2;
|
|
break;
|
|
case 2:
|
|
TDE_vCalculateIntermediateVertex(p_stCLine2Inter++, p_stCLineInter2, p_stCLineInter1, p_stCLineInter2->Point.lY, p_stCLineInter1->Point.lY, lYemin1616);
|
|
cClipped_NB_Sommets++;
|
|
break;
|
|
}
|
|
p_stCLineInter2 = p_stCLineInter1;
|
|
p_stCLineInter1++;
|
|
}
|
|
if (cClipped_NB_Sommets<2) return(0);
|
|
cNB_SOMMETS2 = cClipped_NB_Sommets;
|
|
|
|
// Bottom cutting
|
|
cVertexIndix = (char)(cNB_SOMMETS2-1);
|
|
cClipped_NB_Sommets = 0;
|
|
p_stCLineInter2 = &p_stClipped_Line_2[cVertexIndix];
|
|
p_stCLineInter1 = &p_stClipped_Line_2[0];
|
|
p_stCLine2Inter = &p_stClipped_Line[0];
|
|
for (cIndix=0; cIndix<cNB_SOMMETS2; cIndix++)
|
|
{
|
|
cOver = 0;
|
|
if (p_stCLineInter1->Point.lY<=lYemax1616) cOver = 1;
|
|
if (p_stCLineInter2->Point.lY<=lYemax1616) cOver |= 2;
|
|
switch (cOver&3) {
|
|
case 3:
|
|
*(p_stCLine2Inter++) = *p_stCLineInter1;
|
|
cClipped_NB_Sommets++;
|
|
break;
|
|
|
|
case 1:
|
|
TDE_vCalculateIntermediateVertex(p_stCLine2Inter++, p_stCLineInter1, p_stCLineInter2, p_stCLineInter1->Point.lY, p_stCLineInter2->Point.lY, lYemax1616);
|
|
*(p_stCLine2Inter++) = *p_stCLineInter1;
|
|
cClipped_NB_Sommets += 2;
|
|
break;
|
|
|
|
case 2:
|
|
TDE_vCalculateIntermediateVertex(p_stCLine2Inter++, p_stCLineInter2, p_stCLineInter1, p_stCLineInter2->Point.lY, p_stCLineInter1->Point.lY, lYemax1616);
|
|
cClipped_NB_Sommets++;
|
|
break;
|
|
}
|
|
p_stCLineInter2 = p_stCLineInter1;
|
|
p_stCLineInter1++;
|
|
}
|
|
if (cClipped_NB_Sommets<2) return(0);
|
|
cNB_SOMMETS = cClipped_NB_Sommets;
|
|
|
|
// Left cutting
|
|
|
|
cVertexIndix= (char)(cNB_SOMMETS-1);
|
|
cClipped_NB_Sommets = 0;
|
|
p_stCLineInter2 = &p_stClipped_Line[cVertexIndix];
|
|
p_stCLineInter1 = &p_stClipped_Line[0];
|
|
p_stCLine2Inter = &p_stClipped_Line_2[0];
|
|
for (cIndix=0; cIndix<cNB_SOMMETS; cIndix++)
|
|
{
|
|
cOver = 0;
|
|
if (p_stCLineInter1->Point.lX>=lXemin1616) cOver = 1;
|
|
if (p_stCLineInter2->Point.lX>=lXemin1616) cOver |= 2;
|
|
switch (cOver&3) {
|
|
case 3:
|
|
*(p_stCLine2Inter++) = *p_stCLineInter1;
|
|
cClipped_NB_Sommets++;
|
|
break;
|
|
case 1:
|
|
TDE_vCalculateIntermediateVertex(p_stCLine2Inter++, p_stCLineInter1, p_stCLineInter2, p_stCLineInter1->Point.lX, p_stCLineInter2->Point.lX, lXemin1616);
|
|
*(p_stCLine2Inter++) = *p_stCLineInter1;
|
|
cClipped_NB_Sommets += 2;
|
|
break;
|
|
|
|
case 2:
|
|
TDE_vCalculateIntermediateVertex(p_stCLine2Inter++, p_stCLineInter2, p_stCLineInter1, p_stCLineInter2->Point.lX, p_stCLineInter1->Point.lX, lXemin1616);
|
|
cClipped_NB_Sommets++;
|
|
break;
|
|
}
|
|
p_stCLineInter2 = p_stCLineInter1;
|
|
p_stCLineInter1++;
|
|
}
|
|
if (cClipped_NB_Sommets<2) return(0);
|
|
|
|
// Right cutting
|
|
|
|
cNB_SOMMETS2 = cClipped_NB_Sommets;
|
|
cVertexIndix = (char)(cNB_SOMMETS2-1);
|
|
cClipped_NB_Sommets = 0;
|
|
p_stCLineInter2 = &p_stClipped_Line_2[cVertexIndix];
|
|
p_stCLineInter1 = &p_stClipped_Line_2[0];
|
|
p_stCLine2Inter = p_stClipped_Line;
|
|
for (cIndix=0; cIndix<cNB_SOMMETS2; cIndix++)
|
|
{
|
|
cOver = 0;
|
|
if (p_stCLineInter1->Point.lX<=lXemax1616) cOver = 1;
|
|
if (p_stCLineInter2->Point.lX<=lXemax1616) cOver |= 2;
|
|
switch (cOver&3) {
|
|
case 3:
|
|
*(p_stCLine2Inter++) = *p_stCLineInter1;
|
|
cClipped_NB_Sommets++;
|
|
break;
|
|
case 1:
|
|
TDE_vCalculateIntermediateVertex(p_stCLine2Inter++, p_stCLineInter1, p_stCLineInter2, p_stCLineInter1->Point.lX, p_stCLineInter2->Point.lX, lXemax1616);
|
|
*(p_stCLine2Inter++) = *p_stCLineInter1;
|
|
cClipped_NB_Sommets += 2;
|
|
break;
|
|
case 2:
|
|
TDE_vCalculateIntermediateVertex(p_stCLine2Inter++, p_stCLineInter2, p_stCLineInter1, p_stCLineInter2->Point.lX, p_stCLineInter1->Point.lX, lXemax1616);
|
|
cClipped_NB_Sommets++;
|
|
break;
|
|
}
|
|
p_stCLineInter2 = p_stCLineInter1;
|
|
p_stCLineInter1++;
|
|
}
|
|
|
|
if (cClipped_NB_Sommets<2) return(0);
|
|
return(cClipped_NB_Sommets);
|
|
}
|
|
|
|
|
|
/**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~**
|
|
NAME : TDE_vFillTableMM
|
|
VERSION : 2.0 / Valérie
|
|
1.0 / Franck
|
|
|
|
AIM : Fill the Min-Max Table
|
|
**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~**/
|
|
|
|
void TDE_vFillTableMM(long lStart, long lLenght, long lColumn, TDE_tdl1616 lValue1, TDE_tdl1616 lValue2)
|
|
{
|
|
TDE_tdl1616 *p_MMStart, *p_MMEnd;
|
|
TDE_tdl1616 lVinc;
|
|
|
|
if (lValue2 != lValue1)
|
|
{
|
|
lVinc = TDE_DIV( lValue2-lValue1 , (lLenght<<16) );
|
|
p_MMStart = &a_lTableMM[lStart][lColumn];
|
|
p_MMEnd = p_MMStart + (lLenght<<3);
|
|
for (;p_MMStart<p_MMEnd; p_MMStart=p_MMStart+8, lValue1 += lVinc)
|
|
*p_MMStart = lValue1;
|
|
}
|
|
else
|
|
{
|
|
p_MMStart = &a_lTableMM[lStart][lColumn];
|
|
p_MMEnd = p_MMStart+(lLenght<<3);
|
|
for (;p_MMStart<p_MMEnd; p_MMStart = p_MMStart+8)
|
|
*p_MMStart = lValue1;
|
|
}
|
|
}
|
|
|
|
|
|
void TDE_vDrawSuperObjectRotated16(GLD_tdpstViewportAttributes p_stViewAttrib,
|
|
TDE_tdsSuperObject *p_stSuperObject)
|
|
{
|
|
TDE_tdxValue xW, xH, xXc, xYc, xXs, xYs, xWs, xHs, xX, xY;
|
|
TDE_tdl1616 lXg, lXd, lUg, lUd, lVg, lVd, ldU, ldV, ldX,
|
|
ldE, lF, ldF, ldY;
|
|
short si;
|
|
long lPitSrc, lPitDest, lgW, lgH,
|
|
lNBSommets, lYmin, lYmax, *T_H, lMiddle;
|
|
TDE_tdxPixel *p_usDest, *p_usDestEnd, *p_usDestSave, *p_usOfs, *p_usL,
|
|
c, usSpritePixel, usBackPixel;
|
|
TDE_tdsClippedVertex1616 Polygon[8], *Ptr1, *Ptr2;
|
|
TDE_tdsClippedVertex xPolygon[8];
|
|
|
|
TDE_tdsSprite *p_stSprite = p_stSuperObject->p_stSprite;
|
|
|
|
// Variables for alpha-transparency
|
|
short sBlueMask = 0x001F; // 0000 0000 0001 1111 -> obtain blue component
|
|
short sGreenMask = 0x07E0; // 0000 0111 1110 0000 -> obtain green component
|
|
// short sRedMask = 0xF800; // 1111 1000 0000 0000 -> obtain red component
|
|
short sB, sG, sR;
|
|
char cIndix1, cIndix2;
|
|
unsigned char *p_cAcc15, *p_cAcc25, *p_cAcc16, *p_cAcc26;
|
|
|
|
lPitSrc = ((long)(p_stSprite->stPicture.xSrcPitch))>>C_TDEDEC;
|
|
lPitDest = (p_stViewAttrib->lPitch)>>C_TDEDEC;
|
|
lgW = p_stViewAttrib->dwWidth;
|
|
lgH = p_stViewAttrib->dwHeight;
|
|
|
|
// xValues
|
|
xW = TDE_M_Mul(lgW , p_stSprite->stDim.xX);
|
|
xH = TDE_M_Mul(lgH , p_stSprite->stDim.xY);
|
|
xXc = TDE_M_Mul(lgW , p_stSuperObject->stModifiedMatrix.stTranslateVertex.xX);
|
|
xYc = TDE_M_Mul(lgH , p_stSuperObject->stModifiedMatrix.stTranslateVertex.xY);
|
|
xXs = TDE_M_Mul(p_stSprite->stPicture.xWidth , p_stSprite->stSourceOrigin.xX);
|
|
xYs = TDE_M_Mul(p_stSprite->stPicture.xHeight , p_stSprite->stSourceOrigin.xY);
|
|
xWs = TDE_M_Mul(p_stSprite->stPicture.xWidth , p_stSprite->stDim.xX);
|
|
xHs = TDE_M_Mul(p_stSprite->stPicture.xHeight , p_stSprite->stDim.xY);
|
|
xX = xXc - TDE_M_Div(xW,2);
|
|
xY = xYc - TDE_M_Div(xH,2);
|
|
|
|
p_usOfs = p_usL = (TDE_tdxPixel *)(p_stSprite->stPicture.lp_Data);
|
|
p_usDest = (TDE_tdxPixel *)p_stViewAttrib->p_cVirtualScreen;
|
|
|
|
if (((xX+xW)<=1.0)||(xX>=lgW)) return;
|
|
if (((xY+xH)<=1.0)||(xY>=lgH)) return;
|
|
|
|
xPolygon[0].Point.xX = xX-xXc;
|
|
xPolygon[0].Point.xY = xY-xYc;
|
|
|
|
xPolygon[1].Point.xX = xX+xW-xXc;
|
|
xPolygon[1].Point.xY = xY-xYc;
|
|
|
|
xPolygon[2].Point.xX = xX+xW-xXc;
|
|
xPolygon[2].Point.xY = xY+xH-xYc;
|
|
|
|
xPolygon[3].Point.xX = xX-xXc;
|
|
xPolygon[3].Point.xY = xY+xH-xYc;
|
|
|
|
for (si=0; si<4; si++)
|
|
{
|
|
TDE_vMulMatrixByVertex(&(p_stSuperObject->stModifiedMatrix.a4_xRxS), &xPolygon[si].Point, &xPolygon[si].Point);
|
|
xPolygon[si].Point.xX += xXc;
|
|
xPolygon[si].Point.xY += xYc;
|
|
}
|
|
|
|
xPolygon[0].TexPoint.xX = xPolygon[3].TexPoint.xX = xXs;
|
|
xPolygon[1].TexPoint.xX = xPolygon[2].TexPoint.xX = xXs+xWs;
|
|
|
|
xPolygon[0].TexPoint.xY = xPolygon[1].TexPoint.xY = xYs;
|
|
xPolygon[2].TexPoint.xY = xPolygon[3].TexPoint.xY = xYs+xHs;
|
|
|
|
// xPolygon -> Polygon
|
|
for (si=0; si<4; si++)
|
|
{
|
|
Polygon[si].Point.lX = TDE_M_ValueTo1616(xPolygon[si].Point.xX);
|
|
Polygon[si].Point.lY = TDE_M_ValueTo1616(xPolygon[si].Point.xY);
|
|
Polygon[si].TexPoint.lX = TDE_M_ValueTo1616(xPolygon[si].TexPoint.xX);
|
|
Polygon[si].TexPoint.lY = TDE_M_ValueTo1616(xPolygon[si].TexPoint.xY);
|
|
}
|
|
|
|
// Clip
|
|
lNBSommets = TDE_cClipPolygon(4, Polygon, lgW, lgH);
|
|
|
|
// 16:16 -> int
|
|
for (si=0; si<lNBSommets; si++)
|
|
Polygon[si].Point.lY>>=16;
|
|
|
|
// Fills min-max table
|
|
if (lNBSommets>2)
|
|
{
|
|
Ptr1 = &Polygon[0];
|
|
Ptr2 = &Polygon[lNBSommets-1];
|
|
lYmin = Ptr2->Point.lY;
|
|
lYmax = Ptr2->Point.lY;
|
|
for (si=0; si<lNBSommets; si++)
|
|
{
|
|
if (Ptr1->Point.lY<lYmin) lYmin = Ptr1->Point.lY;
|
|
if (Ptr1->Point.lY>lYmax) lYmax = Ptr1->Point.lY;
|
|
if (Ptr2->Point.lY<Ptr1->Point.lY)
|
|
{ // Right
|
|
TDE_vFillTableMM(Ptr2->Point.lY, Ptr1->Point.lY-Ptr2->Point.lY, 1, Ptr2->Point.lX, Ptr1->Point.lX);
|
|
TDE_vFillTableMM(Ptr2->Point.lY, Ptr1->Point.lY-Ptr2->Point.lY, 4, Ptr2->TexPoint.lX, Ptr1->TexPoint.lX);
|
|
TDE_vFillTableMM(Ptr2->Point.lY, Ptr1->Point.lY-Ptr2->Point.lY, 5, Ptr2->TexPoint.lY, Ptr1->TexPoint.lY);
|
|
}
|
|
else if (Ptr2->Point.lY>Ptr1->Point.lY)
|
|
{ // Left
|
|
TDE_vFillTableMM(Ptr1->Point.lY, Ptr2->Point.lY-Ptr1->Point.lY, 0, (Ptr1->Point.lX), (Ptr2->Point.lX));
|
|
TDE_vFillTableMM(Ptr1->Point.lY, Ptr2->Point.lY-Ptr1->Point.lY, 2, (Ptr1->TexPoint.lX), (Ptr2->TexPoint.lX));
|
|
TDE_vFillTableMM(Ptr1->Point.lY, Ptr2->Point.lY-Ptr1->Point.lY, 3, (Ptr1->TexPoint.lY), (Ptr2->TexPoint.lY));
|
|
}
|
|
Ptr2=Ptr1;
|
|
Ptr1++;
|
|
}
|
|
}
|
|
|
|
// Is the sprite out of screen (Y) ?
|
|
if ((lYmin>=(lgH-1))||(lYmax<=1)) return;
|
|
|
|
// Increments calculation
|
|
lMiddle = lYmin+((lYmax-lYmin)>>1);
|
|
if ((lMiddle<0)||(lMiddle>768)) return; // debug
|
|
T_H = &a_lTableMM[lMiddle][0];
|
|
ldX = *(T_H+1) - *(T_H);
|
|
lUg = *(T_H+2);
|
|
lVg = *(T_H+3);
|
|
lUd = *(T_H+4);
|
|
lVd = *(T_H+5);
|
|
|
|
if (ldX>0)
|
|
{
|
|
ldU = TDE_DIV((lUd-lUg),ldX);
|
|
ldV = TDE_DIV((lVd-lVg),ldX);
|
|
}
|
|
else return;
|
|
|
|
ldE = lPitSrc*(ldV>>16)+(ldU>>16);
|
|
ldF = ((ldV>>1)&0x7FFF)+((ldU<<15)&0x7FFF0000);
|
|
T_H = &a_lTableMM[lYmin][0];
|
|
p_usDest += lYmin*lPitDest;
|
|
ldY = lYmax-lYmin;
|
|
|
|
// Main loop
|
|
|
|
if (!p_stSprite->cSemiTransparent)
|
|
{
|
|
// No semi-transparency
|
|
for (si=0; si<ldY; si++,T_H+=8)
|
|
{
|
|
lXg = *(T_H)>>16;
|
|
lXd = *(T_H+1)>>16;
|
|
lUg = *(T_H+2);
|
|
lVg = *(T_H+3);
|
|
lF = ((lVg>>1)&0x7FFF)+((lUg<<15)&0x7FFF0000);
|
|
p_usOfs = p_usL + lPitSrc*(lVg>>16)+(lUg>>16);
|
|
p_usDestSave = p_usDest;
|
|
p_usDestEnd = p_usDest+lXd;
|
|
|
|
for (p_usDest=p_usDest+lXg; p_usDest<p_usDestEnd; p_usDest++)
|
|
{
|
|
//if (p_cOfs>p_cL) // debug
|
|
c = *p_usOfs;
|
|
if (c>0)
|
|
*p_usDest = c;
|
|
lF += ldF;
|
|
p_usOfs += ldE;
|
|
if (lF&0x8000) {lF&=0xFFFF7FFF; p_usOfs+=lPitSrc; }
|
|
if (lF&0x80000000) {lF&=0x7FFFFFFF; p_usOfs++; }
|
|
}
|
|
|
|
p_usDest = p_usDestSave + lPitDest;
|
|
}
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
cIndix1 = ((char)(p_stSprite->alpha*64))&0x3F;
|
|
cIndix2 = 63-cIndix1;
|
|
p_cAcc15 = &(a_cTransparencyTable5[cIndix1][0]);
|
|
p_cAcc25 = &(a_cTransparencyTable5[cIndix2][0]);
|
|
p_cAcc16 = &(a_cTransparencyTable6[cIndix1][0]);
|
|
p_cAcc26 = &(a_cTransparencyTable6[cIndix2][0]);
|
|
|
|
// semi-transparency
|
|
for (si=0; si<ldY; si++,T_H+=8)
|
|
{
|
|
lXg = *(T_H)>>16;
|
|
lXd = *(T_H+1)>>16;
|
|
lUg = *(T_H+2);
|
|
lVg = *(T_H+3);
|
|
lF = ((lVg>>1)&0x7FFF)+((lUg<<15)&0x7FFF0000);
|
|
p_usOfs = p_usL + lPitSrc*(lVg>>16)+(lUg>>16);
|
|
p_usDestSave = p_usDest;
|
|
p_usDestEnd = p_usDest + lXd;
|
|
|
|
|
|
for (p_usDest=p_usDest+lXg; p_usDest<p_usDestEnd; p_usDest++)
|
|
{
|
|
usSpritePixel = *p_usOfs;
|
|
if (usSpritePixel>0)
|
|
{
|
|
usBackPixel = *p_usDest;
|
|
sB = *(p_cAcc15 + (usBackPixel & sBlueMask)) + *(p_cAcc25+ (usSpritePixel & sBlueMask));
|
|
sG = *(p_cAcc16 + ((usBackPixel & sGreenMask)>>5)) + *(p_cAcc26 + ((usSpritePixel & sGreenMask)>>5));
|
|
sR = *(p_cAcc15 + (usBackPixel>>11)) + *(p_cAcc25 + (usSpritePixel>>11));
|
|
*p_usDest = sB+(sG<<5)+(sR<<11);
|
|
}
|
|
lF += ldF;
|
|
p_usOfs += ldE;
|
|
if (lF&0x8000) {lF&=0xFFFF7FFF; p_usOfs+=lPitSrc; }
|
|
if (lF&0x80000000) {lF&=0x7FFFFFFF; p_usOfs++; }
|
|
}
|
|
p_usDest = p_usDestSave + lPitDest;
|
|
|
|
}
|
|
} // if (!p_stSprite->cSemiTransparent ....)
|
|
}
|
|
|
|
void TDE_vResetTable()
|
|
{
|
|
short si, sj;
|
|
|
|
for (si=0; si<768; si++)
|
|
{
|
|
for (sj=0; sj<8; sj++) a_lTableMM[si][sj] = 0;
|
|
}
|
|
}
|
|
|
|
|
|
void TDE_vSendObjectsToViewPort(GLD_tdpstViewportAttributes p_stViewAttrib, TDE_tdsSuperObject *p_stSuperObject, TDE_p_stSuperObject *ZList)
|
|
{
|
|
//TDE_tdsSuperObject *p_stSuperObjectTemp;
|
|
|
|
// Reset matrices stack (!)
|
|
ResetMatrixStack((TDE_tdsCamera *)(p_stViewAttrib->p_vSpecificToXD));
|
|
// Init Z list
|
|
TDE_vInitZList(ZList);
|
|
// Rebuild all SuperObjects matrices
|
|
TDE_vCreateSuperObjectDescendancyMatrices(p_stSuperObject);
|
|
// Build Z list
|
|
TDE_vBuildHierarchy(p_stSuperObject, ZList);
|
|
}
|
|
|
|
/**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~**
|
|
NAME : TDE_vSendListToViewPort
|
|
VERSION : 2.0 / Valérie
|
|
1.0 / Franck
|
|
|
|
AIM : Send Z liste to a viewport
|
|
Disposable functions :
|
|
TDE_vDrawSuperObject16(GLD_tdpstViewportAttributes p_stViewAttrib, TDE_tdsSuperObject *p_stSuperObjet);
|
|
TDE_vDrawSuperObjectFast16(GLD_tdpstViewportAttributes p_stViewAttrib, TDE_tdsSuperObject *p_stSuperObjet);
|
|
TDE_vDrawMemSprite_Abs_16(GLD_tdpstViewportAttributes p_stViewAttrib, TDE_tdsSuperObject *p_stSuperObjet);
|
|
TDE_vDrawSuperObjectRotated16(GLD_tdpstViewportAttributes p_stViewAttrib, TDE_tdsSuperObject *p_stSuperObjet);
|
|
TDE_vDrawSuperObjectClipped16(GLD_tdpstViewportAttributes p_stViewAttrib, TDE_tdsSuperObject *p_stSuperObjet);
|
|
**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~**/
|
|
void TDE_vSendListToViewPort(GLD_tdpstViewportAttributes p_stViewAttrib, TDE_p_stSuperObject *ZList, TDE_tdsRect *stClipScreenRect, BOOL bViewPortLocked)
|
|
{
|
|
TDE_tdsSuperObject *p_stSuperObjectTemp;
|
|
short si;
|
|
|
|
// Draw ZList
|
|
if (bViewPortLocked)
|
|
{
|
|
// Viewport is locked : draw everything but True Type text
|
|
for (si=0; si<TDE_kMAXPRIORITY; si++)
|
|
{
|
|
if (ZList[si]!=NULL)
|
|
for (p_stSuperObjectTemp = ZList[si]; p_stSuperObjectTemp != NULL; p_stSuperObjectTemp = p_stSuperObjectTemp->p_stNextZList)
|
|
{
|
|
if (p_stSuperObjectTemp->p_vPointer != NULL)
|
|
{
|
|
switch (p_stSuperObjectTemp->eType)
|
|
{
|
|
case TDE_eOT_SPRITE:
|
|
TDE_vFastDrawMemorySpriteAbsolute(p_stViewAttrib, p_stSuperObjectTemp, stClipScreenRect);
|
|
break;
|
|
case TDE_eOT_TEXTBOX:
|
|
TDE_vDrawTextInABox(p_stViewAttrib, p_stSuperObjectTemp, TRUE);
|
|
break;
|
|
case TDE_eOT_LINE:
|
|
TDE_vDrawSuperObjectLineAbs(p_stViewAttrib, p_stSuperObjectTemp);
|
|
break;
|
|
case TDE_eOT_EMPTY:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Viewport is not locked : draw nothing but True Type text
|
|
for (si=0; si<TDE_kMAXPRIORITY; si++)
|
|
{
|
|
if (ZList[si]!=NULL)
|
|
for (p_stSuperObjectTemp = ZList[si]; p_stSuperObjectTemp != NULL; p_stSuperObjectTemp = p_stSuperObjectTemp->p_stNextZList)
|
|
{
|
|
if (p_stSuperObjectTemp->p_vPointer != NULL)
|
|
{
|
|
switch (p_stSuperObjectTemp->eType)
|
|
{
|
|
case TDE_eOT_TEXTBOX:
|
|
TDE_vDrawTextInABox(p_stViewAttrib, p_stSuperObjectTemp, FALSE);
|
|
break;
|
|
case TDE_eOT_EMPTY:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|