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

📄 directdraw.cpp

📁 游戏《家园》源码
💻 CPP
字号:
// Copyright (c) 1998 Relic Entertainment Inc.
// Written by Janik Joire
//
// $History: $

#include <stdio.h>
#include <stdarg.h>
#include <windows.h>
#include <ddraw.h>
#include "directdraw.h"
#include "render.h"

DDCONT *ddInit(HWND hWnd)
{
	DDCONT              *pDdc;
    HRESULT		        hRet;
    DDSURFACEDESC       ddsd;
	LPDIRECTDRAW        pDD;
    LPDIRECTDRAWCLIPPER pClipper;

	pDdc=(DDCONT *)malloc(sizeof(DDCONT));
	if(pDdc == NULL) return(NULL);

    pDdc->hWnd = hWnd;

    // Create the main DirectDraw object
    hRet = DirectDrawCreate( NULL, &pDD, NULL);
    if (hRet != DD_OK)
	{
		free(pDdc);
		return(NULL);
	}

    // Fetch DirectDraw interface
    hRet = pDD->QueryInterface(IID_IDirectDraw, (LPVOID *)&pDdc->pDD);
    if (hRet != DD_OK)
	{
		free(pDdc);
		return(NULL);
	}

    // Get normal windowed mode
    hRet = pDdc->pDD->SetCooperativeLevel(pDdc->hWnd, DDSCL_NORMAL);
    if (hRet != DD_OK)
	{
		free(pDdc);
		return(NULL);
	}

    // Get the dimensions of the viewport and screen bounds
    GetClientRect(pDdc->hWnd, &pDdc->rcViewport);
    GetClientRect(pDdc->hWnd, &pDdc->rcScreen);
    ClientToScreen(pDdc->hWnd, (POINT*)&pDdc->rcScreen.left);
    ClientToScreen(pDdc->hWnd, (POINT*)&pDdc->rcScreen.right);

    // Create the primary surface
    ZeroMemory(&ddsd,sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_CAPS;
    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
    hRet = pDdc->pDD->CreateSurface(&ddsd, &pDdc->pDDSPrimary, NULL);
    if (hRet != DD_OK)
	{
		free(pDdc);
		return(NULL);
	}

    // Create a clipper object since this is for a Windowed render
    hRet = pDdc->pDD->CreateClipper(0, &pClipper, NULL);
    if (hRet != DD_OK)
	{
		free(pDdc);
		return(NULL);
	}

    // Associate the clipper with the window
    pClipper->SetHWnd(0, pDdc->hWnd);
    pDdc->pDDSPrimary->SetClipper(pClipper);
    pClipper->Release();
    pClipper = NULL;

    // Get the backbuffer
    ddsd.dwFlags        = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
    ddsd.dwWidth        = pDdc->rcViewport.right-pDdc->rcViewport.left+1;
    ddsd.dwHeight       = pDdc->rcViewport.bottom-pDdc->rcViewport.top+1;
    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
    hRet = pDdc->pDD->CreateSurface(&ddsd, &pDdc->pDDSBack, NULL);
    if (hRet != DD_OK)
	{
		free(pDdc);
		return(NULL);
	}

    return(pDdc);
}

int ddClean(DDCONT *pDdc)
{
    if (pDdc->pDD != NULL)
    {
        if (pDdc->pDDSBack != NULL)
        {
            pDdc->pDDSBack->Release();
            pDdc->pDDSBack = NULL;
        }
        if (pDdc->pDDSPrimary != NULL)
        {
            pDdc->pDDSPrimary->Release();
            pDdc->pDDSPrimary = NULL;
        }
    }

    // Release the main DDraw interface
    if (pDdc->pDD)
        pDdc->pDD->Release();

	free(pDdc);

	return(OK);
}

int ddUpdate(DDCONT *pDdc,void *pContext)
{
	HDC         hDC;
    HRESULT		hRet;
    DDBLTFX     ddbltfx;

    // Retrieve the window position after a move
    GetClientRect(pDdc->hWnd, &pDdc->rcScreen);
    ClientToScreen(pDdc->hWnd, (POINT*)&pDdc->rcScreen.left);
    ClientToScreen(pDdc->hWnd, (POINT*)&pDdc->rcScreen.right);

    // Use the blter to do a color fill to clear the back buffer
    ddbltfx.dwSize = sizeof(DDBLTFX);
    ddbltfx.dwFillColor = 0;
    pDdc->pDDSBack->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);

    if (pDdc->pDDSBack->GetDC(&hDC) == DD_OK)
    {
		// Draw
		if(rendRendCont((RENDCONT *)pContext,hDC) < 0)
		{
	        pDdc->pDDSBack->ReleaseDC(hDC);
			return(ERR);
		}

        pDdc->pDDSBack->ReleaseDC(hDC);
    }

	hRet = pDdc->pDDSBack->IsLost();
	if (hRet != DD_OK) pDdc->pDDSBack->Restore();

	hRet = pDdc->pDDSPrimary->IsLost();
	if (hRet != DD_OK) pDdc->pDDSPrimary->Restore();
    
	// Perform a blt.
	while(1)
    {
		hRet = pDdc->pDDSPrimary->Blt(&pDdc->rcScreen, pDdc->pDDSBack,
                              &pDdc->rcViewport, DDBLT_WAIT,
                              NULL);
		if (hRet != DDERR_WASSTILLDRAWING ) break;
	}

    return(OK);
}

int ddResize(DDCONT *pDdc)
{
    HRESULT		        hRet;
    DDSURFACEDESC       ddsd;
	DWORD               dwIHeight,dwIWidth,dwFHeight,dwFWidth;

	dwIWidth  = pDdc->rcViewport.right-pDdc->rcViewport.left+1;
	dwIHeight = pDdc->rcViewport.bottom-pDdc->rcViewport.top+1;
    
    // Retrieve the window position after a move
    GetClientRect(pDdc->hWnd, &pDdc->rcViewport);

	dwFWidth  = pDdc->rcViewport.right-pDdc->rcViewport.left+1;
	dwFHeight = pDdc->rcViewport.bottom-pDdc->rcViewport.top+1;

	if((dwIWidth  == dwFWidth) && (dwIHeight == dwFHeight)) return(OK);
    
	if (pDdc->pDDSBack != NULL)
    {
        pDdc->pDDSBack->Release();
        pDdc->pDDSBack = NULL;
    }

    // Get the backbuffer
    ZeroMemory(&ddsd,sizeof(ddsd));
    ddsd.dwSize         = sizeof(ddsd);
    ddsd.dwFlags        = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
    ddsd.dwWidth        = dwFWidth;
    ddsd.dwHeight       = dwFHeight;
    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
    hRet = pDdc->pDD->CreateSurface(&ddsd, &pDdc->pDDSBack, NULL);
    if (hRet != DD_OK) return(ERR);

	return(OK);
}

int ddPaint(DDCONT *pDdc)
{
    HRESULT         hRet;

    // Retrieve the window position after a move
    GetClientRect(pDdc->hWnd, &pDdc->rcScreen);
    ClientToScreen(pDdc->hWnd, (POINT*)&pDdc->rcScreen.left);
    ClientToScreen(pDdc->hWnd, (POINT*)&pDdc->rcScreen.right);

	hRet = pDdc->pDDSBack->IsLost();
	if (hRet != DD_OK) pDdc->pDDSBack->Restore();

	hRet = pDdc->pDDSPrimary->IsLost();
	if (hRet != DD_OK) pDdc->pDDSPrimary->Restore();
    
	// Perform a blt.
	while(1)
    {
		hRet = pDdc->pDDSPrimary->Blt(&pDdc->rcScreen, pDdc->pDDSBack,
                              &pDdc->rcViewport, DDBLT_WAIT,
                              NULL);
		if (hRet != DDERR_WASSTILLDRAWING ) break;
	}

	return(OK);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -