d3dapp.cpp
上传用户:garry_shen
上传日期:2015-04-15
资源大小:45647k
文件大小:48k
源码类别:

游戏引擎

开发平台:

Visual C++

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