D3DAPP.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:47k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*
  2.  *  Copyright (C) 1995, 1996 Microsoft Corporation. All Rights Reserved.
  3.  *
  4.  *  File: d3dapp.c
  5.  *
  6.  *  Top level D3DApp functions and internal global variables.  See
  7.  *  d3dapp.h for more information.
  8.  *
  9.  *  D3DApp is a collection of helper functions for Direct3D applications.
  10.  *  D3DApp consists of the following files:
  11.  * d3dapp.h    Main D3DApp header to be included by application
  12.  *      d3dappi.h   Internal header
  13.  *      d3dapp.c    D3DApp functions seen by application.
  14.  *      ddcalls.c   All calls to DirectDraw objects except textures
  15.  *      d3dcalls.c  All calls to Direct3D objects except textures
  16.  *      texture.c   Texture loading and managing texture list
  17.  *      misc.c     Miscellaneous calls
  18.  */
  19. #include "d3dappi.h"
  20. #define INITGUID
  21. /***************************************************************************/
  22. /*                           GLOBAL VARIABLES                              */
  23. /***************************************************************************/
  24. /*
  25.  * All DD and D3D objects which are also available to the application
  26.  * See d3dapp.h for typedef
  27.  */
  28. D3DAppInfo d3dappi;
  29. /*
  30.  * Internal record of the render state.  See d3dapp.h for typedef
  31.  */
  32. D3DAppRenderState d3dapprs; 
  33. /* 
  34.  * Callback functions for D3D device creation and destruction
  35.  */
  36. BOOL(*D3DDeviceDestroyCallback)(LPVOID);
  37. LPVOID D3DDeviceDestroyCallbackContext;
  38. BOOL(*D3DDeviceCreateCallback)(int, int, LPDIRECT3DVIEWPORT2*, LPVOID);
  39. LPVOID D3DDeviceCreateCallbackContext;
  40. /*
  41.  * The last error code and string
  42.  */
  43. HRESULT LastError;
  44. char LastErrorString[256];
  45. /*
  46.  * List of dirty rectangles on back buffer and client area
  47.  */
  48. int NumDirtyClientRects, NumDirtyBackRects, NumDirtyZRects;
  49. D3DRECT DirtyClient[D3DAPP_MAXCLEARRECTS];
  50. D3DRECT DirtyBack[D3DAPP_MAXCLEARRECTS];
  51. D3DRECT DirtyZ[D3DAPP_MAXCLEARRECTS];
  52. /*
  53.  * List of texture handles which is copied to D3DAppInfo structure when
  54.  * necessary
  55.  */
  56. D3DTEXTUREHANDLE MasterTextureHandle[D3DAPP_MAXTEXTURES];
  57. LPDIRECTDRAWCLIPPER lpClipper; /* Clipper in windowed case */
  58. LPDIRECTDRAWPALETTE lpPalette; /* Front buffer's palette */
  59. PALETTEENTRY ppe[256];         /* Current palette entries */
  60. PALETTEENTRY Originalppe[256]; /* Windows palette entries at startup */
  61. BOOL bD3DAppInitialized;       /* Is D3DApp initialized? */
  62. BOOL bPrimaryPalettized;       /* Is the front buffer palettized? */
  63. BOOL bPaletteActivate;        /* Is the front buffer's palette valid? */
  64. BOOL bIgnoreWM_SIZE;        /* Ignore this WM_SIZE messages */
  65. SIZE szLastClient;        /* Dimensions of the last window */
  66. SIZE szBuffers;        /* Current buffer dimensions, not necessarily
  67.   the same as the client window */
  68. int CallbackRefCount;        /* How many times DeviceCreateCallback has
  69.   been called in a row */
  70. /***************************************************************************/
  71. /*                               FUNCTIONS                                 */
  72. /***************************************************************************/
  73. /*
  74.  * D3DAppCreateFromHWND
  75.  */
  76. BOOL D3DAppCreateFromHWND(DWORD flags, HWND hwnd,
  77.   BOOL(*DeviceCreateCallback)(int, int,
  78.       LPDIRECT3DVIEWPORT2*,
  79.       LPVOID),
  80.   LPVOID lpCreateContext,
  81.   BOOL(*DeviceDestroyCallback)(LPVOID),
  82.   LPVOID lpDestroyContext,
  83.   D3DAppInfo** D3DApp)
  84. {
  85.     int driver, mode, w, h;
  86.     /* 
  87.      * Clean the global varaibles and check the flags
  88.      */
  89.     D3DAppISetDefaults();
  90.     if (flags & D3DAPP_ONLYSYSTEMMEMORY) {
  91. d3dappi.bOnlySystemMemory = TRUE;
  92. d3dappi.bOnlyEmulation = TRUE;
  93.     }
  94.     if (flags & D3DAPP_ONLYD3DEMULATION)
  95. d3dappi.bOnlyEmulation = TRUE;
  96.     /* 
  97.      * Create DirectDraw, remember the Windows display mode and enumerate the
  98.      * display modes
  99.      */
  100.     ATTEMPT(D3DAppICreateDD(d3dappi.bOnlyEmulation ?
  101.     D3DAPP_ONLYDDEMULATION : 0L));
  102.     ATTEMPT(D3DAppIRememberWindowsMode());
  103.     ATTEMPT(D3DAppIEnumDisplayModes());
  104.     /*
  105.      * Create Direct3D and enumerate the D3D drivers
  106.      */
  107.     ATTEMPT(D3DAppICreateD3D());
  108.     ATTEMPT(D3DAppIEnumDevices());
  109.     /*
  110.      * Set the device creation and destroy callback functions
  111.      */
  112.     D3DDeviceDestroyCallback = DeviceDestroyCallback;
  113.     D3DDeviceDestroyCallbackContext = lpDestroyContext;
  114.     D3DDeviceCreateCallback = DeviceCreateCallback;
  115.     D3DDeviceCreateCallbackContext = lpCreateContext;
  116.     *D3DApp = &d3dappi;
  117.     d3dappi.hwnd = hwnd;
  118.     /*
  119.      * Choose a driver and display mode.  Using the current window is 
  120.      * prefered, but a fullscreen mode may be selected.  Set the cooperative
  121.      * level and create the front and back buffers for this mode.
  122.      */
  123.     driver = D3DAPP_YOUDECIDE;
  124.     mode = D3DAPP_YOUDECIDE;
  125.     ATTEMPT(D3DAppIVerifyDriverAndMode(&driver, &mode));
  126.     D3DAppIGetClientWin(hwnd);
  127.     if (mode == D3DAPP_USEWINDOW) {
  128. w = d3dappi.szClient.cx;
  129. h = d3dappi.szClient.cy;
  130. ATTEMPT(D3DAppISetCoopLevel(hwnd, FALSE));
  131. ATTEMPT(D3DAppICreateBuffers(hwnd, w, h, D3DAPP_BOGUS, FALSE,
  132.      d3dappi.Driver[driver].bIsHardware));
  133. /*
  134.  * Change the currently selected mode if it's not compatible with
  135.  * this driver.  Just to make sure that CurrMode is always a mode the
  136.  * current driver can do.
  137.  */
  138. if (!(d3dappi.Driver[driver].Desc.dwDeviceRenderBitDepth &
  139.       D3DAppIBPPToDDBD(d3dappi.Mode[d3dappi.CurrMode].bpp))){
  140.     ATTEMPT(D3DAppIPickDisplayMode(&d3dappi.CurrMode,
  141.         d3dappi.Driver[driver].Desc.dwDeviceRenderBitDepth));
  142. }
  143.     } else {
  144. szLastClient = d3dappi.szClient;
  145. w = d3dappi.Mode[mode].w;
  146. h = d3dappi.Mode[mode].h;
  147. d3dappi.szClient.cx = w; d3dappi.szClient.cy = h;
  148. ATTEMPT(D3DAppISetCoopLevel(hwnd, TRUE));
  149. ATTEMPT(D3DAppISetDisplayMode(w, h, d3dappi.Mode[mode].bpp));
  150. d3dappi.CurrMode = mode;
  151. ATTEMPT(D3DAppICreateBuffers(hwnd, w, h, d3dappi.Mode[mode].bpp, TRUE,
  152.      d3dappi.Driver[driver].bIsHardware));
  153.     }
  154.     /*
  155.      * If the front buffer is palettized, initialize its palette
  156.      */
  157.     ATTEMPT(D3DAppICheckForPalettized());
  158.     /*
  159.      * Create the Z-buffer
  160.      */
  161.     ATTEMPT(D3DAppICreateZBuffer(w, h, driver));
  162.     /*
  163.      * Create the D3D device, load the textures, call the device create
  164.      * callback and set a default render state
  165.      */
  166.     ATTEMPT(D3DAppICreateDevice(driver));
  167.     ATTEMPT(D3DAppILoadAllTextures());
  168.     ATTEMPT(D3DAppIFilterDisplayModes(driver));  /* bThisDriverCanDo flags */
  169.     ATTEMPT(D3DAppICallDeviceCreateCallback(w, h));
  170.     ATTEMPT(D3DAppISetRenderState());
  171.     /* 
  172.      * Initialize dirty rectangle information
  173.      */
  174.     D3DAppIValidateDirtyRects();
  175.     /*
  176.      * Ready to render
  177.      */
  178.     bD3DAppInitialized = TRUE;
  179.     d3dappi.bRenderingIsOK = TRUE;
  180.     return TRUE;
  181. exit_with_error:
  182.     D3DAppICallDeviceDestroyCallback();
  183.     RELEASE(d3dappi.lpD3DDevice);
  184.     RELEASE(d3dappi.lpZBuffer);
  185.     RELEASE(lpPalette);
  186.     RELEASE(lpClipper);
  187.     RELEASE(d3dappi.lpBackBuffer);
  188.     RELEASE(d3dappi.lpFrontBuffer);
  189.     if (d3dappi.bFullscreen) {
  190. D3DAppIRestoreDispMode();
  191. D3DAppISetCoopLevel(hwnd, FALSE);
  192.     }
  193.     RELEASE(d3dappi.lpD3D);
  194.     RELEASE(d3dappi.lpDD);
  195.     return FALSE;
  196. }   
  197. /*
  198.  * D3DAppFullscreen
  199.  */
  200. BOOL D3DAppFullscreen(int mode)
  201. {
  202.     int w, h, bpp;
  203.     BOOL b; /* was already in a fullscreen mode? */
  204.     d3dappi.bRenderingIsOK = FALSE;
  205.     /* 
  206.      * Make sure this is a valid request, otherwise doctor mode so it will
  207.      * work with this driver.
  208.      */
  209.     ATTEMPT(D3DAppIVerifyDriverAndMode(&d3dappi.CurrDriver, &mode));
  210.     /* 
  211.      * Release everything
  212.      */
  213.     ATTEMPT(D3DAppICallDeviceDestroyCallback());
  214.     if (d3dappi.bFullscreen) {
  215. ATTEMPT(D3DAppIClearBuffers());
  216.     }
  217.     D3DAppIReleaseAllTextures();
  218.     RELEASE(d3dappi.lpD3DDevice);
  219.     RELEASE(d3dappi.lpZBuffer);
  220.     RELEASE(lpPalette);
  221.     RELEASE(lpClipper);
  222.     RELEASE(d3dappi.lpBackBuffer);
  223.     RELEASE(d3dappi.lpFrontBuffer);
  224.     /*
  225.      * Record information about the current status
  226.      */
  227.     b = d3dappi.bFullscreen;
  228.     w = d3dappi.Mode[mode].w;
  229.     h = d3dappi.Mode[mode].h;
  230.     bpp = d3dappi.Mode[mode].bpp;
  231.     if (!b) {
  232. /*
  233.  * If this is not a fullscreen mode, we'll need to record the window
  234.  * size for when we return to it.
  235.  */
  236. szLastClient = d3dappi.szClient;
  237.     }
  238.     /*
  239.      * Set the cooperative level and create front and back buffers
  240.      */
  241.     d3dappi.szClient.cx = w; d3dappi.szClient.cy = h;
  242.     ATTEMPT(D3DAppISetCoopLevel(d3dappi.hwnd, TRUE));
  243.     ATTEMPT(D3DAppISetDisplayMode(w, h, bpp));
  244.     d3dappi.CurrMode = mode;
  245.     ATTEMPT(D3DAppICreateBuffers(d3dappi.hwnd, w, h, bpp, TRUE,
  246.  d3dappi.Driver[d3dappi.CurrDriver].bIsHardware));
  247.     /*
  248.      * If the front buffer is palettized, initialize its palette
  249.      */
  250.     ATTEMPT(D3DAppICheckForPalettized());
  251.     /*
  252.      * Create the Z-buffer
  253.      */
  254.     ATTEMPT(D3DAppICreateZBuffer(w, h, d3dappi.CurrDriver));
  255.     /*
  256.      * Create the D3D device, load the textures, call the device create
  257.      * callback and set a default render state
  258.      */
  259.     ATTEMPT(D3DAppICreateDevice(d3dappi.CurrDriver));
  260.     ATTEMPT(D3DAppILoadAllTextures());
  261.     ATTEMPT(D3DAppICallDeviceCreateCallback(w, h));
  262.     ATTEMPT(D3DAppISetRenderState());
  263.     /* 
  264.      * Set current mode and clear dirty rectangle information
  265.      */
  266.     d3dappi.CurrMode = mode;
  267.     D3DAppIValidateDirtyRects();
  268.     d3dappi.bRenderingIsOK = TRUE;
  269.     return TRUE;
  270. exit_with_error:
  271.     D3DAppICallDeviceDestroyCallback();
  272.     RELEASE(d3dappi.lpD3DDevice);
  273.     RELEASE(d3dappi.lpZBuffer);
  274.     RELEASE(lpPalette);
  275.     RELEASE(lpClipper);
  276.     RELEASE(d3dappi.lpBackBuffer);
  277.     RELEASE(d3dappi.lpFrontBuffer);
  278.     if (!b) {
  279. D3DAppIRestoreDispMode();
  280. D3DAppISetCoopLevel(d3dappi.hwnd, FALSE);
  281.     }
  282.     return FALSE;
  283. }
  284. /*
  285.  * D3DAppWindow
  286.  */
  287. BOOL
  288. D3DAppWindow(int w, int h)
  289. {
  290.     BOOL b; /* changing from a fullscreen mode? */
  291.     if (!d3dappi.bIsPrimary) {
  292. D3DAppISetErrorString("It is not possible to create a D3D window with a hardware DirectDraw device.  Check the bIsPrimary flag before calling D3DAppWindow.");
  293. return FALSE;
  294.     }
  295.     b = d3dappi.bFullscreen;
  296.     /*
  297.      * If asked to set the window size, return it to the last value or use
  298.      * a default value.
  299.      */
  300.     if (w == D3DAPP_YOUDECIDE) {
  301. w = b ? szLastClient.cx : D3DAPP_DEFAULTWINDOWDIM;
  302.     }
  303.     if (h == D3DAPP_YOUDECIDE) {
  304. h = b ? szLastClient.cy : D3DAPP_DEFAULTWINDOWDIM;
  305.     }
  306.     /*
  307.      * Release everything
  308.      */
  309.     d3dappi.bRenderingIsOK = FALSE;
  310.     ATTEMPT(D3DAppICallDeviceDestroyCallback());
  311.     if (b) {
  312. ATTEMPT(D3DAppIClearBuffers());
  313.     }
  314.     D3DAppIReleaseAllTextures();
  315.     RELEASE(d3dappi.lpD3DDevice);
  316.     RELEASE(d3dappi.lpZBuffer);
  317.     RELEASE(lpPalette);
  318.     RELEASE(lpClipper);
  319.     RELEASE(d3dappi.lpBackBuffer);
  320.     RELEASE(d3dappi.lpFrontBuffer);
  321.     /* 
  322.      * Restore the display mode if we were in a fullscreen mode
  323.      */
  324.     if (b) {
  325. D3DAppIRestoreDispMode();
  326.     }
  327.     /* 
  328.      * Set the cooperative level and create front and back buffers
  329.      */
  330.     D3DAppISetCoopLevel(d3dappi.hwnd, FALSE);
  331.     D3DAppISetClientSize(d3dappi.hwnd, w, h, b);
  332.     ATTEMPT(D3DAppICreateBuffers(d3dappi.hwnd, w, h, D3DAPP_BOGUS, FALSE,
  333.  d3dappi.Driver[d3dappi.CurrDriver].bIsHardware));
  334.     /*
  335.      * If the front buffer is palettized, initialize its palette
  336.      */
  337.     ATTEMPT(D3DAppICheckForPalettized());
  338.     /*
  339.      * Create the Z-buffer
  340.      */
  341.     ATTEMPT(D3DAppICreateZBuffer(szBuffers.cx, szBuffers.cy,
  342.  d3dappi.CurrDriver));
  343.     /*
  344.      * Create the D3D device, load the textures, call the device create
  345.      * callback and set a default render state
  346.      */
  347.     ATTEMPT(D3DAppICreateDevice(d3dappi.CurrDriver));
  348.     ATTEMPT(D3DAppILoadAllTextures());
  349.     ATTEMPT(D3DAppICallDeviceCreateCallback(szBuffers.cx, szBuffers.cy));
  350.     ATTEMPT(D3DAppISetRenderState());
  351.     /* 
  352.      * Clear dirty rectangle information
  353.      */
  354.     D3DAppIValidateDirtyRects();
  355.     d3dappi.bRenderingIsOK = TRUE;
  356.     return TRUE;
  357. exit_with_error:
  358.     D3DAppICallDeviceDestroyCallback();
  359.     RELEASE(d3dappi.lpD3DDevice);
  360.     RELEASE(d3dappi.lpZBuffer);
  361.     RELEASE(lpPalette);
  362.     RELEASE(lpClipper);
  363.     RELEASE(d3dappi.lpBackBuffer);
  364.     RELEASE(d3dappi.lpFrontBuffer);
  365.     return FALSE;  
  366. }
  367. /*
  368.  * D3DAppChangeDriver 
  369.  */
  370. BOOL
  371. D3DAppChangeDriver(int driver, DWORD flags)
  372. {
  373.     int mode;
  374.     /*
  375.      * Verify the compatibility of this mode with the specified driver.
  376.      * The mode may change.
  377.      */
  378.     if (d3dappi.bFullscreen)
  379. mode = d3dappi.CurrMode;
  380.     else
  381. mode = D3DAPP_USEWINDOW;
  382.     ATTEMPT(D3DAppIVerifyDriverAndMode(&driver, &mode));
  383.     if (driver == D3DAPP_BOGUS || mode == D3DAPP_BOGUS)
  384. goto exit_with_error;
  385.     /*
  386.      * Update the current driver and set bThisDriverCanDo flags
  387.      */
  388.     d3dappi.CurrDriver = driver;
  389.     ATTEMPT(D3DAppIFilterDisplayModes(driver));
  390.     /*
  391.      * Either call D3DAppWindow or D3DAppFullscreen depending on mode
  392.      */
  393.     if (mode == D3DAPP_USEWINDOW) {
  394. if (d3dappi.bFullscreen) {
  395.     /*
  396.      * We need to switch to a window.  D3DApp will either use the
  397.      * size of the last window it saw or use a default size.
  398.      */
  399.     ATTEMPT(D3DAppWindow(D3DAPP_YOUDECIDE, D3DAPP_YOUDECIDE));
  400. } else {
  401.     /*
  402.      * We need to recreate the current window.  Don't let D3DApp
  403.      * decide on the size.
  404.      */
  405.     ATTEMPT(D3DAppWindow(d3dappi.szClient.cx, d3dappi.szClient.cy));
  406. }
  407. /*
  408.  * Change the currently selected mode if it's not compatible with
  409.  * this driver.  Just to make sure that CurrMode is always a mode the
  410.  * current driver can do.
  411.  */
  412. if (!(d3dappi.Driver[driver].Desc.dwDeviceRenderBitDepth &
  413.       D3DAppIBPPToDDBD(d3dappi.Mode[d3dappi.CurrMode].bpp))){
  414.     ATTEMPT(D3DAppIPickDisplayMode(&d3dappi.CurrMode,
  415.         d3dappi.Driver[driver].Desc.dwDeviceRenderBitDepth));
  416. }
  417. return TRUE;
  418.     } else {
  419. /*
  420.  * We need to switch to fullscreen or switch fullscreen modes or stay
  421.  * in the same fullscreen mode.  In any of these cases, we call the
  422.  * same function.
  423.  */
  424. ATTEMPT(D3DAppFullscreen(mode));
  425. return TRUE;
  426.     }
  427. exit_with_error:
  428.     /*
  429.      * The failed mode setting call would have released everything
  430.      */
  431.     return FALSE;
  432. }
  433. /*
  434.  * D3DAppWindowProc
  435.  */
  436. BOOL
  437. D3DAppWindowProc(BOOL* bStopProcessing, LRESULT* lresult, HWND hwnd,
  438.  UINT message, WPARAM wParam, LPARAM lParam)
  439. {
  440.     PAINTSTRUCT ps;
  441.     *bStopProcessing = FALSE;
  442.     if (!bD3DAppInitialized)
  443. return TRUE;
  444.     /*
  445.      * Look for messages which effect rendering.  In some cases, we will not
  446.      * want the app to continue processing the message, so set the flag and
  447.      * provide a return value in lresult.
  448.      */
  449.     switch(message) {
  450. case WM_SIZE:
  451.     if (!bIgnoreWM_SIZE) {
  452. /*
  453.  * Too long to fit here, see ddcalls.c. Updates the buffers
  454.  * and re-creates the device.
  455.  */
  456. ATTEMPT(D3DAppIHandleWM_SIZE(lresult, d3dappi.hwnd, message,
  457.      wParam, lParam));
  458. *bStopProcessing = TRUE;
  459.     }
  460.     break;
  461. case WM_MOVE:
  462.     /*
  463.      * Update client window position information
  464.      */
  465.     d3dappi.pClientOnPrimary.x = d3dappi.pClientOnPrimary.y = 0;
  466.     ClientToScreen(hwnd, &d3dappi.pClientOnPrimary);
  467.     break;
  468. case WM_ACTIVATE:
  469.     /*
  470.      * Set the front buffer's palette
  471.      */
  472.     if (bPaletteActivate && bPrimaryPalettized &&
  473. d3dappi.lpFrontBuffer) {
  474. d3dappi.lpFrontBuffer->lpVtbl->SetPalette(d3dappi.lpFrontBuffer,
  475.   lpPalette);
  476.     }
  477.     break;
  478.         case WM_ACTIVATEAPP:
  479.             d3dappi.bAppActive = (BOOL)wParam;
  480.             break;
  481.         case WM_SETCURSOR:
  482.     /*
  483.      * Prevent the cursor from being shown in fullscreen
  484.      */
  485.             if (d3dappi.bFullscreen && !d3dappi.bPaused) {
  486.                 SetCursor(NULL);
  487.                 *lresult = 1;
  488. *bStopProcessing = TRUE;
  489. return TRUE;
  490.             }
  491.             break;
  492. case WM_MOVING:
  493.     /*
  494.      * Prevent the window from moving in fullscreen
  495.      */
  496.     if (d3dappi.bFullscreen) {
  497. GetWindowRect(hwnd, (LPRECT)lParam);
  498.                 *lresult = 1;
  499. *bStopProcessing = TRUE;
  500. return TRUE;
  501.     }
  502.     break;
  503. case WM_GETMINMAXINFO:
  504.     /*
  505.      * Ensure the window won't resize in fullscreen
  506.      */
  507.     if (d3dappi.bFullscreen) {
  508. ((LPMINMAXINFO)lParam)->ptMaxTrackSize.x= d3dappi.ThisMode.w;
  509. ((LPMINMAXINFO)lParam)->ptMaxTrackSize.y= d3dappi.ThisMode.h;
  510. ((LPMINMAXINFO)lParam)->ptMinTrackSize.x= d3dappi.ThisMode.w;
  511. ((LPMINMAXINFO)lParam)->ptMinTrackSize.y= d3dappi.ThisMode.h;
  512.                 *lresult = 0;
  513. *bStopProcessing = TRUE;
  514. return TRUE;
  515.     } else {
  516. ((LPMINMAXINFO)lParam)->ptMaxTrackSize.x =
  517.     d3dappi.WindowsDisplay.w;
  518. ((LPMINMAXINFO)lParam)->ptMaxTrackSize.y =
  519.     d3dappi.WindowsDisplay.h;
  520.                 *lresult = 0;
  521. *bStopProcessing = TRUE;
  522. return TRUE;
  523.     }
  524.     break;
  525. case WM_PAINT:
  526.     /*
  527.      * Clear the rectangle and blt the backbuffer image
  528.      */
  529.     BeginPaint(hwnd, &ps);
  530.     if (d3dappi.bRenderingIsOK && !d3dappi.bFullscreen) {
  531. D3DAppShowBackBuffer(D3DAPP_SHOWALL);
  532.     }
  533.     D3DAppIValidateDirtyRects();
  534.     EndPaint(hwnd, &ps);
  535.     *lresult = 1;
  536.     *bStopProcessing = TRUE;
  537.     return TRUE;
  538. case WM_NCPAINT:
  539.     /*
  540.      * When in fullscreen mode, don't draw the window frame.
  541.      */
  542.     if (d3dappi.bFullscreen && !d3dappi.bPaused) {
  543. *lresult = 0;
  544. *bStopProcessing = TRUE;
  545. return TRUE;
  546.     }
  547.     break;
  548.     }
  549.     return TRUE;
  550. exit_with_error:
  551.     return FALSE;
  552. }
  553. /*
  554.  * D3DAppAddTexture 
  555.  */
  556. BOOL
  557. D3DAppAddTexture(const char* imagefile)
  558. {
  559.     if (d3dappi.NumTextures == D3DAPP_MAXTEXTURES - 1) {
  560. D3DAppISetErrorString("Can only load %i textures.", D3DAPP_MAXTEXTURES);
  561. return FALSE;
  562.     }
  563.     lstrcpy(d3dappi.ImageFile[d3dappi.NumTextures], imagefile);
  564.     /*
  565.      * If this driver does texture mapping, load the texture.
  566.      * This test also tests that a device has been created.
  567.      */
  568.     if (d3dappi.ThisDriver.bDoesTextures && d3dappi.NumUsableTextures == d3dappi.NumTextures) {
  569. BOOL bInVideo;
  570. ATTEMPT(D3DAppILoadTextureSurf(d3dappi.NumTextures, &bInVideo));
  571. if (!bInVideo && d3dappi.ThisDriver.bIsHardware) {
  572.     D3DAppIReleaseTexture(d3dappi.NumTextures);
  573. } else {
  574.     ATTEMPT(D3DAppIGetTextureHandle(d3dappi.NumTextures));
  575.     ++d3dappi.NumUsableTextures;
  576. }
  577.     }
  578.     d3dappi.NumTextures++;
  579.     return TRUE;
  580. exit_with_error:
  581.     d3dappi.ImageFile[d3dappi.NumTextures][0] = 0;
  582.     return FALSE;
  583. }
  584. /*
  585.  * D3DAppChangeTextureFormat
  586.  */
  587. BOOL
  588. D3DAppChangeTextureFormat(int format)
  589. {
  590.     /*
  591.      * Release all the textures, change the format and load them again
  592.      */
  593.     d3dappi.bRenderingIsOK = FALSE;
  594.     D3DAppIReleaseAllTextures();
  595.     d3dappi.CurrTextureFormat = format;
  596.     memcpy(&d3dappi.ThisTextureFormat, &d3dappi.TextureFormat[format],
  597.    sizeof(D3DAppTextureFormat));
  598.     ATTEMPT(D3DAppILoadAllTextures());
  599.     d3dappi.bRenderingIsOK = TRUE;
  600.     return TRUE;
  601. exit_with_error:
  602.     D3DAppIReleaseAllTextures();
  603.     return FALSE;
  604. }
  605. /*
  606.  * D3DAppDisableTextures
  607.  */
  608. BOOL
  609. D3DAppDisableTextures(BOOL flag)
  610. {
  611.     int i;
  612.     if (flag == d3dappi.bTexturesDisabled)
  613. return TRUE;
  614.     if (flag) {
  615. /*
  616.  * Set all the texture handles to 0
  617.  */
  618. d3dappi.bTexturesDisabled = TRUE;
  619. for (i = 0; i < d3dappi.NumTextures; i++)
  620.     d3dappi.TextureHandle[i] = 0;
  621.     } else {
  622. /*
  623.  * Restore the texture handles from the master array
  624.  */
  625. d3dappi.bTexturesDisabled = FALSE;
  626. memcpy(d3dappi.TextureHandle, MasterTextureHandle,
  627.        sizeof(D3DTEXTUREHANDLE) * D3DAPP_MAXTEXTURES);
  628.     }
  629.     return TRUE;
  630. }
  631. /*
  632.  * D3DAppSwapTextures
  633.  */
  634. BOOL
  635. D3DAppSwapTextures()
  636. {
  637.     int i;
  638.     char tempfile[30];
  639.     LPDIRECT3DTEXTURE2 lptempTexture;
  640.     LPDIRECTDRAWSURFACE lptempSurface;
  641.   if (d3dappi.bTexturesDisabled || d3dappi.NumTextures == 0) {
  642. D3DAppISetErrorString("Cannot swap textures which are disable or not loaded.n");
  643. goto exit_with_error;
  644.     }
  645.     if (!d3dappi.ThisDriver.bDoesTextures)
  646. return TRUE;
  647.     /*
  648.      * Swap texture 1 with 2, then 2 with 3, then 3 with 4, etc.
  649.      * Don't forget the image file names, texture objects and surfaces
  650.      */
  651.     for (i = 0; i < d3dappi.NumUsableTextures - 1; i++) {
  652. lstrcpy(tempfile, d3dappi.ImageFile[i]);
  653. lstrcpy(d3dappi.ImageFile[i], d3dappi.ImageFile[i+1]);
  654. lstrcpy(d3dappi.ImageFile[i+1], tempfile);
  655. d3dappi.lpD3DDevice->lpVtbl->SwapTextureHandles(d3dappi.lpD3DDevice,
  656.       d3dappi.lpTexture[i],
  657.       d3dappi.lpTexture[i+1]);
  658. lptempTexture = d3dappi.lpTexture[i];
  659. d3dappi.lpTexture[i] = d3dappi.lpTexture[i+1];
  660. d3dappi.lpTexture[i+1] = lptempTexture;
  661. lptempSurface = d3dappi.lpTextureSurf[i];
  662. d3dappi.lpTextureSurf[i] = d3dappi.lpTextureSurf[i+1];
  663. d3dappi.lpTextureSurf[i+1] = lptempSurface;
  664.     }
  665.     return TRUE;
  666. exit_with_error:
  667.     return FALSE;
  668. }
  669. /*
  670.  * D3DAppSetRenderState
  671.  */
  672. BOOL
  673. D3DAppSetRenderState(D3DAppRenderState* lpState)
  674. {
  675.     /*
  676.      * If none was provided, reset the current render state.
  677.      */
  678.     if (!lpState)
  679. lpState = &d3dapprs;
  680.     /*
  681.      * Record this render state and set it.
  682.      */
  683.     if (lpState != &d3dapprs)
  684. memcpy(&d3dapprs, lpState, sizeof(D3DAppRenderState));
  685.     if (d3dappi.bRenderingIsOK) {
  686. ATTEMPT(D3DAppISetRenderState());
  687.     }
  688.     return TRUE;
  689. exit_with_error:
  690.     return FALSE;
  691. }
  692. /*
  693.  * D3DAppGetRenderState
  694.  */
  695. BOOL
  696. D3DAppGetRenderState(D3DAppRenderState* lpState)
  697. {
  698.     memcpy(lpState, &d3dapprs, sizeof(D3DAppRenderState));
  699.     return TRUE;
  700. }
  701. /*
  702.  * D3DAppShowBackBuffer
  703.  */
  704. BOOL
  705. D3DAppShowBackBuffer(DWORD flags)
  706. {
  707.     if (!d3dappi.bRenderingIsOK) {
  708. D3DAppISetErrorString("Cannot call D3DAppShowBackBuffer while bRenderingIsOK is FALSE.n");
  709. return FALSE;
  710.     }
  711.     if (d3dappi.bPaused)
  712. return TRUE;
  713.     if (d3dappi.bFullscreen) {  
  714. int numtemp;
  715. D3DRECT temp[D3DAPP_MAXCLEARRECTS];
  716. /*
  717.  * Flip the back and front buffers
  718.  */
  719.         LastError = d3dappi.lpFrontBuffer->lpVtbl->Flip(d3dappi.lpFrontBuffer,
  720. d3dappi.lpBackBuffer,
  721. 1);
  722. if (LastError == DDERR_SURFACELOST) {
  723.     d3dappi.lpFrontBuffer->lpVtbl->Restore(d3dappi.lpFrontBuffer);
  724.     d3dappi.lpBackBuffer->lpVtbl->Restore(d3dappi.lpBackBuffer);
  725.     D3DAppIClearBuffers();
  726. } else if (LastError != DD_OK) {
  727.             D3DAppISetErrorString("Flipping complex display surface failed.n%s", D3DAppErrorToString(LastError));
  728.             return FALSE;
  729.         }
  730. if (d3dappi.bBackBufferInVideo) {
  731.     /*
  732.      * This is a real flip, so the client and back buffer dirty
  733.      * rectangles also flip
  734.      */
  735.     D3DAppICopyRectList(&numtemp, temp, NumDirtyClientRects,
  736. DirtyClient);
  737.     D3DAppICopyRectList(&NumDirtyClientRects, DirtyClient,
  738. NumDirtyBackRects, DirtyBack);
  739.     D3DAppICopyRectList(&NumDirtyBackRects, DirtyBack, numtemp, temp);
  740. } else {
  741.     /*
  742.      * The flip is being emulated as a blt from a system memory back
  743.      * buffer, so the back buffer's dirty rectangles are now also the
  744.      * client's.
  745.      */
  746.     D3DAppICopyRectList(&NumDirtyClientRects, DirtyClient,
  747. NumDirtyBackRects, DirtyBack);
  748. }
  749.     } else {
  750. int NumFrontRects, NumBufferRects, i;
  751. RECT front[D3DAPP_MAXCLEARRECTS];
  752. RECT buffer[D3DAPP_MAXCLEARRECTS];
  753. /*
  754.  * Set the rectangle to blt from the back to front bufer
  755.  */
  756. if (flags & D3DAPP_SHOWALL) {
  757.     /*
  758.      * Set to entire client window
  759.      */
  760.     NumBufferRects = 1;
  761.     SetRect(&buffer[0], 0, 0, d3dappi.szClient.cx,
  762.     d3dappi.szClient.cy);
  763.     SetRect(&front[0],
  764.     d3dappi.pClientOnPrimary.x, d3dappi.pClientOnPrimary.y,
  765.     d3dappi.szClient.cx + d3dappi.pClientOnPrimary.x,
  766.     d3dappi.szClient.cy + d3dappi.pClientOnPrimary.y);
  767. } else {
  768.     /*
  769.      * Merge the back and front buffer dirty rectangle lists to get
  770.      * a list of rectangles to blt.  This will simultaneously clear
  771.      * the smallest front buffer region while blt'ing all the back
  772.      * buffer which changed.
  773.      */
  774.     D3DAppIMergeRectLists(&NumBufferRects, (LPD3DRECT)buffer,
  775.   NumDirtyClientRects, DirtyClient,
  776.   NumDirtyBackRects, DirtyBack);
  777.     D3DAppICopyRectList(&NumFrontRects, (LPD3DRECT)front,
  778. NumBufferRects, (LPD3DRECT)buffer);
  779.     for (i = 0; i < NumFrontRects; i++) {
  780. front[i].top += d3dappi.pClientOnPrimary.y;
  781. front[i].left += d3dappi.pClientOnPrimary.x;
  782. front[i].bottom += d3dappi.pClientOnPrimary.y;
  783. front[i].right += d3dappi.pClientOnPrimary.x;
  784.     }
  785. }
  786. /*
  787.  * Blt the list of rectangles from the back to front buffer
  788.  */
  789. for (i = 0; i < NumBufferRects; i++) {
  790.     LastError =
  791.     d3dappi.lpFrontBuffer->lpVtbl->Blt(d3dappi.lpFrontBuffer,
  792.                              &front[i], d3dappi.lpBackBuffer,
  793.      &buffer[i], DDBLT_WAIT, NULL);
  794.     if (LastError == DDERR_SURFACELOST) {
  795. d3dappi.lpFrontBuffer->lpVtbl->Restore(d3dappi.lpFrontBuffer);
  796. d3dappi.lpBackBuffer->lpVtbl->Restore(d3dappi.lpBackBuffer);
  797. D3DAppIClearBuffers();
  798.     } else if (LastError != DD_OK) {
  799. D3DAppISetErrorString("Blt of back buffer to front buffer failed.n%s", D3DAppErrorToString(LastError));
  800. return FALSE;
  801.     }
  802. }
  803. /*
  804.  * The back buffer's dirty rectangles are now also the client's
  805.  */
  806. D3DAppICopyRectList(&NumDirtyClientRects, DirtyClient,
  807.     NumDirtyBackRects, DirtyBack);
  808.     }
  809.     return TRUE;
  810. }
  811. /*
  812.  * D3DAppRenderExtents
  813.  */
  814. BOOL
  815. D3DAppRenderExtents(DWORD dwCount, LPD3DRECT extent, DWORD flags)
  816. {
  817.     if (dwCount > D3DAPP_MAXCLEARRECTS) {
  818. D3DAppISetErrorString("The number of clear rectangles exceeded D3DAPP_MAXCLEARRECTS.");
  819. return FALSE;
  820.     }
  821.     if (flags & D3DAPP_CLEARALL) {
  822. /*
  823.  * Set the back buffer dirty rectangle to the entire client area
  824.  */
  825. D3DRECT dummy;
  826. dummy.x1 = dummy.y1 = 0;
  827. dummy.x2 = d3dappi.szClient.cx;
  828. dummy.y2 = d3dappi.szClient.cy;
  829. D3DAppICopyRectList(&NumDirtyBackRects, DirtyBack, 1, &dummy);
  830. D3DAppICopyRectList(&NumDirtyClientRects, DirtyClient, 1, &dummy);
  831. D3DAppICopyRectList(&NumDirtyZRects, DirtyZ, 1, &dummy);
  832.     } else {
  833. /*
  834.  * Set the back and Z buffer dirty rectangle list as specified
  835.  */
  836. D3DAppICopyRectList(&NumDirtyBackRects, DirtyBack, dwCount, extent);
  837. D3DAppICopyRectList(&NumDirtyZRects, DirtyZ, dwCount, extent);
  838.     }
  839.     return TRUE;
  840. }
  841. /*
  842.  * D3DAppClearBackBuffer
  843.  */
  844. BOOL
  845. D3DAppClearBackBuffer(DWORD flags)
  846. {
  847.     if (!d3dappi.bRenderingIsOK) {
  848. D3DAppISetErrorString("Cannot call D3DAppClearBackBuffer while bRenderingIsOK is FALSE.n");
  849. return FALSE;
  850.     }
  851.     if (flags & D3DAPP_CLEARALL) {
  852. /*
  853.  * Clear the entire back buffer
  854.  */
  855. int clearflags;
  856. D3DRECT dummy;
  857. /*
  858.  * Decided wether to clear just back buffer or also z-buffer
  859.  */
  860. clearflags = D3DCLEAR_TARGET;
  861. if (d3dapprs.bZBufferOn)
  862.     clearflags |= D3DCLEAR_ZBUFFER;
  863. dummy.x1 = dummy.y1 = 0;
  864. dummy.x2 = d3dappi.szClient.cx;
  865. dummy.y2 = d3dappi.szClient.cy;
  866. LastError =
  867.           d3dappi.lpD3DViewport->lpVtbl->Clear(d3dappi.lpD3DViewport,
  868.        1, &dummy,
  869.        clearflags);
  870. if (LastError != D3D_OK) {
  871.     D3DAppISetErrorString("Viewport clear failed.n%s",
  872.                   D3DAppErrorToString(LastError));
  873.     return FALSE;
  874. }
  875.     } else {
  876. /*
  877.  * Clear the dirty rectangles on the back buffer
  878.  */
  879. LastError =
  880.           d3dappi.lpD3DViewport->lpVtbl->Clear(d3dappi.lpD3DViewport,
  881.                                        NumDirtyBackRects,
  882.       DirtyBack, D3DCLEAR_TARGET);
  883. if (LastError != D3D_OK) {
  884.     D3DAppISetErrorString("Viewport clear of back buffer failed.n%s",
  885.                   D3DAppErrorToString(LastError));
  886.     return FALSE;
  887. }
  888. /*
  889.  * Clear the dirty rectangles on the Z buffer
  890.  */
  891. LastError =
  892.           d3dappi.lpD3DViewport->lpVtbl->Clear(d3dappi.lpD3DViewport,
  893.                                        NumDirtyZRects,
  894.       DirtyZ, D3DCLEAR_ZBUFFER);
  895. if (LastError != D3D_OK) {
  896.     D3DAppISetErrorString("Viewport clear of Z buffer failed.n%s",
  897.                   D3DAppErrorToString(LastError));
  898.     return FALSE;
  899. }
  900.     }
  901.     return TRUE;
  902. }
  903. /*
  904.  * D3DAppCheckForLostSurfaces
  905.  */
  906. #define CHECKSURF(x) if (x) {     
  907. if (x->lpVtbl->IsLost(x) == DDERR_SURFACELOST) {    
  908.     LastError = x->lpVtbl->Restore(x);     
  909.     if (LastError != DD_OK) goto exit_with_error;   
  910.     b = TRUE;     
  911. }     
  912.      }
  913. BOOL
  914. D3DAppCheckForLostSurfaces(void)
  915. {
  916.     int i;
  917.     BOOL b = FALSE;
  918.     /*
  919.      * Check all the surfaces D3DApp owns and restore them if lost.
  920.      */
  921.     CHECKSURF(d3dappi.lpFrontBuffer);
  922.     CHECKSURF(d3dappi.lpBackBuffer);
  923.     CHECKSURF(d3dappi.lpZBuffer);
  924.     if (b) {
  925. /*
  926.  * If any of the surfaces were lost and restored, clear all the buffers.
  927.  * If this fails, that's fine, just move on.
  928.  */
  929. D3DAppIClearBuffers();
  930.     }
  931.     for (i = 0; i < d3dappi.NumUsableTextures; i++) {
  932. b = FALSE;
  933. CHECKSURF(d3dappi.lpTextureSurf[i]);
  934. if (b) {
  935.     ATTEMPT(D3DAppIReloadTextureSurf(i));
  936. }
  937.     }
  938.     return TRUE;
  939. exit_with_error:
  940.     D3DAppISetErrorString("Restoring of a lost surface failed.n%s",
  941.           D3DAppErrorToString(LastError));
  942.     return FALSE;
  943. }
  944. /*
  945.  * D3DAppPause
  946.  */
  947. BOOL
  948. D3DAppPause(BOOL flag)
  949. {
  950.     static int pausecount;
  951.     /*
  952.      * Keep a count of the number of times D3DAppPause has been called to 
  953.      * prevent pausing more than once in a row.
  954.      */
  955.     if (pausecount != 0) {
  956. if (flag) {
  957.     ++pausecount;
  958.     return TRUE;
  959. } else {
  960.     --pausecount;
  961.     if (pausecount != 0)
  962. return TRUE;
  963.     }
  964.     d3dappi.bPaused = flag;
  965.     if (!flag) {
  966. /*
  967.  * Returning from a pause
  968.  */
  969.         if (d3dappi.bFullscreen && bPrimaryPalettized && lpPalette) {
  970.     /*
  971.      * Set front buffer's palette back to what it was before pause
  972.      */
  973.             LastError = lpPalette->lpVtbl->SetEntries(lpPalette, 0, 0, 256,
  974.       &ppe[0]);
  975.     if (LastError != DD_OK) {
  976. D3DAppISetErrorString("Setting palette entries during unpause failed.n%s", D3DAppErrorToString(LastError));
  977. goto exit_with_error;
  978.     }
  979.         }
  980. /*
  981.  * Dirty rectangle info is no longer valid
  982.  */
  983. D3DAppIValidateDirtyRects();
  984.     }
  985.     if (flag && d3dappi.bFullscreen) {
  986. /*
  987.  * Pausing in a fullscreen mode
  988.  */
  989.         if (bPrimaryPalettized && lpPalette) {
  990.     /*
  991.      * Save the front buffer's current palette and restore the
  992.      * original Windows palette.
  993.      */
  994.             int i;
  995.             LastError = lpPalette->lpVtbl->GetEntries(lpPalette, 0, 0, 256,
  996.       &ppe[0]);
  997.     if (LastError != DD_OK) {
  998. D3DAppISetErrorString("Getting palette entries before a pause failed.n%s", D3DAppErrorToString(LastError));
  999. goto exit_with_error;
  1000.     }
  1001.             for (i = 10; i < 246; i++)
  1002.                 Originalppe[i] = ppe[i];
  1003.             LastError = lpPalette->lpVtbl->SetEntries(lpPalette, 0, 0, 256,
  1004.         &Originalppe[0]);
  1005.     if (LastError != DD_OK) {
  1006. D3DAppISetErrorString("Returning palette entries to defaults failed.n%s", D3DAppErrorToString(LastError));
  1007. goto exit_with_error;
  1008.     }
  1009.         }
  1010. /*
  1011.  * Flip to GDI surface (either front or back buffer)
  1012.  */
  1013.         if (d3dappi.lpDD) {
  1014.             LastError = d3dappi.lpDD->lpVtbl->FlipToGDISurface(d3dappi.lpDD);
  1015.     if (LastError != DD_OK) {
  1016. D3DAppISetErrorString("Flipping to GDI surface failed.n%s", D3DAppErrorToString(LastError));
  1017. goto exit_with_error;
  1018.     }
  1019. }
  1020. /*
  1021.  * Draw the menu and frame
  1022.  */
  1023.         DrawMenuBar(d3dappi.hwnd);
  1024.         RedrawWindow(d3dappi.hwnd, NULL, NULL, RDW_FRAME);
  1025.     }
  1026.     return TRUE;
  1027. exit_with_error:
  1028.     return FALSE;
  1029. }
  1030. /*
  1031.  * D3DAppCreateSurface
  1032.  */
  1033. BOOL
  1034. D3DAppCreateSurface(DDSURFACEDESC *ddsd, LPDIRECTDRAWSURFACE *lplpSurf)
  1035. {
  1036.     return D3DAppICreateSurface(ddsd, lplpSurf);
  1037. }
  1038. /*
  1039.  * D3DAppLastError
  1040.  */
  1041. HRESULT
  1042. D3DAppLastError(void)
  1043. {
  1044.     return LastError;  
  1045. }
  1046. /*
  1047.  * D3DAppLastD3DAppISetErrorString
  1048.  */
  1049. char*
  1050. D3DAppLastErrorString(void)
  1051. {
  1052.     return LastErrorString;
  1053. }
  1054. /*
  1055.  * D3DAppDestroy
  1056.  */
  1057. BOOL
  1058. D3DAppDestroy(void)
  1059. {
  1060.     /*
  1061.      * Destroys all objects including Direct Draw.
  1062.      */
  1063.     d3dappi.bRenderingIsOK = FALSE;
  1064.     d3dappi.hwnd = NULL;
  1065.     ATTEMPT(D3DAppICallDeviceDestroyCallback());
  1066.     D3DAppIReleaseAllTextures();
  1067.     RELEASE(d3dappi.lpD3DDevice);
  1068.     RELEASE(d3dappi.lpZBuffer);
  1069.     RELEASE(lpPalette);
  1070.     RELEASE(lpClipper);
  1071.     RELEASE(d3dappi.lpBackBuffer);
  1072.     RELEASE(d3dappi.lpFrontBuffer);
  1073.     if (d3dappi.bFullscreen) {
  1074. D3DAppIRestoreDispMode();
  1075. D3DAppISetCoopLevel(d3dappi.hwnd, FALSE);
  1076.     }
  1077.     D3DAppIReleasePathList();
  1078.     RELEASE(d3dappi.lpD3D);
  1079.     RELEASE(d3dappi.lpDD);
  1080.     return TRUE;
  1081. exit_with_error:
  1082.     return FALSE;
  1083. }
  1084. /*
  1085.  * D3DAppErrorToString
  1086.  */
  1087. char*
  1088. D3DAppErrorToString(HRESULT error)
  1089. {
  1090.     switch(error) {
  1091.         case DD_OK:
  1092.             return "No error.";
  1093.         case DDERR_ALREADYINITIALIZED:
  1094.             return "This object is already initialized.";
  1095.         case DDERR_BLTFASTCANTCLIP:
  1096.             return "Return if a clipper object is attached to the source surface passed into a BltFast call.";
  1097.         case DDERR_CANNOTATTACHSURFACE:
  1098.             return "This surface can not be attached to the requested surface.";
  1099.         case DDERR_CANNOTDETACHSURFACE:
  1100.             return "This surface can not be detached from the requested surface.";
  1101.         case DDERR_CANTCREATEDC:
  1102.             return "Windows can not create any more DCs.";
  1103.         case DDERR_CANTDUPLICATE:
  1104.             return "Can't duplicate primary & 3D surfaces, or surfaces that are implicitly created.";
  1105.         case DDERR_CLIPPERISUSINGHWND:
  1106.             return "An attempt was made to set a cliplist for a clipper object that is already monitoring an hwnd.";
  1107.         case DDERR_COLORKEYNOTSET:
  1108.             return "No src color key specified for this operation.";
  1109.         case DDERR_CURRENTLYNOTAVAIL:
  1110.             return "Support is currently not available.";
  1111.         case DDERR_DIRECTDRAWALREADYCREATED:
  1112.             return "A DirectDraw object representing this driver has already been created for this process.";
  1113.         case DDERR_EXCEPTION:
  1114.             return "An exception was encountered while performing the requested operation.";
  1115.         case DDERR_EXCLUSIVEMODEALREADYSET:
  1116.             return "An attempt was made to set the cooperative level when it was already set to exclusive.";
  1117.         case DDERR_GENERIC:
  1118.             return "Generic failure.";
  1119.         case DDERR_HEIGHTALIGN:
  1120.             return "Height of rectangle provided is not a multiple of reqd alignment.";
  1121.         case DDERR_HWNDALREADYSET:
  1122.             return "The CooperativeLevel HWND has already been set. It can not be reset while the process has surfaces or palettes created.";
  1123.         case DDERR_HWNDSUBCLASSED:
  1124.             return "HWND used by DirectDraw CooperativeLevel has been subclassed, this prevents DirectDraw from restoring state.";
  1125.         case DDERR_IMPLICITLYCREATED:
  1126.             return "This surface can not be restored because it is an implicitly created surface.";
  1127.         case DDERR_INCOMPATIBLEPRIMARY:
  1128.             return "Unable to match primary surface creation request with existing primary surface.";
  1129.         case DDERR_INVALIDCAPS:
  1130.             return "One or more of the caps bits passed to the callback are incorrect.";
  1131.         case DDERR_INVALIDCLIPLIST:
  1132.             return "DirectDraw does not support the provided cliplist.";
  1133.         case DDERR_INVALIDDIRECTDRAWGUID:
  1134.             return "The GUID passed to DirectDrawCreate is not a valid DirectDraw driver identifier.";
  1135.         case DDERR_INVALIDMODE:
  1136.             return "DirectDraw does not support the requested mode.";
  1137.         case DDERR_INVALIDOBJECT:
  1138.             return "DirectDraw received a pointer that was an invalid DIRECTDRAW object.";
  1139.         case DDERR_INVALIDPARAMS:
  1140.             return "One or more of the parameters passed to the function are incorrect.";
  1141.         case DDERR_INVALIDPIXELFORMAT:
  1142.             return "The pixel format was invalid as specified.";
  1143.         case DDERR_INVALIDPOSITION:
  1144.             return "Returned when the position of the overlay on the destination is no longer legal for that destination.";
  1145.         case DDERR_INVALIDRECT:
  1146.             return "Rectangle provided was invalid.";
  1147.         case DDERR_LOCKEDSURFACES:
  1148.             return "Operation could not be carried out because one or more surfaces are locked.";
  1149.         case DDERR_NO3D:
  1150.             return "There is no 3D present.";
  1151.         case DDERR_NOALPHAHW:
  1152.             return "Operation could not be carried out because there is no alpha accleration hardware present or available.";
  1153.         case DDERR_NOBLTHW:
  1154.             return "No blitter hardware present.";
  1155.         case DDERR_NOCLIPLIST:
  1156.             return "No cliplist available.";
  1157.         case DDERR_NOCLIPPERATTACHED:
  1158.             return "No clipper object attached to surface object.";
  1159.         case DDERR_NOCOLORCONVHW:
  1160.             return "Operation could not be carried out because there is no color conversion hardware present or available.";
  1161.         case DDERR_NOCOLORKEY:
  1162.             return "Surface doesn't currently have a color key";
  1163.         case DDERR_NOCOLORKEYHW:
  1164.             return "Operation could not be carried out because there is no hardware support of the destination color key.";
  1165.         case DDERR_NOCOOPERATIVELEVELSET:
  1166.             return "Create function called without DirectDraw object method SetCooperativeLevel being called.";
  1167.         case DDERR_NODC:
  1168.             return "No DC was ever created for this surface.";
  1169.         case DDERR_NODDROPSHW:
  1170.             return "No DirectDraw ROP hardware.";
  1171.         case DDERR_NODIRECTDRAWHW:
  1172.             return "A hardware-only DirectDraw object creation was attempted but the driver did not support any hardware.";
  1173.         case DDERR_NOEMULATION:
  1174.             return "Software emulation not available.";
  1175.         case DDERR_NOEXCLUSIVEMODE:
  1176.             return "Operation requires the application to have exclusive mode but the application does not have exclusive mode.";
  1177.         case DDERR_NOFLIPHW:
  1178.             return "Flipping visible surfaces is not supported.";
  1179.         case DDERR_NOGDI:
  1180.             return "There is no GDI present.";
  1181.         case DDERR_NOHWND:
  1182.             return "Clipper notification requires an HWND or no HWND has previously been set as the CooperativeLevel HWND.";
  1183.         case DDERR_NOMIRRORHW:
  1184.             return "Operation could not be carried out because there is no hardware present or available.";
  1185.         case DDERR_NOOVERLAYDEST:
  1186.             return "Returned when GetOverlayPosition is called on an overlay that UpdateOverlay has never been called on to establish a destination.";
  1187.         case DDERR_NOOVERLAYHW:
  1188.             return "Operation could not be carried out because there is no overlay hardware present or available.";
  1189.         case DDERR_NOPALETTEATTACHED:
  1190.             return "No palette object attached to this surface.";
  1191.         case DDERR_NOPALETTEHW:
  1192.             return "No hardware support for 16 or 256 color palettes.";
  1193.         case DDERR_NORASTEROPHW:
  1194.             return "Operation could not be carried out because there is no appropriate raster op hardware present or available.";
  1195.         case DDERR_NOROTATIONHW:
  1196.             return "Operation could not be carried out because there is no rotation hardware present or available.";
  1197.         case DDERR_NOSTRETCHHW:
  1198.             return "Operation could not be carried out because there is no hardware support for stretching.";
  1199.         case DDERR_NOT4BITCOLOR:
  1200.             return "DirectDrawSurface is not in 4 bit color palette and the requested operation requires 4 bit color palette.";
  1201.         case DDERR_NOT4BITCOLORINDEX:
  1202.             return "DirectDrawSurface is not in 4 bit color index palette and the requested operation requires 4 bit color index palette.";
  1203.         case DDERR_NOT8BITCOLOR:
  1204.             return "DirectDrawSurface is not in 8 bit color mode and the requested operation requires 8 bit color.";
  1205.         case DDERR_NOTAOVERLAYSURFACE:
  1206.             return "Returned when an overlay member is called for a non-overlay surface.";
  1207.         case DDERR_NOTEXTUREHW:
  1208.             return "Operation could not be carried out because there is no texture mapping hardware present or available.";
  1209.         case DDERR_NOTFLIPPABLE:
  1210.             return "An attempt has been made to flip a surface that is not flippable.";
  1211.         case DDERR_NOTFOUND:
  1212.             return "Requested item was not found.";
  1213.         case DDERR_NOTLOCKED:
  1214.             return "Surface was not locked.  An attempt to unlock a surface that was not locked at all, or by this process, has been attempted.";
  1215.         case DDERR_NOTPALETTIZED:
  1216.             return "The surface being used is not a palette-based surface.";
  1217.         case DDERR_NOVSYNCHW:
  1218.             return "Operation could not be carried out because there is no hardware support for vertical blank synchronized operations.";
  1219.         case DDERR_NOZBUFFERHW:
  1220.             return "Operation could not be carried out because there is no hardware support for zbuffer blitting.";
  1221.         case DDERR_NOZOVERLAYHW:
  1222.             return "Overlay surfaces could not be z layered based on their BltOrder because the hardware does not support z layering of overlays.";
  1223.         case DDERR_OUTOFCAPS:
  1224.             return "The hardware needed for the requested operation has already been allocated.";
  1225.         case DDERR_OUTOFMEMORY:
  1226.             return "DirectDraw does not have enough memory to perform the operation.";
  1227.         case DDERR_OUTOFVIDEOMEMORY:
  1228.             return "DirectDraw does not have enough memory to perform the operation.";
  1229.         case DDERR_OVERLAYCANTCLIP:
  1230.             return "The hardware does not support clipped overlays.";
  1231.         case DDERR_OVERLAYCOLORKEYONLYONEACTIVE:
  1232.             return "Can only have ony color key active at one time for overlays.";
  1233.         case DDERR_OVERLAYNOTVISIBLE:
  1234.             return "Returned when GetOverlayPosition is called on a hidden overlay.";
  1235.         case DDERR_PALETTEBUSY:
  1236.             return "Access to this palette is being refused because the palette is already locked by another thread.";
  1237.         case DDERR_PRIMARYSURFACEALREADYEXISTS:
  1238.             return "This process already has created a primary surface.";
  1239.         case DDERR_REGIONTOOSMALL:
  1240.             return "Region passed to Clipper::GetClipList is too small.";
  1241.         case DDERR_SURFACEALREADYATTACHED:
  1242.             return "This surface is already attached to the surface it is being attached to.";
  1243.         case DDERR_SURFACEALREADYDEPENDENT:
  1244.             return "This surface is already a dependency of the surface it is being made a dependency of.";
  1245.         case DDERR_SURFACEBUSY:
  1246.             return "Access to this surface is being refused because the surface is already locked by another thread.";
  1247.         case DDERR_SURFACEISOBSCURED:
  1248.             return "Access to surface refused because the surface is obscured.";
  1249.         case DDERR_SURFACELOST:
  1250.             return "Access to this surface is being refused because the surface memory is gone. The DirectDrawSurface object representing this surface should have Restore called on it.";
  1251.         case DDERR_SURFACENOTATTACHED:
  1252.             return "The requested surface is not attached.";
  1253.         case DDERR_TOOBIGHEIGHT:
  1254.             return "Height requested by DirectDraw is too large.";
  1255.         case DDERR_TOOBIGSIZE:
  1256.             return "Size requested by DirectDraw is too large, but the individual height and width are OK.";
  1257.         case DDERR_TOOBIGWIDTH:
  1258.             return "Width requested by DirectDraw is too large.";
  1259.         case DDERR_UNSUPPORTED:
  1260.             return "Action not supported.";
  1261.         case DDERR_UNSUPPORTEDFORMAT:
  1262.             return "FOURCC format requested is unsupported by DirectDraw.";
  1263.         case DDERR_UNSUPPORTEDMASK:
  1264.             return "Bitmask in the pixel format requested is unsupported by DirectDraw.";
  1265.         case DDERR_VERTICALBLANKINPROGRESS:
  1266.             return "Vertical blank is in progress.";
  1267.         case DDERR_WASSTILLDRAWING:
  1268.             return "Informs DirectDraw that the previous Blt which is transfering information to or from this Surface is incomplete.";
  1269.         case DDERR_WRONGMODE:
  1270.             return "This surface can not be restored because it was created in a different mode.";
  1271.         case DDERR_XALIGN:
  1272.             return "Rectangle provided was not horizontally aligned on required boundary.";
  1273.         case D3DERR_BADMAJORVERSION:
  1274.             return "D3DERR_BADMAJORVERSION";
  1275.         case D3DERR_BADMINORVERSION:
  1276.             return "D3DERR_BADMINORVERSION";
  1277.         case D3DERR_EXECUTE_LOCKED:
  1278.             return "D3DERR_EXECUTE_LOCKED";
  1279.         case D3DERR_EXECUTE_NOT_LOCKED:
  1280.             return "D3DERR_EXECUTE_NOT_LOCKED";
  1281.         case D3DERR_EXECUTE_CREATE_FAILED:
  1282.             return "D3DERR_EXECUTE_CREATE_FAILED";
  1283.         case D3DERR_EXECUTE_DESTROY_FAILED:
  1284.             return "D3DERR_EXECUTE_DESTROY_FAILED";
  1285.         case D3DERR_EXECUTE_LOCK_FAILED:
  1286.             return "D3DERR_EXECUTE_LOCK_FAILED";
  1287.         case D3DERR_EXECUTE_UNLOCK_FAILED:
  1288.             return "D3DERR_EXECUTE_UNLOCK_FAILED";
  1289.         case D3DERR_EXECUTE_FAILED:
  1290.             return "D3DERR_EXECUTE_FAILED";
  1291.         case D3DERR_EXECUTE_CLIPPED_FAILED:
  1292.             return "D3DERR_EXECUTE_CLIPPED_FAILED";
  1293.         case D3DERR_TEXTURE_NO_SUPPORT:
  1294.             return "D3DERR_TEXTURE_NO_SUPPORT";
  1295.         case D3DERR_TEXTURE_NOT_LOCKED:
  1296.             return "D3DERR_TEXTURE_NOT_LOCKED";
  1297.         case D3DERR_TEXTURE_LOCKED:
  1298.             return "D3DERR_TEXTURELOCKED";
  1299.         case D3DERR_TEXTURE_CREATE_FAILED:
  1300.             return "D3DERR_TEXTURE_CREATE_FAILED";
  1301.         case D3DERR_TEXTURE_DESTROY_FAILED:
  1302.             return "D3DERR_TEXTURE_DESTROY_FAILED";
  1303.         case D3DERR_TEXTURE_LOCK_FAILED:
  1304.             return "D3DERR_TEXTURE_LOCK_FAILED";
  1305.         case D3DERR_TEXTURE_UNLOCK_FAILED:
  1306.             return "D3DERR_TEXTURE_UNLOCK_FAILED";
  1307.         case D3DERR_TEXTURE_LOAD_FAILED:
  1308.             return "D3DERR_TEXTURE_LOAD_FAILED";
  1309.         case D3DERR_MATRIX_CREATE_FAILED:
  1310.             return "D3DERR_MATRIX_CREATE_FAILED";
  1311.         case D3DERR_MATRIX_DESTROY_FAILED:
  1312.             return "D3DERR_MATRIX_DESTROY_FAILED";
  1313.         case D3DERR_MATRIX_SETDATA_FAILED:
  1314.             return "D3DERR_MATRIX_SETDATA_FAILED";
  1315.         case D3DERR_SETVIEWPORTDATA_FAILED:
  1316.             return "D3DERR_SETVIEWPORTDATA_FAILED";
  1317.         case D3DERR_MATERIAL_CREATE_FAILED:
  1318.             return "D3DERR_MATERIAL_CREATE_FAILED";
  1319.         case D3DERR_MATERIAL_DESTROY_FAILED:
  1320.             return "D3DERR_MATERIAL_DESTROY_FAILED";
  1321.         case D3DERR_MATERIAL_SETDATA_FAILED:
  1322.             return "D3DERR_MATERIAL_SETDATA_FAILED";
  1323.         case D3DERR_LIGHT_SET_FAILED:
  1324.             return "D3DERR_LIGHT_SET_FAILED";
  1325.         default:
  1326.             return "Unrecognized error value.";
  1327.     }
  1328. }