📄 ddhsurf.cpp
字号:
pd->ddRVal = DD_OK;
return DDHAL_DRIVER_HANDLED;
}
else if (! ((pd->lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) == DDSD_PIXELFORMAT) )
{
// can create surfaces of same type as current primary surface
pd->ddRVal = DD_OK;
return DDHAL_DRIVER_HANDLED;
}
else // trying to create a different surface type
{
// DDGPEGetPixelFormatFromSurfaceDesc calls DDGPE::DetectPixelFormat
// for now, we will assume that if the surface type can be detected, it can
// be created
// BUGBUG
// no checking for:
// overlays
// video/system memory
// memory availability
// is this necessary based on the spec?
pd->ddRVal = DD_OK;
return DDHAL_DRIVER_HANDLED;
}
}
pd->ddRVal = DD_OK;
DEBUGLEAVE( HalCanCreateSurface );
return DDHAL_DRIVER_HANDLED;
}
EXTERN_C DWORD WINAPI DDGPECreateSurface( LPDDHAL_CREATESURFACEDATA pd )
{
SCODE sc = S_OK;
unsigned int iSurf; // Surface index
//unsigned int nBPP; // Bits-per-pixel on surface
unsigned int nWidth; // Width of surface in pixels
//unsigned int nPitch; // Width of surface in bytes
unsigned int nHeight; // Height of surface in pixels
LPDDRAWI_DDRAWSURFACE_LCL
pSurf; // Pointer to surface data
EDDGPEPixelFormat pixelFormat;
EGPEFormat format; // Pixel format of surface(s) being created
DWORD dwFlags = pd->lpDDSurfaceDesc->dwFlags;
DWORD dwCaps = pd->lpDDSurfaceDesc->ddsCaps.dwCaps;
DEBUGENTER( DDGPECreateSurface );
//DebugBreak();
/*
typedef struct _DDHAL_CREATESURFACEDATA
{
LPDDRAWI_DIRECTDRAW_GBL lpDD; // driver struct
LPDDSURFACEDESC lpDDSurfaceDesc;// description of surface being created
LPDDRAWI_DDRAWSURFACE_LCL FAR *lplpSList; // list of created surface objects
DWORD dwSCnt; // number of surfaces in SList
HRESULT ddRVal; // return value
LPDDHAL_CREATESURFACE CreateSurface; // PRIVATE: ptr to callback
} DDHAL_CREATESURFACEDATA;
*/
sc = DDGPEGetPixelFormatFromSurfaceDesc(
pd->lpDDSurfaceDesc,
&pixelFormat,
&format
);
if (FAILED(sc))
{
DEBUGMSG(HAL_ZONE_WARNING,(TEXT("DDGPECreateSurface ERROR - DDERR_UNSUPPORTEDFORMAT (0x%08x)\r\n"),
sc ));
pd->ddRVal = DDERR_UNSUPPORTEDFORMAT;
DEBUGLEAVE(HalCreateSurface);
return DDHAL_DRIVER_HANDLED;
}
// Use pd->lpDDSurfaceDesc->dwFlags to determine which fields are valid and use them
/* nBPP = (pd->lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) ?
((USHORT)(pd->lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount)) :
g_pDDrawPrimarySurface->Bpp();*/
/*#ifdef FB16BPP
16; // REVIEW!
#else
8; // REVIEW!
#endif*/
nWidth = (pd->lpDDSurfaceDesc->dwFlags & DDSD_WIDTH) ?
( pd->lpDDSurfaceDesc->dwWidth ) : DDRAW_SCREEN_WIDTH; // resolves to a call to
// g_pDDrawPrimarySurface or a GPE query
nHeight = (pd->lpDDSurfaceDesc->dwFlags & DDSD_HEIGHT) ?
( pd->lpDDSurfaceDesc->dwHeight ) : DDRAW_SCREEN_HEIGHT; // resolves to a call to
// g_pDDrawPrimarySurface or a GPE query
//DEBUGMSG(GPE_ZONE_CREATE,(TEXT("nBPP: %d\r\n"), nBPP ));
/*switch(nBPP)
{
case 8:
format = gpe8Bpp;
break;
case 16:
format = gpe16Bpp;
break;
case 24:
// if( pd->lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS )
// format = pfmt_24a;
// else
// format = pfmt_24;
// nBPP = 32;
// break;
DEBUGMSG(GPE_ZONE_WARNING,(TEXT("HalCreateSurface rejecting %d BPP surface\r\n"), nBPP));
pd->ddRVal = DDERR_UNSUPPORTEDFORMAT;
return DDHAL_DRIVER_HANDLED;
case 32:
format = gpe32Bpp;
break;
}*/
//nPitch = ( nWidth * nBPP ) >>3;
//nPitch = ( nPitch + 3 ) & ~3;
#if DEBUG
DEBUGMSG(HAL_ZONE_CREATE,(TEXT("Number of surfaces to create: %d\r\n"), pd->dwSCnt ));
DEBUGMSG(HAL_ZONE_CREATE,(TEXT("Create Surface flags: ")));
// DumpDDSCAPS(pd->lpDDSurfaceDesc->ddsCaps);
#endif
for( iSurf=0; iSurf<pd->dwSCnt; iSurf++ )
{
pSurf = pd->lplpSList[iSurf];
//#if DEBUG
#if 0
DEBUGMSG(HAL_ZONE_CREATE,(TEXT("Surface #%d: LCL:%08x FLAGS:"), iSurf, pSurf ));
DumpDDSCAPS( pSurf->ddsCaps );
if( dwCaps & DDSCAPS_MIPMAP )
{
DEBUGMSG(HAL_ZONE_CREATE,(TEXT("MipMap count: %d\r\n"), pSurf->lpSurfMore->dwMipMapCount ));
}
DEBUGMSG(HAL_ZONE_CREATE,(TEXT("\r\nAddr of GBL: 0x%08x, Addr of LCL: 0x%08x\r\n"),
pSurf->lpGbl, pSurf ));
#endif
if ( pSurf->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE )
{
DEBUGMSG(HAL_ZONE_INFO, (TEXT("dwCaps4 = 0x%x\r\n"), pSurf->lpSurfMore->ddsCapsEx.dwCaps4));
if ( (pSurf->lpSurfMore->ddsCapsEx.dwCaps4 & DDSCAPS4_NONGDIPRIMARY) )
{
DWORD dwModeID = -1L;
DEBUGMSG(HAL_ZONE_INFO, (TEXT("SPLITTING THE DDRAW SURFACE\r\n") ));
// g_pDrawPrimarySurface is originally set to the GDI primary surface, but this isn't what we want
// for our model. We want a ddraw primary surface that is separate from the GDI primary surface.
// (and that could have a different pixel depth, stride, format, etc.)
DEBUGMSG(HAL_ZONE_INFO, (TEXT("still have pixelFormat %d\r\n"), pixelFormat));
if ( (pd->lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) )
{
DEBUGMSG(HAL_ZONE_INFO, (TEXT("Using pixel format to find split mode\r\n") ));
sc = g_pGPE->DetectMode(&dwModeID, nWidth, nHeight, format, pixelFormat, &pd->lpDDSurfaceDesc->ddpfPixelFormat);
}
else
{
DEBUGMSG(HAL_ZONE_INFO, (TEXT("NOT using pixel format to find split mode\r\n") ));
sc = g_pGPE->DetectMode(&dwModeID, nWidth, nHeight, format, pixelFormat);
}
GPEMode modeInfo;
DDGPESurf* pDDGPESurf = NULL;
if (FAILED(sc))
{
DEBUGMSG(HAL_ZONE_WARNING, (TEXT("Could not find requested primary surface mode 0x%08x\r\n"), sc));
// try to just split off a surface of the same type as the current primary surface (GDI surface)
sc = S_OK;
dwModeID = g_pGPE->GetModeId(); // can only split off GDI surface
}
else
{
DEBUGMSG(HAL_ZONE_INFO, (TEXT("Found requested primary surface mode: ID = %d\r\n"), dwModeID));
}
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))
{
DEBUGMSG(HAL_ZONE_ERROR, (TEXT("DDGPECreateSurface- Could not find a good mode: DetectMode and GetModeInfo failed. 0x%x\r\n"), sc ));
}
else
{
BOOL bSplitToSame = FALSE;
if (DDGPEGDIHasSplitFromDDraw())
{
// 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;
DEBUGMSG(HAL_ZONE_WARNING, (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 );
DEBUGMSG(
HAL_ZONE_INFO,
(TEXT("Created primary surface at: 0x%x (%d)\r\n"),
dwOffsetInVideoMemory,
dwOffsetInVideoMemory
));
}
}
if (FAILED(sc))
{
DEBUGMSG(HAL_ZONE_ERROR, (TEXT("DDGPECreateSurface-AllocSurface failed 0x%x\r\n"), sc ));
}
else
{
if (pDDGPESurf != NULL)
{
g_pDDrawPrimarySurface = pDDGPESurf; //(DDGPESurf*)g_pGPE->PrimarySurface();
DEBUGMSG(HAL_ZONE_SUCCESS, (TEXT("DDGPECreateSurface-AllocSurface successful 0x%x\r\n"), g_pDDrawPrimarySurface->OffsetInVideoMemory() ));
}
else
{
DEBUGMSG(HAL_ZONE_ERROR, (TEXT("DDGPECreateSurface-AllocSurface returned NULL 0x%x\r\n"), sc ));
}
}
if (dwModeID != (DWORD)-1L)
{
if (dwModeID != (DWORD)g_pGPE->GetPhysicalModeId())
{
DEBUGMSG(HAL_ZONE_INFO, (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))
{
DEBUGMSG(HAL_ZONE_ERROR, (TEXT("Failed to set the physical mode 0x%08x\r\n"), sc));
}
DEBUGMSG(HAL_ZONE_INFO, (TEXT("Calling UpdateHALInit\r\n") ));
UpdateHALInit(pd->lpDD, dwModeID);
DEBUGMSG(HAL_ZONE_INFO, (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
{
DEBUGMSG(HAL_ZONE_WARNING, (TEXT("Current mode is same as requested split mode (%d)\r\n"), dwModeID));
}
}
//DEBUGMSG(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.
//DEBUGMSG(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
//DEBUGMSG(HAL_ZONE_INFO, (TEXT("Flipping to the new primary surface\r\n") ));
g_pGPE->SetVisibleSurface(g_pDDrawPrimarySurface, NULL, FALSE);
//DEBUGMSG(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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -