home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / pc / directx2 / sdk / samples / misc / misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-28  |  19.6 KB  |  586 lines

  1. /*
  2.  *  Copyright (C) 1995, 1996 Microsoft Corporation. All Rights Reserved.
  3.  *
  4.  *  File: misc.c
  5.  *
  6.  *  Miscellaneous functions not involving DD and D3D.  Part of D3DApp.
  7.  *
  8.  *  D3DApp is a collection of helper functions for Direct3D applications.
  9.  *  D3DApp consists of the following files:
  10.  *      d3dapp.h    Main D3DApp header to be included by application
  11.  *      d3dappi.h   Internal header
  12.  *      d3dapp.c    D3DApp functions seen by application.
  13.  *      ddcalls.c   All calls to DirectDraw objects except textures
  14.  *      d3dcalls.c  All calls to Direct3D objects except textures
  15.  *      texture.c   Texture loading and managing texture list
  16.  *      misc.c      Miscellaneous calls
  17.  */
  18.  
  19. #include "d3dappi.h"
  20.  
  21. /***************************************************************************/
  22. /*                          Setting Defaults                               */
  23. /***************************************************************************/
  24. /*
  25.  * D3DAppISetDefaults
  26.  * Set all the global variables to their default values.  Do not reset the
  27.  * image files.
  28.  */
  29. void
  30. D3DAppISetDefaults(void)
  31. {
  32.     int n;
  33.     char backup[D3DAPP_MAXTEXTURES][50];
  34.  
  35.     n = d3dappi.NumTextures;
  36.     memcpy(&backup[0][0], &d3dappi.ImageFile[0][0], 50 * D3DAPP_MAXTEXTURES);
  37.     ZEROMEM(d3dappi);
  38.     memcpy(&d3dappi.ImageFile[0][0], &backup[0][0], 50 * D3DAPP_MAXTEXTURES);
  39.     d3dappi.NumTextures = n;
  40.     ZEROMEM(d3dapprs);
  41.     d3dapprs.bZBufferOn = TRUE;
  42.     d3dapprs.bPerspCorrect = FALSE;
  43.     d3dapprs.ShadeMode = D3DSHADE_GOURAUD;
  44.     d3dapprs.TextureFilter = D3DFILTER_NEAREST;
  45.     d3dapprs.TextureBlend = D3DTBLEND_MODULATE;
  46.     d3dapprs.FillMode = D3DFILL_SOLID;
  47.     d3dapprs.bDithering = FALSE;
  48.     d3dapprs.bSpecular = TRUE;
  49.     d3dapprs.bAntialiasing = FALSE;
  50.     d3dapprs.bFogEnabled = FALSE;
  51.     d3dapprs.FogColor = RGB_MAKE(0, 0, 0);
  52.     d3dapprs.FogMode = D3DFOG_LINEAR;
  53.     d3dapprs.FogStart = D3DVAL(6.0);
  54.     d3dapprs.FogEnd = D3DVAL(11.0);
  55.  
  56.     lpClipper = NULL;
  57.     lpPalette = NULL;
  58.     bPrimaryPalettized = FALSE;
  59.     bPaletteActivate = FALSE;
  60.     bIgnoreWM_SIZE = FALSE;
  61.     ZEROMEM(ppe);
  62.     ZEROMEM(Originalppe);
  63.     LastError = DD_OK;
  64.     ZEROMEM(LastErrorString);
  65.     D3DDeviceDestroyCallback = NULL;
  66.     D3DDeviceDestroyCallbackContext = NULL;
  67.     D3DDeviceCreateCallback = NULL;
  68.     D3DDeviceCreateCallbackContext = NULL;
  69. }
  70.  
  71. /***************************************************************************/
  72. /*                Calling Device Create And Destroy Callbacks              */
  73. /***************************************************************************/
  74. BOOL
  75. D3DAppICallDeviceDestroyCallback(void)
  76. {
  77.     if (D3DDeviceDestroyCallback) {
  78.         if (CallbackRefCount) {
  79.             --CallbackRefCount;
  80.             return (D3DDeviceDestroyCallback)(D3DDeviceDestroyCallbackContext);
  81.         }
  82.     }
  83.     return TRUE;
  84. }
  85.  
  86. BOOL
  87. D3DAppICallDeviceCreateCallback(int w, int h)
  88. {
  89.     if (D3DDeviceCreateCallback) {
  90.         ++CallbackRefCount;
  91.         return (D3DDeviceCreateCallback)(w, h, &d3dappi.lpD3DViewport,
  92.                                          D3DDeviceCreateCallbackContext);
  93.     }
  94.     return TRUE;
  95. }
  96.  
  97. /***************************************************************************/
  98. /*            Choosing and verifying the driver and display mode           */
  99. /***************************************************************************/
  100. /*
  101.  * D3DAppIPickDriver
  102.  * Choose a driver from the list of available drivers which can render to one
  103.  * of the given depths.  Hardware is prefered.  Mono-lighting drivers are
  104.  * prefered over RGB.
  105.  */
  106. BOOL
  107. D3DAppIPickDriver(int* driver, DWORD depths)
  108. {
  109.     int i, j;
  110.     j = 0;
  111.     for (i = 0; i < d3dappi.NumDrivers; i++)
  112.         if (d3dappi.Driver[i].Desc.dwDeviceRenderBitDepth & depths)
  113.             break;
  114.     if (i >= d3dappi.NumDrivers) {
  115.         *driver = D3DAPP_BOGUS;
  116.         return TRUE;
  117.     }
  118.     j = i;
  119.     for (i = 0; i < d3dappi.NumDrivers; i++) {
  120.         if (d3dappi.Driver[i].Desc.dwDeviceRenderBitDepth & depths) {
  121.             if (d3dappi.Driver[i].bIsHardware &&
  122.                                               !d3dappi.Driver[j].bIsHardware)
  123.                                                   j = i;
  124.             else if (d3dappi.Driver[i].bIsHardware ==
  125.                                              d3dappi.Driver[j].bIsHardware) {
  126.                 if (d3dappi.Driver[i].Desc.dcmColorModel & D3DCOLOR_MONO &&
  127.                     !(d3dappi.Driver[j].Desc.dcmColorModel & D3DCOLOR_MONO))
  128.                         j = i;
  129.             }
  130.         }
  131.     }
  132.     if (j >= d3dappi.NumDrivers)
  133.         *driver = D3DAPP_BOGUS;
  134.     else
  135.         *driver = j;
  136.     return TRUE;
  137. }
  138.  
  139. /*
  140.  * D3DAppIFilterDisplayModes
  141.  * Set the bThisDriverCanDo flag for each display mode if the given driver
  142.  * can render in that depth.  Also checks to make sure there is enough
  143.  * total video memory for front/back/z-buffer in video memory if it's a
  144.  * hardware device.
  145.  */
  146. BOOL
  147. D3DAppIFilterDisplayModes(int driver)
  148. {
  149.     int i;
  150.     DWORD depths = d3dappi.Driver[driver].Desc.dwDeviceRenderBitDepth;
  151.  
  152.     for (i = 0; i < d3dappi.NumModes; i++) {
  153.         d3dappi.Mode[i].bThisDriverCanDo = FALSE;
  154.         if (!(D3DAppIBPPToDDBD(d3dappi.Mode[i].bpp) & depths))
  155.             continue;
  156.         d3dappi.Mode[i].bThisDriverCanDo = TRUE;
  157.             
  158.     }
  159.     d3dappi.ThisMode.bThisDriverCanDo =
  160.                              d3dappi.Mode[d3dappi.CurrMode].bThisDriverCanDo;
  161.     return TRUE;
  162. }
  163.  
  164. /*
  165.  * D3DAppIPickDisplayMode
  166.  * Pick a display mode of one of the given depths.  640x480x16 is prefered.
  167.  */
  168. BOOL
  169. D3DAppIPickDisplayMode(int *mode, DWORD depths)
  170. {
  171.     int i, j;
  172.     for (i = 0; i < d3dappi.NumModes; i++)
  173.         if (D3DAppIBPPToDDBD(d3dappi.Mode[i].bpp) & depths)
  174.             break;
  175.     j = i;
  176.     for (; i < d3dappi.NumModes; i++) {
  177.         if (!(D3DAppIBPPToDDBD(d3dappi.Mode[i].bpp) & depths))
  178.             continue;
  179.         if (d3dappi.Mode[i].w == 640 && d3dappi.Mode[i].h == 480 &&
  180.             d3dappi.Mode[i].bpp == 16) {
  181.             j = i;
  182.             break;
  183.         }
  184.     }
  185.     if (j >= d3dappi.NumModes)
  186.         *mode = D3DAPP_BOGUS;
  187.     else
  188.         *mode = j;
  189.     return TRUE;
  190. }
  191.  
  192. /*
  193.  * D3DAppIVerifyDriverAndMode
  194.  * Verifies the selected driver and mode combination.  If the driver is
  195.  * specified, the mode will be changed to accomodate the driver if it's not
  196.  * compatible.  If the driver is not specified, one will be selected which is
  197.  * compatible with the specified mode.  If neither are specified, a suitable
  198.  * pair will be returned.
  199.  */
  200. BOOL
  201. D3DAppIVerifyDriverAndMode(int* lpdriver, int* lpmode)
  202. {
  203.     DWORD depths;
  204.     int driver, mode, i;
  205.     driver = *lpdriver; mode = *lpmode;
  206.  
  207.     if (mode == D3DAPP_USEWINDOW && !d3dappi.bIsPrimary) {
  208.         D3DAppISetErrorString("Cannot render to a window when the DirectDraw device is not the primary.\n");
  209.         goto exit_with_error;
  210.     }
  211.  
  212.     /*
  213.      * If I've been ask to choose a driver, choose one which is compatible
  214.      * with the specified mode.
  215.      */
  216.     if (driver == D3DAPP_YOUDECIDE) {   
  217.         if (mode == D3DAPP_USEWINDOW) {
  218.             /*
  219.              * I must find a driver for this display depth
  220.              */
  221.             depths = D3DAppIBPPToDDBD(d3dappi.WindowsDisplay.bpp);
  222.             ATTEMPT(D3DAppIPickDriver(&driver, depths));
  223.             if (driver == D3DAPP_BOGUS) {
  224.                 D3DAppISetErrorString("Cannot find a D3D device driver which is compatible with the current display depth.\n");
  225.                 goto exit_with_error;
  226.             }
  227.             /*
  228.              * I don't need to go through the mode selection since I've
  229.              * verified it here
  230.              */
  231.             goto ret_ok;
  232.         } else if (mode == D3DAPP_YOUDECIDE) {
  233.             /*
  234.              * I'm free to choose any driver which can use even one
  235.              * supported depth
  236.              */
  237.             if (d3dappi.bIsPrimary)
  238.                 depths = D3DAppIBPPToDDBD(d3dappi.WindowsDisplay.bpp);
  239.             else
  240.                 depths = 0;
  241.             for (i = 0; i < d3dappi.NumModes; i++)
  242.                 depths |= D3DAppIBPPToDDBD(d3dappi.Mode[i].bpp);
  243.             ATTEMPT(D3DAppIPickDriver(&driver, depths));
  244.             if (driver == D3DAPP_BOGUS) {
  245.                 D3DAppISetErrorString("Cannot find a D3D device driver which is compatible with the current display depth or any supported fullscreen mode.\n");
  246.                 goto exit_with_error;
  247.             }
  248.             /*
  249.              * The mode will be chosen in the next section
  250.              */
  251.         } else {
  252.             /*
  253.              * Must pick a driver which uses the given mode depth
  254.              */
  255.             ATTEMPT(D3DAppIPickDriver(&driver,
  256.                                   D3DAppIBPPToDDBD(d3dappi.Mode[mode].bpp)));
  257.             if (driver == D3DAPP_BOGUS) {
  258.                 D3DAppISetErrorString("Cannot find a D3D device driver which is compatible with the specified fullscreen mode.\n");
  259.                 goto exit_with_error;
  260.             }
  261.             /*
  262.              * I don't need to go through the mode selection since I've
  263.              * verified it here
  264.              */
  265.             goto ret_ok;
  266.         }
  267.     }
  268.  
  269.     /* 
  270.      * At this stage, I have a driver I want to match the mode to.
  271.      */
  272.     if (mode == D3DAPP_YOUDECIDE) {
  273.         /*
  274.          * If it's my choice, I prefer windowed over fullscreen
  275.          */
  276.         if (d3dappi.bIsPrimary) {
  277.             if (D3DAppIBPPToDDBD(d3dappi.WindowsDisplay.bpp) & 
  278.                     d3dappi.Driver[driver].Desc.dwDeviceRenderBitDepth) {
  279.                 mode = D3DAPP_USEWINDOW;
  280.                 goto ret_ok;
  281.             }
  282.         }
  283.         /*
  284.          * Either this is not a primary DD device or the driver cannot use
  285.          * the Windows display depth
  286.          */
  287.         ATTEMPT(D3DAppIPickDisplayMode(&mode,
  288.                         d3dappi.Driver[driver].Desc.dwDeviceRenderBitDepth));
  289.         if (mode == D3DAPP_BOGUS) {
  290.             D3DAppISetErrorString("The selected D3D device driver is not compatible with the current display depth or any supported fullscreen modes.\n");
  291.             goto exit_with_error;
  292.         }
  293.         goto ret_ok;
  294.     } else if (mode == D3DAPP_USEWINDOW) {
  295.         /*
  296.          * Check to see if this driver can use the Windows display depth
  297.          */
  298.         if (D3DAppIBPPToDDBD(d3dappi.WindowsDisplay.bpp) &
  299.                 d3dappi.Driver[driver].Desc.dwDeviceRenderBitDepth) {
  300.             goto ret_ok;
  301.         } else {
  302.             /*
  303.              * Since it cannot, call this function again to choose any 
  304.              * display mode which is compatible 
  305.              */
  306.             mode = D3DAPP_YOUDECIDE;
  307.             ATTEMPT(D3DAppIVerifyDriverAndMode(&driver, &mode));
  308.             if (driver == D3DAPP_BOGUS)
  309.                 goto exit_with_error;
  310.             goto ret_ok;
  311.         }
  312.     } else {
  313.         /*
  314.          * Check to see if this driver can use the specified fullscreen mode
  315.          */
  316.         if (D3DAppIBPPToDDBD(d3dappi.Mode[mode].bpp) &
  317.                 d3dappi.Driver[driver].Desc.dwDeviceRenderBitDepth) {
  318.             goto ret_ok;
  319.         } else {
  320.             /*
  321.              * Since it cannot, call this function again to choose any
  322.              * display mode which is compatible
  323.              */
  324.             mode = D3DAPP_YOUDECIDE;
  325.             ATTEMPT(D3DAppIVerifyDriverAndMode(&driver, &mode));
  326.             if (driver == D3DAPP_BOGUS)
  327.                 goto exit_with_error;
  328.             goto ret_ok;
  329.         }
  330.     }
  331.  
  332. ret_ok:
  333.     *lpdriver = driver; *lpmode = mode;
  334.     return TRUE;
  335. exit_with_error:
  336.     return FALSE;
  337. }
  338.  
  339. /***************************************************************************/
  340. /*                        Dirty Rectangle Functions                        */
  341. /***************************************************************************/
  342. /*
  343.  * D3DAppIValidateDirtyRects
  344.  * Set the dirty rectangles for the front and back buffers to the entire
  345.  * client size.
  346.  */
  347. void
  348. D3DAppIValidateDirtyRects(void)
  349. {
  350.     NumDirtyClientRects = 1; NumDirtyBackRects = 1; NumDirtyZRects = 1;
  351.     SetRect((LPRECT)&DirtyClient[0], 0, 0, d3dappi.szClient.cx,
  352.             d3dappi.szClient.cy);
  353.     SetRect((LPRECT)&DirtyBack[0], 0, 0, d3dappi.szClient.cx,
  354.             d3dappi.szClient.cy);
  355.     SetRect((LPRECT)&DirtyZ[0], 0, 0, d3dappi.szClient.cx,
  356.             d3dappi.szClient.cy);
  357. }
  358.  
  359. /*
  360.  * D3DAppICopyRectList
  361.  * Copy a list of rectangles to another
  362.  */
  363. void
  364. D3DAppICopyRectList(int* dstnum, LPD3DRECT dst, int srcnum, LPD3DRECT src)
  365. {
  366.     int i;
  367.     for (i = 0; i < srcnum; i++)
  368.         dst[i] = src[i];
  369.     *dstnum = srcnum;
  370. }
  371.  
  372. /*
  373.  * MERGE macro
  374.  * Set first rectangle to be the smallest rectangle containing both rects
  375.  */
  376. #undef MERGE
  377. #define MERGE(rc1, rc2)                         \
  378.     do {                                        \
  379.         if (rc2.x1 < rc1.x1) rc1.x1 = rc2.x1;   \
  380.         if (rc2.y1 < rc1.y1) rc1.y1 = rc2.y1;   \
  381.         if (rc2.x2 > rc1.x2) rc1.x2 = rc2.x2;   \
  382.         if (rc2.y2 > rc1.y2) rc1.y2 = rc2.y2;   \
  383.     } while(0)
  384.  
  385. /*
  386.  * D3DAppIMergeRectLists
  387.  * Merge two lists of rectangles to create another list of rectangles. The
  388.  * merged list of rectangles covers all the area of the original two with NO
  389.  * OVERLAPPING amongst it's rectangles.
  390.  */
  391. void
  392. D3DAppIMergeRectLists(int* dstnum, LPD3DRECT dst, int src1num, LPD3DRECT src1,
  393.                      int src2num, LPD3DRECT src2)
  394. {
  395.     LPD3DRECT rc;
  396.     int* isvalid;
  397.     int num, i, j, intersect;
  398.     rc = (LPD3DRECT)malloc(sizeof(D3DRECT) * D3DAPP_MAXCLEARRECTS * 2);
  399.     memset(rc, 0, sizeof(D3DRECT) * D3DAPP_MAXCLEARRECTS * 2);
  400.     isvalid = (int*)malloc(sizeof(int) * D3DAPP_MAXCLEARRECTS * 2);
  401.     memset(isvalid, 0, sizeof(int) * D3DAPP_MAXCLEARRECTS * 2);
  402.     for (i = 0; i < src1num; i++) {
  403.         memcpy(&rc[i], &src1[i], sizeof(D3DRECT));
  404.         if ((rc[i].x1 == 0 && rc[i].x2 == 0) ||
  405.             (rc[i].y1 == 0 && rc[i].y2 == 0))
  406.             isvalid[i] = 0;
  407.         else if (rc[i].x1 <= rc[i].x2 && rc[i].y1 <= rc[i].y2)
  408.             isvalid[i] = 1;
  409.         else
  410.             isvalid[i] = 0;
  411.     }
  412.     for (i = 0; i < src2num; i++) {
  413.         memcpy(&rc[i + src1num], &src2[i], sizeof(D3DRECT));
  414.         if (rc[i + src1num].x1 <= rc[i + src1num].x2 &&
  415.             rc[i + src1num].y1 <= rc[i + src1num].y2)
  416.             isvalid[i + src1num] = 1;
  417.         else
  418.             isvalid[i + src1num] = 0;
  419.  
  420.     }
  421.     num = src1num + src2num;
  422.     for (i = 0; i < num - 1; i++) {
  423.         if (!isvalid[i]) continue;
  424.         j = i + 1;
  425.         do {
  426.             intersect = 0;
  427.             for (; j < num; j++) {
  428.                 if (j != i && isvalid[j]) {
  429.                     if (rc[i].x1 < rc[j].x1) {
  430.                         if (rc[i].x2 < rc[j].x1)
  431.                             continue;
  432.                     } else {
  433.                         if (rc[j].x2 < rc[i].x1)
  434.                             continue;
  435.                     }
  436.                     if (rc[i].y1 < rc[j].y1) {
  437.                         if (rc[i].y2 < rc[j].y1)
  438.                             continue;
  439.                     } else {
  440.                         if (rc[j].y2 < rc[i].y1)
  441.                             continue;
  442.                     }
  443.                     MERGE(rc[i], rc[j]);
  444.                     isvalid[j] = 0;
  445.                     j = 0; intersect = 1;
  446.                     break;
  447.                 }
  448.             }
  449.         } while(intersect);
  450.     }
  451.  
  452.     for (i = 0, j = 0; i < num; i++)
  453.         if (isvalid[i]) ++j;
  454.     if (j > D3DAPP_MAXCLEARRECTS) {
  455.         for (i = 0; i < num; i++)
  456.             if (isvalid[i]) break;
  457.         if (i < num) {
  458.             *dstnum = 1;
  459.             dst[0] = rc[i];
  460.             for (; i < num; i++) {
  461.                 if (isvalid[i]) {
  462.                     MERGE(dst[0], rc[i]);
  463.                 }
  464.             }
  465.         } else {
  466.             *dstnum = 0;
  467.         }
  468.     } else {
  469.         for (i = 0, j = 0; i < num; i++) {
  470.             if (isvalid[i]) {
  471.                 memcpy(&dst[j], &rc[i], sizeof(D3DRECT));
  472.                 ++j;
  473.             }
  474.         }
  475.         *dstnum = j;
  476.     }
  477.     free(rc);
  478.     free(isvalid);
  479. }
  480.  
  481. /***************************************************************************/
  482. /*                     Getting and Setting Window Attribs                  */
  483. /***************************************************************************/
  484. /*
  485.  * D3DAppISetClientSize
  486.  * Set the client size of the given window.  A WM_SIZE message is generated,
  487.  * but ignored.
  488.  */
  489. void
  490. D3DAppISetClientSize(HWND hwnd, int w, int h, BOOL bReturnFromFullscreen)
  491. {
  492.     RECT rc;
  493.  
  494.     bIgnoreWM_SIZE = TRUE;
  495.     if (bReturnFromFullscreen) {
  496.         SetRect(&rc, 0, 0, w, h);
  497.         AdjustWindowRectEx(&rc, GetWindowLong(hwnd, GWL_STYLE),
  498.                            GetMenu(hwnd) != NULL,
  499.                            GetWindowLong(hwnd, GWL_EXSTYLE));
  500.         SetWindowPos(hwnd, NULL, 0, 0, rc.right-rc.left,
  501.                      rc.bottom-rc.top,
  502.                      SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
  503.         SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0,
  504.                      SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
  505.  
  506.     } else {
  507.         /*
  508.          * This is the only way to set the client size correctly if the menu
  509.          * is stacked, so do it unless we are returning from a fullscreen
  510.          * mode.
  511.          */
  512.         SendMessage(hwnd, WM_SIZE, SIZE_RESTORED, w + h << 16);
  513.         GetWindowRect(hwnd, &rc);
  514.         SetWindowPos(hwnd, NULL, 0, 0, rc.right-rc.left,
  515.                      rc.bottom-rc.top,
  516.                      SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
  517.         SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0,
  518.                      SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
  519.     }
  520.     bIgnoreWM_SIZE = FALSE;
  521.     d3dappi.pClientOnPrimary.x = d3dappi.pClientOnPrimary.y = 0;
  522.     ClientToScreen(hwnd, &d3dappi.pClientOnPrimary);
  523.     d3dappi.szClient.cx = w; d3dappi.szClient.cy = h;
  524. }
  525.  
  526. /*
  527.  * D3DAppIGetClientWin
  528.  * Gets the client window size and sets it in the D3DAppInfo structure
  529.  */
  530. void
  531. D3DAppIGetClientWin(HWND hwnd)
  532. {
  533.     RECT rc;
  534.     if (!d3dappi.bFullscreen) {
  535.         d3dappi.pClientOnPrimary.x = d3dappi.pClientOnPrimary.y = 0;
  536.         ClientToScreen(hwnd, &d3dappi.pClientOnPrimary);
  537.         GetClientRect(hwnd, &rc);
  538.         d3dappi.szClient.cx = rc.right;
  539.         d3dappi.szClient.cy = rc.bottom;
  540.     } else {
  541.         /*
  542.          * In the fullscreen case, we must be careful because if the window
  543.          * frame has been drawn, the client size has shrunk and this can
  544.          * cause problems, so it's best to report the entire screen.
  545.          */
  546.         d3dappi.pClientOnPrimary.x = d3dappi.pClientOnPrimary.y = 0;
  547.         d3dappi.szClient.cx = d3dappi.ThisMode.w;
  548.         d3dappi.szClient.cy = d3dappi.ThisMode.h;
  549.     }
  550. }
  551.  
  552.  
  553. /***************************************************************************/
  554. /*                              Error reporting                            */
  555. /***************************************************************************/
  556.  
  557. /*
  558.  * D3DAppISetErrorString
  559.  * Set the global variable which records the last error string.
  560.  */
  561. void
  562. D3DAppISetErrorString( LPSTR fmt, ... )
  563. {
  564.     char buff[256];
  565.  
  566.     buff[0] = 0;
  567.     wvsprintf(&buff[0], fmt, (char *)(&fmt+1));
  568.     lstrcat(buff, "\r\n");
  569.     lstrcpy(LastErrorString, buff);
  570. }
  571.  
  572. /* dpf
  573.  * Debug printf.  Very useful for fullscreen exclusive mode or when surfaces
  574.  * are in video memory.
  575.  */
  576. void __cdecl
  577. dpf( LPSTR fmt, ... )
  578. {
  579.     char buff[256];
  580.  
  581.     lstrcpy(buff, "D3DApp: ");
  582.     wvsprintf(&buff[lstrlen(buff)], fmt, (char *)(&fmt+1));
  583.     lstrcat(buff, "\r\n");
  584.     OutputDebugString(buff);
  585. }
  586.