Initial commit: ROW Client source code

Game client codebase including:
- CharacterActionControl: Character and creature management
- GlobalScript: Network, items, skills, quests, utilities
- RYLClient: Main client application with GUI and event handlers
- Engine: 3D rendering engine (RYLGL)
- MemoryManager: Custom memory allocation
- Library: Third-party dependencies (DirectX, boost, etc.)
- Tools: Development utilities

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-29 16:24:34 +09:00
commit e067522598
5135 changed files with 1745744 additions and 0 deletions

View File

@@ -0,0 +1,147 @@
# Microsoft Developer Studio Project File - Name="Cube" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=Cube - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "Cube.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "Cube.mak" CFG="Cube - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Cube - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "Cube - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "Cube - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\DirectShow\BaseClasses" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D WINVER=0x501 /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG" /d "WIN32"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 ..\..\..\DirectShow\BaseClasses\Release\strmbase.lib strmiids.lib quartz.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib comctl32.lib /nologo /subsystem:windows /pdb:none /machine:I386 /OPT:NOREF /OPT:ICF
!ELSEIF "$(CFG)" == "Cube - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /Gi /GX /ZI /Od /I "..\..\..\DirectShow\BaseClasses" /D "_DEBUG" /D "DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D WINVER=0x501 /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG" /d "WIN32"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 ..\..\..\DirectShow\BaseClasses\Debug\strmbasd.lib strmiids.lib quartz.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib comctl32.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcmtd" /pdbtype:sept
!ENDIF
# Begin Target
# Name "Cube - Win32 Release"
# Name "Cube - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\app.cpp
# End Source File
# Begin Source File
SOURCE=.\commands.cpp
# End Source File
# Begin Source File
SOURCE=.\compositor.cpp
# End Source File
# Begin Source File
SOURCE=.\vcdplyer.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\app.h
# End Source File
# Begin Source File
SOURCE=.\project.h
# End Source File
# Begin Source File
SOURCE=.\resource.h
# End Source File
# Begin Source File
SOURCE=.\vcdplyer.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=.\Cube.ico
# End Source File
# Begin Source File
SOURCE=.\Cube.rc
# End Source File
# Begin Source File
SOURCE=.\toolbar.bmp
# End Source File
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "Cube"=".\Cube.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@@ -0,0 +1,992 @@
//------------------------------------------------------------------------------
// File: app.cpp
//
// Desc: DirectShow sample code - VMR-based Cube video player
//
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <streams.h>
#include <atlbase.h>
#include <atlconv.cpp>
#include <mmreg.h>
#include <commctrl.h>
#include <initguid.h>
#include "project.h"
#include "resource.h"
#include <stdarg.h>
#include <stdio.h>
/* -------------------------------------------------------------------------
** Global variables that are initialized at run time and then stay constant.
** -------------------------------------------------------------------------
*/
HINSTANCE hInst;
HICON hIconVideoCd;
HWND hwndApp;
HWND g_hwndToolbar;
CMpegMovie *pMpegMovie;
BOOL m_bFullScreen = FALSE;
/* -------------------------------------------------------------------------
** True Globals - these may change during execution of the program.
** -------------------------------------------------------------------------
*/
DWORD g_State = VCD_NO_CD;
/* -------------------------------------------------------------------------
** Constants
** -------------------------------------------------------------------------
*/
const TCHAR szClassName[] = TEXT("VMR_CubePlayer_CLASS");
const TCHAR g_szNULL[] = TEXT("\0");
const TCHAR g_szEmpty[] = TEXT("");
/*
** User interface values
*/
int dyToolbar;
const int dxBitmap = 16;
const int dyBitmap = 15;
const int dxButtonSep = 8;
const TCHAR g_chNULL = TEXT('\0');
const LONG g_Style = WS_THICKFRAME | WS_POPUP | WS_CAPTION |
WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX |
WS_CLIPCHILDREN;
const TBBUTTON tbButtons[DEFAULT_TBAR_SIZE] = {
{ IDX_SEPARATOR, 1, 0, TBSTYLE_SEP },
{ IDX_1, IDM_MOVIE_PLAY, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1 },
{ IDX_2, IDM_MOVIE_PAUSE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1 },
{ IDX_3, IDM_MOVIE_STOP, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1 },
{ IDX_SEPARATOR, 1, 0, TBSTYLE_SEP },
{ IDX_4, IDM_FULL_SCREEN, TBSTATE_ENABLED, TBSTYLE_CHECK, 0, 0, 0, -1 }
};
/* -------------------------------------------------------------------------
** Local function prototypes
** -------------------------------------------------------------------------
*/
void SetFullScreenMode(BOOL bMode);
BOOL IsFullScreenMode();
LRESULT CALLBACK AboutDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
/******************************Public*Routine******************************\
* WinMain
*
*
* Windows recognizes this function by name as the initial entry point
* for the program. This function calls the application initialization
* routine, if no other instance of the program is running, and always
* calls the instance initialization routine. It then executes a message
* retrieval and dispatch loop that is the top-level control structure
* for the remainder of execution. The loop is terminated when a WM_QUIT
* message is received, at which time this function exits the application
* instance by returning the value passed by PostQuitMessage().
*
* If this function must abort before entering the message loop, it
* returns the conventional value NULL.
*
\**************************************************************************/
int PASCAL
WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLineOld,
int nCmdShow
)
{
USES_CONVERSION;
HRESULT hres = CoInitialize(NULL);
if(hres == S_FALSE)
{
CoUninitialize();
}
if(!hPrevInstance)
{
if(!InitApplication(hInstance))
{
return FALSE;
}
}
/*
** Perform initializations that apply to a specific instance
*/
if(!InitInstance(hInstance, nCmdShow))
{
return FALSE;
}
/* Verify that the VMR is present on this system */
if(!VerifyVMR())
return FALSE;
/*
** Acquire and dispatch messages until a WM_QUIT message is received.
*/
int iRet = DoMainLoop();
QzUninitialize();
return iRet;
}
/*****************************Private*Routine******************************\
* DoMainLoop
*
* Process the main message loop
*
\**************************************************************************/
int
DoMainLoop(
void
)
{
MSG msg;
HANDLE ahObjects[8];;
int cObjects;
HACCEL haccel = LoadAccelerators(hInst, MAKEINTRESOURCE(IDR_ACCELERATOR));
//
// message loop lasts until we get a WM_QUIT message
//
for(;;)
{
if(pMpegMovie != NULL)
{
cObjects = 1;
ahObjects[0] = pMpegMovie->GetMovieEventHandle();
}
else
{
ahObjects[0] = NULL;
cObjects = 0;
}
if(ahObjects[0] == NULL)
{
WaitMessage();
}
else
{
//
// wait for any message sent or posted to this queue
// or for a graph notification
//
DWORD result;
result = MsgWaitForMultipleObjects(cObjects, ahObjects, FALSE,
INFINITE, QS_ALLINPUT);
if(result != (WAIT_OBJECT_0 + cObjects))
{
VideoCd_OnGraphNotify(result - WAIT_OBJECT_0);
continue;
}
}
//
// When here, we either have a message or no event handle
// has been created yet.
//
// read all of the messages in this next loop
// removing each message as we read it
//
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if(msg.message == WM_QUIT)
{
return (int) msg.wParam;
}
if(!TranslateAccelerator(hwndApp, haccel, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
} // DoMainLoop
/*****************************Private*Routine******************************\
* InitApplication(HANDLE)
*
* This function is called at initialization time only if no other
* instances of the application are running. This function performs
* initialization tasks that can be done once for any number of running
* instances.
*
* In this case, we initialize a window class by filling out a data
* structure of type WNDCLASS and calling the Windows RegisterClass()
* function. Since all instances of this application use the same window
* class, we only need to do this when the first instance is initialized.
*
\**************************************************************************/
BOOL
InitApplication(
HINSTANCE hInstance
)
{
WNDCLASS wc;
/*
** Fill in window class structure with parameters that describe the
** main window.
*/
hIconVideoCd = LoadIcon(hInstance, MAKEINTRESOURCE(IDR_VIDEOCD_ICON));
wc.style = CS_VREDRAW | CS_HREDRAW;
wc.lpfnWndProc = VideoCdWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = hIconVideoCd;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)NULL;
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAIN_MENU);
wc.lpszClassName = szClassName;
/*
** Register the window class and return success/failure code.
*/
return RegisterClass(&wc);
}
/*****************************Private*Routine******************************\
* InitInstance
*
* This function is called at initialization time for every instance of
* this application. This function performs initialization tasks that
* cannot be shared by multiple instances.
*
* In this case, we save the instance handle in a static variable and
* create and display the main program window.
*
\**************************************************************************/
BOOL
InitInstance(
HINSTANCE hInstance,
int nCmdShow
)
{
HWND hwnd;
RECT rc;
/*
** Save the instance handle in static variable, which will be used
** in many subsequent calls to Windows.
*/
hInst = hInstance;
rc.left = rc.top = 100;
rc.bottom = rc.right = 400;
/*
** Create a main window for this application instance.
*/
hwnd = CreateWindow(szClassName, IdStr(STR_APP_TITLE), g_Style,
rc.left, rc.top,
rc.right, rc.bottom,
NULL, NULL, hInstance, NULL);
/*
** If window could not be created, return "failure"
*/
if(NULL == hwnd)
{
return FALSE;
}
hwndApp = hwnd;
/*
** Make the window visible; update its client area; and return "success"
*/
SetPlayButtonsEnableState();
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
return TRUE;
}
/*****************************Private*Routine******************************\
* GetMoviePosition
*
* Place the movie in the centre of the client window.
* We do not stretch the the movie yet.
*
\**************************************************************************/
void
GetMoviePosition(
HWND hwnd,
long* xPos,
long* yPos,
long* pcx,
long* pcy
)
{
RECT rc;
GetAdjustedClientRect(&rc);
*xPos = rc.left;
*yPos = rc.top;
*pcx = rc.right - rc.left;
*pcy = rc.bottom - rc.top;
}
/******************************Public*Routine******************************\
* RepositionMovie
*
\**************************************************************************/
void
RepositionMovie(HWND hwnd)
{
if(pMpegMovie)
{
long xPos, yPos, cx, cy;
GetMoviePosition(hwnd, &xPos, &yPos, &cx, &cy);
pMpegMovie->PutMoviePosition(xPos, yPos, cx, cy);
InvalidateRect(hwnd, NULL, false);
UpdateWindow(hwnd);
}
}
/*****************************Private*Routine******************************\
* VideoCd_OnMove
*
\**************************************************************************/
void
VideoCd_OnMove(
HWND hwnd,
int x,
int y
)
{
if(pMpegMovie)
{
if(pMpegMovie->GetStateMovie() != State_Running)
{
RepositionMovie(hwnd);
}
else
{
long xPos, yPos, cx, cy;
// Reposition movie but don't invalidate the rect, since
// the next video frame will handle the redraw.
GetMoviePosition(hwnd, &xPos, &yPos, &cx, &cy);
pMpegMovie->PutMoviePosition(xPos, yPos, cx, cy);
}
}
}
/******************************Public*Routine******************************\
* VideoCdWndProc
*
\**************************************************************************/
LRESULT CALLBACK
VideoCdWndProc(
HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam
)
{
switch(message)
{
HANDLE_MSG(hwnd, WM_CREATE, VideoCd_OnCreate);
HANDLE_MSG(hwnd, WM_PAINT, VideoCd_OnPaint);
HANDLE_MSG(hwnd, WM_COMMAND, VideoCd_OnCommand);
HANDLE_MSG(hwnd, WM_CLOSE, VideoCd_OnClose);
HANDLE_MSG(hwnd, WM_DESTROY, VideoCd_OnDestroy);
HANDLE_MSG(hwnd, WM_SIZE, VideoCd_OnSize);
HANDLE_MSG(hwnd, WM_SYSCOLORCHANGE, VideoCd_OnSysColorChange);
HANDLE_MSG(hwnd, WM_INITMENUPOPUP, VideoCd_OnInitMenuPopup);
HANDLE_MSG(hwnd, WM_NOTIFY, VideoCd_OnNotify);
HANDLE_MSG(hwnd, WM_KEYUP, VideoCd_OnKeyUp);
HANDLE_MSG(hwnd, WM_MOVE, VideoCd_OnMove);
case WM_DISPLAYCHANGE:
{
if(pMpegMovie)
{
pMpegMovie->DisplayModeChanged();
}
}
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0L;
}
/*****************************Private*Routine******************************\
* VideoCd_OnCreate
*
\**************************************************************************/
BOOL
VideoCd_OnCreate(
HWND hwnd,
LPCREATESTRUCT lpCreateStruct
)
{
InitCommonControls();
/*
** Create the toolbar and statusbar.
*/
g_hwndToolbar = CreateToolbarEx(hwnd,
WS_VISIBLE | WS_CHILD |
TBSTYLE_TOOLTIPS | CCS_NODIVIDER,
ID_TOOLBAR, NUMBER_OF_BITMAPS,
hInst, IDR_TOOLBAR, tbButtons,
DEFAULT_TBAR_SIZE, dxBitmap, dyBitmap,
dxBitmap, dyBitmap, sizeof(TBBUTTON));
if(g_hwndToolbar == NULL)
{
return FALSE;
}
return TRUE;
}
/*****************************Private*Routine******************************\
* VideoCd_OnKeyUp
*
\**************************************************************************/
void
VideoCd_OnKeyUp(
HWND hwnd,
UINT vk,
BOOL fDown,
int cRepeat,
UINT flags
)
{
// Catch escape sequences to stop fullscreen mode
if((vk == VK_ESCAPE) || (vk == VK_RETURN))
{
if(pMpegMovie && IsFullScreenMode())
{
SetFullScreenMode(FALSE);
SetPlayButtonsEnableState();
}
}
}
/*****************************Private*Routine******************************\
* VideoCd_OnPaint
*
\**************************************************************************/
void
VideoCd_OnPaint(
HWND hwnd
)
{
PAINTSTRUCT ps;
HDC hdc;
RECT rc1;
RECT rc2;
/*
** Draw a frame around the movie playback area.
*/
GetClientRect(hwnd, &rc2);
hdc = BeginPaint(hwnd, &ps);
if(pMpegMovie)
{
long xPos, yPos, cx, cy;
GetMoviePosition(hwnd, &xPos, &yPos, &cx, &cy);
SetRect(&rc1, xPos, yPos, xPos + cx, yPos + cy);
HRGN rgnClient = CreateRectRgnIndirect(&rc2);
HRGN rgnVideo = CreateRectRgnIndirect(&rc1);
CombineRgn(rgnClient, rgnClient, rgnVideo, RGN_DIFF);
HBRUSH hbr = GetSysColorBrush(COLOR_BTNFACE);
FillRgn(hdc, rgnClient, hbr);
DeleteObject(hbr);
DeleteObject(rgnClient);
DeleteObject(rgnVideo);
pMpegMovie->RepaintVideo(hwnd, hdc);
}
else
{
FillRect(hdc, &rc2, (HBRUSH)(COLOR_BTNFACE + 1));
}
EndPaint(hwnd, &ps);
}
/*****************************Private*Routine******************************\
* AboutDlgProc
*
\**************************************************************************/
LRESULT CALLBACK AboutDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if(wParam == IDOK)
{
EndDialog(hWnd, TRUE);
return TRUE;
}
break;
}
return FALSE;
}
/*****************************Private*Routine******************************\
* VideoCd_OnCommand
*
\**************************************************************************/
void
VideoCd_OnCommand(
HWND hwnd,
int id,
HWND hwndCtl,
UINT codeNotify
)
{
switch(id)
{
case IDM_FILE_OPEN:
if(VcdPlayerOpenCmd())
VcdPlayerPlayCmd();
break;
case IDM_FILE_CLOSE:
VcdPlayerCloseCmd();
QzFreeUnusedLibraries();
break;
case IDM_FILE_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX),
hwnd, (DLGPROC) AboutDlgProc);
break;
case IDM_FILE_EXIT:
PostMessage(hwnd, WM_CLOSE, 0, 0L);
break;
case IDM_MOVIE_PLAY:
VcdPlayerPlayCmd();
break;
case IDM_MOVIE_STOP:
VcdPlayerStopCmd();
VcdPlayerRewindCmd();
break;
case IDM_MOVIE_PAUSE:
VcdPlayerPauseCmd();
break;
case IDM_FULL_SCREEN:
if(pMpegMovie)
{
BOOL bFullScreen = (BOOL)SendMessage(g_hwndToolbar,
TB_ISBUTTONCHECKED, IDM_FULL_SCREEN, 0);
SetFullScreenMode(bFullScreen);
}
break;
}
SetPlayButtonsEnableState();
}
/******************************Public*Routine******************************\
* VideoCd_OnDestroy
*
\**************************************************************************/
void
VideoCd_OnDestroy(
HWND hwnd
)
{
PostQuitMessage(0);
}
/******************************Public*Routine******************************\
* VideoCd_OnClose
*
\**************************************************************************/
void
VideoCd_OnClose(
HWND hwnd
)
{
VcdPlayerCloseCmd();
DestroyWindow(hwnd);
}
/******************************Public*Routine******************************\
* VideoCd_OnSize
*
\**************************************************************************/
void
VideoCd_OnSize(
HWND hwnd,
UINT state,
int dx,
int dy
)
{
if(IsWindow(g_hwndToolbar))
SendMessage(g_hwndToolbar, WM_SIZE, 0, 0L);
RepositionMovie(hwnd);
}
/*****************************Private*Routine******************************\
* VideoCd_OnSysColorChange
*
\**************************************************************************/
void
VideoCd_OnSysColorChange(
HWND hwnd
)
{
FORWARD_WM_SYSCOLORCHANGE(g_hwndToolbar, SendMessage);
}
/*****************************Private*Routine******************************\
* VideoCd_OnInitMenuPopup
*
\**************************************************************************/
void
VideoCd_OnInitMenuPopup(
HWND hwnd,
HMENU hMenu,
UINT item,
BOOL fSystemMenu
)
{
UINT uFlags;
if(item == 0)
{ // File menu
if(g_State & (VCD_IN_USE | VCD_NO_CD | VCD_DATA_CD_LOADED))
{
uFlags = (MF_BYCOMMAND | MF_GRAYED);
}
else
{
uFlags = (MF_BYCOMMAND | MF_ENABLED);
}
// Disable menu items until a movie is opened
EnableMenuItem(hMenu, IDM_FILE_CLOSE, uFlags);
EnableMenuItem(hMenu, IDM_MOVIE_STOP, uFlags);
EnableMenuItem(hMenu, IDM_MOVIE_PLAY, uFlags);
EnableMenuItem(hMenu, IDM_MOVIE_PAUSE, uFlags);
}
}
/*****************************Private*Routine******************************\
* VideoCd_OnGraphNotify
*
* This is where we get any notifications from the filter graph.
*
\**************************************************************************/
void
VideoCd_OnGraphNotify(
int stream
)
{
long lEventCode;
lEventCode = pMpegMovie->GetMovieEventCode();
switch(lEventCode)
{
case EC_FULLSCREEN_LOST:
SetPlayButtonsEnableState();
break;
case EC_USERABORT:
case EC_ERRORABORT:
VcdPlayerStopCmd();
SetPlayButtonsEnableState();
break;
case EC_COMPLETE:
VcdPlayerRewindCmd();
break;
default:
break;
}
}
/*****************************Private*Routine******************************\
* VideoCd_OnNotify
*
* This is where we get the text for tooltips
*
\**************************************************************************/
LRESULT
VideoCd_OnNotify(
HWND hwnd,
int idFrom,
NMHDR FAR* pnmhdr
)
{
switch(pnmhdr->code)
{
case TTN_NEEDTEXT:
{
LPTOOLTIPTEXT lpTt;
lpTt = (LPTOOLTIPTEXT)pnmhdr;
LoadString(hInst, (UINT) lpTt->hdr.idFrom, lpTt->szText,
sizeof(lpTt->szText));
}
break;
}
return 0;
}
/******************************Public*Routine******************************\
* SetPlayButtonsEnableState
*
* Sets the play buttons enable state to match the state of the current
* cdrom device. See below...
*
*
* VCD Player buttons enable state table
* --------------------------------------------------------------------
* -E=Enabled D=Disabled - Play - Pause - Eject - Stop - Other -
* --------------------------------------------------------------------
* -Disk in use - D - D - D - D - D -
* --------------------------------------------------------------------
* -No video cd or data cdrom - D - D - E - D - D -
* --------------------------------------------------------------------
* -Video cd (playing) - D - E - E - E - E -
* --------------------------------------------------------------------
* -Video cd (paused) - E - D - E - E - E -
* --------------------------------------------------------------------
* -Video cd (stopped) - E - D - E - D - E -
* --------------------------------------------------------------------
*
\**************************************************************************/
void
SetPlayButtonsEnableState(
void
)
{
BOOL fEnable, fPress;
BOOL fVideoCdLoaded;
/*
** Do we have a video cd loaded.
*/
if(g_State & (VCD_NO_CD | VCD_DATA_CD_LOADED | VCD_IN_USE))
{
fVideoCdLoaded = FALSE;
}
else
{
fVideoCdLoaded = TRUE;
}
/*
** Do the play button
*/
if(fVideoCdLoaded
&& ((g_State & VCD_STOPPED) || (g_State & VCD_PAUSED)))
{
fEnable = TRUE;
}
else
{
fEnable = FALSE;
}
SendMessage(g_hwndToolbar, TB_ENABLEBUTTON, IDM_MOVIE_PLAY, fEnable);
/*
** Do the stop button
*/
if(fVideoCdLoaded
&& ((g_State & VCD_PLAYING) || (g_State & VCD_PAUSED)))
{
fEnable = TRUE;
}
else
{
fEnable = FALSE;
}
SendMessage(g_hwndToolbar, TB_ENABLEBUTTON, IDM_MOVIE_STOP, fEnable);
/*
** Do the pause button
*/
if(fVideoCdLoaded && (g_State & VCD_PLAYING))
{
fEnable = TRUE;
}
else
{
fEnable = FALSE;
}
SendMessage(g_hwndToolbar, TB_ENABLEBUTTON, IDM_MOVIE_PAUSE, fEnable);
/*
** Do the remaining buttons
*/
/*
** Do the fullscreen button
*/
fPress = (fVideoCdLoaded && IsFullScreenMode());
SendMessage(g_hwndToolbar, TB_CHECKBUTTON, IDM_FULL_SCREEN, MAKELONG(fPress,0));
SendMessage(g_hwndToolbar, TB_ENABLEBUTTON, IDM_FULL_SCREEN, fVideoCdLoaded && (g_State & VCD_PLAYING));
}
/*****************************Private*Routine******************************\
* GetAdjustedClientRect
*
* Calculate the size of the client rect and then adjusts it to take into
* account the space taken by the toolbar and status bar.
*
\**************************************************************************/
void
GetAdjustedClientRect(
RECT *prc
)
{
RECT rcTool;
GetClientRect(hwndApp, prc);
if(IsWindowVisible(g_hwndToolbar))
{
GetWindowRect(g_hwndToolbar, &rcTool);
prc->top += (rcTool.bottom - rcTool.top);
}
}
/******************************Public*Routine******************************\
* IdStr
*
* Loads the given string resource ID into the passed storage.
*
\**************************************************************************/
LPCTSTR
IdStr(
int idResource
)
{
static TCHAR chBuffer[ STR_MAX_STRING_LEN ];
if(LoadString(hInst, idResource, chBuffer, STR_MAX_STRING_LEN) == 0)
{
return g_szEmpty;
}
return chBuffer;
}
/******************************Public*Routine******************************\
* SetFullScreenMode
*
\**************************************************************************/
void
SetFullScreenMode(BOOL bMode)
{
m_bFullScreen = bMode;
// Defer until we activate the movie
if(pMpegMovie->GetStateMovie() != State_Running)
{
if(bMode == TRUE)
return;
}
static HMENU hMenu;
static LONG lStyle;
static int xs, ys, cxs, cys;
HDC hdcScreen = GetDC(NULL);
int cx = GetDeviceCaps(hdcScreen,HORZRES);
int cy = GetDeviceCaps(hdcScreen,VERTRES);
ReleaseDC(NULL, hdcScreen);
if(bMode)
{
hMenu = GetMenu(hwndApp);
lStyle = GetWindowStyle(hwndApp);
WINDOWPLACEMENT wp;
wp.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(hwndApp, &wp);
xs = wp.rcNormalPosition.left;
ys = wp.rcNormalPosition.top;
cxs = wp.rcNormalPosition.right - xs;
cys = wp.rcNormalPosition.bottom - ys;
ShowWindow(g_hwndToolbar, SW_HIDE);
SetMenu(hwndApp, NULL);
SetWindowLong(hwndApp, GWL_STYLE, WS_POPUP | WS_VISIBLE);
SetWindowPos(hwndApp, HWND_TOP, 0, 0, cx, cy, SWP_NOACTIVATE);
ShowCursor(FALSE);
}
else
{
ShowCursor(TRUE);
ShowWindow(g_hwndToolbar, SW_SHOW);
SetMenu(hwndApp, hMenu);
SetWindowLong(hwndApp, GWL_STYLE, lStyle);
SetWindowPos(hwndApp, HWND_TOP, xs, ys, cxs, cys, SWP_NOACTIVATE);
}
}
/******************************Public*Routine******************************\
* IsFullScreenMode()
*
\**************************************************************************/
BOOL
IsFullScreenMode()
{
return m_bFullScreen;
}

