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