summaryrefslogtreecommitdiff
path: root/utils/smp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/smp')
-rw-r--r--utils/smp/CWMPEventDispatch.cpp584
-rw-r--r--utils/smp/CWMPEventDispatch.h102
-rw-r--r--utils/smp/CWMPHost.cpp603
-rw-r--r--utils/smp/CWMPHost.h94
-rw-r--r--utils/smp/IceKey.H65
-rw-r--r--utils/smp/IceKey.cpp392
-rw-r--r--utils/smp/StdAfx.h45
-rw-r--r--utils/smp/resource.h62
-rw-r--r--utils/smp/smp.cpp1441
-rw-r--r--utils/smp/smp.icobin0 -> 2998 bytes
-rw-r--r--utils/smp/smp.rc228
-rw-r--r--utils/smp/smp.sln36
-rw-r--r--utils/smp/smp.vcproj625
13 files changed, 4277 insertions, 0 deletions
diff --git a/utils/smp/CWMPEventDispatch.cpp b/utils/smp/CWMPEventDispatch.cpp
new file mode 100644
index 0000000..a49f042
--- /dev/null
+++ b/utils/smp/CWMPEventDispatch.cpp
@@ -0,0 +1,584 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+// CWMPEventDispatch.cpp : Implementation of the event dispatcher
+//
+
+#include "CWMPEventDispatch.h"
+#include "CWMPHost.h"
+
+extern HWND g_hBlackFadingWindow;
+extern CComPtr<IWMPPlayer> g_spWMPPlayer;
+extern CWMPHost* g_pFrame;
+extern double g_timeAtFadeStart;
+extern bool g_bFadeIn;
+
+bool g_bFadeWindowTriggered = false;
+
+
+bool IsFullScreen();
+bool SetFullScreen( bool bWantToBeFullscreen );
+bool IsVideoPlaying();
+void PlayVideo( bool bPlay );
+bool ShowFadeWindow( bool bShow );
+void LogPlayerEvent( EventType_t e, float pos );
+void LogPlayerEvent( EventType_t e );
+
+
+HRESULT CWMPEventDispatch::Invoke(
+ DISPID dispIdMember,
+ REFIID riid,
+ LCID lcid,
+ WORD wFlags,
+ DISPPARAMS FAR* pDispParams,
+ VARIANT FAR* pVarResult,
+ EXCEPINFO FAR* pExcepInfo,
+ unsigned int FAR* puArgErr )
+{
+ if (!pDispParams)
+ return E_POINTER;
+
+ if (pDispParams->cNamedArgs != 0)
+ return DISP_E_NONAMEDARGS;
+
+ HRESULT hr = DISP_E_MEMBERNOTFOUND;
+
+ switch (dispIdMember)
+ {
+ case DISPID_WMPCOREEVENT_OPENSTATECHANGE:
+ OpenStateChange(pDispParams->rgvarg[0].lVal /* NewState */ );
+ break;
+
+ case DISPID_WMPCOREEVENT_PLAYSTATECHANGE:
+ PlayStateChange(pDispParams->rgvarg[0].lVal /* NewState */);
+ break;
+
+ case DISPID_WMPCOREEVENT_AUDIOLANGUAGECHANGE:
+ AudioLanguageChange(pDispParams->rgvarg[0].lVal /* LangID */);
+ break;
+
+ case DISPID_WMPCOREEVENT_STATUSCHANGE:
+ StatusChange();
+ break;
+
+ case DISPID_WMPCOREEVENT_SCRIPTCOMMAND:
+ ScriptCommand(pDispParams->rgvarg[1].bstrVal /* scType */, pDispParams->rgvarg[0].bstrVal /* Param */ );
+ break;
+
+ case DISPID_WMPCOREEVENT_NEWSTREAM:
+ NewStream();
+ break;
+
+ case DISPID_WMPCOREEVENT_DISCONNECT:
+ Disconnect(pDispParams->rgvarg[0].lVal /* Result */ );
+ break;
+
+ case DISPID_WMPCOREEVENT_BUFFERING:
+ Buffering(pDispParams->rgvarg[0].boolVal /* Start */);
+ break;
+
+ case DISPID_WMPCOREEVENT_ERROR:
+ Error();
+ break;
+
+ case DISPID_WMPCOREEVENT_WARNING:
+ Warning(pDispParams->rgvarg[1].lVal /* WarningType */, pDispParams->rgvarg[0].lVal /* Param */, pDispParams->rgvarg[2].bstrVal /* Description */);
+ break;
+
+ case DISPID_WMPCOREEVENT_ENDOFSTREAM:
+ EndOfStream(pDispParams->rgvarg[0].lVal /* Result */ );
+ break;
+
+ case DISPID_WMPCOREEVENT_POSITIONCHANGE:
+ PositionChange(pDispParams->rgvarg[1].dblVal /* oldPosition */, pDispParams->rgvarg[0].dblVal /* newPosition */);
+ break;
+
+ case DISPID_WMPCOREEVENT_MARKERHIT:
+ MarkerHit(pDispParams->rgvarg[0].lVal /* MarkerNum */);
+ break;
+
+ case DISPID_WMPCOREEVENT_DURATIONUNITCHANGE:
+ DurationUnitChange(pDispParams->rgvarg[0].lVal /* NewDurationUnit */);
+ break;
+
+ case DISPID_WMPCOREEVENT_CDROMMEDIACHANGE:
+ CdromMediaChange(pDispParams->rgvarg[0].lVal /* CdromNum */);
+ break;
+
+ case DISPID_WMPCOREEVENT_PLAYLISTCHANGE:
+ PlaylistChange(pDispParams->rgvarg[1].pdispVal /* Playlist */, (WMPPlaylistChangeEventType) pDispParams->rgvarg[0].lVal /* change */);
+ break;
+
+ case DISPID_WMPCOREEVENT_CURRENTPLAYLISTCHANGE:
+ CurrentPlaylistChange((WMPPlaylistChangeEventType) pDispParams->rgvarg[0].lVal /* change */);
+ break;
+
+ case DISPID_WMPCOREEVENT_CURRENTPLAYLISTITEMAVAILABLE:
+ CurrentPlaylistItemAvailable(pDispParams->rgvarg[0].bstrVal /* bstrItemName */);
+ break;
+
+ case DISPID_WMPCOREEVENT_MEDIACHANGE:
+ MediaChange(pDispParams->rgvarg[0].pdispVal /* Item */);
+ break;
+
+ case DISPID_WMPCOREEVENT_CURRENTMEDIAITEMAVAILABLE:
+ CurrentMediaItemAvailable(pDispParams->rgvarg[0].bstrVal /* bstrItemName */);
+ break;
+
+ case DISPID_WMPCOREEVENT_CURRENTITEMCHANGE:
+ CurrentItemChange(pDispParams->rgvarg[0].pdispVal /* pdispMedia */);
+ break;
+
+ case DISPID_WMPCOREEVENT_MEDIACOLLECTIONCHANGE:
+ MediaCollectionChange();
+ break;
+
+ case DISPID_WMPCOREEVENT_MEDIACOLLECTIONATTRIBUTESTRINGADDED:
+ MediaCollectionAttributeStringAdded(pDispParams->rgvarg[1].bstrVal /* bstrAttribName */, pDispParams->rgvarg[0].bstrVal /* bstrAttribVal */ );
+ break;
+
+ case DISPID_WMPCOREEVENT_MEDIACOLLECTIONATTRIBUTESTRINGREMOVED:
+ MediaCollectionAttributeStringRemoved(pDispParams->rgvarg[1].bstrVal /* bstrAttribName */, pDispParams->rgvarg[0].bstrVal /* bstrAttribVal */ );
+ break;
+
+ case DISPID_WMPCOREEVENT_MEDIACOLLECTIONATTRIBUTESTRINGCHANGED:
+ MediaCollectionAttributeStringChanged(pDispParams->rgvarg[2].bstrVal /* bstrAttribName */, pDispParams->rgvarg[1].bstrVal /* bstrOldAttribVal */, pDispParams->rgvarg[0].bstrVal /* bstrNewAttribVal */);
+ break;
+
+ case DISPID_WMPCOREEVENT_PLAYLISTCOLLECTIONCHANGE:
+ PlaylistCollectionChange();
+ break;
+
+ case DISPID_WMPCOREEVENT_PLAYLISTCOLLECTIONPLAYLISTADDED:
+ PlaylistCollectionPlaylistAdded(pDispParams->rgvarg[0].bstrVal /* bstrPlaylistName */ );
+ break;
+
+ case DISPID_WMPCOREEVENT_PLAYLISTCOLLECTIONPLAYLISTREMOVED:
+ PlaylistCollectionPlaylistRemoved(pDispParams->rgvarg[0].bstrVal /* bstrPlaylistName */ );
+ break;
+
+ case DISPID_WMPCOREEVENT_PLAYLISTCOLLECTIONPLAYLISTSETASDELETED:
+ PlaylistCollectionPlaylistSetAsDeleted(pDispParams->rgvarg[1].bstrVal /* bstrPlaylistName */, pDispParams->rgvarg[0].boolVal /* varfIsDeleted */);
+ break;
+
+ case DISPID_WMPCOREEVENT_MODECHANGE:
+ ModeChange(pDispParams->rgvarg[1].bstrVal /* ModeName */, pDispParams->rgvarg[0].boolVal /* NewValue */);
+ break;
+
+ case DISPID_WMPCOREEVENT_MEDIAERROR:
+ MediaError(pDispParams->rgvarg[0].pdispVal /* pMediaObject */);
+ break;
+
+ case DISPID_WMPCOREEVENT_OPENPLAYLISTSWITCH:
+ OpenPlaylistSwitch(pDispParams->rgvarg[0].pdispVal /* pItem */);
+ break;
+
+ case DISPID_WMPCOREEVENT_DOMAINCHANGE:
+ DomainChange(pDispParams->rgvarg[0].bstrVal /* strDomain */);
+ break;
+
+ case DISPID_WMPOCXEVENT_SWITCHEDTOPLAYERAPPLICATION:
+ SwitchedToPlayerApplication();
+ break;
+
+ case DISPID_WMPOCXEVENT_SWITCHEDTOCONTROL:
+ SwitchedToControl();
+ break;
+
+ case DISPID_WMPOCXEVENT_PLAYERDOCKEDSTATECHANGE:
+ PlayerDockedStateChange();
+ break;
+
+ case DISPID_WMPOCXEVENT_PLAYERRECONNECT:
+ PlayerReconnect();
+ break;
+
+ case DISPID_WMPOCXEVENT_CLICK:
+ Click(pDispParams->rgvarg[3].iVal /* nButton */, pDispParams->rgvarg[2].iVal /* nShiftState */, pDispParams->rgvarg[1].lVal /* fX */, pDispParams->rgvarg[0].lVal /* fY */);
+ break;
+
+ case DISPID_WMPOCXEVENT_DOUBLECLICK:
+ DoubleClick(pDispParams->rgvarg[3].iVal /* nButton */, pDispParams->rgvarg[2].iVal /* nShiftState */, pDispParams->rgvarg[1].lVal /* fX */, pDispParams->rgvarg[0].lVal /* fY */);
+ break;
+
+ case DISPID_WMPOCXEVENT_KEYDOWN:
+ KeyDown(pDispParams->rgvarg[1].iVal /* nKeyCode */, pDispParams->rgvarg[0].iVal /* nShiftState */);
+ break;
+
+ case DISPID_WMPOCXEVENT_KEYPRESS:
+ KeyPress(pDispParams->rgvarg[0].iVal /* nKeyAscii */);
+ break;
+
+ case DISPID_WMPOCXEVENT_KEYUP:
+ KeyUp(pDispParams->rgvarg[1].iVal /* nKeyCode */, pDispParams->rgvarg[0].iVal /* nShiftState */);
+ break;
+
+ case DISPID_WMPOCXEVENT_MOUSEDOWN:
+ MouseDown(pDispParams->rgvarg[3].iVal /* nButton */, pDispParams->rgvarg[2].iVal /* nShiftState */, pDispParams->rgvarg[1].lVal /* fX */, pDispParams->rgvarg[0].lVal /* fY */);
+ break;
+
+ case DISPID_WMPOCXEVENT_MOUSEMOVE:
+ MouseMove(pDispParams->rgvarg[3].iVal /* nButton */, pDispParams->rgvarg[2].iVal /* nShiftState */, pDispParams->rgvarg[1].lVal /* fX */, pDispParams->rgvarg[0].lVal /* fY */);
+ break;
+
+ case DISPID_WMPOCXEVENT_MOUSEUP:
+ MouseUp(pDispParams->rgvarg[3].iVal /* nButton */, pDispParams->rgvarg[2].iVal /* nShiftState */, pDispParams->rgvarg[1].lVal /* fX */, pDispParams->rgvarg[0].lVal /* fY */);
+ break;
+ }
+
+ return( hr );
+}
+
+// Sent when the control changes OpenState
+void CWMPEventDispatch::OpenStateChange(long NewState)
+{
+ return;
+}
+
+// Sent when the control changes PlayState
+void CWMPEventDispatch::PlayStateChange(long NewState)
+{
+ WMPPlayState playstate;
+ if ( g_spWMPPlayer->get_playState( &playstate ) == S_OK )
+ {
+ switch ( playstate )
+ {
+ case wmppsPlaying:
+ {
+ static bool s_first = true;
+ if ( s_first )
+ {
+ s_first = false;
+
+ LogPlayerEvent( ET_MEDIABEGIN );
+
+ SetFullScreen( true );
+ ShowFadeWindow( false );
+ }
+ else
+ {
+ LogPlayerEvent( ET_PLAY );
+ }
+ break;
+ }
+
+ case wmppsPaused:
+ LogPlayerEvent( ET_PAUSE );
+ break;
+
+ case wmppsStopped:
+ LogPlayerEvent( ET_STOP );
+ break;
+
+ case wmppsMediaEnded:
+ LogPlayerEvent( ET_MEDIAEND );
+
+ if ( IsFullScreen() && !g_bFadeWindowTriggered )
+ {
+ g_bFadeWindowTriggered = true;
+ ShowFadeWindow( true );
+ }
+ break;
+ }
+ }
+}
+
+// Sent when the audio language changes
+void CWMPEventDispatch::AudioLanguageChange(long LangID)
+{
+ return;
+}
+
+// Sent when the status string changes
+void CWMPEventDispatch::StatusChange()
+{
+}
+
+// Sent when a synchronized command or URL is received
+void CWMPEventDispatch::ScriptCommand(BSTR scType,BSTR Param)
+{
+ return;
+}
+
+// Sent when a new stream is encountered (obsolete)
+void CWMPEventDispatch::NewStream()
+{
+ return;
+}
+
+// Sent when the control is disconnected from the server (obsolete)
+void CWMPEventDispatch:: Disconnect(long Result )
+{
+ return;
+}
+
+// Sent when the control begins or ends buffering
+void CWMPEventDispatch:: Buffering(VARIANT_BOOL Start)
+{
+ return;
+}
+
+// Sent when the control has an error condition
+void CWMPEventDispatch::Error()
+{
+ return;
+}
+
+// Sent when the control has an warning condition (obsolete)
+void CWMPEventDispatch::Warning(long WarningType, long Param, BSTR Description)
+{
+ return;
+}
+
+// Sent when the media has reached end of stream
+void CWMPEventDispatch::EndOfStream(long Result)
+{
+ return;
+}
+
+// Indicates that the current position of the movie has changed
+void CWMPEventDispatch::PositionChange(double oldPosition,double newPosition)
+{
+ LogPlayerEvent( ET_SCRUBFROM, ( float )oldPosition );
+ LogPlayerEvent( ET_SCRUBTO, ( float )newPosition );
+}
+
+// Sent when a marker is reached
+void CWMPEventDispatch::MarkerHit(long MarkerNum )
+{
+ return;
+}
+
+// Indicates that the unit used to express duration and position has changed
+void CWMPEventDispatch::DurationUnitChange(long NewDurationUnit)
+{
+ return;
+}
+
+// Indicates that the CD ROM media has changed
+void CWMPEventDispatch::CdromMediaChange(long CdromNum)
+{
+ return;
+}
+
+// Sent when a playlist changes
+void CWMPEventDispatch::PlaylistChange(IDispatch * Playlist,WMPPlaylistChangeEventType change)
+{
+ return;
+}
+
+// Sent when the current playlist changes
+void CWMPEventDispatch::CurrentPlaylistChange(WMPPlaylistChangeEventType change )
+{
+ return;
+}
+
+// Sent when a current playlist item becomes available
+void CWMPEventDispatch::CurrentPlaylistItemAvailable(BSTR bstrItemName)
+{
+ return;
+}
+
+// Sent when a media object changes
+void CWMPEventDispatch::MediaChange(IDispatch * Item)
+{
+ return;
+}
+
+// Sent when a current media item becomes available
+void CWMPEventDispatch::CurrentMediaItemAvailable(BSTR bstrItemName)
+{
+ return;
+}
+
+// Sent when the item selection on the current playlist changes
+void CWMPEventDispatch::CurrentItemChange(IDispatch *pdispMedia)
+{
+ return;
+}
+
+// Sent when the media collection needs to be requeried
+void CWMPEventDispatch::MediaCollectionChange()
+{
+ return;
+}
+
+// Sent when an attribute string is added in the media collection
+void CWMPEventDispatch::MediaCollectionAttributeStringAdded(BSTR bstrAttribName, BSTR bstrAttribVal)
+{
+ return;
+}
+
+// Sent when an attribute string is removed from the media collection
+void CWMPEventDispatch::MediaCollectionAttributeStringRemoved(BSTR bstrAttribName, BSTR bstrAttribVal)
+{
+ return;
+}
+
+// Sent when an attribute string is changed in the media collection
+void CWMPEventDispatch::MediaCollectionAttributeStringChanged(BSTR bstrAttribName, BSTR bstrOldAttribVal, BSTR bstrNewAttribVal)
+{
+ return;
+}
+
+// Sent when playlist collection needs to be requeried
+void CWMPEventDispatch::PlaylistCollectionChange()
+{
+ return;
+}
+
+// Sent when a playlist is added to the playlist collection
+void CWMPEventDispatch::PlaylistCollectionPlaylistAdded(BSTR bstrPlaylistName)
+{
+ return;
+}
+
+// Sent when a playlist is removed from the playlist collection
+void CWMPEventDispatch::PlaylistCollectionPlaylistRemoved(BSTR bstrPlaylistName)
+{
+ return;
+}
+
+// Sent when a playlist has been set or reset as deleted
+void CWMPEventDispatch::PlaylistCollectionPlaylistSetAsDeleted(BSTR bstrPlaylistName, VARIANT_BOOL varfIsDeleted)
+{
+ return;
+}
+
+// Playlist playback mode has changed
+void CWMPEventDispatch::ModeChange(BSTR ModeName, VARIANT_BOOL NewValue)
+{
+ return;
+}
+
+// Sent when the media object has an error condition
+void CWMPEventDispatch::MediaError(IDispatch * pMediaObject)
+{
+ while ( ShowCursor( TRUE ) < 0 )
+ ;
+
+ ShowWindow( g_hBlackFadingWindow, SW_HIDE );
+ if ( g_pFrame )
+ {
+ g_pFrame->ShowWindow( SW_HIDE );
+ }
+
+ CComPtr< IWMPMedia > spWMPMedia;
+ if ( pMediaObject )
+ {
+ pMediaObject->QueryInterface( &spWMPMedia );
+ }
+ if ( spWMPMedia )
+ {
+ BSTR bstr;
+ spWMPMedia->get_sourceURL( &bstr );
+ char str[ 1024 ];
+ sprintf( str, "Unable to open media: %s\n", CW2T( bstr ) );
+ MessageBox( NULL, str, "Media Error", MB_OK | MB_ICONERROR );
+ }
+ else
+ {
+ MessageBox( NULL, "Media Error", "Media Error", MB_OK | MB_ICONERROR );
+ }
+
+ g_pFrame->PostMessage( WM_CLOSE );
+}
+
+// Current playlist switch with no open state change
+void CWMPEventDispatch::OpenPlaylistSwitch(IDispatch *pItem)
+{
+ return;
+}
+
+// Sent when the current DVD domain changes
+void CWMPEventDispatch::DomainChange(BSTR strDomain)
+{
+ return;
+}
+
+// Sent when display switches to player application
+void CWMPEventDispatch::SwitchedToPlayerApplication()
+{
+}
+
+// Sent when display switches to control
+void CWMPEventDispatch::SwitchedToControl()
+{
+}
+
+// Sent when the player docks or undocks
+void CWMPEventDispatch::PlayerDockedStateChange()
+{
+}
+
+// Sent when the OCX reconnects to the player
+void CWMPEventDispatch::PlayerReconnect()
+{
+}
+
+// Occurs when a user clicks the mouse
+void CWMPEventDispatch::Click( short nButton, short nShiftState, long fX, long fY )
+{
+ if ( IsFullScreen() )
+ {
+ SetFullScreen( false );
+ }
+}
+
+// Occurs when a user double-clicks the mouse
+void CWMPEventDispatch::DoubleClick( short nButton, short nShiftState, long fX, long fY )
+{
+ // the controls are just drawn into the main window, wheras the video has its own window
+ // this check allows us to only fullscreen on doubleclick within the video area
+ POINT pt = { fX, fY };
+ HWND hWnd = g_pFrame->ChildWindowFromPoint( pt );
+ if ( ChildWindowFromPoint( hWnd, pt ) != hWnd )
+ {
+ SetFullScreen( !IsFullScreen() );
+ }
+}
+
+// Occurs when a key is pressed
+void CWMPEventDispatch::KeyDown( short nKeyCode, short nShiftState )
+{
+#if 1
+ if ( !g_pFrame )
+ return;
+
+ BOOL rval;
+ if ( nShiftState & 4 ) // 4 is the alt keymask
+ {
+ g_pFrame->OnSysKeyDown( WM_KEYDOWN, nKeyCode, 0, rval );
+ }
+ else
+ {
+ g_pFrame->OnKeyDown( WM_KEYDOWN, nKeyCode, 0, rval );
+ }
+#endif
+}
+
+// Occurs when a key is pressed and released
+void CWMPEventDispatch::KeyPress( short nKeyAscii )
+{
+ return;
+}
+
+// Occurs when a key is released
+void CWMPEventDispatch::KeyUp( short nKeyCode, short nShiftState )
+{
+ return;
+}
+
+// Occurs when a mouse button is pressed
+void CWMPEventDispatch::MouseDown( short nButton, short nShiftState, long fX, long fY )
+{
+}
+
+// Occurs when a mouse pointer is moved
+void CWMPEventDispatch::MouseMove( short nButton, short nShiftState, long fX, long fY )
+{
+ return;
+}
+
+// Occurs when a mouse button is released
+void CWMPEventDispatch::MouseUp( short nButton, short nShiftState, long fX, long fY )
+{
+}
diff --git a/utils/smp/CWMPEventDispatch.h b/utils/smp/CWMPEventDispatch.h
new file mode 100644
index 0000000..7ceecff
--- /dev/null
+++ b/utils/smp/CWMPEventDispatch.h
@@ -0,0 +1,102 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+// CWMPEventDispatch.h : Declaration of the event dispatcher
+//
+
+#pragma once
+
+#include "stdafx.h"
+
+// if these files aren't found, set your path to include the wmp sdk include directory
+// download the sdk from http://www.microsoft.com/windows/windowsmedia/mp10/sdk.aspx
+#include "wmpids.h"
+#include "wmp.h"
+
+class CWMPEventDispatch:
+ public CComObjectRootEx<CComSingleThreadModel>,
+ public IWMPEvents,
+ public _WMPOCXEvents
+ {
+public:
+
+ BEGIN_COM_MAP(CWMPEventDispatch)
+ COM_INTERFACE_ENTRY(_WMPOCXEvents)
+ COM_INTERFACE_ENTRY(IWMPEvents)
+ COM_INTERFACE_ENTRY(IDispatch)
+ END_COM_MAP()
+
+ // IDispatch methods
+ STDMETHOD(GetIDsOfNames)( REFIID riid,
+ OLECHAR FAR *FAR *rgszNames,
+ unsigned int cNames,
+ LCID lcid,
+ DISPID FAR *rgDispId )
+ { return( E_NOTIMPL ); }
+
+ STDMETHOD(GetTypeInfo)( unsigned int iTInfo,
+ LCID lcid,
+ ITypeInfo FAR *FAR *ppTInfo )
+ { return( E_NOTIMPL ); }
+
+ STDMETHOD(GetTypeInfoCount)( unsigned int FAR *pctinfo )
+ {
+ return( E_NOTIMPL );
+ }
+
+ STDMETHOD(Invoke)( DISPID dispIdMember,
+ REFIID riid,
+ LCID lcid,
+ WORD wFlags,
+ DISPPARAMS FAR* pDispParams,
+ VARIANT FAR* pVarResult,
+ EXCEPINFO FAR* pExcepInfo,
+ unsigned int FAR* puArgErr );
+
+ // IWMPEvents methods
+ void STDMETHODCALLTYPE OpenStateChange( long NewState );
+ void STDMETHODCALLTYPE PlayStateChange( long NewState );
+ void STDMETHODCALLTYPE AudioLanguageChange( long LangID );
+ void STDMETHODCALLTYPE StatusChange();
+ void STDMETHODCALLTYPE ScriptCommand( BSTR scType, BSTR Param );
+ void STDMETHODCALLTYPE NewStream();
+ void STDMETHODCALLTYPE Disconnect( long Result );
+ void STDMETHODCALLTYPE Buffering( VARIANT_BOOL Start );
+ void STDMETHODCALLTYPE Error();
+ void STDMETHODCALLTYPE Warning( long WarningType, long Param, BSTR Description );
+ void STDMETHODCALLTYPE EndOfStream( long Result );
+ void STDMETHODCALLTYPE PositionChange( double oldPosition, double newPosition);
+ void STDMETHODCALLTYPE MarkerHit( long MarkerNum );
+ void STDMETHODCALLTYPE DurationUnitChange( long NewDurationUnit );
+ void STDMETHODCALLTYPE CdromMediaChange( long CdromNum );
+ void STDMETHODCALLTYPE PlaylistChange( IDispatch * Playlist, WMPPlaylistChangeEventType change );
+ void STDMETHODCALLTYPE CurrentPlaylistChange( WMPPlaylistChangeEventType change );
+ void STDMETHODCALLTYPE CurrentPlaylistItemAvailable( BSTR bstrItemName );
+ void STDMETHODCALLTYPE MediaChange( IDispatch * Item );
+ void STDMETHODCALLTYPE CurrentMediaItemAvailable( BSTR bstrItemName );
+ void STDMETHODCALLTYPE CurrentItemChange( IDispatch *pdispMedia);
+ void STDMETHODCALLTYPE MediaCollectionChange();
+ void STDMETHODCALLTYPE MediaCollectionAttributeStringAdded( BSTR bstrAttribName, BSTR bstrAttribVal );
+ void STDMETHODCALLTYPE MediaCollectionAttributeStringRemoved( BSTR bstrAttribName, BSTR bstrAttribVal );
+ void STDMETHODCALLTYPE MediaCollectionAttributeStringChanged( BSTR bstrAttribName, BSTR bstrOldAttribVal, BSTR bstrNewAttribVal);
+ void STDMETHODCALLTYPE PlaylistCollectionChange();
+ void STDMETHODCALLTYPE PlaylistCollectionPlaylistAdded( BSTR bstrPlaylistName);
+ void STDMETHODCALLTYPE PlaylistCollectionPlaylistRemoved( BSTR bstrPlaylistName);
+ void STDMETHODCALLTYPE PlaylistCollectionPlaylistSetAsDeleted( BSTR bstrPlaylistName, VARIANT_BOOL varfIsDeleted);
+ void STDMETHODCALLTYPE ModeChange( BSTR ModeName, VARIANT_BOOL NewValue);
+ void STDMETHODCALLTYPE MediaError( IDispatch * pMediaObject);
+ void STDMETHODCALLTYPE OpenPlaylistSwitch( IDispatch *pItem );
+ void STDMETHODCALLTYPE DomainChange( BSTR strDomain);
+ void STDMETHODCALLTYPE SwitchedToPlayerApplication();
+ void STDMETHODCALLTYPE SwitchedToControl();
+ void STDMETHODCALLTYPE PlayerDockedStateChange();
+ void STDMETHODCALLTYPE PlayerReconnect();
+ void STDMETHODCALLTYPE Click( short nButton, short nShiftState, long fX, long fY );
+ void STDMETHODCALLTYPE DoubleClick( short nButton, short nShiftState, long fX, long fY );
+ void STDMETHODCALLTYPE KeyDown( short nKeyCode, short nShiftState );
+ void STDMETHODCALLTYPE KeyPress( short nKeyAscii );
+ void STDMETHODCALLTYPE KeyUp( short nKeyCode, short nShiftState );
+ void STDMETHODCALLTYPE MouseDown( short nButton, short nShiftState, long fX, long fY );
+ void STDMETHODCALLTYPE MouseMove( short nButton, short nShiftState, long fX, long fY );
+ void STDMETHODCALLTYPE MouseUp( short nButton, short nShiftState, long fX, long fY );
+};
+
+typedef CComObject<CWMPEventDispatch> CComWMPEventDispatch; \ No newline at end of file
diff --git a/utils/smp/CWMPHost.cpp b/utils/smp/CWMPHost.cpp
new file mode 100644
index 0000000..c5b2cb1
--- /dev/null
+++ b/utils/smp/CWMPHost.cpp
@@ -0,0 +1,603 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+// CWMPHost.cpp : Implementation of the CWMPHost
+//
+
+#include "stdafx.h"
+#include "CWMPHost.h"
+#include <cstdio>
+#include <assert.h>
+#include <string>
+
+
+extern HWND g_hBlackFadingWindow;
+extern CWMPHost*g_pFrame;
+extern LPTSTR g_lpCommandLine;
+extern bool g_bFrameCreated;
+extern double g_timeAtFadeStart;
+extern bool g_bFadeIn;
+extern bool g_bFadeWindowTriggered;
+extern std::string g_URL;
+
+bool ShowFadeWindow( bool bShow );
+void LogPlayerEvent( EventType_t e, float pos );
+
+
+CComPtr<IWMPPlayer> g_spWMPPlayer;
+bool g_bWantToBeFullscreen = false;
+bool g_bPlayOnRestore = false;
+int g_desiredVideoScaleMode = ID_STRETCH_TO_FIT;
+
+
+#define MAX_STRING 1024
+
+bool FAILMSG(HRESULT hr)
+{
+ if (FAILED(hr))
+ {
+ TCHAR szError[MAX_STRING];
+
+ ::wsprintf(szError, _T("Error code = %08X"), hr);
+ ::MessageBox(NULL, szError, _T("Error"), MB_OK | MB_ICONERROR);
+ }
+
+ return FAILED(hr);
+}
+
+void LogPlayerEvent( EventType_t e )
+{
+ double dpos = 0.0f;
+
+ CComPtr<IWMPControls> spWMPControls;
+ if ( g_spWMPPlayer )
+ {
+ g_spWMPPlayer->get_controls(&spWMPControls);
+ if ( spWMPControls )
+ {
+ spWMPControls->get_currentPosition( &dpos );
+ }
+ }
+
+ LogPlayerEvent( e, ( float )dpos );
+}
+
+bool IsStretchedToFit()
+{
+ if ( !g_spWMPPlayer )
+ return false;
+
+ CComPtr< IWMPPlayer2 > spWMPPlayer2;
+ g_spWMPPlayer.QueryInterface( &spWMPPlayer2 );
+ if ( !spWMPPlayer2 )
+ return false;
+
+ VARIANT_BOOL vbStretchToFit = VARIANT_FALSE;
+ spWMPPlayer2->get_stretchToFit( &vbStretchToFit );
+ return vbStretchToFit == VARIANT_TRUE;
+}
+
+bool SetVideoScaleMode( int videoScaleMode )
+{
+ g_desiredVideoScaleMode = videoScaleMode;
+
+ if ( !g_spWMPPlayer )
+ return false;
+
+ long width = 0, height = 0;
+ CComPtr<IWMPMedia> spWMPMedia;
+ g_spWMPPlayer->get_currentMedia( &spWMPMedia );
+ if ( spWMPMedia )
+ {
+ spWMPMedia->get_imageSourceWidth ( &width );
+ spWMPMedia->get_imageSourceHeight( &height );
+ }
+
+ VARIANT_BOOL vbStretchToFit = VARIANT_FALSE;
+ switch ( videoScaleMode )
+ {
+ case ID_HALF_SIZE:
+ // TODO - set video player size
+ break;
+ case ID_FULL_SIZE:
+ // TODO - set video player size
+ break;
+ case ID_DOUBLE_SIZE:
+ // TODO - set video player size
+ break;
+
+ case ID_STRETCH_TO_FIT:
+ vbStretchToFit = VARIANT_TRUE;
+ break;
+
+ default:
+ return false;
+ }
+
+ CComPtr< IWMPPlayer2 > spWMPPlayer2;
+ g_spWMPPlayer.QueryInterface( &spWMPPlayer2 );
+ if ( !spWMPPlayer2 )
+ return false;
+
+ bool bStretchToFit = vbStretchToFit == VARIANT_TRUE;
+ if ( bStretchToFit == IsStretchedToFit() )
+ return true;
+
+ spWMPPlayer2->put_stretchToFit( vbStretchToFit );
+
+ return bStretchToFit == IsStretchedToFit();
+}
+
+bool IsFullScreen()
+{
+ if ( !g_spWMPPlayer )
+ return false;
+
+ VARIANT_BOOL vbFullscreen = VARIANT_TRUE;
+ g_spWMPPlayer->get_fullScreen( &vbFullscreen );
+ return vbFullscreen == VARIANT_TRUE;
+}
+
+bool SetFullScreen( bool bWantToBeFullscreen )
+{
+ g_bWantToBeFullscreen = bWantToBeFullscreen;
+
+ if ( !g_spWMPPlayer )
+ return false;
+
+ LogPlayerEvent( bWantToBeFullscreen ? ET_MAXIMIZE : ET_RESTORE );
+
+ bool bIsFullscreen = IsFullScreen();
+
+ CComPtr<IWMPPlayer2> spWMPPlayer2;
+ HRESULT hr = g_spWMPPlayer.QueryInterface(&spWMPPlayer2);
+ if ( hr != S_OK )
+ {
+ assert( spWMPPlayer2 == NULL ); // the MS documentation claims this shouldn't happen, but it does...
+ spWMPPlayer2 = NULL;
+ }
+
+ if ( spWMPPlayer2 )
+ {
+ VARIANT_BOOL vbStretch = VARIANT_TRUE;
+ spWMPPlayer2->get_stretchToFit( &vbStretch );
+ bool bStretch = vbStretch == VARIANT_TRUE;
+ if ( bStretch != g_bWantToBeFullscreen )
+ {
+ bIsFullscreen = !g_bWantToBeFullscreen;
+ }
+ }
+
+ if ( g_bWantToBeFullscreen == bIsFullscreen )
+ return true;
+
+ if ( g_bWantToBeFullscreen )
+ {
+ g_spWMPPlayer->put_uiMode(L"none");
+
+ g_spWMPPlayer->put_fullScreen(VARIANT_TRUE);
+
+ if ( spWMPPlayer2 )
+ {
+ spWMPPlayer2->put_stretchToFit( VARIANT_TRUE );
+ }
+
+ while ( ShowCursor( FALSE ) >= 0 )
+ ;
+ }
+ else
+ {
+ g_spWMPPlayer->put_fullScreen(VARIANT_FALSE);
+
+ g_spWMPPlayer->put_uiMode(L"full");
+
+ if ( spWMPPlayer2 )
+ {
+ spWMPPlayer2->put_stretchToFit( g_desiredVideoScaleMode == ID_STRETCH_TO_FIT ? VARIANT_TRUE : VARIANT_FALSE );
+ }
+
+ g_pFrame->ShowWindow( SW_RESTORE );
+
+ while ( ShowCursor( TRUE ) < 0 )
+ ;
+ }
+
+ bIsFullscreen = IsFullScreen();
+
+ if ( bIsFullscreen != g_bWantToBeFullscreen )
+ {
+ g_bWantToBeFullscreen = bIsFullscreen;
+ OutputDebugString( "SetFullScreen FAILED!\n" );
+ return false;
+ }
+
+ if ( spWMPPlayer2 )
+ {
+ if ( g_bWantToBeFullscreen )
+ {
+ VARIANT_BOOL vbStretch = VARIANT_TRUE;
+ spWMPPlayer2->get_stretchToFit( &vbStretch );
+ if ( vbStretch != VARIANT_TRUE )
+ {
+ OutputDebugString( "SetFullScreen FAILED to set stretchToFit!\n" );
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool IsVideoPlaying()
+{
+ WMPPlayState playState;
+ g_spWMPPlayer->get_playState(&playState);
+ return playState == wmppsPlaying;
+}
+
+void PlayVideo( bool bPlay )
+{
+ CComPtr<IWMPControls> spWMPControls;
+ g_spWMPPlayer->get_controls(&spWMPControls);
+ if ( spWMPControls )
+ {
+ if ( bPlay )
+ {
+ spWMPControls->play();
+ }
+ else
+ {
+ spWMPControls->pause();
+ }
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CWMPHost
+
+LRESULT CWMPHost::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ AtlAxWinInit();
+ CComPtr<IAxWinHostWindow> spHost;
+ CComPtr<IConnectionPointContainer> spConnectionContainer;
+ CComWMPEventDispatch *pEventListener = NULL;
+ CComPtr<IWMPEvents> spEventListener;
+ HRESULT hr;
+ RECT rcClient;
+
+ m_dwAdviseCookie = 0;
+ m_hPopupMenu = 0;
+
+ // create window
+
+ GetClientRect(&rcClient);
+ m_wndView.Create(m_hWnd, rcClient, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN, WS_EX_CLIENTEDGE);
+ if (NULL == m_wndView.m_hWnd)
+ goto FAILURE;
+
+ // load OCX in window
+
+ hr = m_wndView.QueryHost(&spHost);
+ if (FAILMSG(hr))
+ goto FAILURE;
+
+ hr = spHost->CreateControl(CComBSTR(_T("{6BF52A52-394A-11d3-B153-00C04F79FAA6}")), m_wndView, 0);
+ if (FAILMSG(hr))
+ goto FAILURE;
+
+ hr = m_wndView.QueryControl(&g_spWMPPlayer);
+ if (FAILMSG(hr))
+ goto FAILURE;
+
+ // start listening to events
+
+ hr = CComWMPEventDispatch::CreateInstance(&pEventListener);
+ spEventListener = pEventListener;
+ if (FAILMSG(hr))
+ goto FAILURE;
+
+ hr = g_spWMPPlayer->QueryInterface(&spConnectionContainer);
+ if (FAILMSG(hr))
+ goto FAILURE;
+
+ // See if OCX supports the IWMPEvents interface
+ hr = spConnectionContainer->FindConnectionPoint(__uuidof(IWMPEvents), &m_spConnectionPoint);
+ if (FAILED(hr))
+ {
+ // If not, try the _WMPOCXEvents interface, which will use IDispatch
+ hr = spConnectionContainer->FindConnectionPoint(__uuidof(_WMPOCXEvents), &m_spConnectionPoint);
+ if (FAILMSG(hr))
+ goto FAILURE;
+ }
+
+ hr = m_spConnectionPoint->Advise(spEventListener, &m_dwAdviseCookie);
+ if (FAILMSG(hr))
+ goto FAILURE;
+
+ IWMPSettings *spWMPSettings;
+ g_spWMPPlayer->get_settings( &spWMPSettings );
+ if ( spWMPSettings )
+ {
+ spWMPSettings->put_volume( 100 );
+ }
+
+ g_spWMPPlayer->put_enableContextMenu( VARIANT_FALSE );
+
+ // set the url of the movie
+ hr = g_spWMPPlayer->put_URL( CT2W( g_URL.c_str() ) );
+ if (FAILED(hr))
+ OutputDebugString( "put_URL failed\n" );
+
+ return 0;
+
+FAILURE:
+ OutputDebugString( "CWMPHost::OnCreate FAILED!\n" );
+ DestroyWindow();
+ if ( g_hBlackFadingWindow )
+ {
+ ::DestroyWindow( g_hBlackFadingWindow );
+ }
+// ::PostQuitMessage(0);
+ return 0;
+}
+
+LRESULT CWMPHost::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ LogPlayerEvent( ET_CLOSE );
+
+ DestroyWindow();
+ if ( g_hBlackFadingWindow )
+ {
+ ::DestroyWindow( g_hBlackFadingWindow );
+ }
+
+ return 0;
+}
+
+LRESULT CWMPHost::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ // stop listening to events
+ if (m_spConnectionPoint)
+ {
+ if (0 != m_dwAdviseCookie)
+ m_spConnectionPoint->Unadvise(m_dwAdviseCookie);
+ m_spConnectionPoint.Release();
+ }
+
+ // close the OCX
+ if (g_spWMPPlayer)
+ {
+ g_spWMPPlayer->close();
+ g_spWMPPlayer.Release();
+ }
+
+ m_hWnd = NULL;
+ g_bFrameCreated = false;
+
+ bHandled = FALSE;
+ return 1;
+}
+
+LRESULT CWMPHost::OnErase(UINT /* uMsg */, WPARAM /* wParam */, LPARAM /* lParam */, BOOL& bHandled)
+{
+ if ( g_bWantToBeFullscreen && !IsFullScreen() )
+ {
+ g_pFrame->BringWindowToTop();
+ SetFullScreen( false );
+ }
+
+ bHandled = TRUE;
+ return 0;
+}
+
+LRESULT CWMPHost::OnSize(UINT /* uMsg */, WPARAM wParam, LPARAM lParam, BOOL& /* lResult */)
+{
+ if ( wParam == SIZE_MAXIMIZED )
+ {
+ SetFullScreen( true );
+ }
+ else
+ {
+ if ( wParam == SIZE_MINIMIZED )
+ {
+ LogPlayerEvent( ET_MINIMIZE );
+ if ( IsVideoPlaying() )
+ {
+ g_bPlayOnRestore = true;
+ PlayVideo( false );
+ }
+ }
+ else if ( wParam == SIZE_RESTORED )
+ {
+ LogPlayerEvent( ET_RESTORE );
+ }
+
+ RECT rcClient;
+ GetClientRect(&rcClient);
+ m_wndView.MoveWindow(rcClient.left, rcClient.top, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top);
+ }
+
+ return 0;
+}
+
+LRESULT CWMPHost::OnContextMenu(UINT /* uMsg */, WPARAM /* wParam */, LPARAM lParam, BOOL& /* lResult */)
+{
+ if ( !m_hPopupMenu )
+ {
+ m_hPopupMenu = CreatePopupMenu();
+// AppendMenu( m_hPopupMenu, MF_STRING, ID_HALF_SIZE, "Zoom 50%" );
+ AppendMenu( m_hPopupMenu, MF_STRING, ID_FULL_SIZE, "Zoom 100%" );
+// AppendMenu( m_hPopupMenu, MF_STRING, ID_DOUBLE_SIZE, "Zoom 200%" );
+ AppendMenu( m_hPopupMenu, MF_STRING, ID_STRETCH_TO_FIT, "Stretch to fit window" );
+ }
+
+ int x = GET_X_LPARAM( lParam );
+ int y = GET_Y_LPARAM( lParam );
+ TrackPopupMenu( m_hPopupMenu, TPM_LEFTALIGN | TPM_TOPALIGN, x, y, 0, m_hWnd, NULL );
+
+ return 0;
+}
+
+LRESULT CWMPHost::OnClick(UINT /* uMsg */, WPARAM /* wParam */, LPARAM /* lParam */, BOOL& /* lResult */)
+{
+ if ( IsFullScreen() )
+ {
+ SetFullScreen( false );
+ }
+ return 1;
+}
+
+LRESULT CWMPHost::OnLeftDoubleClick(UINT /* uMsg */, WPARAM /* wParam */, LPARAM /* lParam */, BOOL& /* lResult */)
+{
+ SetFullScreen( !IsFullScreen() );
+ return 1;
+}
+
+LRESULT CWMPHost::OnSysKeyDown(UINT /* uMsg */, WPARAM wParam, LPARAM /* lParam */, BOOL& /* lResult */)
+{
+ switch ( wParam )
+ {
+ case VK_RETURN:
+ SetFullScreen( !IsFullScreen() );
+ break;
+ }
+
+ return 1;
+}
+
+LRESULT CWMPHost::OnKeyDown(UINT /* uMsg */, WPARAM wParam, LPARAM /* lParam */, BOOL& /* lResult */)
+{
+ switch ( wParam )
+ {
+ case VK_SPACE:
+ PlayVideo( !IsVideoPlaying() );
+ break;
+
+ case VK_LEFT:
+ case VK_RIGHT:
+ {
+ CComPtr<IWMPControls> spWMPControls;
+ g_spWMPPlayer->get_controls(&spWMPControls);
+ if ( !spWMPControls )
+ break;
+
+ CComPtr<IWMPControls2> spWMPControls2;
+ spWMPControls.QueryInterface(&spWMPControls2);
+ if ( !spWMPControls2 )
+ break;
+
+ spWMPControls2->step( wParam == VK_LEFT ? -1 : 1 );
+
+ LogPlayerEvent( wParam == VK_LEFT ? ET_STEPBCK : ET_STEPFWD );
+ }
+ break;
+
+ case VK_UP:
+ case VK_DOWN:
+ {
+ CComPtr<IWMPControls> spWMPControls;
+ g_spWMPPlayer->get_controls(&spWMPControls);
+ if ( !spWMPControls )
+ break;
+
+ double curpos = 0.0f;
+ if ( spWMPControls->get_currentPosition( &curpos ) != S_OK )
+ break;
+
+ curpos += wParam == VK_UP ? -5.0f : 5.0f;
+
+ spWMPControls->put_currentPosition( curpos );
+ if ( !IsVideoPlaying() )
+ {
+ spWMPControls->play();
+ spWMPControls->pause();
+ }
+
+ LogPlayerEvent( wParam == VK_UP ? ET_JUMPBCK : ET_JUMPFWD );
+ }
+ break;
+
+ case VK_HOME:
+ {
+ CComPtr<IWMPControls> spWMPControls;
+ g_spWMPPlayer->get_controls(&spWMPControls);
+ if ( !spWMPControls )
+ break;
+
+ spWMPControls->put_currentPosition( 0.0f );
+ if ( !IsVideoPlaying() )
+ {
+ spWMPControls->play();
+ spWMPControls->pause();
+ }
+
+ LogPlayerEvent( ET_JUMPHOME );
+ }
+ break;
+
+ case VK_END:
+ {
+ CComPtr<IWMPMedia> spWMPMedia;
+ g_spWMPPlayer->get_currentMedia( &spWMPMedia );
+ if ( !spWMPMedia )
+ break;
+
+ CComPtr<IWMPControls> spWMPControls;
+ g_spWMPPlayer->get_controls(&spWMPControls);
+ if ( !spWMPControls )
+ break;
+
+ double duration = 0.0f;
+ if ( spWMPMedia->get_duration( &duration ) != S_OK )
+ break;
+
+ spWMPControls->put_currentPosition( duration - 0.050 ); // back a little more than a frame - this avoids triggering the end fade
+ spWMPControls->play();
+ spWMPControls->pause();
+
+ LogPlayerEvent( ET_JUMPEND );
+ }
+ break;
+
+ case VK_ESCAPE:
+ if ( IsFullScreen() && !g_bFadeWindowTriggered )
+ {
+ CComPtr<IWMPControls> spWMPControls;
+ g_spWMPPlayer->get_controls(&spWMPControls);
+ if ( spWMPControls )
+ {
+ spWMPControls->stop();
+ }
+
+ LogPlayerEvent( ET_FADEOUT );
+
+ g_bFadeWindowTriggered = true;
+ ShowFadeWindow( true );
+ }
+ break;
+ }
+
+ return 0;
+}
+
+LRESULT CWMPHost::OnNCActivate(UINT /* uMsg */, WPARAM wParam, LPARAM /* lParam */, BOOL& /* lResult */ )
+{
+ if ( wParam )
+ {
+ if ( g_bWantToBeFullscreen )
+ {
+ SetFullScreen( true );
+ }
+ if ( g_bPlayOnRestore )
+ {
+ g_bPlayOnRestore = false;
+ PlayVideo( true );
+ }
+ }
+
+ return 1;
+}
+
+LRESULT CWMPHost::OnVideoScale(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
+{
+ SetVideoScaleMode( wID );
+ return 0;
+}
diff --git a/utils/smp/CWMPHost.h b/utils/smp/CWMPHost.h
new file mode 100644
index 0000000..f417bac
--- /dev/null
+++ b/utils/smp/CWMPHost.h
@@ -0,0 +1,94 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+// CWMPHost.h : Declaration of the CWMPHost
+//
+
+#include "resource.h" // main symbols
+#include <oledlg.h>
+
+// if this file isn't found, set your path to include the wmp sdk include directory
+// download the sdk from http://www.microsoft.com/windows/windowsmedia/mp10/sdk.aspx
+#include "wmp.h"
+#include "CWMPEventDispatch.h"
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CWMPHost
+
+class CWMPHost : public CWindowImpl< CWMPHost, CWindow, CWinTraits< WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE > >
+{
+public:
+ DECLARE_WND_CLASS_EX(NULL, 0, 0)
+
+ BEGIN_MSG_MAP(CWMPHost)
+ MESSAGE_HANDLER(WM_CREATE, OnCreate)
+ MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
+ MESSAGE_HANDLER(WM_CLOSE, OnClose)
+ MESSAGE_HANDLER(WM_SIZE, OnSize)
+ MESSAGE_HANDLER(WM_CONTEXTMENU, OnContextMenu)
+ MESSAGE_HANDLER(WM_LBUTTONDOWN, OnClick)
+ MESSAGE_HANDLER(WM_MBUTTONDOWN, OnClick)
+ MESSAGE_HANDLER(WM_RBUTTONDOWN, OnClick)
+ MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLeftDoubleClick)
+ MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
+ MESSAGE_HANDLER(WM_SYSKEYDOWN, OnSysKeyDown)
+ MESSAGE_HANDLER(WM_ERASEBKGND, OnErase)
+ MESSAGE_HANDLER(WM_NCACTIVATE, OnNCActivate)
+
+ COMMAND_ID_HANDLER(ID_HALF_SIZE, OnVideoScale)
+ COMMAND_ID_HANDLER(ID_FULL_SIZE, OnVideoScale)
+ COMMAND_ID_HANDLER(ID_DOUBLE_SIZE, OnVideoScale)
+ COMMAND_ID_HANDLER(ID_STRETCH_TO_FIT, OnVideoScale)
+ END_MSG_MAP()
+
+ LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+ LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+ LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+ LRESULT OnErase(UINT /* uMsg */, WPARAM /* wParam */, LPARAM /* lParam */, BOOL& bHandled);
+ LRESULT OnSize(UINT /* uMsg */, WPARAM /* wParam */, LPARAM /* lParam */, BOOL& /* lResult */);
+ LRESULT OnContextMenu(UINT /* uMsg */, WPARAM /* wParam */, LPARAM /* lParam */, BOOL& /* lResult */);
+ LRESULT OnClick(UINT /* uMsg */, WPARAM /* wParam */, LPARAM /* lParam */, BOOL& /* lResult */);
+ LRESULT OnLeftDoubleClick(UINT /* uMsg */, WPARAM /* wParam */, LPARAM /* lParam */, BOOL& /* lResult */);
+ LRESULT OnSysKeyDown(UINT /* uMsg */, WPARAM wParam, LPARAM /* lParam */, BOOL& /* lResult */);
+ LRESULT OnKeyDown(UINT /* uMsg */, WPARAM wParam, LPARAM /* lParam */, BOOL& /* lResult */);
+ LRESULT OnNCActivate(UINT /* uMsg */, WPARAM wParam, LPARAM /* lParam */, BOOL& /* lResult */);
+
+ LRESULT OnVideoScale(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
+
+ CAxWindow m_wndView;
+ CComPtr<IConnectionPoint> m_spConnectionPoint;
+ DWORD m_dwAdviseCookie;
+ HMENU m_hPopupMenu;
+};
+
+
+/////////////////////////////////////////////////////////////////////////////
+// event logging - this should really be in its own smp.h or something...
+
+enum EventType_t
+{
+ ET_APPLAUNCH,
+ ET_APPEXIT,
+ ET_CLOSE,
+ ET_FADEOUT,
+
+ ET_MEDIABEGIN,
+ ET_MEDIAEND,
+
+ ET_JUMPHOME,
+ ET_JUMPEND,
+
+ ET_PLAY,
+ ET_PAUSE,
+ ET_STOP,
+ ET_SCRUBFROM,
+ ET_SCRUBTO,
+ ET_STEPFWD,
+ ET_STEPBCK,
+ ET_JUMPFWD,
+ ET_JUMPBCK,
+ ET_REPEAT,
+
+ ET_MAXIMIZE,
+ ET_MINIMIZE,
+ ET_RESTORE,
+};
diff --git a/utils/smp/IceKey.H b/utils/smp/IceKey.H
new file mode 100644
index 0000000..d6590f4
--- /dev/null
+++ b/utils/smp/IceKey.H
@@ -0,0 +1,65 @@
+//========= Public Domain Code ================================================
+//
+// Purpose: Header file for the C++ ICE encryption class.
+// Taken from public domain code, as written by Matthew Kwan - July 1996
+// http://www.darkside.com.au/ice/
+//=============================================================================
+
+#ifndef _IceKey_H
+#define _IceKey_H
+
+/*
+The IceKey class is used for encrypting and decrypting 64-bit blocks of data
+with the ICE (Information Concealment Engine) encryption algorithm.
+
+The constructor creates a new IceKey object that can be used to encrypt and decrypt data.
+The level of encryption determines the size of the key, and hence its speed.
+Level 0 uses the Thin-ICE variant, which is an 8-round cipher taking an 8-byte key.
+This is the fastest option, and is generally considered to be at least as secure as DES,
+although it is not yet certain whether it is as secure as its key size.
+
+For levels n greater than zero, a 16n-round cipher is used, taking 8n-byte keys.
+Although not as fast as level 0, these are very very secure.
+
+Before an IceKey can be used to encrypt data, its key schedule must be set with the set() member function.
+The length of the key required is determined by the level, as described above.
+
+The member functions encrypt() and decrypt() encrypt and decrypt respectively data
+in blocks of eight chracters, using the specified key.
+
+Two functions keySize() and blockSize() are provided
+which return the key and block size respectively, measured in bytes.
+The key size is determined by the level, while the block size is always 8.
+
+The destructor zeroes out and frees up all memory associated with the key.
+*/
+
+class IceSubkey;
+
+class IceKey {
+ public:
+ IceKey (int n);
+ ~IceKey ();
+
+ void set (const unsigned char *key);
+
+ void encrypt (const unsigned char *plaintext,
+ unsigned char *ciphertext) const;
+
+ void decrypt (const unsigned char *ciphertext,
+ unsigned char *plaintext) const;
+
+ int keySize () const;
+
+ int blockSize () const;
+
+ private:
+ void scheduleBuild (unsigned short *k, int n,
+ const int *keyrot);
+
+ int _size;
+ int _rounds;
+ IceSubkey *_keysched;
+};
+
+#endif
diff --git a/utils/smp/IceKey.cpp b/utils/smp/IceKey.cpp
new file mode 100644
index 0000000..ef3bbbd
--- /dev/null
+++ b/utils/smp/IceKey.cpp
@@ -0,0 +1,392 @@
+//========= Public Domain Code ================================================
+//
+// Purpose: C++ implementation of the ICE encryption algorithm.
+// Taken from public domain code, as written by Matthew Kwan - July 1996
+// http://www.darkside.com.au/ice/
+//=============================================================================
+
+#include "IceKey.H"
+
+#pragma warning(disable: 4244)
+
+
+ /* Structure of a single round subkey */
+class IceSubkey {
+ public:
+ unsigned long val[3];
+};
+
+
+ /* The S-boxes */
+static unsigned long ice_sbox[4][1024];
+static int ice_sboxes_initialised = 0;
+
+
+ /* Modulo values for the S-boxes */
+static const int ice_smod[4][4] = {
+ {333, 313, 505, 369},
+ {379, 375, 319, 391},
+ {361, 445, 451, 397},
+ {397, 425, 395, 505}};
+
+ /* XOR values for the S-boxes */
+static const int ice_sxor[4][4] = {
+ {0x83, 0x85, 0x9b, 0xcd},
+ {0xcc, 0xa7, 0xad, 0x41},
+ {0x4b, 0x2e, 0xd4, 0x33},
+ {0xea, 0xcb, 0x2e, 0x04}};
+
+ /* Permutation values for the P-box */
+static const unsigned long ice_pbox[32] = {
+ 0x00000001, 0x00000080, 0x00000400, 0x00002000,
+ 0x00080000, 0x00200000, 0x01000000, 0x40000000,
+ 0x00000008, 0x00000020, 0x00000100, 0x00004000,
+ 0x00010000, 0x00800000, 0x04000000, 0x20000000,
+ 0x00000004, 0x00000010, 0x00000200, 0x00008000,
+ 0x00020000, 0x00400000, 0x08000000, 0x10000000,
+ 0x00000002, 0x00000040, 0x00000800, 0x00001000,
+ 0x00040000, 0x00100000, 0x02000000, 0x80000000};
+
+ /* The key rotation schedule */
+static const int ice_keyrot[16] = {
+ 0, 1, 2, 3, 2, 1, 3, 0,
+ 1, 3, 2, 0, 3, 1, 0, 2};
+
+
+/*
+ * 8-bit Galois Field multiplication of a by b, modulo m.
+ * Just like arithmetic multiplication, except that additions and
+ * subtractions are replaced by XOR.
+ */
+
+static unsigned int
+gf_mult (
+ register unsigned int a,
+ register unsigned int b,
+ register unsigned int m
+) {
+ register unsigned int res = 0;
+
+ while (b) {
+ if (b & 1)
+ res ^= a;
+
+ a <<= 1;
+ b >>= 1;
+
+ if (a >= 256)
+ a ^= m;
+ }
+
+ return (res);
+}
+
+
+/*
+ * Galois Field exponentiation.
+ * Raise the base to the power of 7, modulo m.
+ */
+
+static unsigned long
+gf_exp7 (
+ register unsigned int b,
+ unsigned int m
+) {
+ register unsigned int x;
+
+ if (b == 0)
+ return (0);
+
+ x = gf_mult (b, b, m);
+ x = gf_mult (b, x, m);
+ x = gf_mult (x, x, m);
+ return (gf_mult (b, x, m));
+}
+
+
+/*
+ * Carry out the ICE 32-bit P-box permutation.
+ */
+
+static unsigned long
+ice_perm32 (
+ register unsigned long x
+) {
+ register unsigned long res = 0;
+ register const unsigned long *pbox = ice_pbox;
+
+ while (x) {
+ if (x & 1)
+ res |= *pbox;
+ pbox++;
+ x >>= 1;
+ }
+
+ return (res);
+}
+
+
+/*
+ * Initialise the ICE S-boxes.
+ * This only has to be done once.
+ */
+
+static void
+ice_sboxes_init (void)
+{
+ register int i;
+
+ for (i=0; i<1024; i++) {
+ int col = (i >> 1) & 0xff;
+ int row = (i & 0x1) | ((i & 0x200) >> 8);
+ unsigned long x;
+
+ x = gf_exp7 (col ^ ice_sxor[0][row], ice_smod[0][row]) << 24;
+ ice_sbox[0][i] = ice_perm32 (x);
+
+ x = gf_exp7 (col ^ ice_sxor[1][row], ice_smod[1][row]) << 16;
+ ice_sbox[1][i] = ice_perm32 (x);
+
+ x = gf_exp7 (col ^ ice_sxor[2][row], ice_smod[2][row]) << 8;
+ ice_sbox[2][i] = ice_perm32 (x);
+
+ x = gf_exp7 (col ^ ice_sxor[3][row], ice_smod[3][row]);
+ ice_sbox[3][i] = ice_perm32 (x);
+ }
+}
+
+
+/*
+ * Create a new ICE key.
+ */
+
+IceKey::IceKey (int n)
+{
+ if (!ice_sboxes_initialised) {
+ ice_sboxes_init ();
+ ice_sboxes_initialised = 1;
+ }
+
+ if (n < 1) {
+ _size = 1;
+ _rounds = 8;
+ } else {
+ _size = n;
+ _rounds = n * 16;
+ }
+
+ _keysched = new IceSubkey[_rounds];
+}
+
+
+/*
+ * Destroy an ICE key.
+ */
+
+IceKey::~IceKey ()
+{
+ int i, j;
+
+ for (i=0; i<_rounds; i++)
+ for (j=0; j<3; j++)
+ _keysched[i].val[j] = 0;
+
+ _rounds = _size = 0;
+
+ delete[] _keysched;
+}
+
+
+/*
+ * The single round ICE f function.
+ */
+
+static unsigned long
+ice_f (
+ register unsigned long p,
+ const IceSubkey *sk
+) {
+ unsigned long tl, tr; /* Expanded 40-bit values */
+ unsigned long al, ar; /* Salted expanded 40-bit values */
+
+ /* Left half expansion */
+ tl = ((p >> 16) & 0x3ff) | (((p >> 14) | (p << 18)) & 0xffc00);
+
+ /* Right half expansion */
+ tr = (p & 0x3ff) | ((p << 2) & 0xffc00);
+
+ /* Perform the salt permutation */
+ // al = (tr & sk->val[2]) | (tl & ~sk->val[2]);
+ // ar = (tl & sk->val[2]) | (tr & ~sk->val[2]);
+ al = sk->val[2] & (tl ^ tr);
+ ar = al ^ tr;
+ al ^= tl;
+
+ al ^= sk->val[0]; /* XOR with the subkey */
+ ar ^= sk->val[1];
+
+ /* S-box lookup and permutation */
+ return (ice_sbox[0][al >> 10] | ice_sbox[1][al & 0x3ff]
+ | ice_sbox[2][ar >> 10] | ice_sbox[3][ar & 0x3ff]);
+}
+
+
+/*
+ * Encrypt a block of 8 bytes of data with the given ICE key.
+ */
+
+void
+IceKey::encrypt (
+ const unsigned char *ptext,
+ unsigned char *ctext
+) const
+{
+ register int i;
+ register unsigned long l, r;
+
+ l = (((unsigned long) ptext[0]) << 24)
+ | (((unsigned long) ptext[1]) << 16)
+ | (((unsigned long) ptext[2]) << 8) | ptext[3];
+ r = (((unsigned long) ptext[4]) << 24)
+ | (((unsigned long) ptext[5]) << 16)
+ | (((unsigned long) ptext[6]) << 8) | ptext[7];
+
+ for (i = 0; i < _rounds; i += 2) {
+ l ^= ice_f (r, &_keysched[i]);
+ r ^= ice_f (l, &_keysched[i + 1]);
+ }
+
+ for (i = 0; i < 4; i++) {
+ ctext[3 - i] = r & 0xff;
+ ctext[7 - i] = l & 0xff;
+
+ r >>= 8;
+ l >>= 8;
+ }
+}
+
+
+/*
+ * Decrypt a block of 8 bytes of data with the given ICE key.
+ */
+
+void
+IceKey::decrypt (
+ const unsigned char *ctext,
+ unsigned char *ptext
+) const
+{
+ register int i;
+ register unsigned long l, r;
+
+ l = (((unsigned long) ctext[0]) << 24)
+ | (((unsigned long) ctext[1]) << 16)
+ | (((unsigned long) ctext[2]) << 8) | ctext[3];
+ r = (((unsigned long) ctext[4]) << 24)
+ | (((unsigned long) ctext[5]) << 16)
+ | (((unsigned long) ctext[6]) << 8) | ctext[7];
+
+ for (i = _rounds - 1; i > 0; i -= 2) {
+ l ^= ice_f (r, &_keysched[i]);
+ r ^= ice_f (l, &_keysched[i - 1]);
+ }
+
+ for (i = 0; i < 4; i++) {
+ ptext[3 - i] = r & 0xff;
+ ptext[7 - i] = l & 0xff;
+
+ r >>= 8;
+ l >>= 8;
+ }
+}
+
+
+/*
+ * Set 8 rounds [n, n+7] of the key schedule of an ICE key.
+ */
+
+void
+IceKey::scheduleBuild (
+ unsigned short *kb,
+ int n,
+ const int *keyrot
+) {
+ int i;
+
+ for (i=0; i<8; i++) {
+ register int j;
+ register int kr = keyrot[i];
+ IceSubkey *isk = &_keysched[n + i];
+
+ for (j=0; j<3; j++)
+ isk->val[j] = 0;
+
+ for (j=0; j<15; j++) {
+ register int k;
+ unsigned long *curr_sk = &isk->val[j % 3];
+
+ for (k=0; k<4; k++) {
+ unsigned short *curr_kb = &kb[(kr + k) & 3];
+ register int bit = *curr_kb & 1;
+
+ *curr_sk = (*curr_sk << 1) | bit;
+ *curr_kb = (*curr_kb >> 1) | ((bit ^ 1) << 15);
+ }
+ }
+ }
+}
+
+
+/*
+ * Set the key schedule of an ICE key.
+ */
+
+void
+IceKey::set (
+ const unsigned char *key
+) {
+ int i;
+
+ if (_rounds == 8) {
+ unsigned short kb[4];
+
+ for (i=0; i<4; i++)
+ kb[3 - i] = (key[i*2] << 8) | key[i*2 + 1];
+
+ scheduleBuild (kb, 0, ice_keyrot);
+ return;
+ }
+
+ for (i=0; i<_size; i++) {
+ int j;
+ unsigned short kb[4];
+
+ for (j=0; j<4; j++)
+ kb[3 - j] = (key[i*8 + j*2] << 8) | key[i*8 + j*2 + 1];
+
+ scheduleBuild (kb, i*8, ice_keyrot);
+ scheduleBuild (kb, _rounds - 8 - i*8, &ice_keyrot[8]);
+ }
+}
+
+
+/*
+ * Return the key size, in bytes.
+ */
+
+int
+IceKey::keySize () const
+{
+ return (_size * 8);
+}
+
+
+/*
+ * Return the block size, in bytes.
+ */
+
+int
+IceKey::blockSize () const
+{
+ return (8);
+}
diff --git a/utils/smp/StdAfx.h b/utils/smp/StdAfx.h
new file mode 100644
index 0000000..649ec17
--- /dev/null
+++ b/utils/smp/StdAfx.h
@@ -0,0 +1,45 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently,
+// but are changed infrequently
+//
+// This is a part of the Active Template Library.
+// Copyright (C) 1996-1998 Microsoft Corporation
+// All rights reserved.
+//
+// This source code is only intended as a supplement to the
+// Active Template Library Reference and related
+// electronic documentation provided with the library.
+// See these sources for detailed information regarding the
+// Active Template Library product.
+
+#if !defined(AFX_STDAFX_H__48C9E972_76B0_11D1_B293_0040053089AE__INCLUDED_)
+#define AFX_STDAFX_H__48C9E972_76B0_11D1_B293_0040053089AE__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#ifndef STRICT
+#define STRICT
+#endif
+
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0501
+#endif
+#define _ATL_APARTMENT_THREADED
+
+
+#include <atlbase.h>
+
+extern CComModule _Module;
+
+#include <atlcom.h>
+#include <atlhost.h>
+#include <atlctl.h>
+#include <afxres.h>
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_STDAFX_H__48C9E972_76B0_11D1_B293_0040053089AE__INCLUDED)
diff --git a/utils/smp/resource.h b/utils/smp/resource.h
new file mode 100644
index 0000000..c1a3a6b
--- /dev/null
+++ b/utils/smp/resource.h
@@ -0,0 +1,62 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by smp.rc
+//
+#define IDS_PROJNAME 100
+#define IDR_SMP 100
+#define IDD_FILEOPEN_DIALOG 201
+#define IDC_FILEOPEN_EDIT 201
+#define IDR_MENU1 202
+#define IDC_FILEOPEN_BROWSE 202
+#define IDC_STRING_EDIT 203
+#define IDI_ICON1 204
+#define IDC_BOOLEAN_TRUE 204
+#define IDD_STRING_DIALOG 205
+#define IDC_BOOLEAN_FALSE 205
+#define IDD_BOOLEAN_DIALOG 206
+#define IDI_ICON 207
+#define ID_WMPCORE 32800
+#define ID_WMPCORE_CLOSE 32801
+#define ID_WMPCORE_URL 32802
+#define ID_WMPCORE_OPENSTATE 32803
+#define ID_WMPCORE_PLAYSTATE 32804
+#define ID_WMPCORE_CONTROLS 32805
+#define ID_WMPCORE_SETTINGS 32806
+#define ID_WMPCORE_CURRENTMEDIA 32807
+#define ID_WMPCORE_MEDIACOLLECTION 32808
+#define ID_WMPCORE_PLAYLISTCOLLECTION 32809
+#define ID_WMPCORE_VERSIONINFO 32810
+#define ID_WMPCORE_LAUNCHURL 32811
+#define ID_WMPCORE_NETWORK 32812
+#define ID_WMPCORE_CURRENTPLAYLIST 32813
+#define ID_WMPCORE_CDROMCOLLECTION 32814
+#define ID_WMPCORE_CLOSEDCAPTION 32815
+#define ID_WMPCORE_ISONLINE 32816
+#define ID_WMPCORE_ERROR 32817
+#define ID_WMPCORE_STATUS 32818
+#define ID_WMPCORE2 32819
+#define ID_WMPCORE2_DVD 32820
+#define ID_WMPPLAYER 32900
+#define ID_WMPPLAYER_ENABLED 32901
+#define ID_WMPPLAYER_FULLSCREEN 32902
+#define ID_WMPPLAYER_ENABLECONTEXTMENU 32903
+#define ID_WMPPLAYER_UIMODE 32904
+#define ID_WMPPLAYER2 32905
+#define ID_WMPPLAYER2_STRETCHTOFIT 32906
+
+#define ID_HALF_SIZE 33000
+#define ID_FULL_SIZE 33001
+#define ID_DOUBLE_SIZE 33002
+#define ID_STRETCH_TO_FIT 33003
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 208
+#define _APS_NEXT_COMMAND_VALUE 32907
+#define _APS_NEXT_CONTROL_VALUE 205
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/utils/smp/smp.cpp b/utils/smp/smp.cpp
new file mode 100644
index 0000000..fb30df9
--- /dev/null
+++ b/utils/smp/smp.cpp
@@ -0,0 +1,1441 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+// smp.cpp : Main window procedure
+//
+
+#include "stdafx.h"
+#include "resource.h"
+#include "initguid.h"
+#include "CWMPHost.h"
+#include <commctrl.h>
+#include <windows.h>
+#include <psapi.h>
+#include <math.h>
+#include <cstdio>
+#include <vector>
+#include <string>
+#include <strstream>
+#include <fstream>
+
+
+#include "IceKey.h"
+
+
+CComModule _Module;
+
+BEGIN_OBJECT_MAP(ObjectMap)
+END_OBJECT_MAP()
+
+
+#define ID_SKIP_FADE_TIMER 1
+#define ID_DRAW_TIMER 2
+
+
+const float FADE_TIME = 1.0f;
+const int MAX_BLUR_STEPS = 100;
+
+HINSTANCE g_hInstance;
+HWND g_hBlackFadingWindow = 0;
+bool g_bFadeIn = true;
+bool g_bFrameCreated = false;
+CWMPHost g_frame;
+CWMPHost *g_pFrame = NULL;
+HDC g_hdcCapture = 0;
+HDC g_hdcBlend = 0;
+HBITMAP g_hbmCapture = 0;
+HBITMAP g_hbmBlend = 0;
+HMONITOR g_hMonitor = 0;
+
+int g_screenWidth = 0;
+int g_screenHeight = 0;
+
+LPTSTR g_lpCommandLine = NULL;
+std::string g_redirectTarget;
+std::string g_URL;
+bool g_bReportStats = false;
+bool g_bUseLocalSteamServer = false;
+
+double g_timeAtFadeStart = 0.0;
+int g_nBlurSteps = 0;
+
+
+void LogPlayerEvent( EventType_t e );
+
+
+enum OSVersion
+{
+ OSV_95,
+ OSV_95OSR2,
+ OSV_98,
+ OSV_98SE,
+ OSV_ME,
+ OSV_NT4,
+ OSV_2000,
+ OSV_SERVER2003,
+ OSV_XP,
+ OSV_XPSP1,
+ OSV_XPSP2,
+ OSV_XPSP3,
+ OSV_VISTA,
+ OSV_UNKNOWN,
+};
+
+OSVersion DetectOSVersion()
+{
+ OSVERSIONINFO version;
+ version.dwOSVersionInfoSize = sizeof( version );
+ GetVersionEx( &version );
+ if ( version.dwPlatformId & VER_PLATFORM_WIN32_WINDOWS )
+ {
+ if ( version.dwMajorVersion != 4 )
+ return OSV_UNKNOWN;
+
+ switch ( version.dwMinorVersion )
+ {
+ case 0:
+ return strstr( version.szCSDVersion, _TEXT( " C" ) ) == version.szCSDVersion ? OSV_95OSR2 : OSV_95;
+ case 10:
+ return ( strstr( version.szCSDVersion, _TEXT( " A" ) ) == version.szCSDVersion ) || ( strstr( version.szCSDVersion, _TEXT( " B" ) ) == version.szCSDVersion ) ? OSV_98SE : OSV_98;
+ case 90:
+ return OSV_ME;
+ }
+ }
+ else if ( version.dwPlatformId & VER_PLATFORM_WIN32_NT )
+ {
+ if ( version.dwMajorVersion == 4 )
+ return OSV_NT4; // or mabye NT3.5???
+
+ if ( version.dwMajorVersion == 6 )
+ return OSV_VISTA;
+
+ if ( version.dwMajorVersion != 5 )
+ return OSV_UNKNOWN;
+
+ switch ( version.dwMinorVersion )
+ {
+ case 0:
+ return OSV_2000;
+ case 1:
+ {
+ if ( version.szCSDVersion == NULL )
+ return OSV_XP;
+
+ if ( strstr( version.szCSDVersion, _TEXT( "Service Pack 1" ) ) != NULL )
+ return OSV_XPSP1;
+
+ if ( strstr( version.szCSDVersion, _TEXT( "Service Pack 2" ) ) != NULL )
+ return OSV_XPSP2;
+
+ if ( strstr( version.szCSDVersion, _TEXT( "Service Pack 3" ) ) != NULL )
+ return OSV_XPSP3;
+ }
+ case 2:
+ return OSV_SERVER2003; // or maybe XP64???
+ }
+ }
+
+ return OSV_UNKNOWN;
+}
+
+const OSVersion g_osVersion = DetectOSVersion();
+
+
+
+#define BLUR
+
+#define USE_D3D8
+#ifdef USE_D3D8
+
+#include <d3d8.h>
+IDirect3D8* g_pD3D = NULL;
+IDirect3DDevice8* g_pd3dDevice = NULL;
+IDirect3DVertexBuffer8* g_pDrawVB = NULL;
+IDirect3DTexture8* g_pImg = NULL;
+int g_nDrawStride = 0;
+DWORD g_dwDrawFVF = 0;
+
+#ifdef BLUR
+
+int g_nBlurStride = 0;
+DWORD g_dwBlurFVF = 0;
+IDirect3DVertexBuffer8* g_pBlurVB = NULL;
+IDirect3DTexture8* g_pTex = NULL;
+IDirect3DTexture8* g_pRT = NULL;
+IDirect3DSurface8* g_pBackBuf = NULL;
+
+#endif // BLUR
+
+#endif // USE_D3D8
+
+
+DWORD g_dwUseVMROverlayOldValue = 0;
+bool g_bUseVMROverlayValueExists = false;
+
+
+void SetRegistryValue( const char *pKeyName, const char *pValueName, DWORD dwValue, DWORD &dwOldValue, bool &bValueExisted )
+{
+ HKEY hKey = 0;
+ LONG rval = RegCreateKeyEx( HKEY_CURRENT_USER, pKeyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL );
+ if ( rval != ERROR_SUCCESS )
+ {
+ OutputDebugString( "unable to open registry key: " );
+ OutputDebugString( pKeyName );
+ OutputDebugString( "\n" );
+ return;
+ }
+
+ DWORD dwType = 0;
+ DWORD dwSize = sizeof( dwOldValue );
+
+ // amusingly enough, if pValueName doesn't exist, RegQueryValueEx returns ERROR_FILE_NOT_FOUND
+ rval = RegQueryValueEx( hKey, pValueName, NULL, &dwType, ( LPBYTE )&dwOldValue, &dwSize );
+ bValueExisted = ( rval == ERROR_SUCCESS );
+
+ rval = RegSetValueEx( hKey, pValueName, 0, REG_DWORD, ( CONST BYTE* )&dwValue, sizeof( dwValue ) );
+ if ( rval != ERROR_SUCCESS )
+ {
+ OutputDebugString( "unable to write registry value " );
+ OutputDebugString( pValueName );
+ OutputDebugString( " in key " );
+ OutputDebugString( pKeyName );
+ OutputDebugString( "\n" );
+ }
+
+ RegCloseKey( hKey );
+}
+
+void RestoreRegistryValue( const char *pKeyName, const char *pValueName, DWORD dwOldValue, bool bValueExisted )
+{
+ HKEY hKey = 0;
+ LONG rval = RegCreateKeyEx( HKEY_CURRENT_USER, pKeyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL );
+ if ( rval != ERROR_SUCCESS )
+ {
+ OutputDebugString( "unable to open registry key: " );
+ OutputDebugString( pKeyName );
+ OutputDebugString( "\n" );
+ return;
+ }
+
+ if ( bValueExisted )
+ {
+ rval = RegSetValueEx( hKey, pValueName, 0, REG_DWORD, ( CONST BYTE* )&dwOldValue, sizeof( dwOldValue ) );
+ }
+ else
+ {
+ rval = RegDeleteValue( hKey, pValueName );
+ }
+ if ( rval != ERROR_SUCCESS )
+ {
+ OutputDebugString( "SetRegistryValue FAILED!\n" );
+ }
+
+ RegCloseKey( hKey );
+}
+
+bool GetRegistryString( const char *pKeyName, const char *pValueName, const char *pValueString, int nValueLen )
+{
+ HKEY hKey = 0;
+ LONG rval = RegCreateKeyEx( HKEY_CURRENT_USER, pKeyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL );
+ if ( rval != ERROR_SUCCESS )
+ {
+ OutputDebugString( "unable to open registry key: " );
+ OutputDebugString( pKeyName );
+ OutputDebugString( "\n" );
+ return false;
+ }
+
+ DWORD dwType = 0;
+ rval = RegQueryValueEx( hKey, pValueName, NULL, &dwType, ( LPBYTE )pValueString, ( DWORD* )&nValueLen );
+
+ RegCloseKey( hKey );
+
+ if ( rval != ERROR_SUCCESS || dwType != REG_SZ )
+ {
+ OutputDebugString( "unable to read registry string: " );
+ OutputDebugString( pValueName );
+ OutputDebugString( "\n" );
+ return false;
+ }
+
+ return true;
+}
+
+struct EventData_t
+{
+ EventData_t( int t, float pos, EventType_t e )
+ : time( t ), position( pos ), event( e )
+ {
+ }
+ int time; // real time
+ float position; // movie position
+ EventType_t event; // event type
+};
+
+const char *GetEventName( EventType_t event )
+{
+ switch ( event )
+ {
+ case ET_APPLAUNCH: return "al";
+ case ET_APPEXIT: return "ae";
+ case ET_CLOSE: return "cl";
+ case ET_FADEOUT: return "fo";
+
+ case ET_MEDIABEGIN: return "mb";
+ case ET_MEDIAEND: return "me";
+
+ case ET_JUMPHOME: return "jh";
+ case ET_JUMPEND: return "je";
+
+ case ET_PLAY: return "pl";
+ case ET_PAUSE: return "ps";
+ case ET_STOP: return "st";
+ case ET_SCRUBFROM: return "jf";
+ case ET_SCRUBTO: return "jt";
+ case ET_STEPFWD: return "sf";
+ case ET_STEPBCK: return "sb";
+ case ET_JUMPFWD: return "jf";
+ case ET_JUMPBCK: return "jb";
+ case ET_REPEAT: return "rp";
+
+ case ET_MAXIMIZE: return "mx";
+ case ET_MINIMIZE: return "mn";
+ case ET_RESTORE: return "rs";
+
+ default: return "<unknown>";
+ }
+}
+
+std::vector< EventData_t > g_events;
+
+void LogPlayerEvent( EventType_t e, float pos )
+{
+ if ( !g_bReportStats )
+ return;
+
+ static int s_firstTick = GetTickCount();
+ int time = GetTickCount() - s_firstTick;
+
+#if 0
+ char msg[ 256 ];
+ sprintf( msg, "event %s at time %d and pos %d\n", GetEventName( e ), time, int( 1000 * pos ) );
+ OutputDebugString( msg );
+#endif
+
+ bool bDropEvent = false;
+
+ int nEvents = g_events.size();
+ if ( ( e == ET_STEPFWD || e == ET_STEPBCK ) && nEvents >= 2 )
+ {
+ const EventData_t &e1 = g_events[ nEvents - 1 ];
+ const EventData_t &e2 = g_events[ nEvents - 2 ];
+ if ( ( e1.event == e || e1.event == ET_REPEAT ) && e2.event == e )
+ {
+ // only store starting and ending stepfwd or stepbck events, since there can be so many
+ // also keep events that are more than a second apart
+ if ( e1.event == ET_REPEAT )
+ {
+ // keep dropping events while e1 isn't before a gap
+ bDropEvent = time - e1.time < 1000;
+ }
+ else
+ {
+ // e2 was kept last time, so keep e1 if e2 was kept because it was before a gap
+ bDropEvent = e1.time - e2.time < 1000;
+ }
+ }
+ }
+
+ if ( bDropEvent )
+ {
+ g_events[ nEvents - 1 ] = EventData_t( time, pos, ET_REPEAT );
+ }
+ else
+ {
+ g_events.push_back( EventData_t( time, pos, e ) );
+ }
+}
+
+char C2M_UPLOADDATA = 'q';
+char C2M_UPLOADDATA_PROTOCOL_VERSION = 1;
+char C2M_UPLOADDATA_DATA_VERSION = 1;
+
+inline void WriteHexDigit( std::ostream &os, byte src )
+{
+ os.put( ( src <= 9 ) ? src + '0' : src - 10 + 'A' );
+}
+
+inline void WriteByte( std::ostream &os, byte src )
+{
+ WriteHexDigit( os, src >> 4 );
+ WriteHexDigit( os, src & 0xf );
+}
+
+inline void WriteShort( std::ostream &os, unsigned short src )
+{
+ WriteByte( os, ( byte )( ( src >> 8 ) & 0xff ) );
+ WriteByte( os, ( byte )( src & 0xff ) );
+}
+
+inline void WriteInt24( std::ostream &os, int src )
+{
+ WriteByte( os, ( byte )( ( src >> 16 ) & 0xff ) );
+ WriteByte( os, ( byte )( ( src >> 8 ) & 0xff ) );
+ WriteByte( os, ( byte )( src & 0xff ) );
+}
+
+inline void WriteInt( std::ostream &os, int src )
+{
+ WriteByte( os, ( byte )( ( src >> 24 ) & 0xff ) );
+ WriteByte( os, ( byte )( ( src >> 16 ) & 0xff ) );
+ WriteByte( os, ( byte )( ( src >> 8 ) & 0xff ) );
+ WriteByte( os, ( byte )( src & 0xff ) );
+}
+
+inline void WriteFloat( std::ostream &os, float src )
+{
+ WriteInt( os, *( int* )&src );
+}
+
+void WriteUUID( std::ostream &os, const UUID &uuid )
+{
+ WriteInt( os, uuid.Data1 );
+ WriteShort( os, uuid.Data2 );
+ WriteShort( os, uuid.Data3 );
+ for ( int i = 0; i < 8; ++i )
+ {
+ WriteByte( os, uuid.Data4[ i ] );
+ }
+}
+
+bool QueryOrGenerateUserID( UUID &userId )
+{
+ HKEY hKey = 0;
+ LONG rval = RegCreateKeyEx( HKEY_CURRENT_USER, "Software\\Valve\\Steam", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL );
+ if ( rval != ERROR_SUCCESS )
+ {
+ UuidCreate( &userId );
+ return false;
+ }
+
+ DWORD dwType = 0;
+ unsigned char idstr[ 40 ];
+ DWORD dwSize = sizeof( idstr );
+
+ rval = RegQueryValueEx( hKey, "smpid", NULL, &dwType, ( LPBYTE )idstr, &dwSize );
+ if ( rval != ERROR_SUCCESS || dwType != REG_SZ )
+ {
+ UuidCreate( &userId );
+
+ unsigned char *outstring = NULL;
+ UuidToString( &userId, &outstring );
+ if ( outstring == NULL || *outstring == '\0' )
+ {
+ RegCloseKey( hKey );
+ return false;
+ }
+
+ rval = RegSetValueEx( hKey, "smpid", 0, REG_SZ, ( CONST BYTE* )outstring, sizeof( idstr ) );
+
+ RpcStringFree( &outstring );
+ RegCloseKey( hKey );
+
+ return rval == ERROR_SUCCESS;
+ }
+
+ if ( RPC_S_OK != UuidFromString( idstr, &userId ) )
+ return false;
+
+ RegCloseKey( hKey );
+ return true;
+}
+
+void PrintStats( const char *pStatsFilename )
+{
+ std::ofstream os( pStatsFilename, std::ios_base::out | std::ios_base::binary );
+
+ // user id
+ UUID userId;
+ QueryOrGenerateUserID( userId );
+ unsigned char *userIdStr;
+ UuidToStringA( &userId, &userIdStr );
+ os << userIdStr << "\n";
+ RpcStringFree( &userIdStr );
+
+ // filename
+ int nOffset = g_URL.find_last_of( "/\\" );
+ if ( nOffset == g_URL.npos )
+ nOffset = 0;
+ std::string filename = g_URL.substr( nOffset + 1 );
+ os << filename << '\n';
+
+ // number of events
+ int nEvents = g_events.size();
+ os << nEvents << "\n";
+
+ // event data (tab-delimited)
+ for ( int i = 0; i < nEvents; ++i )
+ {
+ os << GetEventName( g_events[ i ].event ) << "\t";
+ os << g_events[ i ].time << "\t";
+ os << int( 1000 * g_events[ i ].position ) << "\n";
+ }
+}
+
+void UploadStats()
+{
+ char pathname[ 256 ];
+ if ( !GetRegistryString( "Software\\Valve\\Steam", "SteamExe", pathname, sizeof( pathname ) ) )
+ return;
+
+ char *pExeName = strrchr( pathname, '/' );
+ if ( !pExeName )
+ return;
+
+ *pExeName = '\0'; // truncate exe filename to just pathname
+
+ char filename[ 256 ];
+ sprintf( filename, "%s/smpstats.txt", pathname );
+
+ PrintStats( filename );
+
+ ::ShellExecuteA( NULL, "open", "steam://smp/smpstats.txt", NULL, NULL, SW_SHOWNORMAL );
+}
+
+void RestoreRegistry()
+{
+ static bool s_bDone = false;
+ if ( s_bDone )
+ return;
+
+ s_bDone = true;
+ RestoreRegistryValue( "Software\\Microsoft\\MediaPlayer\\Preferences\\VideoSettings", "UseVMROverlay", g_dwUseVMROverlayOldValue, g_bUseVMROverlayValueExists );
+}
+
+
+#ifdef USE_D3D8
+
+void CleanupD3D()
+{
+ if ( g_pDrawVB )
+ {
+ g_pDrawVB->Release();
+ g_pDrawVB = NULL;
+ }
+ if ( g_pImg )
+ {
+ g_pImg->Release();
+ g_pImg = NULL;
+ }
+#ifdef BLUR
+ if ( g_pBackBuf )
+ {
+ g_pBackBuf->Release();
+ g_pBackBuf = NULL;
+ }
+ if ( g_pBlurVB )
+ {
+ g_pBlurVB->Release();
+ g_pBlurVB = NULL;
+ }
+ if ( g_pTex )
+ {
+ g_pTex->Release();
+ g_pTex = NULL;
+ }
+ if ( g_pRT )
+ {
+ g_pRT->Release();
+ g_pRT = NULL;
+ }
+#endif // BLUR
+ if ( g_pd3dDevice )
+ {
+ g_pd3dDevice->Release();
+ g_pd3dDevice = NULL;
+ }
+ if ( g_pD3D )
+ {
+ g_pD3D->Release();
+ g_pD3D = NULL;
+ }
+}
+
+void InitTextureStageState( int nStage, DWORD dwColorOp, DWORD dwColorArg1, DWORD dwColorArg2, DWORD dwColorArg0 = D3DTA_CURRENT )
+{
+ g_pd3dDevice->SetTextureStageState( nStage, D3DTSS_COLOROP, dwColorOp );
+ g_pd3dDevice->SetTextureStageState( nStage, D3DTSS_COLORARG1, dwColorArg1 );
+ g_pd3dDevice->SetTextureStageState( nStage, D3DTSS_COLORARG2, dwColorArg2 );
+ g_pd3dDevice->SetTextureStageState( nStage, D3DTSS_COLORARG0, dwColorArg0 );
+ g_pd3dDevice->SetTextureStageState( nStage, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
+ g_pd3dDevice->SetTextureStageState( nStage, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
+ g_pd3dDevice->SetTextureStageState( nStage, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );
+ g_pd3dDevice->SetTextureStageState( nStage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
+ g_pd3dDevice->SetTextureStageState( nStage, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
+}
+
+bool InitD3D( HWND hWnd, bool blur )
+{
+ g_pD3D = Direct3DCreate8( D3D_SDK_VERSION );
+ if ( !g_pD3D )
+ {
+ OutputDebugString( "Direct3DCreate8 FAILED!\n" );
+ CleanupD3D();
+ return false;
+ }
+
+ D3DDISPLAYMODE d3ddm;
+ bool bFound = false;
+ int nAdapters = g_pD3D->GetAdapterCount();
+ int nAdapterIndex = 0;
+ for ( ; nAdapterIndex < nAdapters; ++nAdapterIndex )
+ {
+ if ( g_pD3D->GetAdapterMonitor( nAdapterIndex ) == g_hMonitor )
+ {
+ if ( FAILED( g_pD3D->GetAdapterDisplayMode( nAdapterIndex, &d3ddm ) ) )
+ {
+ OutputDebugString( "GetAdapterDisplayMode FAILED!\n" );
+ CleanupD3D();
+ return false;
+ }
+
+ MONITORINFO mi;
+ mi.cbSize = sizeof( mi );
+ GetMonitorInfo( g_hMonitor, &mi );
+ bFound = true;
+ break;
+ }
+ }
+ if ( !bFound )
+ {
+ OutputDebugString( "Starting monitor not found when creating D3D device!\n" );
+ CleanupD3D();
+ return false;
+ }
+
+ D3DPRESENT_PARAMETERS d3dpp;
+ ZeroMemory( &d3dpp, sizeof( d3dpp ) );
+ d3dpp.BackBufferWidth = g_screenWidth;
+ d3dpp.BackBufferHeight = g_screenHeight;
+ d3dpp.BackBufferFormat = d3ddm.Format;
+ d3dpp.BackBufferCount = 1;
+ d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
+ d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ d3dpp.hDeviceWindow = NULL;
+ d3dpp.Windowed = FALSE;
+ d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
+ d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE;
+
+ if ( FAILED( g_pD3D->CreateDevice( nAdapterIndex, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice ) ) )
+ {
+ OutputDebugString( "CreateDevice FAILED!\n" );
+ CleanupD3D();
+ return false;
+ }
+
+ // create and fill vertex buffer(s)
+ float du = 0.5f / g_screenWidth;
+ float dv = 0.5f / g_screenHeight;
+ float u0 = du;
+ float u1 = 1.0f + du;
+ float v0 = dv;
+ float v1 = 1.0f + dv;
+ float drawverts[] =
+ { // x, y, z, u, v
+ -1, -1, 0, u0, v0,
+ -1, 1, 0, u0, v1,
+ 1, -1, 0, u1, v0,
+ 1, 1, 0, u1, v1,
+ };
+ g_dwDrawFVF = D3DFVF_XYZ | D3DFVF_TEX1;
+ g_nDrawStride = sizeof( drawverts ) / 4;
+
+ if ( FAILED( g_pd3dDevice->CreateVertexBuffer( sizeof( drawverts ), D3DUSAGE_WRITEONLY, g_dwDrawFVF, D3DPOOL_MANAGED, &g_pDrawVB ) ) )
+ {
+ OutputDebugString( "CreateVertexBuffer( g_pDrawVB ) FAILED!\n" );
+ CleanupD3D();
+ return false;
+ }
+
+ BYTE* pDrawVBMem;
+ if ( FAILED( g_pDrawVB->Lock( 0, sizeof( drawverts ), &pDrawVBMem, 0 ) ) )
+ {
+ OutputDebugString( "g_pDrawVB->Lock FAILED!\n" );
+ CleanupD3D();
+ return false;
+ }
+ memcpy( pDrawVBMem, drawverts, sizeof( drawverts ) );
+ g_pDrawVB->Unlock();
+
+ g_pd3dDevice->SetStreamSource( 0, g_pDrawVB, g_nDrawStride );
+ g_pd3dDevice->SetVertexShader( g_dwDrawFVF );
+#ifdef BLUR
+ if ( blur )
+ {
+ float f = 2.0f / ( 2.0f + sqrt( 2.0f ) );
+ float ds = 2.0f * f / g_screenWidth;
+ float dt = 2.0f * f / g_screenHeight;
+ float s0 = ( 0.5f - f ) / g_screenWidth;
+ float s1 = 1.0f + s0;
+ float t0 = ( 0.5f - f ) / g_screenHeight;
+ float t1 = 1.0f + t0;
+ float blurverts[] =
+ { // x, y, z, u, v
+ -1, -1, 0, s0, t1, s0+ds, t1, s0, t1+dt, s0+ds, t1+dt,
+ -1, 1, 0, s0, t0, s0+ds, t0, s0, t0+dt, s0+ds, t0+dt,
+ 1, -1, 0, s1, t1, s1+ds, t1, s1, t1+dt, s1+ds, t1+dt,
+ 1, 1, 0, s1, t0, s1+ds, t0, s1, t0+dt, s1+ds, t0+dt,
+ };
+ g_dwBlurFVF = D3DFVF_XYZ | D3DFVF_TEX4;
+ g_nBlurStride = sizeof( blurverts ) / 4;
+
+ if ( FAILED( g_pd3dDevice->CreateVertexBuffer( sizeof( blurverts ), D3DUSAGE_WRITEONLY, g_dwBlurFVF, D3DPOOL_MANAGED, &g_pBlurVB ) ) )
+ {
+ OutputDebugString( "CreateVertexBuffer( g_pBlurVB ) FAILED!\n" );
+ CleanupD3D();
+ return false;
+ }
+
+ BYTE* pBlurVBMem;
+ if ( FAILED( g_pBlurVB->Lock( 0, sizeof( blurverts ), &pBlurVBMem, 0 ) ) )
+ {
+ OutputDebugString( "g_pBlurVB->Lock FAILED!\n" );
+ CleanupD3D();
+ return false;
+ }
+ memcpy( pBlurVBMem, blurverts, sizeof( blurverts ) );
+ g_pBlurVB->Unlock();
+ }
+#endif // BLUR
+
+ // create and fill texture
+ if ( FAILED( g_pd3dDevice->CreateTexture( g_screenWidth, g_screenHeight, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &g_pImg ) ) )
+ {
+ OutputDebugString( "CreateTexture( g_pImg ) FAILED!\n" );
+ CleanupD3D();
+ return false;
+ }
+
+ D3DLOCKED_RECT lockedRect;
+ if ( FAILED( g_pImg->LockRect( 0, &lockedRect, NULL, 0 ) ) )
+ {
+ OutputDebugString( "g_pImg->LockRect FAILED!\n" );
+ CleanupD3D();
+ return false;
+ }
+
+ BITMAPINFO bitmapInfo;
+ bitmapInfo.bmiHeader.biSize = sizeof( bitmapInfo.bmiHeader );
+ bitmapInfo.bmiHeader.biWidth = g_screenWidth;
+ bitmapInfo.bmiHeader.biHeight = g_screenHeight;
+ bitmapInfo.bmiHeader.biPlanes = 1;
+ bitmapInfo.bmiHeader.biBitCount = 32;
+ bitmapInfo.bmiHeader.biCompression = BI_RGB;
+ bitmapInfo.bmiHeader.biSizeImage = 0;
+ bitmapInfo.bmiHeader.biXPelsPerMeter = 0;
+ bitmapInfo.bmiHeader.biYPelsPerMeter = 0;
+ bitmapInfo.bmiHeader.biClrUsed = 0;
+ bitmapInfo.bmiHeader.biClrImportant = 0;
+
+ if ( GetDIBits( g_hdcCapture, g_hbmCapture, 0, g_screenHeight, lockedRect.pBits, &bitmapInfo, DIB_RGB_COLORS ) != g_screenHeight )
+ {
+ OutputDebugString( "GetDIBits FAILED to get the full image!\n" );
+ }
+
+ g_pImg->UnlockRect( 0 );
+
+#ifdef BLUR
+ if ( blur )
+ {
+ if ( FAILED( g_pd3dDevice->CreateTexture( g_screenWidth, g_screenHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_pTex ) ) )
+ {
+ OutputDebugString( "CreateTexture( g_pTex ) FAILED!\n" );
+ CleanupD3D();
+ return false;
+ }
+
+ if ( FAILED( g_pd3dDevice->CreateTexture( g_screenWidth, g_screenHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_pRT ) ) )
+ {
+ OutputDebugString( "CreateTexture( g_pRT ) FAILED!\n" );
+ CleanupD3D();
+ return false;
+ }
+
+ IDirect3DSurface8 *pTexSurf = NULL;
+ g_pTex->GetSurfaceLevel( 0, &pTexSurf );
+ IDirect3DSurface8 *pImgSurf = NULL;
+ g_pImg->GetSurfaceLevel( 0, &pImgSurf );
+
+ RECT rect = { 0, 0, g_screenWidth, g_screenHeight };
+ POINT pt = { 0, 0 };
+ g_pd3dDevice->CopyRects( pImgSurf, &rect, 1, pTexSurf, &pt );
+
+ pTexSurf->Release();
+ pImgSurf->Release();
+ }
+#endif // BLUR
+
+ g_pd3dDevice->SetTexture( 0, g_pImg );
+
+ InitTextureStageState( 0, D3DTOP_MODULATE, D3DTA_TEXTURE, D3DTA_TFACTOR );
+#ifdef BLUR
+ if ( blur )
+ {
+ g_pd3dDevice->SetTexture( 0, g_pTex );
+// g_pd3dDevice->SetTexture( 1, g_pTex );
+// g_pd3dDevice->SetTexture( 2, g_pTex );
+// g_pd3dDevice->SetTexture( 3, g_pTex );
+
+ DWORD op = D3DTOP_DISABLE; // D3DTOP_MULTIPLYADD;
+ InitTextureStageState( 1, op, D3DTA_TEXTURE, D3DTA_TFACTOR, D3DTA_CURRENT );
+ InitTextureStageState( 2, op, D3DTA_TEXTURE, D3DTA_TFACTOR, D3DTA_CURRENT );
+ InitTextureStageState( 3, op, D3DTA_TEXTURE, D3DTA_TFACTOR, D3DTA_CURRENT );
+ }
+#endif // BLUR
+
+ return true;
+}
+
+void DrawD3DFade( BYTE fade, bool blur )
+{
+ if ( g_pd3dDevice )
+ {
+#ifdef BLUR
+ if ( g_pTex )
+ {
+ if ( blur )
+ {
+ IDirect3DSurface8 *pRTSurf = NULL;
+ g_pRT->GetSurfaceLevel( 0, &pRTSurf );
+ g_pd3dDevice->SetRenderTarget( pRTSurf, NULL );
+
+ if ( g_pBackBuf )
+ {
+ g_pBackBuf->Release();
+ g_pBackBuf = NULL;
+ }
+
+ g_pd3dDevice->BeginScene();
+
+ g_pd3dDevice->SetTexture( 0, g_pTex );
+ g_pd3dDevice->SetTexture( 1, g_pTex );
+ g_pd3dDevice->SetTexture( 2, g_pTex );
+ g_pd3dDevice->SetTexture( 3, g_pTex );
+
+ g_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_MULTIPLYADD );
+ g_pd3dDevice->SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_MULTIPLYADD );
+ g_pd3dDevice->SetTextureStageState( 3, D3DTSS_COLOROP, D3DTOP_MULTIPLYADD );
+
+ g_pd3dDevice->SetStreamSource( 0, g_pBlurVB, g_nBlurStride );
+ g_pd3dDevice->SetVertexShader( g_dwBlurFVF );
+
+ DWORD quarter = 0x3f | ( 0x3f << 8 ) | ( 0x3f << 16 ) | ( 0x3f << 24 );
+ g_pd3dDevice->SetRenderState( D3DRS_TEXTUREFACTOR, quarter );
+ g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
+
+ g_pd3dDevice->EndScene();
+
+ pRTSurf->Release();
+
+ g_pd3dDevice->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &g_pBackBuf );
+ g_pd3dDevice->SetRenderTarget( g_pBackBuf, NULL );
+
+ IDirect3DTexture8 *pTemp = g_pTex;
+ g_pTex = g_pRT;
+ g_pRT = pTemp;
+
+ g_pd3dDevice->SetTexture( 0, g_pTex );
+ g_pd3dDevice->SetTexture( 1, NULL );
+ g_pd3dDevice->SetTexture( 2, NULL );
+ g_pd3dDevice->SetTexture( 3, NULL );
+
+ g_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
+ g_pd3dDevice->SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_DISABLE );
+ g_pd3dDevice->SetTextureStageState( 3, D3DTSS_COLOROP, D3DTOP_DISABLE );
+
+ g_pd3dDevice->SetStreamSource( 0, g_pDrawVB, g_nDrawStride );
+ g_pd3dDevice->SetVertexShader( g_dwDrawFVF );
+ }
+ }
+#endif
+
+ g_pd3dDevice->BeginScene();
+
+ // DWORD factor = 0xff | ( fade << 8 ) | ( fade << 16 ) | ( fade << 24 );
+ DWORD factor = fade | ( fade << 8 ) | ( fade << 16 ) | ( fade << 24 );
+ g_pd3dDevice->SetRenderState( D3DRS_TEXTUREFACTOR, factor );
+ g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
+
+ g_pd3dDevice->EndScene();
+ g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
+ }
+}
+
+#endif // USE_D3D8
+
+int g_nTimingIndex = 0;
+double g_timings[ 65536 ];
+
+LRESULT CALLBACK WinProc( HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam )
+{
+ switch ( msg )
+ {
+ case WM_CREATE:
+ {
+ g_timeAtFadeStart = 0.0;
+ g_nBlurSteps = 0;
+
+ g_hBlackFadingWindow = hWnd;
+
+#ifndef USE_D3D8
+ MONITORINFO mi;
+ mi.cbSize = sizeof( mi );
+ if ( GetMonitorInfo( g_hMonitor, &mi ) )
+ {
+ SetWindowPos( hWnd, HWND_TOPMOST, mi.rcMonitor.left, mi.rcMonitor.top, mi.rcMonitor.right - mi.rcMonitor.left, mi.rcMonitor.bottom - mi.rcMonitor.top, 0 );
+ }
+#endif
+
+#ifdef USE_D3D8
+ InitD3D( hWnd, true );
+#endif // USE_D3D8
+ if ( !g_bFadeIn )
+ {
+ g_pFrame->ShowWindow( SW_HIDE );
+ g_pFrame->PostMessage( WM_DESTROY, 0, 0 );
+ }
+
+ InvalidateRect( hWnd, NULL, TRUE );
+
+ SetTimer( hWnd, ID_SKIP_FADE_TIMER, 1000, NULL ); // if the fade doesn't start in 1 second, then just jump to the video
+ SetTimer( hWnd, ID_DRAW_TIMER, 10, NULL ); // draw timer
+ }
+ break;
+
+#ifdef USE_D3D8
+ case WM_TIMER: // WM_ERASEBKGND:
+#else
+ case WM_TIMER: // WM_ERASEBKGND:
+// case WM_NCPAINT:
+#endif
+ if ( wparam == ID_DRAW_TIMER )
+ {
+ static LARGE_INTEGER s_nPerformanceFrequency;
+ if ( g_timeAtFadeStart == 0.0 )
+ {
+ LARGE_INTEGER nTimeAtFadeStart;
+ QueryPerformanceCounter( &nTimeAtFadeStart );
+ QueryPerformanceFrequency( &s_nPerformanceFrequency );
+ g_timeAtFadeStart = nTimeAtFadeStart.QuadPart / double( s_nPerformanceFrequency.QuadPart );
+
+ KillTimer( hWnd, ID_SKIP_FADE_TIMER );
+ SetTimer( hWnd, ID_SKIP_FADE_TIMER, 100 + UINT( FADE_TIME * 1000 ), NULL ); // restart skip fade timer and give it an extra 100ms to allow the fade to draw fully black once
+ }
+
+ LARGE_INTEGER time;
+ QueryPerformanceCounter( &time );
+ g_timings[ g_nTimingIndex++ ] = time.QuadPart / double( s_nPerformanceFrequency.QuadPart );
+ float dt = ( float )( time.QuadPart / double( s_nPerformanceFrequency.QuadPart ) - g_timeAtFadeStart );
+
+ bool bFadeFinished = dt >= FADE_TIME;
+ float fraction = bFadeFinished ? 1.0f : dt / FADE_TIME;
+/*
+ char str[ 256 ];
+ sprintf( str, "A - dt = %f\t time = %f \tfade_finished = %s\n", dt, g_timings[ g_nTimingIndex - 1 ], bFadeFinished ? "true" : "false" );
+ OutputDebugString( str );
+*/
+ bool blur = g_bFadeIn && ( int( fraction * MAX_BLUR_STEPS ) > g_nBlurSteps );
+ if ( blur )
+ {
+ ++g_nBlurSteps;
+ }
+
+ BYTE fade = BYTE( fraction * 255.999f );
+ if ( g_bFadeIn )
+ {
+ fade = 255 - fade;
+ }
+/*
+ char str[ 256 ];
+ sprintf( str, "fade = %d\n", fade );
+ OutputDebugString( str );
+*/
+#ifdef USE_D3D8
+ DrawD3DFade( fade, blur );
+#else // USE_D3D8
+// HDC hdc = GetDCEx( hWnd, ( HRGN )wparam, DCX_WINDOW | DCX_INTERSECTRGN );
+
+ if ( !PatBlt( g_hdcBlend, 0, 0, g_screenWidth, g_screenHeight, BLACKNESS ) )
+ {
+ OutputDebugString( "PatBlt FAILED!\n" );
+ }
+
+// fade = 128;
+ BLENDFUNCTION blendfunc = { AC_SRC_OVER, 0, fade, 0 };
+ if ( !::AlphaBlend( g_hdcBlend, 0, 0, g_screenWidth, g_screenHeight, g_hdcCapture, 0, 0, g_screenWidth, g_screenHeight, blendfunc ) )
+ {
+ OutputDebugString( "AlphaBlend FAILED!\n" );
+ }
+
+ if ( !BitBlt( ( HDC )wparam, 0, 0, g_screenWidth, g_screenHeight, g_hdcBlend, 0, 0, SRCCOPY ) )
+ {
+ OutputDebugString( "BitBlt FAILED!\n" );
+ }
+
+// ReleaseDC( hWnd, hdc );
+// RedrawWindow( hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE );
+#endif // USE_D3D8
+/*
+// char str[ 256 ];
+ sprintf( str, "B - dt = %f\t time = %f \tfade_finished = %s\n", dt, g_timings[ g_nTimingIndex - 1 ], bFadeFinished ? "true" : "false" );
+ OutputDebugString( str );
+*/
+ if ( !bFadeFinished )
+ break;
+
+ // fall-through intentional
+// OutputDebugString( "Fall-through from erase background\n" );
+ }
+
+// case WM_TIMER:
+ {
+ if ( msg == WM_TIMER )
+ {
+/*
+ char str[ 256 ];
+ sprintf( str, "Timer 0x%x triggered for window 0x%x\n", wparam, hWnd );
+ OutputDebugString( str );
+*/
+ if ( wparam == ID_DRAW_TIMER )
+ {
+// UpdateWindow( hWnd );
+// InvalidateRect( hWnd, NULL, TRUE );
+// break;
+ }
+ }
+
+ KillTimer( hWnd, ID_SKIP_FADE_TIMER );
+ KillTimer( hWnd, ID_DRAW_TIMER );
+
+ if ( !g_bFadeIn )
+ {
+// OutputDebugString( "closing fade window\n" );
+ ShowWindow( hWnd, SW_HIDE );
+ PostMessage( hWnd, WM_CLOSE, 0, 0 );
+ return 1;
+ }
+ else if ( !g_bFrameCreated )
+ {
+ g_bFrameCreated = true;
+#ifdef USE_D3D8
+// OutputDebugString( "Cleanup D3D\n" );
+ CleanupD3D();
+#endif
+ g_pFrame = &g_frame;
+ g_pFrame->GetWndClassInfo().m_wc.hIcon = LoadIcon( _Module.GetResourceInstance(), MAKEINTRESOURCE( IDI_ICON ) );
+ RECT rcPos = { CW_USEDEFAULT, 0, 0, 0 };
+
+// OutputDebugString( "Create WMP frame\n" );
+
+ if ( g_osVersion < OSV_XP )
+ {
+ g_pFrame->Create( GetDesktopWindow(), rcPos, _T( "Steam Media Player" ), WS_OVERLAPPEDWINDOW, 0, ( UINT )0 );
+ }
+ else
+ {
+ g_pFrame->Create( GetDesktopWindow(), rcPos, _T( "Steam Media Player" ), WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, ( UINT )0 );
+
+ g_pFrame->ShowWindow( SW_SHOW );
+ }
+
+// OutputDebugString( "Create WMP frame - done\n" );
+ }
+
+ // close WMP window once we paint the fullscreen fade window
+ if ( !g_bFadeIn )
+ {
+ g_pFrame->ShowWindow( SW_HIDE );
+ }
+ }
+ return 1;
+
+ case WM_KEYDOWN:
+ if ( wparam == VK_ESCAPE )
+ {
+ ::DestroyWindow( hWnd );
+ }
+ break;
+
+ case WM_DESTROY:
+ g_hBlackFadingWindow = NULL;
+
+#ifdef USE_D3D8
+ CleanupD3D();
+#endif
+
+ if ( g_bFrameCreated )
+ {
+ g_bFrameCreated = false;
+
+ g_pFrame->DestroyWindow();
+ g_pFrame = NULL;
+ }
+
+ ::PostQuitMessage( 0 );
+ break;
+ }
+
+ return DefWindowProc( hWnd, msg, wparam, lparam );
+}
+
+bool ShowFadeWindow( bool bShow )
+{
+ if ( bShow )
+ {
+ g_timeAtFadeStart = 0.0;
+ g_bFadeIn = false;
+
+ SetTimer( g_hBlackFadingWindow, ID_DRAW_TIMER, 10, NULL );
+
+ if ( g_pFrame )
+ {
+ g_pFrame->ShowWindow( SW_HIDE );
+ }
+#ifdef USE_D3D8
+ if ( g_osVersion < OSV_XP )
+ {
+ ::SetWindowPos( g_hBlackFadingWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW );
+ }
+ InitD3D( g_hBlackFadingWindow, false );
+#else // USE_D3D8
+ ::SetWindowPos( g_hBlackFadingWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW );
+// ::ShowWindow( g_hBlackFadingWindow, SW_SHOWMAXIMIZED );
+#endif // USE_D3D8
+ InvalidateRect( g_hBlackFadingWindow, NULL, TRUE );
+ }
+ else
+ {
+ if ( g_osVersion < OSV_XP )
+ {
+// OutputDebugString( "hiding fade window\n" );
+ ShowWindow( g_hBlackFadingWindow, SW_HIDE );
+ }
+ else
+ {
+// OutputDebugString( "Deferring erase on fade window\n" );
+ ::SetWindowPos( g_hBlackFadingWindow, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_DEFERERASE );
+ }
+ }
+ return true;
+}
+
+HWND CreateFullscreenWindow( bool bFadeIn )
+{
+ if ( g_hBlackFadingWindow )
+ return g_hBlackFadingWindow;
+
+ static s_bRegistered = false;
+ if ( !s_bRegistered )
+ {
+ WNDCLASS wc;
+ wc.style = CS_HREDRAW | CS_VREDRAW;
+ wc.lpfnWndProc = ( WNDPROC )WinProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = g_hInstance;
+ wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
+ wc.hCursor = NULL;
+ wc.hbrBackground = NULL;
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = "myclass";
+
+ if ( !RegisterClass( &wc ) )
+ return 0;
+
+ s_bRegistered = true;
+ }
+
+ g_bFadeIn = bFadeIn;
+ DWORD windowStyle = WS_POPUP;
+#ifndef USE_D3D8
+ windowStyle |= WS_MAXIMIZE | WS_EX_TOPMOST | WS_VISIBLE;
+#endif
+ if ( g_osVersion < OSV_XP )
+ {
+ windowStyle |= WS_MAXIMIZE | WS_EX_TOPMOST | WS_VISIBLE;
+ }
+
+ MONITORINFO mi;
+ mi.cbSize = sizeof( mi );
+ if ( !GetMonitorInfo( g_hMonitor, &mi ) )
+ {
+ GetClientRect( GetDesktopWindow(), &mi.rcMonitor );
+ }
+
+ g_hBlackFadingWindow = CreateWindow( "myclass", _T( "Steam Media Player" ), windowStyle, mi.rcMonitor.left, mi.rcMonitor.top, mi.rcMonitor.right - mi.rcMonitor.left, mi.rcMonitor.bottom - mi.rcMonitor.top, NULL, NULL, g_hInstance, NULL );
+#ifndef USE_D3D8
+ ShowWindow( g_hBlackFadingWindow, SW_SHOWMAXIMIZED );
+#endif
+ if ( g_osVersion < OSV_XP )
+ {
+ ShowWindow( g_hBlackFadingWindow, SW_SHOWMAXIMIZED );
+ }
+
+ while ( ShowCursor( FALSE ) >= 0 )
+ ;
+
+ return g_hBlackFadingWindow;
+}
+
+bool CreateDesktopBitmaps()
+{
+ MONITORINFOEX mi;
+ mi.cbSize = sizeof( mi );
+ if ( !GetMonitorInfo( g_hMonitor, &mi ) )
+ return false;
+
+ g_screenWidth = mi.rcMonitor.right - mi.rcMonitor.left;
+ g_screenHeight = mi.rcMonitor.bottom - mi.rcMonitor.top;
+
+ HDC hdcScreen = CreateDC( mi.szDevice, mi.szDevice, NULL, NULL );
+ if ( !hdcScreen )
+ return false;
+
+ g_hdcCapture = CreateCompatibleDC( hdcScreen );
+ g_hdcBlend = CreateCompatibleDC( hdcScreen );
+ if ( !g_hdcCapture || !g_hdcBlend )
+ return false;
+
+ if ( ( GetDeviceCaps( hdcScreen, SHADEBLENDCAPS ) & SB_CONST_ALPHA ) == 0 )
+ {
+ OutputDebugString( "display doesn't support AlphaBlend!\n" );
+ }
+
+ if ( ( GetDeviceCaps( hdcScreen, RASTERCAPS ) & RC_BITBLT ) == 0 )
+ {
+ OutputDebugString( "display doesn't support BitBlt!\n" );
+ }
+
+ if ( GetDeviceCaps( hdcScreen, BITSPIXEL ) < 32 )
+ {
+ OutputDebugString( "display doesn't support 32bpp!\n" );
+ }
+
+ if ( g_screenWidth != GetDeviceCaps( hdcScreen, HORZRES ) ||
+ g_screenHeight != GetDeviceCaps( hdcScreen, VERTRES ) )
+ {
+ OutputDebugString( "Screen DC size differs from monitor size!\n" );
+ }
+
+ g_hbmCapture = CreateCompatibleBitmap( hdcScreen, g_screenWidth, g_screenHeight );
+ g_hbmBlend = CreateCompatibleBitmap( hdcScreen, g_screenWidth, g_screenHeight );
+ if ( !g_hbmCapture || !g_hbmBlend )
+ return false;
+
+ HGDIOBJ oldCaptureObject = SelectObject( g_hdcCapture, g_hbmCapture );
+ HGDIOBJ oldBlendObject = SelectObject( g_hdcBlend, g_hbmBlend );
+
+ if ( !BitBlt( g_hdcCapture, 0, 0, g_screenWidth, g_screenHeight, hdcScreen, 0, 0, SRCCOPY ) )
+ return false;
+
+ SelectObject( g_hdcCapture, oldCaptureObject );
+ SelectObject( g_hdcBlend, oldBlendObject );
+
+ return true;
+}
+
+void PrintLastError( const char *pPrefix )
+{
+#ifdef _DEBUG
+ DWORD dw = GetLastError();
+
+ LPVOID lpMsgBuf;
+ FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, dw, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
+ ( LPTSTR )&lpMsgBuf, 0, NULL );
+
+ OutputDebugString( pPrefix );
+ char msg[ 256 ];
+ sprintf( msg, "(%d) ", dw );
+ OutputDebugString( msg );
+ OutputDebugString( ( char * )lpMsgBuf );
+
+ LocalFree( lpMsgBuf );
+#endif
+}
+
+void KillOtherSMPs()
+{
+ DWORD nBytesReturned = 0;
+ DWORD procIds[ 1024 ];
+ if ( !EnumProcesses( procIds, sizeof( procIds ), &nBytesReturned ) )
+ {
+ PrintLastError( "EnumProcesses Error: " );
+ return;
+ }
+
+ DWORD dwCurrentProcessId = GetCurrentProcessId();
+
+ int nProcIds = nBytesReturned / sizeof( DWORD );
+ for ( int i = 0; i < nProcIds; ++i )
+ {
+ if ( procIds[ i ] == dwCurrentProcessId )
+ continue;
+
+ if ( procIds[ i ] == 0 ) // system idle process
+ continue;
+
+ HANDLE hProcess = OpenProcess( PROCESS_TERMINATE | PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, procIds[ i ] );
+ if ( !hProcess )
+ {
+ PrintLastError( "OpenProcess Error: " );
+ continue;
+ }
+
+ HMODULE hMod[ 1 ];
+ DWORD cbNeeded;
+ if ( !EnumProcessModules( hProcess, hMod, sizeof( hMod ), &cbNeeded ) )
+ {
+ PrintLastError( "EnumProcessModules Error: " );
+ continue;
+ }
+
+ char processName[ 1024 ];
+ int nChars = GetModuleBaseName( hProcess, hMod[ 0 ], processName, sizeof( processName ) / sizeof( char ) );
+ if ( nChars >= sizeof( processName ) )
+ {
+ PrintLastError( "GetModuleBaseName Error: " );
+ continue;
+ }
+
+ if ( strcmp( processName, "smp.exe" ) == 0 )
+ {
+ OutputDebugString( "!!! Killing smp.exe !!!\n" );
+ TerminateProcess( hProcess, 0 );
+ }
+
+ if ( !CloseHandle( hProcess ) )
+ {
+ PrintLastError( "CloseHandle Error: " );
+ continue;
+ }
+ }
+}
+
+void ParseCommandLine( const char *cmdline, std::vector< std::string > &params )
+{
+ params.push_back( "" );
+
+ bool quoted = false;
+ for ( const char *cp = cmdline; *cp; ++cp )
+ {
+ if ( *cp == '\"' )
+ {
+ quoted = !quoted;
+ }
+ else if ( isspace( *cp ) && !quoted )
+ {
+ if ( !params.back().empty() )
+ {
+ params.push_back( "" );
+ }
+ }
+ else
+ {
+ params.back().push_back( *cp );
+ }
+ }
+
+ if ( params.back().empty() )
+ {
+ params.pop_back();
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+//
+extern "C" int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpCmdLine, int /*nShowCmd*/ )
+{
+ g_hInstance = hInstance;
+
+ KillOtherSMPs();
+
+ g_lpCommandLine = lpCmdLine;
+ if ( lpCmdLine == NULL || *lpCmdLine == '\0' )
+ return 0;
+
+ std::vector< std::string > params;
+ ParseCommandLine( lpCmdLine, params );
+ int nParams = params.size();
+ for ( int i = 0; i < nParams; ++i )
+ {
+ if ( params[ i ][ 0 ] == '-' || params[ i ][ 0 ] == '/' )
+ {
+ const char *pOption = params[ i ].c_str() + 1;
+ if ( strcmp( pOption, "reportstats" ) == 0 )
+ {
+ g_bReportStats = true;
+ }
+ else if ( strcmp( pOption, "localsteamserver" ) == 0 )
+ {
+ g_bUseLocalSteamServer = true;
+ }
+ else if ( strcmp( pOption, "redirect" ) == 0 )
+ {
+ ++i;
+ g_redirectTarget = params[ i ];
+ }
+ }
+ else
+ {
+ g_URL = params[ i ];
+ }
+ }
+
+ SetRegistryValue( "Software\\Microsoft\\MediaPlayer\\Preferences\\VideoSettings", "UseVMROverlay", 0, g_dwUseVMROverlayOldValue, g_bUseVMROverlayValueExists );
+ atexit( RestoreRegistry );
+
+ LogPlayerEvent( ET_APPLAUNCH, 0.0f );
+
+ lpCmdLine = GetCommandLine(); //this line necessary for _ATL_MIN_CRT
+
+ CoInitialize( 0 );
+ _Module.Init( ObjectMap, hInstance, &LIBID_ATLLib );
+
+ ::InitCommonControls();
+
+ POINT pt;
+ GetCursorPos( &pt );
+ g_hMonitor = MonitorFromPoint( pt, MONITOR_DEFAULTTONEAREST );
+
+ if ( !CreateDesktopBitmaps() )
+ {
+ OutputDebugString( "CreateDesktopBitmaps FAILED!\n" );
+ }
+
+ ShowCursor( FALSE );
+ CreateFullscreenWindow( true );
+
+ MSG msg;
+ while ( GetMessage( &msg, 0, 0, 0 ) )
+ {
+ TranslateMessage( &msg );
+ DispatchMessage( &msg );
+ }
+
+ LogPlayerEvent( ET_APPEXIT );
+ if ( g_bReportStats )
+ {
+ UploadStats();
+ }
+
+ if ( !g_redirectTarget.empty() )
+ {
+ ::ShellExecuteA( NULL, "open", g_redirectTarget.c_str(), NULL, NULL, SW_SHOWNORMAL );
+ }
+
+ _Module.Term();
+ CoUninitialize();
+
+ RestoreRegistry();
+
+ return 0;
+}
diff --git a/utils/smp/smp.ico b/utils/smp/smp.ico
new file mode 100644
index 0000000..ae7c799
--- /dev/null
+++ b/utils/smp/smp.ico
Binary files differ
diff --git a/utils/smp/smp.rc b/utils/smp/smp.rc
new file mode 100644
index 0000000..d114041
--- /dev/null
+++ b/utils/smp/smp.rc
@@ -0,0 +1,228 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904B0"
+ BEGIN
+ VALUE "CompanyName", "Valve"
+ VALUE "FileDescription", "Steam Media Player"
+ VALUE "FileVersion", "1, 0, 0, 1"
+ VALUE "InternalName", "Steam Media Player"
+ VALUE "LegalCopyright", "Copyright 2005"
+ VALUE "OriginalFilename", "smp.exe"
+ VALUE "ProductName", "Steam Media Player"
+ VALUE "ProductVersion", "1, 0, 0, 1"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_MENU1 MENU
+BEGIN
+ POPUP "&File"
+ BEGIN
+ MENUITEM "&Open URL", ID_FILE_OPEN
+ MENUITEM "E&xit", ID_APP_EXIT
+ END
+ POPUP "Interfaces"
+ BEGIN
+ MENUITEM "IWMPCore", ID_WMPCORE, INACTIVE
+ MENUITEM " close", ID_WMPCORE_CLOSE
+ MENUITEM " URL", ID_WMPCORE_URL
+ MENUITEM " openState", ID_WMPCORE_OPENSTATE
+ MENUITEM " playState", ID_WMPCORE_PLAYSTATE
+ MENUITEM " controls", ID_WMPCORE_CONTROLS
+ MENUITEM " settings", ID_WMPCORE_SETTINGS
+ MENUITEM " currentMedia", ID_WMPCORE_CURRENTMEDIA
+ MENUITEM " mediaCollection", ID_WMPCORE_MEDIACOLLECTION
+ MENUITEM " playlistCollection", ID_WMPCORE_PLAYLISTCOLLECTION
+
+ MENUITEM " versionInfo", ID_WMPCORE_VERSIONINFO
+ MENUITEM " launchURL", ID_WMPCORE_LAUNCHURL
+ MENUITEM " network", ID_WMPCORE_NETWORK
+ MENUITEM " currentPlaylist", ID_WMPCORE_CURRENTPLAYLIST
+ MENUITEM " cdromCollection", ID_WMPCORE_CDROMCOLLECTION
+ MENUITEM " closedCaption", ID_WMPCORE_CLOSEDCAPTION
+ MENUITEM " isOnline", ID_WMPCORE_ISONLINE
+ MENUITEM " error", ID_WMPCORE_ERROR
+ MENUITEM " status", ID_WMPCORE_STATUS
+ MENUITEM "IWMPCore2", ID_WMPCORE2, INACTIVE
+ MENUITEM " dvd", ID_WMPCORE2_DVD
+ MENUITEM "IWMPlayer", ID_WMPPLAYER, INACTIVE
+ MENUITEM " enabled", ID_WMPPLAYER_ENABLED
+ MENUITEM " fullScreen", ID_WMPPLAYER_FULLSCREEN
+ MENUITEM " enableContextMenu", ID_WMPPLAYER_ENABLECONTEXTMENU
+
+ MENUITEM " uiMode", ID_WMPPLAYER_UIMODE
+ MENUITEM "IWMPlayer2", ID_WMPPLAYER2, INACTIVE
+ MENUITEM " stretchToFit", ID_WMPPLAYER2_STRETCHTOFIT
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_FILEOPEN_DIALOG DIALOGEX 0, 0, 274, 74
+STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Open URL"
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ EDITTEXT IDC_FILEOPEN_EDIT,7,25,235,14,ES_AUTOHSCROLL | WS_GROUP
+ PUSHBUTTON "...",IDC_FILEOPEN_BROWSE,246,26,21,14,0,
+ WS_EX_CLIENTEDGE
+ DEFPUSHBUTTON "OK",IDOK,160,53,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,217,53,50,14
+ LTEXT "Enter URL to play:",IDC_STATIC,7,7,59,8
+END
+
+IDD_STRING_DIALOG DIALOG 0, 0, 244, 50
+STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Property"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,123,29,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,183,29,50,14
+ EDITTEXT IDC_STRING_EDIT,7,7,226,13,ES_AUTOHSCROLL
+END
+
+IDD_BOOLEAN_DIALOG DIALOG 0, 0, 125, 58
+STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Boolean"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,7,37,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,68,37,50,14
+ CONTROL "VARIANT_TRUE",IDC_BOOLEAN_TRUE,"Button",
+ BS_AUTORADIOBUTTON,7,7,85,10
+ CONTROL "VARIANT_FALSE",IDC_BOOLEAN_FALSE,"Button",
+ BS_AUTORADIOBUTTON,7,21,85,10
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_STRING_DIALOG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 237
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 43
+ END
+
+ IDD_BOOLEAN_DIALOG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 118
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 51
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON ICON "smp.ico"
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/utils/smp/smp.sln b/utils/smp/smp.sln
new file mode 100644
index 0000000..330d060
--- /dev/null
+++ b/utils/smp/smp.sln
@@ -0,0 +1,36 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "smp", "smp.vcproj", "{F2E998F8-1482-4A51-A70C-C3B225A7A201}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Release = Release
+ Release MinDependency = Release MinDependency
+ Release MinSize = Release MinSize
+ Unicode Debug = Unicode Debug
+ Unicode Release MinDependency = Unicode Release MinDependency
+ Unicode Release MinSize = Unicode Release MinSize
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {F2E998F8-1482-4A51-A70C-C3B225A7A201}.Debug.ActiveCfg = Debug|Win32
+ {F2E998F8-1482-4A51-A70C-C3B225A7A201}.Debug.Build.0 = Debug|Win32
+ {F2E998F8-1482-4A51-A70C-C3B225A7A201}.Release.ActiveCfg = Release MinSize|Win32
+ {F2E998F8-1482-4A51-A70C-C3B225A7A201}.Release.Build.0 = Release MinSize|Win32
+ {F2E998F8-1482-4A51-A70C-C3B225A7A201}.Release MinDependency.ActiveCfg = Release MinDependency|Win32
+ {F2E998F8-1482-4A51-A70C-C3B225A7A201}.Release MinDependency.Build.0 = Release MinDependency|Win32
+ {F2E998F8-1482-4A51-A70C-C3B225A7A201}.Release MinSize.ActiveCfg = Release MinSize|Win32
+ {F2E998F8-1482-4A51-A70C-C3B225A7A201}.Release MinSize.Build.0 = Release MinSize|Win32
+ {F2E998F8-1482-4A51-A70C-C3B225A7A201}.Unicode Debug.ActiveCfg = Unicode Debug|Win32
+ {F2E998F8-1482-4A51-A70C-C3B225A7A201}.Unicode Debug.Build.0 = Unicode Debug|Win32
+ {F2E998F8-1482-4A51-A70C-C3B225A7A201}.Unicode Release MinDependency.ActiveCfg = Unicode Release MinDependency|Win32
+ {F2E998F8-1482-4A51-A70C-C3B225A7A201}.Unicode Release MinDependency.Build.0 = Unicode Release MinDependency|Win32
+ {F2E998F8-1482-4A51-A70C-C3B225A7A201}.Unicode Release MinSize.ActiveCfg = Unicode Release MinSize|Win32
+ {F2E998F8-1482-4A51-A70C-C3B225A7A201}.Unicode Release MinSize.Build.0 = Unicode Release MinSize|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/utils/smp/smp.vcproj b/utils/smp/smp.vcproj
new file mode 100644
index 0000000..3d6a6ee
--- /dev/null
+++ b/utils/smp/smp.vcproj
@@ -0,0 +1,625 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="smp"
+ ProjectGUID="{6ACEBE96-D4A4-439D-881A-A3DD1F6FEB89}"
+ RootNamespace="smp"
+ SccProjectName=""
+ SccLocalPath=""
+ Keyword="AtlProj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Unicode Release MinSize|Win32"
+ OutputDirectory=".\ReleaseUMinSize"
+ IntermediateDirectory=".\ReleaseUMinSize"
+ ConfigurationType="1"
+ UseOfMFC="0"
+ UseOfATL="2"
+ ATLMinimizesCRunTimeLibraryUsage="TRUE"
+ CharacterSet="1">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories=".;..\..\common;..\..\dx8sdk\include;..\WMPSDK10\include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+ StringPooling="TRUE"
+ ExceptionHandling="TRUE"
+ RuntimeLibrary="5"
+ EnableFunctionLevelLinking="TRUE"
+ ForceConformanceInForLoopScope="TRUE"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderFile=".\ReleaseUMinSize/smp.pch"
+ AssemblerListingLocation=".\ReleaseUMinSize/"
+ ObjectFile=".\ReleaseUMinSize/"
+ ProgramDataBaseFileName=".\ReleaseUMinSize/"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ CompileAs="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib Msimg32.lib ws2_32.lib rpcrt4.lib ..\..\dx8sdk\lib\d3d8.lib"
+ OutputFile=".\ReleaseUMinSize/smp.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="TRUE"
+ IgnoreAllDefaultLibraries="FALSE"
+ ProgramDatabaseFile=".\ReleaseUMinSize/smp.pdb"
+ SubSystem="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ TypeLibraryName=".\ReleaseUMinSize/smp.tlb"
+ HeaderFileName=""/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release MinDependency|Win32"
+ OutputDirectory=".\ReleaseMinDependency"
+ IntermediateDirectory=".\ReleaseMinDependency"
+ ConfigurationType="1"
+ UseOfMFC="0"
+ UseOfATL="1"
+ ATLMinimizesCRunTimeLibraryUsage="TRUE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories=".;..\..\common;..\..\dx8sdk\include;..\WMPSDK10\include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+ StringPooling="TRUE"
+ ExceptionHandling="TRUE"
+ RuntimeLibrary="5"
+ EnableFunctionLevelLinking="TRUE"
+ ForceConformanceInForLoopScope="TRUE"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderFile=".\ReleaseMinDependency/smp.pch"
+ AssemblerListingLocation=".\ReleaseMinDependency/"
+ ObjectFile=".\ReleaseMinDependency/"
+ ProgramDataBaseFileName=".\ReleaseMinDependency/"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ CompileAs="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib Msimg32.lib ws2_32.lib rpcrt4.lib psapi.lib ..\..\dx8sdk\lib\d3d8.lib"
+ OutputFile=".\ReleaseMinDependency/smp.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="TRUE"
+ IgnoreAllDefaultLibraries="FALSE"
+ IgnoreDefaultLibraryNames=""
+ ProgramDatabaseFile=".\ReleaseMinDependency/smp.pdb"
+ SubSystem="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ TypeLibraryName=".\ReleaseMinDependency/smp.tlb"
+ HeaderFileName=""/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Unicode Release MinDependency|Win32"
+ OutputDirectory=".\ReleaseUMinDependency"
+ IntermediateDirectory=".\ReleaseUMinDependency"
+ ConfigurationType="1"
+ UseOfMFC="0"
+ UseOfATL="1"
+ ATLMinimizesCRunTimeLibraryUsage="TRUE"
+ CharacterSet="1">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories=".;..\..\common;..\..\dx8sdk\include;..\WMPSDK10\include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+ StringPooling="TRUE"
+ ExceptionHandling="TRUE"
+ RuntimeLibrary="5"
+ EnableFunctionLevelLinking="TRUE"
+ ForceConformanceInForLoopScope="TRUE"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderFile=".\ReleaseUMinDependency/smp.pch"
+ AssemblerListingLocation=".\ReleaseUMinDependency/"
+ ObjectFile=".\ReleaseUMinDependency/"
+ ProgramDataBaseFileName=".\ReleaseUMinDependency/"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ CompileAs="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib Msimg32.lib ws2_32.lib rpcrt4.lib ..\..\dx8sdk\lib\d3d8.lib"
+ OutputFile=".\ReleaseUMinDependency/smp.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="TRUE"
+ IgnoreAllDefaultLibraries="FALSE"
+ ProgramDatabaseFile=".\ReleaseUMinDependency/smp.pdb"
+ SubSystem="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ TypeLibraryName=".\ReleaseUMinDependency/smp.tlb"
+ HeaderFileName=""/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Unicode Debug|Win32"
+ OutputDirectory=".\DebugU"
+ IntermediateDirectory=".\DebugU"
+ ConfigurationType="1"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="1">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=".;..\..\common;..\..\dx8sdk\include;..\WMPSDK10\include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+ ExceptionHandling="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="5"
+ ForceConformanceInForLoopScope="TRUE"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="stdafx.h"
+ PrecompiledHeaderFile=".\DebugU/smp.pch"
+ AssemblerListingLocation=".\DebugU/"
+ ObjectFile=".\DebugU/"
+ ProgramDataBaseFileName=".\DebugU/"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ DebugInformationFormat="4"
+ CompileAs="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib Msimg32.lib ws2_32.lib rpcrt4.lib ..\..\dx8sdk\lib\d3d8.lib"
+ OutputFile=".\DebugU/smp.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="TRUE"
+ IgnoreAllDefaultLibraries="FALSE"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile=".\DebugU/smp.pdb"
+ SubSystem="2"
+ EntryPointSymbol="wWinMainCRTStartup"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ TypeLibraryName=".\DebugU/smp.tlb"
+ HeaderFileName=""/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release MinSize|Win32"
+ OutputDirectory=".\ReleaseMinSize"
+ IntermediateDirectory=".\ReleaseMinSize"
+ ConfigurationType="1"
+ UseOfMFC="0"
+ UseOfATL="2"
+ ATLMinimizesCRunTimeLibraryUsage="TRUE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories=".;..\..\common;..\..\dx8sdk\include;..\WMPSDK10\include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+ StringPooling="TRUE"
+ ExceptionHandling="TRUE"
+ RuntimeLibrary="5"
+ EnableFunctionLevelLinking="TRUE"
+ ForceConformanceInForLoopScope="TRUE"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderFile=".\ReleaseMinSize/smp.pch"
+ AssemblerListingLocation=".\ReleaseMinSize/"
+ ObjectFile=".\ReleaseMinSize/"
+ ProgramDataBaseFileName=".\ReleaseMinSize/"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ CompileAs="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib Msimg32.lib ws2_32.lib rpcrt4.lib psapi.lib ..\..\dx8sdk\lib\d3d8.lib"
+ OutputFile=".\ReleaseMinSize/smp.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="TRUE"
+ IgnoreAllDefaultLibraries="FALSE"
+ ProgramDatabaseFile=".\ReleaseMinSize/smp.pdb"
+ SubSystem="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ TypeLibraryName=".\ReleaseMinSize/smp.tlb"
+ HeaderFileName=""/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory=".\Debug"
+ IntermediateDirectory=".\Debug"
+ ConfigurationType="1"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=".;..\..\common;..\..\dx8sdk\include;..\WMPSDK10\include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+ ExceptionHandling="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ ForceConformanceInForLoopScope="TRUE"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderFile=".\Debug/smp.pch"
+ AssemblerListingLocation=".\Debug/"
+ ObjectFile=".\Debug/"
+ ProgramDataBaseFileName=".\Debug/"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ DebugInformationFormat="4"
+ CompileAs="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib Msimg32.lib ws2_32.lib rpcrt4.lib psapi.lib ..\..\dx8sdk\lib\d3d8.lib"
+ OutputFile=".\Debug/smp.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="TRUE"
+ IgnoreAllDefaultLibraries="FALSE"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile=".\Debug/smp.pdb"
+ SubSystem="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ TypeLibraryName=".\Debug/smp.tlb"
+ HeaderFileName=""/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
+ <File
+ RelativePath="CWMPEventDispatch.cpp">
+ <FileConfiguration
+ Name="Unicode Release MinSize|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_UNICODE;_ATL_DLL;_ATL_MIN_CRT;$(NoInherit)"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release MinDependency|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Unicode Release MinDependency|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_UNICODE;_ATL_STATIC_REGISTRY;_ATL_MIN_CRT;$(NoInherit)"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Unicode Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_UNICODE;$(NoInherit)"
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release MinSize|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="CWMPHost.cpp">
+ <FileConfiguration
+ Name="Unicode Release MinSize|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_UNICODE;_ATL_DLL;_ATL_MIN_CRT;$(NoInherit)"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release MinDependency|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Unicode Release MinDependency|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_UNICODE;_ATL_STATIC_REGISTRY;_ATL_MIN_CRT;$(NoInherit)"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Unicode Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_UNICODE;$(NoInherit)"
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release MinSize|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\IceKey.cpp">
+ </File>
+ <File
+ RelativePath="smp.cpp">
+ <FileConfiguration
+ Name="Unicode Release MinSize|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_UNICODE;_ATL_DLL;_ATL_MIN_CRT;$(NoInherit)"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release MinDependency|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Unicode Release MinDependency|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_UNICODE;_ATL_STATIC_REGISTRY;_ATL_MIN_CRT;$(NoInherit)"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Unicode Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_UNICODE;$(NoInherit)"
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release MinSize|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl">
+ <File
+ RelativePath=".\IceKey.H">
+ </File>
+ <File
+ RelativePath="Resource.h">
+ </File>
+ <File
+ RelativePath=".\StdAfx.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
+ <File
+ RelativePath=".\smp.ico">
+ </File>
+ <File
+ RelativePath="smp.rc">
+ <FileConfiguration
+ Name="Unicode Release MinSize|Win32">
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;$(NoInherit)"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Unicode Release MinDependency|Win32">
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;$(NoInherit)"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Unicode Debug|Win32">
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;$(NoInherit)"/>
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Library Files"
+ Filter="">
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>