View File

@@ -0,0 +1,301 @@
//------------------------------------------------------------------------------
// File: app.h
//
// Desc: DirectShow sample code - prototypes for the Renderless player
//
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
/* -------------------------------------------------------------------------
** Function prototypes
** -------------------------------------------------------------------------
*/
int DoMainLoop(void);
BOOL InitApplication(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE hInstance,int nCmdShow);
void UpdateMpegMovieRect(void);
void GetAdjustedClientRect(RECT *prc);
BOOL DrawStats(HDC hdc);
void CalcMovieRect(LPRECT lprc);
LPCTSTR IdStr(int idResource);
void UpdateSystemColors(void);
/* -------------------------------------------------------------------------
** Message crackers
** -------------------------------------------------------------------------
*/
/* void Cls_OnUser(HWND hwnd, WPARAM wParam, LPARAM lParam ) */
#define HANDLE_WM_USER(hwnd, wParam, lParam, fn) \
((fn)(hwnd, wParam, lParam), 0L)
#ifndef HANDLE_WM_NOTIFY
/* LRESULT Cls_OnNotify(HWND hwnd, int idFrom, NMHDR FAR* pnmhdr); */
#define HANDLE_WM_NOTIFY(hwnd, wParam, lParam, fn) \
(fn)((hwnd), (int)(wParam), (NMHDR FAR*)(lParam))
#endif
/* -------------------------------------------------------------------------
** VideoCd window class prototypes
** -------------------------------------------------------------------------
*/
extern "C" LRESULT CALLBACK
VideoCdWndProc(
HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam
);
void
VideoCd_OnClose(
HWND hwnd
);
BOOL
VideoCd_OnQueryEndSession(
HWND hwnd
);
void
VideoCd_OnDestroy(
HWND hwnd
);
void
VideoCd_OnCommand(
HWND hwnd,
int id,
HWND hwndCtl,
UINT codeNotify
);
void
VideoCd_OnPaint(
HWND hwnd
);
void
VideoCd_OnTimer(
HWND hwnd,
UINT id
);
BOOL
VideoCd_OnCreate(
HWND hwnd,
LPCREATESTRUCT lpCreateStruct
);
void
VideoCd_OnSize(
HWND hwnd,
UINT state,
int cx,
int cy
);
void
VideoCd_OnKeyUp(
HWND hwnd,
UINT vk,
BOOL fDown,
int cRepeat,
UINT flags
);
void
VideoCd_OnHScroll(
HWND hwnd,
HWND hwndCtl,
UINT code,
int pos
);
void
VideoCd_OnUser(
HWND hwnd,
WPARAM wParam,
LPARAM lParam
);
void
VideoCd_OnSysColorChange(
HWND hwnd
);
void
VideoCd_OnMenuSelect(
HWND hwnd,
HMENU hmenu,
int item,
HMENU hmenuPopup,
UINT flags
);
void
VideoCd_OnInitMenuPopup(
HWND hwnd,
HMENU hMenu,
UINT item,
BOOL fSystemMenu
);
#ifdef WM_NOTIFY
LRESULT
VideoCd_OnNotify(
HWND hwnd,
int idFrom,
NMHDR FAR* pnmhdr
);
#endif
void
VideoCd_OnGraphNotify(
int stream
);
void
VideoCd_OnDropFiles(
HWND hwnd,
HDROP hdrop);
void
SetPlayButtonsEnableState(
void
);
/* -------------------------------------------------------------------------
** Command processing functions
** -------------------------------------------------------------------------
*/
BOOL
VcdPlayerSetLog(
void
);
BOOL
VcdPlayerSetPerfLogFile(
void
);
BOOL
VcdPlayerOpenCmd(
void
);
BOOL
VcdPlayerCloseCmd(
void
);
BOOL
VcdPlayerPlayCmd(
void
);
BOOL
VcdPlayerStopCmd(
void
);
BOOL
VcdPlayerPauseCmd(
void
);
BOOL
VcdPlayerPauseCmd(
void
);
BOOL
VcdPlayerRewindCmd(
void
);
void
VcdPlayerSeekCmd(
REFTIME rtSeekBy
);
void
ProcessOpen(
TCHAR achFileName[][MAX_PATH],
DWORD dwNumFiles,
BOOL bPlay = FALSE
);
/* -------------------------------------------------------------------------
** Recent filename defines
** -------------------------------------------------------------------------
*/
typedef TCHAR RECENTFILES[MAX_PATH];
#define MAX_RECENT_FILES 5
#define ID_RECENT_FILE_BASE 500
int
GetRecentFiles(
int LastCount
);
int
SetRecentFiles(
TCHAR *FileName,
int iCount
);
/* -------------------------------------------------------------------------
** Global Variables
** -------------------------------------------------------------------------
*/
extern int cxMovie;
extern int cyMovie;
extern HWND hwndApp;
extern int cx;
extern int cy;
extern int xOffset;
extern int yOffset;
extern DWORD g_State;
extern TCHAR g_szPerfLog[];
extern int g_TimeFormat;
/* -------------------------------------------------------------------------
** Constants
** -------------------------------------------------------------------------
*/
#define LEFT_MARGIN 0
const DWORD MAXSTREAMS = 3;
/* -------------------------------------------------------------------------
** Video CD Player states
**
** These are bit flags
** -------------------------------------------------------------------------
*/
#define VCD_PLAYING 0x0001
#define VCD_STOPPED 0x0002
#define VCD_PAUSED 0x0004
#define VCD_SKIP_F 0x0008
#define VCD_SKIP_B 0x0010
#define VCD_FF 0x0020
#define VCD_RW 0x0040
#define VCD_SEEKING (VCD_FF | VCD_RW)
#define VCD_LOADED 0x0080
#define VCD_NO_CD 0x0100
#define VCD_DATA_CD_LOADED 0x0200
#define VCD_EDITING 0x0400
#define VCD_PAUSED_AND_MOVED 0x0800
#define VCD_PLAY_PENDING 0x1000
#define VCD_WAS_PLAYING 0x2000
#define VCD_IN_USE 0x4000
enum {PerformanceTimer = 32, StatusTimer = 33};

