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

Windows编程

开发平台:

Visual C++

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