home *** CD-ROM | disk | FTP | other *** search
/ NEXT Generation 27 / NEXT27.iso / pc / demos / emperor / dx3.exe / SDK / SAMPLES / ROCKEM / DIRECTX.CPP < prev    next >
C/C++ Source or Header  |  1996-08-28  |  68KB  |  1,945 lines

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995, 1996 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.  
  16. // Includes....
  17. #include "directx.h"
  18. #include "mmsystem.h"
  19. #include "winmain.h"
  20. #include "conio.h"
  21.  
  22. // Globals....
  23. LPDIRECTDRAW            g_lpDD = NULL;          // DirectDraw object
  24. LPDIRECT3D              g_lpD3D = NULL;         // Direct3D object
  25. LPDIRECTSOUND           g_lpDS = NULL;          // DirectSound object
  26. LPDIRECT3DRM            g_lpD3DRM = NULL;       // Direct3D RM object
  27. DWORD                   g_dwGDIMem = 0;         // Memory in available from GDI's surface
  28.  
  29. D3DDeviceInfo           g_deviceInfo;           // 3D device info
  30. LPGUID                  g_lpD3DDeviceGuid = NULL; // Guid to 3D device
  31.  
  32. VideoMode               g_vidModes[NUM_VID_MODES];// Array of available video modes
  33. DWORD                   g_dwCurrMode = 0;
  34. DWORD                   g_dwNumModes = 0;
  35.  
  36. BOOL                    g_bSoundPresent = FALSE; // Do we have sound capabilites?
  37.  
  38. LPDIRECTDRAWSURFACE     g_lpPrimary = NULL;     // Primary surface
  39. LPDIRECTDRAWSURFACE     g_lpBackBuffer = NULL;  // BackBuffer surface
  40. LPDIRECTDRAWSURFACE     g_lpZBuffer = NULL;     // ZBuffer
  41. LPDIRECTDRAWPALETTE     g_lpPalette = NULL;     // Palette
  42. PALETTEENTRY            g_rPal[768];            // Rockem3D palette
  43.  
  44. LPDIRECTDRAW            g_lpSplashDD = NULL;        // DirectDraw object used for splash screen
  45. LPDIRECTDRAWSURFACE     g_lpSplashPrimary = NULL;   // Primary surface
  46. LPDIRECTDRAWPALETTE     g_lpSplashPalette = NULL;   // Palette
  47.  
  48. LPDIRECT3DDEVICE        g_lpD3DDevice = NULL;   // Direct3D device
  49. LPDIRECT3DRMDEVICE      g_lpD3DRMDevice = NULL; // Direct3D RM Device
  50. LPDIRECT3DRMVIEWPORT    g_lpD3DRMViewport = NULL; // Direct3D RM Viewport
  51.  
  52. DDCAPS                  g_driverCaps;           // Driver capabilities
  53. DDCAPS                  g_HELcaps;              // HEL capabilities
  54.  
  55. DWORD                   g_dwZBufferBitDepth = 16;// ZBuffer bit depth
  56. DWORD                   g_dwZBufferMemType = DDSCAPS_SYSTEMMEMORY;// Type of ZBuffer
  57.  
  58. LPDIRECTSOUNDBUFFER     g_lpSounds[NUM_SOUNDS]; // Sound buffers
  59. LPDIRECTSOUND3DLISTENER      g_lpDs3dListener;               // Listener object for Direct 3D Sound
  60. LPDIRECTSOUNDBUFFER             g_3DSoundBuffer;                // Direct Sound buffer for the Listener object
  61. LPDIRECTSOUND3DBUFFER   g_lp3dSounds[NUM_SOUNDS];//3D Sound Buffers
  62.  
  63.  
  64. // State booleans
  65. BOOL                    g_bHardware3D = FALSE;  // Do we have hardware?
  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(.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     : EnterVideoMode()
  1089. //
  1090. // Purpose      : Calls EnterVideoModeWHBD with mode information
  1091. //
  1092. //----------------------------------------------------------------------
  1093.  
  1094. BOOL EnterVideoMode(int mode)
  1095. {
  1096.     int width    = g_vidModes[mode].width;
  1097.     int height   = g_vidModes[mode].height;
  1098.     int bitdepth = g_vidModes[mode].bpp;
  1099.     g_dwCurrMode = mode;
  1100.  
  1101.     // Try to enter video mode described by width, height and bitdepth
  1102.     return EnterVideoModeWHBD(width, height, bitdepth);
  1103. }
  1104.  
  1105. //----------------------------------------------------------------------
  1106. // 
  1107. // Function     : EnterVideoModeWHBD()
  1108. //
  1109. // Purpose      : Switches video mode and creates all neccessary structures
  1110. //                        required for rendering
  1111. //
  1112. //----------------------------------------------------------------------
  1113.  
  1114. BOOL EnterVideoModeWHBD(int width, int height, int bitdepth)
  1115. {
  1116.     DDSURFACEDESC ddsd;
  1117.     DDSCAPS ddscaps;
  1118.  
  1119.     // Destroy all existing viewports, devices and surfaces     
  1120.     
  1121.     // Destroy Direct3D RM viewport
  1122.     if (g_lpD3DRMViewport)
  1123.     {   
  1124.         g_lpD3DRMViewport->Release();
  1125.         g_lpD3DRMViewport = NULL;
  1126.     }
  1127.  
  1128.     // Destroy Direct3D RM device
  1129.     if (g_lpD3DRMDevice)
  1130.     {
  1131.         g_lpD3DRMDevice->Release();
  1132.         g_lpD3DRMDevice = NULL;
  1133.     }
  1134.  
  1135.     // Destroy Direct3D device
  1136.     if (g_lpD3DDevice)
  1137.     {
  1138.         g_lpD3DDevice->Release();
  1139.         g_lpD3DDevice = NULL;
  1140.     }
  1141.  
  1142.     // Destroy ZBuffer
  1143.     if (g_lpZBuffer)
  1144.     {
  1145.         g_lpZBuffer->Release();
  1146.         g_lpZBuffer = NULL;
  1147.     }
  1148.  
  1149.     // Destroy Primary surface
  1150.     if (g_lpPrimary)
  1151.     {
  1152.         g_lpPrimary->Release();
  1153.         g_lpPrimary = NULL;
  1154.     }
  1155.  
  1156.     // Switch video mode
  1157.     TRY_DD(g_lpDD->SetDisplayMode(width, height, bitdepth))
  1158.  
  1159.     // First, create complex flipping primary surface
  1160.     
  1161.     // Fill out surface description
  1162.     memset(&ddsd, sizeof(DDSURFACEDESC), 0);
  1163.     ddsd.dwSize                 = sizeof(DDSURFACEDESC);
  1164.     ddsd.dwFlags                = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
  1165.     ddsd.ddsCaps.dwCaps         = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX | DDSCAPS_3DDEVICE;
  1166.     ddsd.dwBackBufferCount      = 1;
  1167.  
  1168.     // Create the primary surface with 1 back buffer
  1169.     TRY_DD(g_lpDD->CreateSurface(&ddsd, &g_lpPrimary, NULL))
  1170.  
  1171.     // Get pointer to back buffer
  1172.     ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
  1173.     TRY_DD(g_lpPrimary->GetAttachedSurface(&ddscaps, &g_lpBackBuffer))
  1174.  
  1175.     // Only create a ZBuffer if g_dwZBufferBitDepth > 0
  1176.     if (g_dwZBufferBitDepth)
  1177.     {
  1178.         // Then, create Z-Buffer. The g_dwZBufferMemType and g_dwZBufferBitDepth variables
  1179.         // are set up when the Direct3D device enumeration is done at runtime
  1180.         memset(&ddsd, sizeof(DDSURFACEDESC), 0);
  1181.         ddsd.dwSize             = sizeof(DDSURFACEDESC);
  1182.         ddsd.dwFlags            = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_ZBUFFERBITDEPTH;;
  1183.         ddsd.dwWidth            = width;
  1184.         ddsd.dwHeight           = height;
  1185.         ddsd.ddsCaps.dwCaps     = DDSCAPS_ZBUFFER | g_dwZBufferMemType;
  1186.         ddsd.dwZBufferBitDepth  = g_dwZBufferBitDepth;
  1187.  
  1188.         // Create the ZBuffer
  1189.         TRY_DD(g_lpDD->CreateSurface(&ddsd, &g_lpZBuffer, NULL))
  1190.  
  1191.         // Attach ZBuffer to the back buffer
  1192.         TRY_DD(g_lpBackBuffer->AddAttachedSurface(g_lpZBuffer))
  1193.     }
  1194.  
  1195.     // Retrieve the caps of the primary surface
  1196.     TRY_DD(g_lpPrimary->GetCaps(&ddscaps))
  1197.  
  1198.     // Create and attach palette (only if we in 8-bit palettized colour modes)
  1199.     if ((bitdepth == 8) && (ddscaps.dwCaps & DDCAPS_PALETTE))
  1200.     {
  1201.         // Create the palette
  1202.         TRY_DD(g_lpDD->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE, g_rPal, &g_lpPalette, NULL))
  1203.         
  1204.         // Set the back buffer's palette
  1205.         TRY_DD(g_lpBackBuffer->SetPalette(g_lpPalette))
  1206.  
  1207.         // Set the primary surface's palette
  1208.         TRY_DD(g_lpPrimary->SetPalette(g_lpPalette))
  1209.     }
  1210.  
  1211.     // Create Direct3D device
  1212.     TRY_D3D(g_lpBackBuffer->QueryInterface(*g_lpD3DDeviceGuid, (LPVOID *)&g_lpD3DDevice))
  1213.  
  1214.     // Create Direct3D RM Device from Direct3D Device
  1215.     TRY_D3DRM(g_lpD3DRM->CreateDeviceFromD3D(g_lpD3D, g_lpD3DDevice, &g_lpD3DRMDevice))
  1216.  
  1217.     // Set the buffer count to 2 so D3DRM can keep track of extents for fullscreen flipping surface
  1218.     TRY_D3DRM(g_lpD3DRMDevice->SetBufferCount(2))
  1219.  
  1220.     // Render using gouraud shading
  1221.     g_lpD3DRMDevice->SetQuality(D3DRMRENDER_GOURAUD);
  1222.  
  1223.     // And no dithering please (NOTE : dithering is for looks not speed!)
  1224.     g_lpD3DRMDevice->SetDither(FALSE);
  1225.  
  1226.     // Set texture quality
  1227.     g_lpD3DRMDevice->SetTextureQuality(D3DRMTEXTURE_NEAREST);
  1228.  
  1229.     // Set the number of shades for lighting
  1230.     g_lpD3DRMDevice->SetShades(8);
  1231.     
  1232.     // Create RM viewport from device and camera (camera has already been initialised
  1233.     // by InitScene() in RM.CPP)
  1234.     TRY_D3DRM(g_lpD3DRM->CreateViewport(g_lpD3DRMDevice, 
  1235.                                         g_lpCamera,
  1236.                                         0,
  1237.                                         0,
  1238.                                         width,
  1239.                                         height,
  1240.                                         &g_lpD3DRMViewport))
  1241.  
  1242.     // Set the back clipping plane to be something fairly large
  1243.     g_lpD3DRMViewport->SetBack(D3DVAL(30000.0f));
  1244.  
  1245.     // Diddle with the lights depending on what driver we are using
  1246.     switch (g_deviceInfo.cm)
  1247.     {
  1248.         case D3DCOLOR_MONO : 
  1249.         {
  1250.             // Enable the directional light only to hit the players, not the arena
  1251.             g_lpDir->SetEnableFrame(g_lpPlayers);
  1252.         }
  1253.         break;
  1254.  
  1255.         case D3DCOLOR_RGB :
  1256.         {
  1257.             // Enable the directional light to hit all objects
  1258.             g_lpDir->SetEnableFrame(g_lpScene);
  1259.         }
  1260.         break;
  1261.     }   
  1262.  
  1263.     // Record video mode information
  1264.     g_vidModeX = width;
  1265.     g_vidModeY = height;
  1266.     g_vidModeBIT = bitdepth;
  1267.     
  1268.     // And calculate values for the power bars
  1269.     g_xratio = (float)width / 1000.0f;
  1270.     g_yratio = (float)height / 1000.0f;
  1271.  
  1272.     g_lbar1 = (DWORD)(float)(50.0f * g_xratio);
  1273.     g_wbar1 = (DWORD)(float)(400.0f * g_xratio);
  1274.     g_lbar2 = (DWORD)(float)(550.0f * g_xratio);
  1275.     g_wbar2 = g_wbar1;
  1276.     g_hbar1 = (DWORD)(float)(30.0f * g_yratio);
  1277.     g_hbar2 = (DWORD)(float)(20.0f * g_yratio);
  1278.  
  1279.     // Finally, calculate the height of the current font
  1280.     HDC hDC;
  1281.     hDC = ::GetDC(g_hWnd);
  1282.     
  1283.     TEXTMETRIC txtMetric;
  1284.     GetTextMetrics(hDC, &txtMetric);
  1285.     
  1286.     ::ReleaseDC(g_hWnd, hDC);
  1287.  
  1288.     g_dwFontHeight   = txtMetric.tmHeight;
  1289.     g_dwAveCharWidth = txtMetric.tmAveCharWidth;
  1290.  
  1291.     // Yahoo!
  1292.     return TRUE;        
  1293. }
  1294.  
  1295. //----------------------------------------------------------------------
  1296. // 
  1297. // Function     : EnterPrevVideoMode()
  1298. //
  1299. // Purpose      : Enters previous mode in vidModes[]
  1300. //
  1301. //----------------------------------------------------------------------
  1302.  
  1303. BOOL EnterPrevVideoMode()
  1304. {
  1305.     if (g_dwCurrMode > 0)
  1306.     {
  1307.         return EnterVideoMode(-- g_dwCurrMode);
  1308.     }
  1309.     
  1310.     return TRUE;
  1311. }
  1312.  
  1313. //----------------------------------------------------------------------
  1314. // 
  1315. // Function     : EnterNextVideoMode()
  1316. //
  1317. // Purpose      : Enters nextmode in vidModes[]
  1318. //
  1319. //----------------------------------------------------------------------
  1320.  
  1321. BOOL EnterNextVideoMode()
  1322. {
  1323.     if (g_dwCurrMode < g_dwNumModes - 1)
  1324.     {
  1325.         return EnterVideoMode(++ g_dwCurrMode);
  1326.     }
  1327.     
  1328.     return TRUE;
  1329. }
  1330.  
  1331. //----------------------------------------------------------------------
  1332. // 
  1333. // Function     : EnterLowestVideoMode()
  1334. //
  1335. // Purpose      : Enters lowest mode in vidModes[]
  1336. //
  1337. //----------------------------------------------------------------------
  1338.  
  1339. BOOL EnterLowestVideoMode()
  1340. {
  1341.     return EnterVideoMode(0);   
  1342. }
  1343.  
  1344. //----------------------------------------------------------------------
  1345. // 
  1346. // Function     : EnterHighestVideoMode()
  1347. //
  1348. // Purpose      : Enters highest mode in vidModes[]
  1349. //
  1350. //----------------------------------------------------------------------
  1351.  
  1352. BOOL EnterHighestVideoMode()
  1353. {
  1354.     return EnterVideoMode(g_dwNumModes - 1);    
  1355. }
  1356.  
  1357. //----------------------------------------------------------------------
  1358. // 
  1359. // Function     : ReenterVideoMode()
  1360. //
  1361. // Purpose      : Re-enters current video mode
  1362. //
  1363. //----------------------------------------------------------------------
  1364.  
  1365. BOOL ReenterCurrentVideoMode()
  1366. {
  1367.     return EnterVideoMode(g_dwCurrMode);
  1368. }
  1369.  
  1370. //----------------------------------------------------------------------
  1371. // 
  1372. // Function     : CleanUp()
  1373. //
  1374. // Purpose      : Destroys all surfaces and rendering devices 
  1375. //
  1376. //----------------------------------------------------------------------
  1377.  
  1378. void CleanUp()
  1379. {
  1380.     // Destroy everything in the reverse order that they were created
  1381.             
  1382.     // Destroy viewport
  1383.     if (g_lpD3DRMViewport)
  1384.     {
  1385.         g_lpD3DRMViewport->Release();
  1386.         g_lpD3DRMViewport = NULL;
  1387.     }
  1388.  
  1389.     // Destroy rendering devices
  1390.     if (g_lpD3DRMDevice)
  1391.     {
  1392.         g_lpD3DRMDevice->Release();
  1393.         g_lpD3DRMDevice = NULL;
  1394.     }
  1395.  
  1396.     if (g_lpD3DDevice)
  1397.     {
  1398.         g_lpD3DDevice->Release();
  1399.         g_lpD3DDevice = NULL;
  1400.     }
  1401.  
  1402.     // Destroy all surfaces
  1403.     if (g_lpZBuffer)
  1404.     {
  1405.         g_lpZBuffer->Release();
  1406.         g_lpZBuffer = NULL;
  1407.     }
  1408.  
  1409.     if (g_lpBackBuffer)
  1410.     {
  1411.         g_lpBackBuffer->Release();
  1412.         g_lpBackBuffer = NULL;
  1413.     }
  1414.  
  1415.     if (g_lpPrimary)
  1416.     {
  1417.         g_lpPrimary->Release();
  1418.         g_lpPrimary = NULL;
  1419.     }   
  1420.  
  1421.     // Destroy palette
  1422.     if (g_lpPalette)
  1423.     {
  1424.         g_lpPalette->Release();
  1425.         g_lpPalette = NULL;
  1426.     }
  1427.     
  1428.     // Restore the original video mode
  1429.     g_lpDD->RestoreDisplayMode();
  1430. }
  1431.  
  1432. //----------------------------------------------------------------------
  1433. // 
  1434. // Function     : DoSplashScreen()
  1435. //
  1436. // Purpose      : Draws splash screen (if possible)
  1437. //
  1438. //----------------------------------------------------------------------
  1439.  
  1440. BOOL DoSplashScreen(DWORD delay)
  1441. {
  1442.     LPDIRECTDRAWSURFACE backbuffer = NULL;
  1443.     DDSURFACEDESC       ddsd;
  1444.     DDSCAPS             ddscaps;
  1445.     HRESULT             rval;
  1446.     DWORD               dwStart;
  1447.     int                 i;
  1448.     FILE                *fp;
  1449.     BYTE                rgbs[768], scanbuf[640];
  1450.     void                *lpSurf;
  1451.     BYTE                *pSurf;
  1452.     DWORD               dummy;
  1453.  
  1454.     delay;
  1455.     
  1456.     // Create a DirectDraw device
  1457.     rval = DirectDrawCreate(NULL, &g_lpSplashDD, NULL);
  1458.     if (rval != DD_OK) goto fail;
  1459.  
  1460.     // Set cooperative level
  1461.     rval = g_lpSplashDD->SetCooperativeLevel(g_hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
  1462.     if (rval != DD_OK) goto fail;
  1463.  
  1464.     // Attempt to enter 640x480x8
  1465.     // Switch video mode        
  1466.     rval = g_lpSplashDD->SetDisplayMode(640, 480, 8);
  1467.     if (rval != DD_OK) goto fail;
  1468.  
  1469.     // Create complex flipping primary surface
  1470.  
  1471.     // Clear surface caps structure
  1472.     memset(&ddscaps, 0, sizeof(DDSCAPS));
  1473.     
  1474.     // Fill out surface description
  1475.     memset(&ddsd, sizeof(DDSURFACEDESC), 0);
  1476.     ddsd.dwSize                 = sizeof(DDSURFACEDESC);
  1477.     ddsd.dwFlags                = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
  1478.     ddsd.ddsCaps.dwCaps         = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
  1479.     ddsd.dwBackBufferCount      = 1;
  1480.  
  1481.     // Create the primary surface with 1 back buffer
  1482.     rval = g_lpSplashDD->CreateSurface(&ddsd, &g_lpSplashPrimary, NULL);
  1483.     if (rval != DD_OK) goto fail;
  1484.  
  1485.     // Get pointer to back buffer
  1486.     ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
  1487.     rval = g_lpSplashPrimary->GetAttachedSurface(&ddscaps, &backbuffer);
  1488.     if (rval != DD_OK) goto fail;
  1489.  
  1490.     // Open the splash screen file
  1491.     fp = fopen("ROCKEM3D.BIN", "rb");
  1492.     if (!fp) goto fail;
  1493.     
  1494.     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
  1495.     ddsd.dwSize = sizeof(DDSURFACEDESC);
  1496.  
  1497.     // Lock the backbuffer to get a pointer to it
  1498.     rval = backbuffer->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR, NULL);
  1499.     if (rval != DD_OK) goto fail;
  1500.  
  1501.     // Read the image into the backbuffer
  1502.     lpSurf = ddsd.lpSurface;
  1503.  
  1504.     // Read in lines of image, accounting for pitch
  1505.     pSurf = (BYTE *)lpSurf;
  1506.  
  1507.     // Read first dword from .BIN file, that corresponds to WIDTH and HEIGHT (two words)
  1508.     fread(&dummy, 4, 1, fp);
  1509.  
  1510.     for (i = 0; i < 480; i ++)
  1511.     {
  1512.         fread(scanbuf, 640, 1, fp);
  1513.         memcpy(pSurf, scanbuf, 640);
  1514.         pSurf += ddsd.lPitch;
  1515.     }
  1516.  
  1517.     // Close the file
  1518.     fclose(fp);
  1519.  
  1520.     // Unlock the surface
  1521.     rval = backbuffer->Unlock(lpSurf);
  1522.     if (rval != DD_OK) goto fail;
  1523.  
  1524.     // Set up the palette               
  1525.     fp = fopen("SPLASH.PAL", "rb");
  1526.     if (!fp) goto fail;
  1527.  
  1528.     fread(rgbs, 768, 1, fp);
  1529.     fclose(fp);
  1530.     
  1531.     // Set up the PALETTEENTRY's from the 768 byte RGB array
  1532.     PALETTEENTRY ppe[256];
  1533.     for (i = 0; i < 256; i ++)
  1534.     {
  1535.         ppe[i].peRed   = rgbs[i * 3];
  1536.         ppe[i].peGreen = rgbs[(i * 3) + 1];
  1537.         ppe[i].peBlue  = rgbs[(i * 3) + 2];
  1538.         ppe[i].peFlags = PC_NOCOLLAPSE;
  1539.     }
  1540.     
  1541.     // Create the palette
  1542.     //rval = g_lpDD->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE, ppe, &g_lpPalette, NULL);
  1543.     rval = g_lpSplashDD->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE, ppe, &g_lpSplashPalette, NULL);
  1544.     if (rval != DD_OK) goto fail;
  1545.  
  1546.     // Set the backbuffer's palette
  1547.     rval = g_lpSplashPrimary->SetPalette(g_lpSplashPalette);
  1548.     if (rval != DD_OK) goto fail;
  1549.  
  1550.     // And flip the splash screen into view
  1551.     rval = g_lpSplashPrimary->Flip(NULL, DDFLIP_WAIT);
  1552.     if (rval != DD_OK) goto fail;
  1553.  
  1554.     // Wait for delay milliseconds or a specific keypress
  1555.     dwStart = timeGetTime();
  1556.     
  1557.     while (timeGetTime() - dwStart < delay)
  1558.     {
  1559.         if (GetAsyncKeyState(VK_SPACE) & 0x8000) break;
  1560.         if (GetAsyncKeyState(VK_RETURN) & 0x8000) break;
  1561.         if (GetAsyncKeyState(VK_ESCAPE) & 0x8000) break;
  1562.         if ((GetAsyncKeyState(VK_MENU) & 0x8000) && (GetAsyncKeyState(VK_F4) & 0x8000)) break;
  1563.     }   
  1564.  
  1565.     backbuffer->Release();
  1566.  
  1567.     // Yahoo!
  1568.     return TRUE;
  1569.  
  1570.     fail:
  1571.  
  1572.     // Close file
  1573.     if (fp)
  1574.     {
  1575.         fclose(fp);
  1576.     }
  1577.     
  1578.     // Release palette
  1579.     if (g_lpSplashPalette)
  1580.     {
  1581.         g_lpSplashPalette->Release();
  1582.         g_lpSplashPalette = NULL;
  1583.     }
  1584.  
  1585.     // Release primary surface
  1586.     if (g_lpSplashPrimary)
  1587.     {
  1588.         g_lpSplashPrimary->Release();
  1589.         g_lpSplashPrimary = NULL;
  1590.     }
  1591.  
  1592.     if (g_lpSplashDD)
  1593.     {
  1594.         g_lpSplashDD->Release();
  1595.         g_lpSplashDD = NULL;
  1596.     }
  1597.  
  1598.     // Yahoo!
  1599.     return FALSE;
  1600. }
  1601.  
  1602.  
  1603. //----------------------------------------------------------------------
  1604. // 
  1605. // Function     : ReleaseSplashScreen()
  1606. //
  1607. // Purpose      : Releases the splash screen
  1608. //
  1609. //----------------------------------------------------------------------
  1610.  
  1611. void ReleaseSplashScreen()
  1612. {
  1613.     // Release palette
  1614.     if (g_lpSplashPalette)
  1615.     {
  1616.         g_lpSplashPalette->Release();
  1617.         g_lpSplashPalette = NULL;
  1618.     }
  1619.  
  1620.     // Release primary surface
  1621.     if (g_lpSplashPrimary)
  1622.     {
  1623.         g_lpSplashPrimary->Release();
  1624.         g_lpSplashPrimary = NULL;
  1625.     }
  1626.  
  1627.     if (g_lpSplashDD)
  1628.     {
  1629.         g_lpSplashDD->Release();
  1630.         g_lpSplashDD = NULL;
  1631.     }
  1632. }
  1633.  
  1634.  
  1635. //----------------------------------------------------------------------
  1636. // 
  1637. // Function     : RestoreSurfaces()
  1638. //
  1639. // Purpose      : Restores all surfaces if they somehow got lost (Alt-Tab)
  1640. //
  1641. //----------------------------------------------------------------------
  1642.  
  1643. BOOL RestoreSurfaces()
  1644. {
  1645.     // Attempt to restore primary surface
  1646.     if (g_lpPrimary)
  1647.     {
  1648.         if (g_lpPrimary->IsLost()) TRY_DD(g_lpPrimary->Restore())
  1649.     }
  1650.  
  1651.     // Attempt to restore zbuffer
  1652.     if (g_lpZBuffer)
  1653.     {
  1654.         if (g_lpZBuffer->IsLost()) TRY_DD(g_lpZBuffer->Restore())
  1655.     }
  1656.  
  1657.     // Yahoo!
  1658.     return TRUE;
  1659. }
  1660.  
  1661. //----------------------------------------------------------------------
  1662. // 
  1663. // Function     : CreateSoundBuffer()
  1664. //
  1665. // Purpose      : Creates a DirectSound buffer
  1666. //
  1667. //----------------------------------------------------------------------
  1668.  
  1669. BOOL CreateSoundBuffer(DWORD dwBuf, DWORD dwBufSize, DWORD dwFreq, DWORD dwBitsPerSample, DWORD dwBlkAlign, BOOL bStereo)
  1670. {
  1671.     PCMWAVEFORMAT pcmwf;
  1672.     DSBUFFERDESC dsbdesc;
  1673.     
  1674.     // Set up wave format structure.
  1675.     memset( &pcmwf, 0, sizeof(PCMWAVEFORMAT) );
  1676.     pcmwf.wf.wFormatTag         = WAVE_FORMAT_PCM;      
  1677.     pcmwf.wf.nChannels          = bStereo ? 2 : 1;
  1678.     pcmwf.wf.nSamplesPerSec     = dwFreq;
  1679.     pcmwf.wf.nBlockAlign        = (WORD)dwBlkAlign;
  1680.     pcmwf.wf.nAvgBytesPerSec    = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign;
  1681.     pcmwf.wBitsPerSample        = (WORD)dwBitsPerSample;
  1682.  
  1683.     // Set up DSBUFFERDESC structure.
  1684.     memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));  // Zero it out. 
  1685.     dsbdesc.dwSize              = sizeof(DSBUFFERDESC);
  1686.     dsbdesc.dwFlags             = DSBCAPS_CTRL3D;               // Needed creation flag for Direct 3D Sound
  1687.         dsbdesc.dwBufferBytes       = dwBufSize; 
  1688.     dsbdesc.lpwfxFormat         = (LPWAVEFORMATEX)&pcmwf;
  1689.  
  1690.     TRY_DS(g_lpDS->CreateSoundBuffer(&dsbdesc, &g_lpSounds[dwBuf], NULL))
  1691.     
  1692.         // Query for the 3D Sound Buffer interface.
  1693.     TRY_DS(g_lpSounds[dwBuf]->QueryInterface(IID_IDirectSound3DBuffer, (void**) &g_lp3dSounds[dwBuf]));
  1694.  
  1695.     // Yahoo!
  1696.     return TRUE;
  1697. }
  1698.  
  1699. //----------------------------------------------------------------------
  1700. // 
  1701. // Function     : ReadData()
  1702. //
  1703. // Purpose      : Reads in data from a wave file
  1704. //
  1705. //----------------------------------------------------------------------
  1706.  
  1707. BOOL ReadData(LPDIRECTSOUNDBUFFER lpDSB, FILE* pFile, DWORD dwSize, DWORD dwPos) 
  1708. {
  1709.     // Seek to correct position in file (if necessary)
  1710.     if (dwPos != 0xffffffff) 
  1711.     {
  1712.         if (fseek(pFile, dwPos, SEEK_SET) != 0) 
  1713.         {
  1714.             return FALSE;
  1715.         }
  1716.     }
  1717.  
  1718.     // Lock data in buffer for writing
  1719.     LPVOID pData1;
  1720.     DWORD  dwData1Size;
  1721.     LPVOID pData2;
  1722.     DWORD  dwData2Size;
  1723.     HRESULT rval;
  1724.  
  1725.     rval = lpDSB->Lock(0, dwSize, &pData1, &dwData1Size, &pData2, &dwData2Size, DSBLOCK_FROMWRITECURSOR);
  1726.     if (rval != DS_OK)
  1727.     {
  1728.         return FALSE;
  1729.     }
  1730.  
  1731.     // Read in first chunk of data
  1732.     if (dwData1Size > 0) 
  1733.     {
  1734.         if (fread(pData1, dwData1Size, 1, pFile) != 1) 
  1735.         {          
  1736.                         char holder[256];
  1737.                         wsprintf(holder,"Data1 : %d, dwdata: %d, pFile: %d",pData1,dwData1Size,pFile);
  1738.                         OutputDebugString(holder);
  1739.             return FALSE;
  1740.         }
  1741.     }
  1742.  
  1743.     // read in second chunk if necessary
  1744.     if (dwData2Size > 0) 
  1745.     {
  1746.         if (fread(pData2, dwData2Size, 1, pFile) != 1) 
  1747.         {
  1748.             return FALSE;
  1749.         }
  1750.     }
  1751.  
  1752.     // Unlock data in buffer
  1753.     rval = lpDSB->Unlock(pData1, dwData1Size, pData2, dwData2Size);
  1754.     if (rval != DS_OK)
  1755.     {
  1756.         return FALSE;
  1757.     }
  1758.  
  1759.     // Yahoo!
  1760.     return TRUE;
  1761. }
  1762.  
  1763. //----------------------------------------------------------------------
  1764. // 
  1765. // Function     : CreateSoundBufferFromWaveFile()
  1766. //
  1767. // Purpose      : Creates a DirectSound buffer from a wave file
  1768. //
  1769. //----------------------------------------------------------------------
  1770.  
  1771. BOOL CreateBufferFromWaveFile(char* FileName, DWORD dwBuf)
  1772. {
  1773.     // Open the wave file       
  1774.     FILE* pFile = fopen(FileName,"rb");
  1775.     if (pFile == NULL) return FALSE;
  1776.  
  1777.     // Read in the wave header          
  1778.     WaveHeader wavHdr;
  1779.     if (fread(&wavHdr, sizeof(wavHdr), 1, pFile) != 1) 
  1780.     {
  1781.         fclose(pFile);
  1782.         return NULL;
  1783.     }
  1784.  
  1785.     // Figure out the size of the data region
  1786.     DWORD dwSize = wavHdr.dwDSize;
  1787.  
  1788.     // Is this a stereo or mono file?
  1789.     BOOL bStereo = wavHdr.wChnls > 1 ? TRUE : FALSE;
  1790.  
  1791.     // Create the sound buffer for the wave file
  1792.     if (!CreateSoundBuffer(dwBuf, dwSize, wavHdr.dwSRate, wavHdr.BitsPerSample, wavHdr.wBlkAlign, bStereo))
  1793.     {
  1794.         // Close the file
  1795.         fclose(pFile);
  1796.         
  1797.         return FALSE;
  1798.     }
  1799.  
  1800.     // Read the data for the wave file into the sound buffer
  1801.     if (!ReadData(g_lpSounds[dwBuf], pFile, dwSize, sizeof(wavHdr))) 
  1802.     {
  1803.         fclose(pFile);
  1804.         return FALSE;
  1805.     }
  1806.  
  1807.     // Close out the wave file
  1808.     fclose(pFile);
  1809.  
  1810.     // Yahoo!
  1811.     return TRUE;
  1812. }
  1813.  
  1814. //----------------------------------------------------------------------
  1815. // 
  1816. // Function     : StopAllSounds()
  1817. //
  1818. // Purpose      : Stops all sounds
  1819. //
  1820. //----------------------------------------------------------------------
  1821.  
  1822. BOOL StopAllSounds()
  1823. {
  1824.     // Make sure we have a valid sound buffer
  1825.     for (int i = 0; i < NUM_SOUNDS; i ++)
  1826.     {
  1827.         if (g_lpSounds[i])
  1828.         {
  1829.             DWORD dwStatus;
  1830.             TRY_DS(g_lpSounds[i]->GetStatus(&dwStatus));
  1831.  
  1832.             if ((dwStatus & DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING)
  1833.             {
  1834.                 // Play the sound
  1835.                 TRY_DS(g_lpSounds[i]->Stop())
  1836.             }
  1837.         }
  1838.     }
  1839.  
  1840.     // Yahoo!
  1841.     return TRUE;
  1842. }
  1843.  
  1844. //----------------------------------------------------------------------
  1845. // 
  1846. // Function     : PlaySoundDS()
  1847. //
  1848. // Purpose      : Plays a sound using direct sound
  1849. // 
  1850. //                      D3DVECTOR
  1851. //----------------------------------------------------------------------
  1852.  
  1853. BOOL PlaySoundDS(DWORD dwSound,D3DVECTOR d3dvPos, DWORD dwFlags)
  1854. {
  1855.  
  1856.     if (g_bSoundPaused) return TRUE;
  1857.  
  1858.     if (!g_bSoundPresent) return TRUE;
  1859.  
  1860.     // Make sure the sound is valid
  1861.     if (dwSound >= NUM_SOUNDS) return FALSE;    
  1862.  
  1863.     // Make sure we have a valid sound buffer
  1864.     if (g_lpSounds[dwSound])
  1865.     {
  1866.         DWORD dwStatus;
  1867.         TRY_DS(g_lpSounds[dwSound]->GetStatus(&dwStatus));
  1868.  
  1869.         if ((dwStatus & DSBSTATUS_PLAYING) != DSBSTATUS_PLAYING)
  1870.         {
  1871.            // Set the 3D position of the sound, using supplied position vector.
  1872.            TRY_DS(g_lp3dSounds[dwSound]->SetPosition(d3dvPos.x, d3dvPos.y, d3dvPos.z, DS3D_IMMEDIATE));
  1873.             // Play the sound
  1874.            TRY_DS(g_lpSounds[dwSound]->Play(0, 0, dwFlags));
  1875.         }
  1876.     }
  1877.  
  1878.     // Yahoo!
  1879.     return TRUE;
  1880. }
  1881.  
  1882. //----------------------------------------------------------------------
  1883. // 
  1884. // Function     : RecalcPowerBars()
  1885. //
  1886. // Purpose      : Calculates width of power bars based upon current 
  1887. //                        screen resolution
  1888. //
  1889. //----------------------------------------------------------------------
  1890.  
  1891. void RecalcPowerBars(DWORD player1health, DWORD player2health)
  1892. {
  1893.     g_wbar1 = (DWORD)(float)((400.0f * ((float)player1health / 100.0f)) * g_xratio);
  1894.     g_wbar2 = (DWORD)(float)((400.0f * ((float)player2health / 100.0f)) * g_xratio);
  1895. }
  1896.  
  1897.  
  1898.  
  1899. //----------------------------------------------------------------------
  1900. // 
  1901. // Function     : CreateSoundBuffer3D()
  1902. //
  1903. // Purpose      : Creates a 3D sound buffer and returns the sound buffer
  1904. //
  1905. //----------------------------------------------------------------------
  1906.  
  1907. IDirectSoundBuffer *CreateSoundBuffer3D()
  1908. {
  1909.     IDirectSoundBuffer *pDSB = NULL;
  1910.     DSBUFFERDESC dsBD = {0};
  1911.  
  1912.         ZeroMemory( &dsBD, sizeof(DSBUFFERDESC));
  1913.         dsBD.dwSize = sizeof(dsBD);
  1914.     dsBD.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_PRIMARYBUFFER;
  1915.         dsBD.dwBufferBytes = 0;  //must be zero for primary buffer..
  1916.  
  1917.         if (g_lpDS->CreateSoundBuffer(&dsBD, &pDSB, NULL) != DS_OK)
  1918.                 pDSB = NULL;
  1919.  
  1920.     return pDSB;
  1921. }
  1922.  
  1923. //----------------------------------------------------------------------
  1924. // 
  1925. // Function     : PlayRandomWave()
  1926. //
  1927. // Purpose      : Creates a random wave at a random spot
  1928. //
  1929. //----------------------------------------------------------------------
  1930.  
  1931. int CALLBACK  PlayRandomWave()
  1932. {
  1933.         D3DVECTOR       d3dPosition;    // DSVECTOR used for the positon of the wave...
  1934.  
  1935.         int RandomWave[]={RANDOM1,RANDOM2,RANDOM3,RANDOM4,RANDOM5,RANDOM6};
  1936.  
  1937.         g_lpCamera->GetPosition(g_lpScene, &d3dPosition);
  1938.         // fill in the position generated for the wave file.
  1939.         d3dPosition.x += (rand() % 2 == 0 ? (rand() % 250) : -(rand() % 250));
  1940.         d3dPosition.z += (rand() % 2 == 0 ? (rand() % 250) : -(rand() % 250));
  1941.  
  1942.         PlaySoundDS(RandomWave[rand() % (sizeof(RandomWave) / sizeof(RandomWave[0]))],d3dPosition);
  1943.         return TRUE;
  1944. }
  1945.