View File

@@ -0,0 +1,284 @@
//------------------------------------------------------------------------------
// File: commands.cpp
//
// Desc: DirectShow sample code - Processes commands from the user
//
// Copyright (c) 1994-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <streams.h>
#include <mmreg.h>
#include <commctrl.h>
#include "project.h"
#include <stdio.h>
extern void RepositionMovie(HWND hwnd);
extern CMpegMovie *pMpegMovie;
/******************************Public*Routine******************************\
* ProcessOpen
*
\**************************************************************************/
void
ProcessOpen(
TCHAR achFileName[][MAX_PATH],
DWORD dwNumFiles,
BOOL bPlay
)
{
/*
** If we currently have a video loaded we need to discard it here.
*/
if(g_State & VCD_LOADED)
{
VcdPlayerCloseCmd();
}
pMpegMovie = new CMpegMovie(hwndApp);
if(pMpegMovie)
{
HRESULT hr = pMpegMovie->OpenMovie(achFileName, dwNumFiles);
if(SUCCEEDED(hr))
{
g_State = (VCD_LOADED | VCD_STOPPED);
RepositionMovie(hwndApp);
InvalidateRect(hwndApp, NULL, TRUE);
if(bPlay)
{
pMpegMovie->PlayMovie();
}
}
else
{
MessageBox(hwndApp, TEXT("Failed to open the movie! "),
IdStr(STR_APP_TITLE), MB_OK);
pMpegMovie->CloseMovie();
delete pMpegMovie;
pMpegMovie = NULL;
}
}
InvalidateRect(hwndApp, NULL, FALSE);
UpdateWindow(hwndApp);
}
/******************************Public*Routine******************************\
* VcdPlayerOpenCmd
*
\**************************************************************************/
BOOL
VcdPlayerOpenCmd(
void
)
{
static OPENFILENAME ofn;
static BOOL fFirstTime = TRUE;
BOOL fRet = FALSE;
TCHAR achFileName[MAXSTREAMS][MAX_PATH];
TCHAR achFilter[MAX_PATH];
LPTSTR lp;
DWORD dwNumFiles = 0;
if(fFirstTime)
{
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hwndApp;
ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST |
OFN_SHAREAWARE | OFN_PATHMUSTEXIST;
}
lstrcpy(achFilter, IdStr(STR_FILE_FILTER));
ofn.lpstrFilter = achFilter;
/*
** Convert the resource string into to something suitable for
** GetOpenFileName ie. replace '#' characters with '\0' characters.
*/
for(lp = achFilter; *lp; lp++)
{
if(*lp == TEXT('#'))
{
*lp = TEXT('\0');
}
}
for (DWORD i = 0; i < MAXSTREAMS; i++)
{
ofn.lpstrFile = achFileName[i];
ofn.nMaxFile = sizeof(achFileName[i]) / sizeof(TCHAR);
ZeroMemory(achFileName[i], sizeof(achFileName[i]));
switch (i)
{
case 0:
// load first file
ofn.lpstrTitle = TEXT("Select First Media File");
break;
case 1:
// load first file
ofn.lpstrTitle = TEXT("Select Second Media File");
break;
case 2:
// load first file
ofn.lpstrTitle = TEXT("Select Third Media File");
break;
}
fRet = GetOpenFileName(&ofn);
if(!fRet)
{
break;
}
dwNumFiles++;
} // for i
fFirstTime = FALSE;
if (0 == dwNumFiles)
{
return fRet;
}
ProcessOpen(achFileName, dwNumFiles);
return fRet;
}
/******************************Public*Routine******************************\
* VcdPlayerCloseCmd
*
\**************************************************************************/
BOOL
VcdPlayerCloseCmd(
void
)
{
if(pMpegMovie)
{
g_State = VCD_NO_CD;
pMpegMovie->StopMovie();
pMpegMovie->CloseMovie();
delete pMpegMovie;
pMpegMovie = NULL;
}
// Redraw main window
InvalidateRect(hwndApp, NULL, FALSE);
UpdateWindow(hwndApp);
return TRUE;
}
/******************************Public*Routine******************************\
* VcdPlayerPlayCmd
*
\**************************************************************************/
BOOL
VcdPlayerPlayCmd(
void
)
{
BOOL fStopped = (g_State & VCD_STOPPED);
BOOL fPaused = (g_State & VCD_PAUSED);
if((fStopped || fPaused))
{
if(pMpegMovie)
{
pMpegMovie->PlayMovie();
}
g_State &= ~(fStopped ? VCD_STOPPED : VCD_PAUSED);
g_State |= VCD_PLAYING;
}
return TRUE;
}
/******************************Public*Routine******************************\
* VcdPlayerStopCmd
*
\**************************************************************************/
BOOL
VcdPlayerStopCmd(
void
)
{
BOOL fPlaying = (g_State & VCD_PLAYING);
BOOL fPaused = (g_State & VCD_PAUSED);
if((fPlaying || fPaused))
{
if(pMpegMovie)
{
pMpegMovie->StopMovie();
}
g_State &= ~(fPlaying ? VCD_PLAYING : VCD_PAUSED);
g_State |= VCD_STOPPED;
}
return TRUE;
}
/******************************Public*Routine******************************\
* VcdPlayerPauseCmd
*
\**************************************************************************/
BOOL
VcdPlayerPauseCmd(
void
)
{
BOOL fPlaying = (g_State & VCD_PLAYING);
BOOL fPaused = (g_State & VCD_PAUSED);
if(fPlaying)
{
if(pMpegMovie)
{
pMpegMovie->PauseMovie();
}
g_State &= ~VCD_PLAYING;
g_State |= VCD_PAUSED;
}
else if(fPaused)
{
if(pMpegMovie)
{
pMpegMovie->PlayMovie();
}
g_State &= ~VCD_PAUSED;
g_State |= VCD_PLAYING;
}
return TRUE;
}
/******************************Public*Routine******************************\
* VcdPlayerRewindCmd
*
\**************************************************************************/
BOOL
VcdPlayerRewindCmd(
void
)
{
if(pMpegMovie)
{
pMpegMovie->SeekToPosition((REFTIME)0,FALSE);
}
return TRUE;
}

