📄 sa2video.cpp
字号:
if (*surface != NULL)
{
// Check that the bits were allocated succesfully
if (((*surface)->Buffer()) == NULL)
{
delete *surface;
}
else
{
return S_OK;
}
}
return E_OUTOFMEMORY;
}
SCODE
SA2Video::WrappedEmulatedLine(
GPELineParms *pParms
)
{
SCODE retval;
RECT bounds;
int N_plus_1; // Minor length of bounding rect + 1
// calculate the bounding-rect to determine overlap with cursor
if (pParms->dN) // The line has a diagonal component (we'll refresh the bounding rect)
{
N_plus_1 = 2 + ((pParms->cPels * pParms->dN) / pParms->dM);
}
else
{
N_plus_1 = 1;
}
switch(pParms->iDir)
{
case 0:
bounds.left = pParms->xStart;
bounds.top = pParms->yStart;
bounds.right = pParms->xStart + pParms->cPels + 1;
bounds.bottom = bounds.top + N_plus_1;
break;
case 1:
bounds.left = pParms->xStart;
bounds.top = pParms->yStart;
bounds.bottom = pParms->yStart + pParms->cPels + 1;
bounds.right = bounds.left + N_plus_1;
break;
case 2:
bounds.right = pParms->xStart + 1;
bounds.top = pParms->yStart;
bounds.bottom = pParms->yStart + pParms->cPels + 1;
bounds.left = bounds.right - N_plus_1;
break;
case 3:
bounds.right = pParms->xStart + 1;
bounds.top = pParms->yStart;
bounds.left = pParms->xStart - pParms->cPels;
bounds.bottom = bounds.top + N_plus_1;
break;
case 4:
bounds.right = pParms->xStart + 1;
bounds.bottom = pParms->yStart + 1;
bounds.left = pParms->xStart - pParms->cPels;
bounds.top = bounds.bottom - N_plus_1;
break;
case 5:
bounds.right = pParms->xStart + 1;
bounds.bottom = pParms->yStart + 1;
bounds.top = pParms->yStart - pParms->cPels;
bounds.left = bounds.right - N_plus_1;
break;
case 6:
bounds.left = pParms->xStart;
bounds.bottom = pParms->yStart + 1;
bounds.top = pParms->yStart - pParms->cPels;
bounds.right = bounds.left + N_plus_1;
break;
case 7:
bounds.left = pParms->xStart;
bounds.bottom = pParms->yStart + 1;
bounds.right = pParms->xStart + pParms->cPels + 1;
bounds.top = bounds.bottom - N_plus_1;
break;
default:
DEBUGMSG(GPE_ZONE_ERROR,(TEXT("Invalid direction: %d\r\n"), pParms->iDir));
return E_INVALIDARG;
}
// check for line overlap with cursor and turn off cursor if overlaps
if (!bDoRotation)
{
if (m_CursorVisible && !m_CursorDisabled)
{
RotateRectl(&m_CursorRect);
if (m_CursorRect.top < bounds.bottom && m_CursorRect.bottom > bounds.top &&
m_CursorRect.left < bounds.right && m_CursorRect.right > bounds.left)
{
RotateRectlBack(&m_CursorRect);
CursorOff();
m_CursorForcedOff = TRUE;
}
else
{
RotateRectlBack(&m_CursorRect);
}
}
}
// do emulated line
retval = EmulatedLine(pParms);
// see if cursor was forced off because of overlap with line bouneds and turn back on.
if (!bDoRotation)
{
if (m_CursorForcedOff)
{
m_CursorForcedOff = FALSE;
CursorOn();
}
}
return retval;
}
#undef SWAP
#define SWAP(a,b,type) { type tmp=a; a=b; b=tmp; }
int
EmulatedBltFill16_C(
WORD * pDst,
WORD color,
int width,
int height,
unsigned int step
)
{
step >>= 1; //in 16-bit
step -= width;
for (int r = 0; r < height; r++)
{
for (int w = 0; w < width; w++)
{
*pDst++ = color;
}
pDst += step;
}
return 0;
}
extern "C" SCODE EmulatedBltFill16ASM(WORD* pDst, WORD color, int width, int height, unsigned int step);
SCODE EmulatedBltSrcCopy0416( GPEBltParms *pParms );
SCODE EmulatedBltSrcCopy0116( GPEBltParms *pParms );
SCODE EmulatedBltSrcCopy0808( GPEBltParms *pParms );
SCODE EmulatedBltSrcCopy0408( GPEBltParms *pParms );
SCODE EmulatedBltSrcCopy0108( GPEBltParms *pParms );
__inline
SCODE
EmulatedBltFill16_Eml(
GPEBltParms * pParms
)
{
DEBUGMSG(GPE_ZONE_BLT_HI,(TEXT("EmulatedBltFill16\r\n")));
UINT32 iDstScanStride = pParms->pDst->Stride();
BYTE * pbDibBitsDst = (BYTE *)pParms->pDst->Buffer();
PRECTL prcDst = pParms->prclDst;
DWORD dwOnColorIndex = pParms->solidColor;
int iNumDstRows = prcDst->bottom - prcDst->top;
int iNumDstCols = prcDst->right - prcDst->left;
// Compute pointer to the starting rows in the dst bitmap
WORD *pwDstScanLine = (WORD *)(pbDibBitsDst + prcDst->top * iDstScanStride + prcDst->left * 2);
WORD wColor = (WORD)dwOnColorIndex;
EmulatedBltFill16ASM(pwDstScanLine, wColor, iNumDstCols, iNumDstRows, iDstScanStride);
return S_OK;
}
#define BLOCK_OP(pbDst, pbSrc, cBytes) memmove(pbDst, pbSrc, cBytes)
#define SCRCOPY_ASM
extern "C" void EmulatedBltSrcCopy1616ASM(WORD* pwScanLineSrc, WORD *pwScanLineDst, int width, int height, UINT32 iScanStrideSrc, UINT32 iScanStrideDst);
#define _MM_OPT_ASM
#ifdef _MM_OPT_ASM
extern "C"
{
void Memmove1616_ASM_LE16(WORD* pSrc, WORD *pDst, int len) ;
void Memmove1616_ASM_GT16(WORD* pSrc, WORD *pDst, int len) ;
}
#else
#include "ebcopy1616.h"
#endif
SCODE
EmulatedBltSrcCopy1616_Eml(
GPEBltParms *pParms
)
{
// Source-related info
PRECTL prcSrc = pParms->prclSrc;
UINT32 iScanStrideSrc = pParms->pSrc->Stride()/sizeof(WORD);
WORD * pwScanLineSrc = (WORD *)pParms->pSrc->Buffer() +
prcSrc->top * iScanStrideSrc +
prcSrc->left;
// Dest-related info
PRECTL prcDst = pParms->prclDst;
UINT32 iScanStrideDst = pParms->pDst->Stride()/sizeof(WORD);
WORD * pwScanLineDst = (WORD *)pParms->pDst->Buffer() +
prcDst->top * iScanStrideDst +
prcDst->left;
int cRows = prcDst->bottom - prcDst->top;
int cCols = prcDst->right - prcDst->left;
// Make sure to copy source before overwriting.
if (!pParms->yPositive)
{
// Scan from end of memory, and negate stride
pwScanLineSrc += iScanStrideSrc * (cRows - 1);
pwScanLineDst += iScanStrideDst * (cRows - 1);
iScanStrideSrc = (UINT32)-(INT32)iScanStrideSrc;
iScanStrideDst = (UINT32)-(INT32)iScanStrideDst;
}
#ifdef SCRCOPY_ASM
EmulatedBltSrcCopy1616ASM(pwScanLineSrc, pwScanLineDst, cCols, cRows,
iScanStrideSrc, iScanStrideDst);
#else
//
// Do the copy line by line.
//
//EmulatedBltSrcCopy1616_CO(pwScanLineSrc, pwScanLineDst, cCols, cRows,
// iScanStrideSrc, iScanStrideDst, xPositive);
for (int row = 0; row < cRows; row++)
{
//BLOCK_OP(pwScanLineDst, pwScanLineSrc, cCols*sizeof(WORD));
if ( cCols < 8 ) {
#ifndef _MM_OPT_ASM
Memmove1616_C_SIMPLE(pwScanLineSrc, pwScanLineDst, cCols);
#else
Memmove1616_ASM_LE16(pwScanLineSrc, pwScanLineDst, cCols);
#endif
} else {
#ifndef _MM_OPT_ASM
Memmove1616_C(pwScanLineSrc, pwScanLineDst, cCols);
#else
Memmove1616_ASM_GT16(pwScanLineSrc, pwScanLineDst, cCols);
#endif
}
pwScanLineSrc += iScanStrideSrc;
pwScanLineDst += iScanStrideDst;
}
#endif
return S_OK;
}
#define SHIFT_ONE_MASK 0x7BEF
#define SHIFT_TWO_MASK 0x39E7
extern "C" void EmulatedBltText16ASM(BYTE* pSrcMask, WORD* pDstPixel, WORD color, int width, int height, unsigned int stepMask, unsigned int stepDst, int OffsetSrc);
__inline
SCODE
EmulatedBltAlphaText16_Eml(
GPEBltParms *pParms
)
{
DEBUGMSG(GPE_ZONE_BLT_HI,(TEXT("EmulatedBltAlphaText16\r\n")));
UINT32 iDstScanStride = pParms->pDst->Stride();
BYTE * pDibBitsDst = (BYTE *)pParms->pDst->Buffer();
UINT32 iSrcScanStride = pParms->pMask->Stride();
BYTE * pDibBitsSrc = (BYTE *)pParms->pMask->Buffer();
PRECTL prcSrc = pParms->prclMask;
PRECTL prcDst = pParms->prclDst;
WORD wOnColor[5];
int iNumDstRows;
int iNumDstCols;
BYTE * pbSrcScanLine;
BYTE * pbDstScanLine;
BYTE * pbSrc;
WORD * pwDstPixel;
BOOL bOdd;
BYTE bSrc;
// Caller assures a well-ordered, non-empty rect
// compute size of destination rect
iNumDstCols = prcDst->right - prcDst->left;
iNumDstRows = prcDst->bottom - prcDst->top;
// compute pointers to the starting rows in the src and dst bitmaps
pbSrcScanLine = pDibBitsSrc + prcSrc->top * iSrcScanStride + (prcSrc->left >> 1);
pbDstScanLine = pDibBitsDst + prcDst->top * iDstScanStride + prcDst->left * 2;
// Create pixel values with 0/4, 1/4, 2/4, 3/4 and 4/4 of the solid brush color
wOnColor[0] = 0;
wOnColor[4] = (WORD)pParms->solidColor;
wOnColor[2] = (wOnColor[4] >> 1 ) & SHIFT_ONE_MASK;
wOnColor[1] = (wOnColor[4] >> 2 ) & SHIFT_TWO_MASK;
wOnColor[3] = wOnColor[1] + wOnColor[2];
for (int i = 0; i < iNumDstRows; i++)
{
// set up pointers to first bytes on src and dst scanlines
pbSrc = pbSrcScanLine;
pwDstPixel = (WORD *)pbDstScanLine;
bOdd = prcSrc->left & 1;
for (int j = 0; j < iNumDstCols; j++ )
{
if (bOdd)
{
bSrc = *pbSrc++ & 0xF;
}
else
{
bSrc = *pbSrc >> 4;
}
bOdd = !bOdd;
switch ( (bSrc + 1) >> 2 ) // src pixel in range 0...4
{
case 0:
// Leave destination untouched
break;
case 1:
// 3/4 destination color and 1/4 brush color
*pwDstPixel = ((*pwDstPixel >> 2) & SHIFT_TWO_MASK)
+ ((*pwDstPixel >> 1) & SHIFT_ONE_MASK) + wOnColor[1];
break;
case 2:
// 1/2 destination color and 1/2 brush color
*pwDstPixel = ((*pwDstPixel >> 1) & SHIFT_ONE_MASK) + wOnColor[2];
break;
case 3:
// 1/4 destination color and 3/4 brush color
*pwDstPixel = ((*pwDstPixel >> 2) & SHIFT_TWO_MASK) + wOnColor[3];
break;
case 4:
// Fill with solid brush color
*pwDstPixel = wOnColor[4];
break;
default:
DebugBreak();
}
pwDstPixel++;
}
// advance to next scanline
pbSrcScanLine += iSrcScanStride;
pbDstScanLine += iDstScanStride;
}
return S_OK;
}
__inline
SCODE
EmulatedBltText16_Eml(
GPEBltParms * pParms
)
{
DEBUGMSG(GPE_ZONE_BLT_HI,(TEXT("EmulatedBltText16\r\n")));
UINT32 iDstScanStride = pParms->pDst->Stride();
BYTE * pDibBitsDst = (BYTE *)pParms->pDst->Buffer();
UINT32 iSrcScanStride = pParms->pMask->Stride();
BYTE * pDibBitsSrc = (BYTE *)pParms->pMask->Buffer();
PRECTL prcSrc = pParms->prclMask;
PRECTL prcDst = pParms->prclDst;
unsigned int wOnColor = (unsigned int)pParms->solidColor;
int iSrcBitOffset;
int iNumDstRows;
int iNumDstCols;
BYTE * pbSrcScanLine;
BYTE * pbDstScanLine;
WORD * pwDstPixel;
// Caller assures a well-ordered, non-empty rect
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -