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

📄 cdxapp.cpp

📁 一个Direct3DRM的包装类的例子
💻 CPP
📖 第 1 页 / 共 5 页
字号:
#include "stdcdx.h"
#include <windowsx.h>
#include "CDXApp.h"
#include <stdio.h>
#include <memory.h>
#include <time.h>
#include <stdarg.h>

#ifdef _DEBUG

#define FRAME_INTERVAL  50

static struct
{
    HFONT       hFont;
    SIZE        sizeStats;
    SIZE        sizeInfo;
    DWORD       dwIntervalCount;
    DWORD       dwFrameCount;
    DWORD       dwLastFrames;
    DWORD       dwLastTriangles;
    DWORD       dwTPS;
    float       floatFPS;
    time_t      timeLast;
    BOOL        bValid;
} gStats;

#endif      //_DEBUG

static BOOL     bHardware=FALSE;
static BOOL     bMono=FALSE;

extern LONG FAR PASCAL CDXWindowProc( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam );

static DWORD BPPToDDBD( int nBitsPerPixel )
{
    switch( nBitsPerPixel )
    {
        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 );
    }

    return( 0 );
}

static HRESULT WINAPI enumDeviceFunc( LPGUID lpGUID,LPSTR lpDeviceDesc,LPSTR lpDeviceName,LPD3DDEVICEDESC lpHWDesc,LPD3DDEVICEDESC lpHELDesc,LPVOID lpContext )
{
    LPD3DDEVICEDESC         lpDesc;
    int                     *lpStartDriver=(int *)lpContext;
    BOOL                    bFirstTime=(*lpStartDriver==-1);

    /*  Decide which device description should be used  */

    lpDesc = lpHWDesc->dcmColorModel ? lpHWDesc : lpHELDesc;

    /*  If this driver cannot support the required bit depth trivially reject it  */

    if ( !(lpDesc->dwDeviceRenderBitDepth&BPPToDDBD(pApp->GetBitDepth())) )
    {
        return( D3DENUMRET_OK );
    }

    /*  Record this driver's name and GUID  */

    pApp->AddEnumDevice( lpGUID,lpDeviceName );

    /*  Choose hardware over software and RGB over mono lights  */

    if ( bFirstTime )
    {
        /*  Initialise our determinant variables  */

        *lpStartDriver  = pApp->GetNumDrivers() - 1;
        bHardware       = (lpDesc==lpHWDesc);
        bMono           = (lpDesc->dcmColorModel&D3DCOLOR_MONO)?TRUE:FALSE;
    }
    else if ( lpDesc==lpHWDesc && (!bHardware || lpDesc->dcmColorModel==pApp->GetPreferedColorModel()))
    {
        /*  Choose this hardware driver  */

        *lpStartDriver  = pApp->GetNumDrivers() - 1;
        bHardware       = (lpDesc==lpHWDesc);
        bMono           = (lpDesc->dcmColorModel&D3DCOLOR_MONO)?TRUE:FALSE;
    }
    else if ( (lpDesc==lpHWDesc && bHardware) || (lpDesc==lpHELDesc && !bHardware) )
    {
        /*  Both the current and this device are the same (hardware/software).  */
        /*  Choose this one if the lights are not mono and we have an MMX       */

        if ( (lpDesc->dcmColorModel==pApp->GetPreferedColorModel() && !bHardware) || (bMono && pApp->IsMMX() && lpDesc->dcmColorModel&D3DCOLOR_RGB) )
        {
            *lpStartDriver  = pApp->GetNumDrivers() - 1;
            bHardware       = (lpDesc==lpHWDesc);
            bMono           = (lpDesc->dcmColorModel&D3DCOLOR_MONO)?TRUE:FALSE;
        }
    }

    /*  Don't enumerate more than allowed  */

    if ( pApp->GetNumDrivers() >= MAX_DRIVERS ) return( D3DENUMRET_CANCEL );

    return( D3DENUMRET_OK );
}

typedef HRESULT (WINAPI *DIRECTDRAWCREATE)(GUID *, LPDIRECTDRAW *, IUnknown *);
typedef HRESULT (WINAPI *DIRECTINPUTCREATE)(HINSTANCE, DWORD, LPDIRECTINPUT *, IUnknown *);

static void GetDXVersion(LPDWORD pdwDXVersion, LPDWORD pdwDXPlatform)
{
    HRESULT		            hr;
    HINSTANCE		        DDHinst = 0;
    HINSTANCE		        DIHinst = 0;
    LPDIRECTDRAW	        pDDraw = 0;
    LPDIRECTDRAW2	        pDDraw2 = 0;
    DIRECTDRAWCREATE	    DirectDrawCreate = 0;
    DIRECTINPUTCREATE	    DirectInputCreate = 0;
    OSVERSIONINFO	        osVer;
    LPDIRECTDRAWSURFACE	    pSurf = 0;
    LPDIRECTDRAWSURFACE3    pSurf3 = 0;

    /*
     * First get the windows platform
     */
    osVer.dwOSVersionInfoSize = sizeof(osVer);
    if (!GetVersionEx(&osVer))
    {
    	*pdwDXVersion = 0;
	    *pdwDXPlatform = 0;
    	return;
    }

    if (osVer.dwPlatformId == VER_PLATFORM_WIN32_NT)
    {
	    *pdwDXPlatform = VER_PLATFORM_WIN32_NT;
    	/*
	     * NT is easy... NT 4.0 is DX2, 4.0 SP3 is DX3, 5.0 is DX5
    	 * and no DX on earlier versions.
	     */
    	if (osVer.dwMajorVersion < 4)
	    {
	        *pdwDXPlatform = 0;	//No DX on NT3.51 or earlier
    	    return;
	    }
    	if (osVer.dwMajorVersion == 4)
	    {
	        /*
    	     * NT4 up to SP2 is DX2, and SP3 onwards is DX3, so we are at least DX2
	         */

	        *pdwDXVersion = 0x200;

            /*
             * We're not supposed to be able to tell which SP we're on, so check for dinput
             */

            DIHinst = LoadLibrary("DINPUT.DLL");
            if (DIHinst == 0)
            {
                /*
                 * No DInput... must be DX2 on NT 4 pre-SP3
                 */
                pApp->ErrHandler( "GetDXVersion() Couldn't LoadLibrary DInput");
	            return;
            }

            DirectInputCreate = (DIRECTINPUTCREATE)GetProcAddress(DIHinst, "DirectInputCreateA");
            FreeLibrary(DIHinst);

            if (DirectInputCreate == 0)
            {
                /*
                 * No DInput... must be pre-SP3 DX2
                 */
                pApp->ErrHandler( "GetDXVersion() Couldn't GetProcAddress DInputCreate" );
    	        return;
            }

	        /*
	         * It must be NT4, DX2
    	     */
	        *pdwDXVersion = 0x300; //DX3 on NT4 SP3 or higher
	        return;
    	}

	    /*
    	 * Else it's NT5 or higher, and it's DX5a or higher:
	     */

    	*pdwDXVersion = 0x501; //DX5a on NT5
	    return;
    }

    /*
     * Not NT... must be Win9x
     */

    *pdwDXPlatform = VER_PLATFORM_WIN32_WINDOWS;

    /*
     * If we are on Memphis or higher, then we are at least DX5a
     */

    if ( (osVer.dwBuildNumber & 0xffff) > 1353) //Check for higher than developer release
    {
	    *pdwDXVersion = 0x501; //DX5a on Memphis or higher
    	return;
    }

    /*
     * Now we know we are in Windows 9x (or maybe 3.1), so anything's possible.
     * First see if DDRAW.DLL even exists.
     */

    DDHinst = LoadLibrary("DDRAW.DLL");
    if (DDHinst == 0)
    {
	    *pdwDXVersion = 0;
    	*pdwDXPlatform = 0;
	    FreeLibrary(DDHinst);
    	return;
    }

    /*
     *  See if we can create the DirectDraw object.
     */
    DirectDrawCreate = (DIRECTDRAWCREATE)GetProcAddress(DDHinst, "DirectDrawCreate");
    if (DirectDrawCreate == 0)
    {
    	*pdwDXVersion = 0;
	    *pdwDXPlatform = 0;
    	FreeLibrary(DDHinst);
        pApp->ErrHandler( "GetDXVersion() Couldn't LoadLibrary DDraw" );
    	return;
    }

    hr = DirectDrawCreate(NULL, &pDDraw, NULL);

    if (FAILED(hr))
    {
	    *pdwDXVersion = 0;
    	*pdwDXPlatform = 0;
	    FreeLibrary(DDHinst);
        pApp->ErrHandler("GetDXVersion() Couldn't create DDraw");
    	return;
    }

    /*
     *  So DirectDraw exists.  We are at least DX1.
     */

    *pdwDXVersion = 0x100;

    /*
     *  Let's see if IID_IDirectDraw2 exists.
     */

    hr = pDDraw->QueryInterface(IID_IDirectDraw2, (LPVOID *)&pDDraw2);
    if (FAILED(hr))
    {
	    /*
    	 * No IDirectDraw2 exists... must be DX1
    	 */
	    pDDraw->Release();
    	FreeLibrary(DDHinst);
        pApp->ErrHandler("GetDXVersion() Couldn't QI DDraw2");
    	return;
    }

    /*
     * IDirectDraw2 exists. We must be at least DX2
     */

    pDDraw2->Release();
    *pdwDXVersion = 0x200;

    /*
     *  See if we can create the DirectInput object.
     */

    DIHinst = LoadLibrary("DINPUT.DLL");
    if (DIHinst == 0)
    {
        /*
         * No DInput... must be DX2
         */
        pApp->ErrHandler("GetDXVersion() Couldn't LoadLibrary DInput");
    	pDDraw->Release();
	    FreeLibrary(DDHinst);
    	return;
    }

    DirectInputCreate = (DIRECTINPUTCREATE)GetProcAddress(DIHinst, "DirectInputCreateA");
    FreeLibrary(DIHinst);

    if (DirectInputCreate == 0)
    {
        /*
         * No DInput... must be DX2
         */
    	FreeLibrary(DDHinst);
	    pDDraw->Release();
        pApp->ErrHandler("GetDXVersion() Couldn't GetProcAddress DInputCreate");
    	return;
    }

    /*
     * DirectInputCreate exists. That's enough to tell us that we are at least DX3
     */

    *pdwDXVersion = 0x300;

    /*
     * Checks for 3a vs 3b?
     */

    /*
     * We can tell if DX5 is present by checking for the existence of IDirectDrawSurface3.
     * First we need a surface to QI off of.
     */

    DDSURFACEDESC desc;

    ZeroMemory(&desc, sizeof(desc));
    desc.dwSize = sizeof(desc);
    desc.dwFlags = DDSD_CAPS;
    desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

    hr = pDDraw->SetCooperativeLevel(NULL,DDSCL_NORMAL);
    if (FAILED(hr))
    {
	    /*
    	 * Failure. This means DDraw isn't properly installed.
	     */
    	pDDraw->Release();
	    FreeLibrary(DDHinst);
    	*pdwDXVersion = 0;
        pApp->ErrHandler("GetDXVersion() Couldn't Set coop level");
    	return;
    }

    hr = pDDraw->CreateSurface(&desc, &pSurf, NULL);
    if (FAILED(hr))
    {
    	/*
	     * Failure. This means DDraw isn't properly installed.
    	 */
	    pDDraw->Release();
    	FreeLibrary(DDHinst);
	    *pdwDXVersion = 0;
        pApp->ErrHandler("GetDXVersion() Couldn't CreateSurface");
    	return;
    }

    /*
     * Try for the IDirectDrawSurface3 interface. If it works, we're on DX5 at least
     */

    if ( FAILED(pSurf->QueryInterface(IID_IDirectDrawSurface3,(LPVOID*)&pSurf3)) )
    {
        pDDraw->Release();
        FreeLibrary(DDHinst);

        return;
    }

    /*
     * QI for IDirectDrawSurface3 succeeded. We must be at least DX5

⌨️ 快捷键说明

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