View File

@@ -0,0 +1,626 @@
//------------------------------------------------------------------------------
// File: compositor.cpp
//
// Desc: DirectShow sample code - VMR-based Cube video player
//
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <streams.h>
#include <dvdmedia.h>
#include <mmreg.h>
#include <commctrl.h>
#include "project.h"
#include <stdarg.h>
#include <stdio.h>
/*****************************Private*Routine******************************\
* MakeD3DVector
*
\**************************************************************************/
D3DVECTOR
MakeD3DVector( float x, float y, float z )
{
D3DVECTOR ret;
ret.x = x;
ret.y = y;
ret.z = z;
return ret;
}
/*****************************Private*Routine******************************\
* MakeD3DVertex
*
\**************************************************************************/
D3DVERTEX
MakeD3DVertex( const D3DVECTOR& p, const D3DVECTOR& n, float tu, float tv )
{
D3DVERTEX ret;
ret.x = p.x; ret.y = p.y; ret.z = p.z;
ret.nx = n.x; ret.ny = n.y; ret.nz = n.z;
ret.tu = tu; ret.tv = tv;
return ret;
}
/*****************************Private*Routine******************************\
* Name: MatrixMultiply()
* Desc: Multiplies matrix B onto matrix A, as in: [Q] = [B] * [A].
\**************************************************************************/
VOID MatrixMultiply( D3DMATRIX& q, D3DMATRIX& a, D3DMATRIX& b )
{
FLOAT* pA = (FLOAT*)&a;
FLOAT* pB = (FLOAT*)&b;
FLOAT pM[16];
ZeroMemory( pM, sizeof(D3DMATRIX) );
for( DWORD i=0; i<4; i++ )
for( DWORD j=0; j<4; j++ )
for( DWORD k=0; k<4; k++ )
pM[4*i+j] += pA[4*k+j] * pB[4*i+k];
memcpy( &q, pM, sizeof(D3DMATRIX) );
}
/*****************************Private*Routine******************************\
* CreateCube()
*
* Sets up the vertices for a cube. Don't forget to set the texture
* coordinates for each vertex.
*
\**************************************************************************/
VOID
CreateCube(
D3DVERTEX* pVertices,
StreamSize * pSize
)
{
// Define the normals for the cube
D3DVECTOR n0 = MakeD3DVector( 0.0f, 0.0f, 1.0f ); // Front face
D3DVECTOR n4 = MakeD3DVector( 1.0f, 0.0f, 0.0f ); // Right face
D3DVECTOR n1 = MakeD3DVector( 0.0f, 0.0f, 1.0f ); // Back face
D3DVECTOR n5 = MakeD3DVector(-1.0f, 0.0f, 0.0f ); // Left face
D3DVECTOR n2 = MakeD3DVector( 0.0f, 1.0f, 0.0f ); // Top face
D3DVECTOR n3 = MakeD3DVector( 0.0f,-1.0f, 0.0f ); // Bottom face
// Front face
*pVertices++ = MakeD3DVertex( MakeD3DVector(-1.0f, 1.0f,-1.0f), n0, 0.0f, 0.0f );
*pVertices++ = MakeD3DVertex( MakeD3DVector( 1.0f, 1.0f,-1.0f), n0, pSize[0].cx , 0.0f );
*pVertices++ = MakeD3DVertex( MakeD3DVector(-1.0f,-1.0f,-1.0f), n0, 0.0f, pSize[0].cy );
*pVertices++ = MakeD3DVertex( MakeD3DVector( 1.0f,-1.0f,-1.0f), n0, pSize[0].cx , pSize[0].cy );
// Right face
*pVertices++ = MakeD3DVertex( MakeD3DVector( 1.0f, 1.0f,-1.0f), n4, 0.0f, 0.0f );
*pVertices++ = MakeD3DVertex( MakeD3DVector( 1.0f, 1.0f, 1.0f), n4, pSize[1].cx , 0.0f );
*pVertices++ = MakeD3DVertex( MakeD3DVector( 1.0f,-1.0f,-1.0f), n4, 0.0f, pSize[1].cy );
*pVertices++ = MakeD3DVertex( MakeD3DVector( 1.0f,-1.0f, 1.0f), n4, pSize[1].cx , pSize[1].cy );
// Top face
*pVertices++ = MakeD3DVertex( MakeD3DVector(-1.0f, 1.0f, 1.0f), n2, 0.0f, 0.0f );
*pVertices++ = MakeD3DVertex( MakeD3DVector( 1.0f, 1.0f, 1.0f), n2, pSize[2].cx , 0.0f );
*pVertices++ = MakeD3DVertex( MakeD3DVector(-1.0f, 1.0f,-1.0f), n2, 0.0f, pSize[2].cy );
*pVertices++ = MakeD3DVertex( MakeD3DVector( 1.0f, 1.0f,-1.0f), n2, pSize[2].cx , pSize[2].cy );
// Back face
*pVertices++ = MakeD3DVertex( MakeD3DVector(-1.0f, 1.0f, 1.0f), n1, pSize[0].cx , 0.0f );
*pVertices++ = MakeD3DVertex( MakeD3DVector(-1.0f,-1.0f, 1.0f), n1, pSize[0].cx , pSize[0].cy );
*pVertices++ = MakeD3DVertex( MakeD3DVector( 1.0f, 1.0f, 1.0f), n1, 0.0f, 0.0f );
*pVertices++ = MakeD3DVertex( MakeD3DVector( 1.0f,-1.0f, 1.0f), n1, 0.0f, pSize[0].cy );
// Left face
*pVertices++ = MakeD3DVertex( MakeD3DVector(-1.0f, 1.0f,-1.0f), n5, pSize[1].cx , 0.0f );
*pVertices++ = MakeD3DVertex( MakeD3DVector(-1.0f,-1.0f,-1.0f), n5, pSize[1].cx , pSize[1].cy );
*pVertices++ = MakeD3DVertex( MakeD3DVector(-1.0f, 1.0f, 1.0f), n5, 0.0f, 0.0f );
*pVertices++ = MakeD3DVertex( MakeD3DVector(-1.0f,-1.0f, 1.0f), n5, 0.0f, pSize[1].cy );
// Bottom face
*pVertices++ = MakeD3DVertex( MakeD3DVector(-1.0f,-1.0f, 1.0f), n3, 0.0f, 0.0f );
*pVertices++ = MakeD3DVertex( MakeD3DVector(-1.0f,-1.0f,-1.0f), n3, 0.0f, pSize[2].cy );
*pVertices++ = MakeD3DVertex( MakeD3DVector( 1.0f,-1.0f, 1.0f), n3, pSize[2].cx , 0.0f );
*pVertices++ = MakeD3DVertex( MakeD3DVector( 1.0f,-1.0f,-1.0f), n3, pSize[2].cx , pSize[2].cy );
}
/*****************************Private*Routine******************************\
* FrameMove
*
* Called once per frame, the call is used for animating the scene. The
* device is used for changing various render states, and the timekey is
* used for timing of the dynamics of the scene.
*
\**************************************************************************/
HRESULT
CMpegMovie::FrameMove(
LPDIRECT3DDEVICE7 pd3dDevice,
FLOAT fTimeKey
)
{
HRESULT hr = S_OK;
__try {
// Set the view matrix so that the camera is backed out along the z-axis,
// and looks down on the cube (rotating along the x-axis by -0.5 radians).
D3DMATRIX matView;
ZeroMemory(&matView, sizeof(D3DMATRIX));
matView._11 = 1.0f;
matView._22 = (FLOAT)cos(-0.5f);
matView._23 = (FLOAT)sin(-0.5f);
matView._32 = -(FLOAT)sin(-0.5f);
matView._33 = (FLOAT)cos(-0.5f);
matView._43 = 5.0f;
matView._44 = 1.0f;
CHECK_HR(hr = pd3dDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &matView));
// Set the world matrix to rotate along the y-axis, in sync with the timekey
D3DMATRIX matRotate, matRotate2, matWorld;
ZeroMemory(&matRotate, sizeof(D3DMATRIX));
ZeroMemory(&matRotate2, sizeof(D3DMATRIX));
ZeroMemory(&matWorld, sizeof(D3DMATRIX));
// rotate along y axis
matRotate._11 = (FLOAT)cos(fTimeKey);
matRotate._13 = (FLOAT)sin(fTimeKey);
matRotate._22 = 1.0f;
matRotate._31 = -(FLOAT)sin(fTimeKey);
matRotate._33 = (FLOAT)cos(fTimeKey);
matRotate._44 = 1.0f;
// rotate along z axis
matRotate2._11 = (FLOAT)cos(fTimeKey);
matRotate2._12 = (FLOAT)sin(fTimeKey);
matRotate2._21 = -(FLOAT)sin(fTimeKey);
matRotate2._22 = (FLOAT)cos(fTimeKey);
matRotate2._33 = 1.0f;
matRotate2._44 = 1.0f;
MatrixMultiply(matWorld, matRotate, matRotate2);
CHECK_HR(hr = pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &matWorld));
}
__finally {}
return hr;
}
/******************************Public*Routine******************************\
* GetSourceRectFromMediaType
*
\**************************************************************************/
RECT
GetSourceRectFromMediaType(
const AM_MEDIA_TYPE *pMediaType
)
{
RECT rRect = {0,0,0,0};
if (!pMediaType)
{
DbgLog((LOG_ERROR, 1, TEXT("pMediaType is NULL")));
return rRect;
}
if (!(pMediaType->pbFormat))
{
return rRect;
}
if ((pMediaType->formattype == FORMAT_VideoInfo) &&
(pMediaType->cbFormat >= sizeof(VIDEOINFOHEADER)))
{
rRect = (((VIDEOINFOHEADER*)(pMediaType->pbFormat))->rcSource);
}
else if ((pMediaType->formattype == FORMAT_VideoInfo2) &&
(pMediaType->cbFormat >= sizeof(VIDEOINFOHEADER2)))
{
rRect = (((VIDEOINFOHEADER2*)(pMediaType->pbFormat))->rcSource);
}
// DShow filters have the habit of sometimes not setting the src and dst
// rectangles, in this case we should imply that the these rectangles
// should be the same width and height as the bitmap in the media format.
if (IsRectEmpty(&rRect))
{
LPBITMAPINFOHEADER lpbi = GetbmiHeader(pMediaType);
if (lpbi)
{
SetRect(&rRect, 0, 0, abs(lpbi->biWidth), abs(lpbi->biHeight));
}
}
return rRect;
}
/*****************************Private*Routine******************************\
* GetbmiHeader
*
* Returns the bitmap info header associated with the specified CMediaType.
* Returns NULL if the CMediaType is not either of FORMAT_VideoInfo or
* FORMAT_VideoInfo2.
*
\**************************************************************************/
LPBITMAPINFOHEADER
GetbmiHeader(
const AM_MEDIA_TYPE *pMediaType
)
{
AMTRACE((TEXT("GetbmiHeader")));
if (!pMediaType)
{
DbgLog((LOG_ERROR, 1, TEXT("pMediaType is NULL")));
return NULL;
}
if (!(pMediaType->pbFormat))
{
DbgLog((LOG_ERROR, 1, TEXT("pMediaType->pbFormat is NULL")));
return NULL;
}
LPBITMAPINFOHEADER lpHeader = NULL;
if ((pMediaType->formattype == FORMAT_VideoInfo) &&
(pMediaType->cbFormat >= sizeof(VIDEOINFOHEADER)))
{
lpHeader = &(((VIDEOINFOHEADER*)(pMediaType->pbFormat))->bmiHeader);
}
else if ((pMediaType->formattype == FORMAT_VideoInfo2) &&
(pMediaType->cbFormat >= sizeof(VIDEOINFOHEADER2)))
{
lpHeader = &(((VIDEOINFOHEADER2*)(pMediaType->pbFormat))->bmiHeader);
}
return lpHeader;
}
/*****************************Private*Routine******************************\
* AllocateTextureMirror
*
\**************************************************************************/
// global data structures and static helper function for AllocateTextureMirror
const DDPIXELFORMAT g_rgTextMirFormats[] = {
{ sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 32, 0xff0000, 0xff00, 0xff, 0xff<<24ul},
{ sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 24, 0xff0000, 0xff00, 0xff, 0 },
{ sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16, 0x1f<<11, 0x3f<<5, 0x1f, 0 },
{ sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16, 0x1f<<10, 0x1f<<5, 0x1f, 0 }
};
const UINT g_cTextMirFormats = sizeof(g_rgTextMirFormats)/sizeof(DDPIXELFORMAT);
static UINT
NextPow2( UINT i )
{
UINT ret = 1;
while ( ret < i )
{
ret <<= 1;
}
return ret;
}
/*****************************Private*Routine******************************\
* AllocateTextureMirror
*
\**************************************************************************/
HRESULT
CMpegMovie::AllocateTextureMirror(
LPDIRECTDRAWSURFACE7 pddsVideo,
DWORD* lpdwWidth,
DWORD* lpdwHeight,
bool bNonPow2Cond
)
{
HRESULT hr = E_UNEXPECTED;
DDSURFACEDESC2 ddsd = {sizeof(ddsd)};
__try {
LPDIRECTDRAW7 pDD;
CHECK_HR(pddsVideo->GetDDInterface((LPVOID*)&pDD));
if (m_pDDSTextureMirror) {
CHECK_HR(hr = m_pDDSTextureMirror->GetSurfaceDesc(&ddsd));
// early out if mirror already exists and is large enough to accommodate pDDS
if (ddsd.dwWidth >= *lpdwWidth && ddsd.dwHeight >= *lpdwHeight) {
*lpdwWidth = ddsd.dwWidth;
*lpdwHeight = ddsd.dwHeight;
return S_OK;
}
*lpdwWidth = max(ddsd.dwWidth, *lpdwWidth);
*lpdwHeight = max(ddsd.dwHeight, *lpdwHeight);
}
RELEASE(m_pDDSTextureMirror);
// bump dimensions out to next power of 2
// if the 3D hardware needs it that way
if (!bNonPow2Cond) {
*lpdwWidth = NextPow2(*lpdwWidth);
*lpdwHeight = NextPow2(*lpdwHeight);
}
DDSURFACEDESC2 ddsd = {sizeof(ddsd)};
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
ddsd.dwWidth = *lpdwWidth;
ddsd.dwHeight = *lpdwHeight;
ddsd.ddsCaps.dwCaps |= DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
// loop over texture formats and return as soon as CreateSurface succeeds
for (UINT i = 0; i < g_cTextMirFormats; i++) {
// create texture mirror
ddsd.ddpfPixelFormat = g_rgTextMirFormats[i];
hr = pDD->CreateSurface(&ddsd, &m_pDDSTextureMirror, NULL);
if (SUCCEEDED(hr))
break;
}
RELEASE(pDD);
}
__finally {}
return hr;
}
/*****************************Private*Routine******************************\
* InitCompositionTarget
*
\**************************************************************************/
STDMETHODIMP
CMpegMovie::InitCompositionTarget(
IUnknown* lpUnk,
LPDIRECTDRAWSURFACE7 pddsRenderTarget
)
{
HRESULT hr = S_OK;
__try {
LPDIRECT3DDEVICE7 pd3dDevice = (LPDIRECT3DDEVICE7)lpUnk;
DDSURFACEDESC2 ddsd = {sizeof(DDSURFACEDESC2)};
CHECK_HR(hr = pddsRenderTarget->GetSurfaceDesc(&ddsd));
D3DVIEWPORT7 vp = { 0, 0, ddsd.dwWidth, ddsd.dwHeight, 0.0f, 1.0f };
CHECK_HR(hr = pd3dDevice->SetViewport(&vp));
//
// Remind the CompositeImage (see below) to init the cube vertices.
// We can't do it here because we don't know the size of the movie
// being played yet.
//
m_bInitCube = true;
// For simplicity, just use ambient lighting and a white material
D3DMATERIAL7 mtrl;
ZeroMemory(&mtrl, sizeof(mtrl));
mtrl.diffuse.r = mtrl.diffuse.g = mtrl.diffuse.b = 1.0f;
mtrl.ambient.r = mtrl.ambient.g = mtrl.ambient.b = 1.0f;
CHECK_HR(hr = pd3dDevice->SetMaterial(&mtrl));
CHECK_HR(hr = pd3dDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff));
// Set the projection matrix. Note that the view and world matrices are
// set in the App_FrameMove() function, so they can be animated each
// frame.
D3DMATRIX matProj;
ZeroMemory(&matProj, sizeof(D3DMATRIX));
matProj._11 = 2.0f;
matProj._22 = 2.0f;
matProj._33 = 1.0f;
matProj._34 = 1.0f;
matProj._43 = -1.0f;
CHECK_HR(hr = pd3dDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &matProj));
}
__finally {
};
return hr;
}
/*****************************Private*Routine******************************\
* CompositeImage
*
\**************************************************************************/
STDMETHODIMP
CMpegMovie::CompositeImage(
IUnknown* lpUnk,
LPDIRECTDRAWSURFACE7 pddsRenderTarget,
AM_MEDIA_TYPE* pmtRenderTarget,
REFERENCE_TIME rtStart,
REFERENCE_TIME rtEnd,
DWORD dwMapped,
VMRVIDEOSTREAMINFO* pStrmInfo,
UINT cStreams
)
{
LPDIRECT3DDEVICE7 pd3dDevice = (LPDIRECT3DDEVICE7)lpUnk;
HRESULT hr = S_OK;
bool bInScene = false;
__try
{
LPDIRECTDRAWSURFACE7 pDDS;
//
// First time thru init the Cube compositor
//
if (m_bInitCube)
{
// if the dimensions are not 0, one of the surfaces is not a texture and we need to create a texture mirror
if (m_dwTexMirrorWidth && m_dwTexMirrorHeight)
{
hr = AllocateTextureMirror(pStrmInfo->pddsVideoSurface, &m_dwTexMirrorWidth, &m_dwTexMirrorHeight,
DoesSupportNonPow2CondCap(pd3dDevice));
}
m_bInitCube = false;
}
// Rotate the Cube
CHECK_HR(hr = FrameMove(pd3dDevice, ConvertToMilliseconds(rtStart) * 0.0005f));
// Clear the viewport to dark gray
CHECK_HR(hr = pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, 0x00404040, 1.0f, 0L));
cStreams = min(MAXSTREAMS, cStreams);
StreamSize Sizes[MAXSTREAMS];
for (DWORD j = 0; j < MAXSTREAMS; j++)
{
int iStream = j % cStreams;
if (m_StreamInfo[pStrmInfo[iStream].dwStrmID].bTexture)
{
Sizes[j].cx = (FLOAT)WIDTH(&m_StreamInfo[pStrmInfo[iStream].dwStrmID].SourceRect) / (FLOAT)pStrmInfo[iStream].dwWidth;
Sizes[j].cy = (FLOAT)HEIGHT(&m_StreamInfo[pStrmInfo[iStream].dwStrmID].SourceRect) / (FLOAT)pStrmInfo[iStream].dwHeight;
}
else
{
Sizes[j].cx = (FLOAT)WIDTH(&m_StreamInfo[pStrmInfo[iStream].dwStrmID].SourceRect) / (FLOAT)m_dwTexMirrorWidth;
Sizes[j].cy = (FLOAT)HEIGHT(&m_StreamInfo[pStrmInfo[iStream].dwStrmID].SourceRect) / (FLOAT)m_dwTexMirrorHeight;
}
}
CreateCube(m_pCubeVertices, Sizes);
// Begin the scene
CHECK_HR(hr = pd3dDevice->BeginScene());
bInScene = true;
for (unsigned int i = 0; i < MAXSTREAMS; i++)
{
int iStream = i % cStreams;
//
// Make sure we are dealing with a texture surface - if not
// copy the stream to the mirror surface.
//
if (m_StreamInfo[pStrmInfo[iStream].dwStrmID].bTexture)
{
pDDS = pStrmInfo[iStream].pddsVideoSurface;
}
else
{
RECT r = { 0, 0, pStrmInfo->dwWidth, pStrmInfo->dwHeight };
pDDS = m_pDDSTextureMirror;
CHECK_HR(hr = pDDS->Blt(&r, pStrmInfo[iStream].pddsVideoSurface, &r, DDBLT_WAIT, NULL));
}
// Prepare the texture stages
CHECK_HR(hr = pd3dDevice->SetTexture(0, pDDS));
if (DoesSupportAnisoCap(pd3dDevice))
{
CHECK_HR(hr = pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTFG_ANISOTROPIC));
CHECK_HR(hr = pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_ANISOTROPIC));
CHECK_HR(hr = pd3dDevice->SetTextureStageState( 0, D3DTSS_MAXANISOTROPY, 4));
}
else if (DoesSupportLinearCap(pd3dDevice))
{
CHECK_HR(hr = pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTFG_LINEAR));
CHECK_HR(hr = pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR));
}
else
{
CHECK_HR(hr = pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTFG_POINT));
CHECK_HR(hr = pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_POINT));
}
CHECK_HR(hr = pd3dDevice->SetTextureStageState( 0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP));
// Draw the faces of the cube
CHECK_HR(hr = pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX,
m_pCubeVertices+(4*i), 4, NULL));
CHECK_HR(hr = pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX,
m_pCubeVertices+(4*i)+12, 4, NULL));
} // for i
}
__finally
{
if (bInScene) {
// End the scene.
pd3dDevice->EndScene();
}
}
return S_OK;
}
/*****************************Private*Routine******************************\
* SetStreamMediaType
*
\**************************************************************************/
HRESULT CMpegMovie::SetStreamMediaType(DWORD dwStrmID, AM_MEDIA_TYPE *pmt, BOOL fTexture)
{
if (pmt)
{
m_StreamInfo[dwStrmID].bTexture = fTexture;
m_StreamInfo[dwStrmID].SourceRect = GetSourceRectFromMediaType(pmt);
if (!fTexture)
{
// choose the largest measure in each dimension
m_dwTexMirrorWidth = max(m_dwTexMirrorWidth, (DWORD)WIDTH(&m_StreamInfo[dwStrmID].SourceRect));
m_dwTexMirrorHeight = max(m_dwTexMirrorHeight, (DWORD)HEIGHT(&m_StreamInfo[dwStrmID].SourceRect));
}
}
return S_OK;
}
/*****************************Private*Routine******************************\
* DoesSupportNonPow2CondCap
*
\**************************************************************************/
bool CMpegMovie::DoesSupportNonPow2CondCap(LPDIRECT3DDEVICE7 pD3DDevice)
{
ASSERT(pD3DDevice);
D3DDEVICEDESC7 ddDesc;
if (!(DD_OK == pD3DDevice->GetCaps(&ddDesc)))
{
return false;
}
return (ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) ? true : false;
}
/*****************************Private*Routine******************************\
* DoesSupportAnisoCap
*
\**************************************************************************/
bool CMpegMovie::DoesSupportAnisoCap(LPDIRECT3DDEVICE7 pD3DDevice)
{
ASSERT(pD3DDevice);
D3DDEVICEDESC7 ddDesc;
if (!(DD_OK == pD3DDevice->GetCaps(&ddDesc)))
{
return false;
}
bool bMag = (ddDesc.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC) ? true : false;
bool bMin = (ddDesc.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) ? true : false;
return (bMag && bMin);
}
/*****************************Private*Routine******************************\
* DoesSupportLinearCap
*
\**************************************************************************/
bool CMpegMovie::DoesSupportLinearCap(LPDIRECT3DDEVICE7 pD3DDevice)
{
ASSERT(pD3DDevice);
D3DDEVICEDESC7 ddDesc;
if (!(DD_OK == pD3DDevice->GetCaps(&ddDesc)))
{
return false;
}
bool bMag = (ddDesc.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_MAGFLINEAR) ? true : false;
bool bMin = (ddDesc.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR) ? true : false;
return (bMag && bMin);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,231 @@
//Microsoft Developer Studio generated resource script.
//
#include "resrc1.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
#include "resource.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
/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
IDR_TOOLBAR BITMAP DISCARDABLE "toolbar.bmp"
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDR_VIDEOCD_ICON ICON DISCARDABLE "cube.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDR_MAIN_MENU MENU DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "&Open Video Files...\tCtrl+O", IDM_FILE_OPEN
MENUITEM "&Close", IDM_FILE_CLOSE
MENUITEM SEPARATOR
MENUITEM "&Play\tCtrl+P", IDM_MOVIE_PLAY
MENUITEM "Pa&use\tCtrl+U", IDM_MOVIE_PAUSE
MENUITEM "&Stop\tCtrl+S", IDM_MOVIE_STOP
MENUITEM SEPARATOR
MENUITEM "Ex&it\tCtrl+X", IDM_FILE_EXIT
END
POPUP "&Help"
BEGIN
MENUITEM "&About Cube Player...", IDM_FILE_ABOUT
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_ABOUTBOX DIALOG DISCARDABLE 0, 0, 235, 55
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About Cube Player"
FONT 8, "MS Shell Dlg"
BEGIN
ICON IDR_VIDEOCD_ICON,-1,11,17,20,20
LTEXT "DirectShow VMR Cube Player Sample",-1,40,10,131,8,
SS_NOPREFIX
LTEXT "Copyright (C) 1999-2001 Microsoft Corporation",-1,40,34,
188,8
DEFPUSHBUTTON "OK",IDOK,178,7,50,14,WS_GROUP
LTEXT "Version 8.1",-1,40,22,119,8,SS_NOPREFIX
END
/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//
IDR_ACCELERATOR ACCELERATORS DISCARDABLE
BEGIN
"F", IDM_MOVIE_FULLSCREEN, VIRTKEY, CONTROL, NOINVERT
"O", IDM_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT
"P", IDM_MOVIE_PLAY, VIRTKEY, CONTROL, NOINVERT
"S", IDM_MOVIE_STOP, VIRTKEY, CONTROL, NOINVERT
"T", ID_FILE_OPENSECONDVIDEO, VIRTKEY, CONTROL, NOINVERT
"U", IDM_MOVIE_PAUSE, VIRTKEY, CONTROL, NOINVERT
"X", IDM_FILE_EXIT, VIRTKEY, CONTROL, NOINVERT
END
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resrc1.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
"#include ""windows.h""\r\n"
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
"#include ""resource.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 8,1,0,0
PRODUCTVERSION 8,1,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "This sample requires Windows XP or greater.\0"
VALUE "CompanyName", "Microsoft\0"
VALUE "FileDescription", "Cube Application\0"
VALUE "FileVersion", "8.10\0"
VALUE "InternalName", "VMR Cube\0"
VALUE "LegalCopyright", "Copyright (c) 2000-2001 Microsoft Corporation\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "Cube.EXE\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "DirectX 8.1 SDK\0"
VALUE "ProductVersion", "8.1\0"
VALUE "SpecialBuild", "\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // !_MAC
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDM_MOVIE_STOP "Stop"
IDM_MOVIE_PLAY "Play"
IDM_MOVIE_PAUSE "Pause"
IDM_FULL_SCREEN "Full screen playback"
END
STRINGTABLE DISCARDABLE
BEGIN
STR_FILE_OPEN "Open a new movie"
STR_FILE_CLOSE "Close the movie"
STR_FILE_EXIT "Quit Cube player"
END
STRINGTABLE DISCARDABLE
BEGIN
STR_SYSMENU_RESTORE "Restore the window to normal size"
STR_SYSMENU_MOVE "Changes the window position"
STR_SYSMENU_MINIMIZE "Reduce the window to an icon"
STR_SYSMENU_CLOSE "Closes the window"
STR_SYSMENU_MAXIMIZE "Enlarges the window to its maximum size"
STR_SYSMENU_TASK_LIST "Opens the task list"
END
STRINGTABLE DISCARDABLE
BEGIN
STR_FILE_FILTER "All Movies#*.mpg;*.avi;*.dat;*.mov#Mpeg Files (*.mpg)#*.mpg#Video CD Files (*.dat)#*.dat#QuickTime Files (*.mov)#*.mov#All Files (*.*)#*.*#"
STR_APP_TITLE "VMR Cube Player"
STR_APP_TITLE_LOADED "VMR Cube Player - %s"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -0,0 +1,29 @@
//------------------------------------------------------------------------------
// File: project.h
//
// Desc: DirectShow sample code - main header file for Renderless player
//
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include "app.h"
#include "vcdplyer.h"
#include "resource.h"
#ifndef __RELEASE_DEFINED
#define __RELEASE_DEFINED
template<typename T>
__inline void RELEASE( T* &p )
{
if( p ) {
p->Release();
p = NULL;
}
}
#endif
#ifndef CHECK_HR
#define CHECK_HR(expr) { if (FAILED(expr)) __leave; };
#endif

View File

@@ -0,0 +1,8 @@
Windows XP DirectShow Sample -- Cube
------------------------------------
This sample demonstrates using the Video Mixing Renderer and
a plug-in compositor to render video on a spinning cube.
NOTE: This sample requires Windows XP (or greater) functionality
and will exit on other systems.

View File

@@ -0,0 +1,80 @@
//------------------------------------------------------------------------------
// File: resource.h
//
// Desc: DirectShow sample code - resource header file for Cube player
//
// Copyright (c) 1995 - 2001, Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#define IDC_STATIC -1
#define STR_MAX_STRING_LEN 256
#define IDX_SEPARATOR -1
#define IDX_1 0
#define IDX_2 1
#define IDX_3 2
#define IDX_4 3
#define IDX_5 4
#define IDX_6 5
#define IDX_7 6
#define IDX_8 7
#define IDX_10 9
#define IDX_11 10
#define DEFAULT_TBAR_SIZE 6
#define NUMBER_OF_BITMAPS 11
#define ID_TOOLBAR 9
#define IDD_ABOUTBOX 20
#define IDR_MAIN_MENU 101
#define IDR_TOOLBAR 102
#define IDR_VIDEOCD_ICON 103
#define IDR_ACCELERATOR 104
#define IDM_FILE_OPEN 40001
#define IDM_FILE_CLOSE 40002
#define IDM_FILE_EXIT 40003
#define IDM_FILE_ABOUT 40004
// Toolbar commands
#define IDM_MOVIE_STOP 40010
#define IDM_MOVIE_PLAY 40011
#define IDM_MOVIE_PAUSE 40012
#define IDM_FULL_SCREEN 40013
#define IDM_MOVIE_FULLSCREEN 40014
#define MENU_STRING_BASE 1000
// File
#define STR_FILE_OPEN IDM_FILE_OPEN + MENU_STRING_BASE
#define STR_FILE_CLOSE IDM_FILE_CLOSE + MENU_STRING_BASE
#define STR_FILE_EXIT IDM_FILE_EXIT + MENU_STRING_BASE
// System Menu
#define STR_SYSMENU_RESTORE 1800
#define STR_SYSMENU_MOVE 1801
#define STR_SYSMENU_MINIMIZE 1802
#define STR_SYSMENU_CLOSE 1803
#define STR_SYSMENU_MAXIMIZE 1804
#define STR_SYSMENU_TASK_LIST 1805
#define STR_FILE_FILTER 2000
#define STR_APP_TITLE 2001
#define STR_APP_TITLE_LOADED 2002
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40002
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -0,0 +1,16 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by Cube.rc
//
#define ID_FILE_OPENSECONDVIDEO 40005
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40007
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 B

View File

@@ -0,0 +1,567 @@
//------------------------------------------------------------------------------
// File: vcdplyer.cpp
//
// Desc: DirectShow sample code - VMR-based Cube video player
//
// Copyright (c) 1994-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <streams.h>
#include <mmreg.h>
#include <commctrl.h>
#include <atlbase.h>
#include "project.h"
#include <stdarg.h>
#include <stdio.h>
#define MY_USER_ID 0x1234ACDE
/******************************Public*Routine******************************\
* CMpegMovie
*
* Constructors and destructors
*
\**************************************************************************/
CMpegMovie::CMpegMovie(HWND hwndApplication)
: CUnknown(NAME("Allocator Presenter"), NULL),
m_hwndApp(hwndApplication),
m_bInitCube(false),
m_pDDSTextureMirror(NULL),
m_MediaEvent(NULL),
m_Mode(MOVIE_NOTOPENED),
m_Fg(NULL),
m_Gb(NULL),
m_Mc(NULL),
m_Me(NULL),
m_Wc(NULL),
m_Ms(NULL),
m_dwRegister(0),
m_dwTexMirrorWidth(0),
m_dwTexMirrorHeight(0)
{
AddRef();
}
CMpegMovie::~CMpegMovie() {
;
}
/******************************Public*Routine******************************\
* NonDelegatingQueryInterface
*
\**************************************************************************/
STDMETHODIMP
CMpegMovie::NonDelegatingQueryInterface(
REFIID riid,
void** ppv
)
{
if (riid == IID_IVMRImageCompositor) {
return GetInterface((IVMRImageCompositor*)this, ppv);
}
return CUnknown::NonDelegatingQueryInterface(riid,ppv);
}
/*****************************Private*Routine******************************\
* SetRenderingMode
*
\**************************************************************************/
HRESULT
SetRenderingMode(
IBaseFilter* pBaseFilter,
VMRMode mode,
int iNumStreams,
IVMRImageCompositor* lpCompositor
)
{
IVMRFilterConfig* pConfig = NULL;
HRESULT hr = S_OK;
__try {
CHECK_HR(hr = pBaseFilter->QueryInterface(IID_IVMRFilterConfig,
(LPVOID *)&pConfig));
//
// If you are pluging in a compositor you have to be in
// mixing mode, that is, iNumStreams needs to be greater than 0.
//
if (lpCompositor && iNumStreams < 1) {
iNumStreams = 1;
}
if (iNumStreams) {
CHECK_HR(hr = pConfig->SetNumberOfStreams(iNumStreams));
}
if (lpCompositor) {
CHECK_HR(hr = pConfig->SetImageCompositor(lpCompositor));
}
CHECK_HR(hr = pConfig->SetRenderingMode(mode));
}
__finally {
RELEASE(pConfig);
}
return hr;
}
/*****************************Private*Routine******************************\
* AddVideoMixingRendererToFG()
*
\**************************************************************************/
HRESULT
CMpegMovie::AddVideoMixingRendererToFG(DWORD dwStreams)
{
IBaseFilter* pBF = NULL;
HRESULT hRes = S_OK;
__try {
CHECK_HR(hRes = CoCreateInstance(CLSID_VideoMixingRenderer,
NULL, CLSCTX_INPROC,IID_IBaseFilter,
(LPVOID *)&pBF));
CHECK_HR(hRes = m_Fg->AddFilter(pBF, L"Video Mixing Renderer"));
CHECK_HR(hRes = SetRenderingMode(pBF, VMRMode_Windowless,
dwStreams, (IVMRImageCompositor*)this));
CHECK_HR(hRes = pBF->QueryInterface(IID_IVMRWindowlessControl, (LPVOID *)&m_Wc));
CHECK_HR(hRes = m_Wc->SetVideoClippingWindow(m_hwndApp));
CHECK_HR(hRes = m_Wc->SetAspectRatioMode(VMR_ARMODE_LETTER_BOX));
}
__finally {
RELEASE(pBF);
}
return hRes;
}
HRESULT AddToRot(IUnknown *pUnkGraph, DWORD *pdwRegister)
{
IMoniker * pMoniker;
IRunningObjectTable *pROT;
if (FAILED(GetRunningObjectTable(0, &pROT))) {
return E_FAIL;
}
WCHAR wsz[256];
wsprintfW(wsz, L"FilterGraph %08p pid %08x", (DWORD_PTR)pUnkGraph, GetCurrentProcessId());
HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker);
if (SUCCEEDED(hr)) {
hr = pROT->Register(0, pUnkGraph, pMoniker, pdwRegister);
pMoniker->Release();
}
pROT->Release();
return hr;
}
/******************************Public*Routine******************************\
* OpenMovie
*
\**************************************************************************/
HRESULT
CMpegMovie::OpenMovie(
TCHAR achFileName[][MAX_PATH],
DWORD dwNumFiles
)
{
USES_CONVERSION;
IUnknown *pUnk = NULL;
HRESULT hres = S_OK;
WCHAR FileName[MAX_PATH];
__try {
CHECK_HR(hres = CoCreateInstance(CLSID_FilterGraph,
NULL, CLSCTX_INPROC,
IID_IUnknown, (LPVOID *)&pUnk));
m_Mode = MOVIE_OPENED;
CHECK_HR(hres = pUnk->QueryInterface(IID_IFilterGraph, (LPVOID *)&m_Fg));
CHECK_HR(hres = AddVideoMixingRendererToFG(4));
CHECK_HR(hres = pUnk->QueryInterface(IID_IGraphBuilder, (LPVOID *)&m_Gb));
AddToRot(m_Gb, &m_dwRegister);
for (DWORD i = 0; i < dwNumFiles; i++)
{
wcscpy(FileName, T2W(achFileName[i]));
CHECK_HR(hres = m_Gb->RenderFile(FileName, NULL));
}
CHECK_HR(hres = pUnk->QueryInterface(IID_IMediaControl, (LPVOID *)&m_Mc));
//
// Not being able to get the IMediaEvent interface does
// necessarly mean that we can't play the graph.
//
pUnk->QueryInterface(IID_IMediaEvent, (LPVOID *)&m_Me);
GetMovieEventHandle();
pUnk->QueryInterface(IID_IMediaSeeking, (LPVOID *)&m_Ms);
}
__finally {
if (FAILED(hres)) {
RELEASE(m_Ms);
RELEASE(m_Me);
RELEASE(m_Mc);
RELEASE(m_Gb);
RELEASE(m_Fg);
}
RELEASE(pUnk);
}
return hres;
}
void RemoveFromRot(DWORD pdwRegister)
{
IRunningObjectTable *pROT;
if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) {
pROT->Revoke(pdwRegister);
pROT->Release();
}
}
/******************************Public*Routine******************************\
* CloseMovie
*
\**************************************************************************/
DWORD
CMpegMovie::CloseMovie(
)
{
m_Mode = MOVIE_NOTOPENED;
RELEASE(m_Ms);
RELEASE(m_Mc);
RELEASE(m_Me);
RELEASE(m_Gb);
RELEASE(m_Fg);
RELEASE(m_Wc);
RELEASE(m_pDDSTextureMirror);
if (m_dwRegister)
{
RemoveFromRot(m_dwRegister);
m_dwRegister = 0;
}
return 0L;
}
/******************************Public*Routine******************************\
* RepaintVideo
*
\**************************************************************************/
BOOL
CMpegMovie::RepaintVideo(
HWND hwnd,
HDC hdc
)
{
BOOL bRet = FALSE;
if (m_Wc) {
bRet = (m_Wc->RepaintVideo(hwnd, hdc) == S_OK);
}
return bRet;
}
/******************************Public*Routine******************************\
* PutMoviePosition
*
\**************************************************************************/
BOOL
CMpegMovie::PutMoviePosition(
LONG x,
LONG y,
LONG cx,
LONG cy
)
{
RECT rc;
SetRect(&rc, x, y, x + cx, y + cy);
BOOL bRet = (m_Wc->SetVideoPosition(NULL, &rc) == S_OK);
return bRet;
}
/******************************Public*Routine******************************\
* PlayMovie
*
\**************************************************************************/
BOOL
CMpegMovie::PlayMovie(
)
{
REFTIME rt;
REFTIME rtAbs;
REFTIME rtDur;
rt = GetCurrentPosition();
rtDur = GetDuration();
//
// If we are near the end of the movie seek to the start, otherwise
// stay where we are.
//
rtAbs = rt - rtDur;
if (rtAbs < (REFTIME)0) {
rtAbs = -rtAbs;
}
if (rtAbs <= (REFTIME)1) {
SeekToPosition((REFTIME)0,FALSE);
}
//
// Change mode after setting m_Mode but before starting the graph
//
m_Mode = MOVIE_PLAYING;
HRESULT hr = m_Mc->Run();
ASSERT(SUCCEEDED(hr));
return TRUE;
}
/******************************Public*Routine******************************\
* PauseMovie
*
\**************************************************************************/
BOOL
CMpegMovie::PauseMovie(
)
{
m_Mode = MOVIE_PAUSED;
HRESULT hr = m_Mc->Pause();
ASSERT(SUCCEEDED(hr));
return TRUE;
}
/******************************Public*Routine******************************\
* GetStateMovie
*
\**************************************************************************/
OAFilterState
CMpegMovie::GetStateMovie(
)
{
OAFilterState State;
HRESULT hr = m_Mc->GetState(INFINITE,&State);
ASSERT(SUCCEEDED(hr));
return State;
}
/******************************Public*Routine******************************\
* StopMovie
*
\**************************************************************************/
BOOL
CMpegMovie::StopMovie(
)
{
m_Mode = MOVIE_STOPPED;
HRESULT hr = m_Mc->Stop();
ASSERT(SUCCEEDED(hr));
return TRUE;
}
/******************************Public*Routine******************************\
* GetMediaEventHandle
*
* Returns the IMediaEvent event hamdle for the filter graph iff the
* filter graph exists.
*
\**************************************************************************/
HANDLE
CMpegMovie::GetMovieEventHandle(
)
{
HRESULT hr;
if (m_Me != NULL) {
if ( m_MediaEvent == NULL) {
hr = m_Me->GetEventHandle((OAEVENT *)&m_MediaEvent);
}
}
else {
m_MediaEvent = NULL;
}
return m_MediaEvent;
}
/******************************Public*Routine******************************\
* GetMovieEventCode
*
\**************************************************************************/
long
CMpegMovie::GetMovieEventCode()
{
HRESULT hr;
long lEventCode;
LONG_PTR lParam1, lParam2;
if (m_Me != NULL) {
hr = m_Me->GetEvent(&lEventCode, &lParam1, &lParam2, 0);
if(SUCCEEDED(hr))
{
hr = m_Me->FreeEventParams(lEventCode, lParam1, lParam2);
return lEventCode;
}
}
return 0L;
}
/******************************Public*Routine******************************\
* GetDuration
*
* Returns the duration of the current movie
*
\**************************************************************************/
REFTIME
CMpegMovie::GetDuration()
{
HRESULT hr;
LONGLONG Duration;
// Should we seek using IMediaSelection
if (m_Ms != NULL && m_TimeFormat != TIME_FORMAT_MEDIA_TIME) {
hr = m_Ms->GetDuration(&Duration);
if (SUCCEEDED(hr)) {
return double(Duration);
}
} else if (m_Ms != NULL) {
hr = m_Ms->GetDuration(&Duration);
if (SUCCEEDED(hr)) {
return double(Duration) / UNITS;
}
}
return 0;
}
/******************************Public*Routine******************************\
* GetCurrentPosition
*
* Returns the duration of the current movie
*
\**************************************************************************/
REFTIME
CMpegMovie::GetCurrentPosition()
{
REFTIME rt = (REFTIME)0;
HRESULT hr;
LONGLONG Position;
// Should we return a media position
if (m_Ms != NULL && m_TimeFormat != TIME_FORMAT_MEDIA_TIME) {
hr = m_Ms->GetPositions(&Position, NULL);
if (SUCCEEDED(hr)) {
return double(Position);
}
} else if (m_Ms != NULL) {
hr = m_Ms->GetPositions(&Position, NULL);
if (SUCCEEDED(hr)) {
return double(Position) / UNITS;
}
}
return rt;
}
/*****************************Private*Routine******************************\
* SeekToPosition
*
\**************************************************************************/
BOOL
CMpegMovie::SeekToPosition(
REFTIME rt,
BOOL bFlushData
)
{
HRESULT hr=S_OK;
LONGLONG llTime =
LONGLONG(m_TimeFormat == TIME_FORMAT_MEDIA_TIME ? rt * double(UNITS) : rt);
if (m_Ms != NULL) {
FILTER_STATE fs;
hr = m_Mc->GetState(100, (OAFilterState *)&fs);
hr = m_Ms->SetPositions(&llTime, AM_SEEKING_AbsolutePositioning, NULL, 0);
// This gets new data through to the renderers
if (fs == State_Stopped && bFlushData){
hr = m_Mc->Pause();
hr = m_Mc->GetState(INFINITE, (OAFilterState *)&fs);
hr = m_Mc->Stop();
}
if (SUCCEEDED(hr)) {
return TRUE;
}
}
return FALSE;
}
/*****************************Private*Routine******************************\
* VerifyVMR
*
\**************************************************************************/
BOOL VerifyVMR(void)
{
HRESULT hres;
// Verify that the VMR exists on this system
IBaseFilter* pBF = NULL;
hres = CoCreateInstance(CLSID_VideoMixingRenderer,
NULL,
CLSCTX_INPROC,
IID_IBaseFilter,
(LPVOID *)&pBF);
if(SUCCEEDED(hres))
{
pBF->Release();
return TRUE;
}
else
{
MessageBox(hwndApp,
TEXT("This application requires the Video Mixing Renderer, which is present\r\n")
TEXT("only on Windows XP.\r\n\r\n")
TEXT("The Video Mixing Renderer (VMR) is also not enabled when viewing a \r\n")
TEXT("remote Windows XP machine through a Remote Desktop session.\r\n")
TEXT("You can run VMR-enabled applications only on your local machine.")
TEXT("\r\n\r\nThis sample will now exit."),
TEXT("Video Mixing Renderer capabilities are required"), MB_OK);
return FALSE;
}
}

View File

@@ -0,0 +1,146 @@
//------------------------------------------------------------------------------
// File: vcdplyer.h
//
// Desc: DirectShow sample code - header file for CMpegMovie class
//
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <ddraw.h>
#define D3D_OVERLOADS
#include <d3d.h>
/* -------------------------------------------------------------------------
** CMpegMovie - an Mpeg movie playback class.
** -------------------------------------------------------------------------
*/
enum EMpegMovieMode { MOVIE_NOTOPENED = 0x00,
MOVIE_OPENED = 0x01,
MOVIE_PLAYING = 0x02,
MOVIE_STOPPED = 0x03,
MOVIE_PAUSED = 0x04 };
#define NUM_CUBE_VERTICES (4*6)
BOOL VerifyVMR(void);
struct StreamInfo
{
RECT SourceRect;
BOOL bTexture;
};
struct StreamSize
{
float cx;
float cy;
};
class CMpegMovie :
public CUnknown,
public IVMRImageCompositor
{
private:
bool DoesSupportNonPow2CondCap(LPDIRECT3DDEVICE7 pD3DDevice);
bool DoesSupportLinearCap(LPDIRECT3DDEVICE7 pD3DDevice);
bool DoesSupportAnisoCap(LPDIRECT3DDEVICE7 pD3DDevice);
DWORD m_dwTexMirrorWidth;
DWORD m_dwTexMirrorHeight;
DWORD m_dwRegister;
// Our state variable - records whether we are opened, playing etc.
EMpegMovieMode m_Mode;
HANDLE m_MediaEvent;
HWND m_hwndApp;
int m_iDuration;
GUID m_TimeFormat;
bool m_bInitCube;
StreamInfo m_StreamInfo[16];
HRESULT FrameMove(LPDIRECT3DDEVICE7 pd3dDevice, FLOAT fTimeKey);
D3DVERTEX m_pCubeVertices[NUM_CUBE_VERTICES];
HRESULT AllocateTextureMirror(LPDIRECTDRAWSURFACE7 pddsVideo,
DWORD* dwWidth, DWORD* dwHeight,
bool bNonPow2Cond);
LPDIRECTDRAWSURFACE7 m_pDDSTextureMirror;
IFilterGraph* m_Fg;
IGraphBuilder* m_Gb;
IMediaControl* m_Mc;
IMediaSeeking* m_Ms;
IMediaEvent* m_Me;
IVMRWindowlessControl* m_Wc;
HRESULT AddVideoMixingRendererToFG(DWORD dwStreams);
public:
STDMETHODIMP SetStreamMediaType(DWORD dwStrmID, AM_MEDIA_TYPE* pmt, BOOL fTexture);
CMpegMovie(HWND hwndApplication);
~CMpegMovie();
DECLARE_IUNKNOWN
STDMETHODIMP NonDelegatingQueryInterface(REFIID, void**);
STDMETHODIMP InitCompositionTarget(
IUnknown* pD3DDevice,
LPDIRECTDRAWSURFACE7 pddsRenderTarget
);
STDMETHODIMP TermCompositionTarget(
IUnknown* pD3DDevice,
LPDIRECTDRAWSURFACE7 pddsRenderTarget
)
{
return S_OK;
}
STDMETHODIMP CompositeImage(
IUnknown* pD3DDevice,
LPDIRECTDRAWSURFACE7 pddsRenderTarget,
AM_MEDIA_TYPE* pmtRenderTarget,
REFERENCE_TIME rtStart,
REFERENCE_TIME rtEnd,
DWORD dwMappedClrBkgnd,
VMRVIDEOSTREAMINFO* pVideoStreamInfo,
UINT cStreams
);
HRESULT OpenMovie(TCHAR achFileName[][MAX_PATH], DWORD dwNumFiles);
DWORD CloseMovie();
BOOL PlayMovie();
BOOL PauseMovie();
BOOL StopMovie();
OAFilterState GetStateMovie();
HANDLE GetMovieEventHandle();
long GetMovieEventCode();
BOOL PutMoviePosition(LONG x, LONG y, LONG cx, LONG cy);
BOOL RepaintVideo(HWND hwnd, HDC hdc);
REFTIME GetDuration();
REFTIME GetCurrentPosition();
BOOL SeekToPosition(REFTIME rt,BOOL bFlushData);
void SetFullScreenMode(BOOL bMode);
void DisplayModeChanged() {
if (m_Wc) {
m_Wc->DisplayModeChanged();
}
}
};
RECT GetSourceRectFromMediaType(const AM_MEDIA_TYPE *pMediaType);
LPBITMAPINFOHEADER GetbmiHeader(const AM_MEDIA_TYPE *pMediaType);