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 / rockem / directx.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-15  |  68.0 KB  |  2,012 lines

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995-1997 Microsoft Corporation. All Rights Reserved.
  4.  *
  5.  *  File: directx.cpp
  6.  *
  7.  ***************************************************************************/
  8.  
  9. // N.B. The use of RM denotes the Direct3D retained mode objects
  10.  
  11. // The Macros TRY_DD, TRY_DS, TRY_D3D, TRY_D3DRM are defined in DirectX.h and are for
  12. // error checking.
  13.  
  14. #define INITGUID
  15. // Includes....
  16. #include "directx.h"
  17. #include "mmsystem.h"
  18. #include "winmain.h"
  19. #include "conio.h"
  20.  
  21. // Globals....
  22. LPDIRECTDRAW            g_lpDD = NULL;          // DirectDraw object
  23. LPDIRECT3D              g_lpD3D = NULL;         // Direct3D object
  24. LPDIRECTSOUND           g_lpDS = NULL;          // DirectSound object
  25. LPDIRECT3DRM            g_lpD3DRM = NULL;       // Direct3D RM object
  26. DWORD                   g_dwGDIMem = 0;         // Memory in available from GDI's surface
  27.  
  28. D3DDeviceInfo           g_deviceInfo;           // 3D device info
  29. LPGUID                  g_lpD3DDeviceGuid = NULL; // Guid to 3D device
  30.  
  31. VideoMode               g_vidModes[NUM_VID_MODES];// Array of available video modes
  32. DWORD                   g_dwCurrMode = 0;
  33. DWORD                   g_dwNumModes = 0;
  34.  
  35. BOOL                    g_bSoundPresent = FALSE; // Do we have sound capabilites?
  36.  
  37. LPDIRECTDRAWSURFACE     g_lpPrimary = NULL;     // Primary surface
  38. LPDIRECTDRAWSURFACE     g_lpBackBuffer = NULL;  // BackBuffer surface
  39. LPDIRECTDRAWSURFACE     g_lpZBuffer = NULL;     // ZBuffer
  40. LPDIRECTDRAWPALETTE     g_lpPalette = NULL;     // Palette
  41. PALETTEENTRY            g_rPal[768];            // Rockem3D palette
  42.  
  43. LPDIRECTDRAW            g_lpSplashDD = NULL;        // DirectDraw object used for splash screen
  44. LPDIRECTDRAWSURFACE     g_lpSplashPrimary = NULL;   // Primary surface
  45. LPDIRECTDRAWPALETTE     g_lpSplashPalette = NULL;   // Palette
  46.  
  47. LPDIRECT3DDEVICE        g_lpD3DDevice = NULL;   // Direct3D device
  48. LPDIRECT3DRMDEVICE      g_lpD3DRMDevice = NULL; // Direct3D RM Device
  49. LPDIRECT3DRMVIEWPORT    g_lpD3DRMViewport = NULL; // Direct3D RM Viewport
  50.  
  51. DDCAPS                  g_driverCaps;           // Driver capabilities
  52. DDCAPS                  g_HELcaps;              // HEL capabilities
  53.  
  54. DWORD                   g_dwZBufferBitDepth = 16;// ZBuffer bit depth
  55. DWORD                   g_dwZBufferMemType = DDSCAPS_SYSTEMMEMORY;// Type of ZBuffer
  56.  
  57. LPDIRECTSOUNDBUFFER     g_lpSounds[NUM_SOUNDS]; // Sound buffers
  58. LPDIRECTSOUND3DLISTENER      g_lpDs3dListener;               // Listener object for Direct 3D Sound
  59. LPDIRECTSOUNDBUFFER             g_3DSoundBuffer;                // Direct Sound buffer for the Listener object
  60. LPDIRECTSOUND3DBUFFER   g_lp3dSounds[NUM_SOUNDS];//3D Sound Buffers
  61.  
  62.  
  63. // State booleans
  64. BOOL                    g_bHardware3D = FALSE;  // Do we have hardware?
  65. BOOL            g_bOutOfVideoMemory = FALSE; // Out of video memory, fall back on software
  66.  
  67. float                   g_xratio = 0.0f;        // X ratio used for computing power bars
  68. float                   g_yratio = 0.0f;        // Y ratio used for computing power bars
  69.  
  70. // Power bar x,y and width values
  71. DWORD                   g_vidModeX;             // Current X video resolution
  72. DWORD                   g_vidModeY;             // Current Y video resolution
  73. DWORD                   g_vidModeBIT;           // Current video bit depth
  74. DWORD                   g_dwFontHeight = 0;
  75. DWORD                   g_dwAveCharWidth = 0;
  76. DWORD                   g_lbar1 = 0;
  77. DWORD                   g_wbar1 = 0;
  78. DWORD                   g_lbar2 = 0;
  79. DWORD                   g_wbar2 = 0;
  80. DWORD                   g_hbar1 = 0;
  81. DWORD                   g_hbar2 = 0;
  82.  
  83. // Externals....
  84. extern HWND                     g_hWnd;         // Defined in WINMAIN.CPP
  85. extern BOOL                     g_bSoundPaused; // Defined in WINMAIN.CPP
  86. extern LPDIRECT3DRMFRAME        g_lpCamera;     // Defined in RM.CPP
  87. extern LPDIRECT3DRMFRAME        g_lpScene;      // Defined in RM.CPP
  88. extern LPDIRECT3DRMFRAME        g_lpPlayers;    // Defined in RM.CPP
  89. extern LPDIRECT3DRMLIGHT        g_lpDir;        // Defined in RM.CPP
  90.  
  91. //----------------------------------------------------------------------
  92. // 
  93. // Function     : TraceErrorDD()
  94. //
  95. // Purpose      : Traces an error (DirectDraw)
  96. //
  97. //----------------------------------------------------------------------
  98.  
  99. void TraceErrorDD(HRESULT hErr, char *sFile, int nLine)
  100. {       
  101.     char dderr[256];
  102.     char err[1024];
  103.  
  104.     switch (hErr)
  105.     {
  106.         case DDERR_ALREADYINITIALIZED : sprintf(dderr, "DDERR_ALREADYINITIALIZED"); break;
  107.         case DDERR_CANNOTATTACHSURFACE : sprintf(dderr, "DDERR_CANNOTATTACHSURFACE"); break;
  108.         case DDERR_CANNOTDETACHSURFACE : sprintf(dderr, "DDERR_CANNOTDETACHSURFACE"); break;
  109.         case DDERR_CURRENTLYNOTAVAIL : sprintf(dderr, "DDERR_CURRENTLYNOTAVAIL"); break;
  110.         case DDERR_EXCEPTION : sprintf(dderr, "DDERR_EXCEPTION"); break;
  111.         case DDERR_GENERIC : sprintf(dderr, "DDERR_GENERIC"); break;
  112.         case DDERR_HEIGHTALIGN : sprintf(dderr, "DDERR_HEIGHTALIGN"); break;
  113.         case DDERR_INCOMPATIBLEPRIMARY : sprintf(dderr, "DDERR_INCOMPATIBLEPRIMARY"); break;
  114.         case DDERR_INVALIDCAPS : sprintf(dderr, "DDERR_INVALIDCAPS"); break;
  115.         case DDERR_INVALIDCLIPLIST : sprintf(dderr, "DDERR_INVALIDCLIPLIST"); break;
  116.         case DDERR_INVALIDMODE : sprintf(dderr, "DDERR_INVALIDMODE"); break;
  117.         case DDERR_INVALIDOBJECT : sprintf(dderr, "DDERR_INVALIDOBJECT"); break;
  118.         case DDERR_INVALIDPARAMS : sprintf(dderr, "DDERR_INVALIDPARAMS"); break;
  119.         case DDERR_INVALIDPIXELFORMAT : sprintf(dderr, "DDERR_INVALIDPIXELFORMAT"); break;
  120.         case DDERR_INVALIDRECT : sprintf(dderr, "DDERR_INVALIDRECT"); break;
  121.         case DDERR_LOCKEDSURFACES : sprintf(dderr, "DDERR_LOCKEDSURFACES"); break;
  122.         case DDERR_NO3D : sprintf(dderr, "DDERR_NO3D"); break;
  123.         case DDERR_NOALPHAHW : sprintf(dderr, "DDERR_NOALPHAHW"); break;
  124.         case DDERR_NOCLIPLIST : sprintf(dderr, "DDERR_NOCLIPLIST"); break;
  125.         case DDERR_NOCOLORCONVHW : sprintf(dderr, "DDERR_NOCOLORCONVHW"); break;
  126.         case DDERR_NOCOOPERATIVELEVELSET : sprintf(dderr, "DDERR_NOCOOPERATIVELEVELSET"); break;
  127.         case DDERR_NOCOLORKEY : sprintf(dderr, "DDERR_NOCOLORKEY"); break;
  128.         case DDERR_NOCOLORKEYHW : sprintf(dderr, "DDERR_NOCOLORKEYHW"); break;
  129.         case DDERR_NODIRECTDRAWSUPPORT : sprintf(dderr, "DDERR_NODIRECTDRAWSUPPORT"); break;
  130.         case DDERR_NOEXCLUSIVEMODE : sprintf(dderr, "DDERR_NOEXCLUSIVEMODE"); break;
  131.         case DDERR_NOFLIPHW : sprintf(dderr, "DDERR_NOFLIPHW"); break;
  132.         case DDERR_NOGDI : sprintf(dderr, "DDERR_NOGDI"); break;
  133.         case DDERR_NOMIRRORHW : sprintf(dderr, "DDERR_NOMIRRORHW"); break;
  134.         case DDERR_NOTFOUND : sprintf(dderr, "DDERR_NOTFOUND"); break;
  135.         case DDERR_NOOVERLAYHW : sprintf(dderr, "DDERR_NOOVERLAYHW"); break;
  136.         case DDERR_NORASTEROPHW : sprintf(dderr, "DDERR_NORASTEROPHW"); break;
  137.         case DDERR_NOROTATIONHW : sprintf(dderr, "DDERR_NOROTATIONHW"); break;
  138.         case DDERR_NOSTRETCHHW : sprintf(dderr, "DDERR_NOSTRETCHHW"); break;
  139.         case DDERR_NOT4BITCOLOR : sprintf(dderr, "DDERR_NOT4BITCOLOR"); break;
  140.         case DDERR_NOT4BITCOLORINDEX : sprintf(dderr, "DDERR_NOT4BITCOLORINDEX"); break;
  141.         case DDERR_NOT8BITCOLOR : sprintf(dderr, "DDERR_NOT8BITCOLOR"); break;
  142.         case DDERR_NOTEXTUREHW : sprintf(dderr, "DDERR_NOTEXTUREHW"); break;
  143.         case DDERR_NOVSYNCHW : sprintf(dderr, "DDERR_NOVSYNCHW"); break;
  144.         case DDERR_NOZBUFFERHW : sprintf(dderr, "DDERR_NOZBUFFERHW"); break;
  145.         case DDERR_NOZOVERLAYHW : sprintf(dderr, "DDERR_NOZOVERLAYHW"); break;
  146.         case DDERR_OUTOFCAPS : sprintf(dderr, "DDERR_OUTOFCAPS"); break;
  147.         case DDERR_OUTOFMEMORY : sprintf(dderr, "DDERR_OUTOFMEMORY"); break;
  148.         case DDERR_OUTOFVIDEOMEMORY : sprintf(dderr, "DDERR_OUTOFVIDEOMEMORY"); break;
  149.         case DDERR_OVERLAYCANTCLIP : sprintf(dderr, "DDERR_OVERLAYCANTCLIP"); break;
  150.         case DDERR_OVERLAYCOLORKEYONLYONEACTIVE : sprintf(dderr, "DDERR_OVERLAYCOLORKEYONLYONEACTIVE"); break;
  151.         case DDERR_PALETTEBUSY : sprintf(dderr, "DDERR_PALETTEBUSY"); break;
  152.         case DDERR_COLORKEYNOTSET : sprintf(dderr, "DDERR_COLORKEYNOTSET"); break;
  153.         case DDERR_SURFACEALREADYATTACHED : sprintf(dderr, "DDERR_SURFACEALREADYATTACHED"); break;
  154.         case DDERR_SURFACEALREADYDEPENDENT : sprintf(dderr, "DDERR_SURFACEALREADYDEPENDENT"); break;
  155.         case DDERR_SURFACEBUSY : sprintf(dderr, "DDERR_SURFACEBUSY"); break;
  156.         case DDERR_CANTLOCKSURFACE : sprintf(dderr, "DDERR_CANTLOCKSURFACE"); break;
  157.         case DDERR_SURFACEISOBSCURED : sprintf(dderr, "DDERR_SURFACEISOBSCURED"); break;
  158.         case DDERR_SURFACELOST : sprintf(dderr, "DDERR_SURFACELOST"); break;
  159.         case DDERR_SURFACENOTATTACHED : sprintf(dderr, "DDERR_SURFACENOTATTACHED"); break;
  160.         case DDERR_TOOBIGHEIGHT : sprintf(dderr, "DDERR_TOOBIGHEIGHT"); break;
  161.         case DDERR_TOOBIGSIZE : sprintf(dderr, "DDERR_TOOBIGSIZE"); break;
  162.         case DDERR_TOOBIGWIDTH : sprintf(dderr, "DDERR_TOOBIGWIDTH"); break;
  163.         case DDERR_UNSUPPORTED : sprintf(dderr, "DDERR_UNSUPPORTED"); break;
  164.         case DDERR_UNSUPPORTEDFORMAT : sprintf(dderr, "DDERR_UNSUPPORTEDFORMAT"); break;
  165.         case DDERR_UNSUPPORTEDMASK : sprintf(dderr, "DDERR_UNSUPPORTEDMASK"); break;
  166.         case DDERR_VERTICALBLANKINPROGRESS : sprintf(dderr, "DDERR_VERTICALBLANKINPROGRESS"); break;
  167.         case DDERR_WASSTILLDRAWING : sprintf(dderr, "DDERR_WASSTILLDRAWING"); break;
  168.         case DDERR_XALIGN : sprintf(dderr, "DDERR_XALIGN"); break;
  169.         case DDERR_INVALIDDIRECTDRAWGUID : sprintf(dderr, "DDERR_INVALIDDIRECTDRAWGUID"); break;
  170.         case DDERR_DIRECTDRAWALREADYCREATED : sprintf(dderr, "DDERR_DIRECTDRAWALREADYCREATED"); break;
  171.         case DDERR_NODIRECTDRAWHW : sprintf(dderr, "DDERR_NODIRECTDRAWHW"); break;
  172.         case DDERR_PRIMARYSURFACEALREADYEXISTS : sprintf(dderr, "DDERR_PRIMARYSURFACEALREADYEXISTS"); break;
  173.         case DDERR_NOEMULATION : sprintf(dderr, "DDERR_NOEMULATION"); break;
  174.         case DDERR_REGIONTOOSMALL : sprintf(dderr, "DDERR_REGIONTOOSMALL"); break;
  175.         case DDERR_CLIPPERISUSINGHWND : sprintf(dderr, "DDERR_CLIPPERISUSINGHWND"); break;
  176.         case DDERR_NOCLIPPERATTACHED : sprintf(dderr, "DDERR_NOCLIPPERATTACHED"); break;
  177.         case DDERR_NOHWND : sprintf(dderr, "DDERR_NOHWND"); break;
  178.         case DDERR_HWNDSUBCLASSED : sprintf(dderr, "DDERR_HWNDSUBCLASSED"); break;
  179.         case DDERR_HWNDALREADYSET : sprintf(dderr, "DDERR_HWNDALREADYSET"); break;
  180.         case DDERR_NOPALETTEATTACHED : sprintf(dderr, "DDERR_NOPALETTEATTACHED"); break;
  181.         case DDERR_NOPALETTEHW : sprintf(dderr, "DDERR_NOPALETTEHW"); break;
  182.         case DDERR_BLTFASTCANTCLIP : sprintf(dderr, "DDERR_BLTFASTCANTCLIP"); break;
  183.         case DDERR_NOBLTHW : sprintf(dderr, "DDERR_NOBLTHW"); break;
  184.         case DDERR_NODDROPSHW : sprintf(dderr, "DDERR_NODDROPSHW"); break;
  185.         case DDERR_OVERLAYNOTVISIBLE : sprintf(dderr, "DDERR_OVERLAYNOTVISIBLE"); break;
  186.         case DDERR_NOOVERLAYDEST : sprintf(dderr, "DDERR_NOOVERLAYDEST"); break;
  187.         case DDERR_INVALIDPOSITION : sprintf(dderr, "DDERR_INVALIDPOSITION"); break;
  188.         case DDERR_NOTAOVERLAYSURFACE : sprintf(dderr, "DDERR_NOTAOVERLAYSURFACE"); break;
  189.         case DDERR_EXCLUSIVEMODEALREADYSET : sprintf(dderr, "DDERR_EXCLUSIVEMODEALREADYSET"); break;
  190.         case DDERR_NOTFLIPPABLE : sprintf(dderr, "DDERR_NOTFLIPPABLE"); break;
  191.         case DDERR_CANTDUPLICATE : sprintf(dderr, "DDERR_CANTDUPLICATE"); break;
  192.         case DDERR_NOTLOCKED : sprintf(dderr, "DDERR_NOTLOCKED"); break;
  193.         case DDERR_CANTCREATEDC : sprintf(dderr, "DDERR_CANTCREATEDC"); break;
  194.         case DDERR_NODC : sprintf(dderr, "DDERR_NODC"); break;
  195.         case DDERR_WRONGMODE : sprintf(dderr, "DDERR_WRONGMODE"); break;
  196.         case DDERR_IMPLICITLYCREATED : sprintf(dderr, "DDERR_IMPLICITLYCREATED"); break;
  197.         case DDERR_NOTPALETTIZED : sprintf(dderr, "DDERR_NOTPALETTIZED"); break;
  198.         case DDERR_UNSUPPORTEDMODE : sprintf(dderr, "DDERR_UNSUPPORTEDMODE"); break;
  199.         case DDERR_NOMIPMAPHW : sprintf(dderr, "DDERR_NOMIPMAPHW"); break;
  200.         case DDERR_INVALIDSURFACETYPE : sprintf(dderr, "DDERR_INVALIDSURFACETYPE"); break;
  201.         case DDERR_DCALREADYCREATED : sprintf(dderr, "DDERR_DCALREADYCREATED"); break;
  202.         case DDERR_CANTPAGELOCK : sprintf(dderr, "DDERR_CANTPAGELOCK"); break;
  203.         case DDERR_CANTPAGEUNLOCK : sprintf(dderr, "DDERR_CANTPAGEUNLOCK"); break;
  204.         case DDERR_NOTPAGELOCKED : sprintf(dderr, "DDERR_NOTPAGELOCKED"); break;
  205.         case DDERR_NOTINITIALIZED : sprintf(dderr, "DDERR_NOTINITIALIZED"); break;
  206.  
  207.         default : sprintf(dderr, "Unknown Error"); break;
  208.     }
  209.     sprintf(err, "DirectDraw Error %s\nin file %s at line %d", dderr, sFile, nLine);
  210.     RegError(err);
  211. }
  212.  
  213. //----------------------------------------------------------------------
  214. // 
  215. // Function     : TraceErrorDS()
  216. //
  217. // Purpose      : Traces an error (DirectSound)
  218. //
  219. //----------------------------------------------------------------------
  220.  
  221. void TraceErrorDS(HRESULT hErr, char *sFile, int nLine)
  222. {       
  223.     char dserr[256];
  224.     char err[1024];
  225.  
  226.     switch (hErr)
  227.     {
  228.         case DSERR_ALLOCATED : sprintf(dserr, "DSERR_ALLOCATED"); break;
  229.         case DSERR_CONTROLUNAVAIL : sprintf(dserr, "DSERR_CONTROLUNAVAIL"); break;
  230.         case DSERR_INVALIDPARAM : sprintf(dserr, "DSERR_INVALIDPARAM"); break;
  231.         case DSERR_INVALIDCALL : sprintf(dserr, "DSERR_INVALIDCALL"); break;
  232.         case DSERR_GENERIC : sprintf(dserr, "DSERR_GENERIC"); break;
  233.         case DSERR_PRIOLEVELNEEDED : sprintf(dserr, "DSERR_PRIOLEVELNEEDED"); break;
  234.         case DSERR_OUTOFMEMORY : sprintf(dserr, "DSERR_OUTOFMEMORY"); break;
  235.         case DSERR_BADFORMAT : sprintf(dserr, "DSERR_BADFORMAT"); break;
  236.         case DSERR_UNSUPPORTED : sprintf(dserr, "DSERR_UNSUPPORTED"); break;
  237.         case DSERR_NODRIVER : sprintf(dserr, "DSERR_NODRIVER"); break;
  238.         case DSERR_ALREADYINITIALIZED : sprintf(dserr, "DSERR_ALREADYINITIALIZED"); break;
  239.         case DSERR_NOAGGREGATION : sprintf(dserr, "DSERR_NOAGGREGATION"); break;
  240.         case DSERR_BUFFERLOST : sprintf(dserr, "DSERR_BUFFERLOST"); break;
  241.         case DSERR_OTHERAPPHASPRIO : sprintf(dserr, "DSERR_OTHERAPPHASPRIO"); break;
  242.         case DSERR_UNINITIALIZED : sprintf(dserr, "DSERR_UNINITIALIZED"); break;
  243.  
  244.         default : sprintf(dserr, "Unknown Error"); break;
  245.     }
  246.     sprintf(err, "DirectSound Error %s\nin file %s at line %d", dserr, sFile, nLine);
  247.     RegError(err);
  248. }
  249.  
  250. //----------------------------------------------------------------------
  251. // 
  252. // Function     : TraceErrorD3D()
  253. //
  254. // Purpose      : Traces an error (Direct3D)
  255. //
  256. //----------------------------------------------------------------------
  257.  
  258. void TraceErrorD3D(HRESULT hErr, char *sFile, int nLine)
  259. {       
  260.     char d3derr[256];
  261.     char err[1024];
  262.  
  263.     switch (hErr)
  264.     {
  265.         case D3DERR_BADMAJORVERSION : sprintf(d3derr, "D3DERR_BADMAJORVERSION"); break;
  266.         case D3DERR_BADMINORVERSION : sprintf(d3derr, "D3DERR_BADMINORVERSION"); break;
  267.         case D3DERR_EXECUTE_CREATE_FAILED : sprintf(d3derr, "D3DERR_EXECUTE_CREATE_FAILED"); break;
  268.         case D3DERR_EXECUTE_DESTROY_FAILED : sprintf(d3derr, "D3DERR_EXECUTE_DESTROY_FAILED"); break;
  269.         case D3DERR_EXECUTE_LOCK_FAILED : sprintf(d3derr, "D3DERR_EXECUTE_LOCK_FAILED"); break;
  270.         case D3DERR_EXECUTE_UNLOCK_FAILED : sprintf(d3derr, "D3DERR_EXECUTE_UNLOCK_FAILED"); break;
  271.         case D3DERR_EXECUTE_LOCKED : sprintf(d3derr, "D3DERR_EXECUTE_LOCKED"); break;
  272.         case D3DERR_EXECUTE_NOT_LOCKED : sprintf(d3derr, "D3DERR_EXECUTE_NOT_LOCKED"); break;
  273.         case D3DERR_EXECUTE_FAILED : sprintf(d3derr, "D3DERR_EXECUTE_FAILED"); break;
  274.         case D3DERR_EXECUTE_CLIPPED_FAILED : sprintf(d3derr, "D3DERR_EXECUTE_CLIPPED_FAILED"); break;
  275.         case D3DERR_TEXTURE_NO_SUPPORT : sprintf(d3derr, "D3DERR_TEXTURE_NO_SUPPORT"); break;
  276.         case D3DERR_TEXTURE_CREATE_FAILED : sprintf(d3derr, "D3DERR_TEXTURE_CREATE_FAILED"); break;
  277.         case D3DERR_TEXTURE_DESTROY_FAILED : sprintf(d3derr, "D3DERR_TEXTURE_DESTROY_FAILED"); break;
  278.         case D3DERR_TEXTURE_LOCK_FAILED : sprintf(d3derr, "D3DERR_TEXTURE_LOCK_FAILED"); break;
  279.         case D3DERR_TEXTURE_UNLOCK_FAILED : sprintf(d3derr, "D3DERR_TEXTURE_UNLOCK_FAILED"); break;
  280.         case D3DERR_TEXTURE_LOAD_FAILED : sprintf(d3derr, "D3DERR_TEXTURE_LOAD_FAILED"); break;
  281.         case D3DERR_TEXTURE_SWAP_FAILED : sprintf(d3derr, "D3DERR_TEXTURE_SWAP_FAILED"); break;
  282.         case D3DERR_TEXTURE_LOCKED : sprintf(d3derr, "D3DERR_TEXTURE_LOCKED"); break;
  283.         case D3DERR_TEXTURE_NOT_LOCKED : sprintf(d3derr, "D3DERR_TEXTURE_NOT_LOCKED"); break;
  284.         case D3DERR_TEXTURE_GETSURF_FAILED : sprintf(d3derr, "D3DERR_TEXTURE_GETSURF_FAILED"); break;
  285.         case D3DERR_MATRIX_CREATE_FAILED : sprintf(d3derr, "D3DERR_MATRIX_CREATE_FAILED"); break;
  286.         case D3DERR_MATRIX_DESTROY_FAILED : sprintf(d3derr, "D3DERR_MATRIX_DESTROY_FAILED"); break;
  287.         case D3DERR_MATRIX_SETDATA_FAILED : sprintf(d3derr, "D3DERR_MATRIX_SETDATA_FAILED"); break;
  288.         case D3DERR_MATRIX_GETDATA_FAILED : sprintf(d3derr, "D3DERR_MATRIX_GETDATA_FAILED"); break;
  289.         case D3DERR_SETVIEWPORTDATA_FAILED : sprintf(d3derr, "D3DERR_SETVIEWPORTDATA_FAILED"); break;
  290.         case D3DERR_MATERIAL_CREATE_FAILED : sprintf(d3derr, "D3DERR_MATERIAL_CREATE_FAILED"); break;
  291.         case D3DERR_MATERIAL_DESTROY_FAILED : sprintf(d3derr, "D3DERR_MATERIAL_DESTROY_FAILED"); break;
  292.         case D3DERR_MATERIAL_SETDATA_FAILED : sprintf(d3derr, "D3DERR_MATERIAL_SETDATA_FAILED"); break;
  293.         case D3DERR_MATERIAL_GETDATA_FAILED : sprintf(d3derr, "D3DERR_MATERIAL_GETDATA_FAILED"); break;
  294.         case D3DERR_LIGHT_SET_FAILED : sprintf(d3derr, "D3DERR_LIGHT_SET_FAILED"); break;
  295.         case D3DERR_SCENE_IN_SCENE : sprintf(d3derr, "D3DERR_SCENE_IN_SCENE"); break;
  296.         case D3DERR_SCENE_NOT_IN_SCENE : sprintf(d3derr, "D3DERR_SCENE_NOT_IN_SCENE"); break;
  297.         case D3DERR_SCENE_BEGIN_FAILED : sprintf(d3derr, "D3DERR_SCENE_BEGIN_FAILED"); break;
  298.         case D3DERR_SCENE_END_FAILED : sprintf(d3derr, "D3DERR_SCENE_END_FAILED"); break;
  299.  
  300.         default : sprintf(d3derr, "Unknown Error"); break;
  301.     }
  302.     sprintf(err, "Direct3D Error %s\nin file %s at line %d", d3derr, sFile, nLine);
  303.     RegError(err);
  304. }
  305.  
  306. //----------------------------------------------------------------------
  307. // 
  308. // Function     : TraceErrorD3DRM()
  309. //
  310. // Purpose      : Traces an error (Direct3D retained mode)
  311. //
  312. //----------------------------------------------------------------------
  313.  
  314. void TraceErrorD3DRM(HRESULT hErr, char *sFile, int nLine)
  315. {       
  316.     char d3drmerr[256];
  317.     char err[1024];
  318.  
  319.     switch (hErr)
  320.     {
  321.         case D3DRMERR_BADOBJECT : sprintf(d3drmerr, "D3DRMERR_BADOBJECT"); break;
  322.         case D3DRMERR_BADTYPE : sprintf(d3drmerr, "D3DRMERR_BADTYPE"); break;
  323.         case D3DRMERR_BADALLOC : sprintf(d3drmerr, "D3DRMERR_BADALLOC"); break;
  324.         case D3DRMERR_FACEUSED : sprintf(d3drmerr, "D3DRMERR_FACEUSED"); break;
  325.         case D3DRMERR_NOTFOUND : sprintf(d3drmerr, "D3DRMERR_NOTFOUND"); break;
  326.         case D3DRMERR_NOTDONEYET : sprintf(d3drmerr, "D3DRMERR_NOTDONEYET"); break;
  327.         case D3DRMERR_FILENOTFOUND : sprintf(d3drmerr, "D3DRMERR_FILENOTFOUND"); break;
  328.         case D3DRMERR_BADFILE : sprintf(d3drmerr, "D3DRMERR_BADFILE"); break;
  329.         case D3DRMERR_BADDEVICE : sprintf(d3drmerr, "D3DRMERR_BADDEVICE"); break;
  330.         case D3DRMERR_BADVALUE : sprintf(d3drmerr, "D3DRMERR_BADVALUE"); break;
  331.         case D3DRMERR_BADMAJORVERSION : sprintf(d3drmerr, "D3DRMERR_BADMAJORVERSION"); break;
  332.         case D3DRMERR_BADMINORVERSION : sprintf(d3drmerr, "D3DRMERR_BADMINORVERSION"); break;
  333.         case D3DRMERR_UNABLETOEXECUTE : sprintf(d3drmerr, "D3DRMERR_UNABLETOEXECUTE"); break;
  334.  
  335.         default : sprintf(d3drmerr, "Unknown Error"); break;
  336.     }
  337.     sprintf(err, "Direct3D-RM Error : %s\nin file %s at line %d", d3drmerr, sFile, nLine);
  338.     RegError(err);
  339. }
  340.  
  341. //----------------------------------------------------------------------
  342. // 
  343. // Function     : SortDisplayModes()
  344. //
  345. // Purpose      : Sorts the list of display modes
  346. //
  347. //----------------------------------------------------------------------
  348.  
  349. void SortDisplayModes()
  350. {
  351.     // Sort by width * height
  352.     for (DWORD i = 0; i < g_dwNumModes; i ++)
  353.     {
  354.         for (DWORD k = 0; k < g_dwNumModes - 1; k ++)
  355.         {
  356.             int c1 = g_vidModes[k].width * g_vidModes[k].height;
  357.             int c2 = g_vidModes[k + 1].width * g_vidModes[k + 1].height;
  358.  
  359.             if (c1 > c2)
  360.             {
  361.                 VideoMode tmp;
  362.                 
  363.                 // Swap the two video modes
  364.                 tmp                     = g_vidModes[k];
  365.                 g_vidModes[k]           = g_vidModes[k + 1];
  366.                 g_vidModes[k + 1]       = tmp;
  367.  
  368.                 // Keep g_dwCurrMode up to date
  369.                 if (g_dwCurrMode == k)
  370.                 {
  371.                     g_dwCurrMode = k + 1;
  372.                 }
  373.                 else if (g_dwCurrMode == k + 1)
  374.                 {
  375.                     g_dwCurrMode = k;
  376.                 }
  377.             }
  378.         }
  379.     }
  380. }
  381.  
  382. //----------------------------------------------------------------------
  383. // 
  384. // Function     : DDEnumCallBack()
  385. //
  386. // Purpose      : Call back to enumerate installed DirectDraw devices
  387. //
  388. //----------------------------------------------------------------------
  389.  
  390. BOOL FAR PASCAL DDEnumCallback(GUID FAR* lpGUID, LPSTR lpDriverDesc, LPSTR lpDriverName, LPVOID lpContext)
  391. {
  392.     LPDIRECTDRAW lpDD;
  393.     DDCAPS DriverCaps, HELCaps;
  394.  
  395.         // Make sure the guid is valid
  396.     if (lpGUID) 
  397.     {
  398.         // Try to create a DirectDraw object
  399.         TRY_DD(DirectDrawCreate(lpGUID, &lpDD, NULL))
  400.         
  401.         // Get the DirectDraw capabilities
  402.         memset(&DriverCaps, 0, sizeof(DDCAPS));
  403.         DriverCaps.dwSize = sizeof(DDCAPS);
  404.         
  405.         memset(&HELCaps, 0, sizeof(DDCAPS));
  406.         HELCaps.dwSize = sizeof(DDCAPS);
  407.         
  408.         TRY_DD(lpDD->GetCaps(&DriverCaps, &HELCaps))
  409.  
  410.         // Does this driver have 3D hardware capabilites?
  411.         if (DriverCaps.dwCaps & DDCAPS_3D) 
  412.         {
  413.             *(LPDIRECTDRAW*)lpContext = lpDD;
  414.             return DDENUMRET_CANCEL;
  415.         }
  416.  
  417.         *(LPDIRECTDRAW*)lpContext = NULL;
  418.         lpDD->Release();
  419.     }
  420.  
  421.         // Yahoo!
  422.     return DDENUMRET_OK;
  423. }
  424.  
  425. //----------------------------------------------------------------------
  426. // 
  427. // Function     : DDEnumDisplayModesCallBack()
  428. //
  429. // Purpose      : Call back function to receive display mode information
  430. //
  431. //----------------------------------------------------------------------
  432.  
  433. HRESULT CALLBACK DDEnumDisplayModesCallback(LPDDSURFACEDESC pddsd, LPVOID Context)
  434. {       
  435.     // While each mode gets enumerated we have to decide whether 
  436.     // the 3D device and mode are compatible
  437.     if (g_deviceInfo.lpHWGuid)
  438.     {           
  439.         // Make sure there is enough video ram to support this mode
  440.         //if hardware is in use
  441.         DWORD dwBitDepthMultiplier;
  442.         
  443.         switch(pddsd->ddpfPixelFormat.dwRGBBitCount)
  444.         {
  445.             case 8  : dwBitDepthMultiplier = 1; break;
  446.             case 16 : dwBitDepthMultiplier = 2; break;
  447.             case 24 : dwBitDepthMultiplier = 3; break;
  448.             case 32 : dwBitDepthMultiplier = 4; break;
  449.         }
  450.  
  451.         DWORD dwVidRamNeeded = ((pddsd->dwWidth * pddsd->dwHeight) * dwBitDepthMultiplier) * 3;
  452.  
  453.         if (dwVidRamNeeded > (g_driverCaps.dwVidMemFree + g_dwGDIMem))
  454.           return DDENUMRET_OK;
  455.  
  456.         // Make sure the Direct3D device can render at a given bit depth
  457.         switch (pddsd->ddpfPixelFormat.dwRGBBitCount)
  458.         {
  459.             case 8 : 
  460.             {
  461.                 if (!(g_deviceInfo.HWDeviceDesc.dwDeviceRenderBitDepth & DDBD_8)) return DDENUMRET_OK;
  462.             }
  463.             break;
  464.  
  465.             case 16 :
  466.             {
  467.                 if (!(g_deviceInfo.HWDeviceDesc.dwDeviceRenderBitDepth & DDBD_16)) return DDENUMRET_OK;
  468.             }
  469.             break;
  470.  
  471.             case 24 : 
  472.             {
  473.                 if (!(g_deviceInfo.HWDeviceDesc.dwDeviceRenderBitDepth & DDBD_24)) return DDENUMRET_OK;
  474.             }
  475.             break;
  476.  
  477.             case 32 :
  478.             {
  479.                 if (!(g_deviceInfo.HWDeviceDesc.dwDeviceRenderBitDepth & DDBD_32)) return DDENUMRET_OK;
  480.             }
  481.             break;
  482.         }
  483.  
  484.         // If we have hardware, start up in 640x480x16 if possible
  485.         if ((pddsd->dwWidth == 640) && (pddsd->dwHeight == 480) && (pddsd->ddpfPixelFormat.dwRGBBitCount == 16))
  486.         {
  487.             g_dwCurrMode = g_dwNumModes;
  488.         }
  489.     }
  490.  
  491.     // Record the video mode information
  492.     g_vidModes[g_dwNumModes].width  = pddsd->dwWidth;
  493.     g_vidModes[g_dwNumModes].height = pddsd->dwHeight;
  494.     g_vidModes[g_dwNumModes].bpp    = pddsd->ddpfPixelFormat.dwRGBBitCount;
  495.     
  496.     g_dwNumModes ++;
  497.             
  498.     return DDENUMRET_OK;
  499. }
  500.  
  501. //------------------------------------------------------------------
  502. // 
  503. // Function     : D3DEnumDriverCallBack()
  504. //
  505. // Purpose      : Enumeration Function
  506. //
  507. //------------------------------------------------------------------
  508.  
  509. HRESULT WINAPI D3DEnumDeviceCallBack(LPGUID lpGuid,     
  510.                                      LPSTR lpDeviceDescription,
  511.                                      LPSTR lpDeviceName,
  512.                                      LPD3DDEVICEDESC lpHWDesc, 
  513.                                      LPD3DDEVICEDESC lpHELDesc, 
  514.                                      LPVOID lpContext)
  515. {
  516.     static BOOL bFoundHardwareDevice = FALSE;   
  517.  
  518.     // No need to enumerate if we already found the device that supports
  519.     if (bFoundHardwareDevice) return D3DENUMRET_OK;
  520.  
  521.     D3DDeviceInfo* pInfo = (D3DDeviceInfo *)lpContext;
  522.     
  523.     // Is this a hardware device?
  524.     if (lpHWDesc->dcmColorModel & pInfo->cm)
  525.     {
  526.         // Driver needs to pass some tests....
  527.  
  528.         // Make sure the driver has ZBuffering capabilities
  529.         if ((lpHWDesc->dwDeviceZBufferBitDepth & DDBD_16) || 
  530.             (lpHWDesc->dwDeviceZBufferBitDepth & DDBD_24) ||
  531.             (lpHWDesc->dwDeviceZBufferBitDepth & DDBD_32))
  532.         {                                       
  533.             // Record the HAL description for later use
  534.             memcpy(&pInfo->HWDeviceDesc, lpHWDesc, sizeof(D3DDEVICEDESC));
  535.  
  536.             // Record the guid for later use
  537.             pInfo->lpHWGuid = lpGuid;
  538.             
  539.             // No need to keep looking for any more devices
  540.             bFoundHardwareDevice = TRUE;
  541.         }
  542.         
  543.         // Yahoo!
  544.         return D3DENUMRET_OK;
  545.     }
  546.  
  547.     // Is this a software device?
  548.     if (lpHELDesc->dcmColorModel & pInfo->cm) 
  549.     {
  550.         // Record the HEL description for later use
  551.         memcpy(&pInfo->SWDeviceDesc, lpHELDesc, sizeof(D3DDEVICEDESC));
  552.             
  553.         // Record the guid for later use
  554.         pInfo->lpSWGuid = lpGuid;
  555.             
  556.         g_lpD3DDeviceGuid = lpGuid;
  557.     }
  558.  
  559.     return D3DENUMRET_OK;
  560. }
  561.  
  562. //----------------------------------------------------------------------
  563. // 
  564. // Function     : InitD3DDevice()
  565. //
  566. // Purpose      : Performs initialisation for correct Direct3D device
  567. //                        RGB, MONO, HAL etc
  568. //
  569. //----------------------------------------------------------------------
  570.  
  571. BOOL InitD3DDevice()
  572. {
  573.     memset(&g_deviceInfo, 0, sizeof(D3DDeviceInfo));
  574.  
  575.     // Use RGB colour if in hardware, RAMP if in software       
  576.  
  577.     // Record the colour model that we wish to search for in the structure passed
  578.     // to the enumeration call back
  579.     g_deviceInfo.cm = g_bHardware3D ? D3DCOLOR_RGB : D3DCOLOR_MONO;;
  580.     
  581.     // Enumerate the drivers
  582.     TRY_D3D(g_lpD3D->EnumDevices(D3DEnumDeviceCallBack, &g_deviceInfo)) 
  583.  
  584.     // Test to see whether we have hardware or software
  585.     if (g_deviceInfo.lpHWGuid)
  586.     {
  587.         // We have a hardware driver!
  588.  
  589.         // Use a video memory based ZBuffer
  590.         g_dwZBufferMemType = DDSCAPS_VIDEOMEMORY;
  591.  
  592.         // Use 16 bit ZBuffering if possible, higher if not
  593.         if (g_deviceInfo.HWDeviceDesc.dwDeviceZBufferBitDepth & DDBD_16)
  594.         {
  595.             g_dwZBufferBitDepth = 16;
  596.         }
  597.         else if (g_deviceInfo.HWDeviceDesc.dwDeviceZBufferBitDepth & DDBD_24)
  598.         {
  599.             g_dwZBufferBitDepth = 24;
  600.         }
  601.         else if (g_deviceInfo.HWDeviceDesc.dwDeviceZBufferBitDepth & DDBD_32)
  602.         {
  603.             g_dwZBufferBitDepth = 32;
  604.         }
  605.         else
  606.         {
  607.             g_dwZBufferBitDepth = 0;
  608.         }
  609.         
  610.         // Use Hardware device
  611.         g_lpD3DDeviceGuid = g_deviceInfo.lpHWGuid;
  612.     }
  613.     else
  614.     {
  615.         // We have a software driver!
  616.  
  617.         // Use a system memory based ZBuffer
  618.         g_dwZBufferMemType = DDSCAPS_SYSTEMMEMORY;
  619.  
  620.         // And force the bit depth to 16
  621.         g_dwZBufferBitDepth = 16;
  622.  
  623.         // Default to the software device
  624.         g_lpD3DDeviceGuid = g_deviceInfo.lpSWGuid;
  625.     }
  626.  
  627.     // Yahoo!
  628.     return TRUE;
  629. }
  630.  
  631. //----------------------------------------------------------------------
  632. // 
  633. // Function     : InitDirectX()
  634. //
  635. // Purpose      : Initialises DirectX (DirectDraw, Direct3D, Direct3DRM, DirectSound)
  636. //
  637. //----------------------------------------------------------------------
  638.  
  639. BOOL InitDirectX()
  640. {
  641.     FILE        *fp;
  642.     BYTE        pal[768];
  643.     HRESULT     rval;
  644.     DDSURFACEDESC ddsd;
  645.  
  646.     // Enumerate DirectDraw drivers to see what is installed, preferring one with
  647.     // Hardware 3D capabilities
  648.     TRY_DD(DirectDrawEnumerate(DDEnumCallback, &g_lpDD))
  649.  
  650.     // If g_lpDD is NULL, there isn't a DirectDraw device with hardware 3D capabilities,
  651.     // so create a device using the HEL 
  652.     if (!g_lpDD)
  653.     {
  654.             TRY_DD(DirectDrawCreate(NULL, &g_lpDD, NULL))
  655.     }
  656.  
  657.     // NOTE : Exclusive mode would normally be set here but because of the splash
  658.     // screen being displayed it isn't. The reason is that the splash screen uses
  659.     // 640x480x8 and that mode may not be available if we are using a hardware 3D
  660.     // DirectDraw device.
  661.  
  662.     // Zero out caps structures
  663.     memset(&g_driverCaps, 0, sizeof(DDCAPS));
  664.     g_driverCaps.dwSize = sizeof(DDCAPS);
  665.  
  666.     memset(&g_HELcaps, 0, sizeof(DDCAPS));
  667.     g_HELcaps.dwSize = sizeof(DDCAPS);
  668.  
  669.     // Get the current display mode as we can use that memory when full
  670.     // screen exclusive
  671.     memset(&ddsd, 0, sizeof ddsd);
  672.     ddsd.dwSize = sizeof ddsd;
  673.     TRY_DD(g_lpDD->GetDisplayMode(&ddsd));
  674.     g_dwGDIMem = ddsd.lPitch * ddsd.dwHeight *
  675.       (ddsd.ddpfPixelFormat.dwRGBBitCount / 8);
  676.  
  677.     // Get hardware capabilities
  678.     TRY_DD(g_lpDD->GetCaps(&g_driverCaps, &g_HELcaps));
  679.  
  680.     // Global to determine whether we have hardware 3D capabilities or not
  681.     g_bHardware3D = g_driverCaps.dwCaps & DDCAPS_3D;
  682.  
  683.     // Create Direct3D object
  684.     TRY_D3D(g_lpDD->QueryInterface(IID_IDirect3D, (LPVOID *)&g_lpD3D));
  685.  
  686.     // Enumerate Direct3D devices, preferring hardware rendering over software
  687.     if (!InitD3DDevice())
  688.     {
  689.             RegError("Error locating suitable Direct3D driver!");
  690.             return FALSE;
  691.     }
  692.  
  693.     // Enumerate all the display modes, this is done after locating the 3D device so
  694.     // that any mode that is not compatible with the 3D device does not get added to
  695.     // the list of valid modes.
  696.     TRY_DD(g_lpDD->EnumDisplayModes(0, NULL, NULL, DDEnumDisplayModesCallback))
  697.  
  698.     // Sort display modes into lowest width * height first
  699.     SortDisplayModes();
  700.  
  701.     // Create Direct3D RM object
  702.     TRY_D3DRM(Direct3DRMCreate(&g_lpD3DRM))
  703.  
  704.     // Set default amount of texture colours
  705.     g_lpD3DRM->SetDefaultTextureColors(16);
  706.     
  707.     // Set default amount of texture shades
  708.     g_lpD3DRM->SetDefaultTextureShades(16);
  709.  
  710.     // Create DirectSound object
  711.     rval = DirectSoundCreate(NULL, &g_lpDS, NULL);
  712.     
  713.     // Determine whether sound is present
  714.     g_bSoundPresent = rval == DS_OK ? TRUE : FALSE;
  715.  
  716.     if (g_bSoundPresent)
  717.     {
  718.         // Set the DirectSound cooperative level
  719.         TRY_DS(g_lpDS->SetCooperativeLevel(g_hWnd, DSSCL_NORMAL))
  720.  
  721.                 // Create the Direct 3D Sound Buffer
  722.                 g_3DSoundBuffer = CreateSoundBuffer3D();
  723.                 if(g_3DSoundBuffer == NULL)
  724.                 {
  725.                         RegError("Not able to create Direct 3D Sound Buffer");
  726.             return FALSE;
  727.                 }
  728.                 // Query interface for Direct 3D Sound Listener object
  729.                 if(DS_OK != g_3DSoundBuffer->QueryInterface(IID_IDirectSound3DListener, (void**)&g_lpDs3dListener))
  730.                 {
  731.                         RegError("Not able to create Direct 3D Sound Listener object");
  732.             return FALSE;
  733.                 }
  734.                 // Set the Direct 3D Sound Rolloff Factor
  735.                 g_lpDs3dListener->SetRolloffFactor((FLOAT).01,DS3D_DEFERRED);
  736.                 // Change listener's orientation
  737.                 g_lpDs3dListener->SetOrientation(-D3DVAL(1), D3DVAL(0), D3DVAL(0), D3DVAL(0), D3DVAL(1), D3DVAL(0),DS3D_DEFERRED);
  738.                 // Commit the changes to Rolloff Factor and orientation
  739.                 g_lpDs3dListener->CommitDeferredSettings();
  740.  
  741.         // Null out all the sound pointers
  742.         for (int i = 0; i < NUM_SOUNDS; i ++)
  743.         {
  744.             g_lpSounds[i] = NULL;
  745.         }
  746.  
  747.         // Load the sounds      
  748.         if (!CreateBufferFromWaveFile("INTRO.WAV", INTRO))
  749.         {
  750.             RegError("Couldn't load INTRO.WAV!");
  751.             return FALSE;
  752.         }
  753.         
  754.         if (!CreateBufferFromWaveFile("PUNCH1.WAV", PLAYER1_PUNCH1))
  755.         {
  756.             RegError("Couldn't load PUNCH1.WAV!");
  757.             return FALSE;
  758.         }
  759.         
  760.         if (!CreateBufferFromWaveFile("PUNCH3.WAV", PLAYER1_PUNCH2))
  761.         {
  762.             RegError("Couldn't load PUNCH3.WAV!");
  763.             return FALSE;
  764.         }
  765.         
  766.         if (!CreateBufferFromWaveFile("PUNCH2.WAV", PLAYER2_PUNCH1))
  767.         {
  768.             RegError("Couldn't load PUNCH2.WAV!");
  769.             return FALSE;
  770.         }
  771.  
  772.         if (!CreateBufferFromWaveFile("PUNCH4.WAV", PLAYER2_PUNCH2))    
  773.         {
  774.             RegError("Couldn't load PUNCH4.WAV!");
  775.             return FALSE;
  776.         }
  777.         
  778.         if (!CreateBufferFromWaveFile("WALK0.WAV", PLAYER1_WALK))
  779.         {
  780.             RegError("Couldn't load WALK0.WAV!");
  781.             return FALSE;
  782.         }
  783.  
  784.         if (!CreateBufferFromWaveFile("WALK1.WAV", PLAYER2_WALK))
  785.         {
  786.             RegError("Couldn't load WALK1.WAV!");
  787.             return FALSE;
  788.         }
  789.  
  790.         if (!CreateBufferFromWaveFile("WHOOSH1.WAV", WHOOSH1))  
  791.         {
  792.             RegError("Couldn't load WHOOSH1.WAV!");
  793.             return FALSE;
  794.         }
  795.         
  796.         if (!CreateBufferFromWaveFile("WHOOSH2.WAV", WHOOSH2))
  797.         {
  798.             RegError("Couldn't load WHOOSH2.WAV!");
  799.             return FALSE;
  800.         }
  801.  
  802.         if (!CreateBufferFromWaveFile("DEFEND1.WAV", PLAYER1_OUCH))
  803.         {
  804.             RegError("Couldn't load DEFEND1.WAV!");
  805.             return FALSE;
  806.         }
  807.  
  808.         if (!CreateBufferFromWaveFile("DEFEND2.WAV", PLAYER2_OUCH))
  809.         {
  810.             RegError("Couldn't load DEFEND2.WAV!");
  811.             return FALSE;
  812.         }
  813.         
  814.         if (!CreateBufferFromWaveFile("HEAD.WAV", HEAD_SPRING))
  815.         {
  816.             RegError("Couldn't load HEAD.WAV!");
  817.             return FALSE;
  818.         }
  819.  
  820.         if (!CreateBufferFromWaveFile("BLOCK1.WAV", BLOCK1))
  821.         {
  822.             RegError("Couldn't load BLOCK1.WAV!");
  823.             return FALSE;
  824.         }
  825.  
  826.         if (!CreateBufferFromWaveFile("BLOCK2.WAV", BLOCK2))
  827.         {
  828.             RegError("Couldn't load BLOCK2.WAV!");
  829.             return FALSE;
  830.         }
  831.         
  832.         if (!CreateBufferFromWaveFile("BLOCK3.WAV", BLOCK3))
  833.         {
  834.             RegError("Couldn't load BLOCK3.WAV!");
  835.             return FALSE;
  836.         }
  837.         
  838.         if (!CreateBufferFromWaveFile("CLOOP.WAV", CROWD_LOOP))
  839.         {
  840.             RegError("Couldn't load CLOOP.WAV!");
  841.             return FALSE;
  842.         }
  843.         
  844.         if (!CreateBufferFromWaveFile("CBOO.WAV", VICTORY_BOO))
  845.         {
  846.             RegError("Couldn't load CBOO.WAV!");
  847.             return FALSE;
  848.         }
  849.         
  850.         if (!CreateBufferFromWaveFile("CYEAH.WAV", VICTORY_YEAH))
  851.         {
  852.             RegError("Couldn't load CYEAH.WAV!");
  853.             return FALSE;
  854.         }
  855.  
  856.         if (!CreateBufferFromWaveFile("REVUP1.WAV", SERVO_UP_1))
  857.         {
  858.             RegError("Couldn't load REVUP1.WAV!");
  859.             return FALSE;
  860.         }
  861.         
  862.         if (!CreateBufferFromWaveFile("REVUP2.WAV", SERVO_UP_2))
  863.         {
  864.             RegError("Couldn't load REVUP2.WAV!");
  865.             return FALSE;
  866.         }
  867.         
  868.         if (!CreateBufferFromWaveFile("REVUP3.WAV", SERVO_UP_3))
  869.         {
  870.             RegError("Couldn't load REVUP3.WAV!");
  871.             return FALSE;
  872.         }
  873.         
  874.         if (!CreateBufferFromWaveFile("REVDN1.WAV", SERVO_DOWN_1))
  875.         {
  876.             RegError("Couldn't load REVDOWN1.WAV!");
  877.             return FALSE;
  878.         }
  879.         
  880.         if (!CreateBufferFromWaveFile("REVDN2.WAV", SERVO_DOWN_2))
  881.         {
  882.             RegError("Couldn't load REVDOWN2.WAV!");
  883.             return FALSE;
  884.         }
  885.         
  886.         if (!CreateBufferFromWaveFile("REVDN3.WAV", SERVO_DOWN_3))
  887.         {
  888.             RegError("Couldn't load REVDOWN3.WAV!");
  889.             return FALSE;
  890.         }
  891.                 if (!CreateBufferFromWaveFile("RANDOM1.WAV", RANDOM1))
  892.         {
  893.             RegError("Couldn't load RANDOM1.WAV!");
  894.             return FALSE;
  895.         }
  896.                 if (!CreateBufferFromWaveFile("RANDOM2.WAV", RANDOM2))
  897.         {
  898.             RegError("Couldn't load RANDOM2.WAV!");
  899.             return FALSE;
  900.         }
  901.                 if (!CreateBufferFromWaveFile("RANDOM3.WAV", RANDOM3))
  902.         {
  903.             RegError("Couldn't load RANDOM3.WAV!");
  904.             return FALSE;
  905.         }
  906.                 if (!CreateBufferFromWaveFile("RANDOM4.WAV", RANDOM4))
  907.         {
  908.             RegError("Couldn't load RANDOM4.WAV!");
  909.             return FALSE;
  910.         }
  911.                 if (!CreateBufferFromWaveFile("RANDOM5.WAV", RANDOM5))
  912.         {
  913.             RegError("Couldn't load RANDOM5.WAV!");
  914.             return FALSE;
  915.         }
  916.                 if (!CreateBufferFromWaveFile("RANDOM6.WAV", RANDOM6))
  917.         {
  918.             RegError("Couldn't load RANDOM6.WAV!");
  919.             return FALSE;
  920.         }
  921.     }
  922.                             
  923.     // Load Rockem3D's palette
  924.     fp = fopen("ROCKEM3D.PAL", "rb");
  925.     if (!fp)
  926.     {
  927.         RegError("Couldn't load ROCKEM3D.PAL!");
  928.         return FALSE;
  929.     }
  930.  
  931.     // Read in the raw rgb's
  932.     fread(pal, 768, 1, fp);
  933.     
  934.     // Close the file
  935.     fclose(fp); 
  936.             
  937.     // Set up palette 
  938.     g_rPal[0].peFlags   = D3DPAL_READONLY;
  939.     g_rPal[253].peFlags = D3DPAL_READONLY;
  940.     g_rPal[254].peFlags = D3DPAL_READONLY;
  941.     g_rPal[255].peFlags = D3DPAL_READONLY;
  942.     
  943.     for (int i = 1; i < 253; i++)
  944.     {
  945.         g_rPal[i].peRed   = pal[i * 3];
  946.         g_rPal[i].peGreen = pal[(i * 3) + 1];
  947.         g_rPal[i].peBlue  = pal[(i * 3) + 2];                   
  948.         g_rPal[i].peFlags = D3DPAL_READONLY;
  949.     }
  950.     
  951.     // Set the entries 253 and 254 to a colour for the power bars
  952.     g_rPal[253].peRed   = 0;
  953.     g_rPal[253].peGreen = 0;
  954.     g_rPal[253].peBlue  = 255;
  955.  
  956.     g_rPal[254].peRed   = 255;
  957.     g_rPal[254].peGreen = 0;
  958.     g_rPal[254].peBlue  = 0;
  959.  
  960.     // Yahoo!
  961.     return TRUE;
  962. }
  963.  
  964. //----------------------------------------------------------------------
  965. // 
  966. // Function     : SetDirectDrawExclusiveMode()
  967. //
  968. // Purpose      : Sets exclusive mode for DirectDraw
  969. //
  970. //----------------------------------------------------------------------
  971.  
  972. BOOL SetDirectDrawExclusiveMode()
  973. {
  974.     TRY_DD(g_lpDD->SetCooperativeLevel(g_hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX))
  975.  
  976.     // Yahoo!
  977.     return TRUE;
  978. }
  979.  
  980.  
  981. //----------------------------------------------------------------------
  982. // 
  983. // Function     : TermDirectX()
  984. //
  985. // Purpose      : Destroys all the DirectX objects
  986. //
  987. //----------------------------------------------------------------------
  988.  
  989. void TermDirectX()
  990. {
  991.     // Destroy everything in the reverse order in which they were created
  992.         int i;
  993.  
  994.     // Destroy rendering device
  995.     if (g_lpD3DDevice)
  996.     {
  997.         g_lpD3DDevice->Release();
  998.         g_lpD3DDevice = NULL;
  999.     }
  1000.  
  1001.     // Destroy all surfaces
  1002.     if (g_lpZBuffer)
  1003.     {
  1004.         g_lpZBuffer->Release();
  1005.         g_lpZBuffer = NULL;
  1006.     }
  1007.  
  1008.     if (g_lpBackBuffer)
  1009.     {
  1010.         g_lpBackBuffer->Release();
  1011.         g_lpBackBuffer = NULL;
  1012.     }
  1013.  
  1014.     if (g_lpPrimary)
  1015.     {
  1016.         g_lpPrimary->Release();
  1017.         g_lpPrimary = NULL;
  1018.     }
  1019.  
  1020.     // Restore the original video mode  
  1021.     if(g_lpDD)
  1022.         g_lpDD->RestoreDisplayMode();
  1023.  
  1024.     // Destroy sounds
  1025.     for (i = 0; i < NUM_SOUNDS; i ++)
  1026.     {
  1027.         if (g_lpSounds[i])
  1028.         {       
  1029.             g_lpSounds[i]->Release();
  1030.             g_lpSounds[i] = NULL;
  1031.         }
  1032.     }
  1033.  
  1034.         // Destroy DirectSound3D buffers
  1035.     for (i = 0; i < NUM_SOUNDS; i ++)
  1036.     {
  1037.         if (g_lp3dSounds[i])
  1038.         {       
  1039.             g_lp3dSounds[i]->Release();
  1040.             g_lp3dSounds[i] = NULL;
  1041.         }
  1042.     }
  1043.         
  1044.         // Destroy DirectSound3D Listener object
  1045.     if (g_lpDs3dListener)
  1046.     {
  1047.         g_lpDs3dListener->Release();
  1048.         g_lpDs3dListener = NULL;
  1049.     }
  1050.         // Destroy DirectSound3D Primary buffer
  1051.     if (g_3DSoundBuffer)
  1052.     {
  1053.         g_3DSoundBuffer->Release();
  1054.         g_3DSoundBuffer = NULL;
  1055.     } 
  1056.  
  1057.     // Destroy DirectSound object
  1058.     if (g_lpDS)
  1059.     {
  1060.         g_lpDS->Release();
  1061.         g_lpDS = NULL;
  1062.     }
  1063.     
  1064.     // Destroy Direct3D RM object
  1065.     if (g_lpD3DRM)
  1066.     {
  1067.         g_lpD3DRM->Release();
  1068.         g_lpD3DRM = NULL;
  1069.     }
  1070.  
  1071.     // Destroy Direct3D object
  1072.     if (g_lpD3D)
  1073.     {
  1074.         g_lpD3D->Release();
  1075.         g_lpD3D = NULL;
  1076.     }
  1077.  
  1078.     // Destroy DirectDraw object
  1079.     if (g_lpDD)
  1080.     {
  1081.         g_lpDD->Release();
  1082.         g_lpDD = NULL;
  1083.     }
  1084. }
  1085.  
  1086. //----------------------------------------------------------------------
  1087. // 
  1088. // Function     : SoftwareGUID();
  1089. //
  1090. // Purpose      : Returns a pointer to a software driver GUID
  1091. //
  1092. //----------------------------------------------------------------------
  1093. HRESULT SoftwareGUID(LPGUID* ret_guid)
  1094. {
  1095.     static D3DFINDDEVICERESULT result;
  1096.     D3DFINDDEVICESEARCH search;
  1097.     HRESULT err;
  1098.     
  1099.     memset(&search, 0, sizeof search);
  1100.     search.dwSize = sizeof search;
  1101.     search.dwFlags = D3DFDS_HARDWARE | D3DFDS_COLORMODEL;
  1102.     search.bHardware = FALSE;
  1103.     search.dcmColorModel = D3DCOLOR_RGB;
  1104.     result.dwSize = sizeof(D3DFINDDEVICERESULT);
  1105.  
  1106.     if (err = g_lpD3D->FindDevice(&search, &result))
  1107.     return err;
  1108.     *ret_guid = &result.guid;
  1109.     return D3D_OK;
  1110. }
  1111.  
  1112.  
  1113. //----------------------------------------------------------------------
  1114. // 
  1115. // Function     : EnterVideoMode()
  1116. //
  1117. // Purpose      : Calls EnterVideoModeWHBD with mode information
  1118. //
  1119. //----------------------------------------------------------------------
  1120.  
  1121. BOOL EnterVideoMode(int mode)
  1122. {
  1123.     int width    = g_vidModes[mode].width;
  1124.     int height   = g_vidModes[mode].height;
  1125.     int bitdepth = g_vidModes[mode].bpp;
  1126.     g_dwCurrMode = mode;
  1127.  
  1128.     // Try to enter video mode described by width, height and bitdepth
  1129.     return EnterVideoModeWHBD(width, height, bitdepth);
  1130. }
  1131.  
  1132. //----------------------------------------------------------------------
  1133. // 
  1134. // Function     : EnterVideoModeWHBD()
  1135. //
  1136. // Purpose      : Switches video mode and creates all neccessary structures
  1137. //                        required for rendering
  1138. //
  1139. //----------------------------------------------------------------------
  1140.  
  1141. BOOL EnterVideoModeWHBD(int width, int height, int bitdepth)
  1142. {
  1143.     DDSURFACEDESC ddsd;
  1144.     DDSCAPS ddscaps;
  1145.  
  1146.     // Destroy all existing viewports, devices and surfaces     
  1147.     
  1148.     // Destroy Direct3D RM viewport
  1149.     if (g_lpD3DRMViewport)
  1150.     {   
  1151.         g_lpD3DRMViewport->Release();
  1152.         g_lpD3DRMViewport = NULL;
  1153.     }
  1154.  
  1155.     // Destroy Direct3D RM device
  1156.     if (g_lpD3DRMDevice)
  1157.     {
  1158.         g_lpD3DRMDevice->Release();
  1159.         g_lpD3DRMDevice = NULL;
  1160.     }
  1161.  
  1162.     // Destroy Direct3D device
  1163.     if (g_lpD3DDevice)
  1164.     {
  1165.         g_lpD3DDevice->Release();
  1166.         g_lpD3DDevice = NULL;
  1167.     }
  1168.  
  1169.     // Destroy ZBuffer
  1170.     if (g_lpZBuffer)
  1171.     {
  1172.         g_lpZBuffer->Release();
  1173.         g_lpZBuffer = NULL;
  1174.     }
  1175.  
  1176.     // Destroy Primary surface
  1177.     if (g_lpPrimary)
  1178.     {
  1179.         g_lpPrimary->Release();
  1180.         g_lpPrimary = NULL;
  1181.     }
  1182.  
  1183.     // Switch video mode
  1184.     TRY_DD(g_lpDD->SetDisplayMode(width, height, bitdepth))
  1185.  
  1186.     // First, create complex flipping primary surface
  1187.     
  1188.     // Fill out surface description
  1189.     memset(&ddsd, sizeof(DDSURFACEDESC), 0);
  1190.     ddsd.dwSize                 = sizeof(DDSURFACEDESC);
  1191.     ddsd.dwFlags                = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
  1192.     ddsd.ddsCaps.dwCaps         = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX | DDSCAPS_3DDEVICE;
  1193.     ddsd.dwBackBufferCount      = 1;
  1194.  
  1195.     // Create the primary surface with 1 back buffer
  1196.     TRY_DD(g_lpDD->CreateSurface(&ddsd, &g_lpPrimary, NULL))
  1197.  
  1198.     // Get pointer to back buffer
  1199.     ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
  1200.     TRY_DD(g_lpPrimary->GetAttachedSurface(&ddscaps, &g_lpBackBuffer))
  1201.  
  1202.     // Only create a ZBuffer if g_dwZBufferBitDepth > 0
  1203.     if (g_dwZBufferBitDepth)
  1204.     {
  1205.     HRESULT err;
  1206.  
  1207.         // Then, create Z-Buffer. The g_dwZBufferMemType and g_dwZBufferBitDepth variables
  1208.         // are set up when the Direct3D device enumeration is done at runtime
  1209.         memset(&ddsd, sizeof(DDSURFACEDESC), 0);
  1210.         ddsd.dwSize             = sizeof(DDSURFACEDESC);
  1211.         ddsd.dwFlags            = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_ZBUFFERBITDEPTH;;
  1212.         ddsd.dwWidth            = width;
  1213.         ddsd.dwHeight           = height;
  1214.         ddsd.ddsCaps.dwCaps     = DDSCAPS_ZBUFFER | g_dwZBufferMemType;
  1215.         ddsd.dwZBufferBitDepth  = g_dwZBufferBitDepth;
  1216.  
  1217.         // Create the ZBuffer
  1218.     if (err = g_lpDD->CreateSurface(&ddsd, &g_lpZBuffer, NULL))
  1219.     {
  1220.         if (err == DDERR_OUTOFVIDEOMEMORY)
  1221.         {
  1222.         // Out of video memory - create system memory zbuffer for software renderer
  1223.         memset(&ddsd, sizeof(DDSURFACEDESC), 0);
  1224.         ddsd.dwSize             = sizeof(DDSURFACEDESC);
  1225.         ddsd.dwFlags            = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_ZBUFFERBITDEPTH;;
  1226.         ddsd.dwWidth            = width;
  1227.         ddsd.dwHeight           = height;
  1228.         ddsd.ddsCaps.dwCaps     = DDSCAPS_ZBUFFER | DDSCAPS_SYSTEMMEMORY;
  1229.         ddsd.dwZBufferBitDepth  = 16;
  1230.         if (err = g_lpDD->CreateSurface(&ddsd, &g_lpZBuffer, NULL))
  1231.         {
  1232.             TRY_DD(err);
  1233.         }
  1234.         else
  1235.         {
  1236.             g_bOutOfVideoMemory = TRUE;
  1237.         }
  1238.         }
  1239.         else
  1240.         {
  1241.         TRY_DD(err);
  1242.         }
  1243.     }
  1244.     else
  1245.     {
  1246.         g_bOutOfVideoMemory = FALSE;
  1247.     }
  1248.  
  1249.         // Attach ZBuffer to the back buffer
  1250.         TRY_DD(g_lpBackBuffer->AddAttachedSurface(g_lpZBuffer))
  1251.     }
  1252.  
  1253.     // Retrieve the caps of the primary surface
  1254.     TRY_DD(g_lpPrimary->GetCaps(&ddscaps))
  1255.  
  1256.     // Create and attach palette (only if we in 8-bit palettized colour modes)
  1257.     if ((bitdepth == 8) && (ddscaps.dwCaps & DDCAPS_PALETTE))
  1258.     {
  1259.         // Create the palette
  1260.         TRY_DD(g_lpDD->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE, g_rPal, &g_lpPalette, NULL))
  1261.         
  1262.         // Set the back buffer's palette
  1263.         TRY_DD(g_lpBackBuffer->SetPalette(g_lpPalette))
  1264.  
  1265.         // Set the primary surface's palette
  1266.         TRY_DD(g_lpPrimary->SetPalette(g_lpPalette))
  1267.     }
  1268.  
  1269.     // Create Direct3D device
  1270.     if (!g_bOutOfVideoMemory)
  1271.     {
  1272.     TRY_D3D(g_lpBackBuffer->QueryInterface(*g_lpD3DDeviceGuid, (LPVOID *)&g_lpD3DDevice))
  1273.     }
  1274.     else 
  1275.     {
  1276.     LPGUID guidSoftware;
  1277.     TRY_D3D(SoftwareGUID(&guidSoftware))
  1278.     TRY_D3D(g_lpBackBuffer->QueryInterface(*guidSoftware, (LPVOID*)&g_lpD3DDevice))
  1279.     }
  1280.  
  1281.     // Create Direct3D RM Device from Direct3D Device
  1282.     TRY_D3DRM(g_lpD3DRM->CreateDeviceFromD3D(g_lpD3D, g_lpD3DDevice, &g_lpD3DRMDevice))
  1283.  
  1284.     // Set the buffer count to 2 so D3DRM can keep track of extents for fullscreen flipping surface
  1285.     TRY_D3DRM(g_lpD3DRMDevice->SetBufferCount(2))
  1286.  
  1287.     // Render using gouraud shading
  1288.     g_lpD3DRMDevice->SetQuality(D3DRMRENDER_GOURAUD);
  1289.  
  1290.     // And no dithering please (NOTE : dithering is for looks not speed!)
  1291.     g_lpD3DRMDevice->SetDither(FALSE);
  1292.  
  1293.     // Set texture quality
  1294.     g_lpD3DRMDevice->SetTextureQuality(D3DRMTEXTURE_NEAREST);
  1295.  
  1296.     // Set the number of shades for lighting
  1297.     g_lpD3DRMDevice->SetShades(8);
  1298.     
  1299.     // Create RM viewport from device and camera (camera has already been initialised
  1300.     // by InitScene() in RM.CPP)
  1301.     TRY_D3DRM(g_lpD3DRM->CreateViewport(g_lpD3DRMDevice, 
  1302.                                         g_lpCamera,
  1303.                                         0,
  1304.                                         0,
  1305.                                         width,
  1306.                                         height,
  1307.                                         &g_lpD3DRMViewport))
  1308.  
  1309.     // Set the back clipping plane to be something fairly large
  1310.     g_lpD3DRMViewport->SetBack(D3DVAL(30000.0f));
  1311.  
  1312.     // Diddle with the lights depending on what driver we are using
  1313.     switch (g_deviceInfo.cm)
  1314.     {
  1315.         case D3DCOLOR_MONO : 
  1316.         {
  1317.             // Enable the directional light only to hit the players, not the arena
  1318.             g_lpDir->SetEnableFrame(g_lpPlayers);
  1319.         }
  1320.         break;
  1321.  
  1322.         case D3DCOLOR_RGB :
  1323.         {
  1324.             // Enable the directional light to hit all objects
  1325.             g_lpDir->SetEnableFrame(g_lpScene);
  1326.         }
  1327.         break;
  1328.     }   
  1329.  
  1330.     // Record video mode information
  1331.     g_vidModeX = width;
  1332.     g_vidModeY = height;
  1333.     g_vidModeBIT = bitdepth;
  1334.     
  1335.     // And calculate values for the power bars
  1336.     g_xratio = (float)width / 1000.0f;
  1337.     g_yratio = (float)height / 1000.0f;
  1338.  
  1339.     g_lbar1 = (DWORD)(float)(50.0f * g_xratio);
  1340.     g_wbar1 = (DWORD)(float)(400.0f * g_xratio);
  1341.     g_lbar2 = (DWORD)(float)(550.0f * g_xratio);
  1342.     g_wbar2 = g_wbar1;
  1343.     g_hbar1 = (DWORD)(float)(30.0f * g_yratio);
  1344.     g_hbar2 = (DWORD)(float)(20.0f * g_yratio);
  1345.  
  1346.     // Finally, calculate the height of the current font
  1347.     HDC hDC;
  1348.     hDC = ::GetDC(g_hWnd);
  1349.     
  1350.     TEXTMETRIC txtMetric;
  1351.     GetTextMetrics(hDC, &txtMetric);
  1352.     
  1353.     ::ReleaseDC(g_hWnd, hDC);
  1354.  
  1355.     g_dwFontHeight   = txtMetric.tmHeight;
  1356.     g_dwAveCharWidth = txtMetric.tmAveCharWidth;
  1357.  
  1358.     // Yahoo!
  1359.     return TRUE;        
  1360. }
  1361.  
  1362. //----------------------------------------------------------------------
  1363. // 
  1364. // Function     : EnterPrevVideoMode()
  1365. //
  1366. // Purpose      : Enters previous mode in vidModes[]
  1367. //
  1368. //----------------------------------------------------------------------
  1369.  
  1370. BOOL EnterPrevVideoMode()
  1371. {
  1372.     if (g_dwCurrMode > 0)
  1373.     {
  1374.         return EnterVideoMode(-- g_dwCurrMode);
  1375.     }
  1376.     
  1377.     return TRUE;
  1378. }
  1379.  
  1380. //----------------------------------------------------------------------
  1381. // 
  1382. // Function     : EnterNextVideoMode()
  1383. //
  1384. // Purpose      : Enters nextmode in vidModes[]
  1385. //
  1386. //----------------------------------------------------------------------
  1387.  
  1388. BOOL EnterNextVideoMode()
  1389. {
  1390.     if (g_dwCurrMode < g_dwNumModes - 1)
  1391.     {
  1392.         return EnterVideoMode(++ g_dwCurrMode);
  1393.     }
  1394.     
  1395.     return TRUE;
  1396. }
  1397.  
  1398. //----------------------------------------------------------------------
  1399. // 
  1400. // Function     : EnterLowestVideoMode()
  1401. //
  1402. // Purpose      : Enters lowest mode in vidModes[]
  1403. //
  1404. //----------------------------------------------------------------------
  1405.  
  1406. BOOL EnterLowestVideoMode()
  1407. {
  1408.     return EnterVideoMode(0);   
  1409. }
  1410.  
  1411. //----------------------------------------------------------------------
  1412. // 
  1413. // Function     : EnterHighestVideoMode()
  1414. //
  1415. // Purpose      : Enters highest mode in vidModes[]
  1416. //
  1417. //----------------------------------------------------------------------
  1418.  
  1419. BOOL EnterHighestVideoMode()
  1420. {
  1421.     return EnterVideoMode(g_dwNumModes - 1);    
  1422. }
  1423.  
  1424. //----------------------------------------------------------------------
  1425. // 
  1426. // Function     : ReenterVideoMode()
  1427. //
  1428. // Purpose      : Re-enters current video mode
  1429. //
  1430. //----------------------------------------------------------------------
  1431.  
  1432. BOOL ReenterCurrentVideoMode()
  1433. {
  1434.     return EnterVideoMode(g_dwCurrMode);
  1435. }
  1436.  
  1437. //----------------------------------------------------------------------
  1438. // 
  1439. // Function     : CleanUp()
  1440. //
  1441. // Purpose      : Destroys all surfaces and rendering devices 
  1442. //
  1443. //----------------------------------------------------------------------
  1444.  
  1445. void CleanUp()
  1446. {
  1447.     // Destroy everything in the reverse order that they were created
  1448.             
  1449.     // Destroy viewport
  1450.     if (g_lpD3DRMViewport)
  1451.     {
  1452.         g_lpD3DRMViewport->Release();
  1453.         g_lpD3DRMViewport = NULL;
  1454.     }
  1455.  
  1456.     // Destroy rendering devices
  1457.     if (g_lpD3DRMDevice)
  1458.     {
  1459.         g_lpD3DRMDevice->Release();
  1460.         g_lpD3DRMDevice = NULL;
  1461.     }
  1462.  
  1463.     if (g_lpD3DDevice)
  1464.     {
  1465.         g_lpD3DDevice->Release();
  1466.         g_lpD3DDevice = NULL;
  1467.     }
  1468.  
  1469.     // Destroy all surfaces
  1470.     if (g_lpZBuffer)
  1471.     {
  1472.         g_lpZBuffer->Release();
  1473.         g_lpZBuffer = NULL;
  1474.     }
  1475.  
  1476.     if (g_lpBackBuffer)
  1477.     {
  1478.         g_lpBackBuffer->Release();
  1479.         g_lpBackBuffer = NULL;
  1480.     }
  1481.  
  1482.     if (g_lpPrimary)
  1483.     {
  1484.         g_lpPrimary->Release();
  1485.         g_lpPrimary = NULL;
  1486.     }   
  1487.  
  1488.     // Destroy palette
  1489.     if (g_lpPalette)
  1490.     {
  1491.         g_lpPalette->Release();
  1492.         g_lpPalette = NULL;
  1493.     }
  1494.     
  1495.     // Restore the original video mode
  1496.     g_lpDD->RestoreDisplayMode();
  1497. }
  1498.  
  1499. //----------------------------------------------------------------------
  1500. // 
  1501. // Function     : DoSplashScreen()
  1502. //
  1503. // Purpose      : Draws splash screen (if possible)
  1504. //
  1505. //----------------------------------------------------------------------
  1506.  
  1507. BOOL DoSplashScreen(DWORD delay)
  1508. {
  1509.     LPDIRECTDRAWSURFACE backbuffer = NULL;
  1510.     DDSURFACEDESC       ddsd;
  1511.     DDSCAPS             ddscaps;
  1512.     HRESULT             rval;
  1513.     DWORD               dwStart;
  1514.     int                 i;
  1515.     FILE                *fp;
  1516.     BYTE                rgbs[768], scanbuf[640];
  1517.     void                *lpSurf;
  1518.     BYTE                *pSurf;
  1519.     DWORD               dummy;
  1520.  
  1521.     delay;
  1522.     
  1523.     // Create a DirectDraw device
  1524.     rval = DirectDrawCreate(NULL, &g_lpSplashDD, NULL);
  1525.     if (rval != DD_OK) goto fail;
  1526.  
  1527.     // Set cooperative level
  1528.     rval = g_lpSplashDD->SetCooperativeLevel(g_hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
  1529.     if (rval != DD_OK) goto fail;
  1530.  
  1531.     // Attempt to enter 640x480x8
  1532.     // Switch video mode        
  1533.     rval = g_lpSplashDD->SetDisplayMode(640, 480, 8);
  1534.     if (rval != DD_OK) goto fail;
  1535.  
  1536.     // Create complex flipping primary surface
  1537.  
  1538.     // Clear surface caps structure
  1539.     memset(&ddscaps, 0, sizeof(DDSCAPS));
  1540.     
  1541.     // Fill out surface description
  1542.     memset(&ddsd, sizeof(DDSURFACEDESC), 0);
  1543.     ddsd.dwSize                 = sizeof(DDSURFACEDESC);
  1544.     ddsd.dwFlags                = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
  1545.     ddsd.ddsCaps.dwCaps         = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
  1546.     ddsd.dwBackBufferCount      = 1;
  1547.  
  1548.     // Create the primary surface with 1 back buffer
  1549.     rval = g_lpSplashDD->CreateSurface(&ddsd, &g_lpSplashPrimary, NULL);
  1550.     if (rval != DD_OK) goto fail;
  1551.  
  1552.     // Get pointer to back buffer
  1553.     ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
  1554.     rval = g_lpSplashPrimary->GetAttachedSurface(&ddscaps, &backbuffer);
  1555.     if (rval != DD_OK) goto fail;
  1556.  
  1557.     // Open the splash screen file
  1558.     fp = fopen("ROCKEM3D.BIN", "rb");
  1559.     if (!fp) goto fail;
  1560.     
  1561.     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
  1562.     ddsd.dwSize = sizeof(DDSURFACEDESC);
  1563.  
  1564.     // Lock the backbuffer to get a pointer to it
  1565.     rval = backbuffer->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR, NULL);
  1566.     if (rval != DD_OK) goto fail;
  1567.  
  1568.     // Read the image into the backbuffer
  1569.     lpSurf = ddsd.lpSurface;
  1570.  
  1571.     // Read in lines of image, accounting for pitch
  1572.     pSurf = (BYTE *)lpSurf;
  1573.  
  1574.     // Read first dword from .BIN file, that corresponds to WIDTH and HEIGHT (two words)
  1575.     fread(&dummy, 4, 1, fp);
  1576.  
  1577.     for (i = 0; i < 480; i ++)
  1578.     {
  1579.         fread(scanbuf, 640, 1, fp);
  1580.         memcpy(pSurf, scanbuf, 640);
  1581.         pSurf += ddsd.lPitch;
  1582.     }
  1583.  
  1584.     // Close the file
  1585.     fclose(fp);
  1586.  
  1587.     // Unlock the surface
  1588.     rval = backbuffer->Unlock(lpSurf);
  1589.     if (rval != DD_OK) goto fail;
  1590.  
  1591.     // Set up the palette               
  1592.     fp = fopen("SPLASH.PAL", "rb");
  1593.     if (!fp) goto fail;
  1594.  
  1595.     fread(rgbs, 768, 1, fp);
  1596.     fclose(fp);
  1597.     
  1598.     // Set up the PALETTEENTRY's from the 768 byte RGB array
  1599.     PALETTEENTRY ppe[256];
  1600.     for (i = 0; i < 256; i ++)
  1601.     {
  1602.         ppe[i].peRed   = rgbs[i * 3];
  1603.         ppe[i].peGreen = rgbs[(i * 3) + 1];
  1604.         ppe[i].peBlue  = rgbs[(i * 3) + 2];
  1605.         ppe[i].peFlags = PC_NOCOLLAPSE;
  1606.     }
  1607.     
  1608.     // Create the palette
  1609.     //rval = g_lpDD->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE, ppe, &g_lpPalette, NULL);
  1610.     rval = g_lpSplashDD->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE, ppe, &g_lpSplashPalette, NULL);
  1611.     if (rval != DD_OK) goto fail;
  1612.  
  1613.     // Set the backbuffer's palette
  1614.     rval = g_lpSplashPrimary->SetPalette(g_lpSplashPalette);
  1615.     if (rval != DD_OK) goto fail;
  1616.  
  1617.     // And flip the splash screen into view
  1618.     rval = g_lpSplashPrimary->Flip(NULL, DDFLIP_WAIT);
  1619.     if (rval != DD_OK) goto fail;
  1620.  
  1621.     // Wait for delay milliseconds or a specific keypress
  1622.     dwStart = timeGetTime();
  1623.     
  1624.     while (timeGetTime() - dwStart < delay)
  1625.     {
  1626.         if (GetAsyncKeyState(VK_SPACE) & 0x8000) break;
  1627.         if (GetAsyncKeyState(VK_RETURN) & 0x8000) break;
  1628.         if (GetAsyncKeyState(VK_ESCAPE) & 0x8000) break;
  1629.         if ((GetAsyncKeyState(VK_MENU) & 0x8000) && (GetAsyncKeyState(VK_F4) & 0x8000)) break;
  1630.     }   
  1631.  
  1632.     backbuffer->Release();
  1633.  
  1634.     // Yahoo!
  1635.     return TRUE;
  1636.  
  1637.     fail:
  1638.  
  1639.     // Close file
  1640.     if (fp)
  1641.     {
  1642.         fclose(fp);
  1643.     }
  1644.     
  1645.     // Release palette
  1646.     if (g_lpSplashPalette)
  1647.     {
  1648.         g_lpSplashPalette->Release();
  1649.         g_lpSplashPalette = NULL;
  1650.     }
  1651.  
  1652.     // Release primary surface
  1653.     if (g_lpSplashPrimary)
  1654.     {
  1655.         g_lpSplashPrimary->Release();
  1656.         g_lpSplashPrimary = NULL;
  1657.     }
  1658.  
  1659.     if (g_lpSplashDD)
  1660.     {
  1661.         g_lpSplashDD->Release();
  1662.         g_lpSplashDD = NULL;
  1663.     }
  1664.  
  1665.     // Yahoo!
  1666.     return FALSE;
  1667. }
  1668.  
  1669.  
  1670. //----------------------------------------------------------------------
  1671. // 
  1672. // Function     : ReleaseSplashScreen()
  1673. //
  1674. // Purpose      : Releases the splash screen
  1675. //
  1676. //----------------------------------------------------------------------
  1677.  
  1678. void ReleaseSplashScreen()
  1679. {
  1680.     // Release palette
  1681.     if (g_lpSplashPalette)
  1682.     {
  1683.         g_lpSplashPalette->Release();
  1684.         g_lpSplashPalette = NULL;
  1685.     }
  1686.  
  1687.     // Release primary surface
  1688.     if (g_lpSplashPrimary)
  1689.     {
  1690.         g_lpSplashPrimary->Release();
  1691.         g_lpSplashPrimary = NULL;
  1692.     }
  1693.  
  1694.     if (g_lpSplashDD)
  1695.     {
  1696.         g_lpSplashDD->Release();
  1697.         g_lpSplashDD = NULL;
  1698.     }
  1699. }
  1700.  
  1701.  
  1702. //----------------------------------------------------------------------
  1703. // 
  1704. // Function     : RestoreSurfaces()
  1705. //
  1706. // Purpose      : Restores all surfaces if they somehow got lost (Alt-Tab)
  1707. //
  1708. //----------------------------------------------------------------------
  1709.  
  1710. BOOL RestoreSurfaces()
  1711. {
  1712.     // Attempt to restore primary surface
  1713.     if (g_lpPrimary)
  1714.     {
  1715.         if (g_lpPrimary->IsLost()) TRY_DD(g_lpPrimary->Restore())
  1716.     }
  1717.  
  1718.     // Attempt to restore zbuffer
  1719.     if (g_lpZBuffer)
  1720.     {
  1721.         if (g_lpZBuffer->IsLost()) TRY_DD(g_lpZBuffer->Restore())
  1722.     }
  1723.  
  1724.     // Yahoo!
  1725.     return TRUE;
  1726. }
  1727.  
  1728. //----------------------------------------------------------------------
  1729. // 
  1730. // Function     : CreateSoundBuffer()
  1731. //
  1732. // Purpose      : Creates a DirectSound buffer
  1733. //
  1734. //----------------------------------------------------------------------
  1735.  
  1736. BOOL CreateSoundBuffer(DWORD dwBuf, DWORD dwBufSize, DWORD dwFreq, DWORD dwBitsPerSample, DWORD dwBlkAlign, BOOL bStereo)
  1737. {
  1738.     PCMWAVEFORMAT pcmwf;
  1739.     DSBUFFERDESC dsbdesc;
  1740.     
  1741.     // Set up wave format structure.
  1742.     memset( &pcmwf, 0, sizeof(PCMWAVEFORMAT) );
  1743.     pcmwf.wf.wFormatTag         = WAVE_FORMAT_PCM;      
  1744.     pcmwf.wf.nChannels          = bStereo ? 2 : 1;
  1745.     pcmwf.wf.nSamplesPerSec     = dwFreq;
  1746.     pcmwf.wf.nBlockAlign        = (WORD)dwBlkAlign;
  1747.     pcmwf.wf.nAvgBytesPerSec    = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign;
  1748.     pcmwf.wBitsPerSample        = (WORD)dwBitsPerSample;
  1749.  
  1750.     // Set up DSBUFFERDESC structure.
  1751.     memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));  // Zero it out. 
  1752.     dsbdesc.dwSize              = sizeof(DSBUFFERDESC);
  1753.     dsbdesc.dwFlags             = DSBCAPS_CTRL3D;               // Needed creation flag for Direct 3D Sound
  1754.         dsbdesc.dwBufferBytes       = dwBufSize; 
  1755.     dsbdesc.lpwfxFormat         = (LPWAVEFORMATEX)&pcmwf;
  1756.  
  1757.     TRY_DS(g_lpDS->CreateSoundBuffer(&dsbdesc, &g_lpSounds[dwBuf], NULL))
  1758.     
  1759.         // Query for the 3D Sound Buffer interface.
  1760.     TRY_DS(g_lpSounds[dwBuf]->QueryInterface(IID_IDirectSound3DBuffer, (void**) &g_lp3dSounds[dwBuf]));
  1761.  
  1762.     // Yahoo!
  1763.     return TRUE;
  1764. }
  1765.  
  1766. //----------------------------------------------------------------------
  1767. // 
  1768. // Function     : ReadData()
  1769. //
  1770. // Purpose      : Reads in data from a wave file
  1771. //
  1772. //----------------------------------------------------------------------
  1773.  
  1774. BOOL ReadData(LPDIRECTSOUNDBUFFER lpDSB, FILE* pFile, DWORD dwSize, DWORD dwPos) 
  1775. {
  1776.     // Seek to correct position in file (if necessary)
  1777.     if (dwPos != 0xffffffff) 
  1778.     {
  1779.         if (fseek(pFile, dwPos, SEEK_SET) != 0) 
  1780.         {
  1781.             return FALSE;
  1782.         }
  1783.     }
  1784.  
  1785.     // Lock data in buffer for writing
  1786.     LPVOID pData1;
  1787.     DWORD  dwData1Size;
  1788.     LPVOID pData2;
  1789.     DWORD  dwData2Size;
  1790.     HRESULT rval;
  1791.  
  1792.     rval = lpDSB->Lock(0, dwSize, &pData1, &dwData1Size, &pData2, &dwData2Size, DSBLOCK_FROMWRITECURSOR);
  1793.     if (rval != DS_OK)
  1794.     {
  1795.         return FALSE;
  1796.     }
  1797.  
  1798.     // Read in first chunk of data
  1799.     if (dwData1Size > 0) 
  1800.     {
  1801.         if (fread(pData1, dwData1Size, 1, pFile) != 1) 
  1802.         {          
  1803.                         char holder[256];
  1804.                         wsprintf(holder,"Data1 : %d, dwdata: %d, pFile: %d",pData1,dwData1Size,pFile);
  1805.                         OutputDebugString(holder);
  1806.             return FALSE;
  1807.         }
  1808.     }
  1809.  
  1810.     // read in second chunk if necessary
  1811.     if (dwData2Size > 0) 
  1812.     {
  1813.         if (fread(pData2, dwData2Size, 1, pFile) != 1) 
  1814.         {
  1815.             return FALSE;
  1816.         }
  1817.     }
  1818.  
  1819.     // Unlock data in buffer
  1820.     rval = lpDSB->Unlock(pData1, dwData1Size, pData2, dwData2Size);
  1821.     if (rval != DS_OK)
  1822.     {
  1823.         return FALSE;
  1824.     }
  1825.  
  1826.     // Yahoo!
  1827.     return TRUE;
  1828. }
  1829.  
  1830. //----------------------------------------------------------------------
  1831. // 
  1832. // Function     : CreateSoundBufferFromWaveFile()
  1833. //
  1834. // Purpose      : Creates a DirectSound buffer from a wave file
  1835. //
  1836. //----------------------------------------------------------------------
  1837.  
  1838. BOOL CreateBufferFromWaveFile(char* FileName, DWORD dwBuf)
  1839. {
  1840.     // Open the wave file       
  1841.     FILE* pFile = fopen(FileName,"rb");
  1842.     if (pFile == NULL) return FALSE;
  1843.  
  1844.     // Read in the wave header          
  1845.     WaveHeader wavHdr;
  1846.     if (fread(&wavHdr, sizeof(wavHdr), 1, pFile) != 1) 
  1847.     {
  1848.         fclose(pFile);
  1849.         return NULL;
  1850.     }
  1851.  
  1852.     // Figure out the size of the data region
  1853.     DWORD dwSize = wavHdr.dwDSize;
  1854.  
  1855.     // Is this a stereo or mono file?
  1856.     BOOL bStereo = wavHdr.wChnls > 1 ? TRUE : FALSE;
  1857.  
  1858.     // Create the sound buffer for the wave file
  1859.     if (!CreateSoundBuffer(dwBuf, dwSize, wavHdr.dwSRate, wavHdr.BitsPerSample, wavHdr.wBlkAlign, bStereo))
  1860.     {
  1861.         // Close the file
  1862.         fclose(pFile);
  1863.         
  1864.         return FALSE;
  1865.     }
  1866.  
  1867.     // Read the data for the wave file into the sound buffer
  1868.     if (!ReadData(g_lpSounds[dwBuf], pFile, dwSize, sizeof(wavHdr))) 
  1869.     {
  1870.         fclose(pFile);
  1871.         return FALSE;
  1872.     }
  1873.  
  1874.     // Close out the wave file
  1875.     fclose(pFile);
  1876.  
  1877.     // Yahoo!
  1878.     return TRUE;
  1879. }
  1880.  
  1881. //----------------------------------------------------------------------
  1882. // 
  1883. // Function     : StopAllSounds()
  1884. //
  1885. // Purpose      : Stops all sounds
  1886. //
  1887. //----------------------------------------------------------------------
  1888.  
  1889. BOOL StopAllSounds()
  1890. {
  1891.     // Make sure we have a valid sound buffer
  1892.     for (int i = 0; i < NUM_SOUNDS; i ++)
  1893.     {
  1894.         if (g_lpSounds[i])
  1895.         {
  1896.             DWORD dwStatus;
  1897.             TRY_DS(g_lpSounds[i]->GetStatus(&dwStatus));
  1898.  
  1899.             if ((dwStatus & DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING)
  1900.             {
  1901.                 // Play the sound
  1902.                 TRY_DS(g_lpSounds[i]->Stop())
  1903.             }
  1904.         }
  1905.     }
  1906.  
  1907.     // Yahoo!
  1908.     return TRUE;
  1909. }
  1910.  
  1911. //----------------------------------------------------------------------
  1912. // 
  1913. // Function     : PlaySoundDS()
  1914. //
  1915. // Purpose      : Plays a sound using direct sound
  1916. // 
  1917. //                      D3DVECTOR
  1918. //----------------------------------------------------------------------
  1919.  
  1920. BOOL PlaySoundDS(DWORD dwSound,D3DVECTOR d3dvPos, DWORD dwFlags)
  1921. {
  1922.  
  1923.     if (g_bSoundPaused) return TRUE;
  1924.  
  1925.     if (!g_bSoundPresent) return TRUE;
  1926.  
  1927.     // Make sure the sound is valid
  1928.     if (dwSound >= NUM_SOUNDS) return FALSE;    
  1929.  
  1930.     // Make sure we have a valid sound buffer
  1931.     if (g_lpSounds[dwSound])
  1932.     {
  1933.         DWORD dwStatus;
  1934.         TRY_DS(g_lpSounds[dwSound]->GetStatus(&dwStatus));
  1935.  
  1936.         if ((dwStatus & DSBSTATUS_PLAYING) != DSBSTATUS_PLAYING)
  1937.         {
  1938.            // Set the 3D position of the sound, using supplied position vector.
  1939.            TRY_DS(g_lp3dSounds[dwSound]->SetPosition(d3dvPos.x, d3dvPos.y, d3dvPos.z, DS3D_IMMEDIATE));
  1940.             // Play the sound
  1941.            TRY_DS(g_lpSounds[dwSound]->Play(0, 0, dwFlags));
  1942.         }
  1943.     }
  1944.  
  1945.     // Yahoo!
  1946.     return TRUE;
  1947. }
  1948.  
  1949. //----------------------------------------------------------------------
  1950. // 
  1951. // Function     : RecalcPowerBars()
  1952. //
  1953. // Purpose      : Calculates width of power bars based upon current 
  1954. //                        screen resolution
  1955. //
  1956. //----------------------------------------------------------------------
  1957.  
  1958. void RecalcPowerBars(DWORD player1health, DWORD player2health)
  1959. {
  1960.     g_wbar1 = (DWORD)(float)((400.0f * ((float)player1health / 100.0f)) * g_xratio);
  1961.     g_wbar2 = (DWORD)(float)((400.0f * ((float)player2health / 100.0f)) * g_xratio);
  1962. }
  1963.  
  1964.  
  1965.  
  1966. //----------------------------------------------------------------------
  1967. // 
  1968. // Function     : CreateSoundBuffer3D()
  1969. //
  1970. // Purpose      : Creates a 3D sound buffer and returns the sound buffer
  1971. //
  1972. //----------------------------------------------------------------------
  1973.  
  1974. IDirectSoundBuffer *CreateSoundBuffer3D()
  1975. {
  1976.     IDirectSoundBuffer *pDSB = NULL;
  1977.     DSBUFFERDESC dsBD = {0};
  1978.  
  1979.         ZeroMemory( &dsBD, sizeof(DSBUFFERDESC));
  1980.         dsBD.dwSize = sizeof(dsBD);
  1981.     dsBD.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_PRIMARYBUFFER;
  1982.         dsBD.dwBufferBytes = 0;  //must be zero for primary buffer..
  1983.  
  1984.         if (g_lpDS->CreateSoundBuffer(&dsBD, &pDSB, NULL) != DS_OK)
  1985.                 pDSB = NULL;
  1986.  
  1987.     return pDSB;
  1988. }
  1989.  
  1990. //----------------------------------------------------------------------
  1991. // 
  1992. // Function     : PlayRandomWave()
  1993. //
  1994. // Purpose      : Creates a random wave at a random spot
  1995. //
  1996. //----------------------------------------------------------------------
  1997.  
  1998. VOID CALLBACK PlayRandomWave( HWND hwnd, UINT uMsg,    UINT idEvent, DWORD dwTime )
  1999. {
  2000.         D3DVECTOR       d3dPosition;    // DSVECTOR used for the positon of the wave...
  2001.  
  2002.         int RandomWave[]={RANDOM1,RANDOM2,RANDOM3,RANDOM4,RANDOM5,RANDOM6};
  2003.  
  2004.         g_lpCamera->GetPosition(g_lpScene, &d3dPosition);
  2005.         // fill in the position generated for the wave file.
  2006.         d3dPosition.x += (rand() % 2 == 0 ? (rand() % 250) : -(rand() % 250));
  2007.         d3dPosition.z += (rand() % 2 == 0 ? (rand() % 250) : -(rand() % 250));
  2008.  
  2009.         PlaySoundDS(RandomWave[rand() % (sizeof(RandomWave) / sizeof(RandomWave[0]))],d3dPosition);
  2010.         return;
  2011. }
  2012.