⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ddcalls.c

📁 国外游戏开发者杂志1997年第九期配套代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	    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 + -