#pragma comment ( lib, "d3d9.lib" ) #pragma comment ( lib, "d3dx9.lib" ) #pragma comment ( lib, "dxerr9.lib" ) #pragma comment ( lib, "dxguid.lib" ) #pragma comment ( lib, "ddraw.lib" ) #pragma comment ( lib, "dsound.lib" ) #include #include #include #include #include #include //このヘッダが必要! #pragma warning( disable : 4996 ) // 無駄な警告を出さなくする #include #pragma warning( default : 4996 ) //メモリリークを調べるために必要。 #if _DEBUG #include #define new ::new( _NORMAL_BLOCK, __FILE__, __LINE__ ) #endif #define WINDOW_WIDTH (640) // ウィンドウの幅 #define WINDOW_HEIGHT (480) // ウィンドウの高さ #define WINDOW_X ((WINDOW_WIDTH + GetSystemMetrics( SM_CXSIZEFRAME )*2)) #define WINDOW_Y ((WINDOW_HEIGHT + GetSystemMetrics( SM_CYSIZEFRAME )*2 + GetSystemMetrics( SM_CYCAPTION ))) #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } } #define SAFE_DELETE_ARRAY(p) { if(p) { delete[](p); (p)=NULL; } } HINSTANCE g_hInstance = NULL; // インスタンス・ハンドル HWND g_hWindow = NULL; // ウインドウ・ハンドル LPDIRECT3D9 g_pD3D = NULL; // Direct3Dインタフェース LPDIRECT3DDEVICE9 g_pD3DDevice = NULL; // Direct3DDeviceインタフェース LPDIRECTSOUND8 g_pDS8 = NULL; LPDIRECTSOUNDBUFFER g_pSoundBuf = NULL; // Waveファイルオープン関数 bool openWave( TCHAR *filepath, WAVEFORMATEX &waveFormatEx, char** ppData, DWORD &dataSize ) { if ( filepath == 0 ) return false; HMMIO hMmio = NULL; MMIOINFO mmioInfo; // Waveファイルオープン memset( &mmioInfo, 0, sizeof(MMIOINFO) ); hMmio = mmioOpen( filepath, &mmioInfo, MMIO_READ ); if( !hMmio ) return false; // ファイルオープン失敗 // RIFFチャンク検索 MMRESULT mmRes; MMCKINFO riffChunk; riffChunk.fccType = mmioFOURCC('W', 'A', 'V', 'E'); mmRes = mmioDescend( hMmio, &riffChunk, NULL, MMIO_FINDRIFF ); if( mmRes != MMSYSERR_NOERROR ) { mmioClose( hMmio, 0 ); return false; } // フォーマットチャンク検索 MMCKINFO formatChunk; formatChunk.ckid = mmioFOURCC('f', 'm', 't', ' '); mmRes = mmioDescend( hMmio, &formatChunk, &riffChunk, MMIO_FINDCHUNK ); if( mmRes != MMSYSERR_NOERROR ) { mmioClose( hMmio, 0 ); return false; } DWORD fmsize = formatChunk.cksize; DWORD size = mmioRead( hMmio, (HPSTR)&waveFormatEx, fmsize ); if( size != fmsize ) { mmioClose( hMmio, 0 ); return false; } mmioAscend( hMmio, &formatChunk, 0 ); // データチャンク検索 MMCKINFO dataChunk; dataChunk.ckid = mmioFOURCC('d', 'a', 't', 'a'); mmRes = mmioDescend( hMmio, &dataChunk, &riffChunk, MMIO_FINDCHUNK ); if( mmRes != MMSYSERR_NOERROR ) { mmioClose( hMmio, 0 ); return false; } *ppData = new char[ dataChunk.cksize ]; size = mmioRead( hMmio, (HPSTR)*ppData, dataChunk.cksize ); if(size != dataChunk.cksize ) { delete[] *ppData; return false; } dataSize = size; // ハンドルクローズ mmioClose( hMmio, 0 ); return true; } //----------------------------------------------------------------------------- // Name: MsgProc() // Desc: The window's message handler //----------------------------------------------------------------------------- LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_DESTROY: PostQuitMessage( 0 ); return 0; } return DefWindowProc( hWnd, msg, wParam, lParam ); } //----------------------------------------------------------------------------- // Name: InitApp() // Desc: Initialize Window //----------------------------------------------------------------------------- HRESULT InitApp(HINSTANCE hInstance) { g_hInstance = hInstance; WNDCLASSEX wcex ={sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW, MsgProc, 0, 0, g_hInstance, NULL, NULL, (HBRUSH)(COLOR_WINDOW+1), NULL, L"D3D Tutorial", NULL}; if( !RegisterClassEx( &wcex )){ return DXTRACE_ERR(L"InitApp", GetLastError()); } // Create the application's window g_hWindow = CreateWindow( L"D3D Tutorial", L"ゲームプログラミング", WS_OVERLAPPEDWINDOW ^WS_THICKFRAME ^ WS_MAXIMIZEBOX ^ WS_MINIMIZEBOX, 100, 100, WINDOW_X, WINDOW_Y, NULL, NULL, wcex.hInstance, NULL ); if (g_hWindow == NULL) return DXTRACE_ERR(L"InitApp", GetLastError()); return S_OK; } //----------------------------------------------------------------------------- // Name: InitDirectX() // Desc: Initialize DirectX //----------------------------------------------------------------------------- HRESULT InitDirectX(void){ g_pD3D = Direct3DCreate9(D3D_SDK_VERSION); if(g_pD3D == NULL){ DXTRACE_MSG(L"DirectXDeviceの初期化に失敗しました"); return E_FAIL; } D3DDISPLAYMODE d3ddm; if(FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm))) { DXTRACE_MSG(L"DirectX3DDeviceの初期化に失敗しました"); return E_FAIL; } D3DPRESENT_PARAMETERS d3dpp; ZeroMemory(&d3dpp, sizeof(d3dpp)); d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; d3dpp.EnableAutoDepthStencil = TRUE; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; HRESULT hr = g_pD3D->CreateDevice( D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,g_hWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp,&g_pD3DDevice); if(FAILED(hr)) { hr = g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,g_hWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp,&g_pD3DDevice); if(FAILED(hr)) { hr = g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_REF,g_hWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp,&g_pD3DDevice); if(FAILED(hr)){ DXTRACE_MSG(L"DirectX3DDeviceの初期化に失敗しました"); return E_FAIL; } } } //セットアップ レンダーステート g_pD3DDevice->SetRenderState( D3DRS_LIGHTING, FALSE ); g_pD3DDevice->SetRenderState( D3DRS_DITHERENABLE, TRUE ); g_pD3DDevice->SetRenderState( D3DRS_ZENABLE, TRUE ); g_pD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ); g_pD3DDevice->SetRenderState( D3DRS_AMBIENT, 0x33333333 ); g_pD3DDevice->SetRenderState( D3DRS_NORMALIZENORMALS, TRUE ); g_pD3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); g_pD3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); g_pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); g_pD3DDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); g_pD3DDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); //ビュー行列作成 D3DXVECTOR3 vEyePt( 0.0f, 0.0f,-4.0f ); D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f ); D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f ); D3DXMATRIXA16 matView; D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec ); g_pD3DDevice->SetTransform( D3DTS_VIEW, &matView ); //射影行列作成 D3DXMATRIXA16 matProj; D3DXMatrixPerspectiveFovLH( &matProj, D3DXToRadian(90.0f), (float)640/480, 1.0f, 100.0f ); g_pD3DDevice->SetTransform( D3DTS_PROJECTION, &matProj ); return S_OK; } //----------------------------------------------------------------------------- // Name: Uninitialize() // Desc: UnInitialize DirectX //----------------------------------------------------------------------------- void Uninitialize(void) { SAFE_RELEASE(g_pSoundBuf); SAFE_RELEASE(g_pDS8); SAFE_RELEASE(g_pD3DDevice); SAFE_RELEASE(g_pD3D); } //----------------------------------------------------------------------------- // Name: WinMain() // Desc: The application's entry point //----------------------------------------------------------------------------- int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { #ifdef _DEBUG _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); #endif HRESULT hr; if(FAILED(hr = InitApp(hInstance))) { return(0); } // Initialize Direct3D if( SUCCEEDED(hr = InitDirectX()) ) { MSG msg; ZeroMemory( &msg, sizeof(msg) ); ShowWindow(g_hWindow, SW_SHOWDEFAULT); UpdateWindow(g_hWindow); D3DXMATRIX mat; D3DXMatrixIdentity(&mat); g_pD3DDevice->SetTransform(D3DTS_WORLD, &mat); //************* Waveファイルオープン ************* WAVEFORMATEX wFmt; char *pWaveData = 0; DWORD waveSize = 0; if ( !openWave( _T("Test.wav"), wFmt, &pWaveData, waveSize ) ){ return 0; } //************* サウンドデバイス作成 ************* DirectSoundCreate8(NULL, &g_pDS8, NULL); g_pDS8->SetCooperativeLevel(g_hWindow, DSSCL_PRIORITY); DSBUFFERDESC DSBufferDesc; DSBufferDesc.dwSize = sizeof(DSBUFFERDESC); DSBufferDesc.dwFlags = 0; DSBufferDesc.dwBufferBytes = waveSize; DSBufferDesc.dwReserved = 0; DSBufferDesc.lpwfxFormat = &wFmt; DSBufferDesc.guid3DAlgorithm = GUID_NULL; //************ セカンダリバッファの作成 ************ g_pDS8->CreateSoundBuffer(&DSBufferDesc, &g_pSoundBuf, NULL); //************ バッファに音声データを書き込む ****** LPVOID lpBufLock = 0; //バッファをロックした時に得られるポインタ DWORD dwLength = 0; //バッファのサイズ if (DS_OK == g_pSoundBuf->Lock(0, 0, &lpBufLock, &dwLength, NULL, NULL, DSBLOCK_ENTIREBUFFER)) { //waveのデータをコピー memcpy( lpBufLock, pWaveData, dwLength); //アンロック g_pSoundBuf->Unlock(lpBufLock, dwLength, NULL, 0); } //バッファにコピーし終わったので、元のwaveデータはもう要らない SAFE_DELETE_ARRAY(pWaveData); // Enter the message loop while( msg.message!=WM_QUIT ) { if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); }else{ g_pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,60), 1.0f, 0 ); g_pD3DDevice->BeginScene(); if(GetKeyState(VK_RIGHT) < 0){ g_pSoundBuf->Play(0,0,0); } g_pD3DDevice->EndScene(); g_pD3DDevice->Present( NULL, NULL, NULL, NULL ); Sleep(1); } } } Uninitialize(); UnregisterClass( L"D3D Tutorial", g_hInstance ); return 0; }