📄 ddcalls.c
字号:
if (LastError == DDERR_OUTOFMEMORY || LastError == DDERR_OUTOFVIDEOMEMORY) {
D3DAppISetErrorString("There was not enough video memory to create the rendering surface.\nPlease restart the program and try another fullscreen mode with less resolution or lower bit depth.");
} else {
D3DAppISetErrorString("CreateSurface for fullscreen flipping surface failed.\n%s",
D3DAppErrorToString(LastError));
}
goto exit_with_error;
}
/*
* Obtain a pointer to the back buffer surface created above so we
* can use it later. For now, just check to see if it ended up in
* video memory (FYI).
*/
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
LastError = d3dappi.lpFrontBuffer->lpVtbl->GetAttachedSurface(d3dappi.lpFrontBuffer, &ddscaps, &d3dappi.lpBackBuffer);
if(LastError != DD_OK) {
D3DAppISetErrorString("GetAttachedSurface failed to get back buffer.\n%s",
D3DAppErrorToString(LastError));
goto exit_with_error;
}
LastError = D3DAppIGetSurfDesc(&ddsd, d3dappi.lpBackBuffer);
if (LastError != DD_OK) {
D3DAppISetErrorString("Failed to get surface description of back buffer.\n%s",
D3DAppErrorToString(LastError));
goto exit_with_error;
}
d3dappi.bBackBufferInVideo =
(ddsd.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY) ? TRUE : FALSE;
}
else {
/*
* In the window case, create a front buffer which is the primary
* surface and a back buffer which is an offscreen plane surface.
*/
memset(&ddsd,0,sizeof(DDSURFACEDESC));
ddsd.dwSize = sizeof(DDSURFACEDESC);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
/*
* If we specify system memory when creating a primary surface, we
* won't get the actual primary surface in video memory. So, don't
* use D3DAppICreateSurface().
*/
LastError = d3dappi.lpDD->lpVtbl->CreateSurface(d3dappi.lpDD,
&ddsd, &d3dappi.lpFrontBuffer, NULL);
if(LastError != DD_OK ) {
if (LastError == DDERR_OUTOFMEMORY || LastError == DDERR_OUTOFVIDEOMEMORY) {
D3DAppISetErrorString("There was not enough video memory to create the rendering surface.\nTo run this program in a window of this size, please adjust your display settings for a smaller desktop area or a lower palette size and restart the program.");
} else {
D3DAppISetErrorString("CreateSurface for window front buffer failed.\n%s",
D3DAppErrorToString(LastError));
}
goto exit_with_error;
}
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
ddsd.dwWidth = w;
ddsd.dwHeight = h;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
if (bIsHardware)
ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
else
ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
LastError = D3DAppICreateSurface(&ddsd, &d3dappi.lpBackBuffer);
if (LastError != DD_OK) {
if (LastError == DDERR_OUTOFMEMORY || LastError == DDERR_OUTOFVIDEOMEMORY) {
D3DAppISetErrorString("There was not enough video memory to create the rendering surface.\nTo run this program in a window of this size, please adjust your display settings for a smaller desktop area or a lower palette size and restart the program.");
} else {
D3DAppISetErrorString("CreateSurface for window back buffer failed.\n%s",
D3DAppErrorToString(LastError));
}
goto exit_with_error;
}
/*
* Check to see if the back buffer is in video memory (FYI).
*/
LastError = D3DAppIGetSurfDesc(&ddsd, d3dappi.lpBackBuffer);
if (LastError != DD_OK) {
D3DAppISetErrorString("Failed to get surface description for back buffer.\n%s",
D3DAppErrorToString(LastError));
goto exit_with_error;
}
d3dappi.bBackBufferInVideo =
(ddsd.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY) ? TRUE : FALSE;
/*
* Create the DirectDraw Clipper object and attach it to the window
* and front buffer.
*/
LastError = d3dappi.lpDD->lpVtbl->CreateClipper(d3dappi.lpDD, 0,
&lpClipper, NULL);
if(LastError != DD_OK ) {
D3DAppISetErrorString("CreateClipper failed.\n%s",
D3DAppErrorToString(LastError));
goto exit_with_error;
}
LastError = lpClipper->lpVtbl->SetHWnd(lpClipper, 0, hwnd);
if(LastError != DD_OK ) {
D3DAppISetErrorString("Attaching clipper to window failed.\n%s",
D3DAppErrorToString(LastError));
goto exit_with_error;
}
LastError =
d3dappi.lpFrontBuffer->lpVtbl->SetClipper(d3dappi.lpFrontBuffer,
lpClipper);
if(LastError != DD_OK ) {
D3DAppISetErrorString("Attaching clipper to front buffer failed.\n%s",
D3DAppErrorToString(LastError));
goto exit_with_error;
}
}
D3DAppIClearBuffers();
return TRUE;
exit_with_error:
RELEASE(d3dappi.lpFrontBuffer);
RELEASE(d3dappi.lpBackBuffer);
RELEASE(lpClipper);
return FALSE;
}
/*
* D3DAppICheckForPalettized
* If the front/back buffer is palettized, we need to create a palette.
*/
BOOL
D3DAppICheckForPalettized(void)
{
DDSURFACEDESC ddsd;
/*
* Get the back buffer surface description and check to see if it's
* palettized
*/
LastError = D3DAppIGetSurfDesc(&ddsd, d3dappi.lpBackBuffer);
if (LastError != DD_OK) {
D3DAppISetErrorString("Failed to get surface description for back buffer for palettizing.\n%s",
D3DAppErrorToString(LastError));
goto exit_with_error;
}
bPrimaryPalettized =
(ddsd.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) ? TRUE : FALSE;
if (bPrimaryPalettized) {
int i;
/*
* Get the current palette.
*/
HDC hdc = GetDC(NULL);
GetSystemPaletteEntries(hdc, 0, (1 << 8), ppe);
ReleaseDC(NULL, hdc);
/*
* Change the flags on the palette entries to allow D3D to change
* some of them. In the window case, we must not change the top and
* bottom ten (system colors), but in a fullscreen mode we can have
* all but the first and last.
*/
if (!d3dappi.bFullscreen) {
for (i = 0; i < 10; i++) ppe[i].peFlags = D3DPAL_READONLY;
for (i = 10; i < 256 - 10; i++) ppe[i].peFlags = D3DPAL_FREE | PC_RESERVED;
for (i = 256 - 10; i < 256; i++) ppe[i].peFlags = D3DPAL_READONLY;
} else {
ppe[0].peFlags = D3DPAL_READONLY;
for (i = 1; i < 255; i++) ppe[i].peFlags = D3DPAL_FREE | PC_RESERVED;
ppe[255].peFlags = D3DPAL_READONLY;
}
/*
* Create a palette using the old colors and new flags
*/
LastError = d3dappi.lpDD->lpVtbl->CreatePalette(d3dappi.lpDD,
DDPCAPS_8BIT | DDPCAPS_INITIALIZE,
ppe, &lpPalette, NULL);
if (LastError != DD_OK) {
D3DAppISetErrorString("CreatePalette failed.\n%s",
D3DAppErrorToString(LastError));
goto exit_with_error;
}
/*
* Set this as the front and back buffers' palette
*/
LastError =
d3dappi.lpBackBuffer->lpVtbl->SetPalette(d3dappi.lpBackBuffer,
lpPalette);
if(LastError != DD_OK ) {
D3DAppISetErrorString("SetPalette failed on back buffer.\n%s",
D3DAppErrorToString(LastError));
goto exit_with_error;
}
LastError =
d3dappi.lpFrontBuffer->lpVtbl->SetPalette(d3dappi.lpFrontBuffer,
lpPalette);
if(LastError != DD_OK ) {
D3DAppISetErrorString("SetPalette failed on front buffer.\n%s",
D3DAppErrorToString(LastError));
goto exit_with_error;
}
/*
* The palette is now valid, so set it again on anyt WM_ACTIVATE
*/
bPaletteActivate = TRUE;
}
return TRUE;
exit_with_error:
RELEASE(lpPalette);
return FALSE;
}
/***************************************************************************/
/* Creation of Z-Buffer */
/***************************************************************************/
/*
* D3DAppICreateZBuffer
* Create a Z-Buffer of the appropriate depth and attach it to the back
* buffer.
*/
BOOL
D3DAppICreateZBuffer(int w, int h, int driver)
{
DDSURFACEDESC ddsd;
DWORD devDepth;
/*
* Release any Z-Buffer that might be around just in case.
*/
RELEASE(d3dappi.lpZBuffer);
/*
* If this driver does not do z-buffering, don't create a z-buffer
*/
if (!d3dappi.Driver[driver].bDoesZBuffer)
return TRUE;
memset(&ddsd, 0 ,sizeof(DDSURFACEDESC));
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS |
DDSD_ZBUFFERBITDEPTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
ddsd.dwHeight = h;
ddsd.dwWidth = w;
/*
* If this is a hardware D3D driver, the Z-Buffer MUST end up in video
* memory. Otherwise, it MUST end up in system memory.
*/
if (d3dappi.Driver[driver].bIsHardware)
ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
else
ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
/*
* Get the Z buffer bit depth from this driver's D3D device description
*/
devDepth = d3dappi.Driver[driver].Desc.dwDeviceZBufferBitDepth;
if (devDepth & DDBD_32)
ddsd.dwZBufferBitDepth = 32;
else if (devDepth & DDBD_24)
ddsd.dwZBufferBitDepth = 24;
else if (devDepth & DDBD_16)
ddsd.dwZBufferBitDepth = 16;
else if (devDepth & DDBD_8)
ddsd.dwZBufferBitDepth = 8;
else {
D3DAppISetErrorString("Unsupported Z-buffer depth requested by device.\n");
return FALSE;
}
LastError = d3dappi.lpDD->lpVtbl->CreateSurface(d3dappi.lpDD, &ddsd,
&d3dappi.lpZBuffer,
NULL);
if(LastError != DD_OK) {
if (LastError == DDERR_OUTOFMEMORY || LastError == DDERR_OUTOFVIDEOMEMORY) {
if (d3dappi.bFullscreen) {
D3DAppISetErrorString("There was not enough video memory to create the Z-buffer surface.\nPlease restart the program and try another fullscreen mode with less resolution or lower bit depth.");
} else {
D3DAppISetErrorString("There was not enough video memory to create the Z-buffer surface.\nTo run this program in a window of this size, please adjust your display settings for a smaller desktop area or a lower palette size and restart the program.");
}
} else {
D3DAppISetErrorString("CreateSurface for Z-buffer failed.\n%s",
D3DAppErrorToString(LastError));
}
goto exit_with_error;
}
/*
* Attach the Z-buffer to the back buffer so D3D will find it
*/
LastError =
d3dappi.lpBackBuffer->lpVtbl->AddAttachedSurface(d3dappi.lpBackBuffer,
d3dappi.lpZBuffer);
if(LastError != DD_OK) {
D3DAppISetErrorString("AddAttachedBuffer failed for Z-Buffer.\n%s",
D3DAppErrorToString(LastError));
goto exit_with_error;
}
/*
* Find out if it ended up in video memory.
*/
LastError = D3DAppIGetSurfDesc(&ddsd, d3dappi.lpZBuffer);
if (LastError != DD_OK) {
D3DAppISetErrorString("Failed to get surface description of Z buffer.\n%s",
D3DAppErrorToString(LastError));
goto exit_with_error;
}
d3dappi.bZBufferInVideo =
(ddsd.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY) ? TRUE : FALSE;
if (d3dappi.Driver[driver].bIsHardware && !d3dappi.bZBufferInVideo) {
D3DAppISetErrorString("Could not fit the Z-buffer in video memory for this hardware device.\n");
goto exit_with_error;
}
return TRUE;
exit_with_error:
RELEASE(d3dappi.lpZBuffer);
return FALSE;
}
/***************************************************************************/
/* WM_SIZE Handler */
/***************************************************************************/
/*
* D3DAppIHandleWM_SIZE
* Processes the WM_SIZE message. Resizes all the buffers and re-creates
* device if necessary.
*/
BOOL
D3DAppIHandleWM_SIZE(LRESULT* lresult, HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
int w, h, i;
/*
* If we have minimzied, take note and call the default window proc
*/
if (wParam == SIZE_MINIMIZED) {
d3dappi.bMinimized = TRUE;
*lresult = DefWindowProc(hwnd, message, wParam, lParam);
return TRUE;
}
/*
* In fullscreen mode, restore our surfaces and let DDraw take
* care of the rest.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -