ddcalls.cpp
上传用户:garry_shen
上传日期:2015-04-15
资源大小:45647k
文件大小:33k
- /*
- * Copyright (C) 1998 Microsoft Corporation. All Rights Reserved.
- *
- * File: ddcalls.c
- *
- * Manages DirectDraw objects needed for rendering. Part of D3DApp.
- *
- * D3DApp is a collection of helper functions for Direct3D applications.
- * D3DApp consists of the following files:
- * d3dapp.h Main D3DApp header to be included by application
- * d3dappi.h Internal header
- * d3dapp.c D3DApp functions seen by application.
- * ddcalls.c All calls to DirectDraw objects except textures
- * d3dcalls.c All calls to Direct3D objects except textures
- * texture.c Texture loading and managing texture list
- * misc.c Miscellaneous calls
- */
- // Borland CBuilder3 doesn't support nameless unions...
- #include "stdafx.h"
- #include "XMudClient.h"
- #include "d3dappi.h"
- /***************************************************************************/
- /* Direct Draw Enumeration */
- /***************************************************************************/
- typedef struct {
- D3DAppDDDriver* driver;
- int numdriver;
- } DDEnumCallbackContext;
- /*
- * D3DAppIDDEnumCallback
- * Callback function used during enumeration of DirectDraw drivers.
- */
- BOOL FAR PASCAL D3DAppIDDEnumCallback(GUID FAR* lpGUID, LPSTR lpDriverDesc, LPSTR lpDriverName, LPVOID lpContext)
- {
- LPDIRECTDRAW lpDD;
- DDCAPS DriverCaps, HELCaps;
- DDEnumCallbackContext *context = (DDEnumCallbackContext*)lpContext;
- D3DAppDDDriver* driver = &context->driver[context->numdriver];
-
- /*
- * Create the DirectDraw device using this driver. If it fails,
- * just move on to the next driver.
- */
- #ifdef _DIRECTX7
- if (FAILED(DirectDrawCreateEx(lpGUID, (LPVOID *)&lpDD, IID_IDirectDraw7, NULL))) {
- return DDENUMRET_OK;
- }
- #else
- if (FAILED(DirectDrawCreate(lpGUID, &lpDD, NULL))) {
- return DDENUMRET_OK;
- }
- #endif
- /*
- * Get the capabilities of this DirectDraw driver. If it fails,
- * just move on to the next driver.
- */
- memset(&DriverCaps, 0, sizeof(DDCAPS));
- DriverCaps.dwSize = sizeof(DDCAPS);
- memset(&HELCaps, 0, sizeof(DDCAPS));
- HELCaps.dwSize = sizeof(DDCAPS);
- if (FAILED(lpDD->GetCaps(&DriverCaps, &HELCaps)))
- {
- lpDD->Release( );
- return DDENUMRET_OK;
- }
- if (lpGUID && (DriverCaps.dwCaps & DDCAPS_3D))
- {
- /*
- * We have found a secondary 3d hardware device. Return the DD object
- * and stop enumeration.
- */
- memcpy(&driver->Guid, lpGUID, sizeof(GUID));
- memcpy(&driver->HWCaps, &DriverCaps, sizeof(DDCAPS));
- lstrcpy(driver->Name, lpDriverName);
- driver->bIsPrimary = FALSE;
- context->numdriver++;
- } else {
- /*
- * It's the primary, fill in some fields.
- */
- memset(&driver->Guid, 0, sizeof(GUID));
- memcpy(&driver->HWCaps, &DriverCaps, sizeof(DDCAPS));
- lstrcpy(driver->Name, "Primary Device");
- driver->bIsPrimary = TRUE;
- context->numdriver++;
- }
- lpDD->Release( );
- if (context->numdriver >= D3DAPP_MAXDDDRIVERS)
- return DDENUMRET_CANCEL;
- else
- return DDENUMRET_OK;
- }
- /*
- * D3DAppIEnumDDDevices
- * Enumerate all 3D capable devices and the primary display, filling in
- * the driver information variables. lpDriver must point to a region
- * with enough room for the maximum DD drivers.
- */
- BOOL
- D3DAppIEnumDDDevices(int* NumDriver, D3DAppDDDriver* lpDriver)
- {
- DDEnumCallbackContext context;
-
- context.numdriver = 0;
- context.driver = lpDriver;
- LastError = DirectDrawEnumerate(D3DAppIDDEnumCallback, &context);
- if (LastError != DD_OK) {
- D3DAppISetErrorString("DirectDrawEnumerate failed.n%s",
- D3DAppErrorToString(LastError));
- return FALSE;
- }
- *NumDriver = context.numdriver;
- return TRUE;
- }
- /***************************************************************************/
- /* Direct Draw Creation */
- /***************************************************************************/
- /*
- * D3DAppICreateDD
- * Creates the DirectDraw device and saves the current palette.
- * It is assumed that a 3D capable secondary DD driver is not the
- * primary device and hence cannot operate in a window (ie it's a
- * fullscreen only device displaying on a second monitor). Valid flags:
- * D3DAPP_ONLYDDEMULATION Always use the DirectDraw HEL
- */
- BOOL D3DAppICreateDD(DWORD flags, LPGUID lpGuid)
- {
- HDC hdc;
- int i;
- LPDIRECTDRAW lpDD = NULL;
-
- if (flags & D3DAPP_ONLYDDEMULATION)
- lpGuid = NULL;
-
- if (!lpGuid)
- d3dappi.bIsPrimary = TRUE;
- else
- d3dappi.bIsPrimary = FALSE;
- //*/
- #ifdef _DIRECTX7
- LastError = DirectDrawCreateEx(lpGuid, (LPVOID *)&d3dappi.lpDD, IID_IDirectDraw7, NULL);
- #else
- LastError = DirectDrawCreate(lpGuid, &d3dappi.lpDD, NULL);
- #endif
- if (LastError != DD_OK) {
- D3DAppISetErrorString("DirectDrawCreate failed.n%s",
- D3DAppErrorToString(LastError));
- return FALSE;
- }
- /*/
- LastError = DirectDrawCreate(lpGuid, &lpDD, NULL);
- if (LastError != DD_OK)
- {
- D3DAppISetErrorString("DirectDrawCreate failed.n%s",
- D3DAppErrorToString(LastError));
- return FALSE;
- }
-
- LastError = lpDD->QueryInterface( IID_IDirectDraw, (VOID**)&d3dappi.lpDD );
- if (LastError != DD_OK)
- {
- lpDD->Release();
- D3DAppISetErrorString("Couldn't query for DirectDraw4.n%s",
- D3DAppErrorToString(LastError));
- return FALSE;
- }
- lpDD->Release();
- //*/
- //
- // Save the original palette for when we are paused. Just in case we
- // start in a fullscreen mode, put them in ppe.
- //
- hdc = GetDC(NULL);
- GetSystemPaletteEntries(hdc, 0, (1 << 8),
- (LPPALETTEENTRY)(&Originalppe[0]));
- for (i = 0; i < 256; i++)
- ppe[i] = Originalppe[i];
- ReleaseDC(NULL, hdc);
- return TRUE;
- }
- /***************************************************************************/
- /* Enumerating the display modes */
- /***************************************************************************/
- /*
- * EnumDisplayModesCallback
- * Callback to save the display mode information.
- */
- static HRESULT
- CALLBACK EnumDisplayModesCallback(LPDDSURFACEDESC pddsd, LPVOID lpContext)
- {
- /*
- * Very large resolutions cause problems on some hardware. They are also
- * not very useful for real-time rendering. We have chosen to disable
- * them by not reporting them as available.
- */
- if (pddsd->dwWidth > 1024 || pddsd->dwHeight > 768)
- return DDENUMRET_OK;
- /*
- * Save this mode at the end of the mode array and increment mode count
- */
- d3dappi.Mode[d3dappi.NumModes].w = pddsd->dwWidth;
- d3dappi.Mode[d3dappi.NumModes].h = pddsd->dwHeight;
- d3dappi.Mode[d3dappi.NumModes].bpp = pddsd->ddpfPixelFormat.dwRGBBitCount;
- d3dappi.Mode[d3dappi.NumModes].bThisDriverCanDo = FALSE;
- d3dappi.NumModes++;
- if (d3dappi.NumModes == D3DAPP_MAXMODES)
- return DDENUMRET_CANCEL;
- else
- return DDENUMRET_OK;
- }
- /*
- * CompareModes
- * Compare two display modes during sorting. Modes are sorted by depth and
- * then resolution.
- */
- static int
- _cdecl CompareModes(const void* element1, const void* element2) {
- D3DAppMode *lpMode1, *lpMode2;
-
- lpMode1 = (D3DAppMode*)element1;
- lpMode2 = (D3DAppMode*)element2;
-
- if (lpMode1->bpp > lpMode2->bpp)
- return -1;
- else if (lpMode2->bpp > lpMode1->bpp)
- return 1;
- else if (lpMode1->w > lpMode2->w)
- return -1;
- else if (lpMode2->w > lpMode1->w)
- return 1;
- else if (lpMode1->h > lpMode2->h)
- return -1;
- else if (lpMode2->h > lpMode1->h)
- return 1;
- else
- return 0;
- }
- /*
- * EnumerateDisplayModes
- * Generates the list of available display modes.
- */
- BOOL D3DAppIEnumDisplayModes(void)
- {
- int i;
- /*
- * Get a list of available display modes from DirectDraw
- */
- d3dappi.NumModes = 0;
- LastError = d3dappi.lpDD->EnumDisplayModes( 0, NULL, 0, EnumDisplayModesCallback);
- if(LastError != DD_OK ) {
- D3DAppISetErrorString("EnumDisplayModes failed.n%s",
- D3DAppErrorToString(LastError));
- d3dappi.NumModes = 0;
- return FALSE;
- }
- /*
- * Sort the list of display modes
- */
- qsort((void *)&d3dappi.Mode[0], (size_t)d3dappi.NumModes, sizeof(D3DAppMode),
- CompareModes);
- /*
- * Pick a default display mode. 640x480x16 is a very good mode for
- * rendering, so choose it over all others. Otherwise, just take the
- * first one. This selection may be overriden later if a driver is
- * created which cannot render in this mode.
- */
- d3dappi.CurrMode = 0;
- for (i = 0; i < d3dappi.NumModes; i++) {
- if (d3dappi.Mode[i].w == DEFULTWND_WIDTH && d3dappi.Mode[i].h == DEFULTWND_HEIGHT &&
- d3dappi.Mode[i].bpp == 16)
- d3dappi.CurrMode = i;
- }
- memcpy(&d3dappi.ThisMode, &d3dappi.Mode[d3dappi.CurrMode],
- sizeof(D3DAppMode));
- return TRUE;
- }
- /***************************************************************************/
- /* Creating Front and Back Buffers (and misc surf funcs) */
- /***************************************************************************/
- //
- // D3DAppICreateSurface
- // Create a DirectDraw Surface of the given description. Using this function
- // ensures that all surfaces end up in system memory if that option was set.
- // Returns the result of the CreateSurface call.
- //
- HRESULT D3DAppICreateSurface(LPDDSURFACEDESC lpDDSurfDesc,
- LPDIRECTDRAWSURFACE FAR *lpDDSurface)
- {
- HRESULT result;
- if (d3dappi.bOnlySystemMemory)
- lpDDSurfDesc->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
- result = d3dappi.lpDD->CreateSurface(lpDDSurfDesc,
- lpDDSurface, NULL);
- return result;
- }
- /*
- * D3DAppIGetSurfDesc
- * Get the description of the given surface. Returns the result of the
- * GetSurfaceDesc call.
- */
- HRESULT
- D3DAppIGetSurfDesc(LPDDSURFACEDESC lpDDSurfDesc,LPDIRECTDRAWSURFACE lpDDSurf)
- {
- HRESULT result;
- memset(lpDDSurfDesc, 0, sizeof(DDSURFACEDESC));
- lpDDSurfDesc->dwSize = sizeof(DDSURFACEDESC);
- result = lpDDSurf->GetSurfaceDesc(lpDDSurfDesc);
- return result;
- }
- /*
- * D3DAppICreateBuffers
- * Creates the front and back buffers for the window or fullscreen case
- * depending on the bFullscreen flag. In the window case, bpp is ignored.
- */
- BOOL D3DAppICreateBuffers(HWND hwnd, int w, int h, int bpp, BOOL bFullscreen, BOOL bIsHardware)
- {
- DDSURFACEDESC ddsd;
- DDSCAPS ddscaps;
-
- /*
- * Release any old objects that might be lying around. This should have
- * already been taken care of, but just in case...
- */
- RELEASE(lpClipper);
- RELEASE(d3dappi.lpBackBuffer);
- RELEASE(d3dappi.lpFrontBuffer);
- /*
- * The size of the buffers is going to be w x h, so record it now
- */
- if (w < D3DAPP_WINDOWMINIMUM)
- w = D3DAPP_WINDOWMINIMUM;
- if (h < D3DAPP_WINDOWMINIMUM)
- h = D3DAPP_WINDOWMINIMUM;
- szBuffers.cx = w;
- szBuffers.cy = h;
-
- if (bFullscreen)
- {
- //
- // Create a complex flipping surface for fullscreen mode with one
- // back buffer.
- //
- memset(&ddsd,0,sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP |
- DDSCAPS_3DDEVICE | DDSCAPS_COMPLEX;
- ddsd.dwBackBufferCount = 1;
- if (bIsHardware)
- ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
- LastError = D3DAppICreateSurface(&ddsd, &d3dappi.lpFrontBuffer);
- if(LastError != DD_OK) {
- 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->GetAttachedSurface(&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(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- 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->CreateSurface(&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->CreateClipper( 0,&lpClipper, NULL);
- if(LastError != DD_OK )
- {
- D3DAppISetErrorString("CreateClipper failed.n%s",
- D3DAppErrorToString(LastError));
- goto exit_with_error;
- }
- LastError = lpClipper->SetHWnd(0, hwnd);
- if(LastError != DD_OK )
- {
- D3DAppISetErrorString("Attaching clipper to window failed.n%s",
- D3DAppErrorToString(LastError));
- goto exit_with_error;
- }
- LastError =
- d3dappi.lpFrontBuffer->SetClipper(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->CreatePalette(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->SetPalette(lpPalette);
- if(LastError != DD_OK )
- {
- D3DAppISetErrorString("SetPalette failed on back buffer.n%s",
- D3DAppErrorToString(LastError));
- goto exit_with_error;
- }
- LastError =
- d3dappi.lpFrontBuffer->SetPalette(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(ddsd));
- 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;
- #ifdef _DIRECTX7
- if (devDepth & DDBD_32)
- ddsd.ddpfPixelFormat.dwZBufferBitDepth = 32;
- else if (devDepth & DDBD_24)
- ddsd.ddpfPixelFormat.dwZBufferBitDepth = 24;
- else if (devDepth & DDBD_16)
- ddsd.ddpfPixelFormat.dwZBufferBitDepth = 16;
- else if (devDepth & DDBD_8)
- ddsd.ddpfPixelFormat.dwZBufferBitDepth = 8;
- #else
- 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;
- #endif
- else
- {
- D3DAppISetErrorString("Unsupported Z-buffer depth requested by device.n");
- return FALSE;
- }
- LastError = d3dappi.lpDD->CreateSurface(&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->AddAttachedSurface(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.
- */
- if (d3dappi.bFullscreen) {
- D3DAppIValidateDirtyRects();
- D3DAppCheckForLostSurfaces();
- d3dappi.bMinimized = FALSE;
- *lresult = DefWindowProc(hwnd, message, wParam, lParam);
- return TRUE;
- }
- /*
- * If we are minimized, this is the un-minimized size message.
- */
- if (d3dappi.bMinimized) {
- /*
- * Restore our surfaces and update the dirty rectangle info
- */
- D3DAppIValidateDirtyRects();
- D3DAppCheckForLostSurfaces();
- d3dappi.bMinimized = FALSE;
- *lresult = DefWindowProc(hwnd, message, wParam, lParam);
- return TRUE;
- }
- /*
- * Since we are still here, this must be a regular, window resize
- * message. A new viewport will definitely be needed, but the
- * device and buffers will only be re-created if they have gotten bigger
- * or change size by a very large amount.
- */
- D3DAppIGetClientWin(hwnd);
- w = LOWORD(lParam);
- h = HIWORD(lParam);
- /*
- * If w and h are under the minimum, create buffers of the minimum size
- */
- if (w < D3DAPP_WINDOWMINIMUM)
- w = D3DAPP_WINDOWMINIMUM;
- if (h < D3DAPP_WINDOWMINIMUM)
- h = D3DAPP_WINDOWMINIMUM;
- /*
- * Destroy the viewport and all execute buffers
- */
- d3dappi.bRenderingIsOK = FALSE;
- ATTEMPT(D3DAppICallDeviceDestroyCallback());
- /*
- * Only create a new device and buffers if they changed significantly,
- * otherwise just make sure the old buffers aren't lost.
- */
- if ((w > szBuffers.cx || h > szBuffers.cy) ||
- (w < szBuffers.cx / 2 || h < szBuffers.cy / 2)) {
- /*
- * Release the device
- */
- RELEASE(d3dappi.lpD3DDevice);
- /*
- * Release the old buffers
- */
- RELEASE(d3dappi.lpZBuffer);
- RELEASE(lpPalette);
- RELEASE(lpClipper);
- RELEASE(d3dappi.lpBackBuffer);
- RELEASE(d3dappi.lpFrontBuffer);
- /*
- * Create new ones
- */
- ATTEMPT(D3DAppICreateBuffers(hwnd, w, h, D3DAPP_BOGUS, FALSE, d3dappi.ThisDriver.bIsHardware));
- ATTEMPT(D3DAppICheckForPalettized());
- ATTEMPT(D3DAppICreateZBuffer(w, h, d3dappi.CurrDriver));
- /*
- * Create the driver
- */
- ATTEMPT(D3DAppICreateDevice(d3dappi.CurrDriver));
- /*
- * Since the driver did not change, the texture surfaces are still valid.
- * We just need to get new handles.
- */
- if (d3dappi.ThisDriver.bDoesTextures) {
- for (i = 0; i < d3dappi.NumUsableTextures; i++) {
- D3DAppIGetTextureHandle(i);
- }
- }
- } else {
- D3DAppCheckForLostSurfaces();
- }
- /*
- * Call the device create callback to create the viewport, set the render
- * state and clear the dirty rectangle info
- */
- ATTEMPT(D3DAppICallDeviceCreateCallback(w, h));
- ATTEMPT(D3DAppISetRenderState());
- D3DAppIValidateDirtyRects();
- d3dappi.bRenderingIsOK = TRUE;
- /*
- * Call the default window proc
- */
- *lresult = DefWindowProc(hwnd, message, wParam, lParam);
- return TRUE;
- exit_with_error:
- D3DAppICallDeviceDestroyCallback();
- RELEASE(d3dappi.lpD3DDevice);
- RELEASE(d3dappi.lpZBuffer);
- RELEASE(lpPalette);
- RELEASE(lpClipper);
- RELEASE(d3dappi.lpBackBuffer);
- RELEASE(d3dappi.lpFrontBuffer);
- return FALSE;
- }
- /***************************************************************************/
- /* Setting the display mode and cooperative level */
- /***************************************************************************/
- /*
- * D3DAppISetCoopLevel
- * Set the cooperative level to exclusive mode for fullscreen and normal for
- * a window. Set the bIgnoreWM_SIZE flag because SetCooperativeLevel
- * generates a WM_SIZE message you do not have to resize the buffers on.
- */
- BOOL D3DAppISetCoopLevel(HWND hwnd, BOOL bFullscreen)
- {
- if (bFullscreen)
- {
- bIgnoreWM_SIZE = TRUE;
- LastError = d3dappi.lpDD->SetCooperativeLevel(hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
- bIgnoreWM_SIZE = FALSE;
- if(LastError != DD_OK )
- {
- D3DAppISetErrorString("SetCooperativeLevel to fullscreen failed.n%s",
- D3DAppErrorToString(LastError));
- return FALSE;
- }
-
- d3dappi.bFullscreen = TRUE;
- }
- else
- {
- bIgnoreWM_SIZE = TRUE;
- LastError = d3dappi.lpDD->SetCooperativeLevel(hwnd, DDSCL_NORMAL);
- bIgnoreWM_SIZE = FALSE;
- if(LastError != DD_OK ) {
- D3DAppISetErrorString("SetCooperativeLevel to normal failed.n%s",
- D3DAppErrorToString(LastError));
- return FALSE;
- }
- d3dappi.bFullscreen = FALSE;
- }
- return TRUE;
- }
- //
- // D3DAppISetDisplayMode
- // Set the display mode to the given dimensions and bits per pixel. The
- // bIgnoreWM_SIZE message is set because the display change generates a
- // WM_SIZE message which we don't want to resize the buffers on.
- //
- BOOL D3DAppISetDisplayMode(int w, int h, int bpp)
- {
- d3dappi.ThisMode.w = w; d3dappi.ThisMode.h = h;
- d3dappi.ThisMode.bpp = bpp;
- bIgnoreWM_SIZE = TRUE;
- #ifdef _DIRECTX7
- LastError = d3dappi.lpDD->SetDisplayMode(w, h,bpp,0,0);
- #else
- LastError = d3dappi.lpDD->SetDisplayMode(w, h,bpp);
- #endif
- bIgnoreWM_SIZE = FALSE;
- if(LastError != DD_OK )
- {
- D3DAppISetErrorString("SetDisplayMode to %dx%dx%d failedn%s",
- w, h, bpp, D3DAppErrorToString(LastError));
- return FALSE;
- }
- return TRUE;
- }
- /*
- * D3DAppIRestoreDispMode
- * Restores the display mode to the current windows display mode. The
- * bIgnoreWM_SIZE message is set because the display change generates a
- * WM_SIZE message which we don't want to resize the buffers on.
- */
- BOOL D3DAppIRestoreDispMode(void)
- {
- bIgnoreWM_SIZE = TRUE;
- LastError = d3dappi.lpDD->RestoreDisplayMode( );
- if (LastError != DD_OK)
- {
- D3DAppISetErrorString("RestoreDisplayMode failed.n%s",
- D3DAppErrorToString(LastError));
- return FALSE;
- }
- bIgnoreWM_SIZE = FALSE;
- return TRUE;
- }
- /*
- * D3DAppRememberWindowsMode
- * Record the current display mode in d3dappi.WindowsDisplay
- */
- BOOL D3DAppIRememberWindowsMode(void)
- {
- DDSURFACEDESC ddsd;
-
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- LastError = d3dappi.lpDD->GetDisplayMode(&ddsd);
- if (LastError != DD_OK) {
- D3DAppISetErrorString("Getting the current display mode failed.n%s",
- D3DAppErrorToString(LastError));
- return FALSE;
- }
- d3dappi.WindowsDisplay.w = ddsd.dwWidth;
- d3dappi.WindowsDisplay.h = ddsd.dwHeight;
- d3dappi.WindowsDisplay.bpp = ddsd.ddpfPixelFormat.dwRGBBitCount;
- return TRUE;
- }
- /***************************************************************************/
- /* Misc DD Utilities */
- /***************************************************************************/
- //
- // D3DAppIClearBuffers
- // Clear the front and back buffers to black
- //
- BOOL D3DAppIClearBuffers(void)
- {
- DDSURFACEDESC ddsd;
- RECT dst;
- DDBLTFX ddbltfx;
- /*
- * Find the width and height of the front buffer by getting its
- * DDSURFACEDESC
- */
- if (d3dappi.lpFrontBuffer) {
- LastError = D3DAppIGetSurfDesc(&ddsd, d3dappi.lpFrontBuffer);
- if (LastError != DD_OK) {
- D3DAppISetErrorString("Failure getting the surface description of the front buffer before clearing.n%s",
- D3DAppErrorToString(LastError));
- return FALSE;
- }
- /*
- * Clear the front buffer to black
- */
- memset(&ddbltfx, 0, sizeof(ddbltfx));
- ddbltfx.dwSize = sizeof(DDBLTFX);
- SetRect(&dst, 0, 0, ddsd.dwWidth, ddsd.dwHeight);
- LastError = d3dappi.lpFrontBuffer->Blt(&dst, NULL, NULL,
- DDBLT_COLORFILL | DDBLT_WAIT,
- &ddbltfx);
- if (LastError != DD_OK) {
- D3DAppISetErrorString("Clearing the front buffer failed.n%s",
- D3DAppErrorToString(LastError));
- return FALSE;
- }
- }
- if (d3dappi.lpBackBuffer) {
- /*
- * Find the width and height of the back buffer by getting its
- * DDSURFACEDESC
- */
- LastError = D3DAppIGetSurfDesc(&ddsd, d3dappi.lpBackBuffer);
- if (LastError != DD_OK) {
- D3DAppISetErrorString("Failure while getting the surface description of the back buffer before clearing.n%s",
- D3DAppErrorToString(LastError));
- return FALSE;
- }
- /*
- * Clear the back buffer to black
- */
- memset(&ddbltfx, 0, sizeof(ddbltfx));
- ddbltfx.dwSize = sizeof(DDBLTFX);
- SetRect(&dst, 0, 0, ddsd.dwWidth, ddsd.dwHeight);
- LastError = d3dappi.lpBackBuffer->Blt( &dst,NULL, NULL,
- DDBLT_COLORFILL | DDBLT_WAIT,
- &ddbltfx);
- if (LastError != DD_OK) {
- D3DAppISetErrorString("Clearing the front buffer failed.n%s",
- D3DAppErrorToString(LastError));
- return FALSE;
- }
- }
- return TRUE;
- }
- /*
- * D3DAppIBPPToDDBD
- * Convert an integer bit per pixel number to a DirectDraw bit depth flag
- */
- DWORD
- D3DAppIBPPToDDBD(int bpp)
- {
- switch(bpp) {
- case 1:
- return DDBD_1;
- case 2:
- return DDBD_2;
- case 4:
- return DDBD_4;
- case 8:
- return DDBD_8;
- case 16:
- return DDBD_16;
- case 24:
- return DDBD_24;
- case 32:
- return DDBD_32;
- default:
- return (DWORD)D3DAPP_BOGUS;
- }
- }
- /*
- * D3DAppTotalVideoMemory
- * Returns the amount of total video memory supported (not free)
- */
- DWORD
- D3DAppTotalVideoMemory(void)
- {
- DDCAPS DriverCaps, HELCaps;
- memset (&DriverCaps, 0, sizeof(DDCAPS));
- DriverCaps.dwSize = sizeof(DDCAPS);
- memset (&HELCaps, 0, sizeof(DDCAPS));
- HELCaps.dwSize = sizeof(DDCAPS);
- LastError = d3dappi.lpDD->GetCaps( &DriverCaps,&HELCaps);
- if (LastError != DD_OK) {
- D3DAppISetErrorString("Getting DD capabilities failed while checking total video memory.n%s",
- D3DAppErrorToString(LastError));
- return 0L;
- }
- if (DriverCaps.dwVidMemTotal)
- return DriverCaps.dwVidMemTotal;
- else
- return HELCaps.dwVidMemTotal;
- }