📄 sa2video.cpp
字号:
// 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 >> 3);
iSrcBitOffset = prcSrc->left & 0x07;
pbDstScanLine = pDibBitsDst + prcDst->top * iDstScanStride + prcDst->left * 2;
pwDstPixel = (WORD *)pbDstScanLine;
EmulatedBltText16ASM(pbSrcScanLine,pwDstPixel, wOnColor, iNumDstCols, iNumDstRows, iSrcScanStride, iDstScanStride, iSrcBitOffset);
return S_OK;
}
SCODE
SA2Video::Line(
GPELineParms * pLineParms,
EGPEPhase phase
)
{
if(phase == gpeSingle || phase == gpePrepare)
{
if(pLineParms->pDst != m_pPrimarySurface)
{
pLineParms->pLine = EmulatedLine;
}
else
{
pLineParms->pLine = (SCODE (GPE::*)(struct GPELineParms *))WrappedEmulatedLine;
}
}
return S_OK;
}
#undef SWAP
#define SWAP(type,a,b) { type tmp; tmp=a; a=b; b=tmp; }
SCODE
SA2Video::WrappedEmulatedBlt(
GPEBltParms * pParms
)
{
SCODE code;
RECT bounds;
// This function should only be called when using a virtual primary (ie.
// bDoRotation is TRUE).
ASSERT(bDoRotation);
if ((pParms->pDst == m_pPrimarySurface && m_iRotate) || (pParms->pSrc == m_pPrimarySurface && m_iRotate))
{
code = EmulatedBltRotate(pParms);
}
else
{
if ( !( (pParms->bltFlags & (BLT_ALPHABLEND | BLT_TRANSPARENT | BLT_STRETCH)) || (pParms->pLookup) || (pParms->pConvert) )
&& pParms->pDst->Format() == gpe16Bpp )
{
if ( pParms->rop4 == 0xcccc )
{
if ( EGPEFormatToBpp[pParms->pSrc->Format()] == 16 )
{
code = EmulatedBltSrcCopy1616_Eml(pParms);
goto contd;
}
}
else if ( pParms->rop4 == 0xf0f0 )
{
if (pParms->solidColor != -1)
{ // must be a solid colored brush
code = EmulatedBltFill16_Eml(pParms);
goto contd;
}
}
else if ( pParms->rop4 == 0xaaf0 )
{
if (pParms->solidColor != -1)
{
if (pParms->pMask->Format() == gpe1Bpp)
{
code = EmulatedBltText16_Eml(pParms);
goto contd;
}
else if (pParms->pMask->Format() == gpe4Bpp)
{
code = EmulatedBltAlphaText16_Eml(pParms);
goto contd;
}
}
}
}
code = EmulatedBlt(pParms);
}
contd:
if (bDoRotation)
{
bounds.left = pParms->prclDst->left;
bounds.top = pParms->prclDst->top;
bounds.right = pParms->prclDst->right;
bounds.bottom = pParms->prclDst->bottom;
if(bounds.left > bounds.right)
{
SWAP(int,bounds.left,bounds.right)
}
if( bounds.top > bounds.bottom)
{
SWAP(int,bounds.top,bounds.bottom)
}
if (bounds.top == bounds.bottom-1)
{
if ( !( (pParms->bltFlags & (BLT_ALPHABLEND | BLT_TRANSPARENT | BLT_STRETCH)) || (pParms->pLookup) || (pParms->pConvert) ) )
{
if ( pParms->rop4 == 0xf0f0 )
{
if ( EGPEFormatToBpp[pParms->pDst->Format()] == 16 )
{
if (pParms->solidColor != -1)
{ // must be a solid colored brush
if (!gDrawCursorFlag)
{
DispDrvrDirtyRectDump2((LPRECT)&bounds,pParms->solidColor);
return S_OK;
}
}
}
}
}
}
if ( !( (pParms->bltFlags & (BLT_ALPHABLEND | BLT_TRANSPARENT | BLT_STRETCH)) || (pParms->pLookup) || (pParms->pConvert) ) )
{
if ( pParms->rop4 == 0xf0f0 )
{
if ( EGPEFormatToBpp[pParms->pDst->Format()] == 16 )
{
if (pParms->solidColor != -1)
{ // must be a solid colored brush
DispDrvrDirtyRectDump_rectfill((LPRECT)&bounds,pParms->solidColor);
return S_OK;
}
}
}
}
if(FAILED(code))
{
return code;
}
DispDrvrDirtyRectDump((LPRECT)&bounds);
}
return code;
}
SCODE
SA2Video::BltPrepare(
GPEBltParms * pParms
)
{
DEBUGMSG(GPE_ZONE_LINE,(TEXT("SA2Video::BltPrepare\r\n")));
RECTL rectl;
pParms->pBlt = EmulatedBlt;
// Check to see if the software cursor should be disabled.
if (!bDoRotation)
{
if (pParms->pDst == m_pPrimarySurface) // only care if dest is main display surface
{
if (m_CursorVisible && !m_CursorDisabled)
{
if (pParms->prclDst != NULL) // make sure there is a valid prclDst
{
rectl = *pParms->prclDst; // if so, use it
// There is no guarantee of a well ordered rect in pParms
// due to flipping and mirroring.
if(rectl.top > rectl.bottom)
{
int iSwapTmp = rectl.top;
rectl.top = rectl.bottom;
rectl.bottom = iSwapTmp;
}
if(rectl.left > rectl.right)
{
int iSwapTmp = rectl.left;
rectl.left = rectl.right;
rectl.right = iSwapTmp;
}
}
else
{
rectl = m_CursorRect; // if not, use the Cursor rect - this forces the cursor to be turned off in this case.
}
if (m_CursorRect.top <= rectl.bottom && m_CursorRect.bottom >= rectl.top &&
m_CursorRect.left <= rectl.right && m_CursorRect.right >= rectl.left)
{
CursorOff();
m_CursorForcedOff = TRUE;
}
}
}
// check for source overlap with cursor and turn off cursor if overlaps
if (pParms->pSrc == m_pPrimarySurface) // only care if source is main display surface
{
if (m_CursorVisible && !m_CursorDisabled)
{
if (pParms->prclSrc != NULL) // make sure there is a valid prclSrc
{
rectl = *pParms->prclSrc; // if so, use it
}
else
{
rectl = m_CursorRect; // if not, use the Cursor rect - this forces the cursor to be turned off in this case.
}
if (m_CursorRect.top < rectl.bottom && m_CursorRect.bottom > rectl.top &&
m_CursorRect.left < rectl.right && m_CursorRect.right > rectl.left)
{
CursorOff();
m_CursorForcedOff = TRUE;
}
}
}
}
if ((pParms->pDst == m_pPrimarySurface && m_iRotate) || (pParms->pSrc == m_pPrimarySurface && m_iRotate))
{
pParms->pBlt = EmulatedBltRotate;
}
if (bDoRotation && pParms->pDst == m_pPrimarySurface)
{
pParms->pBlt = (SCODE (GPE::*)(GPEBltParms *))WrappedEmulatedBlt;
}
return S_OK;
}
// This function would be used to undo the setting of clip registers etc
SCODE
SA2Video::BltComplete(
GPEBltParms * pParms
)
{
if (!bDoRotation)
{
if (m_CursorForcedOff)
{
m_CursorForcedOff = FALSE;
CursorOn();
}
}
return S_OK;
}
int
SA2Video::InVBlank()
{
static BOOL value = FALSE;
DEBUGMSG (GPE_ZONE_INIT, (TEXT("SA2Video::InVBlank\r\n")));
value = !value;
return value;
}
SCODE
SA2Video::SetPalette(
const PALETTEENTRY * source,
unsigned short firstEntry,
unsigned short numEntries
)
{
if (bpp == 8)
{
if (firstEntry < 0 || firstEntry + numEntries > 256)
{
return E_INVALIDARG;
}
DispDrvrSetPalette(source,firstEntry,numEntries);
}
return S_OK;
}
ULONG *
APIENTRY
DrvGetMasks(
DHPDEV dhpdev
)
{
return BitMasks;
}
ULONG
SA2Video::DrvEscape(
SURFOBJ * pso,
ULONG iEsc,
ULONG cjIn,
PVOID pvIn,
ULONG cjOut,
PVOID pvOut
)
{
int RetVal = 0; // default return value: "not supported"
DWORD EscapeFunction;
GXDeviceInfo *pgxoi;
switch (iEsc)
{
case QUERYESCSUPPORT:
EscapeFunction = *(DWORD *)pvIn;
if ((EscapeFunction == GETVFRAMEPHYSICAL) ||
(EscapeFunction == GETVFRAMELEN) ||
(EscapeFunction == GETPALETTERAMPHYSICAL) ||
(EscapeFunction == VERTICALBLANKINTERRUPT) ||
(EscapeFunction == SCROLL) ||
(EscapeFunction == OVERLAY2_ENABLE) ||
(EscapeFunction == OVERLAY2_DISABLE) ||
(EscapeFunction == OVERLAY1_ENABLE) ||
(EscapeFunction == OVERLAY1_DISABLE) ||
(EscapeFunction == GET_OVERLAY1_ADDRESS) ||
(EscapeFunction == GET_OVERLAY2_ADDRESS) ||
(EscapeFunction == DRVESC_GETSCREENROTATION) ||
(EscapeFunction == DRVESC_SETSCREENROTATION) ||
(EscapeFunction == GETGXINFO))
{
RetVal = 1;
}
break;
// Provide the mapped virtual address of the frame buffer ram
// for direct frame buffer manipulation.
case GETVFRAMEPHYSICAL:
if (cjIn < NUM_FRAME_BUFFERS)
{
// This works as long as the frame buffers are in a contiguous region.
*(DWORD *)pvOut = (ULONG)FRAME_BUFFER_0_BASE_VIRTUAL + cjIn * (DispDrvr_cdwStride * DispDrvr_cyScreen);
RetVal = 1;
} else
{
*(DWORD *)pvOut = NULL;
}
break;
// Provide the length of the frame buffer in bytes
case GETVFRAMELEN:
*(DWORD *)pvOut = (ULONG)DispDrvr_cdwStride * DispDrvr_cyScreen;
RetVal = 1;
break;
// Provide the mapped virtual address of the palette ram
// for direct palette buffer manipulation.
case GETPALETTERAMPHYSICAL:
*(DWORD *)pvOut = (ULONG)PALETTE_BUFFER_BASE_VIRTUAL;
RetVal = 1;
break;
case VERTICALBLANKINTERRUPT:
RetVal = 1;
break;
case SCROLL:
ScrollBuffer(cjIn);
break;
case OVERLAY2_ENABLE:
Overlay2_Enable((P_XLLP_OVERLAY_T)pvIn);
RetVal = 1;
break;
case OVERLAY2_DISABLE:
Overlay2_Disable((P_XLLP_OVERLAY_T)pvIn);
RetVal = 1;
break;
case GET_OVERLAY1_ADDRESS:
RetVal = 1;
break;
case GET_OVERLAY2_ADDRESS:
RetVal = 1;
// Check the DMA length to see if everything will fit into SRAM.
// If it does, then locate the descriptors and the frame buffers there.
// Otherwise, locate it in external memory.
Overlay2_DMA_Length((P_XLLP_OVERLAY_T)pvIn);
XllpLCD._OVERLAY2_Y_CHANNEL_BASE_PHYSICAL = OVERLAY2_PHYSICAL_BASE_ADDRESS;
XllpLCD._OVERLAY2_Cb_CHANNEL_BASE_PHYSICAL = OVERLAY2_PHYSICAL_BASE_ADDRESS + ((P_XLLP_OVERLAY_T)pvIn)->ch2_size;
XllpLCD._OVERLAY2_Cr_CHANNEL_BASE_PHYSICAL = OVERLAY2_PHYSICAL_BASE_ADDRESS + ((P_XLLP_OVERLAY_T)pvIn)->ch2_size + ((P_XLLP_OVERLAY_T)pvIn)->ch3_size;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -