0001: //-----------------------------------------------------------------------------
0002: // File: DirectX9Application1.cpp
0003: //
0004: // Desc: DirectX window application created by the DirectX AppWizard
0005: //-----------------------------------------------------------------------------
0006: #define STRICT
0007: #define DIRECTINPUT_VERSION 0x0800
0008: #include <windows.h>
0009: #include <commctrl.h>
0010: #include <commdlg.h>
0011: #include <basetsd.h>
0012: #include <math.h>
0013: #include <stdio.h>
0014: #include <d3dx9.h>
0015: #include <dxerr9.h>
0016: #include <tchar.h>
0017: #include <dinput.h>
0018: #include "DXUtil.h"
0019: #include "D3DEnumeration.h"
0020: #include "D3DSettings.h"
0021: #include "D3DApp.h"
0022: #include "D3DFont.h"
0023: #include "D3DFile.h"
0024: #include "D3DUtil.h"
0025: #include "DIUtil.h"
0026: #include "DMUtil.h"
0027: #include "resource.h"
0028: #include "DirectX9Application1.h"
0029: 
0030: 
0031: 
0032: //-----------------------------------------------------------------------------
0033: // Defines, and constants
0034: //-----------------------------------------------------------------------------
0035: // This GUID must be unique for every game, and the same for 
0036: // every instance of this app.  // {4CBF02D2-CE10-4C41-8015-EC6330304301}
0037: // The GUID allows DirectInput to remember input settings
0038: GUID g_guidApp = { 0x4CBF02D2, 0xCE10, 0x4C41, { 0x80, 0x15, 0xEC, 0x63, 0x30, 0x30, 0x43, 0x1 } };
0039: 
0040: 
0041: // Input semantics used by this app
0042: enum INPUT_SEMANTICS
0043: {
0044:     // Gameplay semantics
0045:     // TODO: change as needed
0046:     INPUT_ROTATE_AXIS_LR=1, INPUT_ROTATE_AXIS_UD,       
0047:     INPUT_ROTATE_LEFT,      INPUT_ROTATE_RIGHT,    
0048:     INPUT_ROTATE_UP,        INPUT_ROTATE_DOWN,
0049:     INPUT_CONFIG_INPUT,     INPUT_CONFIG_DISPLAY,
0050:     INPUT_PLAY_SOUND,       
0051: };
0052: 
0053: // Actions used by this app
0054: DIACTION g_rgGameAction[] =
0055: {
0056:     // TODO: change as needed.  Be sure to delete user map files 
0057:     // (C:\Program Files\Common Files\DirectX\DirectInput\User Maps\*.ini)
0058:     // after changing this, otherwise settings won't reset and will be read 
0059:     // from the out of date ini files 
0060: 
0061:     // Device input (joystick, etc.) that is pre-defined by DInput, according
0062:     // to genre type. The genre for this app is space simulators.
0063:     { INPUT_ROTATE_AXIS_LR,  DIAXIS_3DCONTROL_LATERAL,      0, TEXT("Rotate left/right"), },
0064:     { INPUT_ROTATE_AXIS_UD,  DIAXIS_3DCONTROL_MOVE,         0, TEXT("Rotate up/down"), },
0065:     { INPUT_PLAY_SOUND,      DIBUTTON_3DCONTROL_SPECIAL,    0, TEXT("Play sound"), },
0066: 
0067:     // Keyboard input mappings
0068:     { INPUT_ROTATE_LEFT,     DIKEYBOARD_LEFT,               0, TEXT("Rotate left"), },
0069:     { INPUT_ROTATE_RIGHT,    DIKEYBOARD_RIGHT,              0, TEXT("Rotate right"), },
0070:     { INPUT_ROTATE_UP,       DIKEYBOARD_UP,                 0, TEXT("Rotate up"), },
0071:     { INPUT_ROTATE_DOWN,     DIKEYBOARD_DOWN,               0, TEXT("Rotate down"), },
0072:     { INPUT_PLAY_SOUND,      DIKEYBOARD_F5,                 0, TEXT("Play sound"), },
0073:     { INPUT_CONFIG_DISPLAY,  DIKEYBOARD_F2,                 DIA_APPFIXED, TEXT("Configure Display"), },    
0074:     { INPUT_CONFIG_INPUT,    DIKEYBOARD_F3,                 DIA_APPFIXED, TEXT("Configure Input"), },    
0075: };
0076: 
0077: #define NUMBER_OF_GAMEACTIONS    (sizeof(g_rgGameAction)/sizeof(DIACTION))
0078: 
0079: 
0080: 
0081: 
0082: //-----------------------------------------------------------------------------
0083: // Global access to the app (needed for the global WndProc())
0084: //-----------------------------------------------------------------------------
0085: CMyD3DApplication* g_pApp  = NULL;
0086: HINSTANCE          g_hInst = NULL;
0087: 
0088: 
0089: 
0090: 
0091: //-----------------------------------------------------------------------------
0092: // Name: WinMain()
0093: // Desc: Entry point to the program. Initializes everything, and goes into a
0094: //       message-processing loop. Idle time is used to render the scene.
0095: //-----------------------------------------------------------------------------
0096: INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
0097: {
0098:     CMyD3DApplication d3dApp;
0099: 
0100:     g_pApp  = &d3dApp;
0101:     g_hInst = hInst;
0102: 
0103:     InitCommonControls();
0104:     if( FAILED( d3dApp.Create( hInst ) ) )
0105:         return 0;
0106: 
0107:     return d3dApp.Run();
0108: }
0109: 
0110: 
0111: 
0112: 
0113: //-----------------------------------------------------------------------------
0114: // Name: CMyD3DApplication()
0115: // Desc: Application constructor.   Paired with ~CMyD3DApplication()
0116: //       Member variables should be initialized to a known state here.  
0117: //       The application window has not yet been created and no Direct3D device 
0118: //       has been created, so any initialization that depends on a window or 
0119: //       Direct3D should be deferred to a later stage. 
0120: //-----------------------------------------------------------------------------
0121: CMyD3DApplication::CMyD3DApplication()
0122: {
0123:     // ★初期化
0124:     m_pEffect         = NULL;
0125:     m_hmWVP = NULL;
0126: 
0127: 
0128:     m_dwCreationWidth           = 500;
0129:     m_dwCreationHeight          = 375;
0130:     m_strWindowTitle            = TEXT( "DirectX9Application1" );
0131:     m_d3dEnumeration.AppUsesDepthBuffer   = TRUE;
0132:     m_bStartFullscreen          = false;
0133:     m_bShowCursorWhenFullscreen = false;
0134: 
0135:     // Create a D3D font using d3dfont.cpp
0136:     m_pFont                     = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
0137:     m_bLoadingApp               = TRUE;
0138:     m_pD3DXMesh                 = NULL;
0139:     m_pInputDeviceManager       = NULL;
0140:     m_pMusicManager             = NULL;
0141:     m_pBounceSound              = NULL;
0142:     m_pDIConfigSurface          = NULL;
0143: 
0144:     ZeroMemory( &m_UserInput, sizeof(m_UserInput) );
0145:     m_fWorldRotX                = 0.0f;
0146:     m_fWorldRotY                = 0.0f;
0147: 
0148:     // Read settings from registry
0149:     ReadSettings();
0150: }
0151: 
0152: 
0153: 
0154: 
0155: //-----------------------------------------------------------------------------
0156: // Name: ~CMyD3DApplication()
0157: // Desc: Application destructor.  Paired with CMyD3DApplication()
0158: //-----------------------------------------------------------------------------
0159: CMyD3DApplication::~CMyD3DApplication()
0160: {
0161: }
0162: 
0163: 
0164: 
0165: 
0166: //-----------------------------------------------------------------------------
0167: // Name: OneTimeSceneInit()
0168: // Desc: Paired with FinalCleanup().
0169: //       The window has been created and the IDirect3D9 interface has been
0170: //       created, but the device has not been created yet.  Here you can
0171: //       perform application-related initialization and cleanup that does
0172: //       not depend on a device.
0173: //-----------------------------------------------------------------------------
0174: HRESULT CMyD3DApplication::OneTimeSceneInit()
0175: {
0176:     // TODO: perform one time initialization
0177: 
0178:     // Drawing loading status message until app finishes loading
0179:     SendMessage( m_hWnd, WM_PAINT, 0, 0 );
0180: 
0181:     // Initialize DirectInput
0182:     InitInput( m_hWnd );
0183: 
0184:     // Initialize audio
0185:     InitAudio( m_hWnd );
0186: 
0187:     m_bLoadingApp = FALSE;
0188: 
0189:     return S_OK;
0190: }
0191: 
0192: 
0193: 
0194: 
0195: //-----------------------------------------------------------------------------
0196: // Name: ReadSettings()
0197: // Desc: Read the app settings from the registry
0198: //-----------------------------------------------------------------------------
0199: VOID CMyD3DApplication::ReadSettings()
0200: {
0201:     HKEY hkey;
0202:     if( ERROR_SUCCESS == RegCreateKeyEx( HKEY_CURRENT_USER, DXAPP_KEY, 
0203:         0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL ) )
0204:     {
0205:         // TODO: change as needed
0206: 
0207:         // Read the stored window width/height.  This is just an example,
0208:         // of how to use DXUtil_Read*() functions.
0209:         DXUtil_ReadIntRegKey( hkey, TEXT("Width"), &m_dwCreationWidth, m_dwCreationWidth );
0210:         DXUtil_ReadIntRegKey( hkey, TEXT("Height"), &m_dwCreationHeight, m_dwCreationHeight );
0211: 
0212:         RegCloseKey( hkey );
0213:     }
0214: }
0215: 
0216: 
0217: 
0218: 
0219: //-----------------------------------------------------------------------------
0220: // Name: WriteSettings()
0221: // Desc: Write the app settings to the registry
0222: //-----------------------------------------------------------------------------
0223: VOID CMyD3DApplication::WriteSettings()
0224: {
0225:     HKEY hkey;
0226: 
0227:     if( ERROR_SUCCESS == RegCreateKeyEx( HKEY_CURRENT_USER, DXAPP_KEY, 
0228:         0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL ) )
0229:     {
0230:         // TODO: change as needed
0231: 
0232:         // Write the window width/height.  This is just an example,
0233:         // of how to use DXUtil_Write*() functions.
0234:         DXUtil_WriteIntRegKey( hkey, TEXT("Width"), m_rcWindowClient.right );
0235:         DXUtil_WriteIntRegKey( hkey, TEXT("Height"), m_rcWindowClient.bottom );
0236: 
0237:         RegCloseKey( hkey );
0238:     }
0239: }
0240: 
0241: 
0242: 
0243: 
0244: 
0245: //-----------------------------------------------------------------------------
0246: // Name: StaticInputAddDeviceCB()
0247: // Desc: Static callback helper to call into CMyD3DApplication class
0248: //-----------------------------------------------------------------------------
0249: HRESULT CALLBACK CMyD3DApplication::StaticInputAddDeviceCB( 
0250:                                          CInputDeviceManager::DeviceInfo* pDeviceInfo, 
0251:                                          const DIDEVICEINSTANCE* pdidi, 
0252:                                          LPVOID pParam )
0253: {
0254:     CMyD3DApplication* pApp = (CMyD3DApplication*) pParam;
0255:     return pApp->InputAddDeviceCB( pDeviceInfo, pdidi );
0256: }
0257: 
0258: 
0259: 
0260: 
0261: //-----------------------------------------------------------------------------
0262: // Name: InputAddDeviceCB()
0263: // Desc: Called from CInputDeviceManager whenever a device is added. 
0264: //       Set the dead zone, and creates a new InputDeviceState for each device
0265: //-----------------------------------------------------------------------------
0266: HRESULT CMyD3DApplication::InputAddDeviceCB( CInputDeviceManager::DeviceInfo* pDeviceInfo, 
0267:                                                    const DIDEVICEINSTANCE* pdidi )
0268: {
0269:     UNREFERENCED_PARAMETER( pdidi );
0270:     
0271:     // Setup the deadzone 
0272:     DIPROPDWORD dipdw;
0273:     dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
0274:     dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
0275:     dipdw.diph.dwObj        = 0;
0276:     dipdw.diph.dwHow        = DIPH_DEVICE;
0277:     dipdw.dwData            = 500;
0278:     pDeviceInfo->pdidDevice->SetProperty( DIPROP_DEADZONE, &dipdw.diph );
0279: 
0280:     // Create a new InputDeviceState for each device so the 
0281:     // app can record its state 
0282:     InputDeviceState* pNewInputDeviceState = new InputDeviceState;
0283:     ZeroMemory( pNewInputDeviceState, sizeof(InputDeviceState) );
0284:     pDeviceInfo->pParam = (LPVOID) pNewInputDeviceState;
0285: 
0286:     return S_OK;
0287: }
0288: 
0289: 
0290: 
0291: 
0292: //-----------------------------------------------------------------------------
0293: // Name: InitInput()
0294: // Desc: Initialize DirectInput objects
0295: //-----------------------------------------------------------------------------
0296: HRESULT CMyD3DApplication::InitInput( HWND hWnd )
0297: {
0298:     HRESULT hr;
0299: 
0300:     // Setup action format for the actual gameplay
0301:     ZeroMemory( &m_diafGame, sizeof(DIACTIONFORMAT) );
0302:     m_diafGame.dwSize          = sizeof(DIACTIONFORMAT);
0303:     m_diafGame.dwActionSize    = sizeof(DIACTION);
0304:     m_diafGame.dwDataSize      = NUMBER_OF_GAMEACTIONS * sizeof(DWORD);
0305:     m_diafGame.guidActionMap   = g_guidApp;
0306: 
0307:     // TODO: change the genre as needed
0308:     m_diafGame.dwGenre         = DIVIRTUAL_CAD_3DCONTROL; 
0309: 
0310:     m_diafGame.dwNumActions    = NUMBER_OF_GAMEACTIONS;
0311:     m_diafGame.rgoAction       = g_rgGameAction;
0312:     m_diafGame.lAxisMin        = -100;
0313:     m_diafGame.lAxisMax        = 100;
0314:     m_diafGame.dwBufferSize    = 16;
0315:     _tcscpy( m_diafGame.tszActionMap, _T("DirectX9Application1 Game") );
0316: 
0317:     // Create a new input device manager
0318:     m_pInputDeviceManager = new CInputDeviceManager();
0319: 
0320:     if( FAILED( hr = m_pInputDeviceManager->Create( hWnd, NULL, m_diafGame, 
0321:                                                     StaticInputAddDeviceCB, this ) ) )
0322:         return DXTRACE_ERR( "m_pInputDeviceManager->Create", hr );
0323: 
0324:     return S_OK;
0325: }
0326: 
0327: 
0328: 
0329: 
0330: //-----------------------------------------------------------------------------
0331: // Name: InitAudio()
0332: // Desc: Initialize DirectX audio objects
0333: //-----------------------------------------------------------------------------
0334: HRESULT CMyD3DApplication::InitAudio( HWND hWnd )
0335: {
0336:     HRESULT hr;
0337: 
0338:     // Create the music manager class, used to create the sounds
0339:     m_pMusicManager = new CMusicManager();
0340:     if( FAILED( hr = m_pMusicManager->Initialize( hWnd ) ) )
0341:         return DXTRACE_ERR( "m_pMusicManager->Initialize", hr );
0342: 
0343:     // Instruct the music manager where to find the files
0344:     // TODO: Set this to the media directory, or use resources
0345:     TCHAR szPath[MAX_PATH];
0346:     GetCurrentDirectory( MAX_PATH, szPath ); 
0347:     m_pMusicManager->SetSearchDirectory( szPath );
0348: 
0349:     // TODO: load the sounds from resources (or files)
0350:     m_pMusicManager->CreateSegmentFromResource( &m_pBounceSound, _T("BOUNCE"), _T("WAVE") );
0351: 
0352:     return S_OK;
0353: }
0354: 
0355: 
0356: 
0357: 
0358: //-----------------------------------------------------------------------------
0359: // Name: ConfirmDevice()
0360: // Desc: Called during device initialization, this code checks the display device
0361: //       for some minimum set of capabilities
0362: //-----------------------------------------------------------------------------
0363: HRESULT CMyD3DApplication::ConfirmDevice( D3DCAPS9* pCaps, DWORD dwBehavior,
0364:                                           D3DFORMAT Format )
0365: {
0366:     UNREFERENCED_PARAMETER( Format );
0367:     UNREFERENCED_PARAMETER( dwBehavior );
0368:     UNREFERENCED_PARAMETER( pCaps );
0369:     
0370:     BOOL bCapsAcceptable;
0371: 
0372:     // TODO: Perform checks to see if these display caps are acceptable.
0373:     bCapsAcceptable = TRUE;
0374: 
0375:     if( bCapsAcceptable )         
0376:         return S_OK;
0377:     else
0378:         return E_FAIL;
0379: }
0380: 
0381: 
0382: 
0383: 
0384: //-----------------------------------------------------------------------------
0385: // Name: InitDeviceObjects()
0386: // Desc: Paired with DeleteDeviceObjects()
0387: //       The device has been created.  Resources that are not lost on
0388: //       Reset() can be created here -- resources in D3DPOOL_MANAGED,
0389: //       D3DPOOL_SCRATCH, or D3DPOOL_SYSTEMMEM.  Image surfaces created via
0390: //       CreateImageSurface are never lost and can be created here.  Vertex
0391: //       shaders and pixel shaders can also be created here as they are not
0392: //       lost on Reset().
0393: //-----------------------------------------------------------------------------
0394: HRESULT CMyD3DApplication::InitDeviceObjects()
0395: {
0396:     // TODO: create device objects
0397: 
0398:     HRESULT hr;
0399: 
0400:     // Init the font
0401:     m_pFont->InitDeviceObjects( m_pd3dDevice );
0402: 
0403:     // Create a teapot mesh using D3DX
0404:     if( FAILED( hr = D3DXCreateTeapot( m_pd3dDevice, &m_pD3DXMesh, NULL ) ) )
0405:         return DXTRACE_ERR( "D3DXCreateTeapot", hr );
0406: 
0407:     // ★シェーダの読み込み
0408:     if( FAILED( hr = D3DXCreateEffectFromFile( m_pd3dDevice, "hlsl.fx", NULL, NULL, 
0409:                                                0, NULL, &m_pEffect, NULL ) ) )
0410:     {
0411:         return hr;
0412:     }
0413:     D3DXEFFECT_DESC m_EffectDesc;
0414:     D3DXPARAMETER_DESC ParamDesc;
0415:     D3DXHANDLE hParam;
0416:     m_pEffect->GetDesc( &m_EffectDesc );
0417:     for( UINT iParam = 0; iParam < m_EffectDesc.Parameters; iParam++ )
0418:     {
0419:         hParam = m_pEffect->GetParameter ( NULL, iParam );
0420:         m_pEffect->GetParameterDesc( hParam, &ParamDesc );
0421:         if( ParamDesc.Name != NULL && 
0422:             ( ParamDesc.Class == D3DXPC_MATRIX_ROWS || ParamDesc.Class == D3DXPC_MATRIX_COLUMNS ) )
0423:         {
0424:             if( strcmpi( ParamDesc.Name, "mWVP" ) == 0 )
0425:                 m_hmWVP = hParam;
0426:         }
0427:     }
0428: 
0429:     return S_OK;
0430: }
0431: 
0432: 
0433: 
0434: 
0435: //-----------------------------------------------------------------------------
0436: // Name: RestoreDeviceObjects()
0437: // Desc: Paired with InvalidateDeviceObjects()
0438: //       The device exists, but may have just been Reset().  Resources in
0439: //       D3DPOOL_DEFAULT and any other device state that persists during
0440: //       rendering should be set here.  Render states, matrices, textures,
0441: //       etc., that don't change during rendering can be set once here to
0442: //       avoid redundant state setting during Render() or FrameMove().
0443: //-----------------------------------------------------------------------------
0444: HRESULT CMyD3DApplication::RestoreDeviceObjects()
0445: {
0446:     // TODO: setup render states
0447:     HRESULT hr;
0448: 
0449:     // Setup a material
0450:     D3DMATERIAL9 mtrl;
0451:     D3DUtil_InitMaterial( mtrl, 1.0f, 0.0f, 0.0f );
0452:     m_pd3dDevice->SetMaterial( &mtrl );
0453: 
0454:     // Set up the textures
0455:     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
0456:     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
0457:     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
0458:     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_MODULATE );
0459:     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
0460:     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
0461:     m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
0462:     m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
0463: 
0464:     // Set miscellaneous render states
0465:     m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE,   FALSE );
0466:     m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
0467:     m_pd3dDevice->SetRenderState( D3DRS_ZENABLE,        TRUE );
0468: //    m_pd3dDevice->SetRenderState( D3DRS_AMBIENT,        0x000F0F0F ); // ★いらない
0469:     m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );              // ★ 光源計算なし
0470: 
0471:     // ワールド行列を設定する
0472:     D3DXMATRIX matIdentity;
0473:     D3DXMatrixIdentity( &matIdentity );
0474: //    m_pd3dDevice->SetTransform( D3DTS_WORLD,  &matIdentity ); // ★いらない
0475: 
0476:     // Set up our view matrix. A view matrix can be defined given an eye point,
0477:     // a point to lookat, and a direction for which way is up. Here, we set the
0478:     // eye five units back along the z-axis and up three units, look at the
0479:     // origin, and define "up" to be in the y-direction.
0480:     D3DXMATRIX matView;
0481:     D3DXVECTOR3 vFromPt   = D3DXVECTOR3( 0.0f, 0.0f, -5.0f );
0482:     D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
0483:     D3DXVECTOR3 vUpVec    = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0484: //    D3DXMatrixLookAtLH( &matView, &vFromPt, &vLookatPt, &vUpVec );
0485:     D3DXMatrixLookAtLH( &m_matView, &vFromPt, &vLookatPt, &vUpVec );
0486: //    m_pd3dDevice->SetTransform( D3DTS_VIEW, &matView ); // ★いらない
0487: 
0488:     // Set the projection matrix
0489:     D3DXMATRIX matProj;
0490:     FLOAT fAspect = ((FLOAT)m_d3dsdBackBuffer.Width) / m_d3dsdBackBuffer.Height;
0491:     D3DXMatrixPerspectiveFovLH( &m_matProj, D3DX_PI/4, fAspect, 1.0f, 100.0f );
0492: //    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, fAspect, 1.0f, 100.0f );
0493: //    m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj ); // ★いらない
0494: 
0495: #if 0 // ★いらない
0496:     // Set up lighting states
0497:     D3DLIGHT9 light;
0498:     D3DUtil_InitLight( light, D3DLIGHT_DIRECTIONAL, -1.0f, -1.0f, 2.0f );
0499:     m_pd3dDevice->SetLight( 0, &light );
0500:     m_pd3dDevice->LightEnable( 0, TRUE );
0501:     m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
0502: #endif
0503: 
0504:     // Restore the font
0505:     m_pFont->RestoreDeviceObjects();
0506: 
0507:     if( !m_bWindowed )
0508:     {
0509:         // Create a surface for configuring DInput devices
0510:         if( FAILED( hr = m_pd3dDevice->CreateOffscreenPlainSurface( 640, 480, 
0511:                                         m_d3dsdBackBuffer.Format, D3DPOOL_DEFAULT, 
0512:                                         &m_pDIConfigSurface, NULL ) ) ) 
0513:             return DXTRACE_ERR( "CreateOffscreenPlainSurface", hr );
0514:     }
0515: 
0516:     // ★エフェクトのリセット
0517:     if( m_pEffect != NULL ) m_pEffect->OnResetDevice();
0518: 
0519:     return S_OK;
0520: }
0521: 
0522: 
0523: 
0524: 
0525: //-----------------------------------------------------------------------------
0526: // Name: StaticConfigureInputDevicesCB()
0527: // Desc: Static callback helper to call into CMyD3DApplication class
0528: //-----------------------------------------------------------------------------
0529: BOOL CALLBACK CMyD3DApplication::StaticConfigureInputDevicesCB( 
0530:                                             IUnknown* pUnknown, VOID* pUserData )
0531: {
0532:     CMyD3DApplication* pApp = (CMyD3DApplication*) pUserData;
0533:     return pApp->ConfigureInputDevicesCB( pUnknown );
0534: }
0535: 
0536: 
0537: 
0538: 
0539: //-----------------------------------------------------------------------------
0540: // Name: ConfigureInputDevicesCB()
0541: // Desc: Callback function for configuring input devices. This function is
0542: //       called in fullscreen modes, so that the input device configuration
0543: //       window can update the screen.
0544: //-----------------------------------------------------------------------------
0545: BOOL CMyD3DApplication::ConfigureInputDevicesCB( IUnknown* pUnknown )
0546: {
0547:     // Get access to the surface
0548:     LPDIRECT3DSURFACE9 pConfigSurface = NULL;
0549:     if( FAILED( pUnknown->QueryInterface( IID_IDirect3DSurface9,
0550:                                           (VOID**)&pConfigSurface ) ) )
0551:         return TRUE;
0552: 
0553:     // Render the scene, with the config surface blitted on top
0554:     Render();
0555: 
0556:     RECT  rcSrc;
0557:     SetRect( &rcSrc, 0, 0, 640, 480 );
0558: 
0559:     POINT ptDst;
0560:     ptDst.x = (m_d3dsdBackBuffer.Width-640)/2;
0561:     ptDst.y = (m_d3dsdBackBuffer.Height-480)/2;
0562: 
0563:     LPDIRECT3DSURFACE9 pBackBuffer;
0564:     m_pd3dDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer );
0565:     m_pd3dDevice->UpdateSurface( pConfigSurface, &rcSrc, pBackBuffer, &ptDst );
0566:     pBackBuffer->Release();
0567: 
0568:     // Present the backbuffer contents to the front buffer
0569:     m_pd3dDevice->Present( 0, 0, 0, 0 );
0570: 
0571:     // Release the surface
0572:     pConfigSurface->Release();
0573: 
0574:     return TRUE;
0575: }
0576: 
0577: 
0578: 
0579: 
0580: //-----------------------------------------------------------------------------
0581: // Name: FrameMove()
0582: // Desc: Called once per frame, the call is the entry point for animating
0583: //       the scene.
0584: //-----------------------------------------------------------------------------
0585: HRESULT CMyD3DApplication::FrameMove()
0586: {
0587:     // TODO: update world
0588: 
0589:     // Update user input state
0590:     UpdateInput( &m_UserInput );
0591: 
0592:     // Respond to input
0593:     if( m_UserInput.bDoConfigureInput && m_bWindowed )  // full-screen configure disabled for now
0594:     {
0595:         // One-shot per keypress
0596:         m_UserInput.bDoConfigureInput = FALSE;
0597: 
0598:         Pause( true );
0599: 
0600:         // Get access to the list of semantically-mapped input devices
0601:         // to delete all InputDeviceState structs before calling ConfigureDevices()
0602:         CInputDeviceManager::DeviceInfo* pDeviceInfos;
0603:         DWORD dwNumDevices;
0604:         m_pInputDeviceManager->GetDevices( &pDeviceInfos, &dwNumDevices );
0605: 
0606:         for( DWORD i=0; i<dwNumDevices; i++ )
0607:         {
0608:             InputDeviceState* pInputDeviceState = (InputDeviceState*) pDeviceInfos[i].pParam;
0609:             SAFE_DELETE( pInputDeviceState );
0610:             pDeviceInfos[i].pParam = NULL;
0611:         }
0612: 
0613:         // Configure the devices (with edit capability)
0614:         if( m_bWindowed )
0615:             m_pInputDeviceManager->ConfigureDevices( m_hWnd, NULL, NULL, DICD_EDIT, NULL );
0616:         else
0617:             m_pInputDeviceManager->ConfigureDevices( m_hWnd,
0618:                                                      m_pDIConfigSurface,
0619:                                                      (VOID*)StaticConfigureInputDevicesCB,
0620:                                                      DICD_EDIT, (LPVOID) this );
0621: 
0622:         Pause( false );
0623:     }
0624: 
0625:     if( m_UserInput.bDoConfigureDisplay )
0626:     {
0627:         // One-shot per keypress
0628:         m_UserInput.bDoConfigureDisplay = FALSE;
0629: 
0630:         Pause(true);
0631: 
0632:         // Configure the display device
0633:         UserSelectNewDevice();
0634: 
0635:         Pause(false);
0636:     }
0637: 
0638:     // Update the world state according to user input
0639:     D3DXMATRIX matWorld;
0640:     D3DXMATRIX matRotY;
0641:     D3DXMATRIX matRotX;
0642: 
0643:     if( m_UserInput.fAxisRotateLR )
0644:         m_fWorldRotY += m_fElapsedTime * m_UserInput.fAxisRotateLR;
0645: 
0646:     if( m_UserInput.fAxisRotateUD )
0647:         m_fWorldRotX += m_fElapsedTime * m_UserInput.fAxisRotateUD;
0648: 
0649:     D3DXMatrixRotationX( &matRotX, m_fWorldRotX );
0650:     D3DXMatrixRotationY( &matRotY, m_fWorldRotY );
0651: 
0652: //    D3DXMatrixMultiply( &matWorld, &matRotX, &matRotY );
0653:     D3DXMatrixMultiply( &m_matWorld, &matRotX, &matRotY );  // ★変更
0654: //    m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );// ★いらない
0655: 
0656:     // Play the sound every so often while the button is pressed 
0657:     if( m_UserInput.bPlaySoundButtonDown )
0658:     {
0659:         m_fSoundPlayRepeatCountdown -= m_fElapsedTime;
0660:         if( m_fSoundPlayRepeatCountdown <= 0.0f )
0661:         {
0662:             m_fSoundPlayRepeatCountdown = 0.5f;
0663:             if( m_pBounceSound )
0664:                 m_pBounceSound->Play();
0665:         }
0666:     }
0667:     else
0668:     {
0669:         m_fSoundPlayRepeatCountdown = 0.0f;
0670:     }
0671: 
0672:     return S_OK;
0673: }
0674: 
0675: 
0676: 
0677: 
0678: //-----------------------------------------------------------------------------
0679: // Name: UpdateInput()
0680: // Desc: Update the user input.  Called once per frame 
0681: //-----------------------------------------------------------------------------
0682: void CMyD3DApplication::UpdateInput( UserInput* pUserInput )
0683: {
0684:     if( NULL == m_pInputDeviceManager )
0685:         return;
0686: 
0687:     // Get access to the list of semantically-mapped input devices
0688:     CInputDeviceManager::DeviceInfo* pDeviceInfos;
0689:     DWORD dwNumDevices;
0690:     m_pInputDeviceManager->GetDevices( &pDeviceInfos, &dwNumDevices );
0691: 
0692:     // Loop through all devices and check game input
0693:     for( DWORD i=0; i<dwNumDevices; i++ )
0694:     {
0695:         DIDEVICEOBJECTDATA rgdod[10];
0696:         DWORD   dwItems = 10;
0697:         HRESULT hr;
0698:         LPDIRECTINPUTDEVICE8 pdidDevice = pDeviceInfos[i].pdidDevice;
0699:         InputDeviceState* pInputDeviceState = (InputDeviceState*) pDeviceInfos[i].pParam;
0700: 
0701:         hr = pdidDevice->Acquire();
0702:         hr = pdidDevice->Poll();
0703:         hr = pdidDevice->GetDeviceData( sizeof(DIDEVICEOBJECTDATA),
0704:                                         rgdod, &dwItems, 0 );
0705:         if( FAILED(hr) )
0706:             continue;
0707: 
0708:         // Get the sematics codes for the game menu
0709:         for( DWORD j=0; j<dwItems; j++ )
0710:         {
0711:             BOOL  bButtonState = (rgdod[j].dwData==0x80) ? TRUE : FALSE;
0712:             FLOAT fButtonState = (rgdod[j].dwData==0x80) ? 1.0f : 0.0f;
0713:             FLOAT fAxisState   = (FLOAT)((int)rgdod[j].dwData)/100.0f;
0714:             UNREFERENCED_PARAMETER( fButtonState );
0715: 
0716:             switch( rgdod[j].uAppData )
0717:             {
0718:                 // TODO: Handle semantics for the game 
0719: 
0720:                 // Handle relative axis data
0721:                 case INPUT_ROTATE_AXIS_LR: 
0722:                     pInputDeviceState->fAxisRotateLR = -fAxisState;
0723:                     break;
0724:                 case INPUT_ROTATE_AXIS_UD:
0725:                     pInputDeviceState->fAxisRotateUD = -fAxisState;
0726:                     break;
0727: 
0728:                 // Handle buttons separately so the button state data
0729:                 // doesn't overwrite the axis state data, and handle
0730:                 // each button separately so they don't overwrite each other
0731:                 case INPUT_ROTATE_LEFT:  pInputDeviceState->bButtonRotateLeft  = bButtonState; break;
0732:                 case INPUT_ROTATE_RIGHT: pInputDeviceState->bButtonRotateRight = bButtonState; break;
0733:                 case INPUT_ROTATE_UP:    pInputDeviceState->bButtonRotateUp    = bButtonState; break;
0734:                 case INPUT_ROTATE_DOWN:  pInputDeviceState->bButtonRotateDown  = bButtonState; break;
0735:                 case INPUT_PLAY_SOUND:   pInputDeviceState->bButtonPlaySoundButtonDown = bButtonState; break;
0736: 
0737:                 // Handle one-shot buttons
0738:                 case INPUT_CONFIG_INPUT:   if( bButtonState ) pUserInput->bDoConfigureInput = TRUE; break;
0739:                 case INPUT_CONFIG_DISPLAY: if( bButtonState ) pUserInput->bDoConfigureDisplay = TRUE; break;
0740:             }
0741:         }
0742:     }
0743: 
0744:     // TODO: change process code as needed
0745: 
0746:     // Process user input and store result into pUserInput struct
0747:     pUserInput->fAxisRotateLR = 0.0f;
0748:     pUserInput->fAxisRotateUD = 0.0f;
0749:     pUserInput->bPlaySoundButtonDown = FALSE;
0750: 
0751:     // Concatinate the data from all the DirectInput devices
0752:     for( i=0; i<dwNumDevices; i++ )
0753:     {
0754:         InputDeviceState* pInputDeviceState = (InputDeviceState*) pDeviceInfos[i].pParam;
0755: 
0756:         // Use the axis data that is furthest from zero
0757:         if( fabs(pInputDeviceState->fAxisRotateLR) > fabs(pUserInput->fAxisRotateLR) )
0758:             pUserInput->fAxisRotateLR = pInputDeviceState->fAxisRotateLR;
0759: 
0760:         if( fabs(pInputDeviceState->fAxisRotateUD) > fabs(pUserInput->fAxisRotateUD) )
0761:             pUserInput->fAxisRotateUD = pInputDeviceState->fAxisRotateUD;
0762: 
0763:         // Process the button data 
0764:         if( pInputDeviceState->bButtonRotateLeft )
0765:             pUserInput->fAxisRotateLR = 1.0f;
0766:         else if( pInputDeviceState->bButtonRotateRight )
0767:             pUserInput->fAxisRotateLR = -1.0f;
0768: 
0769:         if( pInputDeviceState->bButtonRotateUp )
0770:             pUserInput->fAxisRotateUD = 1.0f;
0771:         else if( pInputDeviceState->bButtonRotateDown )
0772:             pUserInput->fAxisRotateUD = -1.0f;
0773: 
0774:         if( pInputDeviceState->bButtonPlaySoundButtonDown )
0775:             pUserInput->bPlaySoundButtonDown = TRUE;
0776:     } 
0777: }
0778: 
0779: 
0780: 
0781: 
0782: //-----------------------------------------------------------------------------
0783: // Name: Render()
0784: // Desc: Called once per frame, the call is the entry point for 3d
0785: //       rendering. This function sets up render states, clears the
0786: //       viewport, and renders the scene.
0787: //-----------------------------------------------------------------------------
0788: HRESULT CMyD3DApplication::Render()
0789: {
0790:     // Clear the viewport
0791:     m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
0792:                          0x000000ff, 1.0f, 0L );
0793: 
0794:     // Begin the scene
0795:     if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
0796:     {
0797: #if 1
0798:         UINT nPasses;
0799:         UINT iPass;
0800: 
0801:         if( m_pEffect != NULL )
0802:         {
0803:             // ★シェーダの設定
0804:             D3DXHANDLE hTechnique = m_pEffect->GetTechniqueByName( "TShader" );
0805:             m_pEffect->SetTechnique( hTechnique );
0806:             
0807:             // ★行列の設定
0808:             D3DXMATRIX m = m_matWorld*m_matView*m_matProj;
0809:             if( m_hmWVP != NULL )
0810:                 m_pEffect->SetMatrix( m_hmWVP, &m );
0811: 
0812:             // ★描画
0813:             m_pEffect->Begin( &nPasses, 0 );
0814:             for( iPass = 0; iPass < nPasses; iPass ++ )
0815:             {
0816:                 m_pEffect->Pass( iPass );
0817:                 // ティーポットのレンダリング
0818:                 m_pD3DXMesh->DrawSubset( 0 );
0819:             }
0820:             m_pEffect->End();
0821:         }
0822: #else
0823:         // Render the teapot mesh
0824:         m_pD3DXMesh->DrawSubset(0);
0825: #endif
0826: 
0827:         // Render stats and help text  
0828:         RenderText();
0829: 
0830:         // End the scene.
0831:         m_pd3dDevice->EndScene();
0832:     }
0833: 
0834:     return S_OK;
0835: }
0836: 
0837: 
0838: 
0839: 
0840: //-----------------------------------------------------------------------------
0841: // Name: RenderText()
0842: // Desc: Renders stats and help text to the scene.
0843: //-----------------------------------------------------------------------------
0844: HRESULT CMyD3DApplication::RenderText()
0845: {
0846:     D3DCOLOR fontColor        = D3DCOLOR_ARGB(255,255,255,0);
0847:     TCHAR szMsg[MAX_PATH] = TEXT("");
0848: 
0849:     // Output display stats
0850:     FLOAT fNextLine = 40.0f; 
0851: 
0852:     lstrcpy( szMsg, m_strDeviceStats );
0853:     fNextLine -= 20.0f;
0854:     m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0855: 
0856:     lstrcpy( szMsg, m_strFrameStats );
0857:     fNextLine -= 20.0f;
0858:     m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0859: 
0860:     // Output statistics & help
0861:     fNextLine = (FLOAT) m_d3dsdBackBuffer.Height; 
0862:     sprintf( szMsg, TEXT("Left/Right Axis: %0.2f Up/Down Axis: %0.2f "), 
0863:               m_UserInput.fAxisRotateLR, m_UserInput.fAxisRotateUD );
0864:     fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0865:     lstrcpy( szMsg, TEXT("Use arrow keys or joystick to rotate object") );
0866:     fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0867:     lstrcpy( szMsg, TEXT("Hold 'F5' down to play and repeat a sound") );
0868:     fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0869:     lstrcpy( szMsg, TEXT("Press 'F3' to configure input") );
0870:     fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0871:     lstrcpy( szMsg, TEXT("Press 'F2' to configure display") );
0872:     fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0873:     return S_OK;
0874: }
0875: 
0876: 
0877: 
0878: 
0879: //-----------------------------------------------------------------------------
0880: // Name: Pause()
0881: // Desc: Called in to toggle the pause state of the app.
0882: //-----------------------------------------------------------------------------
0883: VOID CMyD3DApplication::Pause( bool bPause )
0884: {
0885:     // Get access to the list of semantically-mapped input devices
0886:     // to zero the state of all InputDeviceState structs.  This is needed
0887:     // because when using DISCL_FOREGROUND, the action mapper will not 
0888:     // record actions when the focus switches, for example if a dialog appears.
0889:     // This causes a problem when a button held down when loosing focus, and let
0890:     // go when the focus is lost.  The app will not record that the button 
0891:     // has been let go, so the state will be incorrect when focus returns.  
0892:     // To fix this either use DISCL_BACKGROUND or zero the state when 
0893:     // loosing focus.
0894:     CInputDeviceManager::DeviceInfo* pDeviceInfos;
0895:     DWORD dwNumDevices;
0896:     m_pInputDeviceManager->GetDevices( &pDeviceInfos, &dwNumDevices );
0897: 
0898:     for( DWORD i=0; i<dwNumDevices; i++ )
0899:     {
0900:         InputDeviceState* pInputDeviceState = (InputDeviceState*) pDeviceInfos[i].pParam;
0901:         ZeroMemory( pInputDeviceState, sizeof(InputDeviceState) );
0902:     }
0903: 
0904:     CD3DApplication::Pause( bPause );
0905: }
0906: 
0907: 
0908: 
0909: 
0910: //-----------------------------------------------------------------------------
0911: // Name: MsgProc()
0912: // Desc: Overrrides the main WndProc, so the sample can do custom message
0913: //       handling (e.g. processing mouse, keyboard, or menu commands).
0914: //-----------------------------------------------------------------------------
0915: LRESULT CMyD3DApplication::MsgProc( HWND hWnd, UINT msg, WPARAM wParam,
0916:                                     LPARAM lParam )
0917: {
0918:     switch( msg )
0919:     {
0920:         case WM_PAINT:
0921:         {
0922:             if( m_bLoadingApp )
0923:             {
0924:                 // Draw on the window tell the user that the app is loading
0925:                 // TODO: change as needed
0926:                 HDC hDC = GetDC( hWnd );
0927:                 TCHAR strMsg[MAX_PATH];
0928:                 wsprintf( strMsg, TEXT("Loading... Please wait") );
0929:                 RECT rct;
0930:                 GetClientRect( hWnd, &rct );
0931:                 DrawText( hDC, strMsg, -1, &rct, DT_CENTER|DT_VCENTER|DT_SINGLELINE );
0932:                 ReleaseDC( hWnd, hDC );
0933:             }
0934:             break;
0935:         }
0936: 
0937:         case WM_COMMAND:
0938:         {
0939:             switch( LOWORD(wParam) )
0940:             {
0941:                 case IDM_CONFIGINPUT:
0942:                     m_UserInput.bDoConfigureInput = TRUE;
0943:                     break;
0944: 
0945:                 case IDM_CHANGEDEVICE:
0946:                     m_UserInput.bDoConfigureDisplay = TRUE;
0947:                     return 0; // Don't hand off to parent
0948:             }
0949:             break;
0950:         }
0951: 
0952:     }
0953: 
0954:     return CD3DApplication::MsgProc( hWnd, msg, wParam, lParam );
0955: }
0956: 
0957: 
0958: 
0959: 
0960: //-----------------------------------------------------------------------------
0961: // Name: InvalidateDeviceObjects()
0962: // Desc: Invalidates device objects.  Paired with RestoreDeviceObjects()
0963: //-----------------------------------------------------------------------------
0964: HRESULT CMyD3DApplication::InvalidateDeviceObjects()
0965: {
0966:     // TODO: Cleanup any objects created in RestoreDeviceObjects()
0967:     m_pFont->InvalidateDeviceObjects();
0968:     SAFE_RELEASE( m_pDIConfigSurface );
0969: 
0970:     // ★ビデオメモリリソースへの参照を解放する。
0971:     if( m_pEffect != NULL ) m_pEffect->OnLostDevice();
0972: 
0973:     return S_OK;
0974: }
0975: 
0976: 
0977: 
0978: 
0979: //-----------------------------------------------------------------------------
0980: // Name: DeleteDeviceObjects()
0981: // Desc: Paired with InitDeviceObjects()
0982: //       Called when the app is exiting, or the device is being changed,
0983: //       this function deletes any device dependent objects.  
0984: //-----------------------------------------------------------------------------
0985: HRESULT CMyD3DApplication::DeleteDeviceObjects()
0986: {
0987:     // ★エフェクトの開放
0988:     SAFE_RELEASE( m_pEffect );
0989: 
0990:     // TODO: Cleanup any objects created in InitDeviceObjects()
0991:     m_pFont->DeleteDeviceObjects();
0992:     SAFE_RELEASE( m_pD3DXMesh );
0993: 
0994:     return S_OK;
0995: }
0996: 
0997: 
0998: 
0999: 
1000: //-----------------------------------------------------------------------------
1001: // Name: FinalCleanup()
1002: // Desc: Paired with OneTimeSceneInit()
1003: //       Called before the app exits, this function gives the app the chance
1004: //       to cleanup after itself.
1005: //-----------------------------------------------------------------------------
1006: HRESULT CMyD3DApplication::FinalCleanup()
1007: {
1008:     // TODO: Perform any final cleanup needed
1009:     // Cleanup D3D font
1010:     SAFE_DELETE( m_pFont );
1011: 
1012:     // Cleanup DirectInput
1013:     CleanupDirectInput();
1014: 
1015:     // Cleanup DirectX audio objects
1016:     SAFE_DELETE( m_pBounceSound );
1017:     SAFE_DELETE( m_pMusicManager );
1018:     // Write the settings to the registry
1019:     WriteSettings();
1020: 
1021:     return S_OK;
1022: }
1023: 
1024: 
1025: 
1026: 
1027: //-----------------------------------------------------------------------------
1028: // Name: CleanupDirectInput()
1029: // Desc: Cleanup DirectInput 
1030: //-----------------------------------------------------------------------------
1031: VOID CMyD3DApplication::CleanupDirectInput()
1032: {
1033:     if( NULL == m_pInputDeviceManager )
1034:         return;
1035: 
1036:     // Get access to the list of semantically-mapped input devices
1037:     // to delete all InputDeviceState structs
1038:     CInputDeviceManager::DeviceInfo* pDeviceInfos;
1039:     DWORD dwNumDevices;
1040:     m_pInputDeviceManager->GetDevices( &pDeviceInfos, &dwNumDevices );
1041: 
1042:     for( DWORD i=0; i<dwNumDevices; i++ )
1043:     {
1044:         InputDeviceState* pInputDeviceState = (InputDeviceState*) pDeviceInfos[i].pParam;
1045:         SAFE_DELETE( pInputDeviceState );
1046:         pDeviceInfos[i].pParam = NULL;
1047:     }
1048: 
1049:     // Cleanup DirectX input objects
1050:     SAFE_DELETE( m_pInputDeviceManager );
1051: 
1052: }
1053: 
1054: 
1055: 
1056: 
1057: