#include "stdafx.h" #include <d3dx9.h> #include "D3DQuickLib.h" #include <mmsystem.h> #include <dsound.h> #include "DSQuickLib.h" #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> // stat 関数を使う為インクルード #include <crtdbg.h> #include <TCHAR.h> #include <vfw.h> #include <mmreg.h> #include <msacm.h> #include "AVIVideoTexture.h" #include "PCMStreamForAVIStream.h" #pragma comment (lib, "msacm32.lib") #pragma comment (lib, "winmm.lib") #pragma comment (lib, "vfw32.lib") // // Prototypes. // LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam); LRESULT CALLBACK IOProc(LPMMIOINFO lpMMIOInfo, UINT uMessage, LPARAM lParam1, LPARAM lParam2); CD3DEnv *g_pD3DEnv = NULL; CBillboard *g_pBillboard = NULL; CAVIVideoTexture *g_pVideoTexture = NULL; CDSoundEnv *g_pDSoundEnv = NULL; CPCMStreamForAVIStream *g_pAudioStream = NULL; static char * g_lpData = NULL; static long g_cfileSize; CRITICAL_SECTION g_csSema; float g_fTime = 0; //------------------------------------------------------------ // Name: FrameMove // Desc: アニメーションを行う。 // UpdateScene 関数(d3dmain.cpp) からコールバックされる。 //------------------------------------------------------------ void FrameMove(float timeElapsed) { g_fTime = timeElapsed; } //------------------------------------------------------------ // Name: RenderScene // Desc: レンダリングを行う。 // UpdateScene 関数(d3dmain.cpp) からコールバックされる。 //------------------------------------------------------------ void RenderScene(LPDIRECT3DDEVICE9 lpd3ddev) { Yield(); g_pVideoTexture->Lock(); LPDIRECT3DTEXTURE9 pTex = g_pVideoTexture->GetRenderableTexture(); if (pTex != NULL){ int w, h; g_pVideoTexture->GetRenderableTextureSize(&w,&h); g_pBillboard->Render(lpd3ddev,0,0,640,480,0,0,w,h,pTex); lpd3ddev->SetTexture(0,NULL); } g_pVideoTexture->Unlock(); } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = (WNDPROC)WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_APPLICATION)); wcex.hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = NULL; wcex.lpszClassName = "AVITextureAndAVIStreamSound"; wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION); RegisterClassEx(&wcex); HWND hWnd; hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,wcex.lpszClassName,"AVITexture with Sound -- Play AVI Movie", WS_VISIBLE|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX, CW_USEDEFAULT,0,640,480,NULL,NULL,hInstance,NULL); if( !hWnd ) return FALSE; RECT bounds,client; GetWindowRect(hWnd,&bounds); GetClientRect(hWnd,&client); MoveWindow(hWnd,bounds.left,bounds.top, 640 * 2 - client.right, 480 * 2 - client.bottom, false ); ShowWindow( hWnd, nCmdShow ); UpdateWindow( hWnd ); InitializeCriticalSection(&g_csSema); g_pD3DEnv = new CD3DEnv(); if (SUCCEEDED(g_pD3DEnv->InitD3D(hWnd))){ PAVIFILE lpAviFile = NULL; PAVISTREAM lpVideoStream = NULL; PAVISTREAM lpAudioStream = NULL; struct _stat status; if (0 == _tstat(_T("test.avi"),&status)){ g_cfileSize = status.st_size; g_lpData = new char[g_cfileSize]; FILE *fp = fopen(_T("test.avi"),_T("rb")); if (fp != NULL){ fread(g_lpData,g_cfileSize,1,fp); fclose(fp); // mci:カスタムIOProc のインストール mmioInstallIOProc(mmioFOURCC('M', 'E', 'V', ' '), (LPMMIOPROC)IOProc, MMIO_INSTALLPROC | MMIO_GLOBALPROC); AVIFileInit(); if (AVIFileOpen(&lpAviFile, TEXT("test.MEV+"), OF_READ, NULL) != 0) return -1; if (AVIFileGetStream(lpAviFile, &lpVideoStream, streamtypeVIDEO, 0) != 0) lpVideoStream = NULL; if (AVIFileGetStream(lpAviFile, &lpAudioStream, streamtypeAUDIO, 0) != 0) lpAudioStream = NULL; } } if (lpAudioStream != NULL){ g_pDSoundEnv = new CDSoundEnv(2,44100,16); if (g_pDSoundEnv){ if (SUCCEEDED(g_pDSoundEnv->Initialize(hWnd,DSSCL_PRIORITY))){ g_pAudioStream = new CPCMStreamForAVIStream(g_pDSoundEnv,lpAudioStream); if (g_pAudioStream){ g_pAudioStream->Prepare(); } } } } if (lpVideoStream != NULL){ g_pVideoTexture = new CAVIVideoTexture(g_pD3DEnv,lpVideoStream); } g_pBillboard = new CBillboard(g_pD3DEnv,0); g_pD3DEnv->ReloadGraphics(); } MSG msg; while(true){ if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)){ if(msg.message == WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); }else{ g_pD3DEnv->UpdateScene(FrameMove,RenderScene); if (!g_pVideoTexture->IsPlaying() && !g_pAudioStream->IsPlaying()){ Sleep(100); g_pVideoTexture->Rewind(); g_pAudioStream->Rewind(); g_pVideoTexture->Run(); g_pAudioStream->Play(); } } } SAFE_DELETE(g_pBillboard); SAFE_DELETE(g_pVideoTexture); SAFE_DELETE(g_pD3DEnv); EnterCriticalSection(&g_csSema); if (g_lpData != NULL){ mmioInstallIOProc(mmioFOURCC('M', 'E', 'V', ' '), NULL,MMIO_REMOVEPROC); delete g_lpData; g_lpData = NULL; } LeaveCriticalSection(&g_csSema); DeleteCriticalSection(&g_csSema); return (int)msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { switch (message){ case WM_SIZE: if (SIZE_MAXIMIZED == wParam){ g_pD3DEnv->ForceFullscreen(); } break; case WM_SETCURSOR: if (g_pD3DEnv->IsWindowed()) ::SetCursor(::LoadCursor(NULL,IDC_ARROW)); else ::SetCursor(NULL); break; case WM_SYSCHAR: if (lParam&0x20000000){ if (wParam == '\x0d'){ g_pD3DEnv->ToggleFullscreen(); break; } } return DefWindowProc( hWnd, message, wParam, lParam ); case WM_SYSCOMMAND: if (!g_pD3DEnv->IsWindowed()){ // フルスクリーン時 if (wParam != SC_CLOSE) break; // Windowが閉じられる前にWindowモードに戻しておく。 g_pD3DEnv->ToggleFullscreen(); Sleep(100); } return DefWindowProc( hWnd, message, wParam, lParam ); case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // // mmio: IOProc // LRESULT CALLBACK IOProc(LPMMIOINFO lpMMIOInfo, UINT uMessage, LPARAM lParam1, LPARAM lParam2) { static BOOL alreadyOpened = FALSE; switch (uMessage) { case MMIOM_OPEN: if (alreadyOpened) return 0; alreadyOpened = TRUE; lpMMIOInfo->lDiskOffset = 0; return 0; case MMIOM_CLOSE: return 0; case MMIOM_READ:{ LPARAM dataRead = 0; EnterCriticalSection(&g_csSema); if (g_lpData != NULL){ dataRead = lParam2; memcpy((void *)lParam1, g_lpData+lpMMIOInfo->lDiskOffset, lParam2); lpMMIOInfo->lDiskOffset += lParam2; dataRead = lParam2; } LeaveCriticalSection(&g_csSema); return (dataRead); } case MMIOM_SEEK: switch (lParam2) { case SEEK_SET: lpMMIOInfo->lDiskOffset = lParam1; break; case SEEK_CUR: lpMMIOInfo->lDiskOffset += lParam1; break; case SEEK_END: lpMMIOInfo->lDiskOffset = g_cfileSize - lParam1; break; } return lpMMIOInfo->lDiskOffset; default: return -1; } }
戻る