123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566 |
- /*
- * Seven Kingdoms: Ancient Adversaries
- *
- * Copyright 1997,1998 Enlight Software Ltd.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- //Filename : OVIDEO.CPP
- //Description : Video for Windows playback class
- //Owner : Gilbert
- #ifdef ENABLE_INTRO_VIDEO
- // for some .h files to define some IIDs
- #include <windows.h>
- #include <windowsx.h>
- #include <commdlg.h>
- #include <string.h>
- #include <objbase.h>
- #include <strmif.h>
- #include <evcode.h>
- #include <control.h>
- #include <amvideo.h>
- #include <uuids.h>
- //#include <mmsystem.h>
- //#include <digitalv.h>
- #include <ALL.h>
- #include <OSTR.h>
- #include <OVIDEO.h>
- // --------- Define constant -------//
- // OATRUE and OAFALSE are defined in classes\base\ctlutil.h under active movie SDK
- #define OATRUE -1
- #define OAFALSE 0
- static long FAR PASCAL video_win_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
- static void create_dummy_window(HINSTANCE hInstance);
- // #define FULL_SCREEN_VIDEO
- #define CREATE_DUMMY_WINDOW
- /*
- //--------- Begin of function Video::play() ----------//
- //
- // <char*> aviFileName - the file name of the AVI file.
- // [DWORD] waitTime - no. of milli-seconds to wait still after
- // finishing playing the AVI.
- // (default: 0)
- //
- void Video::play(char* aviFileName, DWORD waitTime)
- {
- char resultStr[101];
- String str;
- str = "open ";
- str += aviFileName;
- str += " alias mov";
- mciSendString(str, NULL, 0, NULL);
- mciSendString("play mov fullscreen", NULL, 0, NULL);
- //------ wait until the whole video playback process is complete ------//
- while( 1 )
- {
- mciSendString( "status mov mode", resultStr, 100, NULL );
- if( strcmp(resultStr, "stopped")==0 )
- break;
- }
- //-------- wait still after playing the movie ------//
- DWORD curTime = m.get_time();
- while( m.get_time() < curTime+waitTime );
- //------------ close the MCI ---------------//
- mciSendString("close mov" , NULL, 0, NULL);
- mciSendString("close avivideo", NULL, 0, NULL);
- }
- //--------- End of function Video::play() ----------//
- */
- Video::Video()
- {
- CoInitialize(NULL);
- state = UNINITIALIZED;
- pGraph = NULL;
- hGraphNotifyEvent = NULL;
- init_success = 0;
- skip_on_fail_flag = 0;
- }
- Video::~Video()
- {
- CoUninitialize();
- }
- void Video::set_skip_on_fail()
- {
- skip_on_fail_flag = 1;
- }
- void Video::clear_skip_on_fail()
- {
- skip_on_fail_flag = 0;
- }
- void Video::init()
- {
- IMediaEvent *pME;
- HRESULT hr;
- init_success = 0;
- hwnd = NULL;
- if( ( hr = CoCreateInstance(CLSID_FilterGraph, // CLSID of object
- NULL, // Outer unknown
- CLSCTX_INPROC_SERVER, // Type of server
- IID_IGraphBuilder, // Interface wanted
- (void **) &pGraph) // Returned object
- ) == 0 )
- {
- // We use this to find out events sent by the filtergraph
- if( (hr = pGraph->QueryInterface(IID_IMediaEvent, (void **) &pME)) == 0)
- {
- if( (hr = pME->GetEventHandle( (OAEVENT*) &hGraphNotifyEvent)) == 0)
- {
- init_success = 1;
- state = STOPPED;
- }
- pME->Release();
- }
- }
- if( hr && !skip_on_fail_flag)
- {
- err.run("video.init error %ld", hr );
- }
- }
- void Video::deinit()
- {
- if( pGraph )
- {
- pGraph->Release();
- pGraph = NULL;
- }
- hGraphNotifyEvent = NULL;
- state = UNINITIALIZED;
- }
- void Video::play( char *fileName, DWORD )
- {
- WCHAR wPath[100];
- HRESULT hr;
- IMediaControl *pMC;
- if(!init_success)
- return;
- MultiByteToWideChar( CP_ACP, 0, fileName, -1, wPath, 100 );
- if( (hr = pGraph->RenderFile(wPath, NULL)) == 0)
- {
- // use full screen video interface
- // try to change display mode
- IVideoWindow *iVideoWindow = NULL;
- if( (hr = pGraph->QueryInterface(IID_IVideoWindow, (void **) &iVideoWindow)) == 0)
- {
- #ifdef CREATE_DUMMY_WINDOW
- if(hwnd)
- {
- HRESULT hr2 = iVideoWindow->put_MessageDrain((OAHWND) hwnd);
- hr2 = 0;
- }
- #endif
- #ifdef FULL_SCREEN_VIDEO
- IFilter *iFilter;
- if( pGraph->FindFilterByName(L"Video Renderer", &iFilter) == 0)
- {
- IBasicVideo *iBasicVideo;
- if( iFilter->QueryInterface(IID_IBasicVideo, (void **)&iBasicVideo) == 0)
- {
- IFullScreenVideo *iFullScreenVideo;
- IDirectDrawVideo *iDirectDrawVideo;
- if( iFilter->QueryInterface(IID_IFullScreenVideo, (void **)&iFullScreenVideo) == 0)
- {
- iFullScreenVideo->Release();
- }
- else if( iFilter->QueryInterface(IID_IDirectDrawVideo, (void **)&iDirectDrawVideo) == 0)
- {
- HRESULT hr2;
- hr2 = iDirectDrawVideo->UseWhenFullScreen(OATRUE);
- iDirectDrawVideo->Release();
- }
- iBasicVideo->Release();
- }
- iFilter->Release();
- }
- hr=iVideoWindow->put_FullScreenMode(OATRUE);
- #endif
- /* // code to find all filter in the filter graph
- {
- IEnumFilters *iEnumFilters;
- pGraph->EnumFilters(&iEnumFilters);
- ULONG filterCount = 16;
- IFilter *iFilters[16];
- iEnumFilters->Next(filterCount, iFilters, &filterCount);
- for( ULONG j = 0; j < filterCount; ++j )
- {
- FILTER_INFO filterInfo;
- iFilters[j]->QueryFilterInfo(&filterInfo);
- filterInfo.pGraph->Release();
- iFilters[j]->Release();
- }
- iEnumFilters->Release();
- }*/
- iVideoWindow->HideCursor(OATRUE);
- iVideoWindow->put_Visible( OAFALSE );
- iVideoWindow->put_AutoShow( OAFALSE );
- LONG windowStyle;
- iVideoWindow->get_WindowStyle( &windowStyle);
- windowStyle &= ~WS_BORDER & ~WS_CAPTION & ~WS_SIZEBOX & ~WS_THICKFRAME &
- ~WS_HSCROLL & ~WS_VSCROLL & ~WS_VISIBLE;
- iVideoWindow->put_WindowStyle( windowStyle);
- }
- else
- iVideoWindow = NULL;
-
- if( (hr = pGraph->QueryInterface(IID_IMediaControl, (void **) &pMC)) == 0)
- {
- pMC->Run(); // sometimes it returns 1, but still ok
- state = PLAYING;
- pMC->Release();
- }
- if( iVideoWindow )
- {
- iVideoWindow->put_Visible( OAFALSE );
- LONG windowStyle;
- iVideoWindow->get_WindowStyle( &windowStyle);
- windowStyle &= ~WS_BORDER & ~WS_CAPTION & ~WS_SIZEBOX & ~WS_THICKFRAME &
- ~WS_HSCROLL & ~WS_VSCROLL & ~WS_VISIBLE;
- iVideoWindow->put_WindowStyle( windowStyle);
- LONG maxWidth;
- LONG maxHeight;
- hr=iVideoWindow->GetMaxIdealImageSize( &maxWidth, &maxHeight);
- #ifdef FULL_SCREEN_VIDEO
- #else
- iVideoWindow->put_BorderColor( RGB(0,0,0) );
- iVideoWindow->put_WindowState(SW_MAXIMIZE);
- IBaseFilter *iFilter;
- if( pGraph->FindFilterByName((const WCHAR *)L"Video Renderer", &iFilter) == 0)
- {
- IBasicVideo *iBasicVideo;
- if( iFilter->QueryInterface(IID_IBasicVideo, (void **)&iBasicVideo) == 0)
- {
- LONG screenWidth;
- LONG screenHeight;
- LONG videoWidth;
- LONG videoHeight;
- if( iVideoWindow->get_Width(&screenWidth) == 0 &&
- iVideoWindow->get_Height(&screenHeight) == 0 &&
- iBasicVideo->GetVideoSize(&videoWidth, &videoHeight) == 0)
- {
- // zoom in by 2 if possible
- if( screenWidth >= videoWidth * 2 &&
- screenHeight >= videoHeight * 2)
- {
- videoWidth *= 2;
- videoHeight *= 2;
- }
- // center the video client area
- iBasicVideo->SetDestinationPosition(
- (screenWidth-videoWidth)/2, (screenHeight-videoHeight)/2,
- videoWidth, videoHeight);
- }
- iBasicVideo->Release();
- }
- iFilter->Release();
- }
- #endif
- iVideoWindow->HideCursor(OATRUE);
- iVideoWindow->SetWindowForeground(OATRUE);
- }
- if(iVideoWindow)
- {
- iVideoWindow->Release();
- iVideoWindow = NULL;
- }
- }
- if( hr && !skip_on_fail_flag)
- err.run("video.play error %d", hr );
- }
- void Video::play_until_end( char *fileName, HINSTANCE hInstance, DWORD t)
- {
- HANDLE ahObjects[1]; // Handles that need to be waited on
- const int cObjects = 1; // Number of objects that we have
-
- if(!init_success)
- return;
- hwnd = NULL;
- #ifdef CREATE_DUMMY_WINDOW
- create_dummy_window(hInstance);
- #endif
- play(fileName, t);
- while( state == PLAYING )
- {
- if( (ahObjects[ 0 ] = hGraphNotifyEvent) == NULL)
- {
- state = STOPPED;
- break;
- }
- DWORD Result = MsgWaitForMultipleObjects( cObjects, ahObjects,
- FALSE, INFINITE, QS_ALLINPUT);
-
- // Have we received an event notification
- if( Result >= WAIT_OBJECT_0 && Result < (WAIT_OBJECT_0 + cObjects) )
- {
- if( Result == WAIT_OBJECT_0 )
- on_graph_notify();
- }
- else if( Result == WAIT_OBJECT_0 + cObjects )
- {
- if( hwnd )
- {
- // message in the message queue
- MSG msg;
- while( PeekMessage(&msg, hwnd, 0, ~0UL, PM_NOREMOVE) )
- {
- if( !GetMessage(&msg, hwnd, 0, ~0UL) )
- break;
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- }
- else
- {
- // other event to wait ...
- }
- }
- if( hwnd )
- {
- PostMessage( hwnd, WM_CLOSE, 0, 0 );
- //handle outstanding message
- MSG msg;
- while( GetMessage(&msg, hwnd, 0, ~0UL) )
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- hwnd = NULL;
- }
- void Video::stop()
- {
- HRESULT hr;
- IMediaControl *pMC;
- if(!init_success)
- return;
- // Obtain the interface to our filter graph
- if( (hr = pGraph->QueryInterface(IID_IMediaControl, (void **) &pMC))== 0 )
- {
- hr = pMC->Stop();
- pMC->Release();
- // rewind to the beginning
- IMediaPosition *pMP;
- if( (hr=pGraph->QueryInterface( IID_IMediaPosition, (void **) &pMP))==0)
- {
- pMP->put_CurrentPosition( 0);
- pMP->Release();
- }
- }
- // force it to stop
- state = STOPPED;
- if( hr && !skip_on_fail_flag)
- err.run("video.stop error %d", hr );
- }
- void Video::abort()
- {
- HRESULT hr;
- IMediaControl *pMC;
- if(!init_success)
- return;
- // Obtain the interface to our filter graph
- if( (hr = pGraph->QueryInterface(IID_IMediaControl, (void **) &pMC)) == 0)
- {
- // Ask the filter graph to stop and release the interface
- hr = pMC->Stop();
- pMC->Release();
- // rewind to the beginning
- IMediaPosition *pMP;
- if( (hr=pGraph->QueryInterface( IID_IMediaPosition, (void **) &pMP))==0)
- {
- pMP->put_CurrentPosition( 0);
- pMP->Release();
- }
- }
- state = STOPPED;
- if( hr && !skip_on_fail_flag)
- err.run("video.abort error %d", hr);
- }
- void Video::on_graph_notify()
- {
- IMediaEvent *pME;
- LONG lEventCode;
- LONG_PTR lParam1, lParam2;
- HRESULT hr;
- if( (hr=pGraph->QueryInterface(IID_IMediaEvent, (void **) &pME)) == 0)
- {
- if( (hr=pME->GetEvent(&lEventCode, &lParam1, &lParam2, 0)) == 0)
- {
- switch(lEventCode)
- {
- case EC_COMPLETE:
- stop();
- break;
- case EC_USERABORT:
- case EC_ERRORABORT:
- abort();
- break;
- }
- }
- pME->Release();
- }
- if( hr && !skip_on_fail_flag)
- err.run("video.on_graph_notify error %d", hr);
- }
- static void create_dummy_window(HINSTANCE hInstance)
- {
- //--------- register window class --------//
- WNDCLASS wc;
- BOOL rc;
- wc.style = CS_DBLCLKS;
- wc.lpfnWndProc = video_win_proc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = hInstance;
- wc.hIcon = NULL; // LoadIcon( hInstance, MAKEINTATOM(IDI_ICON1));
- wc.hCursor = LoadCursor( NULL, IDC_ARROW );
- wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
- wc.lpszMenuName = NULL;
- wc.lpszClassName = "Seven Kingdoms Video Window";
- rc = RegisterClass( &wc );
- if( !rc )
- return;
- video.hwnd = CreateWindowEx(
- WS_EX_APPWINDOW | WS_EX_TOPMOST,
- "Seven Kingdoms Video Window",
- "Seven Kingdoms",
- WS_POPUP,
- 0,
- 0,
- GetSystemMetrics(SM_CXSCREEN),
- GetSystemMetrics(SM_CYSCREEN),
- NULL,
- NULL,
- hInstance,
- NULL );
- if( !video.hwnd)
- return;
- UpdateWindow( video.hwnd );
- SetFocus( video.hwnd );
- return;
- }
- static long FAR PASCAL video_win_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- switch( message )
- {
- case WM_CREATE:
- video.hwnd = hWnd;
- break;
- //case WM_SYSKEYUP:
- // if( (wParam==27 && lParam==0x80010001) || (wParam==9 && lParam==0xa00f0001) )
- // pause();
- // break;
- case WM_DESTROY:
- video.hwnd = NULL;
- PostQuitMessage( 0 );
- break;
- case WM_LBUTTONDOWN:
- video.stop();
- PostMessage(hWnd, WM_CLOSE, 0, 0);
- break;
- default:
- break;
- }
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
- #endif // ENABLE_INTRO_VIDEO
|