📄 surf.cpp
字号:
m_pDUPnRegs[0][DU_PnDSA2R] = NCG_FBBASE + dwOffset;
m_pVisiblePlane[nPlane] = (NCGSurf*)pSurf;
DEBUGMSG(GPE_ZONE_FLIP,
// RETAILMSG(1,
(TEXT("SetVisibleSurface: ")
TEXT("Current offset of visible surface = %08x\r\n"),
dwOffset));
}
void NCG::SetVisibleSurface( GPESurf *pSurf, BOOL bWaitForVBlank )
{
SetVisibleSurface(pSurf);
if (bWaitForVBlank)
WaitForVBlank();
}
BOOL NCG::SearchSurface(
LPDDRAWI_DDRAWSURFACE_LCL lpDDSurface,
DWORD nSearchOffset)
{
/* This method searches surfaces that has specified start offset */
/* from attached surface list of surface structure, and returns */
/* whether the surface is found or not. */
LPDDRAWI_DDRAWSURFACE_LCL lpCurrent;
DDGPESurf* pSurf;
DWORD nOffset;
BOOL bResult = FALSE;
// Check current surface structure
if (lpDDSurface == NULL)
return FALSE; // NULL pointer passed.
pSurf = DDGPESurf::GetDDGPESurf(lpDDSurface);
nOffset = pSurf->OffsetInVideoMemory();
if (nOffset == nSearchOffset)
return TRUE;
lpCurrent = lpDDSurface;
while (lpCurrent != NULL) {
if (lpCurrent->lpAttachList == NULL)
break; // List termination found.
if (lpCurrent->lpAttachList->lpAttached == NULL) { // Broken struct?
RETAILMSG(1, (TEXT("SearchSurface: Empty element in list.\r\n")));
break;
}
lpCurrent = lpCurrent->lpAttachList->lpAttached;
if (lpCurrent == lpDDSurface)
break; // List circulated (normal end).
pSurf = DDGPESurf::GetDDGPESurf(lpCurrent);
nOffset = pSurf->OffsetInVideoMemory();
if (nOffset == nSearchOffset)
bResult = TRUE;
}
return bResult;
}
DWORD NCG::Blt(LPDDHAL_BLTDATA pd)
{
/* prototype is copied from S3Virge DDGPE driver. */
/* Copyright (c) 1995-1998 Microsoft Corporation */
/*
typedef struct _DDHAL_BLTDATA
{
LPDDRAWI_DIRECTDRAW_GBL lpDD; // driver struct
LPDDRAWI_DDRAWSURFACE_LCL lpDDDestSurface;// dest surface
RECTL rDest; // dest rect
LPDDRAWI_DDRAWSURFACE_LCL lpDDSrcSurface; // src surface
RECTL rSrc; // src rect
DWORD dwFlags; // blt flags
DWORD dwROPFlags; // ROP flags
// (valid for ROPS only)
DDBLTFX bltFX; // blt FX
HRESULT ddRVal; // return value
LPDDHALSURFCB_BLT Blt; // PRIVATE: ptr to callback
} DDHAL_BLTDATA;
*/
DDGPESurf* pDstSurf = DDGPESurf::GetDDGPESurf(pd->lpDDDestSurface);
DDGPESurf* pSrcSurf = NULL;
DDGPESurf* pPattern = NULL;
RECT *prclDst = (RECT*)&(pd->rDest);
RECT *prclSrc = (RECT*)&(pd->rSrc);
DWORD solidColor = 0;
DWORD bltFlags = (pd->dwFlags & DDBLT_WAIT) ? 0x100 : 0;
DWORD rop4;
if (pd->lpDDSrcSurface) {
pSrcSurf = DDGPESurf::GetDDGPESurf(pd->lpDDSrcSurface);
}
else {
pSrcSurf = NULL;
}
if (prclSrc)
DEBUGMSG(GPE_ZONE_BLT_HI,
(TEXT("Blt: Src rect is (%d,%d) - (%d,%d).\r\n"),
prclSrc->left, prclSrc->top, prclSrc->right, prclSrc->bottom));
else
DEBUGMSG(GPE_ZONE_BLT_HI,
(TEXT("Blt: Src rect is NULL.\r\n")));
if (prclDst)
DEBUGMSG(GPE_ZONE_BLT_HI,
(TEXT("Blt: Dst rect is (%d,%d) - (%d,%d).\r\n"),
prclDst->left, prclDst->top, prclDst->right, prclDst->bottom));
else
DEBUGMSG(GPE_ZONE_BLT_HI,
(TEXT("Blt: Dst rect is NULL.\r\n")));
if (pd->dwFlags & DDBLT_COLORFILL) {
// FILL BLT
DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("FILL BLT\n")));
rop4 = 0xF0F0; // PATCOPY
solidColor = pd->bltFX.dwFillColor;
}
else if ((pd->dwFlags & DDBLT_ROP) && (pd->bltFX.dwROP == BLACKNESS)) {
// FILL BLT
DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("FILL BLT\n")));
rop4 = 0x0000;
if (pDstSurf->Bpp() == 8) {
solidColor = 0;
}
else {
solidColor = 0x0000;
}
pSrcSurf = NULL;
}
else if ((pd->dwFlags & DDBLT_ROP) && (pd->bltFX.dwROP == WHITENESS)) {
// FILL BLT
DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("FILL BLT\n")));
rop4 = 0xFFFF;
if (pDstSurf->Bpp() == 8) {
solidColor = 255;
}
else {
solidColor = 0xFFFF;
}
pSrcSurf = NULL;
}
else if ((pd->dwFlags & DDBLT_ROP) && (pd->bltFX.dwROP == PATCOPY)) {
// PAT BLT
DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("PAT BLT\n")));
rop4 = 0xF0F0; // PATCOPY;
solidColor = 0xFFFFFFFF; // i.e. not a solid color blt
pPattern = DDGPESurf::GetDDGPESurf(
(LPDDRAWI_DDRAWSURFACE_LCL)(pd->bltFX.lpDDSPattern));
}
else if (pd->dwFlags & (DDBLT_KEYSRCOVERRIDE | DDBLT_KEYSRC)) {
// TRANSPARENT BLT
DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("TRANSPARENT BLT\n")));
if (pd->dwFlags & DDBLT_KEYSRCOVERRIDE) {
DEBUGMSG(GPE_ZONE_BLT_LO,
(TEXT("DDBLT_KEYSRCOVERRIDE, transparent = 0x%x\n"),
pd->bltFX.ddckSrcColorkey.dwColorSpaceLowValue));
solidColor = pd->bltFX.ddckSrcColorkey.dwColorSpaceLowValue;
}
else {
DEBUGMSG(GPE_ZONE_BLT_LO,
(TEXT("DDBLT_KEYSRC, transparent = 0x%x\n"),
pd->lpDDSrcSurface->ddckCKSrcBlt.dwColorSpaceLowValue));
solidColor = pd->lpDDSrcSurface->ddckCKSrcBlt.dwColorSpaceLowValue;
}
rop4 = 0xCCCC; // SRCCOPY
bltFlags |= BLT_TRANSPARENT;
// BLT_STRETCH?
if ((prclDst != NULL) && (prclSrc != NULL)) {
if (((prclDst->bottom - prclDst->top) !=
(prclSrc->bottom - prclSrc->top)) ||
((prclDst->right - prclDst->left) !=
(prclSrc->right - prclSrc->left) )) {
bltFlags |= BLT_STRETCH;
}
}
}
else {
// SIMPLE BLT
DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("SIMPLE BLT\n")));
// BLT_STRETCH?
if ((prclDst != NULL) && (prclSrc != NULL)) {
if (((prclDst->bottom - prclDst->top) !=
(prclSrc->bottom - prclSrc->top)) ||
((prclDst->right - prclDst->left) !=
(prclSrc->right - prclSrc->left) )) {
bltFlags |= BLT_STRETCH;
}
}
rop4 = 0xCCCC; // SRCCOPY
}
if (pd->lpDDSrcSurface) {
pSrcSurf = DDGPESurf::GetDDGPESurf(pd->lpDDSrcSurface);
}
else {
pSrcSurf = NULL;
}
pd->ddRVal = BltExpanded(
pDstSurf,
pSrcSurf,
pPattern,
prclDst,
prclSrc,
solidColor,
bltFlags,
rop4 );
return DDHAL_DRIVER_HANDLED;
}
DWORD NCG::GetBltStatus(
LPDDRAWI_DDRAWSURFACE_LCL lpDDSurface,
DWORD dwFlags )
{
DWORD dwRet;
NCGSurf *pSurf;
if (dwFlags & DDGBS_CANBLT) {
dwRet = DD_OK;
}
else if (dwFlags & DDGBS_ISBLTDONE) {
pSurf = (NCGSurf*)DDGPESurf::GetDDGPESurf(lpDDSurface);
if (pSurf->GetDstCount() == 0) {
// There are no unfinished blt request on this surface.
dwRet = DD_OK;
}
else {
// Some blt requests are still not finished.
dwRet = (DWORD)DDERR_WASSTILLDRAWING;
}
}
else
dwRet = DD_OK; // No function specified.
return dwRet;
}
DWORD NCG::Flip( LPDDHAL_FLIPDATA pd )
{
/*
typedef struct _DDHAL_FLIPDATA
{
LPDDRAWI_DIRECTDRAW_GBL lpDD; // driver struct
LPDDRAWI_DDRAWSURFACE_LCL lpSurfCurr; // current surface
LPDDRAWI_DDRAWSURFACE_LCL lpSurfTarg; // target surface (to flip to)
DWORD dwFlags; // flags
HRESULT ddRVal; // return value
LPDDHALSURFCB_FLIP Flip; // PRIVATE: ptr to callback
} DDHAL_FLIPDATA;
*/
NCGSurf* pCurr = (NCGSurf*)(DDGPESurf::GetDDGPESurf(pd->lpSurfCurr));
NCGSurf* pTarg = (NCGSurf*)(DDGPESurf::GetDDGPESurf(pd->lpSurfTarg));
DWORD dwCurrOffset = pCurr->OffsetInVideoMemory();
DWORD dwTargOffset = pTarg->OffsetInVideoMemory();
BOOL bRet;
int nPlane = 0;
// check whether VisiblePlane[nPlane]
bRet = m_pVisiblePlane[nPlane]
? SearchSurface(pd->lpSurfCurr, m_pVisiblePlane[nPlane]->OffsetInVideoMemory())
: FALSE;
if (bRet) { // flip
// set display start address
m_pDUPnRegs[0][DU_PnDSA0R] = NCG_FBBASE + dwTargOffset;
m_pDUPnRegs[0][DU_PnDSA1R] = NCG_FBBASE + dwTargOffset;
m_pDUPnRegs[0][DU_PnDSA2R] = NCG_FBBASE + dwTargOffset;
m_pVisiblePlane[nPlane] = pTarg;
m_bFlippingPlane[nPlane] = TRUE;
DEBUGMSG(GPE_ZONE_FLIP,
// RETAILMSG(1,
(TEXT("Flip: Plane[%d] offset is changed from %08x to %08x.\r\n"),
nPlane, dwCurrOffset, dwTargOffset));
if(!(pd->dwFlags & DDFLIP_NOVSYNC))
WaitForVBlank();
pd->ddRVal = DD_OK;
return DDHAL_DRIVER_HANDLED;
}
// invisible surface, need not check
pd->ddRVal = DD_OK;
return DDHAL_DRIVER_HANDLED;
}
DWORD NCG::GetFlipStatus( LPDDHAL_GETFLIPSTATUSDATA pd )
{
/*
typedef struct _DDHAL_GETFLIPSTATUSDATA
{
LPDDRAWI_DIRECTDRAW_GBL lpDD; // driver struct
LPDDRAWI_DDRAWSURFACE_LCL lpDDSurface; // surface struct
DWORD dwFlags; // flags
HRESULT ddRVal; // return value
LPDDHALSURFCB_GETFLIPSTATUS GetFlipStatus; // PRIVATE: ptr to callback
} DDHAL_GETFLIPSTATUSDATA;
*/
BOOL bRet;
int nPlane = 0;
if (!(pd->lpDDSurface->ddsCaps.dwCaps & DDSCAPS_COMPLEX) ||
!(pd->lpDDSurface->ddsCaps.dwCaps & DDSCAPS_FLIP)) {
pd->ddRVal = DDERR_NOTFLIPPABLE;
return DDHAL_DRIVER_HANDLED;
}
// check whether VisiblePlane[nPlane]
bRet = m_pVisiblePlane[nPlane]
? SearchSurface(pd->lpDDSurface, m_pVisiblePlane[nPlane]->OffsetInVideoMemory())
: FALSE;
if (bRet) {
if (pd->dwFlags == DDGFS_CANFLIP) {
pd->ddRVal = DD_OK;
}
else if (pd->dwFlags == DDGFS_ISFLIPDONE) {
if (m_bFlippingPlane[nPlane] != FALSE) {
/* Previous flip is still unprocessed. */
/* This flag works not exactly. */
pd->ddRVal = DDERR_WASSTILLDRAWING;
}
else
pd->ddRVal = DD_OK;
}
else
pd->ddRVal = DDERR_INVALIDPARAMS; // Invalid function.
return DDHAL_DRIVER_HANDLED;
}
pd->ddRVal = DD_OK; // not visible surface
return DDHAL_DRIVER_HANDLED;
}
DWORD NCG::GetFreeVideoMemory()
{
return m_pVideoMemoryHeap ? m_pVideoMemoryHeap->Available() : 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -