📄 halsurf.cpp
字号:
if (SUCCEEDED(sc))
{
sc = g_pGPE->GetModeInfo(&modeInfo, dwModeID);
if (SUCCEEDED(sc))
{
GPEModeEx modeInfoEx; // restrict the scope of this, since we can't rely on it being valid for all drivers
sc = g_pGPE->GetModeInfoEx(&modeInfoEx, dwModeID);
if (FAILED(sc))
{
// function probably wasn't supported by the driver
pixelFormat = EGPEFormatToEDDGPEPixelFormat[modeInfo.format];
sc = S_OK;
}
else
{
pixelFormat = modeInfoEx.ePixelFormat;
}
}
}
if (FAILED(sc))
{
RETAILMSG(1, (TEXT("DDGPECreateSurface- Could not find a good mode: DetectMode and GetModeInfo failed. 0x%x\r\n"), sc ));
}
else
{
BOOL bSplitToSame = FALSE;
if (HalGDIHasSplitFromDDraw())
{
// for now, don't worry about the case where the rect is invalid.
// let it just fall through.
if ( (g_pDDrawPrimarySurface->PixelFormat() == pixelFormat) &&
(g_pDDrawPrimarySurface->Format() == modeInfo.format) &&
(g_pDDrawPrimarySurface->Width() == modeInfo.width) &&
(g_pDDrawPrimarySurface->Height() == modeInfo.height) &&
(1) )
{
bSplitToSame = TRUE;
}
}
// don't need to split if the ddraw surface is already split, and
// the mode requested is the same as the current ddraw primary surface's mode
if (bSplitToSame)
{
pDDGPESurf = g_pDDrawPrimarySurface;
RETAILMSG(1, (TEXT("Surface is already split in requested mode!\r\n") ));
}
else
{
unsigned long dwOffsetInVideoMemory = 0L;
// don't deallocate our existing surface yet, because the allocate
// might fail
sc = g_pGPE->AllocVideoSurface(
&pDDGPESurf,
modeInfo.width,
modeInfo.height,
modeInfo.format,
pixelFormat,
&dwOffsetInVideoMemory );
RETAILMSG(
1,
(TEXT("Created primary surface at: 0x%x (%d)\r\n"),
dwOffsetInVideoMemory,
dwOffsetInVideoMemory
));
}
}
if (FAILED(sc))
{
RETAILMSG(1, (TEXT("DDGPECreateSurface-AllocSurface failed 0x%x\r\n"), sc ));
}
else
{
if (pDDGPESurf != NULL)
{
g_pDDrawPrimarySurface = pDDGPESurf; //(DDGPESurf*)g_pGPE->PrimarySurface();
RETAILMSG(1, (TEXT("DDGPECreateSurface-AllocSurface successful 0x%x\r\n"), g_pDDrawPrimarySurface->OffsetInVideoMemory() ));
}
else
{
RETAILMSG(1, (TEXT("DDGPECreateSurface-AllocSurface returned NULL 0x%x\r\n"), sc ));
}
}
if (dwModeID != (DWORD)-1L)
{
if (dwModeID != (DWORD)g_pGPE->GetPhysicalModeId())
{
RETAILMSG(1, (TEXT("Setting DDraw Primary mode to id %d\r\n"), dwModeID));
sc = g_pGPE->SetMode(dwModeID, NULL, FALSE); // don't change GDI mode (just HW)
if (FAILED(sc))
{
RETAILMSG(1, (TEXT("Failed to set the physical mode 0x%08x\r\n"), sc));
}
RETAILMSG(1, (TEXT("Calling UpdateHALInit\r\n") ));
UpdateHALInit(pd->lpDD, dwModeID);
RETAILMSG(1, (TEXT("Done calling UpdateHALInit\r\n") ));
/*
// This is handled by UpdateHALInit, so we shouldn't have to call this any more
pd->lpDD->vmiData.ddpfDisplay.dwFlags = DDPF_RGB; // NOTENOTE this must be updated when splitting or changing display mode
pd->lpDD->vmiData.ddpfDisplay.dwFlags |= (pDDGPESurf->HasAlpha()) ? DDPF_ALPHAPIXELS : 0;
pd->lpDD->vmiData.ddpfDisplay.dwRBitMask = pd->lpDD->lpModeInfo[dwModeID].dwRBitMask;
pd->lpDD->vmiData.ddpfDisplay.dwGBitMask = pd->lpDD->lpModeInfo[dwModeID].dwGBitMask;
pd->lpDD->vmiData.ddpfDisplay.dwBBitMask = pd->lpDD->lpModeInfo[dwModeID].dwBBitMask;
pd->lpDD->vmiData.ddpfDisplay.dwRGBAlphaBitMask = pd->lpDD->lpModeInfo[dwModeID].dwAlphaBitMask;
pd->lpDD->vmiData.ddpfDisplay.dwRGBBitCount = pd->lpDD->lpModeInfo[dwModeID].dwBPP;
*/
}
else
{
RETAILMSG(1, (TEXT("Current mode is same as requested split mode (%d)\r\n"), dwModeID));
}
}
PREFAST_ASSERT(g_pDDrawPrimarySurface);
//RETAILMSG(HAL_ZONE_INFO, (TEXT("Setting up lpGbl\r\n") ));
pSurf->lpGbl->fpVidMem = (unsigned long)(g_pVideoMemory) + g_pDDrawPrimarySurface->OffsetInVideoMemory();
pSurf->lpGbl->lPitch = g_pDDrawPrimarySurface->Stride();
// BUGBUG
// This will cause a problem if more than one process creates a primary surface
// but I don't think ddraw lets that happen.
//RETAILMSG(HAL_ZONE_INFO, (TEXT("Setting DDGPESurf for new ddraw primary surface\r\n") ));
g_pDDrawPrimarySurface->SetDDGPESurf(pSurf->lpGbl);
// show the new primary surface // don't wait for vblank
//RETAILMSG(HAL_ZONE_INFO, (TEXT("Flipping to the new primary surface\r\n") ));
g_pGPE->SetVisibleSurface(g_pDDrawPrimarySurface, NULL, FALSE);
//RETAILMSG(HAL_ZONE_INFO, (TEXT("Done flipping to the new primary surface\r\n") ));
// OLDOLD
// last but not least, change the video mode
// GPE should NOT know about this change
// DDGPE must keep track of the OLD mode so it knows what to restore it as when
// FlipToGDISurface is called.
// TODO: Will there be a case where the caller wants to flip the GDI to front, then flip the
// ddraw primary to front? Mode switching will need to be done there.
// NOTE: This is done above, now.
}
else // not split primary
{
// We could get here in one of two cases:
// 1. The program is creating ddraw and just wants to create a primary surface
// 2. The ddraw primary is split and the user is getting the GDI ddraw surface
// The GDI primary surface should already exist, so we don't need to
// do any allocation for it
DDGPESurf* pPrimary = (DDGPESurf*)g_pGPE->PrimarySurface();
//PrimarySurface() should always return a valid surface
//ASSERT(pPrimary != NULL);
if (pPrimary != NULL)
{
//RETAILMSG(HAL_ZONE_INFO, (TEXT("Setting up lpGbl\r\n") ));
pSurf->lpGbl->fpVidMem = (unsigned long)(g_pVideoMemory) + pPrimary->OffsetInVideoMemory();
pSurf->lpGbl->lPitch = pPrimary->Stride();
// BUGBUG
// This will cause a problem if more than one process creates a primary surface
// but I don't think ddraw lets that happen.
//RETAILMSG(HAL_ZONE_INFO, (TEXT("Setting DDGPESurf for new ddraw primary surface\r\n") ));
//
// Note: pSurf is stored in lcl so we need to attach it to the surface
pPrimary->SetDDGPESurf(pSurf->lpGbl);
// No change is required to g_pDDrawPrimarySurface, because it is by default
// the primary surface.
// If it's not the primary surface then it's been split and we definitely
// don't want to change the ddraw primary
/*
// This should already be the case in an un-split world
if (!DDGPEGDIHasSplitFromDDraw())
{
g_pDDrawPrimarySurface = pPrimary;
}
*/
// the ddraw primary should already be visible if necessary (it's the GDI surface)
//g_pGPE->SetVisibleSurface(pPrimary, NULL, FALSE);
}
}
RETAILMSG(
1 ,
(TEXT("Create %s Primary Surface! (&GPESurf = 0x%08x, fpvidmem=0x%08x)\r\n"),
(((pSurf->lpSurfMore->ddsCapsEx.dwCaps4 & DDSCAPS4_NONGDIPRIMARY) == DDSCAPS4_NONGDIPRIMARY)
? L"SPLIT" : L""),
(unsigned long)g_pDDrawPrimarySurface,
pSurf->lpGbl->fpVidMem
));
}
else
{
unsigned long offset;
if( !(pd->lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY ) )
{
sc = g_pGPE->AllocVideoSurface(
pSurf->lpGbl,
nWidth,
nHeight,
format,
pixelFormat,//EGPEFormatToEDDGPEPixelFormat[format],
&offset );
if( SUCCEEDED(sc) )
{
DDGPESurf* pGPESurf = DDGPESurf::GetDDGPESurf(pSurf);
pSurf->lpGbl->fpVidMem = (unsigned long)(g_pVideoMemory + offset);
pSurf->lpGbl->lPitch = pGPESurf->Stride();
pd->lpDDSurfaceDesc->ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
RETAILMSG(1, (TEXT("Created a surface at: 0x%x (%d)\r\n"), offset, offset));
}
}
if( ( ( sc == E_OUTOFMEMORY )
&& ( ! ( pd->lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY ) )
&& ( ! ( pd->lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER ) )
&& ( ! ( pd->lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_BACKBUFFER ) )
&& ( ! ( pd->lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_COMPLEX ) )
)
|| (pd->lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY ) )
{
// Try allocating in system memory
//DWORD nPitch;
//nPitch = ( nWidth * nBPP ) >>3;
//nPitch = ( nPitch + 3 ) & ~3;
DWORD nBPP = EGPEFormatToBpp[format];
// don't LocalAlloc here any more
//pSurf->lpGbl->lPitch = ( nWidth * nBPP / 8 + 3 ) & 0xFFFFFFFC;
//pSurf->lpGbl->fpVidMem = (unsigned long)LocalAlloc( LMEM_FIXED, pSurf->lpGbl->lPitch * nHeight );
//if( !pSurf->lpGbl->fpVidMem )
//{
// pd->ddRVal = DDERR_OUTOFMEMORY;
// RETAILMSG(GPE_ZONE_ERROR,(TEXT("Failed to create surface, sc=0x%08x\r\n"),sc));
// return DDHAL_DRIVER_HANDLED;
//}
if (pd->lpDDSurfaceDesc->dwFlags & DDSD_LPSURFACE)
{
sc = g_pGPE->WrapSurface(
pSurf->lpGbl,
nWidth,
nHeight,
format,
pixelFormat,//EGPEFormatToEDDGPEPixelFormat[format],
(unsigned char *)pd->lpDDSurfaceDesc->lpSurface,
pd->lpDDSurfaceDesc->lPitch
);
}
else
{
sc = g_pGPE->WrapSurface(
pSurf->lpGbl,
nWidth,
nHeight,
format,
pixelFormat,//EGPEFormatToEDDGPEPixelFormat[format],
//(unsigned char *)pSurf->lpGbl->fpVidMem,
pSurf->lpGbl->lPitch,
0);
}
if( SUCCEEDED(sc) )
{
RETAILMSG(1, (TEXT("DDGPEHAL: DDGPE has allocated system memory surface for me at 0x%08x\r\n"), pSurf->lpGbl->fpVidMem));
pSurf->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
}
}
else if ( sc == E_OUTOFMEMORY )
{
sc = DDERR_OUTOFVIDEOMEMORY;
RETAILMSG(1,(TEXT("Not attempting system memory allocation!")));
}
if( FAILED( sc ) )
{
pd->ddRVal = sc;
RETAILMSG(1,(TEXT("Failed to create surface, sc=0x%08x\r\n"),sc));
return DDHAL_DRIVER_HANDLED;
}
pd->lpDDSurfaceDesc->lPitch = pSurf->lpGbl->lPitch;
RETAILMSG(1,(TEXT("Create Non-Primary Surface! (&GPESurf = 0x%08x, fpvidmem=0x%08x)\r\n"),
DDGPESurf::GetDDGPESurf(pSurf),
pSurf->lpGbl->fpVidMem));
}
// any operations that should be performed on all created surfaces
if (pSurf != NULL)
{
DDGPESurf* pDDGPESurf = NULL;
pDDGPESurf = DDGPESurf::GetDDGPESurf(pSurf);
if (pDDGPESurf != NULL)
{
pDDGPESurf->SetColorKeyLow(pd->lpDDSurfaceDesc->ddckCKDestBlt.dwColorSpaceLowValue);
pDDGPESurf->SetColorKeyHigh(pd->lpDDSurfaceDesc->ddckCKDestBlt.dwColorSpaceHighValue);
}
}
} // end of for loop
pd->ddRVal = DD_OK;
DEBUGLEAVE( HalCreateSurface );
return DDHAL_DRIVER_HANDLED;
}
//////////////////////////// DDHAL_DDEXEBUFCALLBACKS ////////////////////////////
DWORD WINAPI HalCanCreateSurface( LPDDHAL_CANCREATESURFACEDATA pd )
{
DEBUGENTER( HalCanCreateSurface );
/*
typedef struct _DDHAL_CANCREATESURFACEDATA
{
LPDDRAWI_DIRECTDRAW_GBL lpDD; // driver struct
LPDDSURFACEDESC lpDDSurfaceDesc; // description of surface being created
DWORD bIsDifferentPixelFormat;
// pixel format differs from primary surface
HRESULT ddRVal; // return value
LPDDHAL_CANCREATESURFACE CanCreateSurface;
// PRIVATE: ptr to callback
} DDHAL_CANCREATESURFACEDATA;
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -