home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / DirectX SDK / DXSDK / samples / Multimedia / DirectPlay / Maze / MazeClient / D3DGraphics.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-10-31  |  49.3 KB  |  1,372 lines

  1. //----------------------------------------------------------------------------
  2. // File: d3dgraphics.cpp
  3. //
  4. // Desc: see main.cpp
  5. //
  6. // Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #define STRICT
  9. #define D3D_OVERLOADS
  10. #include <windows.h>
  11. #include <D3DX8.h>
  12. #include <dplay8.h>
  13. #include <stdio.h>
  14. #include <math.h>
  15. #include <mmsystem.h>
  16. #include <process.h>
  17. #include <dxerr8.h>
  18. #include <tchar.h>
  19. #include <dplay8.h>
  20. #include "SyncObjects.h"
  21. #include "DummyConnector.h"
  22. #include "IMazeGraphics.h"
  23. #include "SmartVB.h"
  24. #include "MazeServer.h"
  25. #include "MazeApp.h"
  26. #include "IMazeGraphics.h"
  27. #include "d3dSaver.h"
  28. #include "D3DFont.h"
  29. #include "D3DFile.h"
  30. #include "D3DUtil.h"
  31. #include "D3DGraphics.h"
  32. #include "resource.h"
  33. #include "DXUtil.h"
  34.  
  35. static CD3DGraphics* s_pGraphics = NULL;
  36.  
  37.  
  38.  
  39. //-----------------------------------------------------------------------------
  40. // Name:
  41. // Desc:
  42. //-----------------------------------------------------------------------------
  43. CD3DGraphics::CD3DGraphics()
  44. {
  45.     s_pGraphics             = this;
  46.     m_pMazeApp              = NULL;
  47.  
  48.     m_pSphere               = NULL;
  49.     m_pWallTexture          = NULL;
  50.     m_pFloorTexture         = NULL;
  51.     m_pCeilingTexture       = NULL;
  52.     m_pNetIconTexture       = NULL;
  53.     m_pLocalIconTexture     = NULL;
  54.  
  55.     // Tell the d3dsaver framework to run on one monitor only
  56.     m_bOneScreenOnly        = TRUE;
  57.  
  58.     m_bUseDepthBuffer       = TRUE;
  59.  
  60.     // Create fonts
  61.     m_pFont      = new CD3DFont( _T("Courier"), 12, D3DFONT_BOLD );
  62.     m_pStatsFont = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
  63.     m_pPlayerMesh  = new CD3DFile();
  64.     lstrcpy( m_strRegPath, MAZE_REGKEYNAME );
  65.     
  66. }
  67.  
  68.  
  69.  
  70.  
  71. //-----------------------------------------------------------------------------
  72. // Name:
  73. // Desc:
  74. //-----------------------------------------------------------------------------
  75. CD3DGraphics::~CD3DGraphics()
  76. {
  77. }
  78.  
  79.  
  80.  
  81.  
  82. //-----------------------------------------------------------------------------
  83. // Name:
  84. // Desc:
  85. //-----------------------------------------------------------------------------
  86. VOID CD3DGraphics::Init( CMazeApp* pMazeApp, CDPlay8Client* pDP8Client, 
  87.                          CMazeClient* pMazeClient )
  88. {
  89.     m_pMazeApp      = pMazeApp;
  90.     m_pMazeClient   = pMazeClient;
  91.     m_pDP8Client    = pDP8Client;
  92. }
  93.  
  94.  
  95.  
  96.  
  97. //-----------------------------------------------------------------------------
  98. // Name:
  99. // Desc:
  100. //-----------------------------------------------------------------------------
  101. HRESULT CD3DGraphics::Create( HINSTANCE hInstance )
  102. {
  103.     return CD3DScreensaver::Create( hInstance );
  104. }
  105.  
  106.  
  107.  
  108. //-----------------------------------------------------------------------------
  109. // Name: PostCreate()
  110. // Desc: 
  111. //-----------------------------------------------------------------------------
  112. HRESULT CD3DGraphics::PostCreate()
  113. {
  114.     HRESULT hr;
  115.  
  116.     // Create the screen saver window
  117.     if( m_SaverMode == sm_test    || 
  118.         m_SaverMode == sm_full )
  119.     {
  120.         if( FAILED( hr = CreateSaverWindow() ) )
  121.         {
  122.             m_bErrorMode = TRUE;
  123.             m_hrError = hr;
  124.         }
  125.     }
  126.  
  127.     return S_OK;
  128. }
  129.  
  130.  
  131.  
  132.  
  133. //-----------------------------------------------------------------------------
  134. // Name: Run()
  135. // Desc:
  136. //-----------------------------------------------------------------------------
  137. INT CD3DGraphics::Run()
  138. {
  139.     HRESULT hr;
  140.     BOOL bIsScreenSaver = TRUE;
  141.     TCHAR* strCmdLine = GetCommandLine();
  142.  
  143.     // Parse the command line and do the appropriate thing
  144.     m_SaverMode = ParseCommandLine( strCmdLine );
  145.  
  146.     // Skip along to the first option delimiter "/" or "-"
  147.     while ( *strCmdLine && *strCmdLine != '/' && *strCmdLine != '-' )
  148.         strCmdLine++;
  149.     
  150.     // If there weren't any params, then it must have run from a exe form
  151.     if ( *strCmdLine == 0 )
  152.     {
  153.         m_SaverMode = sm_config;
  154.         bIsScreenSaver = FALSE;
  155.     }
  156.  
  157.     m_pMazeApp->SetAllowLoopback( TRUE );
  158.  
  159.     switch ( m_SaverMode )
  160.     {
  161.         case sm_config:
  162.             ScreenSaverDoConfig( bIsScreenSaver );
  163.             if( m_dwStartMode == 0 )
  164.                 break;
  165.  
  166.             // Don't do AutoDisconnnect or Stress Connect in 3D client
  167.             m_pConfig = m_pMazeApp->GetConfig();
  168.             m_pConfig->bAutoDisconnnect = FALSE;
  169.             m_pConfig->dwStressConnect = 0;
  170.  
  171.             if( m_pConfig->bFullScreen )
  172.                 m_SaverMode = sm_full;
  173.             else
  174.                 m_SaverMode = sm_test;
  175.  
  176.             m_pMazeApp->SetAllowConnect( TRUE );
  177.  
  178.             PostCreate();   
  179.  
  180.             if( FAILED( hr = DoSaver() ) )
  181.                 DisplayErrorMsg( hr, 0 );
  182.             break;
  183.  
  184.         case sm_preview:
  185. /*
  186.             // This is temp code to allow stepping thru code in the preview case
  187.             WNDCLASS    cls;
  188.             cls.hCursor        = NULL; 
  189.             cls.hIcon          = NULL; 
  190.             cls.lpszMenuName   = NULL;
  191.             cls.lpszClassName  = "Parent"; 
  192.             cls.hbrBackground  = (HBRUSH) GetStockObject(WHITE_BRUSH);
  193.             cls.hInstance      = m_hInstance; 
  194.             cls.style          = CS_VREDRAW|CS_HREDRAW|CS_SAVEBITS|CS_DBLCLKS;
  195.             cls.lpfnWndProc    = DefWindowProc;
  196.             cls.cbWndExtra     = 0; 
  197.             cls.cbClsExtra     = 0; 
  198.             RegisterClass( &cls );
  199.  
  200.             // Create the window
  201.             RECT    rect;
  202.             HWND hwnd;
  203.             rect.left = rect.top = 40;
  204.             rect.right = rect.left+100;
  205.             rect.bottom = rect.top+100;
  206.             AdjustWindowRect( &rect , WS_VISIBLE|WS_OVERLAPPED|WS_CAPTION|WS_POPUP , FALSE );
  207.             hwnd= CreateWindow( "Parent", "FakeShell" ,
  208.                                    WS_VISIBLE|WS_OVERLAPPED|WS_CAPTION|WS_POPUP , rect.left , rect.top ,
  209.                                    rect.right-rect.left , rect.bottom-rect.top , NULL ,
  210.                                    NULL , m_hInstance , NULL );
  211.             m_hWndParent = hwnd;
  212. */
  213.         case sm_test:
  214.         case sm_full:
  215.             if( m_SaverMode == sm_preview )
  216.                 m_pMazeApp->SetAllowConnect( FALSE );
  217.             else
  218.                 m_pMazeApp->SetAllowConnect( TRUE );
  219.             
  220.             // Don't do AutoDisconnnect or StressConnect in 3D client
  221.             m_pConfig = m_pMazeApp->GetConfig();
  222.             m_pConfig->bAutoDisconnnect = FALSE;
  223.             m_pConfig->dwStressConnect = 0;
  224.  
  225.             if( m_SaverMode != sm_preview && m_pConfig->bFullScreen )
  226.                 m_SaverMode = sm_full;
  227.             else
  228.             {
  229.                 m_SaverMode = sm_test;
  230.             }
  231.  
  232.             if( FAILED( hr = DoSaver() ) )
  233.                 DisplayErrorMsg( hr, 0 );
  234.             break;
  235.     
  236.         case sm_passwordchange:
  237.             ChangePassword();
  238.             break;
  239.     }
  240.  
  241.     return 0;
  242. }
  243.  
  244.  
  245.  
  246.  
  247. //-----------------------------------------------------------------------------
  248. // Name:
  249. // Desc:
  250. //-----------------------------------------------------------------------------
  251. void CD3DGraphics::Shutdown()
  252. {
  253. }
  254.  
  255.  
  256.  
  257.  
  258.  
  259. //-----------------------------------------------------------------------------
  260. // Name: 
  261. // Desc: 
  262. //-----------------------------------------------------------------------------
  263. int CD3DGraphics::ScreenSaverDoConfig( BOOL bIsScreenSaverSettings )
  264. {
  265.     m_bIsScreenSaverSettings = bIsScreenSaverSettings;
  266.  
  267.     m_pMazeApp->ReadConfig();
  268.  
  269.     HKEY hKey = NULL;
  270.     RegOpenKeyEx( HKEY_CURRENT_USER, MAZE_REGKEYNAME, 0, KEY_READ, &hKey );
  271.     ReadScreenSettings( hKey );
  272.     RegCloseKey( hKey );
  273.  
  274.     m_pConfig = m_pMazeApp->GetConfig();
  275.  
  276.     if( DialogBox( m_hInstance, MAKEINTRESOURCE(IDD_SAVERCONFIG), 
  277.                    NULL, StaticSaverConfigDlgProc ) == IDOK )
  278.     {
  279.         m_pMazeApp->WriteConfig();
  280.  
  281.         HKEY hKey = NULL;
  282.         RegOpenKeyEx( HKEY_CURRENT_USER, MAZE_REGKEYNAME, 0, KEY_READ, &hKey );
  283.         WriteScreenSettings( hKey );
  284.         RegCloseKey( hKey );
  285.     }
  286.  
  287.     return 0;
  288. }
  289.  
  290.  
  291.  
  292.  
  293. //-----------------------------------------------------------------------------
  294. // Name: 
  295. // Desc: 
  296. //-----------------------------------------------------------------------------
  297. INT_PTR CALLBACK CD3DGraphics::StaticSaverConfigDlgProc( HWND hDlg, UINT uMsg, 
  298.                                                          WPARAM wParam, LPARAM lParam )
  299. {
  300.     return s_pGraphics->SaverConfigDlgProc( hDlg, uMsg, wParam, lParam );
  301. }
  302.  
  303.  
  304.  
  305.  
  306. //-----------------------------------------------------------------------------
  307. // Name: 
  308. // Desc: 
  309. //-----------------------------------------------------------------------------
  310. INT_PTR CALLBACK CD3DGraphics::SaverConfigDlgProc( HWND hDlg, UINT uMsg, 
  311.                                                    WPARAM wParam, LPARAM lParam )
  312. {
  313.     switch( uMsg )
  314.     {
  315.         case WM_INITDIALOG:
  316.             PopulateSaverConfigDlg( hDlg );
  317.             return TRUE;
  318.  
  319.         case WM_CLOSE:
  320.             EndDialog( hDlg, IDCANCEL );
  321.             break;
  322.  
  323.         case WM_COMMAND:
  324.             switch( HIWORD(wParam) )
  325.             {
  326.                 case BN_CLICKED:
  327.                     switch( LOWORD(wParam) )
  328.                     {
  329.                         case IDOK:
  330.                             ExtractSaverConfigDlgSettings( hDlg );
  331.                             m_dwStartMode = 0;
  332.                             EndDialog( hDlg, IDOK );
  333.                             break;
  334.  
  335.                         case IDC_LAUNCH:
  336.                             ExtractSaverConfigDlgSettings( hDlg );
  337.                             m_dwStartMode = 1;
  338.                             EndDialog( hDlg, IDOK );
  339.                             break;
  340.  
  341.                         case IDC_SCREENSETTINGS:
  342.                             DoScreenSettingsDialog( hDlg );
  343.                             break;
  344.  
  345.                         case IDCANCEL:
  346.                             EndDialog( hDlg, IDCANCEL );
  347.                             return TRUE;
  348.                     }
  349.                     break;
  350.             }
  351.             break;
  352.     }
  353.  
  354.     return FALSE;
  355. }
  356.  
  357.  
  358.  
  359.  
  360. //-----------------------------------------------------------------------------
  361. // Name: 
  362. // Desc: 
  363. //-----------------------------------------------------------------------------
  364. void CD3DGraphics::PopulateSaverConfigDlg( HWND hDlg )
  365. {
  366.     if( m_bIsScreenSaverSettings )
  367.         ShowWindow( GetDlgItem( hDlg, IDOK ), SW_SHOW );
  368.     else
  369.         ShowWindow( GetDlgItem( hDlg, IDOK ), SW_HIDE );
  370.  
  371.     CheckDlgButton( hDlg, IDC_MICROSOFT, m_pConfig->bConnectToMicrosoftSite );
  372.     CheckDlgButton( hDlg, IDC_LOCAL_SERVER, m_pConfig->bConnectToLocalServer );
  373.     CheckDlgButton( hDlg, IDC_REMOTE_SERVER, m_pConfig->bConnectToRemoteServer );
  374.     SetDlgItemInt( hDlg, IDC_RETRY_DELAY, m_pConfig->dwNetworkRetryDelay, FALSE );
  375.     CheckDlgButton( hDlg, IDC_FRAMERATE, m_pConfig->bShowFramerate );
  376.     CheckDlgButton( hDlg, IDC_INDICATORS, m_pConfig->bShowIndicators );
  377.     CheckDlgButton( hDlg, IDC_FULLSCREEN, m_pConfig->bFullScreen );
  378.     CheckDlgButton( hDlg, IDC_MINIMAP, m_pConfig->bDrawMiniMap );
  379.     CheckDlgButton( hDlg, IDC_REFLECTIONS, m_pConfig->bReflections );
  380.     CheckDlgButton( hDlg, IDC_FILELOGGING, m_pConfig->bFileLogging );
  381.  
  382.     SetDlgItemText( hDlg, IDC_IPADDRESS, m_pConfig->szIPAddress );
  383.     SendDlgItemMessage( hDlg, IDC_IPADDRESS, EM_SETLIMITTEXT, sizeof(m_pConfig->szIPAddress)-1, 0 );
  384. }
  385.  
  386.  
  387.  
  388.  
  389. //-----------------------------------------------------------------------------
  390. // Name: 
  391. // Desc: 
  392. //-----------------------------------------------------------------------------
  393. void CD3DGraphics::ExtractSaverConfigDlgSettings( HWND hDlg )
  394. {
  395.     m_pConfig->bConnectToMicrosoftSite    = IsDlgButtonChecked( hDlg, IDC_MICROSOFT );
  396.     m_pConfig->bConnectToLocalServer      = IsDlgButtonChecked( hDlg, IDC_LOCAL_SERVER );
  397.     m_pConfig->bConnectToRemoteServer     = IsDlgButtonChecked( hDlg, IDC_REMOTE_SERVER );
  398.     m_pConfig->dwNetworkRetryDelay        = GetDlgItemInt( hDlg, IDC_RETRY_DELAY, NULL, FALSE );
  399.     m_pConfig->bShowFramerate             = IsDlgButtonChecked( hDlg, IDC_FRAMERATE );
  400.     m_pConfig->bShowIndicators            = IsDlgButtonChecked( hDlg, IDC_INDICATORS );
  401.     m_pConfig->bFullScreen                = IsDlgButtonChecked( hDlg, IDC_FULLSCREEN );
  402.     m_pConfig->bDrawMiniMap               = IsDlgButtonChecked( hDlg, IDC_MINIMAP );
  403.     m_pConfig->bReflections               = IsDlgButtonChecked( hDlg, IDC_REFLECTIONS );
  404.     m_pConfig->bFileLogging               = IsDlgButtonChecked( hDlg, IDC_FILELOGGING );
  405.  
  406.     GetDlgItemText( hDlg, IDC_IPADDRESS, m_pConfig->szIPAddress, sizeof(m_pConfig->szIPAddress) );
  407. }
  408.  
  409.  
  410.  
  411.  
  412. //-----------------------------------------------------------------------------
  413. // Name: 
  414. // Desc: 
  415. //-----------------------------------------------------------------------------
  416. void CD3DGraphics::HandleOutputMsg( EnumLineType enumLineType, TCHAR* strLine )
  417. {
  418.     // Nothing needs to be done here
  419.     return;
  420. }
  421.  
  422.  
  423.  
  424.  
  425. //-----------------------------------------------------------------------------
  426. // Name: 
  427. // Desc: 
  428. //-----------------------------------------------------------------------------
  429. LRESULT CD3DGraphics::SaverProc( HWND hWnd , UINT message , WPARAM wParam , LPARAM lParam )
  430. {
  431.     switch( message )
  432.     {
  433.         case WM_KEYDOWN:
  434.             if( wParam == 'R' )
  435.                 m_pConfig->bReflections = !m_pConfig->bReflections;
  436.             else if( wParam == 'A' )
  437.                 m_pMazeClient->EngageAutopilot( !m_pMazeClient->IsAutopilot() );
  438.             break;
  439.  
  440.         case WM_POWERBROADCAST:
  441.             switch( wParam )
  442.             {
  443.                 #ifndef PBT_APMQUERYSUSPEND  // Defines are here for old compilers
  444.                     #define PBT_APMQUERYSUSPEND 0x0000
  445.                 #endif
  446.                 #ifndef BROADCAST_QUERY_DENY
  447.                     #define BROADCAST_QUERY_DENY         0x424D5144 
  448.                 #endif
  449.                 case PBT_APMQUERYSUSPEND:
  450.                     // Tell the OS not to suspend, otherwise we
  451.                     // will loose the network connection.
  452.                     return BROADCAST_QUERY_DENY;
  453.  
  454.                 #ifndef PBT_APMRESUMESUSPEND
  455.                     #define PBT_APMRESUMESUSPEND 0x0007
  456.                 #endif
  457.                 case PBT_APMRESUMESUSPEND:
  458.                     return TRUE;
  459.             }
  460.             break;
  461.     }
  462.  
  463.     return CD3DScreensaver::SaverProc( hWnd, message, wParam, lParam );
  464. }
  465.  
  466.  
  467.  
  468.  
  469. //-----------------------------------------------------------------------------
  470. // Name: 
  471. // Desc: 
  472. //-----------------------------------------------------------------------------
  473. HRESULT CD3DGraphics::ConfirmDevice(D3DCAPS8* pCaps, DWORD dwBehavior,
  474.                                           D3DFORMAT Format )
  475.     if( dwBehavior & D3DCREATE_PUREDEVICE )
  476.         return E_FAIL; // GetTransform doesn't work on PUREDEVICE
  477.  
  478.     return S_OK; 
  479. }
  480.  
  481.  
  482.  
  483.  
  484. //-----------------------------------------------------------------------------
  485. // Name: 
  486. // Desc: 
  487. //-----------------------------------------------------------------------------
  488. HRESULT CD3DGraphics::OneTimeSceneInit()                         
  489.     return S_OK; 
  490. }
  491.  
  492.  
  493.  
  494.  
  495. //-----------------------------------------------------------------------------
  496. // Name: 
  497. // Desc: 
  498. //-----------------------------------------------------------------------------
  499. HRESULT CD3DGraphics::CreateTextureFromResource( INT nResource, LPDIRECT3DTEXTURE8* ppTexture )                         
  500.     if( FAILED( D3DXCreateTextureFromResourceEx( m_pd3dDevice, NULL, MAKEINTRESOURCE( nResource ), 
  501.                         D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_A8R8G8B8, 
  502.                         D3DPOOL_MANAGED, D3DX_FILTER_TRIANGLE|D3DX_FILTER_MIRROR, 
  503.                         D3DX_FILTER_TRIANGLE|D3DX_FILTER_MIRROR, 0xFF000000, NULL, NULL, ppTexture ) ) )
  504.         return D3DAPPERR_MEDIANOTFOUND;
  505.  
  506.     return S_OK; 
  507. }
  508.  
  509.  
  510.  
  511.  
  512. //-----------------------------------------------------------------------------
  513. // Name: 
  514. // Desc: 
  515. //-----------------------------------------------------------------------------
  516. HRESULT CD3DGraphics::InitDeviceObjects()
  517.     HRESULT hr;
  518.  
  519.     m_dwTesselation = 3;
  520.  
  521.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
  522.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  523.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );
  524.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
  525.  
  526.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  527.     m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
  528.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
  529.     m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
  530.  
  531.     // Restore the fonts
  532.     m_pFont->InitDeviceObjects( m_pd3dDevice );
  533.     m_pStatsFont->InitDeviceObjects( m_pd3dDevice );
  534.  
  535.     if( FAILED( CreateTextureFromResource( IDB_WALLTEXTURE, &m_pWallTexture ) ) )
  536.         return DXTRACE_ERR_NOMSGBOX( TEXT("IDB_WALLTEXTURE"), D3DAPPERR_MEDIANOTFOUND );
  537.     if( FAILED( CreateTextureFromResource( IDB_FLOORTEXTURE, &m_pFloorTexture ) ) )
  538.         return DXTRACE_ERR_NOMSGBOX( TEXT("IDB_FLOORTEXTURE"), D3DAPPERR_MEDIANOTFOUND );
  539.     if( FAILED( CreateTextureFromResource( IDB_CEILINGTEXTURE, &m_pCeilingTexture ) ) )
  540.         return DXTRACE_ERR_NOMSGBOX( TEXT("IDB_CEILINGTEXTURE"), D3DAPPERR_MEDIANOTFOUND );
  541.     if( FAILED( CreateTextureFromResource( IDB_NETICON, &m_pNetIconTexture ) ) )
  542.         return DXTRACE_ERR_NOMSGBOX( TEXT("IDB_NETICON"), D3DAPPERR_MEDIANOTFOUND );
  543.     if( FAILED( CreateTextureFromResource( IDB_LOCALICON, &m_pLocalIconTexture ) ) )
  544.         return DXTRACE_ERR_NOMSGBOX( TEXT("IDB_LOCALICON"), D3DAPPERR_MEDIANOTFOUND );
  545.  
  546.     // Create airplane for rendering players
  547.     if( FAILED( m_pPlayerMesh->CreateFromResource( m_pd3dDevice, MAKEINTRESOURCE(IDB_TANK), TEXT("XFILE") ) ) )
  548.         return DXTRACE_ERR( TEXT("tank.x"), D3DAPPERR_MEDIANOTFOUND );
  549.  
  550.     // Create sphere for rendering clients
  551.     if( FAILED( hr = D3DXCreateSphere( m_pd3dDevice, 0.2f, 8, 8, &m_pSphere, NULL ) ) )
  552.         return DXTRACE_ERR_NOMSGBOX( TEXT("D3DXCreateSphere"), hr );
  553.  
  554.     if( FAILED( hr = m_pd3dDevice->CreateVertexBuffer( sizeof(VERTEX_TL_DIFFUSE) * 4, 
  555.                                                 D3DUSAGE_WRITEONLY, FVF_TL_DIFFUSE, 
  556.                                                 D3DPOOL_MANAGED, &m_pMiniMapBackgroundVB ) ) )
  557.         return DXTRACE_ERR_NOMSGBOX( TEXT("CreateVertexBuffer"), hr );
  558.  
  559.     if( FAILED( hr = m_pd3dDevice->CreateVertexBuffer( sizeof(VERTEX_TL_TEXTURED) * 4, 
  560.                                                 D3DUSAGE_WRITEONLY, FVF_TL_TEXTURED, 
  561.                                                 D3DPOOL_MANAGED, &m_pIndicatorVB ) ) )
  562.         return DXTRACE_ERR_NOMSGBOX( TEXT("CreateVertexBuffer"), hr );
  563.  
  564.     return S_OK; 
  565. }
  566.  
  567.  
  568.  
  569.  
  570. //-----------------------------------------------------------------------------
  571. // Name: 
  572. // Desc: 
  573. //-----------------------------------------------------------------------------
  574. HRESULT CD3DGraphics::RestoreDeviceObjects()
  575.     HRESULT hr;
  576.  
  577.     // Restore the fonts
  578.     m_pFont->RestoreDeviceObjects();
  579.     m_pStatsFont->RestoreDeviceObjects();
  580.  
  581.     m_pPlayerMesh->RestoreDeviceObjects( m_pd3dDevice );
  582.  
  583.     // Initialise the SmartVB for the walls
  584.     if( FAILED( hr = m_SmartVB.Init( m_pD3D, m_pd3dDevice, 2048 ) ) )
  585.         return DXTRACE_ERR_NOMSGBOX( TEXT("m_SmartVB.Init"), hr );
  586.  
  587.     if( FAILED( hr = m_pd3dDevice->CreateVertexBuffer( sizeof(VERTEX_DIFFUSE) * 1024, 
  588.                                                 D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, FVF_DIFFUSE, 
  589.                                                 D3DPOOL_DEFAULT, &m_pMiniMapVB ) ) )
  590.         return DXTRACE_ERR_NOMSGBOX( TEXT("CreateVertexBuffer"), hr );
  591.  
  592.     // Set projection matrix
  593.     const float fov = 1.8f;
  594.     const float znear = 0.1f;
  595.     const float zfar = 30.0f;
  596.     const float viewwidth = float(tan(fov*0.5f) ) * znear;
  597.     const float viewheight = viewwidth * float(m_d3dsdBackBuffer.Height)/float(m_d3dsdBackBuffer.Width);
  598.     D3DXMatrixPerspectiveLH( &m_Projection, viewwidth, viewheight, znear, zfar );
  599.     m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &m_Projection );
  600.  
  601.     // Set renderstates and lighting
  602.     D3DXMATRIX matIden; D3DXMatrixIdentity( &matIden );
  603.     m_pd3dDevice->SetTransform( D3DTS_WORLD, &matIden );
  604.     m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
  605.     m_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x333333 );
  606.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
  607.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
  608.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR );
  609.     m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
  610.     m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
  611.     m_pd3dDevice->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESSEQUAL );
  612.     m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
  613.     m_pd3dDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
  614.  
  615.     D3DMATERIAL8 mtrl;
  616.     D3DUtil_InitMaterial( mtrl, 1.0f, 1.0f, 1.0f );
  617.     m_pd3dDevice->SetMaterial( &mtrl );
  618.  
  619.     // Init light
  620.     D3DUtil_InitLight( m_Light, D3DLIGHT_POINT, m_vCameraPos.x, m_vCameraPos.y, m_vCameraPos.z );
  621.     m_Light.Direction = D3DXVECTOR3(0,0,0);
  622.     m_Light.Range = 80.0f;
  623.     m_Light.Attenuation0 = 1.0f;
  624.     m_Light.Attenuation1 = 0.0f;
  625.     m_Light.Attenuation2 = 1.0f;
  626.     m_pd3dDevice->SetLight( 0, &m_Light );
  627.     m_pd3dDevice->LightEnable( 0, TRUE );
  628.  
  629.     return S_OK; 
  630. }
  631.  
  632.  
  633.  
  634.  
  635. //-----------------------------------------------------------------------------
  636. // Name: 
  637. // Desc: 
  638. //-----------------------------------------------------------------------------
  639. HRESULT CD3DGraphics::FrameMove()
  640.     m_pMazeApp->FrameMove( m_fElapsedTime );
  641.  
  642.     return S_OK; 
  643. }
  644.  
  645.  
  646.  
  647.  
  648. //-----------------------------------------------------------------------------
  649. // Name: 
  650. // Desc: 
  651. //-----------------------------------------------------------------------------
  652. HRESULT CD3DGraphics::Render()
  653.     // Clear the viewport
  654.     m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L );
  655.  
  656.     // Begin the scene 
  657.     if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
  658.     {
  659.         m_vCameraPos = m_pMazeClient->GetCameraPos();
  660.         m_fCameraYaw = AngleToFloat(m_pMazeClient->GetCameraYaw() );
  661.  
  662.         // Compute and set view matrix
  663.         D3DXMATRIX matTrans,matRot;
  664.         D3DXMatrixTranslation( &matTrans, -m_vCameraPos.x, -m_vCameraPos.y, -m_vCameraPos.z );
  665.         D3DXMatrixRotationY( &matRot, m_fCameraYaw );
  666.         m_Camera = matTrans * matRot;
  667.         m_pd3dDevice->SetTransform( D3DTS_VIEW, &m_Camera );
  668.  
  669.         // Move light
  670.         m_Light.Position = m_vCameraPos;
  671.         m_pd3dDevice->SetLight( 0, &m_Light );
  672.  
  673.         // Get visibility set of maze
  674.         D3DXVECTOR2 dir;
  675.         dir.y = float(cos(m_fCameraYaw) );
  676.         dir.x = float(-sin(m_fCameraYaw) );
  677.         m_dwNumVisibleCells = m_pMazeClient->m_Maze.GetVisibleCells( D3DXVECTOR2(m_vCameraPos.x, m_vCameraPos.z) ,
  678.                                                                    dir, 1.8f, m_mcrVisList, MAX_VISLIST );
  679.  
  680.         // Draw reflection of walls and ceiling in floor
  681.         if( m_pConfig->bReflections )
  682.         {
  683.             D3DXMATRIX reflectcamera = m_Camera;
  684.             reflectcamera.m[1][0] = -reflectcamera.m[1][0];
  685.             reflectcamera.m[1][1] = -reflectcamera.m[1][1];
  686.             reflectcamera.m[1][2] = -reflectcamera.m[1][2];
  687.             reflectcamera.m[1][3] = -reflectcamera.m[1][3];
  688.             m_pd3dDevice->SetTransform( D3DTS_VIEW, &reflectcamera );
  689.  
  690.             m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW );
  691.  
  692.             m_Light.Diffuse = D3DXCOLOR(0.7f,0.7f,0.7f,0);
  693.             m_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x222222 );
  694.             m_pd3dDevice->SetLight( 0, &m_Light );
  695.  
  696.             DrawWalls();
  697.             DrawCeiling();
  698. //            DrawPlayers();
  699.  
  700.             m_Light.Diffuse = D3DXCOLOR(1,1,1,0);
  701.             m_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x333333 );
  702.             m_pd3dDevice->SetLight( 0, &m_Light );
  703.  
  704.             m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
  705.             m_pd3dDevice->SetTransform( D3DTS_VIEW, &m_Camera );
  706.         }
  707.  
  708.         // Draw floor
  709.         if( m_pConfig->bReflections )
  710.         {
  711.             m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
  712.             m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
  713.             m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
  714.         }
  715.  
  716.         DrawFloor();
  717.         if( m_pConfig->bReflections )
  718.             m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
  719.  
  720.         // Draw walls and ceiling
  721.         DrawWalls();
  722.         DrawCeiling();
  723.  
  724.         // Draw Players
  725.         DrawPlayers();
  726.  
  727.         // Draw mini-map
  728.         if( m_pConfig->bDrawMiniMap )
  729.             DrawMiniMap();
  730.  
  731.         // Draw indicators
  732.         if( m_pConfig->bShowIndicators )
  733.             DrawIndicators();
  734.  
  735.         // Show frame rate
  736.         m_pStatsFont->DrawText( 2,  0, D3DCOLOR_ARGB(255,255,255,0), m_strFrameStats );
  737.         m_pStatsFont->DrawText( 2, 20, D3DCOLOR_ARGB(255,255,255,0), m_strDeviceStats );
  738.  
  739.         // End the scene.
  740.         m_pd3dDevice->EndScene();
  741.     }
  742.  
  743.     return S_OK;
  744. }
  745.  
  746.  
  747.  
  748.  
  749.  
  750. //-----------------------------------------------------------------------------
  751. // Name:
  752. // Desc:
  753. //-----------------------------------------------------------------------------
  754. void CD3DGraphics::DrawPlayers()
  755. {
  756.     D3DXMATRIX matWorld;
  757.     D3DXMATRIX matScale;
  758.     D3DXMATRIX matTrans;
  759.     D3DXMATRIX matRot;
  760.  
  761.     D3DXMatrixScaling( &matScale, 0.25f, 0.25f, 0.25f );
  762.  
  763.     MazeCellRef* pCell = m_mcrVisList;
  764.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
  765.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  766.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
  767.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
  768.     m_pd3dDevice->SetTexture( 0, m_pCeilingTexture );
  769.  
  770.     m_pMazeClient->LockWorld();
  771.     for( DWORD i = 0; i < m_dwNumVisibleCells; i++, pCell++ )
  772.     {
  773.         PlayerObject* pPlayerObject = m_pMazeClient->GetFirstPlayerObjectInCell( pCell->x, pCell->y );
  774.         while( pPlayerObject )
  775.         {
  776.             D3DXMatrixTranslation( &matTrans, pPlayerObject->vPos.x, pPlayerObject->vPos.y - 0.5f, pPlayerObject->vPos.z );
  777.             D3DXMatrixRotationYawPitchRoll( &matRot, -AngleToFloat(pPlayerObject->aCameraYaw), -D3DX_PI/2.0f, 0.0f );
  778.             matWorld = matScale * matRot * matTrans;
  779.  
  780.             m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
  781.             // m_pSphere->DrawSubset( 0 );
  782.             m_pPlayerMesh->Render( m_pd3dDevice );
  783.  
  784.             pPlayerObject = pPlayerObject->pNext;
  785.         }
  786.     }
  787.  
  788.     m_pd3dDevice->SetTexture( 0, NULL );
  789.  
  790.     D3DMATERIAL8 mtrl;
  791.     D3DUtil_InitMaterial( mtrl, 1.0f, 1.0f, 1.0f );
  792.     m_pd3dDevice->SetMaterial( &mtrl );
  793.  
  794.     m_pMazeClient->UnlockWorld();
  795. }
  796.  
  797.  
  798.  
  799.  
  800. //-----------------------------------------------------------------------------
  801. // Name:
  802. // Desc:
  803. //-----------------------------------------------------------------------------
  804. void CD3DGraphics::DrawFloor()
  805. {
  806.     MazeCellRef*    pCell = m_mcrVisList;
  807.     VERTEX_TEXURED* pVert;
  808.     WORD*           pIndex;
  809.     WORD            offset;
  810.     D3DXVECTOR3     normal(0,1,0);
  811.     DWORD           verts_per_side = (m_dwTesselation+1)*(m_dwTesselation+1);
  812.     DWORD           indicies_per_side = m_dwTesselation*m_dwTesselation*6;
  813.  
  814.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
  815.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  816.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
  817.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
  818.     m_pd3dDevice->SetTexture( 0, m_pFloorTexture );
  819.  
  820.     m_SmartVB.Begin();
  821.     for( DWORD i = 0; i < m_dwNumVisibleCells; i++, pCell++ )
  822.     {
  823.         D3DXVECTOR3 pos( float(pCell->x), 0, float(pCell->y) );
  824.         m_SmartVB.MakeRoom( verts_per_side, indicies_per_side, &pVert, &pIndex, &offset );
  825.         LoadQuad( pVert, pIndex, offset, pos, D3DXVECTOR3(1,0,0), D3DXVECTOR3(0,0,1) ,
  826.                   D3DXVECTOR3(0,1,0) );
  827.     }
  828.     m_SmartVB.End();
  829. }
  830.  
  831.  
  832.  
  833.  
  834. //-----------------------------------------------------------------------------
  835. // Name:
  836. // Desc:
  837. //-----------------------------------------------------------------------------
  838. void CD3DGraphics::DrawCeiling()
  839. {
  840.     MazeCellRef*    pCell = m_mcrVisList;
  841.     VERTEX_TEXURED* pVert;
  842.     WORD*           pIndex;
  843.     WORD            offset;
  844.     D3DXVECTOR3     normal(0,1,0);
  845.     DWORD           verts_per_side = (m_dwTesselation+1)*(m_dwTesselation+1);
  846.     DWORD           indicies_per_side = m_dwTesselation*m_dwTesselation*6;
  847.  
  848.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
  849.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  850.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
  851.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
  852.     m_pd3dDevice->SetTexture( 0, m_pCeilingTexture );
  853.  
  854.     m_SmartVB.Begin();
  855.     for( DWORD i = 0; i < m_dwNumVisibleCells; i++, pCell++ )
  856.     {
  857.         D3DXVECTOR3 pos( float(pCell->x), 1, float(1+pCell->y) );
  858.         m_SmartVB.MakeRoom( verts_per_side, indicies_per_side, &pVert, &pIndex, &offset );
  859.         LoadQuad( pVert, pIndex, offset, pos, D3DXVECTOR3(1,0,0), D3DXVECTOR3(0,0,-1) ,
  860.                   D3DXVECTOR3(0,-1,0) );
  861.     }
  862.     m_SmartVB.End();
  863. }
  864.  
  865.  
  866.  
  867.  
  868. //-----------------------------------------------------------------------------
  869. // Name:
  870. // Desc:
  871. //-----------------------------------------------------------------------------
  872. void CD3DGraphics::DrawWalls()
  873. {
  874.     MazeCellRef*  pCell = m_mcrVisList;
  875.     VERTEX_TEXURED* pVert;
  876.     WORD*         pIndex;
  877.     WORD          offset;
  878.     DWORD         verts_per_side = (m_dwTesselation+1)*(m_dwTesselation+1);
  879.     DWORD         indicies_per_side = m_dwTesselation*m_dwTesselation*6;
  880.  
  881.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
  882.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  883.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
  884.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
  885.     m_pd3dDevice->SetTexture( 0, m_pWallTexture );
  886.  
  887.     m_SmartVB.Begin();
  888.     for( DWORD i = 0; i < m_dwNumVisibleCells; i++, pCell++ )
  889.     {
  890.         BYTE cell = m_pMazeClient->m_Maze.GetCell(pCell->x,pCell->y);
  891.  
  892.         if( cell & MAZE_WALL_NORTH )
  893.         {
  894.             D3DXVECTOR3 pos( float(pCell->x), 1, float(pCell->y) );
  895.             m_SmartVB.MakeRoom( verts_per_side, indicies_per_side, &pVert, &pIndex, &offset );
  896.             LoadQuad( pVert, pIndex, offset, pos, D3DXVECTOR3(1,0,0), D3DXVECTOR3(0,-1,0) ,
  897.                       D3DXVECTOR3(0,0,1) );
  898.         }
  899.         if( cell & MAZE_WALL_SOUTH )
  900.         {
  901.             D3DXVECTOR3 pos( float(1+pCell->x), 1, float(1+pCell->y) );
  902.             m_SmartVB.MakeRoom( verts_per_side, indicies_per_side, &pVert, &pIndex, &offset );
  903.             LoadQuad( pVert, pIndex, offset, pos, D3DXVECTOR3(-1,0,0), D3DXVECTOR3(0,-1,0) ,
  904.                       D3DXVECTOR3(0,0,-1) );
  905.         }
  906.         if( cell & MAZE_WALL_WEST )
  907.         {
  908.             D3DXVECTOR3 pos( float(pCell->x), 1, float(1+pCell->y) );
  909.             m_SmartVB.MakeRoom( verts_per_side, indicies_per_side, &pVert, &pIndex, &offset );
  910.             LoadQuad( pVert, pIndex, offset, pos, D3DXVECTOR3(0,0,-1), D3DXVECTOR3(0,-1,0) ,
  911.                       D3DXVECTOR3(1,0,0) );
  912.         }
  913.         if( cell & MAZE_WALL_EAST )
  914.         {
  915.             D3DXVECTOR3 pos( float(1+pCell->x), 1, float(pCell->y) );
  916.             m_SmartVB.MakeRoom( verts_per_side, indicies_per_side, &pVert, &pIndex, &offset );
  917.             LoadQuad( pVert, pIndex, offset, pos, D3DXVECTOR3(0,0,1), D3DXVECTOR3(0,-1,0) ,
  918.                       D3DXVECTOR3(-1,0,0) );
  919.         }
  920.     }
  921.     m_SmartVB.End();
  922. }
  923.  
  924.  
  925.  
  926.  
  927. //-----------------------------------------------------------------------------
  928. // Name:
  929. // Desc:
  930. //-----------------------------------------------------------------------------
  931. void CD3DGraphics::LoadQuad( VERTEX_TEXURED* pVerts, WORD* pIndex, WORD wOffset,
  932.                       const D3DXVECTOR3& vOrigin, const D3DXVECTOR3& vBasis1,
  933.                       const D3DXVECTOR3& vBasis2, const D3DXVECTOR3& vNormal )
  934. {
  935.     // Compute edge steps
  936.     float       fStep = 1.0f / m_dwTesselation;
  937.     D3DXVECTOR3 vStep1 = vBasis1 * fStep;
  938.     D3DXVECTOR3 vStep2 = vBasis2 * fStep;
  939.  
  940.     // Fill out grid of vertices
  941.     D3DXVECTOR3 rowstart = vOrigin;
  942.     float u = 0;
  943.     for( DWORD i = 0; i <= m_dwTesselation; i++, rowstart += vStep1, u += fStep )
  944.     {
  945.         D3DXVECTOR3 pos = rowstart;
  946.         float     v = 0;
  947.         for( DWORD j = 0; j <= m_dwTesselation; j++, pos += vStep2, v += fStep )
  948.         {
  949.             pVerts->vPos = pos;
  950.             pVerts->vNormal = vNormal;
  951.             pVerts->fU = u;
  952.             pVerts->fV = v;
  953.             pVerts++;
  954.         }
  955.     }
  956.  
  957.     // Fill out grid of indicies
  958.     for( i = 0; i < m_dwTesselation; i++ )
  959.     {
  960.         for( DWORD j = 0; j < m_dwTesselation; j++ )
  961.         {
  962.             *pIndex++ = wOffset;
  963.             *pIndex++ = wOffset+1;
  964.             *pIndex++ = wOffset+1+(WORD(m_dwTesselation)+1);
  965.             *pIndex++ = wOffset;
  966.             *pIndex++ = wOffset+1+(WORD(m_dwTesselation)+1);
  967.             *pIndex++ = wOffset+(WORD(m_dwTesselation)+1);
  968.             wOffset++;
  969.         }
  970.         wOffset++;
  971.     }
  972. }
  973.  
  974.  
  975.  
  976.  
  977. //-----------------------------------------------------------------------------
  978. // Name:
  979. // Desc:
  980. //-----------------------------------------------------------------------------
  981. void CD3DGraphics::DrawMiniMap()
  982. {
  983.     DWORD           y;
  984.     DWORD           x;
  985.     VERTEX_DIFFUSE* verts = NULL;
  986.     D3DXVECTOR3     pos;
  987.     D3DXVECTOR3     origin;
  988.     D3DXMATRIX      matWorld;
  989.     D3DXMATRIX      matTrans;
  990.     D3DXMATRIX      matRot;
  991.     MazeCellRef*    pCell = NULL;
  992.  
  993.     // Compute size of mini-map based on display size
  994.     DWORD mapsize = m_d3dsdBackBuffer.Width / 4;
  995.     int mapx = m_d3dsdBackBuffer.Width  - mapsize - 16;
  996.     int mapy = m_d3dsdBackBuffer.Height - mapsize - 16;
  997.  
  998.     if( mapx < 0 || mapy < 0 )
  999.         return;
  1000.  
  1001.     // Disable z-buffering
  1002.     m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
  1003.     m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
  1004.  
  1005.     D3DXMatrixIdentity( &matWorld );
  1006.     m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
  1007.  
  1008.     // Draw alpha blended background
  1009.     VERTEX_TL_DIFFUSE* v;   
  1010.  
  1011.     m_pMiniMapBackgroundVB->Lock( 0, 0, (BYTE**)&v, 0 );
  1012.     v[0].vPos.x = float(mapx)-0.5f;             v[0].vPos.y = float(mapy)-0.5f;
  1013.     v[1].vPos.x = float(mapx+mapsize)-0.5f;     v[1].vPos.y = float(mapy)-0.5f;
  1014.     v[2].vPos.x = float(mapx+mapsize)-0.5f;     v[2].vPos.y = float(mapy+mapsize)-0.5f;
  1015.     v[3].vPos.x = float(mapx)-0.5f;             v[3].vPos.y = float(mapy+mapsize)-0.5f;
  1016.     v[0].vPos.z     = v[1].vPos.z     = v[2].vPos.z     = v[3].vPos.z    = 0.1f;
  1017.     v[0].fRHW       = v[1].fRHW       = v[2].fRHW       = v[3].fRHW      = 1.0f;
  1018.     v[0].dwDiffuse  = v[1].dwDiffuse  = v[2].dwDiffuse  = v[3].dwDiffuse = 0x80008000;
  1019.     m_pMiniMapBackgroundVB->Unlock();
  1020.  
  1021.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
  1022.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  1023.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );
  1024.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
  1025.     m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
  1026.     m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
  1027.     m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
  1028.     m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
  1029.  
  1030.     m_pd3dDevice->SetVertexShader( FVF_TL_DIFFUSE );
  1031.     m_pd3dDevice->SetStreamSource( 0, m_pMiniMapBackgroundVB, sizeof(VERTEX_TL_DIFFUSE) );
  1032.     m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 );
  1033.  
  1034.     m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
  1035.     m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
  1036.  
  1037.     DWORD dwLineCount = 0;
  1038.  
  1039.     // Now set matrices for orthogonal top-down line drawing into mini-map area
  1040.     D3DXMATRIX orthproj;
  1041.     D3DXMatrixOrthoLH( &orthproj, 8, 8, 1, 2 );
  1042.     m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &orthproj );
  1043.  
  1044.     D3DXMATRIX orthcam; D3DXMatrixIdentity( &orthcam );
  1045.     orthcam.m[3][0] = -m_vCameraPos.x;
  1046.     orthcam.m[3][1] = -m_vCameraPos.z;
  1047.     orthcam.m[0][0] = orthcam.m[2][1] = orthcam.m[1][2] = 1;
  1048.     orthcam.m[1][1] = orthcam.m[2][2] = 0;
  1049.     D3DXMATRIX rot; D3DXMatrixRotationZ( &rot, -m_fCameraYaw );
  1050.     orthcam = orthcam * rot;
  1051.     m_pd3dDevice->SetTransform( D3DTS_VIEW, &orthcam );
  1052.  
  1053.     // Compute range of cells we're interested in
  1054.     DWORD centrecellx = DWORD(m_vCameraPos.x);
  1055.     DWORD centrecelly = DWORD(m_vCameraPos.z);
  1056.     DWORD mazewidth = m_pMazeClient->m_Maze.GetWidth();
  1057.     DWORD mazeheight = m_pMazeClient->m_Maze.GetHeight();
  1058.     DWORD minx = (centrecellx < 6) ? 0 : centrecellx - 6;
  1059.     DWORD miny = (centrecelly < 6) ? 0 : centrecelly - 6;
  1060.     DWORD maxx = centrecellx+6 > mazewidth - 1  ? mazewidth - 1 : centrecellx+5;
  1061.     DWORD maxy = centrecelly+6 > mazeheight - 1 ? mazeheight - 1 : centrecelly+5;
  1062.  
  1063.     // Change viewport to clip to the map region
  1064.     D3DVIEWPORT8 oldvp;
  1065.     oldvp.X         = 0;
  1066.     oldvp.Y         = 0;
  1067.     oldvp.Width     = m_d3dsdBackBuffer.Width;
  1068.     oldvp.Height    = m_d3dsdBackBuffer.Height;
  1069.     oldvp.MinZ      = 0.0f;
  1070.     oldvp.MaxZ      = 1.0f;
  1071.  
  1072.     D3DVIEWPORT8 mapvp;
  1073.     mapvp.X       = mapx; 
  1074.     mapvp.Y       = mapy;
  1075.     mapvp.Width   = mapsize;
  1076.     mapvp.Height  = mapsize;
  1077.     mapvp.MinZ    = 0.0f; 
  1078.     mapvp.MaxZ    = 1.0f;
  1079.     m_pd3dDevice->SetViewport( &mapvp );
  1080.  
  1081.     // Lock mini-map VB
  1082.     m_pMiniMapVB->Lock( 0, 0, (BYTE**)&verts, D3DLOCK_DISCARD );
  1083.  
  1084.     // Loop through cells
  1085.     origin = D3DXVECTOR3( float(minx),1,float(miny) );
  1086.     for( x = minx; x <= maxx; x++ )
  1087.     {
  1088.         pos = origin;
  1089.         for( DWORD y = miny; y <= maxy; y++ )
  1090.         {
  1091.             // Grab wall bitmask
  1092.             BYTE cell = m_pMazeClient->m_Maze.GetCell(x,y);
  1093.  
  1094.             // Check for north wall
  1095.             if( cell & MAZE_WALL_NORTH )
  1096.             {
  1097.                 verts->vPos = pos;                  verts->dwDiffuse = 0xffffff; verts++;
  1098.                 verts->vPos = pos; verts->vPos.x++; verts->dwDiffuse = 0xffffff; verts++;
  1099.                 dwLineCount++;
  1100.             }
  1101.  
  1102.             // Check for west wall
  1103.             if( cell & MAZE_WALL_WEST )
  1104.             {
  1105.                 verts->vPos = pos;                  verts->dwDiffuse = 0xffffff; verts++;
  1106.                 verts->vPos = pos; verts->vPos.z++; verts->dwDiffuse = 0xffffff; verts++;
  1107.                 dwLineCount++;
  1108.             }
  1109.  
  1110.             if( y==maxy )
  1111.             {
  1112.                 // Check for north wall
  1113.                 if( cell & MAZE_WALL_SOUTH )
  1114.                 {
  1115.                     verts->vPos = pos; verts->vPos.z++;                  verts->dwDiffuse = 0xffffff; verts++;
  1116.                     verts->vPos = pos; verts->vPos.z++; verts->vPos.x++; verts->dwDiffuse = 0xffffff; verts++;
  1117.                     dwLineCount++;
  1118.                 }
  1119.             }
  1120.  
  1121.             if( x==maxx )
  1122.             {
  1123.                 // Check for west wall
  1124.                 if( cell & MAZE_WALL_EAST )
  1125.                 {
  1126.                     verts->vPos = pos; verts->vPos.x++;                  verts->dwDiffuse = 0xffffff; verts++;
  1127.                     verts->vPos = pos; verts->vPos.x++; verts->vPos.z++; verts->dwDiffuse = 0xffffff; verts++;
  1128.                     dwLineCount++;
  1129.                 }
  1130.             }
  1131.  
  1132.             pos.z += 1;
  1133.         }
  1134.  
  1135.         origin.x += 1;
  1136.     }
  1137.  
  1138.     // Unlock VB and submit for rendering
  1139.     m_pMiniMapVB->Unlock();
  1140.     m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
  1141.  
  1142.     m_pd3dDevice->SetVertexShader( FVF_DIFFUSE );
  1143.     m_pd3dDevice->SetStreamSource( 0, m_pMiniMapVB, sizeof(VERTEX_DIFFUSE) );
  1144.     m_pd3dDevice->DrawPrimitive( D3DPT_LINELIST, 0, dwLineCount );
  1145.  
  1146.     // Draw marker for camera
  1147.     D3DXMatrixRotationY( &rot, -m_fCameraYaw );
  1148.     rot.m[3][0] = m_vCameraPos.x; rot.m[3][2] = m_vCameraPos.z;
  1149.     m_pd3dDevice->SetTransform( D3DTS_WORLD, &rot );
  1150.  
  1151.     m_pMiniMapVB->Lock( 0, 0, (BYTE**)&verts, D3DLOCK_DISCARD );
  1152.     verts[0].vPos.y     = verts[1].vPos.y       = verts[2].vPos.y       = verts[3].vPos.y       = 1.0f;
  1153.     verts[0].dwDiffuse  = verts[1].dwDiffuse    = verts[2].dwDiffuse    = verts[3].dwDiffuse    = 0xb01010;
  1154.     verts[0].vPos.x =  0.0f; verts[0].vPos.z =  0.4f;
  1155.     verts[1].vPos.x =  0.2f; verts[1].vPos.z =  0.0f;
  1156.     verts[2].vPos.x =  0.0f; verts[2].vPos.z = -0.2f;
  1157.     verts[3].vPos.x = -0.2f; verts[3].vPos.z =  0.0f;
  1158.     m_pMiniMapVB->Unlock();
  1159.  
  1160.     m_pd3dDevice->SetVertexShader( FVF_DIFFUSE );
  1161.     m_pd3dDevice->SetStreamSource( 0, m_pMiniMapVB, sizeof(VERTEX_DIFFUSE) );
  1162.     m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 );
  1163.  
  1164.     // Draw things in mini-map
  1165.     m_pMazeClient->LockWorld();
  1166.  
  1167.     m_pMiniMapVB->Lock( 0, 0, (BYTE**)&verts, D3DLOCK_DISCARD );
  1168.     verts[0].vPos.y     = verts[1].vPos.y       = verts[2].vPos.y       = verts[3].vPos.y       = 1.0f;
  1169.     verts[0].dwDiffuse  = verts[1].dwDiffuse    = verts[2].dwDiffuse    = verts[3].dwDiffuse    = 0x00FFFF00;
  1170.     verts[0].vPos.x =  0.0f; verts[0].vPos.z =  0.4f;
  1171.     verts[1].vPos.x =  0.2f; verts[1].vPos.z =  0.0f;
  1172.     verts[2].vPos.x =  0.0f; verts[2].vPos.z = -0.2f;
  1173.     verts[3].vPos.x = -0.2f; verts[3].vPos.z =  0.0f;
  1174.     m_pMiniMapVB->Unlock();
  1175.  
  1176.     m_pd3dDevice->SetVertexShader( FVF_DIFFUSE );
  1177.     m_pd3dDevice->SetStreamSource( 0, m_pMiniMapVB, sizeof(VERTEX_DIFFUSE) );
  1178.  
  1179.     for( x = minx; x <= maxx; x++ )
  1180.     {
  1181.         for( y = miny; y <= maxy; y++ )
  1182.         {
  1183.             PlayerObject* pPlayerObject = m_pMazeClient->GetFirstPlayerObjectInCell( x, y );
  1184.             while( pPlayerObject )
  1185.             {
  1186.                 D3DXMatrixTranslation( &matTrans, pPlayerObject->vPos.x, pPlayerObject->vPos.y, pPlayerObject->vPos.z );
  1187.                 D3DXMatrixRotationYawPitchRoll( &matRot, -AngleToFloat(pPlayerObject->aCameraYaw), 0.0f, 0.0f );
  1188.                 matWorld = matRot * matTrans;
  1189.                 m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
  1190.                 m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 );
  1191.  
  1192.                 pPlayerObject = pPlayerObject->pNext;
  1193.             }
  1194.  
  1195.             pos.z += 1;
  1196.         }
  1197.     }
  1198.     m_pMazeClient->UnlockWorld();
  1199.  
  1200.     D3DXMatrixIdentity( &rot );
  1201.     m_pd3dDevice->SetTransform( D3DTS_WORLD, &rot );
  1202.  
  1203.     // Re-enable z-buffering and reset viewport and matrices
  1204.     m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
  1205.     m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
  1206.     m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
  1207.     m_pd3dDevice->SetViewport( &oldvp );
  1208.     m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &m_Projection );
  1209.     m_pd3dDevice->SetTransform( D3DTS_VIEW, &m_Camera );
  1210.  
  1211. }
  1212.  
  1213.  
  1214.  
  1215.  
  1216. //-----------------------------------------------------------------------------
  1217. // Name:
  1218. // Desc:
  1219. //-----------------------------------------------------------------------------
  1220. void CD3DGraphics::DrawIndicators()
  1221. {
  1222.     VERTEX_TL_TEXTURED* v;   
  1223.  
  1224.     float xscale = float(m_d3dsdBackBuffer.Width)/640.0f;
  1225.     float yscale = float(m_d3dsdBackBuffer.Height)/480.0f;
  1226.  
  1227.     // Draw network/local icon and player icon (if connected)
  1228.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
  1229.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  1230.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
  1231.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
  1232.  
  1233.     m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
  1234.     m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
  1235.     m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
  1236.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
  1237.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );
  1238.  
  1239.     m_pIndicatorVB->Lock( 0, 0, (BYTE**)&v, 0 );
  1240.     v[0].dwSpecular = v[1].dwSpecular = v[2].dwSpecular = v[3].dwSpecular = 0;
  1241.     v[0].vPos.z     = v[1].vPos.z     = v[2].vPos.z     = v[3].vPos.z     = 0.0f;
  1242.     v[0].fRHW       = v[1].fRHW       = v[2].fRHW       = v[3].fRHW       = 1.0f;
  1243.     v[0].dwDiffuse  = v[1].dwDiffuse  = v[2].dwDiffuse  = v[3].dwDiffuse  = 0xFFFFFFFF;
  1244.     v[0].fU = 0; v[0].fV = 0;
  1245.     v[1].fU = 1; v[1].fV = 0;
  1246.     v[2].fU = 1; v[2].fV = 1;
  1247.     v[3].fU = 0; v[3].fV = 1;
  1248.     v[0].vPos.x = (xscale*16)-0.5f; v[0].vPos.y = ((480-68)*yscale)-0.5f;
  1249.     v[1].vPos.x = (xscale*48)-0.5f; v[1].vPos.y = ((480-68)*yscale)-0.5f;
  1250.     v[2].vPos.x = (xscale*48)-0.5f; v[2].vPos.y = ((480-36)*yscale)-0.5f;
  1251.     v[3].vPos.x = (xscale*16)-0.5f; v[3].vPos.y = ((480-36)*yscale)-0.5f;
  1252.     m_pIndicatorVB->Unlock();
  1253.  
  1254.     if( m_pDP8Client->IsSessionLost() )
  1255.         m_pd3dDevice->SetTexture( 0, m_pLocalIconTexture );
  1256.     else
  1257.         m_pd3dDevice->SetTexture( 0, m_pNetIconTexture );
  1258.  
  1259.     m_pd3dDevice->SetVertexShader( FVF_TL_TEXTURED );
  1260.     m_pd3dDevice->SetStreamSource( 0, m_pIndicatorVB, sizeof(VERTEX_TL_TEXTURED) );
  1261.     m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 );
  1262.  
  1263.     if( FALSE == m_pDP8Client->IsSessionLost() )
  1264.     {
  1265.         DWORD dwNumPlayers, dwNumNearbyPlayers;
  1266.         m_pMazeClient->GetPlayerStats( &dwNumPlayers, &dwNumNearbyPlayers );
  1267.  
  1268.         // Show frame rate
  1269.         POINT ptStart  = { (long)(xscale*60.0f), (long)((480-95)*yscale) };
  1270.         TCHAR strText[MAX_PATH];
  1271.         wsprintf( strText, TEXT("       Players: %4d"), dwNumPlayers );
  1272.         m_pFont->DrawText( (float)ptStart.x, (float)ptStart.y, D3DCOLOR_ARGB(255,255,255,0), strText );
  1273.         wsprintf( strText, TEXT("Nearby Players: %4d"), dwNumNearbyPlayers );
  1274.         m_pFont->DrawText( (float)ptStart.x, (float)ptStart.y+20, D3DCOLOR_ARGB(255,255,255,0), strText );
  1275.         wsprintf( strText, TEXT("          Ping: %4d ms"), m_pMazeClient->GetRoundTripLatencyMS() );
  1276.         m_pFont->DrawText( (float)ptStart.x, (float)ptStart.y+40, D3DCOLOR_ARGB(255,255,255,0), strText );
  1277.         wsprintf( strText, TEXT("     Data Rate: %4d Bps"), m_pMazeClient->GetThroughputBPS() );
  1278.         m_pFont->DrawText( (float)ptStart.x, (float)ptStart.y+60, D3DCOLOR_ARGB(255,255,255,0), strText );
  1279.     }
  1280.     else
  1281.     {
  1282.         if( m_pMazeApp->IsOutOfDateClient() )
  1283.         {
  1284.             POINT ptStart  = { (long)(xscale*60.0f), (long)((480-75)*yscale) };
  1285.             TCHAR strText[MAX_PATH];
  1286.             wsprintf( strText, TEXT("Client is out of date") );
  1287.             m_pFont->DrawText( (float)ptStart.x, (float)ptStart.y, D3DCOLOR_ARGB(255,255,255,0), strText );
  1288.             wsprintf( strText, TEXT("Please get update at") );
  1289.             m_pFont->DrawText( (float)ptStart.x, (float)ptStart.y+20, D3DCOLOR_ARGB(255,255,255,0), strText );
  1290.             wsprintf( strText, TEXT("http://msdn.microsoft.com/directx/") );
  1291.             m_pFont->DrawText( (float)ptStart.x, (float)ptStart.y+40, D3DCOLOR_ARGB(255,255,255,0), strText );
  1292.         }
  1293.     }
  1294.  
  1295.     m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
  1296.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP );
  1297.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP );
  1298. }
  1299.  
  1300.  
  1301.  
  1302.  
  1303. //-----------------------------------------------------------------------------
  1304. // Name: 
  1305. // Desc: 
  1306. //-----------------------------------------------------------------------------
  1307. HRESULT CD3DGraphics::InvalidateDeviceObjects()
  1308.     m_pFont->InvalidateDeviceObjects();
  1309.     m_pStatsFont->InvalidateDeviceObjects();
  1310.  
  1311.     m_pPlayerMesh->InvalidateDeviceObjects();
  1312.     SAFE_RELEASE( m_pMiniMapVB );
  1313.  
  1314.     return S_OK; 
  1315. }
  1316.  
  1317.  
  1318.  
  1319.  
  1320. //-----------------------------------------------------------------------------
  1321. // Name: 
  1322. // Desc: 
  1323. //-----------------------------------------------------------------------------
  1324. HRESULT CD3DGraphics::DeleteDeviceObjects()
  1325.     m_pFont->DeleteDeviceObjects();
  1326.     m_pStatsFont->DeleteDeviceObjects();
  1327.  
  1328.     SAFE_RELEASE( m_pSphere );
  1329.     if( m_pPlayerMesh )
  1330.         m_pPlayerMesh->Destroy();
  1331.    
  1332.     SAFE_RELEASE( m_pMiniMapBackgroundVB );
  1333.     SAFE_RELEASE( m_pIndicatorVB );
  1334.     m_SmartVB.Uninit();
  1335.  
  1336.     SAFE_RELEASE( m_pWallTexture );
  1337.     SAFE_RELEASE( m_pFloorTexture );
  1338.     SAFE_RELEASE( m_pCeilingTexture );
  1339.     SAFE_RELEASE( m_pNetIconTexture );
  1340.     SAFE_RELEASE( m_pLocalIconTexture );
  1341.  
  1342.     return S_OK; 
  1343. }
  1344.  
  1345.  
  1346.  
  1347.  
  1348. //-----------------------------------------------------------------------------
  1349. // Name: 
  1350. // Desc: 
  1351. //-----------------------------------------------------------------------------
  1352. HRESULT CD3DGraphics::FinalCleanup()
  1353.     SAFE_DELETE( m_pFont );
  1354.     SAFE_DELETE( m_pStatsFont );
  1355.     SAFE_DELETE( m_pPlayerMesh );
  1356.  
  1357.     return S_OK; 
  1358. }
  1359.  
  1360.  
  1361.  
  1362.