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