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:
@@ -0,0 +1,37 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: AllocLib.h
|
||||
//
|
||||
// Desc: DirectShow sample code - header file for VMR sample applications
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifndef __INC_ALLOCLIB_H__
|
||||
#define __INC_ALLOCLIB_H__
|
||||
|
||||
#ifndef __ZEROSTRUCT_DEFINED
|
||||
#define __ZEROSTRUCT_DEFINED
|
||||
template <typename T>
|
||||
__inline void ZeroStruct(T& t)
|
||||
{
|
||||
ZeroMemory(&t, sizeof(t));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __INITDDSTRUCT_DEFINED
|
||||
#define __INITDDSTRUCT_DEFINED
|
||||
template <typename T>
|
||||
__inline void INITDDSTRUCT(T& dd)
|
||||
{
|
||||
ZeroStruct(dd);
|
||||
dd.dwSize = sizeof(dd);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
HRESULT
|
||||
PaintDDrawSurfaceBlack(
|
||||
LPDIRECTDRAWSURFACE7 pDDrawSurface
|
||||
);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,762 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: allocpresenter.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code - Custom Allocator Presenter for VMR sample
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <streams.h>
|
||||
#include <mmreg.h>
|
||||
#include "project.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "alloclib.h"
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* NonDelegatingQueryInterface
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::NonDelegatingQueryInterface(
|
||||
REFIID riid,
|
||||
void** ppv
|
||||
)
|
||||
{
|
||||
if(riid == IID_IVMRSurfaceAllocator)
|
||||
{
|
||||
return GetInterface((IVMRSurfaceAllocator*)this, ppv);
|
||||
}
|
||||
else if(riid == IID_IVMRImagePresenter)
|
||||
{
|
||||
return GetInterface((IVMRImagePresenter*)this, ppv);
|
||||
}
|
||||
|
||||
return CUnknown::NonDelegatingQueryInterface(riid,ppv);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IVMRSurfaceAllocator
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* AllocateSurfaces
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::AllocateSurface(
|
||||
DWORD_PTR x,
|
||||
VMRALLOCATIONINFO *w,
|
||||
DWORD* lpdwBuffer,
|
||||
LPDIRECTDRAWSURFACE7* lplpSurface
|
||||
)
|
||||
{
|
||||
DWORD dwFlags = w->dwFlags;
|
||||
LPBITMAPINFOHEADER lpHdr = w->lpHdr;
|
||||
LPDDPIXELFORMAT lpPixFmt = w->lpPixFmt;
|
||||
LPSIZE lpAspectRatio = &w->szAspectRatio;
|
||||
DWORD dwMinBuffers = w->dwMinBuffers;
|
||||
DWORD dwMaxBuffers = w->dwMaxBuffers;
|
||||
|
||||
if(!lpHdr)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
if(!lpAspectRatio)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
if(dwFlags & AMAP_PIXELFORMAT_VALID)
|
||||
{
|
||||
if(!lpPixFmt)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT hr = AllocateSurfaceWorker(dwFlags, lpHdr, lpPixFmt,
|
||||
lpAspectRatio,
|
||||
dwMinBuffers, dwMaxBuffers,
|
||||
lpdwBuffer, lplpSurface);
|
||||
return hr;
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* AllocateSurfaceWorker
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
CMpegMovie::AllocateSurfaceWorker(
|
||||
DWORD dwFlags,
|
||||
LPBITMAPINFOHEADER lpHdr,
|
||||
LPDDPIXELFORMAT lpPixFmt,
|
||||
LPSIZE lpAspectRatio,
|
||||
DWORD dwMinBuffers,
|
||||
DWORD dwMaxBuffers,
|
||||
DWORD* lpdwBuffer,
|
||||
LPDIRECTDRAWSURFACE7* lplpSurface
|
||||
)
|
||||
{
|
||||
LPBITMAPINFOHEADER lpHeader = lpHdr;
|
||||
if(!lpHeader)
|
||||
{
|
||||
DbgLog((LOG_ERROR, 1, TEXT("Can't get bitmapinfoheader from media type!!")));
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
DDSURFACEDESC2 ddsd;
|
||||
INITDDSTRUCT(ddsd);
|
||||
ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH | DDSD_PIXELFORMAT;
|
||||
ddsd.dwWidth = abs(lpHeader->biWidth);
|
||||
ddsd.dwHeight = abs(lpHeader->biHeight);
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY /*| DDSCAPS_TEXTURE */;
|
||||
|
||||
ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
|
||||
|
||||
if(lpHdr->biCompression <= BI_BITFIELDS &&
|
||||
m_DispInfo.bmiHeader.biBitCount <= lpHdr->biBitCount)
|
||||
{
|
||||
ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
|
||||
|
||||
if(lpHdr->biBitCount == 32)
|
||||
{
|
||||
ddsd.ddpfPixelFormat.dwRGBBitCount = 32;
|
||||
ddsd.ddpfPixelFormat.dwRBitMask = 0xff0000;
|
||||
ddsd.ddpfPixelFormat.dwGBitMask = 0xff00;
|
||||
ddsd.ddpfPixelFormat.dwBBitMask = 0xff;
|
||||
}
|
||||
else if(lpHdr->biBitCount == 16)
|
||||
{
|
||||
ddsd.ddpfPixelFormat.dwRGBBitCount = 16;
|
||||
ddsd.ddpfPixelFormat.dwRBitMask = 0xF800;
|
||||
ddsd.ddpfPixelFormat.dwGBitMask = 0x07e0;
|
||||
ddsd.ddpfPixelFormat.dwBBitMask = 0x001F;
|
||||
}
|
||||
}
|
||||
else if(lpHdr->biCompression > BI_BITFIELDS)
|
||||
{
|
||||
const DWORD dwCaps = (DDCAPS_BLTFOURCC | DDCAPS_BLTSTRETCH);
|
||||
if((dwCaps & m_ddHWCaps.dwCaps) != dwCaps)
|
||||
{
|
||||
DbgLog((LOG_ERROR, 1,
|
||||
TEXT("Can't BLT_FOURCC | BLT_STRETCH!!")));
|
||||
return E_FAIL;
|
||||
}
|
||||
ddsd.ddpfPixelFormat.dwFourCC = lpHdr->biCompression;
|
||||
ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
|
||||
ddsd.ddpfPixelFormat.dwYUVBitCount = lpHdr->biBitCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
|
||||
// Adjust width and height, if the driver requires it
|
||||
DWORD dwWidth = ddsd.dwWidth;
|
||||
DWORD dwHeight = ddsd.dwHeight;
|
||||
|
||||
HRESULT hr = m_lpDDObj->CreateSurface(&ddsd, &m_lpDDTexture, NULL);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
m_VideoAR = *lpAspectRatio;
|
||||
|
||||
m_VideoSize.cx = abs(lpHeader->biWidth);
|
||||
m_VideoSize.cy = abs(lpHeader->biHeight);
|
||||
|
||||
SetRect(&m_rcDst, 0, 0, m_VideoSize.cx, m_VideoSize.cy);
|
||||
m_rcSrc = m_rcDst;
|
||||
|
||||
hr = PaintDDrawSurfaceBlack(m_lpDDTexture);
|
||||
|
||||
*lplpSurface = m_lpDDTexture;
|
||||
*lpdwBuffer = 1;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* FreeSurfaces()
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::FreeSurface(DWORD_PTR w)
|
||||
{
|
||||
if(m_lpDDTexture)
|
||||
{
|
||||
m_lpDDTexture->Release();
|
||||
m_lpDDTexture = NULL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* PrepareSurface
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::PrepareSurface(
|
||||
DWORD_PTR w,
|
||||
LPDIRECTDRAWSURFACE7 lplpSurface,
|
||||
DWORD dwSurfaceFlags
|
||||
)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* AdviseNotify
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::AdviseNotify(
|
||||
IVMRSurfaceAllocatorNotify* lpIVMRSurfAllocNotify
|
||||
)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IVMRImagePresenter
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* StartPresenting()
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::StartPresenting(DWORD_PTR w)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* StopPresenting()
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::StopPresenting(DWORD_PTR w)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* PresentImage
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::PresentImage(
|
||||
DWORD_PTR w,
|
||||
VMRPRESENTATIONINFO* p
|
||||
)
|
||||
{
|
||||
//
|
||||
// Call the app specific function to render the scene
|
||||
//
|
||||
LPDIRECTDRAWSURFACE7 lpSurface = p->lpSurf;
|
||||
const REFERENCE_TIME rtNow = p->rtStart;
|
||||
const DWORD dwSurfaceFlags = p->dwFlags;
|
||||
|
||||
CAutoLock Lock(&m_AppImageLock);
|
||||
|
||||
RECT rSrc = {0, 0, m_VideoSize.cx, m_VideoSize.cy};
|
||||
RECT rDst = {0, 0, WIDTH(&m_rcDst), HEIGHT(&m_rcDst)};
|
||||
|
||||
//PaintDDrawSurfaceBlack(m_lpBackBuffer);
|
||||
//m_lpBltAlpha->AlphaBlt(&rDst, m_lpDDTexture, &rSrc, 0xFF);
|
||||
m_lpBackBuffer->Blt(&rDst, m_lpDDTexture, &rSrc, DDBLT_WAIT, NULL);
|
||||
|
||||
rDst.left = m_cxFontImg;
|
||||
rDst.top = m_cyFontImg * 1;
|
||||
rDst.right = rDst.left + (m_cxFontImg * 40);
|
||||
rDst.bottom = rDst.top + (m_cyFontImg * 4);
|
||||
|
||||
rSrc.left = 0;
|
||||
rSrc.top = 0;
|
||||
rSrc.right = (m_cxFontImg * 40);
|
||||
rSrc.bottom = (m_cyFontImg * 4);
|
||||
m_lpBltAlpha->AlphaBlt(&rDst, m_lpDDAppImage, &rSrc, 0x80);
|
||||
|
||||
|
||||
RECT rc = m_rcDst;
|
||||
RECT rcSrc;
|
||||
|
||||
SetRect(&rcSrc, 0, 0, WIDTH(&rc), HEIGHT(&rc));
|
||||
m_lpPriSurf->Blt(&rc, m_lpBackBuffer, &rcSrc, DDBLT_WAIT, NULL);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Allocator Presenter helper functions
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* InitDisplayInfo
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
InitDisplayInfo(
|
||||
AMDISPLAYINFO* lpDispInfo
|
||||
)
|
||||
{
|
||||
static char szDisplay[] = "DISPLAY";
|
||||
ZeroMemory(lpDispInfo, sizeof(*lpDispInfo));
|
||||
|
||||
HDC hdcDisplay = CreateDCA(szDisplay, NULL, NULL, NULL);
|
||||
HBITMAP hbm = CreateCompatibleBitmap(hdcDisplay, 1, 1);
|
||||
|
||||
lpDispInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
GetDIBits(hdcDisplay, hbm, 0, 1, NULL, (BITMAPINFO *)lpDispInfo, DIB_RGB_COLORS);
|
||||
GetDIBits(hdcDisplay, hbm, 0, 1, NULL, (BITMAPINFO *)lpDispInfo, DIB_RGB_COLORS);
|
||||
|
||||
DeleteObject(hbm);
|
||||
DeleteDC(hdcDisplay);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* DDARGB32SurfaceInit
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
CMpegMovie::DDARGB32SurfaceInit(
|
||||
LPDIRECTDRAWSURFACE7* lplpDDS,
|
||||
BOOL bTexture,
|
||||
DWORD cx,
|
||||
DWORD cy
|
||||
)
|
||||
{
|
||||
DDSURFACEDESC2 ddsd;
|
||||
HRESULT hRet;
|
||||
|
||||
*lplpDDS = NULL;
|
||||
|
||||
INITDDSTRUCT(ddsd);
|
||||
|
||||
ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
|
||||
ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
|
||||
if(bTexture)
|
||||
{
|
||||
ddsd.ddpfPixelFormat.dwFlags |= DDPF_ALPHAPIXELS;
|
||||
}
|
||||
ddsd.ddpfPixelFormat.dwRGBBitCount = 32;
|
||||
if(bTexture)
|
||||
{
|
||||
ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0xFF000000;
|
||||
}
|
||||
ddsd.ddpfPixelFormat.dwRBitMask = 0x00FF0000;
|
||||
ddsd.ddpfPixelFormat.dwGBitMask = 0x0000FF00;
|
||||
ddsd.ddpfPixelFormat.dwBBitMask = 0x000000FF;
|
||||
|
||||
|
||||
if(bTexture)
|
||||
{
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
|
||||
ddsd.ddsCaps.dwCaps2 = (DDSCAPS2_TEXTUREMANAGE | DDSCAPS2_HINTDYNAMIC);
|
||||
}
|
||||
else
|
||||
{
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN;
|
||||
}
|
||||
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
|
||||
ddsd.dwBackBufferCount = 0;
|
||||
|
||||
if(bTexture)
|
||||
{
|
||||
for(ddsd.dwWidth=1; cx>ddsd.dwWidth; ddsd.dwWidth<<=1);
|
||||
for(ddsd.dwHeight=1; cy>ddsd.dwHeight; ddsd.dwHeight<<=1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ddsd.dwWidth=cx;
|
||||
ddsd.dwHeight=cy;
|
||||
}
|
||||
|
||||
|
||||
// Attempt to create the surface with theses settings
|
||||
hRet = m_lpDDObj->CreateSurface(&ddsd, lplpDDS, NULL);
|
||||
|
||||
return hRet;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* CreateFontCache
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
CMpegMovie::CreateFontCache(
|
||||
int cyFont
|
||||
)
|
||||
{
|
||||
//
|
||||
// Initialize the LOGFONT structure - we want to
|
||||
// create an "anti-aliased" Lucida Consol font
|
||||
//
|
||||
LOGFONT lfChar;
|
||||
ZeroMemory(&lfChar, sizeof(lfChar));
|
||||
lfChar.lfHeight = -cyFont;
|
||||
lfChar.lfCharSet = OEM_CHARSET ;
|
||||
lfChar.lfPitchAndFamily = FIXED_PITCH | FF_MODERN ;
|
||||
lstrcpy(lfChar.lfFaceName, TEXT("Lucida Console")) ;
|
||||
lfChar.lfWeight = FW_NORMAL ;
|
||||
lfChar.lfOutPrecision = OUT_STRING_PRECIS ;
|
||||
lfChar.lfClipPrecision = CLIP_STROKE_PRECIS ;
|
||||
lfChar.lfQuality = ANTIALIASED_QUALITY;
|
||||
|
||||
|
||||
HFONT hFont = CreateFontIndirect(&lfChar) ;
|
||||
if(!hFont)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
//
|
||||
// The following magic is necessary to get GDI to rasterize
|
||||
// the font with anti-aliasing switched on when we later use
|
||||
// the font in a DDraw Surface. The doc's say that this is only
|
||||
// necessary in Win9X - but Win2K seems to require it too.
|
||||
//
|
||||
SIZE size;
|
||||
HDC hdcWin = GetDC(NULL);
|
||||
hFont = (HFONT)SelectObject(hdcWin, hFont);
|
||||
GetTextExtentPoint32(hdcWin, TEXT("A"), 1, &size);
|
||||
hFont = (HFONT)SelectObject(hdcWin, hFont);
|
||||
ReleaseDC(NULL, hdcWin);
|
||||
|
||||
//
|
||||
// Make sure that the font doesn't get too big.
|
||||
//
|
||||
if(size.cx * GRID_CX > 1024)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Delete the old font and assign the new one
|
||||
//
|
||||
RELEASE(m_lpDDSFontCache);
|
||||
if(m_hFont)
|
||||
{
|
||||
DeleteObject(m_hFont);
|
||||
}
|
||||
m_cxFont = size.cx; m_cyFont = size.cy;
|
||||
m_hFont = hFont;
|
||||
|
||||
|
||||
//
|
||||
// Create the DDraw ARGB32 surface that we will use
|
||||
// for the font cache.
|
||||
//
|
||||
|
||||
HRESULT hr = DDARGB32SurfaceInit(&m_lpDDSFontCache, TRUE, 16 * size.cx, 6 * size.cy);
|
||||
if(hr == DD_OK)
|
||||
{
|
||||
|
||||
HDC hdcDest;
|
||||
|
||||
m_lpDDSFontCache->GetDC(&hdcDest);
|
||||
|
||||
//
|
||||
// Select the font into the DDraw surface and draw the characters
|
||||
//
|
||||
m_hFont = (HFONT)SelectObject(hdcDest, m_hFont);
|
||||
SetTextColor(hdcDest, RGB(255,255,255));
|
||||
SetBkColor(hdcDest, RGB(0,0,0));
|
||||
SetBkMode(hdcDest, OPAQUE);
|
||||
|
||||
int row, col; TCHAR ch = (TCHAR)32;
|
||||
for(row = 0; row < 6; row++)
|
||||
{
|
||||
for(col = 0; col < 16; col++)
|
||||
{
|
||||
TextOut(hdcDest, col * size.cx, row * size.cy, &ch, 1);
|
||||
ch++;
|
||||
}
|
||||
}
|
||||
m_hFont = (HFONT)SelectObject(hdcDest, m_hFont);
|
||||
m_lpDDSFontCache->ReleaseDC(hdcDest);
|
||||
|
||||
DDSURFACEDESC2 surfDesc;
|
||||
INITDDSTRUCT(surfDesc);
|
||||
HRESULT hr = m_lpDDSFontCache->Lock(NULL, &surfDesc, DDLOCK_WAIT, NULL);
|
||||
if(hr == DD_OK)
|
||||
{
|
||||
|
||||
LPDWORD lpDst = (LPDWORD)surfDesc.lpSurface;
|
||||
for(row = 0; row < 6 * size.cy; row++)
|
||||
{
|
||||
|
||||
LPDWORD lp = lpDst;
|
||||
for(col = 0; col < 16 * size.cx; col++)
|
||||
{
|
||||
|
||||
DWORD dwPel = *lp;
|
||||
if(dwPel)
|
||||
{
|
||||
dwPel <<= 24;
|
||||
dwPel |= 0x00FFFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
dwPel = 0x80000000;
|
||||
}
|
||||
|
||||
*lp++ = dwPel;
|
||||
}
|
||||
lpDst += (surfDesc.lPitch / 4);
|
||||
}
|
||||
m_lpDDSFontCache->Unlock(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* Initialize3DEnvironment
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
CMpegMovie::Initialize3DEnvironment(
|
||||
HWND hWnd
|
||||
)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
//
|
||||
// Create the IDirectDraw interface. The first parameter is the GUID,
|
||||
// which is allowed to be NULL. If there are more than one DirectDraw
|
||||
// drivers on the system, a NULL guid requests the primary driver. For
|
||||
// non-GDI hardware cards like the 3DFX and PowerVR, the guid would need
|
||||
// to be explicity specified . (Note: these guids are normally obtained
|
||||
// from enumeration, which is convered in a subsequent tutorial.)
|
||||
//
|
||||
|
||||
m_hMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTOPRIMARY);
|
||||
|
||||
hr = DirectDrawCreateEx(NULL, (VOID**)&m_lpDDObj, IID_IDirectDraw7, NULL);
|
||||
if(FAILED(hr))
|
||||
return hr;
|
||||
|
||||
//
|
||||
// get the h/w caps for this device
|
||||
//
|
||||
INITDDSTRUCT(m_ddHWCaps);
|
||||
hr = m_lpDDObj->GetCaps(&m_ddHWCaps, NULL);
|
||||
if(FAILED(hr))
|
||||
return hr;
|
||||
InitDisplayInfo(&m_DispInfo);
|
||||
|
||||
//
|
||||
// Set the Windows cooperative level. This is where we tell the system
|
||||
// whether we will be rendering in fullscreen mode or in a window. Note
|
||||
// that some hardware (non-GDI) may not be able to render into a window.
|
||||
// The flag DDSCL_NORMAL specifies windowed mode. Using fullscreen mode
|
||||
// is the topic of a subsequent tutorial. The DDSCL_FPUSETUP flag is a
|
||||
// hint to DirectX to optomize floating points calculations. See the docs
|
||||
// for more info on this. Note: this call could fail if another application
|
||||
// already controls a fullscreen, exclusive mode.
|
||||
//
|
||||
hr = m_lpDDObj->SetCooperativeLevel(hWnd, DDSCL_NORMAL);
|
||||
if(FAILED(hr))
|
||||
return hr;
|
||||
|
||||
//
|
||||
// Initialize a surface description structure for the primary surface. The
|
||||
// primary surface represents the entire display, with dimensions and a
|
||||
// pixel format of the display. Therefore, none of that information needs
|
||||
// to be specified in order to create the primary surface.
|
||||
//
|
||||
DDSURFACEDESC2 ddsd;
|
||||
ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2));
|
||||
ddsd.dwSize = sizeof(DDSURFACEDESC2);
|
||||
ddsd.dwFlags = DDSD_CAPS;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
|
||||
|
||||
//
|
||||
// Create the primary surface.
|
||||
//
|
||||
hr = m_lpDDObj->CreateSurface(&ddsd, &m_lpPriSurf, NULL);
|
||||
if(FAILED(hr))
|
||||
return hr;
|
||||
|
||||
//
|
||||
// Create a clipper object which handles all our clipping for cases when
|
||||
// our window is partially obscured by other windows. This is not needed
|
||||
// for apps running in fullscreen mode.
|
||||
//
|
||||
LPDIRECTDRAWCLIPPER pcClipper;
|
||||
hr = m_lpDDObj->CreateClipper(0, &pcClipper, NULL);
|
||||
if(FAILED(hr))
|
||||
return hr;
|
||||
|
||||
//
|
||||
// Associate the clipper with our window. Note that, afterwards, the
|
||||
// clipper is internally referenced by the primary surface, so it is safe
|
||||
// to release our local reference to it.
|
||||
//
|
||||
pcClipper->SetHWnd(0, hWnd);
|
||||
m_lpPriSurf->SetClipper(pcClipper);
|
||||
pcClipper->Release();
|
||||
|
||||
//
|
||||
// Before creating the device, check that we are NOT in a palettized
|
||||
// display. That case will cause CreateDevice() to fail, since this simple
|
||||
// tutorial does not bother with palettes.
|
||||
//
|
||||
ddsd.dwSize = sizeof(DDSURFACEDESC2);
|
||||
m_lpDDObj->GetDisplayMode(&ddsd);
|
||||
if(ddsd.ddpfPixelFormat.dwRGBBitCount <= 8)
|
||||
return DDERR_INVALIDMODE;
|
||||
|
||||
DWORD dwRenderWidth = ddsd.dwWidth;
|
||||
DWORD dwRenderHeight = ddsd.dwHeight;
|
||||
|
||||
|
||||
//
|
||||
// Setup a surface description to create a backbuffer. This is an
|
||||
// offscreen plain surface with dimensions equal to the current display
|
||||
// size.
|
||||
|
||||
// The DDSCAPS_3DDEVICE is needed so we can later query this surface
|
||||
// for an IDirect3DDevice interface.
|
||||
//
|
||||
ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2));
|
||||
ddsd.dwSize = sizeof(DDSURFACEDESC2);
|
||||
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_3DDEVICE;
|
||||
ddsd.dwWidth = dwRenderWidth;
|
||||
ddsd.dwHeight = dwRenderHeight;
|
||||
|
||||
|
||||
//
|
||||
// Create the backbuffer. The most likely reason for failure is running
|
||||
// out of video memory. (A more sophisticated app should handle this.)
|
||||
//
|
||||
hr = m_lpDDObj->CreateSurface(&ddsd, &m_lpBackBuffer, NULL);
|
||||
if(FAILED(hr))
|
||||
return hr;
|
||||
|
||||
//
|
||||
// Create the textbuffer.
|
||||
//
|
||||
// The text buffer should be RGB32 (for now - later I'll try
|
||||
// ARGB16:4:4:4:4, but that is a lot more work).
|
||||
//
|
||||
hr = DDARGB32SurfaceInit(&m_lpDDAppImage, TRUE,
|
||||
1024, MulDiv(4, (int)dwRenderHeight, GRID_CY));
|
||||
if(FAILED(hr))
|
||||
return hr;
|
||||
|
||||
PaintDDrawSurfaceBlack(m_lpDDAppImage);
|
||||
|
||||
|
||||
//
|
||||
// Create the device. The device is created off of our back buffer, which
|
||||
// becomes the render target for the newly created device. Note that the
|
||||
// z-buffer must be created BEFORE the device
|
||||
//
|
||||
m_lpBltAlpha = new CAlphaBlt(m_lpBackBuffer, &hr);
|
||||
if(m_lpBltAlpha == NULL || hr != DD_OK)
|
||||
{
|
||||
if(m_lpBltAlpha == NULL)
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
}
|
||||
delete m_lpBltAlpha;
|
||||
}
|
||||
|
||||
hr = CreateFontCache(32);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
POINT LookUpChar(char ch, int cxFont, int cyFont)
|
||||
{
|
||||
ch -= 32;
|
||||
|
||||
int row = ch / 16;
|
||||
int col = ch % 16;
|
||||
|
||||
POINT pt;
|
||||
|
||||
pt.x = col * cxFont;
|
||||
pt.y = row * cyFont;
|
||||
|
||||
return pt;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* SetAppText
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::SetAppText(
|
||||
char* sz
|
||||
)
|
||||
{
|
||||
DDBLTFX ddFX;
|
||||
INITDDSTRUCT(ddFX);
|
||||
ddFX.dwFillColor = 0xFF80FF80;
|
||||
CAutoLock Lock(&m_AppImageLock);
|
||||
m_lpDDAppImage->Blt(NULL, NULL, NULL, DDBLT_COLORFILL, &ddFX);
|
||||
|
||||
m_cxFontImg = m_cxFont;
|
||||
m_cyFontImg = m_cyFont;
|
||||
RECT rcDst = {0, 0, m_cxFont, m_cyFont};
|
||||
|
||||
while(*sz)
|
||||
{
|
||||
if(*sz == '\n')
|
||||
{
|
||||
OffsetRect(&rcDst, 0, m_cyFont);
|
||||
rcDst.left = 0;
|
||||
rcDst.right = m_cxFont;
|
||||
}
|
||||
else
|
||||
{
|
||||
POINT pt = LookUpChar(*sz, m_cxFont, m_cyFont);
|
||||
|
||||
RECT rcSrc;
|
||||
rcSrc.left = pt.x;
|
||||
rcSrc.top = pt.y;
|
||||
rcSrc.right = pt.x + m_cxFont;
|
||||
rcSrc.bottom = pt.y + m_cyFont;
|
||||
|
||||
m_lpDDAppImage->Blt(&rcDst, m_lpDDSFontCache, &rcSrc, DDBLT_WAIT, NULL);
|
||||
OffsetRect(&rcDst, m_cxFont, 0);
|
||||
}
|
||||
sz++;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,442 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: BltAlpha.h
|
||||
//
|
||||
// Desc: DirectShow sample code - implementation of CAlphaBlt class.
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef __INITDDSTRUCT_DEFINED
|
||||
#define __INITDDSTRUCT_DEFINED
|
||||
template <typename T>
|
||||
__inline void INITDDSTRUCT(T& dd)
|
||||
{
|
||||
ZeroMemory(&dd, sizeof(dd));
|
||||
dd.dwSize = sizeof(dd);
|
||||
}
|
||||
#endif
|
||||
|
||||
#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) do { if (FAILED(expr)) __leave; } while(0);
|
||||
#endif
|
||||
|
||||
|
||||
class CAlphaBlt
|
||||
{
|
||||
private:
|
||||
|
||||
LPDIRECTDRAW7 m_pDD;
|
||||
LPDIRECT3D7 m_pD3D;
|
||||
LPDIRECT3DDEVICE7 m_pD3DDevice;
|
||||
LPDIRECTDRAWSURFACE7 m_lpDDBackBuffer;
|
||||
|
||||
LPDIRECTDRAWSURFACE7 m_lpDDMirror;
|
||||
LPDIRECTDRAWSURFACE7 m_lpDDM32;
|
||||
LPDIRECTDRAWSURFACE7 m_lpDDM16;
|
||||
DDSURFACEDESC2 m_ddsdM32;
|
||||
DDSURFACEDESC2 m_ddsdM16;
|
||||
|
||||
bool m_fPowerOf2;
|
||||
bool m_fSquare;
|
||||
|
||||
//
|
||||
// IsSurfaceBlendable
|
||||
//
|
||||
// Checks the DD surface description and the given
|
||||
// alpha value to determine if this surface is blendable.
|
||||
//
|
||||
bool
|
||||
IsSurfaceBlendable(
|
||||
DDSURFACEDESC2& ddsd,
|
||||
BYTE fAlpha
|
||||
)
|
||||
{
|
||||
//
|
||||
// Is the blend really a blend ?
|
||||
//
|
||||
|
||||
//if (fAlpha == 0 || fAlpha == 255) {
|
||||
// return true;
|
||||
//}
|
||||
|
||||
//
|
||||
// Is the surface already a D3D texture ?
|
||||
//
|
||||
if (ddsd.ddsCaps.dwCaps & DDSCAPS_TEXTURE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// OK we have to mirror the surface
|
||||
//
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// MirrorSourceSurface
|
||||
//
|
||||
// The mirror surface can be either 16 or 32 bit RGB depending
|
||||
// upon the format of the source surface.
|
||||
//
|
||||
// Of course it should have the "texture" flag
|
||||
// set and should be in VRAM. If we can't create the
|
||||
// surface then the AlphaBlt should fail
|
||||
//
|
||||
HRESULT MirrorSourceSurface(
|
||||
LPDIRECTDRAWSURFACE7 lpDDS,
|
||||
DDSURFACEDESC2& ddsd
|
||||
)
|
||||
{
|
||||
HRESULT hr = DD_OK;
|
||||
DWORD dwMirrorBitDepth = 0;
|
||||
DDSURFACEDESC2 ddsdMirror={0};
|
||||
|
||||
|
||||
//
|
||||
// OK - is it suitable for our needs.
|
||||
//
|
||||
// The following rules apply:
|
||||
// if ddsd is a FOURCC surface the mirror should be 32 bit
|
||||
// if ddsd is RGB then the mirror's bit depth should match that of ddsd.
|
||||
//
|
||||
// Also, the mirror must be large enough to actually hold
|
||||
// the surface to be blended
|
||||
//
|
||||
|
||||
m_lpDDMirror = NULL;
|
||||
|
||||
if (ddsd.ddpfPixelFormat.dwFlags == DDPF_FOURCC ||
|
||||
ddsd.ddpfPixelFormat.dwRGBBitCount == 32) {
|
||||
|
||||
if (ddsd.dwWidth > m_ddsdM32.dwWidth ||
|
||||
ddsd.dwHeight > m_ddsdM32.dwHeight) {
|
||||
|
||||
RELEASE(m_lpDDM32);
|
||||
}
|
||||
|
||||
if (!m_lpDDM32) {
|
||||
dwMirrorBitDepth = 32;
|
||||
}
|
||||
else {
|
||||
m_lpDDMirror = m_lpDDM32;
|
||||
ddsdMirror = m_ddsdM32;
|
||||
}
|
||||
}
|
||||
else if (ddsd.ddpfPixelFormat.dwRGBBitCount == 16) {
|
||||
|
||||
if (ddsd.dwWidth > m_ddsdM16.dwWidth ||
|
||||
ddsd.dwHeight > m_ddsdM16.dwHeight) {
|
||||
|
||||
RELEASE(m_lpDDM16);
|
||||
}
|
||||
|
||||
if (!m_lpDDM16) {
|
||||
dwMirrorBitDepth = 16;
|
||||
}
|
||||
else {
|
||||
m_lpDDMirror = m_lpDDM16;
|
||||
ddsdMirror = m_ddsdM16;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
// No support for RGB24 or RGB8 !
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (!m_lpDDMirror) {
|
||||
|
||||
INITDDSTRUCT(ddsdMirror);
|
||||
ddsdMirror.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
|
||||
ddsdMirror.ddpfPixelFormat.dwFlags = DDPF_RGB;
|
||||
ddsdMirror.ddpfPixelFormat.dwRGBBitCount = dwMirrorBitDepth;
|
||||
|
||||
switch (dwMirrorBitDepth) {
|
||||
case 16:
|
||||
ddsdMirror.ddpfPixelFormat.dwRBitMask = 0x0000F800;
|
||||
ddsdMirror.ddpfPixelFormat.dwGBitMask = 0x000007E0;
|
||||
ddsdMirror.ddpfPixelFormat.dwBBitMask = 0x0000001F;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
ddsdMirror.ddpfPixelFormat.dwRBitMask = 0x00FF0000;
|
||||
ddsdMirror.ddpfPixelFormat.dwGBitMask = 0x0000FF00;
|
||||
ddsdMirror.ddpfPixelFormat.dwBBitMask = 0x000000FF;
|
||||
break;
|
||||
}
|
||||
|
||||
ddsdMirror.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_TEXTURE;
|
||||
ddsdMirror.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
|
||||
|
||||
if (m_fPowerOf2) {
|
||||
|
||||
for (ddsdMirror.dwWidth = 1;
|
||||
ddsd.dwWidth > ddsdMirror.dwWidth;
|
||||
ddsdMirror.dwWidth <<= 1);
|
||||
|
||||
for (ddsdMirror.dwHeight = 1;
|
||||
ddsd.dwHeight > ddsdMirror.dwHeight;
|
||||
ddsdMirror.dwHeight <<= 1);
|
||||
}
|
||||
else {
|
||||
ddsdMirror.dwWidth = ddsd.dwWidth;
|
||||
ddsdMirror.dwHeight = ddsd.dwHeight;
|
||||
}
|
||||
|
||||
if (m_fSquare) {
|
||||
|
||||
if (ddsdMirror.dwHeight > ddsdMirror.dwWidth) {
|
||||
ddsdMirror.dwWidth = ddsdMirror.dwHeight;
|
||||
}
|
||||
|
||||
if (ddsdMirror.dwWidth > ddsdMirror.dwHeight) {
|
||||
ddsdMirror.dwHeight = ddsdMirror.dwWidth;
|
||||
}
|
||||
}
|
||||
|
||||
__try {
|
||||
|
||||
// Attempt to create the surface with theses settings
|
||||
CHECK_HR(hr = m_pDD->CreateSurface(&ddsdMirror, &m_lpDDMirror, NULL));
|
||||
|
||||
INITDDSTRUCT(ddsdMirror);
|
||||
CHECK_HR(hr = m_lpDDMirror->GetSurfaceDesc(&ddsdMirror));
|
||||
|
||||
switch (dwMirrorBitDepth) {
|
||||
case 16:
|
||||
m_ddsdM16 = ddsdMirror;
|
||||
m_lpDDM16 = m_lpDDMirror;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
m_ddsdM32 = ddsdMirror;
|
||||
m_lpDDM32 = m_lpDDMirror;
|
||||
break;
|
||||
}
|
||||
|
||||
} __finally {}
|
||||
}
|
||||
|
||||
if (hr == DD_OK) {
|
||||
|
||||
//ASSERT(m_lpDDMirror != NULL);
|
||||
|
||||
__try {
|
||||
RECT rc = {0, 0, ddsd.dwWidth, ddsd.dwHeight};
|
||||
CHECK_HR(hr = m_lpDDMirror->Blt(&rc, lpDDS, &rc, DDBLT_WAIT, NULL));
|
||||
ddsd = ddsdMirror;
|
||||
} __finally {}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
~CAlphaBlt()
|
||||
{
|
||||
RELEASE(m_lpDDBackBuffer);
|
||||
RELEASE(m_lpDDM32);
|
||||
RELEASE(m_lpDDM16);
|
||||
|
||||
RELEASE(m_pD3DDevice);
|
||||
RELEASE(m_pD3D);
|
||||
RELEASE(m_pDD);
|
||||
}
|
||||
|
||||
CAlphaBlt(LPDIRECTDRAWSURFACE7 lpDDSDst, HRESULT* phr) :
|
||||
m_pDD(NULL),
|
||||
m_pD3D(NULL),
|
||||
m_pD3DDevice(NULL),
|
||||
m_lpDDBackBuffer(NULL),
|
||||
m_lpDDMirror(NULL),
|
||||
m_lpDDM32(NULL),
|
||||
m_lpDDM16(NULL),
|
||||
m_fPowerOf2(false),
|
||||
m_fSquare(false)
|
||||
{
|
||||
|
||||
ZeroMemory(&m_ddsdM32, sizeof(m_ddsdM32));
|
||||
ZeroMemory(&m_ddsdM16, sizeof(m_ddsdM16));
|
||||
|
||||
HRESULT hr;
|
||||
hr = lpDDSDst->GetDDInterface((LPVOID *)&m_pDD);
|
||||
if (FAILED(hr)) {
|
||||
m_pDD = NULL;
|
||||
*phr = hr;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = m_pDD->QueryInterface(IID_IDirect3D7, (LPVOID *)&m_pD3D);
|
||||
if (FAILED(hr)) {
|
||||
m_pD3D = NULL;
|
||||
*phr = hr;
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = m_pD3D->CreateDevice(IID_IDirect3DHALDevice,
|
||||
lpDDSDst,
|
||||
&m_pD3DDevice);
|
||||
if (FAILED(hr)) {
|
||||
m_pD3DDevice = NULL;
|
||||
*phr = hr;
|
||||
}
|
||||
else {
|
||||
m_lpDDBackBuffer = lpDDSDst;
|
||||
m_lpDDBackBuffer->AddRef();
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
|
||||
D3DDEVICEDESC7 ddDesc;
|
||||
if (DD_OK == m_pD3DDevice->GetCaps(&ddDesc)) {
|
||||
|
||||
if (ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) {
|
||||
m_fPowerOf2 = true;
|
||||
}
|
||||
|
||||
if (ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_SQUAREONLY) {
|
||||
m_fSquare = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
*phr = hr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AlphaBlt(RECT* lpDst,
|
||||
LPDIRECTDRAWSURFACE7 lpDDSSrc,
|
||||
RECT* lpSrc,
|
||||
BYTE bAlpha
|
||||
)
|
||||
{
|
||||
HRESULT hr=S_OK;
|
||||
DDSURFACEDESC2 ddsd;
|
||||
|
||||
struct {
|
||||
float x, y, z, rhw;
|
||||
D3DCOLOR clr;
|
||||
float tu, tv;
|
||||
} pVertices[4];
|
||||
|
||||
__try {
|
||||
|
||||
INITDDSTRUCT(ddsd);
|
||||
CHECK_HR(hr = lpDDSSrc->GetSurfaceDesc(&ddsd));
|
||||
|
||||
if (!IsSurfaceBlendable(ddsd, bAlpha)) {
|
||||
CHECK_HR(hr = MirrorSourceSurface(lpDDSSrc, ddsd));
|
||||
lpDDSSrc = m_lpDDMirror;
|
||||
}
|
||||
|
||||
float fWid = (float)ddsd.dwWidth;
|
||||
float fHgt = (float)ddsd.dwHeight;
|
||||
|
||||
BYTE alpha = bAlpha;
|
||||
|
||||
//
|
||||
// Setup the DST info
|
||||
//
|
||||
pVertices[0].x = (float)lpDst->left;
|
||||
pVertices[0].y = (float)lpDst->top;
|
||||
pVertices[0].z = 0.5f;
|
||||
pVertices[0].rhw = 2.0f;
|
||||
pVertices[0].clr = RGBA_MAKE(0xff, 0xff, 0xff, alpha);
|
||||
|
||||
pVertices[1].x = (float)lpDst->right;
|
||||
pVertices[1].y = (float)lpDst->top;
|
||||
pVertices[1].z = 0.5f;
|
||||
pVertices[1].rhw = 2.0f;
|
||||
pVertices[1].clr = RGBA_MAKE(0xff, 0xff, 0xff, alpha);
|
||||
|
||||
pVertices[2].x = (float)lpDst->left;
|
||||
pVertices[2].y = (float)lpDst->bottom;
|
||||
pVertices[2].z = 0.5f;
|
||||
pVertices[2].rhw = 2.0f;
|
||||
pVertices[2].clr = RGBA_MAKE(0xff, 0xff, 0xff, alpha);
|
||||
|
||||
pVertices[3].x = (float)lpDst->right;
|
||||
pVertices[3].y = (float)lpDst->bottom;
|
||||
pVertices[3].z = 0.5f;
|
||||
pVertices[3].rhw = 2.0f;
|
||||
pVertices[3].clr = RGBA_MAKE(0xff, 0xff, 0xff, alpha);
|
||||
|
||||
//
|
||||
// Setup the SRC info
|
||||
//
|
||||
pVertices[0].tu = (float)lpSrc->left / fWid;
|
||||
pVertices[0].tv = (float)lpSrc->top / fHgt;
|
||||
|
||||
pVertices[1].tu = (float)lpSrc->right / fWid;
|
||||
pVertices[1].tv = (float)lpSrc->top / fHgt;
|
||||
|
||||
pVertices[2].tu = (float)lpSrc->left / fWid;
|
||||
pVertices[2].tv = (float)lpSrc->bottom / fHgt;
|
||||
|
||||
pVertices[3].tu = (float)lpSrc->right / fWid;
|
||||
pVertices[3].tv = (float)lpSrc->bottom / fHgt;
|
||||
|
||||
//
|
||||
// Setup some random D3D stuff
|
||||
//
|
||||
m_pD3DDevice->SetTexture(0, lpDDSSrc);
|
||||
m_pD3DDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
|
||||
m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE);
|
||||
m_pD3DDevice->SetRenderState(D3DRENDERSTATE_BLENDENABLE, TRUE);
|
||||
m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
|
||||
// use diffuse alpha from vertices, not texture alpha
|
||||
// m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
|
||||
m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
m_pD3DDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTFG_LINEAR);
|
||||
m_pD3DDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR);
|
||||
m_pD3DDevice->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTFP_LINEAR);
|
||||
m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
|
||||
m_pD3DDevice->SetTextureStageState( 0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP);
|
||||
|
||||
//
|
||||
// Do the alpha BLT
|
||||
//
|
||||
CHECK_HR(hr = m_pD3DDevice->BeginScene());
|
||||
CHECK_HR(hr = m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,
|
||||
D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1,
|
||||
pVertices, 4, D3DDP_WAIT));
|
||||
CHECK_HR(hr = m_pD3DDevice->EndScene());
|
||||
|
||||
} __finally {
|
||||
m_pD3DDevice->SetTexture(0, NULL);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
bool TextureSquare() {
|
||||
return m_fSquare;
|
||||
}
|
||||
|
||||
bool TexturePower2() {
|
||||
return m_fPowerOf2;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,164 @@
|
||||
# Microsoft Developer Studio Project File - Name="TxtPlayer" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Application" 0x0101
|
||||
|
||||
CFG=TxtPlayer - 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 "TxtPlayer.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 "TxtPlayer.mak" CFG="TxtPlayer - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "TxtPlayer - Win32 Release" (based on "Win32 (x86) Application")
|
||||
!MESSAGE "TxtPlayer - 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)" == "TxtPlayer - 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 ddraw.lib dxguid.lib version.lib shell32.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)" == "TxtPlayer - 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 /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 dxguid.lib quartz.lib ..\..\..\DirectShow\baseclasses\debug\strmbasd.lib strmiids.lib ddraw.lib version.lib shell32.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
|
||||
# SUBTRACT LINK32 /profile /nodefaultlib
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "TxtPlayer - Win32 Release"
|
||||
# Name "TxtPlayer - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\alloclib.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\AllocPresenter.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\app.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\commands.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\persist.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=.\BltAlpha.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\mpgcodec.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=.\perftool.ico
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\toolbar.bmp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\TxtPlayer.rc
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "TxtPlayer"=".\TxtPlayer.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -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 "perftool.ico"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Menu
|
||||
//
|
||||
|
||||
IDR_MAIN_MENU MENU DISCARDABLE
|
||||
BEGIN
|
||||
POPUP "&File"
|
||||
BEGIN
|
||||
MENUITEM "&Open...", IDM_FILE_OPEN
|
||||
MENUITEM "&Close", IDM_FILE_CLOSE
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "E&xit", IDM_FILE_EXIT
|
||||
END
|
||||
POPUP "&Help"
|
||||
BEGIN
|
||||
MENUITEM "&About VMR TextPlayer Sample...", IDM_HELP_ABOUT
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_ABOUTBOX DIALOG DISCARDABLE 0, 0, 235, 55
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "About VMR Text Player"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
ICON IDR_VIDEOCD_ICON,-1,11,17,20,20
|
||||
LTEXT "DirectShow VMR TextPlayer 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
|
||||
"P", IDM_MOVIE_PLAY, VIRTKEY, CONTROL, NOINVERT
|
||||
"S", IDM_MOVIE_STOP, 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
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 VOS_NT_WINDOWS32
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "DirectShow Windows XP Sample\0"
|
||||
VALUE "CompanyName", "Microsoft\0"
|
||||
VALUE "FileDescription", "Text Player Application\0"
|
||||
VALUE "FileVersion", "8.10\0"
|
||||
VALUE "InternalName", "VMR TxtPlayer\0"
|
||||
VALUE "LegalCopyright", "Copyright (c) 2000-2001 Microsoft Corporation\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "TxtPlayer.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
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDM_MOVIE_STOP "Stop"
|
||||
IDM_MOVIE_PLAY "Play"
|
||||
IDM_MOVIE_PREVTRACK "Rewind to beginning"
|
||||
IDM_MOVIE_PAUSE "Pause"
|
||||
IDM_MOVIE_SKIP_FORE "Fast Forward"
|
||||
IDM_MOVIE_SKIP_BACK "Rewind"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDM_FULL_SCREEN "Full screen playback"
|
||||
IDM_MOVIE_STEP "Step one frame"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
STR_FILE_OPEN "Open a new movie to play"
|
||||
STR_FILE_CLOSE "Close the movie"
|
||||
STR_FILE_EXIT "Quit DirectShow VMR TextPlayer Sample"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
STR_HELP_ABOUT "Display information about DirectShow VMR TextPlayer Sample"
|
||||
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 "DirectShow VMR TextPlayer Sample"
|
||||
STR_APP_TITLE_LOADED "DirectShow VMR TextPlayer Sample - %s"
|
||||
END
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
@@ -0,0 +1,285 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: alloclib.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <streams.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include "AllocLib.h"
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* YV12PaintSurfaceBlack
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
YV12PaintSurfaceBlack(
|
||||
LPDIRECTDRAWSURFACE7 pDDrawSurface
|
||||
)
|
||||
{
|
||||
AMTRACE((TEXT("YV12PaintSurfaceBlack")));
|
||||
HRESULT hr = NOERROR;
|
||||
DDSURFACEDESC2 ddsd;
|
||||
|
||||
// now lock the surface so we can start filling the surface with black
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
|
||||
for ( ;; ) {
|
||||
|
||||
hr = pDDrawSurface->Lock(NULL, &ddsd,
|
||||
DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL);
|
||||
|
||||
if (hr == DD_OK || hr != DDERR_WASSTILLDRAWING) {
|
||||
break;
|
||||
}
|
||||
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
if (hr == DD_OK)
|
||||
{
|
||||
DWORD y;
|
||||
LPBYTE pDst = (LPBYTE)ddsd.lpSurface;
|
||||
LONG OutStride = ddsd.lPitch;
|
||||
DWORD VSize = ddsd.dwHeight;
|
||||
DWORD HSize = ddsd.dwWidth;
|
||||
|
||||
// Y Component
|
||||
for (y = 0; y < VSize; y++) {
|
||||
FillMemory(pDst, HSize, (BYTE)0x10); // 1 line at a time
|
||||
pDst += OutStride;
|
||||
}
|
||||
|
||||
HSize /= 2;
|
||||
VSize /= 2;
|
||||
OutStride /= 2;
|
||||
|
||||
// Cb Component
|
||||
for (y = 0; y < VSize; y++) {
|
||||
FillMemory(pDst, HSize, (BYTE)0x80); // 1 line at a time
|
||||
pDst += OutStride;
|
||||
}
|
||||
|
||||
// Cr Component
|
||||
for (y = 0; y < VSize; y++) {
|
||||
FillMemory(pDst, HSize, (BYTE)0x80); // 1 line at a time
|
||||
pDst += OutStride;
|
||||
}
|
||||
|
||||
pDDrawSurface->Unlock(NULL);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* YUV16PaintSurfaceBlack
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
YUV16PaintSurfaceBlack(
|
||||
LPDIRECTDRAWSURFACE7 pdds,
|
||||
DWORD dwBlack
|
||||
)
|
||||
{
|
||||
AMTRACE((TEXT("YUV16PaintSurfaceBlack")));
|
||||
HRESULT hr = NOERROR;
|
||||
DDSURFACEDESC2 ddsd;
|
||||
|
||||
// now lock the surface so we can start filling the surface with black
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
|
||||
for ( ;; ) {
|
||||
|
||||
hr = pdds->Lock(NULL, &ddsd, DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL);
|
||||
|
||||
if (hr == DD_OK || hr != DDERR_WASSTILLDRAWING) {
|
||||
break;
|
||||
}
|
||||
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
if (hr == DD_OK)
|
||||
{
|
||||
DWORD y, x;
|
||||
LPDWORD pDst = (LPDWORD)ddsd.lpSurface;
|
||||
LONG OutStride = ddsd.lPitch;
|
||||
|
||||
for (y = 0; y < ddsd.dwHeight; y++) {
|
||||
|
||||
for (x = 0; x < ddsd.dwWidth / 2; x++) {
|
||||
pDst[x] = dwBlack;
|
||||
}
|
||||
|
||||
// Dont forget that the stride is a byte count
|
||||
*((LPBYTE*)&pDst) += OutStride;
|
||||
}
|
||||
|
||||
pdds->Unlock(NULL);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* BlackPaintProc
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
BlackPaintProc(
|
||||
LPDIRECTDRAWSURFACE7 pDDrawSurface,
|
||||
DDSURFACEDESC2* lpddSurfaceDesc
|
||||
)
|
||||
{
|
||||
AMTRACE((TEXT("BlackPaintProc")));
|
||||
|
||||
//
|
||||
// If the surface is YUV take care of the types that we
|
||||
// know the pixel format for. Those surfaces that we don't know
|
||||
// about will get painted '0' which may be bright green for
|
||||
// YUV surfaces.
|
||||
//
|
||||
|
||||
if (lpddSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_FOURCC) {
|
||||
|
||||
//
|
||||
// compute the black value if the fourCC code is suitable,
|
||||
// otherwise can't handle it
|
||||
//
|
||||
|
||||
switch (lpddSurfaceDesc->ddpfPixelFormat.dwFourCC) {
|
||||
|
||||
case mmioFOURCC('Y','V','1','2'):
|
||||
case mmioFOURCC('I','4','2','0'):
|
||||
case mmioFOURCC('I','Y','U','V'):
|
||||
return YV12PaintSurfaceBlack(pDDrawSurface);
|
||||
|
||||
case mmioFOURCC('Y','U','Y','2'):
|
||||
return YUV16PaintSurfaceBlack(pDDrawSurface, 0x80108010);
|
||||
|
||||
case mmioFOURCC('U','Y','V','Y'):
|
||||
return YUV16PaintSurfaceBlack(pDDrawSurface, 0x10801080);
|
||||
}
|
||||
}
|
||||
|
||||
DDBLTFX ddFX;
|
||||
INITDDSTRUCT(ddFX);
|
||||
return pDDrawSurface->Blt(NULL, NULL, NULL, DDBLT_COLORFILL, &ddFX);
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* PaintSurfaceBlack
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
PaintDDrawSurfaceBlack(
|
||||
LPDIRECTDRAWSURFACE7 pDDrawSurface
|
||||
)
|
||||
{
|
||||
AMTRACE((TEXT("PaintDDrawSurfaceBlack")));
|
||||
|
||||
LPDIRECTDRAWSURFACE7 *ppDDrawSurface = NULL;
|
||||
DDSCAPS2 ddSurfaceCaps;
|
||||
DDSURFACEDESC2 ddSurfaceDesc;
|
||||
DWORD dwAllocSize;
|
||||
DWORD i = 0, dwBackBufferCount = 0;
|
||||
|
||||
// get the surface description
|
||||
INITDDSTRUCT(ddSurfaceDesc);
|
||||
HRESULT hr = pDDrawSurface->GetSurfaceDesc(&ddSurfaceDesc);
|
||||
if (SUCCEEDED(hr)) {
|
||||
|
||||
if (ddSurfaceDesc.dwFlags & DDSD_BACKBUFFERCOUNT) {
|
||||
dwBackBufferCount = ddSurfaceDesc.dwBackBufferCount;
|
||||
}
|
||||
|
||||
hr = BlackPaintProc(pDDrawSurface, &ddSurfaceDesc);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
DbgLog((LOG_ERROR,1,
|
||||
TEXT("pDDrawSurface->Blt failed, hr = 0x%x"), hr));
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (dwBackBufferCount > 0) {
|
||||
|
||||
dwAllocSize = (dwBackBufferCount + 1) * sizeof(LPDIRECTDRAWSURFACE);
|
||||
ppDDrawSurface = (LPDIRECTDRAWSURFACE7*)_alloca(dwAllocSize);
|
||||
|
||||
ZeroMemory(ppDDrawSurface, dwAllocSize);
|
||||
ZeroMemory(&ddSurfaceCaps, sizeof(ddSurfaceCaps));
|
||||
ddSurfaceCaps.dwCaps = DDSCAPS_FLIP | DDSCAPS_COMPLEX;
|
||||
|
||||
if( DDSCAPS_OVERLAY & ddSurfaceDesc.ddsCaps.dwCaps ) {
|
||||
ddSurfaceCaps.dwCaps |= DDSCAPS_OVERLAY;
|
||||
}
|
||||
|
||||
for (i = 0; i < dwBackBufferCount; i++) {
|
||||
|
||||
LPDIRECTDRAWSURFACE7 pCurrentDDrawSurface = NULL;
|
||||
if (i == 0) {
|
||||
pCurrentDDrawSurface = pDDrawSurface;
|
||||
}
|
||||
else {
|
||||
pCurrentDDrawSurface = ppDDrawSurface[i];
|
||||
}
|
||||
ASSERT(pCurrentDDrawSurface);
|
||||
|
||||
|
||||
//
|
||||
// Get the back buffer surface and store it in the
|
||||
// next (in the circular sense) entry
|
||||
//
|
||||
|
||||
hr = pCurrentDDrawSurface->GetAttachedSurface(
|
||||
&ddSurfaceCaps,
|
||||
&ppDDrawSurface[i + 1]);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
DbgLog((LOG_ERROR,1,
|
||||
TEXT("Function pDDrawSurface->GetAttachedSurface ")
|
||||
TEXT("failed, hr = 0x%x"), hr ));
|
||||
break;
|
||||
}
|
||||
|
||||
ASSERT(ppDDrawSurface[i+1]);
|
||||
|
||||
//
|
||||
// Peform a DirectDraw colorfill BLT
|
||||
//
|
||||
|
||||
hr = BlackPaintProc(ppDDrawSurface[i + 1], &ddSurfaceDesc);
|
||||
if (FAILED(hr)) {
|
||||
DbgLog((LOG_ERROR,1,
|
||||
TEXT("ppDDrawSurface[i + 1]->Blt failed, ")
|
||||
TEXT("hr = 0x%x"), hr));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ppDDrawSurface) {
|
||||
for (i = 0; i < dwBackBufferCount + 1; i++) {
|
||||
if (ppDDrawSurface[i]) {
|
||||
ppDDrawSurface[i]->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hr != DD_OK) {
|
||||
DbgLog((LOG_ERROR, 1, TEXT("PaintSurfaceBlack failed")));
|
||||
hr = S_OK;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,419 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: app.h
|
||||
//
|
||||
// Desc: DirectShow sample code - header file for TxtPlayer sample
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Function prototypes
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
DoMainLoop(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
InitApplication(
|
||||
HINSTANCE hInstance
|
||||
);
|
||||
|
||||
BOOL
|
||||
InitInstance(
|
||||
HINSTANCE hInstance,
|
||||
int nCmdShow
|
||||
);
|
||||
|
||||
BOOL
|
||||
LoadWindowPos(
|
||||
LPRECT lprc
|
||||
);
|
||||
|
||||
BOOL
|
||||
SaveWindowPos(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
void
|
||||
PatB(
|
||||
HDC hdc,
|
||||
int x,
|
||||
int y,
|
||||
int dx,
|
||||
int dy,
|
||||
DWORD rgb
|
||||
);
|
||||
|
||||
void
|
||||
UpdateMpegMovieRect(
|
||||
void
|
||||
);
|
||||
|
||||
void
|
||||
GetAdjustedClientRect(
|
||||
RECT *prc
|
||||
);
|
||||
|
||||
BOOL
|
||||
DrawStats(
|
||||
HDC hdc
|
||||
);
|
||||
|
||||
void
|
||||
CalcMovieRect(
|
||||
LPRECT lprc
|
||||
);
|
||||
|
||||
LPCTSTR
|
||||
IdStr(
|
||||
int idResource
|
||||
);
|
||||
|
||||
void
|
||||
UpdateSystemColors(
|
||||
void
|
||||
);
|
||||
|
||||
void
|
||||
SetDurationLength(
|
||||
REFTIME rt
|
||||
);
|
||||
|
||||
void
|
||||
SetCurrentPosition(
|
||||
REFTIME rt
|
||||
);
|
||||
|
||||
TCHAR *
|
||||
FormatRefTime(
|
||||
TCHAR *sz,
|
||||
REFTIME rt
|
||||
);
|
||||
|
||||
void
|
||||
DoMpegVideoPropertyPage();
|
||||
|
||||
void
|
||||
DoMpegAudioPropertyPage();
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Registry stuff
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
ProfileIntIn(
|
||||
const TCHAR *szKey,
|
||||
int iDefault
|
||||
);
|
||||
|
||||
BOOL
|
||||
ProfileIntOut(
|
||||
const TCHAR *szKey,
|
||||
int iDefault
|
||||
);
|
||||
|
||||
void
|
||||
ProfileStringOut (
|
||||
LPTSTR szKey,
|
||||
LPTSTR sz
|
||||
);
|
||||
|
||||
UINT
|
||||
ProfileStringIn (
|
||||
LPTSTR szKey,
|
||||
LPTSTR szDef,
|
||||
LPTSTR sz,
|
||||
DWORD cb
|
||||
);
|
||||
|
||||
BOOL
|
||||
LoadWindowPos(
|
||||
LPRECT lprc
|
||||
);
|
||||
|
||||
BOOL
|
||||
SaveWindowPos(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
HKEY
|
||||
GetAppKey(
|
||||
BOOL fCreate
|
||||
);
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** 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_OnActivate(
|
||||
HWND hwnd,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
);
|
||||
|
||||
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(
|
||||
void
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnDropFiles(
|
||||
HWND hwnd,
|
||||
HDROP hdrop);
|
||||
|
||||
void
|
||||
SetPlayButtonsEnableState(
|
||||
void
|
||||
);
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Command processing functions
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
BOOL
|
||||
VcdPlayerOpenCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerCloseCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerPlayCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerRewindCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerStopCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerPauseCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerStepCmd(
|
||||
void
|
||||
);
|
||||
|
||||
void
|
||||
VcdPlayerSeekCmd(
|
||||
REFTIME rtSeekBy
|
||||
);
|
||||
|
||||
void
|
||||
ProcessOpen(
|
||||
TCHAR *achFileName,
|
||||
BOOL bPlay = FALSE
|
||||
);
|
||||
|
||||
int
|
||||
VcdPlayerChangeTimeFormat(
|
||||
int id
|
||||
);
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Recent filename stuff
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
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 HWND g_hwndStatusbar;
|
||||
|
||||
extern int cx;
|
||||
extern int cy;
|
||||
extern int xOffset;
|
||||
extern int yOffset;
|
||||
extern TCHAR g_achFileName[];
|
||||
extern OPENFILENAME ofn;
|
||||
extern DWORD g_State;
|
||||
extern int nRecentFiles;
|
||||
extern LONG lMovieOrgX, lMovieOrgY;
|
||||
extern int g_TimeFormat;
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Constants
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
#define LEFT_MARGIN 0
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** 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
|
||||
#define VCD_STEPPING 0x8000
|
||||
|
||||
enum {PerformanceTimer = 32, StatusTimer = 33};
|
||||
@@ -0,0 +1,393 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// 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 "mpgcodec.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
extern void RepositionMovie(HWND hwnd);
|
||||
extern CMpegMovie *pMpegMovie;
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerOpenCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerOpenCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
static BOOL fFirstTime = TRUE;
|
||||
BOOL fRet;
|
||||
TCHAR achFileName[MAX_PATH];
|
||||
TCHAR achFilter[MAX_PATH];
|
||||
LPTSTR lp;
|
||||
|
||||
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');
|
||||
}
|
||||
}
|
||||
|
||||
ofn.lpstrFile = achFileName;
|
||||
ofn.nMaxFile = sizeof(achFileName) / sizeof(TCHAR);
|
||||
ZeroMemory(achFileName, sizeof(achFileName));
|
||||
|
||||
fRet = GetOpenFileName(&ofn);
|
||||
if(fRet)
|
||||
{
|
||||
fFirstTime = FALSE;
|
||||
ProcessOpen(achFileName);
|
||||
}
|
||||
|
||||
return fRet;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerCloseCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerCloseCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
LONG cx, cy;
|
||||
|
||||
g_State = VCD_NO_CD;
|
||||
pMpegMovie->GetMoviePosition(&lMovieOrgX, &lMovieOrgY, &cx, &cy);
|
||||
pMpegMovie->StopMovie();
|
||||
pMpegMovie->CloseMovie();
|
||||
|
||||
SetDurationLength((REFTIME)0);
|
||||
SetCurrentPosition((REFTIME)0);
|
||||
|
||||
delete pMpegMovie;
|
||||
pMpegMovie = NULL;
|
||||
}
|
||||
|
||||
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******************************\
|
||||
* VcdPlayerPlayCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerStopCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
BOOL fPlaying = (g_State & VCD_PLAYING);
|
||||
BOOL fPaused = (g_State & VCD_PAUSED);
|
||||
|
||||
if((fPlaying || fPaused))
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
pMpegMovie->StopMovie();
|
||||
SetCurrentPosition(pMpegMovie->GetCurrentPosition());
|
||||
}
|
||||
|
||||
g_State &= ~(fPlaying ? VCD_PLAYING : VCD_PAUSED);
|
||||
g_State |= VCD_STOPPED;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerStepCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerStepCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
// Ensure that the video is paused to update toolbar buttons
|
||||
if(g_State & VCD_PLAYING)
|
||||
VcdPlayerPauseCmd();
|
||||
|
||||
if(pMpegMovie->FrameStepMovie())
|
||||
{
|
||||
g_State |= VCD_STEPPING;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerPauseCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerPauseCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
BOOL fPlaying = (g_State & VCD_PLAYING);
|
||||
BOOL fPaused = (g_State & VCD_PAUSED);
|
||||
|
||||
if(fPlaying)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
pMpegMovie->PauseMovie();
|
||||
SetCurrentPosition(pMpegMovie->GetCurrentPosition());
|
||||
}
|
||||
|
||||
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******************************\
|
||||
* VcdPlayerSeekCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VcdPlayerSeekCmd(
|
||||
REFTIME rtSeekBy
|
||||
)
|
||||
{
|
||||
REFTIME rt;
|
||||
REFTIME rtDur;
|
||||
|
||||
rtDur = pMpegMovie->GetDuration();
|
||||
rt = pMpegMovie->GetCurrentPosition() + rtSeekBy;
|
||||
|
||||
rt = max(0, min(rt, rtDur));
|
||||
|
||||
pMpegMovie->SeekToPosition(rt,TRUE);
|
||||
SetCurrentPosition(pMpegMovie->GetCurrentPosition());
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* ProcessOpen
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
ProcessOpen(
|
||||
TCHAR *achFileName,
|
||||
BOOL bPlay
|
||||
)
|
||||
{
|
||||
/*
|
||||
** If we currently have a video loaded we need to discard it here.
|
||||
*/
|
||||
if(g_State & VCD_LOADED)
|
||||
{
|
||||
VcdPlayerCloseCmd();
|
||||
}
|
||||
|
||||
lstrcpy(g_achFileName, achFileName);
|
||||
|
||||
pMpegMovie = new CMpegMovie(hwndApp);
|
||||
|
||||
if(pMpegMovie)
|
||||
{
|
||||
HRESULT hr = pMpegMovie->OpenMovie(g_achFileName);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
TCHAR achTmp[MAX_PATH];
|
||||
|
||||
nRecentFiles = SetRecentFiles(achFileName, nRecentFiles);
|
||||
|
||||
wsprintf(achTmp, IdStr(STR_APP_TITLE_LOADED),
|
||||
g_achFileName);
|
||||
g_State = (VCD_LOADED | VCD_STOPPED);
|
||||
|
||||
// SetDurationLength(pMpegMovie->GetDuration());
|
||||
g_TimeFormat = VcdPlayerChangeTimeFormat(g_TimeFormat);
|
||||
|
||||
RepositionMovie(hwndApp);
|
||||
InvalidateRect(hwndApp, NULL, FALSE);
|
||||
|
||||
// If play option specified on the command line
|
||||
if(bPlay)
|
||||
{
|
||||
pMpegMovie->PlayMovie();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TCHAR Buffer[MAX_ERROR_TEXT_LEN];
|
||||
|
||||
if(AMGetErrorText(hr, Buffer, MAX_ERROR_TEXT_LEN))
|
||||
{
|
||||
MessageBox(hwndApp, Buffer,
|
||||
IdStr(STR_APP_TITLE), MB_OK);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox(hwndApp,
|
||||
TEXT("Failed to open the movie! ")
|
||||
TEXT("Either the file was not found or the wave device is in use."),
|
||||
IdStr(STR_APP_TITLE), MB_OK);
|
||||
}
|
||||
|
||||
pMpegMovie->CloseMovie();
|
||||
delete pMpegMovie;
|
||||
pMpegMovie = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
InvalidateRect(hwndApp, NULL, FALSE);
|
||||
UpdateWindow(hwndApp);
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerChangeTimeFormat
|
||||
*
|
||||
* Tries to change the time format to id. Returns the time format that
|
||||
* actually got set. This may differ from id if the graph does not support
|
||||
* the requested time format.
|
||||
*
|
||||
\**************************************************************************/
|
||||
int
|
||||
VcdPlayerChangeTimeFormat(
|
||||
int id
|
||||
)
|
||||
{
|
||||
// Menu items are disabled while we are playing
|
||||
BOOL bRet = FALSE;
|
||||
int idActual = id;
|
||||
|
||||
ASSERT(pMpegMovie);
|
||||
ASSERT(pMpegMovie->StatusMovie() != MOVIE_NOTOPENED);
|
||||
|
||||
// Change the time format with the filtergraph
|
||||
switch(id)
|
||||
{
|
||||
case IDM_FRAME:
|
||||
bRet = pMpegMovie->SetTimeFormat(TIME_FORMAT_FRAME);
|
||||
break;
|
||||
|
||||
case IDM_FIELD:
|
||||
bRet = pMpegMovie->SetTimeFormat(TIME_FORMAT_FIELD);
|
||||
break;
|
||||
|
||||
case IDM_SAMPLE:
|
||||
bRet = pMpegMovie->SetTimeFormat(TIME_FORMAT_SAMPLE);
|
||||
break;
|
||||
|
||||
case IDM_BYTES:
|
||||
bRet = pMpegMovie->SetTimeFormat(TIME_FORMAT_BYTE);
|
||||
break;
|
||||
}
|
||||
|
||||
if(!bRet)
|
||||
{
|
||||
// IDM_TIME and all other cases, everyone should support IDM_TIME
|
||||
bRet = pMpegMovie->SetTimeFormat(TIME_FORMAT_MEDIA_TIME);
|
||||
ASSERT(bRet);
|
||||
idActual = IDM_TIME;
|
||||
}
|
||||
|
||||
// Pause the movie to get a current position
|
||||
SetDurationLength(pMpegMovie->GetDuration());
|
||||
SetCurrentPosition(pMpegMovie->GetCurrentPosition());
|
||||
|
||||
return idActual;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerRewindCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerRewindCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
pMpegMovie->SeekToPosition((REFTIME)0,FALSE);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: mpgcodec.h
|
||||
//
|
||||
// Desc: DirectShow sample code - header file for TxtPlayer sample
|
||||
//
|
||||
// Copyright (c) 1995 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <mpegtype.h> // IMpegAudioDecoder
|
||||
|
||||
typedef struct {
|
||||
LONG lWidth; // Native Width in pixels
|
||||
LONG lHeight; // Native Height in pixels
|
||||
LONG lvbv; // vbv
|
||||
REFERENCE_TIME PictureTime; // Time per picture in 100ns units
|
||||
LONG lTimePerFrame; // Time per picture in MPEG units
|
||||
LONG dwBitRate; // Bits per second
|
||||
LONG lXPelsPerMeter; // Pel aspect ratio
|
||||
LONG lYPelsPerMeter; // Pel aspect ratio
|
||||
DWORD dwStartTimeCode; // First GOP time code (or -1)
|
||||
LONG lActualHeaderLen; // Length of valid bytes in raw seq hdr
|
||||
BYTE RawHeader[140]; // The real sequence header
|
||||
} SEQHDR_INFO;
|
||||
|
||||
|
||||
#define DECODE_I 0x0001L
|
||||
#define DECODE_IP 0x0003L
|
||||
#define DECODE_IPB 0x0007L // Normal B Frame
|
||||
#define DECODE_IPB1 0x000FL // Decode 1 out of 4 B frames
|
||||
#define DECODE_IPB2 0x0010L // Decode 2 out of 4 B frames
|
||||
#define DECODE_IPB3 0x0020L // Decode 3 out of 4 B frames
|
||||
#define DECODE_DIS 0x0040L // No Decode, Convert only
|
||||
|
||||
#define DECODE_BQUAL_HIGH 0x00000000L // Normal B Decode
|
||||
#define DECODE_BQUAL_MEDIUM 0x10000000L // Fast B Frame (No Half Pixel)
|
||||
#define DECODE_BQUAL_LOW 0x20000000L // Super Fast B Frame (No Half Pixel & Fast IDCT)
|
||||
|
||||
#define MM_NOCONV 0x00000000L // No Conversion
|
||||
#define MM_HRESOLUTION 0x10000000L // Half Resolution
|
||||
#define MM_CLIPPED 0x20000000L // Clipped version (RGB8 only at present)
|
||||
|
||||
#define MM_420PL 0x00000001L // YU12 :: YCbCr
|
||||
#define MM_420PL_ 0x00000002L // YV12 :: YCrCb
|
||||
|
||||
#define MM_422PK 0x00000010L // YUY2 :: YCbCr
|
||||
#define MM_422PK_ 0x00000020L // YVY2 :: YCrCb
|
||||
#define MM_422SPK 0x00000040L // :: CbYCrY
|
||||
#define MM_422SPK_ 0x00000080L // :: CrYCbY
|
||||
#define MM_411PK 0x00000100L // BT41
|
||||
#define MM_410PL_ 0x00000200L // YVU9 - 16:1:1 Planar format
|
||||
|
||||
|
||||
#define MM_Y_DIB 0x00001000L // Luminance Only DIB
|
||||
#define MM_Y_DDB 0x00002000L // Luminance Only DDB
|
||||
|
||||
#define MM_RGB24_DIB 0x00010000L // RGB 8:8:8 DIB (Not Supported)
|
||||
#define MM_RGB24_DDB 0x00020000L // RGB 8:8:8 DDB (Not Supported)
|
||||
#define MM_RGB32_DIB 0x00040000L // RGB a:8:8:8 DIB (Not Supported)
|
||||
#define MM_RGB32_DDB 0x00080000L // RGB a:8:8:8 DDB (Not Supported)
|
||||
|
||||
#define MM_RGB565_DIB 0x00100000L // RGB 5:6:5 DIB
|
||||
#define MM_RGB565_DDB 0x00200000L // RGB 5:6:5 DDB
|
||||
#define MM_RGB555_DIB 0x00400000L // RGB 5:5:5 DIB
|
||||
#define MM_RGB555_DDB 0x00800000L // RGB 5:5:5 DDB
|
||||
|
||||
#define MM_RGB8_DIB 0x01000000L // 8 Bit Paletized RGB DIB
|
||||
#define MM_RGB8_DDB 0x02000000L // 8 Bit Paletized RGB DDB
|
||||
|
||||
|
||||
#define DECODE_HALF_HIQ 0x00004000L
|
||||
#define DECODE_HALF_FULLQ 0x00008000L
|
||||
|
||||
|
||||
//
|
||||
// Structure to describe the caps of the mpeg video decoder.
|
||||
//
|
||||
typedef struct {
|
||||
DWORD VideoMaxBitRate;
|
||||
} MPEG_VIDEO_DECODER_CAPS;
|
||||
|
||||
|
||||
//
|
||||
// IMpegVideoDecoder
|
||||
//
|
||||
DECLARE_INTERFACE_(IMpegVideoDecoder, IUnknown) {
|
||||
|
||||
STDMETHOD(get_CurrentDecoderOption)
|
||||
( THIS_
|
||||
DWORD *pOptions
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(set_CurrentDecoderOption)
|
||||
( THIS_
|
||||
DWORD Options
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(get_DefaultDecoderOption)
|
||||
( THIS_
|
||||
DWORD *pOptions
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(set_DefaultDecoderOption)
|
||||
( THIS_
|
||||
DWORD Options
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(get_QualityMsgProcessing)
|
||||
( THIS_
|
||||
BOOL *pfIgnore
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(set_QualityMsgProcessing)
|
||||
( THIS_
|
||||
BOOL fIgnore
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(get_GreyScaleOutput)
|
||||
( THIS_
|
||||
BOOL *pfGrey
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(set_GreyScaleOutput)
|
||||
( THIS_
|
||||
BOOL fGrey
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(get_SequenceHeader)
|
||||
( THIS_
|
||||
SEQHDR_INFO *pSeqHdrInfo
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(get_OutputFormat)
|
||||
( THIS_
|
||||
DWORD *pOutputFormat
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(get_FrameStatistics)
|
||||
( THIS_
|
||||
DWORD *pIFramesDecoded,
|
||||
DWORD *pPFramesDecoded,
|
||||
DWORD *pBFramesDecoded,
|
||||
DWORD *pIFramesSkipped,
|
||||
DWORD *pPFramesSkipped,
|
||||
DWORD *pBFramesSkipped
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(ResetFrameStatistics)
|
||||
( THIS_
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(get_DecoderPaletteInfo)
|
||||
( THIS_
|
||||
LPDWORD lpdwFirstEntry,
|
||||
LPDWORD lpdwLastEntry
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(get_DecoderPaletteEntries)
|
||||
( THIS_
|
||||
DWORD dwStartEntry,
|
||||
DWORD dwNumEntries,
|
||||
LPPALETTEENTRY lppe
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(get_EncryptionKey)
|
||||
( THIS_
|
||||
DWORD *dwEncrptionKey
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(put_EncryptionKey)
|
||||
( THIS_
|
||||
DWORD dwEncrptionKey
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(get_DecoderCaps)
|
||||
( THIS_
|
||||
MPEG_VIDEO_DECODER_CAPS *pCaps
|
||||
) PURE;
|
||||
|
||||
};
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,408 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: persist.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// - State persistence helper functions
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <streams.h>
|
||||
#include <atlbase.h>
|
||||
#include <atlconv.cpp>
|
||||
#include <mmreg.h>
|
||||
|
||||
#include "project.h"
|
||||
|
||||
// Global data
|
||||
RECENTFILES aRecentFiles[MAX_RECENT_FILES];
|
||||
int nRecentFiles;
|
||||
|
||||
static TCHAR cszWindow[] = TEXT("Window");
|
||||
static TCHAR cszAppKey[] = TEXT("Software\\Microsoft\\Multimedia Tools\\VMRTxtPlayer");
|
||||
|
||||
const int CX_DEFAULT = 400; /* Default window width */
|
||||
const int CY_DEFAULT = 400; /* Default window height */
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetAppKey
|
||||
*
|
||||
\**************************************************************************/
|
||||
HKEY
|
||||
GetAppKey(
|
||||
BOOL fCreate
|
||||
)
|
||||
{
|
||||
HKEY hKey = 0;
|
||||
|
||||
if(fCreate)
|
||||
{
|
||||
if(RegCreateKey(HKEY_CURRENT_USER, cszAppKey, &hKey) == ERROR_SUCCESS)
|
||||
return hKey;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(RegOpenKey(HKEY_CURRENT_USER, cszAppKey, &hKey) == ERROR_SUCCESS)
|
||||
return hKey;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* ProfileIntIn
|
||||
*
|
||||
\**************************************************************************/
|
||||
int
|
||||
ProfileIntIn(
|
||||
const TCHAR *szKey,
|
||||
int iDefault
|
||||
)
|
||||
{
|
||||
DWORD dwType=0;
|
||||
int iValue=0;
|
||||
BYTE aData[20];
|
||||
DWORD cb;
|
||||
HKEY hKey;
|
||||
|
||||
if((hKey = GetAppKey(TRUE)) == 0)
|
||||
{
|
||||
return iDefault;
|
||||
}
|
||||
|
||||
*(UINT *)&aData = 0;
|
||||
cb = sizeof(aData);
|
||||
|
||||
if(RegQueryValueEx(hKey, szKey, NULL, &dwType, aData, &cb))
|
||||
{
|
||||
iValue = iDefault;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dwType == REG_DWORD || dwType == REG_BINARY)
|
||||
{
|
||||
iValue = *(int *)&aData;
|
||||
}
|
||||
#ifdef UNICODE
|
||||
else if(dwType == REG_SZ)
|
||||
{
|
||||
iValue = atoiW((LPWSTR)aData);
|
||||
}
|
||||
#else
|
||||
else if(dwType == REG_SZ)
|
||||
{
|
||||
iValue = atoiA((LPSTR)aData);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
RegCloseKey(hKey);
|
||||
return iValue;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* ProfileIntOut
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
ProfileIntOut(
|
||||
const TCHAR *szKey,
|
||||
int iVal
|
||||
)
|
||||
{
|
||||
HKEY hKey;
|
||||
BOOL bRet = FALSE;
|
||||
|
||||
hKey = GetAppKey(TRUE);
|
||||
if(hKey)
|
||||
{
|
||||
RegSetValueEx(hKey, szKey, 0, REG_DWORD, (LPBYTE)&iVal, sizeof(DWORD));
|
||||
RegCloseKey(hKey);
|
||||
bRet = TRUE;
|
||||
}
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* ProfileString
|
||||
*
|
||||
\**************************************************************************/
|
||||
UINT
|
||||
ProfileStringIn(
|
||||
LPTSTR szKey,
|
||||
LPTSTR szDef,
|
||||
LPTSTR sz,
|
||||
DWORD cb
|
||||
)
|
||||
{
|
||||
HKEY hKey;
|
||||
DWORD dwType;
|
||||
|
||||
if((hKey = GetAppKey(FALSE)) == 0)
|
||||
{
|
||||
lstrcpy(sz, szDef);
|
||||
return lstrlen(sz);
|
||||
}
|
||||
|
||||
if(RegQueryValueEx(hKey, szKey, NULL, &dwType, (LPBYTE)sz, &cb) || dwType != REG_SZ)
|
||||
{
|
||||
lstrcpy(sz, szDef);
|
||||
cb = lstrlen(sz);
|
||||
}
|
||||
|
||||
RegCloseKey(hKey);
|
||||
return cb;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* ProfileStringOut
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
ProfileStringOut(
|
||||
LPTSTR szKey,
|
||||
LPTSTR sz
|
||||
)
|
||||
{
|
||||
HKEY hKey;
|
||||
|
||||
hKey = GetAppKey(TRUE);
|
||||
if(hKey)
|
||||
RegSetValueEx(hKey, szKey, 0, REG_SZ, (LPBYTE)sz,
|
||||
sizeof(TCHAR) * (lstrlen(sz)+1));
|
||||
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* LoadWindowPos
|
||||
*
|
||||
* retrieve the window position information from dragn.ini
|
||||
*
|
||||
\**************************************************************************/
|
||||
|
||||
#ifndef SPI_GETWORKAREA
|
||||
#define SPI_GETWORKAREA 48 // because NT doesnt have this define yet
|
||||
#endif
|
||||
|
||||
BOOL
|
||||
LoadWindowPos(
|
||||
LPRECT lprc
|
||||
)
|
||||
{
|
||||
static RECT rcDefault = {0,0,CX_DEFAULT,CY_DEFAULT};
|
||||
RECT rcScreen;
|
||||
RECT rc;
|
||||
HKEY hKey = GetAppKey(FALSE);
|
||||
|
||||
// read window placement from the registry.
|
||||
//
|
||||
*lprc = rcDefault;
|
||||
if(hKey)
|
||||
{
|
||||
DWORD cb;
|
||||
DWORD dwType;
|
||||
|
||||
cb = sizeof(rc);
|
||||
if(! RegQueryValueEx(hKey, cszWindow, NULL, &dwType, (LPBYTE)&rc, &cb)
|
||||
&& dwType == REG_BINARY && cb == sizeof(RECT))
|
||||
{
|
||||
*lprc = rc;
|
||||
}
|
||||
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
|
||||
// if we fail to get the working area (screen-tray), then assume
|
||||
// the screen is 640x480
|
||||
//
|
||||
if(! SystemParametersInfo(SPI_GETWORKAREA, 0, &rcScreen, FALSE))
|
||||
{
|
||||
rcScreen.top = rcScreen.left = 0;
|
||||
rcScreen.right = 640;
|
||||
rcScreen.bottom = 480;
|
||||
}
|
||||
|
||||
// if the proposed window position is outside the screen,
|
||||
// use the default placement
|
||||
//
|
||||
if(! IntersectRect(&rc, &rcScreen, lprc))
|
||||
{
|
||||
*lprc = rcDefault;
|
||||
}
|
||||
|
||||
return ! IsRectEmpty(lprc);
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* SaveWindowPos
|
||||
*
|
||||
* store the window position information in dragn.ini
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
SaveWindowPos(
|
||||
HWND hwnd
|
||||
)
|
||||
{
|
||||
WINDOWPLACEMENT wpl;
|
||||
HKEY hKey = GetAppKey(TRUE);
|
||||
|
||||
if(!hKey)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// save the current size and position of the window to the registry
|
||||
//
|
||||
ZeroMemory(&wpl, sizeof(wpl));
|
||||
wpl.length = sizeof(wpl);
|
||||
GetWindowPlacement(hwnd, &wpl);
|
||||
|
||||
|
||||
RegSetValueEx(hKey, cszWindow, 0, REG_BINARY,
|
||||
(LPBYTE)&wpl.rcNormalPosition,
|
||||
sizeof(wpl.rcNormalPosition));
|
||||
|
||||
RegCloseKey(hKey);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* GetRecentFiles
|
||||
*
|
||||
* Reads at most MAX_RECENT_FILES from vcdplyer.ini. Returns the number
|
||||
* of files actually read. Updates the File menu to show the "recent" files.
|
||||
*
|
||||
\**************************************************************************/
|
||||
int
|
||||
GetRecentFiles(
|
||||
int iLastCount
|
||||
)
|
||||
{
|
||||
int i;
|
||||
TCHAR FileName[MAX_PATH];
|
||||
TCHAR szKey[32];
|
||||
HMENU hSubMenu;
|
||||
|
||||
//
|
||||
// Delete the files from the menu
|
||||
//
|
||||
hSubMenu = GetSubMenu(GetMenu(hwndApp), 0);
|
||||
|
||||
// Delete the separator at slot 2 and all the other recent file entries
|
||||
|
||||
if(iLastCount != 0)
|
||||
{
|
||||
DeleteMenu(hSubMenu, 2, MF_BYPOSITION);
|
||||
|
||||
for(i = 1; i <= iLastCount; i++)
|
||||
{
|
||||
DeleteMenu(hSubMenu, ID_RECENT_FILE_BASE + i, MF_BYCOMMAND);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for(i = 1; i <= MAX_RECENT_FILES; i++)
|
||||
{
|
||||
DWORD len;
|
||||
TCHAR szMenuName[MAX_PATH + 3];
|
||||
|
||||
wsprintf(szKey, TEXT("File %d"), i);
|
||||
len = ProfileStringIn(szKey, TEXT(""), FileName, MAX_PATH * sizeof(TCHAR));
|
||||
if(len == 0)
|
||||
{
|
||||
i = i - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
lstrcpy(aRecentFiles[i - 1], FileName);
|
||||
wsprintf(szMenuName, TEXT("&%d %s"), i, FileName);
|
||||
|
||||
if(i == 1)
|
||||
{
|
||||
InsertMenu(hSubMenu, 2, MF_SEPARATOR | MF_BYPOSITION, (UINT)-1, NULL);
|
||||
}
|
||||
|
||||
InsertMenu(hSubMenu, 2 + i, MF_STRING | MF_BYPOSITION,
|
||||
ID_RECENT_FILE_BASE + i, szMenuName);
|
||||
}
|
||||
|
||||
//
|
||||
// i is the number of recent files in the array.
|
||||
//
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* SetRecentFiles
|
||||
*
|
||||
* Writes the most recent files to the vcdplyer.ini file. Purges the oldest
|
||||
* file if necessary.
|
||||
*
|
||||
\**************************************************************************/
|
||||
int
|
||||
SetRecentFiles(
|
||||
TCHAR *FileName, // File name to add
|
||||
int iCount // Current count of files
|
||||
)
|
||||
{
|
||||
TCHAR FullPathFileName[MAX_PATH];
|
||||
TCHAR *lpFile;
|
||||
TCHAR szKey[32];
|
||||
int iCountNew;
|
||||
int i;
|
||||
|
||||
//
|
||||
// Check for dupes - we don't allow them !
|
||||
//
|
||||
for(i = 0; i < iCount; i++)
|
||||
{
|
||||
if(0 == lstrcmpi(FileName, aRecentFiles[i]))
|
||||
{
|
||||
return iCount;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Throw away the oldest entry
|
||||
//
|
||||
MoveMemory(&aRecentFiles[1], &aRecentFiles[0],
|
||||
sizeof(aRecentFiles) - sizeof(aRecentFiles[1]));
|
||||
|
||||
//
|
||||
// Copy in the full path of the new file.
|
||||
//
|
||||
GetFullPathName(FileName, MAX_PATH, FullPathFileName, &lpFile);
|
||||
lstrcpy(aRecentFiles[0], FullPathFileName);
|
||||
|
||||
//
|
||||
// Update the count of files, saturate to MAX_RECENT_FILES.
|
||||
//
|
||||
iCountNew = min(iCount + 1, MAX_RECENT_FILES);
|
||||
|
||||
//
|
||||
// Clear the old stuff and the write out the recent files to disk
|
||||
//
|
||||
for(i = 1; i <= iCountNew; i++)
|
||||
{
|
||||
wsprintf(szKey, TEXT("File %d"), i);
|
||||
ProfileStringOut(szKey, aRecentFiles[i - 1]);
|
||||
}
|
||||
|
||||
//
|
||||
// Update the file menu
|
||||
//
|
||||
GetRecentFiles(iCount);
|
||||
|
||||
return iCountNew; // the updated count of files.
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: project.h
|
||||
//
|
||||
// Desc: DirectShow sample code - header file for TxtPlayer sample
|
||||
// Master header file that includes all the other header files used by the
|
||||
// project. This enables compiled headers to work using build.
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include "app.h"
|
||||
#include "vcdplyer.h"
|
||||
#include "resource.h"
|
||||
|
||||
#include <strmif.h>
|
||||
#include <uuids.h>
|
||||
@@ -0,0 +1,15 @@
|
||||
Windows XP DirectShow Sample -- TxtPlayer
|
||||
-----------------------------------------
|
||||
|
||||
This sample demonstrates using the Video Mixing Renderer and
|
||||
a custom allocator-presenter to render alpha-blended text over
|
||||
a running video.
|
||||
|
||||
NOTE: This sample requires Windows XP (or greater) functionality
|
||||
and will exit on other systems.
|
||||
|
||||
Usage:
|
||||
TxtPlayer </P filename>
|
||||
|
||||
/P: Optional filename to automatically render and play at startup
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: resource.h
|
||||
//
|
||||
// Desc: DirectShow sample code - resource header file for TxtPlayer sample
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// These are indexes used by the toolbar.
|
||||
//
|
||||
#define IDC_STATIC -1
|
||||
|
||||
#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_9 8
|
||||
#define IDX_10 9
|
||||
#define IDX_11 10
|
||||
#define IDX_12 11
|
||||
|
||||
#define DEFAULT_TBAR_SIZE 10
|
||||
#define NUMBER_OF_BITMAPS 12
|
||||
|
||||
#define ID_STATUSBAR 8
|
||||
#define ID_TOOLBAR 9
|
||||
#define ID_TRACKBAR 10
|
||||
|
||||
// Dialogs
|
||||
#define IDD_ABOUTBOX 200
|
||||
|
||||
#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_HELP_ABOUT 40102
|
||||
|
||||
// Different time formats
|
||||
#define IDM_TIME 40150
|
||||
#define IDM_FRAME 40151
|
||||
#define IDM_FIELD 40152
|
||||
#define IDM_SAMPLE 40153
|
||||
#define IDM_BYTES 40154
|
||||
|
||||
// Toolbar commands
|
||||
#define IDM_MOVIE_STOP 40010
|
||||
#define IDM_MOVIE_PLAY 40011
|
||||
#define IDM_MOVIE_PREVTRACK 40012
|
||||
#define IDM_MOVIE_PAUSE 40013
|
||||
#define IDM_MOVIE_SKIP_FORE 40014
|
||||
#define IDM_MOVIE_SKIP_BACK 40015
|
||||
#define IDM_FULL_SCREEN 40017
|
||||
#define IDM_MOVIE_STEP 40019
|
||||
|
||||
|
||||
#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
|
||||
|
||||
// Help Menu HELP_MENU_BASE
|
||||
#define STR_HELP_ABOUT IDM_HELP_ABOUT + 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
|
||||
|
||||
|
||||
#define MPEG_CODEC_BASE 4000
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by TxtPlayer.rc
|
||||
//
|
||||
|
||||
// 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 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,944 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: vcdplyer.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code - VMR-enabled player app with text
|
||||
//
|
||||
// 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 "mpgcodec.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern int FrameStepCount;
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* CMpegMovie
|
||||
*
|
||||
* Constructors and destructors
|
||||
*
|
||||
\**************************************************************************/
|
||||
CMpegMovie::CMpegMovie(HWND hwndApplication)
|
||||
: CUnknown(NAME("Allocator Presenter"), NULL),
|
||||
m_hwndApp(hwndApplication),
|
||||
m_MediaEvent(NULL),
|
||||
m_Mode(MOVIE_NOTOPENED),
|
||||
m_Fg(NULL),
|
||||
m_Gb(NULL),
|
||||
m_Mc(NULL),
|
||||
m_Ms(NULL),
|
||||
m_Me(NULL),
|
||||
m_Wc(NULL),
|
||||
m_SAN(NULL),
|
||||
m_bRndLess(TRUE),
|
||||
pMpegAudioDecoder(NULL),
|
||||
pVideoRenderer(NULL),
|
||||
m_TimeFormat(TIME_FORMAT_MEDIA_TIME),
|
||||
m_hFont(NULL),
|
||||
m_cxFont(0), m_cxFontImg(0),
|
||||
m_cyFont(0), m_cyFontImg(0),
|
||||
m_lpDDSFontCache(NULL)
|
||||
{
|
||||
m_hMonitor = NULL;
|
||||
m_lpDDObj = NULL;
|
||||
m_lpPriSurf = NULL;
|
||||
m_lpBackBuffer = NULL;
|
||||
m_lpDDTexture = NULL;
|
||||
|
||||
AddRef();
|
||||
}
|
||||
CMpegMovie::~CMpegMovie()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static HRESULT SetRenderingMode( IBaseFilter* pBaseFilter, VMRMode mode )
|
||||
{
|
||||
// Test VMRConfig, VMRMonitorConfig
|
||||
IVMRFilterConfig* pConfig;
|
||||
HRESULT hr = pBaseFilter->QueryInterface(IID_IVMRFilterConfig, (LPVOID *)&pConfig);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
pConfig->SetRenderingMode(mode);
|
||||
pConfig->SetRenderingPrefs(RenderPrefs_AllowOverlays);
|
||||
pConfig->Release();
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* AddVideoMixingRendererToFG
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
CMpegMovie::AddVideoMixingRendererToFG()
|
||||
{
|
||||
IBaseFilter* pBF = NULL;
|
||||
HRESULT hRes = CoCreateInstance(CLSID_VideoMixingRenderer,
|
||||
NULL,
|
||||
CLSCTX_INPROC,
|
||||
IID_IBaseFilter,
|
||||
(LPVOID *)&pBF);
|
||||
|
||||
if(SUCCEEDED(hRes))
|
||||
{
|
||||
hRes = m_Fg->AddFilter(pBF, L"Video Mixing Renderer");
|
||||
|
||||
if(SUCCEEDED(hRes))
|
||||
{
|
||||
if(m_bRndLess)
|
||||
{
|
||||
hRes = SetRenderingMode(pBF, VMRMode_Renderless);
|
||||
|
||||
if(SUCCEEDED(hRes))
|
||||
{
|
||||
hRes = pBF->QueryInterface(IID_IVMRSurfaceAllocatorNotify,
|
||||
(LPVOID *)&m_SAN);
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hRes))
|
||||
{
|
||||
hRes = m_SAN->AdviseSurfaceAllocator(0, this);
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hRes))
|
||||
{
|
||||
hRes = m_SAN->SetDDrawDevice(m_lpDDObj, m_hMonitor);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hRes = SetRenderingMode(pBF, VMRMode_Windowless);
|
||||
if(SUCCEEDED(hRes))
|
||||
{
|
||||
hRes = pBF->QueryInterface(IID_IVMRWindowlessControl, (LPVOID *)&m_Wc);
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hRes))
|
||||
{
|
||||
m_Wc->SetVideoClippingWindow(m_hwndApp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_Wc)
|
||||
{
|
||||
m_Wc->Release();
|
||||
m_Wc = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(pBF)
|
||||
{
|
||||
pBF->Release();
|
||||
}
|
||||
|
||||
if(FAILED(hRes))
|
||||
{
|
||||
if(m_SAN)
|
||||
{
|
||||
m_SAN->Release();
|
||||
m_SAN = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return hRes;
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* OpenMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
CMpegMovie::OpenMovie(
|
||||
TCHAR *lpFileName
|
||||
)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
IUnknown *pUnk;
|
||||
HRESULT hres;
|
||||
WCHAR FileName[MAX_PATH];
|
||||
|
||||
wcscpy(FileName, T2W(lpFileName));
|
||||
|
||||
hres = CoInitialize(NULL);
|
||||
if(hres == S_FALSE)
|
||||
{
|
||||
CoUninitialize();
|
||||
}
|
||||
|
||||
Initialize3DEnvironment(m_hwndApp);
|
||||
|
||||
hres = CoCreateInstance(
|
||||
CLSID_FilterGraph,
|
||||
NULL,
|
||||
CLSCTX_INPROC,
|
||||
IID_IUnknown,
|
||||
(LPVOID *)&pUnk);
|
||||
|
||||
if(SUCCEEDED(hres))
|
||||
{
|
||||
m_Mode = MOVIE_OPENED;
|
||||
hres = pUnk->QueryInterface(IID_IFilterGraph, (LPVOID *)&m_Fg);
|
||||
if(FAILED(hres))
|
||||
{
|
||||
pUnk->Release();
|
||||
return hres;
|
||||
}
|
||||
|
||||
hres = AddVideoMixingRendererToFG();
|
||||
if(FAILED(hres))
|
||||
{
|
||||
m_Fg->Release(); m_Fg = NULL;
|
||||
return hres;
|
||||
}
|
||||
|
||||
hres = pUnk->QueryInterface(IID_IGraphBuilder, (LPVOID *)&m_Gb);
|
||||
if(FAILED(hres))
|
||||
{
|
||||
pUnk->Release();
|
||||
m_Fg->Release(); m_Fg = NULL;
|
||||
m_Wc->Release(); m_Wc = NULL;
|
||||
return hres;
|
||||
}
|
||||
|
||||
hres = m_Gb->RenderFile(FileName, NULL);
|
||||
if(FAILED(hres))
|
||||
{
|
||||
pUnk->Release();
|
||||
m_Fg->Release(); m_Fg = NULL;
|
||||
if(m_Wc)
|
||||
m_Wc->Release(); m_Wc = NULL;
|
||||
m_Gb->Release(); m_Gb = NULL;
|
||||
return hres;
|
||||
}
|
||||
|
||||
hres = pUnk->QueryInterface(IID_IMediaControl, (LPVOID *)&m_Mc);
|
||||
if(FAILED(hres))
|
||||
{
|
||||
pUnk->Release();
|
||||
m_Fg->Release(); m_Fg = NULL;
|
||||
m_Wc->Release(); m_Wc = NULL;
|
||||
m_Gb->Release(); m_Gb = NULL;
|
||||
return hres;
|
||||
}
|
||||
|
||||
//
|
||||
// Not being able to get the IMediaEvent interface does not
|
||||
// necessarly mean that we can't play the graph.
|
||||
//
|
||||
pUnk->QueryInterface(IID_IMediaEvent, (LPVOID *)&m_Me);
|
||||
pUnk->QueryInterface(IID_IMediaSeeking, (LPVOID *)&m_Ms);
|
||||
|
||||
GetMovieEventHandle();
|
||||
GetPerformanceInterfaces();
|
||||
|
||||
pUnk->Release();
|
||||
return S_OK;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Fg = NULL;
|
||||
}
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* CloseMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
DWORD
|
||||
CMpegMovie::CloseMovie(
|
||||
)
|
||||
{
|
||||
m_Mode = MOVIE_NOTOPENED;
|
||||
|
||||
if(m_Mc)
|
||||
{
|
||||
if(pMpegAudioDecoder)
|
||||
{
|
||||
pMpegAudioDecoder->Release();
|
||||
pMpegAudioDecoder = NULL;
|
||||
}
|
||||
|
||||
if(pVideoRenderer)
|
||||
{
|
||||
pVideoRenderer->Release();
|
||||
pVideoRenderer = NULL;
|
||||
}
|
||||
|
||||
if(m_Me)
|
||||
{
|
||||
m_MediaEvent = NULL;
|
||||
m_Me->Release();
|
||||
m_Me = NULL;
|
||||
}
|
||||
|
||||
if(m_Ms)
|
||||
{
|
||||
m_Ms->Release();
|
||||
m_Ms = NULL;
|
||||
}
|
||||
|
||||
if(m_Wc)
|
||||
{
|
||||
m_Wc->Release();
|
||||
m_Wc = NULL;
|
||||
}
|
||||
|
||||
m_Mc->Release();
|
||||
m_Mc = NULL;
|
||||
|
||||
if(m_SAN)
|
||||
{
|
||||
m_SAN->Release();
|
||||
m_SAN = NULL;
|
||||
}
|
||||
|
||||
if(m_Gb)
|
||||
{
|
||||
m_Gb->Release();
|
||||
m_Gb = NULL;
|
||||
}
|
||||
|
||||
if(m_Fg)
|
||||
{
|
||||
m_Fg->Release();
|
||||
m_Fg = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
delete m_lpBltAlpha;
|
||||
|
||||
RELEASE(m_lpDDObj);
|
||||
RELEASE(m_lpPriSurf);
|
||||
RELEASE(m_lpBackBuffer);
|
||||
RELEASE(m_lpDDTexture);
|
||||
RELEASE(m_lpDDAppImage);
|
||||
|
||||
if(m_hFont)
|
||||
{
|
||||
DeleteObject(m_hFont);
|
||||
m_hFont = NULL;
|
||||
}
|
||||
|
||||
RELEASE(m_lpDDSFontCache);
|
||||
|
||||
QzUninitialize();
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* CMpegMovie::GetNativeMovieSize
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::GetNativeMovieSize(
|
||||
LONG *pcx,
|
||||
LONG *pcy
|
||||
)
|
||||
{
|
||||
BOOL bRet = FALSE;
|
||||
if(m_Wc)
|
||||
{
|
||||
bRet = (m_Wc->GetNativeVideoSize(pcx, pcy, NULL, NULL) == S_OK);
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetMoviePosition
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::GetMoviePosition(
|
||||
LONG *px,
|
||||
LONG *py,
|
||||
LONG *pcx,
|
||||
LONG *pcy
|
||||
)
|
||||
{
|
||||
BOOL bRet = FALSE;
|
||||
|
||||
if(m_Wc)
|
||||
{
|
||||
RECT src={0}, dest={0};
|
||||
HRESULT hr = m_Wc->GetVideoPosition(&src, &dest);
|
||||
*px = dest.left;
|
||||
*py = dest.right;
|
||||
*pcx = dest.right - dest.left;
|
||||
*pcy = dest.bottom - dest.top;
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* PutMoviePosition
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::PutMoviePosition(
|
||||
LONG x,
|
||||
LONG y,
|
||||
LONG cx,
|
||||
LONG cy
|
||||
)
|
||||
{
|
||||
BOOL bRet = TRUE;
|
||||
|
||||
RECT rc;
|
||||
SetRect(&rc, x, y, x + cx, y + cy);
|
||||
|
||||
if(m_bRndLess)
|
||||
{
|
||||
CAutoLock Lock(&m_AppImageLock);
|
||||
MapWindowRect(m_hwndApp, HWND_DESKTOP, &rc);
|
||||
m_rcDst = rc;
|
||||
CreateFontCache(HEIGHT(&m_rcDst) / GRID_CY);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_Wc)
|
||||
{
|
||||
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;
|
||||
|
||||
//
|
||||
// Start playing from the begining of the movie
|
||||
//
|
||||
m_Mc->Run();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* PauseMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::PauseMovie(
|
||||
)
|
||||
{
|
||||
m_Mode = MOVIE_PAUSED;
|
||||
m_Mc->Pause();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetStateMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
|
||||
OAFilterState
|
||||
CMpegMovie::GetStateMovie(
|
||||
)
|
||||
{
|
||||
OAFilterState State;
|
||||
m_Mc->GetState(INFINITE,&State);
|
||||
return State;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* StopMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::StopMovie(
|
||||
)
|
||||
{
|
||||
m_Mode = MOVIE_STOPPED;
|
||||
m_Mc->Stop();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* StatusMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
EMpegMovieMode
|
||||
CMpegMovie::StatusMovie(
|
||||
)
|
||||
{
|
||||
if(m_Mc)
|
||||
{
|
||||
FILTER_STATE fs;
|
||||
HRESULT hr;
|
||||
|
||||
hr = m_Mc->GetState(100, (OAFilterState *)&fs);
|
||||
|
||||
// Don't know what the state is so just stay at old state.
|
||||
if(hr == VFW_S_STATE_INTERMEDIATE)
|
||||
{
|
||||
return m_Mode;
|
||||
}
|
||||
|
||||
switch(fs)
|
||||
{
|
||||
case State_Stopped:
|
||||
m_Mode = MOVIE_STOPPED;
|
||||
break;
|
||||
|
||||
case State_Paused:
|
||||
m_Mode = MOVIE_PAUSED;
|
||||
break;
|
||||
|
||||
case State_Running:
|
||||
m_Mode = MOVIE_PLAYING;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return m_Mode;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* CanMovieFrameStep
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::CanMovieFrameStep()
|
||||
{
|
||||
IVideoFrameStep* lpFS;
|
||||
HRESULT hr;
|
||||
|
||||
hr = m_Fg->QueryInterface(__uuidof(IVideoFrameStep), (LPVOID *)&lpFS);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
hr = lpFS->CanStep(0L, NULL);
|
||||
lpFS->Release();
|
||||
}
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* FrameStepMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::FrameStepMovie()
|
||||
{
|
||||
IVideoFrameStep* lpFS;
|
||||
HRESULT hr;
|
||||
|
||||
hr = m_Fg->QueryInterface(__uuidof(IVideoFrameStep), (LPVOID *)&lpFS);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
FrameStepCount++;
|
||||
|
||||
hr = lpFS->Step(1, NULL);
|
||||
lpFS->Release();
|
||||
}
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
|
||||
/******************************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;
|
||||
|
||||
if(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_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;
|
||||
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)
|
||||
{
|
||||
m_Mc->Pause();
|
||||
hr = m_Mc->GetState(INFINITE, (OAFilterState *)&fs);
|
||||
m_Mc->Stop();
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* GetPerformanceInterfaces
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
CMpegMovie::GetPerformanceInterfaces(
|
||||
)
|
||||
{
|
||||
FindInterfaceFromFilterGraph(IID_IMpegAudioDecoder, (LPVOID *)&pMpegAudioDecoder);
|
||||
FindInterfaceFromFilterGraph(IID_IQualProp, (LPVOID *)&pVideoRenderer);
|
||||
}
|
||||
|
||||
|
||||
HRESULT
|
||||
CMpegMovie::FindInterfaceFromFilterGraph(
|
||||
REFIID iid, // interface to look for
|
||||
LPVOID *lp // place to return interface pointer in
|
||||
)
|
||||
{
|
||||
IEnumFilters* pEF;
|
||||
IBaseFilter* pFilter;
|
||||
|
||||
// Grab an enumerator for the filter graph.
|
||||
HRESULT hr = m_Fg->EnumFilters(&pEF);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Check out each filter.
|
||||
while(pEF->Next(1, &pFilter, NULL) == S_OK)
|
||||
{
|
||||
hr = pFilter->QueryInterface(iid, lp);
|
||||
pFilter->Release();
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pEF->Release();
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Public*Routine******************************\
|
||||
* IsTimeFormatSupported
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::IsTimeFormatSupported(GUID Format)
|
||||
{
|
||||
return m_Ms != NULL && m_Ms->IsFormatSupported(&Format) == S_OK;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Public*Routine******************************\
|
||||
* IsTimeSupported
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::IsTimeSupported()
|
||||
{
|
||||
return m_Ms != NULL && m_Ms->IsFormatSupported(&TIME_FORMAT_MEDIA_TIME) == S_OK;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Public*Routine******************************\
|
||||
* GetTimeFormat
|
||||
*
|
||||
\**************************************************************************/
|
||||
GUID
|
||||
CMpegMovie::GetTimeFormat()
|
||||
{
|
||||
return m_TimeFormat;
|
||||
}
|
||||
|
||||
/*****************************Public*Routine******************************\
|
||||
* SetTimeFormat
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::SetTimeFormat(GUID Format)
|
||||
{
|
||||
HRESULT hr = m_Ms->SetTimeFormat(&Format);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
m_TimeFormat = Format;
|
||||
}
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* SetFocus
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
CMpegMovie::SetFocus()
|
||||
{
|
||||
if(m_Fg)
|
||||
{
|
||||
// Tell the resource manager that we are being made active. This
|
||||
// will then cause the sound to switch to us. This is especially
|
||||
// important when playing audio only files as there is no other
|
||||
// playback window.
|
||||
IResourceManager* pResourceManager;
|
||||
|
||||
HRESULT hr = m_Fg->QueryInterface(IID_IResourceManager, (void**)&pResourceManager);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
IUnknown* pUnknown;
|
||||
|
||||
hr = m_Fg->QueryInterface(IID_IUnknown, (void**)&pUnknown);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
pResourceManager->SetFocus(pUnknown);
|
||||
pUnknown->Release();
|
||||
}
|
||||
|
||||
pResourceManager->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************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******************************\
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: vcdplyer.h
|
||||
//
|
||||
// Desc: DirectShow sample code - header file for TxtPlayer sample
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
#define D3D_OVERLOADS
|
||||
#include <d3d.h>
|
||||
#include "BltAlpha.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 GRID_CY 24
|
||||
#define GRID_CX 40
|
||||
|
||||
struct IMpegAudioDecoder;
|
||||
struct IMpegVideoDecoder;
|
||||
struct IQualProp;
|
||||
|
||||
typedef struct {
|
||||
BITMAPINFOHEADER bmiHeader;
|
||||
union {
|
||||
RGBQUAD bmiColors[iPALETTE_COLORS];
|
||||
DWORD dwBitMasks[iMASK_COLORS];
|
||||
TRUECOLORINFO TrueColorInfo;
|
||||
};
|
||||
} AMDISPLAYINFO;
|
||||
|
||||
#define NUM_CUBE_VERTICES (4*6)
|
||||
|
||||
BOOL VerifyVMR(void);
|
||||
|
||||
|
||||
class CMpegMovie :
|
||||
public CUnknown,
|
||||
public IVMRSurfaceAllocator,
|
||||
public IVMRImagePresenter
|
||||
{
|
||||
private:
|
||||
// Our state variable - records whether we are opened, playing etc.
|
||||
EMpegMovieMode m_Mode;
|
||||
HANDLE m_MediaEvent;
|
||||
HWND m_hwndApp;
|
||||
GUID m_TimeFormat;
|
||||
|
||||
RECT m_rcSrc;
|
||||
RECT m_rcDst;
|
||||
SIZE m_VideoSize;
|
||||
SIZE m_VideoAR;
|
||||
|
||||
HRESULT Initialize3DEnvironment(HWND hwndApp);
|
||||
HRESULT InitDeviceObjects(LPDIRECT3DDEVICE7 pd3dDevice);
|
||||
HRESULT FrameMove(LPDIRECT3DDEVICE7 pd3dDevice,FLOAT fTimeKey);
|
||||
HRESULT Render(LPDIRECT3DDEVICE7 pd3dDevice, LPDIRECTDRAWSURFACE7 pDDSBlend, BYTE alpha);
|
||||
HRESULT RenderAppImage(LPDIRECT3DDEVICE7 pd3dDevice, LPDIRECTDRAWSURFACE7 pDDSBlend, BYTE alpha);
|
||||
HRESULT AllocateSurfaceWorker(DWORD dwFlags,
|
||||
LPBITMAPINFOHEADER lpHdr,
|
||||
LPDDPIXELFORMAT lpPixFmt,
|
||||
LPSIZE lpAspectRatio,
|
||||
DWORD dwMinBackBuffers,
|
||||
DWORD dwMaxBackBuffers,
|
||||
DWORD* lpdwBackBuffer,
|
||||
LPDIRECTDRAWSURFACE7* lplpSurface);
|
||||
HRESULT DDARGB32SurfaceInit(
|
||||
LPDIRECTDRAWSURFACE7* lplpDDS,
|
||||
BOOL bTexture, DWORD cx, DWORD cy);
|
||||
|
||||
|
||||
HRESULT CreateFontCache(int cyFont);
|
||||
CCritSec m_AppImageLock;
|
||||
HFONT m_hFont;
|
||||
int m_cxFont;
|
||||
int m_cyFont;
|
||||
int m_cxFontImg;
|
||||
int m_cyFontImg;
|
||||
LPDIRECTDRAWSURFACE7 m_lpDDSFontCache;
|
||||
|
||||
HMONITOR m_hMonitor;
|
||||
LPDIRECTDRAW7 m_lpDDObj;
|
||||
CAlphaBlt* m_lpBltAlpha;
|
||||
|
||||
LPDIRECTDRAWSURFACE7 m_lpPriSurf;
|
||||
LPDIRECTDRAWSURFACE7 m_lpBackBuffer;
|
||||
LPDIRECTDRAWSURFACE7 m_lpDDTexture;
|
||||
LPDIRECTDRAWSURFACE7 m_lpDDAppImage;
|
||||
D3DVERTEX m_pCubeVertices[NUM_CUBE_VERTICES];
|
||||
DDCAPS m_ddHWCaps;
|
||||
AMDISPLAYINFO m_DispInfo;
|
||||
BOOL m_bRndLess;
|
||||
|
||||
IFilterGraph *m_Fg;
|
||||
IGraphBuilder *m_Gb;
|
||||
IMediaControl *m_Mc;
|
||||
IMediaSeeking *m_Ms;
|
||||
IMediaEvent *m_Me;
|
||||
IVMRSurfaceAllocatorNotify *m_SAN;
|
||||
IVMRWindowlessControl *m_Wc;
|
||||
|
||||
HRESULT AddVideoMixingRendererToFG();
|
||||
void GetPerformanceInterfaces();
|
||||
HRESULT FindInterfaceFromFilterGraph(
|
||||
REFIID iid, // interface to look for
|
||||
LPVOID *lp // place to return interface pointer in
|
||||
);
|
||||
|
||||
public:
|
||||
CMpegMovie(HWND hwndApplication);
|
||||
~CMpegMovie();
|
||||
|
||||
DECLARE_IUNKNOWN
|
||||
STDMETHODIMP NonDelegatingQueryInterface(REFIID, void**);
|
||||
|
||||
// IVMRSurfaceAllocator
|
||||
STDMETHODIMP AllocateSurface(DWORD_PTR w,
|
||||
VMRALLOCATIONINFO *lpAllocInfo,
|
||||
DWORD* lpdwActualBackBuffers,
|
||||
LPDIRECTDRAWSURFACE7* lplpSurface);
|
||||
STDMETHODIMP FreeSurface(DWORD_PTR w);
|
||||
STDMETHODIMP PrepareSurface(DWORD_PTR w, LPDIRECTDRAWSURFACE7 lplpSurface,
|
||||
DWORD dwSurfaceFlags);
|
||||
STDMETHODIMP AdviseNotify(IVMRSurfaceAllocatorNotify* lpIVMRSurfAllocNotify);
|
||||
|
||||
|
||||
// IVMRImagePresenter
|
||||
STDMETHODIMP StartPresenting(DWORD_PTR w);
|
||||
STDMETHODIMP StopPresenting(DWORD_PTR w);
|
||||
STDMETHODIMP PresentImage(DWORD_PTR w, VMRPRESENTATIONINFO* p);
|
||||
|
||||
HRESULT OpenMovie(TCHAR *lpFileName);
|
||||
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 GetMoviePosition(LONG *x, LONG *y, LONG *cx, LONG *cy);
|
||||
BOOL GetNativeMovieSize(LONG *cx, LONG *cy);
|
||||
BOOL CanMovieFrameStep();
|
||||
BOOL FrameStepMovie();
|
||||
REFTIME GetDuration();
|
||||
REFTIME GetCurrentPosition();
|
||||
BOOL SeekToPosition(REFTIME rt,BOOL bFlushData);
|
||||
EMpegMovieMode StatusMovie();
|
||||
BOOL IsTimeFormatSupported(GUID Format);
|
||||
BOOL IsTimeSupported();
|
||||
BOOL SetTimeFormat(GUID Format);
|
||||
GUID GetTimeFormat();
|
||||
void SetFocus();
|
||||
BOOL ConfigDialog(HWND hwnd);
|
||||
BOOL RepaintVideo(HWND hwnd, HDC hdc);
|
||||
BOOL SetAppText(char* sz);
|
||||
|
||||
LPDIRECTDRAWSURFACE7 GetAppImage() {
|
||||
return m_lpDDAppImage;
|
||||
}
|
||||
|
||||
|
||||
IMpegAudioDecoder *pMpegAudioDecoder;
|
||||
IQualProp *pVideoRenderer;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user