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,371 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// File: AllocPresenter.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Implementation of user-provided allocator-presenter for VMR
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#include "project.h"
|
||||
#include <mmreg.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "resrc1.h"
|
||||
#include "D3DTextr.h"
|
||||
#include "utils.h"
|
||||
|
||||
#ifndef __INITDDSTRUCT_DEFINED
|
||||
#define __INITDDSTRUCT_DEFINED
|
||||
template <typename T>
|
||||
__inline void INITDDSTRUCT(T& dd)
|
||||
{
|
||||
ZeroMemory(&dd, sizeof(dd));
|
||||
dd.dwSize = sizeof(dd);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// CreateDefaultAllocatorPresenter
|
||||
//
|
||||
// creates user-provides allocator presenter
|
||||
//
|
||||
// Usually you have to actually override several functions of AllocatorPresenter;
|
||||
// For the rest, QI IVMRImagePresenter and call default functions
|
||||
//----------------------------------------------------------------------------
|
||||
HRESULT
|
||||
CMpegMovie::CreateDefaultAllocatorPresenter(
|
||||
LPDIRECTDRAW7 lpDD,
|
||||
LPDIRECTDRAWSURFACE7 lpPS
|
||||
)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
IVMRImagePresenterExclModeConfig* lpConfig = NULL;
|
||||
|
||||
__try {
|
||||
// for exclusive mode, we do need AllocPresenterDDXclMode of IVMRSurfaceAllocator
|
||||
CHECK_HR(hr = CoCreateInstance(CLSID_AllocPresenterDDXclMode, NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
__uuidof(IVMRSurfaceAllocator),
|
||||
(LPVOID*)&m_lpDefSA));
|
||||
|
||||
CHECK_HR(hr = m_lpDefSA->QueryInterface(__uuidof(IVMRImagePresenterExclModeConfig),
|
||||
(LPVOID*)&lpConfig));
|
||||
|
||||
CHECK_HR(hr = lpConfig->SetRenderingPrefs(RenderPrefs_ForceOffscreen));
|
||||
|
||||
// this sets exclusive mode
|
||||
CHECK_HR(hr = lpConfig->SetXlcModeDDObjAndPrimarySurface(lpDD, lpPS));
|
||||
|
||||
CHECK_HR(hr = m_lpDefSA->QueryInterface(__uuidof(IVMRImagePresenter),
|
||||
(LPVOID*)&m_lpDefIP));
|
||||
|
||||
CHECK_HR(hr = m_lpDefSA->QueryInterface(__uuidof(IVMRWindowlessControl),
|
||||
(LPVOID*)&m_lpDefWC));
|
||||
|
||||
CHECK_HR(hr = m_lpDefWC->SetVideoClippingWindow(m_hwndApp));
|
||||
CHECK_HR(hr = m_lpDefSA->AdviseNotify(this));
|
||||
}
|
||||
__finally {
|
||||
|
||||
RELEASE(lpConfig);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
RELEASE(m_lpDefWC);
|
||||
RELEASE(m_lpDefIP);
|
||||
RELEASE(m_lpDefSA);
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// NonDelegatingQueryInterface
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP
|
||||
CMpegMovie::NonDelegatingQueryInterface(
|
||||
REFIID riid,
|
||||
void** ppv
|
||||
)
|
||||
{
|
||||
if (riid == __uuidof(IVMRSurfaceAllocator)) {
|
||||
return GetInterface((IVMRSurfaceAllocator*)this, ppv);
|
||||
}
|
||||
else if (riid == __uuidof(IVMRImagePresenter)) {
|
||||
return GetInterface((IVMRImagePresenter*)this, ppv);
|
||||
}
|
||||
|
||||
return CUnknown::NonDelegatingQueryInterface(riid,ppv);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IVMRSurfaceAllocator-overriden functions
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// AllocateSurfaces
|
||||
//
|
||||
// call default AllocateSurface
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP
|
||||
CMpegMovie::AllocateSurface(
|
||||
DWORD_PTR dwUserID,
|
||||
VMRALLOCATIONINFO* lpAllocInfo,
|
||||
DWORD* lpdwBuffer,
|
||||
LPDIRECTDRAWSURFACE7* lplpSurface
|
||||
)
|
||||
{
|
||||
HRESULT hr = m_lpDefSA->AllocateSurface(dwUserID, lpAllocInfo,
|
||||
lpdwBuffer, lplpSurface);
|
||||
if( SUCCEEDED(hr))
|
||||
{
|
||||
m_lpSurf = *lplpSurface;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// FreeSurfaces()
|
||||
//
|
||||
// Call default FreeSurface
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP
|
||||
CMpegMovie::FreeSurface(
|
||||
DWORD_PTR dwUserID
|
||||
)
|
||||
{
|
||||
HRESULT hr = m_lpDefSA->FreeSurface(dwUserID);
|
||||
|
||||
if( SUCCEEDED(hr))
|
||||
{
|
||||
m_lpSurf = NULL;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// PrepareSurface
|
||||
//
|
||||
// call default PrepareSurface
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP
|
||||
CMpegMovie::PrepareSurface(
|
||||
DWORD_PTR dwUserID,
|
||||
LPDIRECTDRAWSURFACE7 lplpSurface,
|
||||
DWORD dwSurfaceFlags
|
||||
)
|
||||
{
|
||||
return m_lpDefSA->PrepareSurface(dwUserID, lplpSurface, dwSurfaceFlags);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// AdviseNotify
|
||||
//
|
||||
// call default AdviseNotify
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP
|
||||
CMpegMovie::AdviseNotify(
|
||||
IVMRSurfaceAllocatorNotify* lpIVMRSurfAllocNotify
|
||||
)
|
||||
{
|
||||
return m_lpDefSA->AdviseNotify(lpIVMRSurfAllocNotify);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IVMRSurfaceAllocatorNotify-overriden functions
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// AdviseSurfaceAllocator
|
||||
//
|
||||
// standard AdviseSurfaceAllocator
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP
|
||||
CMpegMovie::AdviseSurfaceAllocator(
|
||||
DWORD_PTR dwUserID,
|
||||
IVMRSurfaceAllocator* lpIVRMSurfaceAllocator
|
||||
)
|
||||
{
|
||||
return m_lpDefSAN->AdviseSurfaceAllocator(dwUserID, lpIVRMSurfaceAllocator);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SetDDrawDevice
|
||||
//
|
||||
// standard SetDDrawDevice
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP
|
||||
CMpegMovie::SetDDrawDevice(LPDIRECTDRAW7 lpDDrawDevice,HMONITOR hMonitor)
|
||||
{
|
||||
return m_lpDefSAN->SetDDrawDevice(lpDDrawDevice, hMonitor);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// ChangeDDrawDevice
|
||||
//
|
||||
// standard ChangeDDrawDevice
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP
|
||||
CMpegMovie::ChangeDDrawDevice(LPDIRECTDRAW7 lpDDrawDevice,HMONITOR hMonitor)
|
||||
{
|
||||
return m_lpDefSAN->ChangeDDrawDevice(lpDDrawDevice, hMonitor);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// RestoreDDrawSurfaces
|
||||
//
|
||||
// standard RestoreDDrawSurfaces
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP CMpegMovie::RestoreDDrawSurfaces()
|
||||
{
|
||||
// Make sure that the menu is redrawn
|
||||
if( m_AlphaBlt )
|
||||
m_AlphaBlt->SetMenuRestoreFlag();
|
||||
|
||||
return m_lpDefSAN->RestoreDDrawSurfaces();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// NotifyEvent
|
||||
//
|
||||
// standard NotifyEvent
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP
|
||||
CMpegMovie::NotifyEvent(LONG EventCode, LONG_PTR lp1, LONG_PTR lp2)
|
||||
{
|
||||
return m_lpDefSAN->NotifyEvent(EventCode, lp1, lp2);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SetBorderColor
|
||||
//
|
||||
// default SetBorderColor
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP
|
||||
CMpegMovie::SetBorderColor(
|
||||
COLORREF clr
|
||||
)
|
||||
{
|
||||
return m_lpDefSAN->SetBorderColor(clr);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IVMRImagePresenter overriden functions
|
||||
// we perform all user customization here
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// StartPresenting()
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP
|
||||
CMpegMovie::StartPresenting(DWORD_PTR dwUserID)
|
||||
{
|
||||
return m_lpDefIP->StartPresenting(dwUserID);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// StopPresenting()
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP
|
||||
CMpegMovie::StopPresenting(DWORD_PTR dwUserID)
|
||||
{
|
||||
return m_lpDefIP->StopPresenting(dwUserID);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// PresentImage
|
||||
//
|
||||
// Here all the fun happens. lpPresInfo contains surface with current video image
|
||||
// Call m_AlphaBlt->AlphaBlt to perform all the necessary transformation
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP
|
||||
CMpegMovie::PresentImage(
|
||||
DWORD_PTR dwUserID,
|
||||
VMRPRESENTATIONINFO* lpPresInfo
|
||||
)
|
||||
{
|
||||
// clear the background
|
||||
DDBLTFX ddFX;
|
||||
INITDDSTRUCT(ddFX);
|
||||
|
||||
RECT rcS = {0, 0, 640, 480};
|
||||
RECT rcD = {128, 96, 512, 384};
|
||||
RECT rcDt ={128, 0, 512, 288};
|
||||
|
||||
m_lpDefWC->GetVideoPosition(&rcS, NULL);
|
||||
if( g_ss.bShowTwist )
|
||||
{
|
||||
m_AlphaBlt->AlphaBlt(&rcDt, lpPresInfo->lpSurf, &rcS, 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_AlphaBlt->AlphaBlt(&rcD, lpPresInfo->lpSurf, &rcS, 0xFF);
|
||||
}
|
||||
|
||||
m_lpSurf->Flip(NULL,0);
|
||||
|
||||
if( g_ss.bShowStatistics && m_Qp)
|
||||
{
|
||||
// call IQualProp functions here to get performance statistics
|
||||
GetPerformance();
|
||||
}
|
||||
|
||||
// Show the scene
|
||||
m_pDDObject.GetFB()->Flip(NULL, /*DDFLIP_WAIT*/ 0);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// GetPerformance
|
||||
//
|
||||
// Calls IQualProp::get_AvgFrameRate
|
||||
// every 25 frames (to not overload VMR with senseless calculations)
|
||||
// and saves this value to g_ss, global SceneSettings structure
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
CMpegMovie::GetPerformance()
|
||||
{
|
||||
|
||||
static int nCounter = 0;
|
||||
static int nAvgFrameRate = 0;
|
||||
char szFrameRate[MAX_PATH];
|
||||
|
||||
nCounter++;
|
||||
if( 25 == nCounter )
|
||||
{
|
||||
m_Qp->get_AvgFrameRate( &nAvgFrameRate);
|
||||
nCounter = 0;
|
||||
}
|
||||
sprintf( szFrameRate, "FPS: %f ", (float)nAvgFrameRate/100.f);
|
||||
lstrcpy(g_ss.achFPS, TEXT(szFrameRate));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,976 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// File: BltAlpha.h
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Header file and class description for CAlphaBlt,
|
||||
// texture surface to be used in PresentImage of the
|
||||
// customized allocator-presenter
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __INITDDSTRUCT_DEFINED
|
||||
#define __INITDDSTRUCT_DEFINED
|
||||
#include <math.h>
|
||||
#include <d3dxmath.h>
|
||||
#include "d3dtextr.h"
|
||||
#include "d3dfont.h"
|
||||
#include "utils.h"
|
||||
#include "resrc1.h"
|
||||
#include "d3dutil.h"
|
||||
|
||||
extern struct SceneSettings g_ss;
|
||||
|
||||
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
|
||||
|
||||
#define COMPLVERTSIZE 640 // must be divisible by 4!!!
|
||||
#define pi 3.1415926535f
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// CAlphaBlt
|
||||
//
|
||||
// Desc: texture surface to be used in PresentImage of the
|
||||
// customized allocator-presenter
|
||||
//----------------------------------------------------------------------------
|
||||
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;
|
||||
bool m_bNeedToRestoreMenu;
|
||||
TextureContainer * m_ptxtrMenu;
|
||||
CD3DFont * m_pFont;
|
||||
|
||||
typedef struct Vertex
|
||||
{
|
||||
float x, y, z, rhw;
|
||||
D3DCOLOR clr;
|
||||
float tu, tv;
|
||||
} Vertex;
|
||||
|
||||
Vertex pVertices[4]; // primitive for rotating effect
|
||||
Vertex pVComplex[COMPLVERTSIZE];// primitive for twisting effect
|
||||
Vertex pVMenu[4]; // primitive for menu effect
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// CAlphaBlt::Rotate
|
||||
//
|
||||
// Desc: 3D transformation of pVertices that provide rotation around Z and Y
|
||||
//
|
||||
// Parameters:
|
||||
// theta - angle of rotation around Z axis
|
||||
// thetaY - angle of rotation around Y axis
|
||||
// pVertices - array of (Vertex*) to be transformed
|
||||
// nSize - number of vertices
|
||||
// (cx2, cy2) - center of rotation
|
||||
//----------------------------------------------------------------------------
|
||||
void Rotate(float theta, float thetaY,
|
||||
CAlphaBlt::Vertex * pVertices,
|
||||
int nSize, float cx2, float cy2)
|
||||
{
|
||||
D3DXMATRIX mtrV;
|
||||
D3DXMATRIX mtrRotZ;
|
||||
D3DXMATRIX mtrRotY;
|
||||
D3DXMATRIX mtrPrs;
|
||||
D3DXMATRIX mtrRes;
|
||||
|
||||
float pi2 = 1.57079632675f; // pi/2.
|
||||
|
||||
// initialize mtrV
|
||||
mtrV.m[0][0] = pVertices[0].x - cx2;
|
||||
mtrV.m[1][0] = pVertices[0].y - cy2;
|
||||
mtrV.m[2][0] = pVertices[0].z;
|
||||
mtrV.m[3][0] = 0.f;
|
||||
|
||||
mtrV.m[0][1] = pVertices[1].x - cx2;
|
||||
mtrV.m[1][1] = pVertices[1].y - cy2;
|
||||
mtrV.m[2][1] = pVertices[1].z;
|
||||
mtrV.m[3][1] = 0;
|
||||
|
||||
mtrV.m[0][2] = pVertices[2].x - cx2;
|
||||
mtrV.m[1][2] = pVertices[2].y - cy2;
|
||||
mtrV.m[2][2] = pVertices[2].z;
|
||||
mtrV.m[3][2] = 0;
|
||||
|
||||
mtrV.m[0][3] = pVertices[3].x - cx2;
|
||||
mtrV.m[1][3] = pVertices[3].y - cy2;
|
||||
mtrV.m[2][3] = pVertices[3].z;
|
||||
mtrV.m[3][3] = 0;
|
||||
|
||||
D3DXMatrixRotationZ( &mtrRotZ, theta);
|
||||
D3DXMatrixRotationY( &mtrRotY, thetaY);
|
||||
D3DXMatrixPerspectiveFov( &mtrPrs, pi2, 1.1f, 0.f, 1.f);
|
||||
|
||||
|
||||
// mtrRotZ * mtrV
|
||||
D3DXMatrixMultiply( &mtrRes, &mtrRotZ, &mtrV);
|
||||
|
||||
// mtrRotY * mtrRotZ * mtrV
|
||||
D3DXMatrixMultiply( &mtrV, &mtrRotY, &mtrRes);
|
||||
|
||||
// mtrPrs * mtrRotY * mtrRotZ * mtrV
|
||||
D3DXMatrixMultiply( &mtrRes, &mtrPrs, &mtrV);
|
||||
|
||||
// here, mtrRes has what we need; copy it back to pVertices
|
||||
pVertices[0].x = mtrRes.m[0][0] + cx2;
|
||||
pVertices[1].x = mtrRes.m[0][1] + cx2;
|
||||
pVertices[2].x = mtrRes.m[0][2] + cx2;
|
||||
pVertices[3].x = mtrRes.m[0][3] + cx2;
|
||||
|
||||
pVertices[0].y = mtrRes.m[1][0] + cy2;
|
||||
pVertices[1].y = mtrRes.m[1][1] + cy2;
|
||||
pVertices[2].y = mtrRes.m[1][2] + cy2;
|
||||
pVertices[3].y = mtrRes.m[1][3] + cy2;
|
||||
|
||||
pVertices[0].z = mtrRes.m[2][0];
|
||||
pVertices[1].z = mtrRes.m[2][1];
|
||||
pVertices[2].z = mtrRes.m[2][2];
|
||||
pVertices[3].z = mtrRes.m[2][3];
|
||||
return;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// 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 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 cab 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.
|
||||
//
|
||||
// Apply the following rules:
|
||||
// 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) {
|
||||
|
||||
__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:
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//----------------------------------------------------------------------------
|
||||
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_ptxtrMenu( NULL),
|
||||
m_pFont(NULL),
|
||||
m_fPowerOf2(false),
|
||||
m_fSquare(false),
|
||||
m_bNeedToRestoreMenu(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;
|
||||
}
|
||||
}
|
||||
|
||||
// here, so far we have D3Device, let's Restore texture surface
|
||||
// it actually loads the bitmap from the resource onto a texture surface
|
||||
m_ptxtrMenu = new TextureContainer(
|
||||
"IDB_MENU", 0, 0, IDB_MENU);
|
||||
|
||||
if( m_ptxtrMenu)
|
||||
{
|
||||
hr = m_ptxtrMenu->LoadImageData();
|
||||
if( m_ptxtrMenu->m_hbmBitmap )
|
||||
{
|
||||
BITMAP bm;
|
||||
GetObject( m_ptxtrMenu->m_hbmBitmap, sizeof(BITMAP), &bm );
|
||||
m_ptxtrMenu->m_dwWidth = (DWORD)bm.bmWidth;
|
||||
m_ptxtrMenu->m_dwHeight = (DWORD)bm.bmHeight;
|
||||
m_ptxtrMenu->m_dwBPP = (DWORD)bm.bmBitsPixel;
|
||||
}
|
||||
|
||||
hr = m_ptxtrMenu->Restore(m_pD3DDevice);
|
||||
if( FAILED(hr))
|
||||
{
|
||||
delete m_ptxtrMenu;
|
||||
m_ptxtrMenu = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// load the font
|
||||
m_pFont = new CD3DFont( TEXT("Comic Sans MS"),18,0);
|
||||
if( m_pFont )
|
||||
{
|
||||
m_pFont->InitDeviceObjects( m_pDD, m_pD3DDevice);
|
||||
}
|
||||
|
||||
// setup menu primitive
|
||||
pVMenu[0].x = 0.f;
|
||||
pVMenu[0].y = 0.f;
|
||||
pVMenu[0].z = 0.0f;
|
||||
pVMenu[0].rhw = 2.0f;
|
||||
pVMenu[0].clr = RGBA_MAKE(0xff, 0xff, 0xff, 0xff);
|
||||
|
||||
pVMenu[1].x = 60.f;
|
||||
pVMenu[1].y = 0.f;
|
||||
pVMenu[1].z = 0.0f;
|
||||
pVMenu[1].rhw = 2.0f;
|
||||
pVMenu[1].clr = RGBA_MAKE(0xff, 0xff, 0xff, 0xff);
|
||||
|
||||
pVMenu[2].x = 0.f;
|
||||
pVMenu[2].y = 480.f;
|
||||
pVMenu[2].z = 0.0f;
|
||||
pVMenu[2].rhw = 2.0f;
|
||||
pVMenu[2].clr = RGBA_MAKE(0xff, 0xff, 0xff, 0xff);
|
||||
|
||||
pVMenu[3].x = 60.f;
|
||||
pVMenu[3].y = 480.f;
|
||||
pVMenu[3].z = 0.0f;
|
||||
pVMenu[3].rhw = 2.0f;
|
||||
pVMenu[3].clr = RGBA_MAKE(0xff, 0xff, 0xff, 0xff);
|
||||
|
||||
//
|
||||
// Setup the SRC info
|
||||
//
|
||||
pVMenu[0].tu = 0.f;
|
||||
pVMenu[0].tv = 0.f;
|
||||
|
||||
pVMenu[1].tu = 1.f;
|
||||
pVMenu[1].tv = 0.f;
|
||||
|
||||
pVMenu[2].tu = 0.f;
|
||||
pVMenu[2].tv = 1.f;
|
||||
|
||||
pVMenu[3].tu = 1.f;
|
||||
pVMenu[3].tv = 1.f;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Destructor
|
||||
//----------------------------------------------------------------------------
|
||||
~CAlphaBlt()
|
||||
{
|
||||
if( m_ptxtrMenu )
|
||||
{
|
||||
delete m_ptxtrMenu;
|
||||
m_ptxtrMenu = NULL;
|
||||
}
|
||||
|
||||
if( m_pFont )
|
||||
{
|
||||
delete m_pFont;
|
||||
m_pFont = NULL;
|
||||
}
|
||||
|
||||
RELEASE(m_lpDDBackBuffer);
|
||||
RELEASE(m_lpDDM32);
|
||||
RELEASE(m_lpDDM16);
|
||||
|
||||
RELEASE(m_pD3DDevice);
|
||||
RELEASE(m_pD3D);
|
||||
RELEASE(m_pDD);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// GetMenuTexture
|
||||
//
|
||||
// returns pointer to texture's DD surface or NULL otherwise
|
||||
//----------------------------------------------------------------------------
|
||||
LPDIRECTDRAWSURFACE7 GetMenuTexture()
|
||||
{
|
||||
if( m_ptxtrMenu && m_ptxtrMenu->m_pddsSurface )
|
||||
{
|
||||
return (m_ptxtrMenu->m_pddsSurface);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SetMenuRestoreFlag
|
||||
//
|
||||
// sets m_bNeedToRestoreMenu = true; (called from CMpegMovie::RestoreDDRawSurfaces() )
|
||||
//----------------------------------------------------------------------------
|
||||
void SetMenuRestoreFlag()
|
||||
{
|
||||
m_bNeedToRestoreMenu = true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// GetFont
|
||||
//----------------------------------------------------------------------------
|
||||
CD3DFont * GetFont()
|
||||
{
|
||||
return m_pFont;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// PrepareVerticesRotate
|
||||
//
|
||||
// This is the 'main' transformation function for foration effect.
|
||||
// It generates rotation angles from 'time' variable that is just
|
||||
// a static counter of images from CMpegMovie:PresentImage function
|
||||
//
|
||||
// Parameters:
|
||||
// lpDst - destination rectangle
|
||||
// lpSrc - source rectangle
|
||||
// alpha - alpha level for the surface
|
||||
// fWid - width of the surface obtained by CMpegMovie:PresentImage
|
||||
// fHgt - height of the surface obtained by CMpegMovie:PresentImage
|
||||
//----------------------------------------------------------------------------
|
||||
void PrepareVerticesRotate( RECT* lpDst, RECT* lpSrc, BYTE alpha,
|
||||
float fWid, float fHgt)
|
||||
{
|
||||
float RotRadZ = 0.f;
|
||||
float RotRadY = 0.f;
|
||||
|
||||
//
|
||||
// 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;
|
||||
|
||||
// g_ss.nGradZ is an angle in grades, so calculate radians
|
||||
RotRadZ = (float) (g_ss.nGradZ++) * pi / 180.f;
|
||||
if( !g_ss.bRotateZ)
|
||||
{
|
||||
g_ss.nGradZ--;
|
||||
}
|
||||
|
||||
RotRadY = (float) (g_ss.nGradY++) * pi / 180.f;
|
||||
if( !g_ss.bRotateY)
|
||||
{
|
||||
g_ss.nGradY--;
|
||||
}
|
||||
|
||||
// to avoid stack overflow, limit counters withing 360 grades
|
||||
if( g_ss.nGradZ > 360)
|
||||
{
|
||||
g_ss.nGradZ = 0;
|
||||
}
|
||||
|
||||
if( g_ss.nGradY > 360)
|
||||
{
|
||||
g_ss.nGradY = 0;
|
||||
}
|
||||
|
||||
// and finally rotate the primitive pVertices
|
||||
// NOTE that rotation center is hardcoded for the case
|
||||
// 640x480 display mode
|
||||
Rotate(RotRadZ, RotRadY, pVertices, 4, 320.f, 240.f);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// PrepareVerticesTwist
|
||||
//
|
||||
// This is the 'main' transformation function for "twist" effect.
|
||||
// It generates transformation parameters 'time' variable that is just
|
||||
// a static counter of images from CMpegMovie:PresentImage function
|
||||
//
|
||||
// Parameters:
|
||||
// lpDst - destination rectangle
|
||||
// lpSrc - source rectangle
|
||||
// alpha - alpha level for the surface
|
||||
// fWid - width of the surface obtained by CMpegMovie:PresentImage
|
||||
// fHgt - height of the surface obtained by CMpegMovie:PresentImage
|
||||
//
|
||||
// Other: put your own effects here
|
||||
// The effect I use is as following:
|
||||
// (a) move picture down to create 'slipping' effect
|
||||
// (b) srink lower part of the picture (parameter c applied to each verticle
|
||||
// so that it would look like a wine glass stem (cosine is what we need)
|
||||
// Shrinking coefficient depends on Y-coordinate of a verticle
|
||||
// (c) twist lower part of the picture around Y axis, angle depends on
|
||||
// Y-coordinate of a verticle
|
||||
//----------------------------------------------------------------------------
|
||||
void PrepareVerticesTwist( RECT* lpDst, RECT* lpSrc, BYTE alpha,
|
||||
float fW, float fH)
|
||||
{
|
||||
CAlphaBlt::Vertex * V = pVComplex;
|
||||
float W = (float)(lpDst->right - lpDst->left);
|
||||
float H = (float)(lpDst->bottom - lpDst->top);
|
||||
float sW = (float)(lpSrc->right - lpSrc->left)/fW;
|
||||
float sH = (float)(lpSrc->bottom - lpSrc->top);
|
||||
float Ht = 480 - H;
|
||||
float c;
|
||||
float radY = 0.f;
|
||||
float radX = pi/4.f;
|
||||
float x;
|
||||
double costh;
|
||||
double sinth;
|
||||
D3DXMATRIX mtrPrs;
|
||||
D3DXMATRIX mtrOrg;
|
||||
D3DXMATRIX mtrRes;
|
||||
|
||||
int N = COMPLVERTSIZE/2;
|
||||
|
||||
g_ss.nDy = g_ss.nDy + 3;
|
||||
if( g_ss.nDy > 480 )
|
||||
{
|
||||
g_ss.nDy = 0;
|
||||
}
|
||||
|
||||
for( int i=0; i<COMPLVERTSIZE; i=i+2)
|
||||
{
|
||||
V[i ].x = (float)(lpDst->left);
|
||||
V[i+1].x = (float)(lpDst->right);
|
||||
V[i ].y = V[i+1].y = (float)(i * H/(N-1)) + g_ss.nDy;
|
||||
V[i ].z = V[i+1].z = 0.5f;
|
||||
V[i ].rhw = V[i+1].rhw = 2.f;
|
||||
V[i ].clr = V[i+1].clr = RGBA_MAKE(0xff, 0xff, 0xff, alpha);
|
||||
V[i ].tu = ((float)lpSrc->left) / fW;
|
||||
V[i+1].tu = ((float)lpSrc->right) / fW;
|
||||
V[i ].tv = V[i+1].tv = (float)(lpSrc->top + sH * (float)i/(N-1.f)/2.f)/fH;
|
||||
|
||||
|
||||
if( V[i].y >= H )
|
||||
{
|
||||
|
||||
c = (float)( W * (1. + cos(pi * (480. - V[i].y)/Ht)) / 4.);
|
||||
//c *= 0.25f;
|
||||
V[i ].x += c;
|
||||
V[i+1].x -= c;
|
||||
|
||||
radY = pi * ( V[i].y - H ) / 2.f / Ht;
|
||||
|
||||
costh = cos(radY);
|
||||
sinth = sin(radY);
|
||||
|
||||
x = V[i].x - 320.f;
|
||||
V[i].x = (float)(costh * x - sinth * V[i].z) + 320.f;
|
||||
V[i].z = (float)(sinth * x + costh * V[i].z);
|
||||
|
||||
x = V[i+1].x - 320.f;
|
||||
V[i+1].x = (float)(costh * x - sinth * V[i+1].z) + 320.f;
|
||||
V[i+1].z = (float)(sinth * x + costh * V[i+1].z);
|
||||
|
||||
} // if
|
||||
|
||||
}// for i
|
||||
|
||||
|
||||
// now let's implement projection
|
||||
D3DXMatrixPerspectiveFov( &mtrPrs, pi/2.f, 1.1f, 0.f, 1.f);
|
||||
for( i=0; i<COMPLVERTSIZE; i = i+4)
|
||||
{
|
||||
mtrOrg.m[0][0] = V[i].x;
|
||||
mtrOrg.m[1][0] = V[i].y;
|
||||
mtrOrg.m[2][0] = V[i].z;
|
||||
mtrOrg.m[3][0] = 0.f;
|
||||
|
||||
mtrOrg.m[0][1] = V[i+1].x;
|
||||
mtrOrg.m[1][1] = V[i+1].y;
|
||||
mtrOrg.m[2][1] = V[i+1].z;
|
||||
mtrOrg.m[3][1] = 0.f;
|
||||
|
||||
mtrOrg.m[0][2] = V[i+2].x;
|
||||
mtrOrg.m[1][2] = V[i+2].y;
|
||||
mtrOrg.m[2][2] = V[i+2].z;
|
||||
mtrOrg.m[3][2] = 0.f;
|
||||
|
||||
mtrOrg.m[0][3] = V[i+3].x;
|
||||
mtrOrg.m[1][3] = V[i+3].y;
|
||||
mtrOrg.m[2][3] = V[i+3].z;
|
||||
mtrOrg.m[3][3] = 0.f;
|
||||
|
||||
D3DXMatrixMultiply( &mtrRes, &mtrPrs, &mtrOrg);
|
||||
|
||||
V[i ].x = mtrRes.m[0][0];
|
||||
V[i ].y = mtrRes.m[1][0];
|
||||
V[i ].z = mtrRes.m[2][0];
|
||||
|
||||
V[i+1].x = mtrRes.m[0][1];
|
||||
V[i+1].y = mtrRes.m[1][1];
|
||||
V[i+1].z = mtrRes.m[2][1];
|
||||
|
||||
V[i+2].x = mtrRes.m[0][2];
|
||||
V[i+2].y = mtrRes.m[1][2];
|
||||
V[i+2].z = mtrRes.m[2][2];
|
||||
|
||||
V[i+3].x = mtrRes.m[0][3];
|
||||
V[i+3].y = mtrRes.m[1][3];
|
||||
V[i+3].z = mtrRes.m[2][3];
|
||||
}// for
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// AlphaBlt
|
||||
//
|
||||
// This function receives LPDIRECTDRAWSURFACE7 from ImagePresenter, calls
|
||||
// transformation functions to provide visual effects, sets the scene and
|
||||
// renders primitives
|
||||
//
|
||||
// Parameters:
|
||||
// lpDst -- destination rectangle
|
||||
// lpDDSSrc -- surface obtained by ImagePresenter
|
||||
// lpSrc -- source rectangle
|
||||
// bAlpha -- alpha value for the surface
|
||||
//----------------------------------------------------------------------------
|
||||
HRESULT
|
||||
AlphaBlt(RECT* lpDst,
|
||||
LPDIRECTDRAWSURFACE7 lpDDSSrc,
|
||||
RECT* lpSrc,
|
||||
BYTE bAlpha
|
||||
)
|
||||
{
|
||||
HRESULT hr=S_OK;
|
||||
DDSURFACEDESC2 ddsd;
|
||||
|
||||
int nVertSize = 0;
|
||||
|
||||
CAlphaBlt::Vertex * pV = NULL;
|
||||
|
||||
__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;
|
||||
|
||||
if( g_ss.bShowTwist )
|
||||
{
|
||||
nVertSize = COMPLVERTSIZE;
|
||||
PrepareVerticesTwist(lpDst, lpSrc, bAlpha, fWid, fHgt);
|
||||
pV = pVComplex;
|
||||
}
|
||||
else
|
||||
{
|
||||
nVertSize = 4;
|
||||
PrepareVerticesRotate(lpDst, lpSrc, bAlpha, fWid, fHgt);
|
||||
pV = pVertices;
|
||||
}
|
||||
|
||||
BYTE alpha = bAlpha;
|
||||
|
||||
m_pD3DDevice->SetTexture(0, lpDDSSrc);
|
||||
// if menu is defined, set it
|
||||
|
||||
m_pD3DDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
|
||||
m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, TRUE);
|
||||
m_pD3DDevice->SetRenderState(D3DRENDERSTATE_BLENDENABLE, TRUE);
|
||||
m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, FALSE);
|
||||
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_ANISOTROPIC);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFN_ANISOTROPIC);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTFP_LINEAR);
|
||||
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
|
||||
|
||||
//
|
||||
// Do the alpha BLT
|
||||
//
|
||||
CHECK_HR(hr = m_pD3DDevice->BeginScene());
|
||||
CHECK_HR(hr = m_pD3DDevice->Clear(0,NULL,D3DCLEAR_TARGET,0,0.5,0));
|
||||
CHECK_HR(hr = m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,
|
||||
D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1,
|
||||
pV, nVertSize, D3DDP_WAIT));
|
||||
|
||||
// now, draw menu over the video
|
||||
|
||||
// if user switched modes, menu texture may be lost; then restore
|
||||
if( m_bNeedToRestoreMenu )
|
||||
{
|
||||
DDSURFACEDESC2 ddsd;
|
||||
ZeroMemory( &ddsd, sizeof(ddsd));
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
ddsd.dwFlags = DDSD_ALL;
|
||||
m_pDD->GetDisplayMode( &ddsd);
|
||||
|
||||
// if we try to restore surface in a different display mode, we will fail
|
||||
// so make the check first
|
||||
if( ddsd.dwWidth == SCRN_WIDTH &&
|
||||
ddsd.dwHeight == SCRN_HEIGHT &&
|
||||
ddsd.ddpfPixelFormat.dwRGBBitCount == SCRN_BITDEPTH )
|
||||
{
|
||||
hr = GetMenuTexture()->Restore();
|
||||
if( FAILED(hr))
|
||||
{
|
||||
OutputDebugString("ERROR: Failed to restore menu texture");
|
||||
}
|
||||
else
|
||||
{
|
||||
// surface restored, but its image lost; reload
|
||||
if( m_ptxtrMenu)
|
||||
{
|
||||
hr = m_ptxtrMenu->LoadImageData();
|
||||
if( FAILED(hr))
|
||||
{
|
||||
OutputDebugString("Failed to load the image from resource\n");
|
||||
}
|
||||
if( m_ptxtrMenu->m_hbmBitmap )
|
||||
{
|
||||
BITMAP bm;
|
||||
GetObject( m_ptxtrMenu->m_hbmBitmap, sizeof(BITMAP), &bm );
|
||||
m_ptxtrMenu->m_dwWidth = (DWORD)bm.bmWidth;
|
||||
m_ptxtrMenu->m_dwHeight = (DWORD)bm.bmHeight;
|
||||
m_ptxtrMenu->m_dwBPP = (DWORD)bm.bmBitsPixel;
|
||||
}
|
||||
|
||||
hr = m_ptxtrMenu->Restore(m_pD3DDevice);
|
||||
if( FAILED(hr))
|
||||
{
|
||||
delete m_ptxtrMenu;
|
||||
m_ptxtrMenu = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
m_bNeedToRestoreMenu = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputDebugString("Failed to restore menu texture");
|
||||
}
|
||||
}
|
||||
|
||||
m_pD3DDevice->SetTexture(0, m_ptxtrMenu->m_pddsSurface);
|
||||
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_ANISOTROPIC);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFN_ANISOTROPIC);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTFP_LINEAR);
|
||||
//
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
|
||||
|
||||
CHECK_HR(hr = m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,
|
||||
D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1,
|
||||
pVMenu, 4, D3DDP_WAIT));
|
||||
m_pD3DDevice->SetTexture(0, NULL);
|
||||
|
||||
// and if necessary, draw the dext over the menu
|
||||
if( g_ss.bShowHelp )
|
||||
{
|
||||
HRESULT hr = m_pFont->DrawText((float)g_ss.nXHelp, (float)g_ss.nYHelp,
|
||||
RGBA_MAKE(0xFF, 0xFF, 0x00, 0xFF),
|
||||
g_ss.achHelp );
|
||||
}
|
||||
if( g_ss.bShowStatistics )
|
||||
{
|
||||
m_pFont->DrawText( 420, 0,
|
||||
RGBA_MAKE(0x00, 0xFF, 0x00, 0xFF),
|
||||
g_ss.achFPS );
|
||||
}
|
||||
|
||||
CHECK_HR(hr = m_pD3DDevice->EndScene());
|
||||
|
||||
} __finally {
|
||||
m_pD3DDevice->SetTexture(0, NULL);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// TextureSquare
|
||||
// true if texture is square
|
||||
//----------------------------------------------------------------------------
|
||||
bool TextureSquare() {
|
||||
return m_fSquare;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// TexturePower2
|
||||
// true if texture size is of a power of 2
|
||||
//----------------------------------------------------------------------------
|
||||
bool TexturePower2() {
|
||||
return m_fPowerOf2;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// File: DDrawSupport.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Implementation of DDrawObject that provides basic DDraw functionality
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------------------
|
||||
#include "project.h"
|
||||
#include <d3d.h>
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Initialize
|
||||
//
|
||||
// Initialize DDrawObject by getting to fullscreen exclusive mode and
|
||||
// setting front and back buffer
|
||||
//----------------------------------------------------------------------------
|
||||
HRESULT
|
||||
CDDrawObject::Initialize(HWND hWndApp)
|
||||
{
|
||||
HRESULT hr;
|
||||
DDSURFACEDESC2 ddsd;
|
||||
|
||||
m_hwndApp = hWndApp;
|
||||
|
||||
hr = DirectDrawCreateEx(NULL, (LPVOID *)&m_pDDObject,
|
||||
IID_IDirectDraw7, NULL);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Get into fullscreen exclusive mode
|
||||
hr = m_pDDObject->SetCooperativeLevel(hWndApp,
|
||||
DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN |
|
||||
DDSCL_ALLOWREBOOT);
|
||||
if (FAILED(hr)) {
|
||||
Terminate();
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = m_pDDObject->SetDisplayMode(SCRN_WIDTH, SCRN_HEIGHT, SCRN_BITDEPTH,
|
||||
0, DDSDM_STANDARDVGAMODE);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
Terminate();
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
// Create the primary surface with 1 back buffer
|
||||
ZeroMemory(&ddsd, sizeof(ddsd));
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP |
|
||||
DDSCAPS_COMPLEX | DDSCAPS_3DDEVICE;
|
||||
ddsd.dwBackBufferCount = 2;
|
||||
hr = m_pDDObject->CreateSurface(&ddsd, &m_pPrimary, NULL);
|
||||
if (FAILED(hr)) {
|
||||
Terminate();
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Get a pointer to the back buffer
|
||||
DDSCAPS2 ddscaps = { DDSCAPS_BACKBUFFER, 0, 0, 0 };
|
||||
hr = m_pPrimary->GetAttachedSurface(&ddscaps, &m_pBackBuff);
|
||||
if (FAILED(hr)) {
|
||||
Terminate();
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
// Get the screen size and save it as a rect
|
||||
ZeroMemory(&ddsd, sizeof(ddsd));
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
hr = m_pPrimary->GetSurfaceDesc(&ddsd);
|
||||
if (!(SUCCEEDED(hr) &&
|
||||
(ddsd.dwFlags & DDSD_WIDTH) && (ddsd.dwFlags & DDSD_HEIGHT))) {
|
||||
|
||||
Terminate();
|
||||
return hr;
|
||||
}
|
||||
|
||||
SetRect(&m_RectScrn, 0, 0, ddsd.dwWidth, ddsd.dwHeight);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Terminate
|
||||
//
|
||||
// return from exclusive mode
|
||||
//----------------------------------------------------------------------------
|
||||
HRESULT
|
||||
CDDrawObject::Terminate()
|
||||
{
|
||||
|
||||
if (m_pBackBuff) {
|
||||
m_pBackBuff->Release();
|
||||
m_pBackBuff = NULL;
|
||||
}
|
||||
|
||||
if (m_pPrimary) {
|
||||
m_pPrimary->Release();
|
||||
m_pPrimary = NULL;
|
||||
}
|
||||
|
||||
if (m_pDDObject) {
|
||||
|
||||
m_pDDObject->SetCooperativeLevel(m_hwndApp, DDSCL_NORMAL) ;
|
||||
m_pDDObject->Release();
|
||||
m_pDDObject = NULL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// File: DDrawSupport.h
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Prototype of DDrawObject that provides basic DDraw functionality
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef DDRAWSUPPORT_HEADER
|
||||
#define DDRAWSUPPORT_HEADER
|
||||
|
||||
#ifndef __RELEASE_DEFINED
|
||||
#define __RELEASE_DEFINED
|
||||
|
||||
template<typename T>
|
||||
__inline void RELEASE( T* &p )
|
||||
{
|
||||
if( p ) {
|
||||
p->Release();
|
||||
p = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CHECK_HR
|
||||
#define CHECK_HR(expr) if (FAILED(expr)) {\
|
||||
DbgLog((LOG_ERROR, 0, \
|
||||
TEXT("FAILED: %s\nat Line:%d of %s"), \
|
||||
TEXT(#expr), __LINE__, TEXT(__FILE__) ));__leave; } else
|
||||
#endif
|
||||
|
||||
|
||||
#define SCRN_WIDTH 640
|
||||
#define SCRN_HEIGHT 480
|
||||
#define SCRN_BITDEPTH 32
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// CDDrawObject
|
||||
//
|
||||
// Class provides basic DDraw functionality
|
||||
//----------------------------------------------------------------------------
|
||||
class CDDrawObject {
|
||||
|
||||
public:
|
||||
CDDrawObject() :
|
||||
m_hwndApp(NULL),
|
||||
m_pDDObject(NULL),
|
||||
m_pPrimary(NULL),
|
||||
m_pBackBuff(NULL)
|
||||
{
|
||||
ZeroMemory(&m_RectScrn, sizeof(m_RectScrn));
|
||||
}
|
||||
|
||||
HRESULT Initialize(HWND hwndApp);
|
||||
HRESULT Terminate();
|
||||
LPDIRECTDRAW7 GetDDObj() {return m_pDDObject;};
|
||||
LPDIRECTDRAWSURFACE7 GetFB() {return m_pPrimary;};
|
||||
LPDIRECTDRAWSURFACE7 GetBB() {return m_pBackBuff;};
|
||||
|
||||
private:
|
||||
HWND m_hwndApp;
|
||||
RECT m_RectScrn;
|
||||
LPDIRECTDRAW7 m_pDDObject;
|
||||
LPDIRECTDRAWSURFACE7 m_pPrimary;
|
||||
LPDIRECTDRAWSURFACE7 m_pBackBuff;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
Windows XP DirectShow Sample -- VMRXCL
|
||||
--------------------------------------
|
||||
|
||||
Description: This application shows capabilities of the new
|
||||
video mixing renderer (VMR) that is the default video
|
||||
renderer in Windows XP. In particular, it demonstrates
|
||||
how to use the VMR in exclusive DirectDraw mode and
|
||||
how to implement a user-provided (customized) Allocator-Presenter
|
||||
for the VMR. Also, it contains useful utilities to manage
|
||||
bitmaps (as textures) and TrueType fonts for text over video.
|
||||
|
||||
Usage:
|
||||
Upon initialization, VMRXCL asks you to specify a video file.
|
||||
The application switches to DirectDraw exclusive mode, after setting
|
||||
the display mode to 640 x 480 x 32bpp. A bitmap-based menu on the
|
||||
left side of the screen provides interactivity.
|
||||
(From top to bottom, the menu items are:
|
||||
- Show statistics
|
||||
- Pause
|
||||
- Run
|
||||
- Rotate in XY plane
|
||||
- Rotate in YX plane
|
||||
- 'Twist' non-linear effect
|
||||
- Exit
|
||||
|
||||
Right click over the menu button to activate its text hint.
|
||||
Left click to hide text hints.
|
||||
|
||||
Troubleshooting:
|
||||
Depending on the capabilities of your video driver, text may be disabled.
|
||||
You may also experience glitches with bitmaps applied over the video.
|
||||
|
||||
NOTE: The speed of the 3D animation is directly related to the frame rate of
|
||||
the video file being played.
|
||||
|
||||
@@ -0,0 +1,561 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// File: Utils.h
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// External (global) utilities specific for VMRXcl app
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------------------
|
||||
#include "project.h"
|
||||
#include "utils.h"
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// Function: hresultNameLookup
|
||||
// Purpose: returns a string value for the given hresult
|
||||
// Arguments: HRESULT that needs verifying
|
||||
// Returns: string
|
||||
//-----------------------------------------------------------------------------------------*/
|
||||
const char * hresultNameLookup(HRESULT hres)
|
||||
{
|
||||
switch(hres)
|
||||
{
|
||||
case VFW_E_CANNOT_RENDER:
|
||||
return "VFW_E_CANNOT_RENDER";
|
||||
break;
|
||||
case VFW_E_INVALID_FILE_FORMAT:
|
||||
return "VFW_E_INVALID_FILE_FORMAT";
|
||||
break;
|
||||
case VFW_E_NOT_FOUND:
|
||||
return "VFW_E_NOT_FOUND";
|
||||
break;
|
||||
case VFW_E_NOT_IN_GRAPH:
|
||||
return "VFW_E_NOT_IN_GRAPH";
|
||||
break;
|
||||
case VFW_E_UNKNOWN_FILE_TYPE:
|
||||
return "VFW_E_UNKNOWN_FILE_TYPE";
|
||||
break;
|
||||
case VFW_E_UNSUPPORTED_STREAM:
|
||||
return "VFW_E_UNSUPPORTED_STREAM";
|
||||
break;
|
||||
case VFW_E_CANNOT_CONNECT:
|
||||
return "VFW_E_CANNOT_CONNECT";
|
||||
break;
|
||||
case VFW_E_CANNOT_LOAD_SOURCE_FILTER:
|
||||
return "VFW_E_CANNOT_LOAD_SOURCE_FILTER";
|
||||
break;
|
||||
case VFW_S_PARTIAL_RENDER:
|
||||
return "VFW_S_PARTIAL_RENDER";
|
||||
break;
|
||||
case VFW_S_VIDEO_NOT_RENDERED:
|
||||
return "VFW_S_VIDEO_NOT_RENDERED";
|
||||
break;
|
||||
case VFW_S_AUDIO_NOT_RENDERED:
|
||||
return "VFW_S_AUDIO_NOT_RENDERED";
|
||||
break;
|
||||
case VFW_S_DUPLICATE_NAME:
|
||||
return "VFW_S_DUPLICATE_NAME";
|
||||
break;
|
||||
case VFW_S_MEDIA_TYPE_IGNORED:
|
||||
return "VFW_S_MEDIA_TYPE_IGNORED";
|
||||
break;
|
||||
case E_INVALIDARG:
|
||||
return "E_INVALIDARG";
|
||||
break;
|
||||
case DDERR_INCOMPATIBLEPRIMARY:
|
||||
return "DDERR_INCOMPATIBLEPRIMARY";
|
||||
break;
|
||||
case DDERR_INVALIDCAPS:
|
||||
return "DDERR_INVALIDCAPS";
|
||||
break;
|
||||
case DDERR_INVALIDOBJECT :
|
||||
return "DDERR_INVALIDOBJECT";
|
||||
break;
|
||||
case DDERR_INVALIDPIXELFORMAT:
|
||||
return "DDERR_INVALIDPIXELFORMAT";
|
||||
break;
|
||||
case DDERR_NOALPHAHW :
|
||||
return "DDERR_NOALPHAHW";
|
||||
break;
|
||||
case DDERR_NOCOOPERATIVELEVELSET :
|
||||
return "DDERR_NOCOOPERATIVELEVELSET";
|
||||
break;
|
||||
case DDERR_NODIRECTDRAWHW :
|
||||
return "DDERR_NODIRECTDRAWHW";
|
||||
break;
|
||||
case DDERR_NOEMULATION :
|
||||
return "DDERR_NOEMULATION";
|
||||
break;
|
||||
case VFW_E_BUFFERS_OUTSTANDING:
|
||||
return "VFW_E_BUFFERS_OUTSTANDING";
|
||||
break;
|
||||
case DDERR_NOEXCLUSIVEMODE :
|
||||
return "DDERR_NOEXCLUSIVEMODE ";
|
||||
break;
|
||||
case DDERR_NOFLIPHW:
|
||||
return "DDERR_NOFLIPHW";
|
||||
break;
|
||||
case DDERR_NOMIPMAPHW:
|
||||
return "DDERR_NOMIPMAPHW";
|
||||
break;
|
||||
case DDERR_NOOVERLAYHW :
|
||||
return "DDERR_NOOVERLAYHW ";
|
||||
break;
|
||||
case E_OUTOFMEMORY:
|
||||
return "E_OUTOFMEMORY";
|
||||
break;
|
||||
case VFW_E_NO_DISPLAY_PALETTE:
|
||||
return "VFW_E_NO_DISPLAY_PALETTE";
|
||||
break;
|
||||
case VFW_E_NO_COLOR_KEY_FOUND:
|
||||
return "VFW_E_NO_COLOR_KEY_FOUND";
|
||||
break;
|
||||
case VFW_E_PALETTE_SET:
|
||||
return "VFW_E_PALETTE_SET";
|
||||
break;
|
||||
case DDERR_NOZBUFFERHW :
|
||||
return "DDERR_NOZBUFFERHW ";
|
||||
break;
|
||||
case DDERR_OUTOFVIDEOMEMORY :
|
||||
return "DDERR_OUTOFVIDEOMEMORY";
|
||||
break;
|
||||
case DDERR_PRIMARYSURFACEALREADYEXISTS:
|
||||
return "DDERR_PRIMARYSURFACEALREADYEXISTS ";
|
||||
break;
|
||||
case DDERR_UNSUPPORTEDMODE:
|
||||
return "DDERR_UNSUPPORTEDMODE";
|
||||
break;
|
||||
case VFW_E_NO_ADVISE_SET:
|
||||
return "VFW_E_NO_ADVISE_SET";
|
||||
break;
|
||||
case S_OK:
|
||||
return "S_OK";
|
||||
break;
|
||||
case S_FALSE:
|
||||
return "S_FALSE";
|
||||
break;
|
||||
case VFW_S_CONNECTIONS_DEFERRED:
|
||||
return "VFW_S_CONNECTIONS_DEFERRED";
|
||||
break;
|
||||
case 0x80040154:
|
||||
return "Class not registered";
|
||||
break;
|
||||
case E_FAIL:
|
||||
return "E_FAIL";
|
||||
break;
|
||||
case VFW_E_DVD_OPERATION_INHIBITED:
|
||||
return "VFW_E_DVD_OPERATION_INHIBITED";
|
||||
break;
|
||||
case VFW_E_DVD_INVALIDDOMAIN:
|
||||
return "VFW_E_DVD_INVALIDDOMAIN";
|
||||
break;
|
||||
case E_NOTIMPL:
|
||||
return "E_NOTIMPL";
|
||||
break;
|
||||
case VFW_E_WRONG_STATE:
|
||||
return "VFW_E_WRONG_STATE";
|
||||
break;
|
||||
case E_PROP_SET_UNSUPPORTED:
|
||||
return "E_PROP_SET_UNSUPPORTED";
|
||||
break;
|
||||
case VFW_E_NO_PALETTE_AVAILABLE:
|
||||
return "VFW_E_NO_PALETTE_AVAILABLE";
|
||||
break;
|
||||
case E_UNEXPECTED:
|
||||
return "E_UNEXPECTED";
|
||||
break;
|
||||
case VFW_E_DVD_NO_BUTTON:
|
||||
return "VFW_E_DVD_NO_BUTTON";
|
||||
break;
|
||||
case VFW_E_DVD_GRAPHNOTREADY:
|
||||
return "VFW_E_DVD_GRAPHNOTREADY";
|
||||
break;
|
||||
case VFW_E_NOT_OVERLAY_CONNECTION:
|
||||
return "VFW_E_NOT_OVERLAY_CONNECTION";
|
||||
break;
|
||||
case VFW_E_DVD_RENDERFAIL:
|
||||
return "VFW_E_DVD_RENDERFAIL";
|
||||
break;
|
||||
case VFW_E_NOT_CONNECTED:
|
||||
return "VFW_E_NOT_CONNECTED";
|
||||
break;
|
||||
case E_NOINTERFACE:
|
||||
return "E_NOINTERFACE";
|
||||
break;
|
||||
case VFW_E_NO_COLOR_KEY_SET :
|
||||
return "VFW_E_NO_COLOR_KEY_SET ";
|
||||
break;
|
||||
case VFW_E_NO_INTERFACE:
|
||||
return "VFW_E_NO_INTERFACE";
|
||||
break;
|
||||
case 0x8004020c:
|
||||
return "VFW_E_BUFFER_NOTSET";
|
||||
break;
|
||||
case 0x80040225:
|
||||
return "VFW_E_NOT_PAUSED";
|
||||
case 0x80070002:
|
||||
return "System cannot find the file specified";
|
||||
break;
|
||||
case 0x80070003:
|
||||
return "System cannot find the path specified";
|
||||
break;
|
||||
case VFW_E_DVD_DECNOTENOUGH:
|
||||
return "VFW_E_DVD_DECNOTENOUGH";
|
||||
break;
|
||||
case VFW_E_ADVISE_ALREADY_SET:
|
||||
return "VFW_E_ADVISE_ALREADY_SET";
|
||||
break;
|
||||
case VFW_E_DVD_CMD_CANCELLED:
|
||||
return "VFW_E_DVD_CMD_CANCELLED";
|
||||
break;
|
||||
case VFW_E_DVD_MENU_DOES_NOT_EXIST:
|
||||
return "VFW_E_DVD_MENU_DOES_NOT_EXIST";
|
||||
break;
|
||||
case VFW_E_DVD_WRONG_SPEED:
|
||||
return "VFW_E_DVD_WRONG_SPEED";
|
||||
break;
|
||||
case VFW_S_DVD_NON_ONE_SEQUENTIAL:
|
||||
return "VFW_S_DVD_NON_ONE_SEQUENTIAL";
|
||||
break;
|
||||
case E_POINTER:
|
||||
return "E_POINTER";
|
||||
break;
|
||||
case VFW_E_DVD_NOT_IN_KARAOKE_MODE:
|
||||
return "VFW_E_DVD_NOT_IN_KARAOKE_MODE";
|
||||
break;
|
||||
case VFW_E_DVD_INVALID_DISC:
|
||||
return "VFW_E_DVD_INVALID_DISC";
|
||||
break;
|
||||
case VFW_E_DVD_STREAM_DISABLED:
|
||||
return "VFW_E_DVD_STREAM_DISABLED";
|
||||
break;
|
||||
case VFW_E_NOT_STOPPED:
|
||||
return "VFW_E_NOT_STOPPED";
|
||||
break;
|
||||
default:
|
||||
return "Unrecognized";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------------------
|
||||
| Function: MySleep
|
||||
| Purpose: if the application is in automated mode, then sleep func is turned off
|
||||
| Arguments: checks m_bAutomatedStatus to see if the func is in automation
|
||||
| Returns: true if automated, false otherwist
|
||||
\-----------------------------------------------------------------------------------------*/
|
||||
|
||||
bool MySleep(DWORD dwTime)
|
||||
{
|
||||
HANDLE hNeverHappensEvent;
|
||||
hNeverHappensEvent = CreateEvent(NULL, FALSE, FALSE, "EVENTTHATNEVERHAPPENS");
|
||||
WaitForSingleObject( hNeverHappensEvent, dwTime);
|
||||
return false;
|
||||
|
||||
} // end of checkHResult method
|
||||
|
||||
|
||||
void ReportDDrawSurfDesc( DDSURFACEDESC2 ddsd)
|
||||
{
|
||||
char szFlags[4096];
|
||||
char szMsg[4096];
|
||||
|
||||
OutputDebugString("*** Surface description ***\n");
|
||||
|
||||
SurfaceDescHelper( ddsd.dwFlags, szFlags);
|
||||
OutputDebugString(szFlags);
|
||||
|
||||
sprintf( szMsg, " dwWidth x dwHeight: %ld x %ld\n", ddsd.dwWidth, ddsd.dwHeight);
|
||||
OutputDebugString(szMsg);
|
||||
|
||||
sprintf( szMsg, " lPitch: %ld\n", ddsd.lPitch);
|
||||
OutputDebugString(szMsg);
|
||||
OutputDebugString(" (dwLinearSize)\n");
|
||||
|
||||
sprintf( szMsg, " dwBackBufferCount: %ld\n", ddsd.dwBackBufferCount);
|
||||
OutputDebugString(szMsg);
|
||||
|
||||
sprintf( szMsg, " dwMipMapCount: %ld\n", ddsd.dwMipMapCount);
|
||||
OutputDebugString(szMsg);
|
||||
OutputDebugString(" (dwRefreshRate)");
|
||||
|
||||
sprintf( szMsg, " dwAlphaBitDepth: %ld\n", (LONG)ddsd.dwAlphaBitDepth);
|
||||
OutputDebugString(szMsg);
|
||||
|
||||
sprintf( szMsg, " lpSurface: %x\n", (LONG_PTR)(ddsd.lpSurface));
|
||||
OutputDebugString(szMsg);
|
||||
|
||||
ReportPixelFormat( ddsd.ddpfPixelFormat );
|
||||
ReportDDSCAPS2( ddsd.ddsCaps );
|
||||
|
||||
sprintf( szMsg, " dwTextureStage: %ld\n", ddsd.dwTextureStage);
|
||||
OutputDebugString(szMsg);
|
||||
|
||||
OutputDebugString("***************************\n");
|
||||
}
|
||||
|
||||
void ReportDDSCAPS2( DDSCAPS2 ddscaps )
|
||||
{
|
||||
char sz[4096];
|
||||
|
||||
strcpy( sz, " DDSCAPS2::dwCaps: ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_3DDEVICE ) strcat( sz, "DDSCAPS_3DDEVICE, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_ALLOCONLOAD ) strcat( sz, "DDSCAPS_ALLOCONLOAD, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_ALPHA ) strcat( sz, "DDSCAPS_ALPHA, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_BACKBUFFER ) strcat( sz, "DDSCAPS_BACKBUFFER, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_COMPLEX ) strcat( sz, "DDSCAPS_COMPLEX, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_FLIP ) strcat( sz, "DDSCAPS_FLIP, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_FRONTBUFFER ) strcat( sz, "DDSCAPS_FRONTBUFFER, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_HWCODEC ) strcat( sz, "DDSCAPS_HWCODEC, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_LIVEVIDEO ) strcat( sz, "DDSCAPS_LIVEVIDEO, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_LOCALVIDMEM ) strcat( sz, "DDSCAPS_LOCALVIDMEM, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_MIPMAP ) strcat( sz, "DDSCAPS_MIPMAP, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_MODEX ) strcat( sz, "DDSCAPS_MODEX, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_NONLOCALVIDMEM ) strcat( sz, "DDSCAPS_NONLOCALVIDMEM, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_OFFSCREENPLAIN ) strcat( sz, "DDSCAPS_OFFSCREENPLAIN, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_OPTIMIZED ) strcat( sz, "DDSCAPS_OPTIMIZED, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_OVERLAY ) strcat( sz, "DDSCAPS_OVERLAY, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_OWNDC ) strcat( sz, "DDSCAPS_OWNDC, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_PALETTE ) strcat( sz, "DDSCAPS_PALETTE, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_PRIMARYSURFACE ) strcat( sz, "DDSCAPS_PRIMARYSURFACE, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_STANDARDVGAMODE ) strcat( sz, "DDSCAPS_STANDARDVGAMODE, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_SYSTEMMEMORY ) strcat( sz, "DDSCAPS_SYSTEMMEMORY, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_TEXTURE ) strcat( sz, "DDSCAPS_TEXTURE, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_VIDEOMEMORY ) strcat( sz, "DDSCAPS_VIDEOMEMORY, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_VIDEOPORT ) strcat( sz, "DDSCAPS_VIDEOPORT, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_VISIBLE ) strcat( sz, "DDSCAPS_VISIBLE, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_WRITEONLY ) strcat( sz, "DDSCAPS_WRITEONLY, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_ZBUFFER ) strcat( sz, "DDSCAPS_ZBUFFER, ");
|
||||
|
||||
strcat( sz, "\n");
|
||||
OutputDebugString(sz);
|
||||
strcpy( sz, " DDSCAPS2::dwCaps2: ");
|
||||
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_CUBEMAP ) strcat( sz, "DDSCAPS2_CUBEMAP, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_CUBEMAP_POSITIVEX ) strcat( sz, "DDSCAPS2_CUBEMAP_POSITIVEX, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_CUBEMAP_NEGATIVEX ) strcat( sz, "DDSCAPS2_CUBEMAP_NEGATIVEX, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_CUBEMAP_POSITIVEY ) strcat( sz, "DDSCAPS2_CUBEMAP_POSITIVEY, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_CUBEMAP_NEGATIVEY ) strcat( sz, "DDSCAPS2_CUBEMAP_NEGATIVEY, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_CUBEMAP_POSITIVEZ ) strcat( sz, "DDSCAPS2_CUBEMAP_POSITIVEZ, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ ) strcat( sz, "DDSCAPS2_CUBEMAP_NEGATIVEZ, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES ) strcat( sz, "DDSCAPS2_CUBEMAP_ALLFACES, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_D3DTEXTUREMANAGE ) strcat( sz, "DDSCAPS2_D3DTEXTUREMANAGE, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_DONOTPERSIST ) strcat( sz, "DDSCAPS2_DONOTPERSIST, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_HARDWAREDEINTERLACE ) strcat( sz, "DDSCAPS2_HARDWAREDEINTERLACE, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_HINTANTIALIASING ) strcat( sz, "DDSCAPS2_HINTANTIALIASING, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_HINTDYNAMIC ) strcat( sz, "DDSCAPS2_HINTDYNAMIC, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_HINTSTATIC ) strcat( sz, "DDSCAPS2_HINTSTATIC, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL ) strcat( sz, "DDSCAPS2_MIPMAPSUBLEVEL, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_OPAQUE ) strcat( sz, "DDSCAPS2_OPAQUE, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_STEREOSURFACELEFT ) strcat( sz, "DDSCAPS2_STEREOSURFACELEFT, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_TEXTUREMANAGE ) strcat( sz, "DDSCAPS2_TEXTUREMANAGE, ");
|
||||
|
||||
strcat( sz, "\n");
|
||||
OutputDebugString(sz);
|
||||
}
|
||||
|
||||
|
||||
void ReportPixelFormat( DDPIXELFORMAT ddpf)
|
||||
{
|
||||
char szFlags[4096];
|
||||
char szMsg[MAX_PATH];
|
||||
|
||||
PixelFormatHelper( ddpf.dwFlags, szFlags);
|
||||
|
||||
OutputDebugString(szFlags);
|
||||
|
||||
sprintf( szMsg, " dwFourCC: %ld\n", ddpf.dwFourCC);
|
||||
OutputDebugString(szMsg);
|
||||
|
||||
sprintf( szMsg, " dwRGBBitCount: %ld\n", ddpf.dwRGBBitCount);
|
||||
OutputDebugString(szMsg);
|
||||
OutputDebugString(" (dwYUVBitCount, dwZBufferBitDepth, dwAlphaBitDepth, dwLuminanceBitCount, dwBumpBitCount)\n");
|
||||
|
||||
sprintf( szMsg, " dwRBitMask: %ld\n", ddpf.dwRBitMask);
|
||||
OutputDebugString(szMsg);
|
||||
OutputDebugString(" (dwYBitMask, dwStencilBitDepth, dwLuminanceBitMask, dwBumpDuBitMask)\n");
|
||||
|
||||
sprintf( szMsg, " dwGBitMask: %ld\n", ddpf.dwGBitMask);
|
||||
OutputDebugString(szMsg);
|
||||
OutputDebugString(" (dwUBitMask, dwZBitMask, dwBumpDvBitMask)\n");
|
||||
|
||||
sprintf( szMsg, " dwBBitMask: %ld\n", ddpf.dwBBitMask);
|
||||
OutputDebugString(szMsg);
|
||||
OutputDebugString(" (dwVBitMask, dwStencilBitMask, dwBumpLuminanceBitMask)\n");
|
||||
|
||||
sprintf( szMsg, " dwRGBAlphaBitMask: %ld\n", ddpf.dwRGBAlphaBitMask);
|
||||
OutputDebugString(szMsg);
|
||||
OutputDebugString(" (dwYUVAlphaBitMask, dwLuminanceAlphaBitMask, dwRGBZBitMask, dwYUVZBitMask)\n");
|
||||
}
|
||||
|
||||
void SurfaceDescHelper( DWORD dwFlags, char * pszFlags )
|
||||
{
|
||||
if( !pszFlags )
|
||||
{
|
||||
return;
|
||||
}
|
||||
strcpy( pszFlags, " dwFlags: ");
|
||||
|
||||
if( dwFlags & DDSD_ALL )
|
||||
strcat( pszFlags, "DDSD_ALL\n");
|
||||
|
||||
if( dwFlags & DDSD_ALPHABITDEPTH )
|
||||
strcat( pszFlags, "DDSD_ALPHABITDEPTH\n");
|
||||
|
||||
if( dwFlags & DDSD_BACKBUFFERCOUNT )
|
||||
strcat( pszFlags, "DDSD_BACKBUFFERCOUNT\n");
|
||||
|
||||
if( dwFlags & DDSD_CAPS )
|
||||
strcat( pszFlags, "DDSD_CAPS\n");
|
||||
|
||||
if( dwFlags & DDSD_CKDESTBLT )
|
||||
strcat( pszFlags, "DDSD_CKDESTBLT\n");
|
||||
|
||||
if( dwFlags & DDSD_CKDESTOVERLAY )
|
||||
strcat( pszFlags, "DDSD_CKDESTOVERLAY\n");
|
||||
|
||||
if( dwFlags & DDSD_CKSRCBLT )
|
||||
strcat( pszFlags, "DDSD_CKSRCBLT\n");
|
||||
|
||||
if( dwFlags & DDSD_CKSRCOVERLAY )
|
||||
strcat( pszFlags, "DDSD_CKSRCOVERLAY\n");
|
||||
|
||||
if( dwFlags & DDSD_HEIGHT )
|
||||
strcat( pszFlags, "DDSD_HEIGHT\n");
|
||||
|
||||
if( dwFlags & DDSD_LINEARSIZE )
|
||||
strcat( pszFlags, "DDSD_LINEARSIZE\n");
|
||||
|
||||
if( dwFlags & DDSD_LPSURFACE )
|
||||
strcat( pszFlags, "DDSD_LPSURFACE\n");
|
||||
|
||||
if( dwFlags & DDSD_MIPMAPCOUNT )
|
||||
strcat( pszFlags, "DDSD_MIPMAPCOUNT\n");
|
||||
|
||||
if( dwFlags & DDSD_PITCH )
|
||||
strcat( pszFlags, "DDSD_PITCH\n");
|
||||
|
||||
if( dwFlags & DDSD_PIXELFORMAT )
|
||||
strcat( pszFlags, "DDSD_PIXELFORMAT\n");
|
||||
|
||||
if( dwFlags & DDSD_REFRESHRATE )
|
||||
strcat( pszFlags, "DDSD_REFRESHRATE\n");
|
||||
|
||||
if( dwFlags & DDSD_TEXTURESTAGE )
|
||||
strcat( pszFlags, "DDSD_TEXTURESTAGE\n");
|
||||
|
||||
if( dwFlags & DDSD_WIDTH )
|
||||
strcat( pszFlags, "DDSD_WIDTH\n");
|
||||
|
||||
strcat(pszFlags, "\n");
|
||||
}
|
||||
|
||||
|
||||
void PixelFormatHelper( DWORD dwFlags, char * pszFlags)
|
||||
{
|
||||
if( !pszFlags )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy( pszFlags, " dwFlags: ");
|
||||
|
||||
if( dwFlags & DDPF_ALPHA )
|
||||
strcat( pszFlags, "DDPF_ALPHA, ");
|
||||
|
||||
if( dwFlags & DDPF_ALPHAPIXELS )
|
||||
strcat( pszFlags, "DDPF_ALPHAPIXELS, ");
|
||||
|
||||
if( dwFlags & DDPF_ALPHAPREMULT )
|
||||
strcat( pszFlags, "DDPF_ALPHAPREMULT, ");
|
||||
|
||||
if( dwFlags & DDPF_BUMPLUMINANCE )
|
||||
strcat( pszFlags, "DDPF_BUMPLUMINANCE, ");
|
||||
|
||||
if( dwFlags & DDPF_BUMPDUDV )
|
||||
strcat( pszFlags, "DDPF_BUMPDUDV, ");
|
||||
|
||||
if( dwFlags & DDPF_COMPRESSED )
|
||||
strcat( pszFlags, "DDPF_COMPRESSED, ");
|
||||
|
||||
if( dwFlags & DDPF_FOURCC )
|
||||
strcat( pszFlags, "DDPF_FOURCC, ");
|
||||
|
||||
if( dwFlags & DDPF_LUMINANCE )
|
||||
strcat( pszFlags, "DDPF_LUMINANCE, ");
|
||||
|
||||
if( dwFlags & DDPF_PALETTEINDEXED1 )
|
||||
strcat( pszFlags, "DDPF_PALETTEINDEXED1, ");
|
||||
|
||||
if( dwFlags & DDPF_PALETTEINDEXED2 )
|
||||
strcat( pszFlags, "DDPF_PALETTEINDEXED2, ");
|
||||
|
||||
if( dwFlags & DDPF_PALETTEINDEXED4 )
|
||||
strcat( pszFlags, "DDPF_PALETTEINDEXED4, ");
|
||||
|
||||
if( dwFlags & DDPF_PALETTEINDEXED8 )
|
||||
strcat( pszFlags, "DDPF_PALETTEINDEXED8, ");
|
||||
|
||||
if( dwFlags & DDPF_PALETTEINDEXEDTO8 )
|
||||
strcat( pszFlags, "DDPF_PALETTEINDEXEDTO8, ");
|
||||
|
||||
if( dwFlags & DDPF_RGB )
|
||||
strcat( pszFlags, "DDPF_RGB, ");
|
||||
|
||||
if( dwFlags & DDPF_RGBTOYUV )
|
||||
strcat( pszFlags, "DDPF_RGBTOYUV, ");
|
||||
|
||||
if( dwFlags & DDPF_STENCILBUFFER )
|
||||
strcat( pszFlags, "DDPF_STENCILBUFFER, ");
|
||||
|
||||
if( dwFlags & DDPF_YUV )
|
||||
strcat( pszFlags, "DDPF_YUV, ");
|
||||
|
||||
if( dwFlags & DDPF_ZBUFFER )
|
||||
strcat( pszFlags, "DDPF_ZBUFFER, ");
|
||||
|
||||
if( dwFlags & DDPF_ZPIXELS )
|
||||
strcat( pszFlags, "DDPF_ZPIXELS, ");
|
||||
|
||||
strcat( pszFlags, "\n");
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VerifyVMR
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL VerifyVMR(void)
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
CoInitialize(NULL);
|
||||
|
||||
// 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();
|
||||
CoUninitialize();
|
||||
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);
|
||||
|
||||
CoUninitialize();
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// File: Utils.h
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Prototypes for external (global) utilities
|
||||
// specific for VMRXcl app
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// global headers
|
||||
#if !defined(UTILS_H)
|
||||
#define UTILS_H
|
||||
|
||||
// helper function prototypes
|
||||
|
||||
DWORD MyMessage(char *sQuestion, char *sTitle);
|
||||
const char * hresultNameLookup(HRESULT hres);
|
||||
bool MySleep(DWORD dwTime = 2500);
|
||||
|
||||
void ReportPixelFormat( DDPIXELFORMAT ddpf);
|
||||
void ReportDDSCAPS2( DDSCAPS2 ddscaps );
|
||||
void ReportDDrawSurfDesc( DDSURFACEDESC2 ddsd);
|
||||
void PixelFormatHelper( DWORD dwFlags, char * pszFlags);
|
||||
void SurfaceDescHelper( DWORD dwFlags, char * pszFlags );
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SceneSettings
|
||||
//
|
||||
// This structure defines demonstration settings
|
||||
//----------------------------------------------------------------------------
|
||||
struct SceneSettings
|
||||
{
|
||||
bool bRotateZ; // rotate around Z axis if true
|
||||
int nGradZ; // angle of rotation around Z axis, in grades
|
||||
// this is a 'time' variable for Z-rotation effect
|
||||
bool bRotateY; // rotate around Y axis if true
|
||||
int nGradY; // angle of rotation around Y axis, in grades
|
||||
// this is a 'time' variable for Y-rotation effect
|
||||
bool bShowStatistics; // show FPS in the upper right corner if true
|
||||
bool bShowTwist; // show "twist" effect if true; THIS STATE OVERRIDES bRotateZ AND bRotateY
|
||||
int nDy; // vertical offset for the twist effect
|
||||
// this is a 'time' variable for "twist" effect
|
||||
bool bShowHelp; // show text help hints if true (it is activated by right click on the control)
|
||||
int nXHelp; // coordinates for text help hint
|
||||
int nYHelp;
|
||||
TCHAR achHelp[MAX_PATH]; // help hint text
|
||||
TCHAR achFPS[MAX_PATH]; // string representation of FramesPerSecons
|
||||
// (when bShowStatistics is on)
|
||||
|
||||
SceneSettings() // constructor: no effects by default
|
||||
{
|
||||
bRotateZ = false;
|
||||
nGradZ = 0;
|
||||
bRotateY = false;
|
||||
nGradY = 0;
|
||||
bShowStatistics = false;
|
||||
bShowTwist = false;
|
||||
nDy = 0;
|
||||
bShowHelp = 0;
|
||||
nXHelp = 0;
|
||||
nYHelp = 0;
|
||||
lstrcpy(achHelp, TEXT(""));
|
||||
};
|
||||
|
||||
~SceneSettings()
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,196 @@
|
||||
# Microsoft Developer Studio Project File - Name="VMRXcl" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Application" 0x0101
|
||||
|
||||
CFG=VMRXcl - 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 "VMRXcl.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 "VMRXcl.mak" CFG="VMRXcl - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "VMRXcl - Win32 Release" (based on "Win32 (x86) Application")
|
||||
!MESSAGE "VMRXcl - 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)" == "VMRXcl - 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 /O2 /I "..\..\BaseClasses" /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 d3dx.lib ..\..\..\DirectShow\baseclasses\release\strmbase.lib strmiids.lib comctl32.lib winmm.lib gdi32.lib ddraw.lib comdlg32.lib /nologo /subsystem:windows /pdb:none /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "VMRXcl - 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 /ZI /Od /I "..\..\..\DirectShow\BaseClasses" /D "DEBUG" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D WINVER=0x501 /YX"project.h" /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 d3dx.lib ..\..\..\DirectShow\baseclasses\debug\strmbasd.lib strmiids.lib comctl32.lib winmm.lib gdi32.lib ddraw.lib comdlg32.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcmtd" /pdbtype:sept
|
||||
# SUBTRACT LINK32 /map
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "VMRXcl - Win32 Release"
|
||||
# Name "VMRXcl - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# 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=.\d3dfont.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\d3dtextr.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\d3dutil.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DDrawSupport.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ReadMe.txt
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Utils.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=.\d3dfont.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\d3dtextr.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\d3dutil.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DDrawSupport.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=.\Utils.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=.\VMRXcl.ico
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\VMRXcl.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\VMRxclMenu.bmp
|
||||
# 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: "VMRXCL"=.\VMRXCL.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,173 @@
|
||||
//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
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Accelerator
|
||||
//
|
||||
|
||||
IDR_ACCELERATOR ACCELERATORS DISCARDABLE
|
||||
BEGIN
|
||||
"S", IDM_MOVIE_STOP, VIRTKEY, CONTROL, NOINVERT
|
||||
"P", IDM_MOVIE_PLAY, 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
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Bitmap
|
||||
//
|
||||
|
||||
IDB_MENU BITMAP DISCARDABLE "VMRxclMenu.bmp"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_ICON1 ICON DISCARDABLE "VMRXcl.ico"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 8,1,0,0
|
||||
PRODUCTVERSION 8,1,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "This sample requires Windows XP or greater.\0"
|
||||
VALUE "CompanyName", "Microsoft\0"
|
||||
VALUE "FileDescription", "VMR Exclusive Mode Application\0"
|
||||
VALUE "FileVersion", "8.10\0"
|
||||
VALUE "InternalName", "VMR XCL\0"
|
||||
VALUE "LegalCopyright", "Copyright (c) 2000-2001 Microsoft Corporation\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "VMRXCL.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_PAUSE "Pause"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDM_FULL_SCREEN "Full screen playback"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
STR_FILE_OPEN "Open a new movie to play"
|
||||
STR_FILE_CLOSE "Close the movie"
|
||||
STR_FILE_EXIT "Quit VMR Exclusive Mode Player"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
STR_FILE_FILTER "All Movies#*.mpg;*.avi;*.dat;*.mov#Mpeg Files (*.mpg)#*.mpg#Video CD Files (*.dat)#*.dat#QuickTime Files (*.mov)#*.mov#All Files (*.*)#*.*#"
|
||||
STR_APP_TITLE "VMR Exclusive Mode Player"
|
||||
STR_APP_TITLE_LOADED "VMR Exclusive Mode Player - %s"
|
||||
END
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 84 KiB |
@@ -0,0 +1,811 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// File: app.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Main module for customized video player in exclusive mode
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#include "project.h"
|
||||
#include <atlbase.h>
|
||||
#include <atlconv.cpp>
|
||||
#include <mmreg.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Global variables that are initialized at run time and then stay constant.
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
HINSTANCE g_hInst;
|
||||
HICON hIconVideoCd;
|
||||
HWND hwndApp;
|
||||
HWND g_hwndToolbar;
|
||||
CMpegMovie *pMpegMovie;
|
||||
BOOL g_bPlay = FALSE;
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** True Globals - these may change during execution of the program.
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
TCHAR g_achFileName[MAX_PATH];
|
||||
DWORD g_State = VCD_NO_CD;
|
||||
BOOL g_bFullScreen = FALSE;
|
||||
|
||||
|
||||
struct SceneSettings g_ss;
|
||||
|
||||
const LONG g_Style = WS_POPUP | WS_CAPTION | WS_SYSMENU;
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Constants
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
const TCHAR szClassName[] = TEXT("VMRXCLPlayer_CLASS");
|
||||
const TCHAR g_szNULL[] = TEXT("\0");
|
||||
const TCHAR g_szEmpty[] = TEXT("");
|
||||
|
||||
typedef enum VMRXcl_menu
|
||||
{
|
||||
evxShowInfo = 0x0,
|
||||
evxMoviePause,
|
||||
evxMoviePlay,
|
||||
evxMovieRotateZ,
|
||||
evxMovieRotateY,
|
||||
evxMovieTwist,
|
||||
evxMovieOption4,
|
||||
evxExit,
|
||||
|
||||
} VMRXcl_menu;
|
||||
|
||||
|
||||
void SetFullScreenMode(BOOL bMode);
|
||||
BOOL IsFullScreenMode();
|
||||
extern BOOL VerifyVMR(void);
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* WinMain
|
||||
*
|
||||
*
|
||||
* Windows recognizes this function by name as the initial entry point
|
||||
* for the program. This function calls the application initialization
|
||||
* routine, if no other instance of the program is running, and always
|
||||
* calls the instance initialization routine. It then executes a message
|
||||
* retrieval and dispatch loop that is the top-level control structure
|
||||
* for the remainder of execution. The loop is terminated when a WM_QUIT
|
||||
* message is received, at which time this function exits the application
|
||||
* instance by returning the value passed by PostQuitMessage().
|
||||
*
|
||||
* If this function must abort before entering the message loop, it
|
||||
* returns the conventional value NULL.
|
||||
*
|
||||
\**************************************************************************/
|
||||
int PASCAL
|
||||
WinMain(
|
||||
HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLineOld,
|
||||
int nCmdShow
|
||||
)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
int iRet=0;
|
||||
LPTSTR lpCmdLine = A2T(lpCmdLineOld);
|
||||
|
||||
HRESULT hres = CoInitialize(NULL);
|
||||
if (hres == S_FALSE) {
|
||||
CoUninitialize();
|
||||
}
|
||||
|
||||
if ( !hPrevInstance ) {
|
||||
if ( !InitApplication( hInstance ) ) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Perform initializations that apply to a specific instance
|
||||
*/
|
||||
if ( !InitInstance( hInstance, nCmdShow ) ) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Verify that the Video Mixing Renderer is present (requires Windows XP).
|
||||
// Otherwise, this sample cannot continue.
|
||||
if (!VerifyVMR())
|
||||
return FALSE;
|
||||
|
||||
/* Look for options */
|
||||
while (lpCmdLine && (*lpCmdLine == '-' || *lpCmdLine == '/')) {
|
||||
if (lpCmdLine[1] == 'P') {
|
||||
g_bPlay = TRUE;
|
||||
lpCmdLine += 2;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
while (lpCmdLine[0] == ' ') {
|
||||
lpCmdLine++;
|
||||
}
|
||||
}
|
||||
|
||||
SetFullScreenMode(g_bPlay);
|
||||
|
||||
// If the user selects a file, open it and start playing.
|
||||
// Otherwise, just exit the app.
|
||||
if (ProcessOpen(lpCmdLine, TRUE) == TRUE)
|
||||
{
|
||||
/*
|
||||
** Acquire and dispatch messages until a WM_QUIT message is received.
|
||||
*/
|
||||
iRet = DoMainLoop();
|
||||
}
|
||||
|
||||
QzUninitialize();
|
||||
return iRet;
|
||||
}
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* DoMainLoop
|
||||
*
|
||||
* Process the main message loop
|
||||
*
|
||||
\**************************************************************************/
|
||||
int
|
||||
DoMainLoop(
|
||||
void
|
||||
)
|
||||
{
|
||||
MSG msg;
|
||||
HANDLE ahObjects[8];;
|
||||
int cObjects;
|
||||
HACCEL haccel = LoadAccelerators(g_hInst, MAKEINTRESOURCE(IDR_ACCELERATOR));
|
||||
|
||||
//
|
||||
// message loop lasts until we get a WM_QUIT message
|
||||
// upon which we shall return from the function
|
||||
//
|
||||
for ( ;; ) {
|
||||
|
||||
if (pMpegMovie != NULL) {
|
||||
cObjects = 1;
|
||||
ahObjects[0] = pMpegMovie->GetMovieEventHandle();
|
||||
}
|
||||
else {
|
||||
ahObjects[0] = NULL;
|
||||
cObjects = 0;
|
||||
}
|
||||
|
||||
if (ahObjects[0] == NULL) {
|
||||
WaitMessage();
|
||||
}
|
||||
else {
|
||||
|
||||
//
|
||||
// wait for any message sent or posted to this queue
|
||||
// or for a graph notification
|
||||
//
|
||||
DWORD result;
|
||||
|
||||
result = MsgWaitForMultipleObjects(cObjects, ahObjects, FALSE,
|
||||
INFINITE, QS_ALLINPUT);
|
||||
|
||||
if (result != (WAIT_OBJECT_0 + cObjects)) {
|
||||
|
||||
VideoCd_OnGraphNotify(result - WAIT_OBJECT_0);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// When here, we either have a message or no event handle
|
||||
// has been created yet.
|
||||
//
|
||||
// read all of the messages in this next loop
|
||||
// removing each message as we read it
|
||||
//
|
||||
|
||||
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
|
||||
switch( msg.message )
|
||||
{
|
||||
case WM_QUIT:
|
||||
return (int) msg.wParam;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!TranslateAccelerator(hwndApp, haccel, &msg)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // DoMainLoop
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* InitApplication(HANDLE)
|
||||
*
|
||||
* This function is called at initialization time only if no other
|
||||
* instances of the application are running. This function performs
|
||||
* initialization tasks that can be done once for any number of running
|
||||
* instances.
|
||||
*
|
||||
* In this case, we initialize a window class by filling out a data
|
||||
* structure of type WNDCLASS and calling the Windows RegisterClass()
|
||||
* function. Since all instances of this application use the same window
|
||||
* class, we only need to do this when the first instance is initialized.
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
InitApplication(
|
||||
HINSTANCE hInstance
|
||||
)
|
||||
{
|
||||
WNDCLASS wc;
|
||||
|
||||
/*
|
||||
** Fill in window class structure with parameters that describe the
|
||||
** main window.
|
||||
*/
|
||||
hIconVideoCd = LoadIcon( hInstance, MAKEINTRESOURCE(IDR_VIDEOCD_ICON) );
|
||||
|
||||
wc.style = CS_VREDRAW | CS_HREDRAW;
|
||||
wc.lpfnWndProc = VideoCdWndProc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = hInstance;
|
||||
wc.hIcon = hIconVideoCd;
|
||||
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
|
||||
wc.hbrBackground = (HBRUSH)NULL; // (COLOR_BTNFACE + 1);
|
||||
wc.lpszMenuName = MAKEINTRESOURCE( IDR_MAIN_MENU);
|
||||
wc.lpszClassName = szClassName;
|
||||
|
||||
/*
|
||||
** Register the window class and return success/failure code.
|
||||
*/
|
||||
return RegisterClass( &wc );
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* InitInstance
|
||||
*
|
||||
*
|
||||
* This function is called at initialization time for every instance of
|
||||
* this application. This function performs initialization tasks that
|
||||
* cannot be shared by multiple instances.
|
||||
*
|
||||
* In this case, we save the instance handle in a static variable and
|
||||
* create and display the main program window.
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
InitInstance(
|
||||
HINSTANCE hInstance,
|
||||
int nCmdShow
|
||||
)
|
||||
{
|
||||
HWND hwnd;
|
||||
|
||||
/*
|
||||
** Save the instance handle in static variable, which will be used in
|
||||
** many subsequence calls from this application to Windows.
|
||||
*/
|
||||
g_hInst = hInstance;
|
||||
|
||||
/*
|
||||
** Create a hidden window for this application instance.
|
||||
*/
|
||||
hwnd = CreateWindow( szClassName, IdStr(STR_APP_TITLE), g_Style,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
NULL, NULL, hInstance, NULL );
|
||||
|
||||
/*
|
||||
** If window could not be created, return "failure"
|
||||
*/
|
||||
if ( NULL == hwnd ) {
|
||||
return FALSE;
|
||||
}
|
||||
hwndApp = hwnd;
|
||||
|
||||
|
||||
/*
|
||||
** Keep the main window invisible, since all we need to do is
|
||||
* display a FileOpen dialog box.
|
||||
*/
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* GetMoviePosition
|
||||
*
|
||||
* Place the movie in the centre of the client window. We do not stretch the
|
||||
* the movie yet !
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
GetMoviePosition(
|
||||
HWND hwnd,
|
||||
long* xPos,
|
||||
long* yPos,
|
||||
long* pcx,
|
||||
long* pcy
|
||||
)
|
||||
{
|
||||
RECT rc = {0, 0, 400, 300};
|
||||
|
||||
GetClientRect(hwnd, &rc);
|
||||
|
||||
*xPos = rc.left;
|
||||
*yPos = rc.top;
|
||||
|
||||
*pcx = rc.right - rc.left;
|
||||
*pcy = rc.bottom - rc.top;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* RepositionMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
RepositionMovie(HWND hwnd)
|
||||
{
|
||||
if (pMpegMovie) {
|
||||
|
||||
IVMRWindowlessControl* lpDefWC = pMpegMovie->GetWLC();
|
||||
if (lpDefWC) {
|
||||
LONG w, h;
|
||||
|
||||
lpDefWC->GetNativeVideoSize(&w, &h, NULL, NULL);
|
||||
|
||||
RECT rc = {(640-w)/2, (480-h)/2, (640+w)/2, (480+h)/2};
|
||||
|
||||
lpDefWC->SetVideoPosition(NULL, &rc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VideoCd_OnMove
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnMove(
|
||||
HWND hwnd,
|
||||
int x,
|
||||
int y
|
||||
)
|
||||
{
|
||||
if (pMpegMovie) {
|
||||
if (pMpegMovie->GetStateMovie() != State_Running) {
|
||||
RepositionMovie(hwnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VideoCdWndProc
|
||||
*
|
||||
\**************************************************************************/
|
||||
LRESULT CALLBACK
|
||||
VideoCdWndProc(
|
||||
HWND hwnd,
|
||||
UINT message,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
)
|
||||
{
|
||||
switch ( message ) {
|
||||
|
||||
HANDLE_MSG( hwnd, WM_CREATE, VideoCd_OnCreate );
|
||||
HANDLE_MSG( hwnd, WM_PAINT, VideoCd_OnPaint );
|
||||
HANDLE_MSG( hwnd, WM_CLOSE, VideoCd_OnClose );
|
||||
HANDLE_MSG( hwnd, WM_DESTROY, VideoCd_OnDestroy );
|
||||
HANDLE_MSG( hwnd, WM_SIZE, VideoCd_OnSize );
|
||||
HANDLE_MSG( hwnd, WM_KEYUP, VideoCd_OnKeyUp);
|
||||
HANDLE_MSG( hwnd, WM_MOVE, VideoCd_OnMove );
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
{
|
||||
VideoCd_OnClick(hwnd, wParam, lParam);
|
||||
}
|
||||
break;
|
||||
case WM_RBUTTONUP:
|
||||
{
|
||||
VideoCd_OnClickHold(hwnd, wParam, lParam);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return DefWindowProc(hwnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VideoCd_OnCreate
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VideoCd_OnCreate(
|
||||
HWND hwnd,
|
||||
LPCREATESTRUCT lpCreateStruct
|
||||
)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VideoCd_OnKeyUp
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnKeyUp(
|
||||
HWND hwnd,
|
||||
UINT vk,
|
||||
BOOL fDown,
|
||||
int cRepeat,
|
||||
UINT flags
|
||||
)
|
||||
{
|
||||
// Catch escape sequences to stop fullscreen mode
|
||||
if (vk == VK_ESCAPE) {
|
||||
|
||||
if (pMpegMovie) {
|
||||
PostMessage(hwnd, WM_CLOSE, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VideoCd_OnClick
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnClick(
|
||||
HWND hwnd,
|
||||
WPARAM pParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
int xPos;
|
||||
int yPos;
|
||||
int nMenuItem = -1;
|
||||
|
||||
xPos = GET_X_LPARAM(lParam);
|
||||
yPos = GET_Y_LPARAM(lParam);
|
||||
|
||||
g_ss.bShowHelp = false;
|
||||
g_ss.nXHelp = 0;
|
||||
g_ss.nYHelp = 0;
|
||||
lstrcpy( g_ss.achHelp, TEXT(""));
|
||||
|
||||
if( xPos >= 3 && xPos <= 55 )
|
||||
{
|
||||
nMenuItem = (yPos -6)/53;
|
||||
if( nMenuItem == 8 )
|
||||
{
|
||||
nMenuItem = -1;
|
||||
}
|
||||
}
|
||||
|
||||
switch( nMenuItem)
|
||||
{
|
||||
case evxMovieRotateZ:
|
||||
g_ss.bShowTwist = false;
|
||||
g_ss.nDy = 0;
|
||||
g_ss.bRotateZ = !(g_ss.bRotateZ);
|
||||
break;
|
||||
case evxMovieRotateY:
|
||||
g_ss.bShowTwist = false;
|
||||
g_ss.nDy = 0;
|
||||
g_ss.bRotateY = !(g_ss.bRotateY);
|
||||
break;
|
||||
case evxMovieTwist:
|
||||
g_ss.bShowTwist = !(g_ss.bShowTwist);
|
||||
break;
|
||||
case evxExit:
|
||||
if (pMpegMovie)
|
||||
{
|
||||
PostMessage(hwnd, WM_CLOSE, 0, 0);
|
||||
}
|
||||
break;
|
||||
case evxMoviePause:
|
||||
if( pMpegMovie )
|
||||
{
|
||||
pMpegMovie->PauseMovie();
|
||||
}
|
||||
break;
|
||||
case evxMoviePlay:
|
||||
if( pMpegMovie )
|
||||
{
|
||||
pMpegMovie->PlayMovie();
|
||||
}
|
||||
break;
|
||||
case evxShowInfo:
|
||||
g_ss.bShowStatistics = !(g_ss.bShowStatistics);
|
||||
break;
|
||||
}// switch
|
||||
}
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VideoCd_OnClickHold
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnClickHold(
|
||||
HWND hwnd,
|
||||
WPARAM pParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
int xPos;
|
||||
int yPos;
|
||||
int nMenuItem = -1;
|
||||
|
||||
OutputDebugString("*** Event is captured\n");
|
||||
|
||||
xPos = GET_X_LPARAM(lParam);
|
||||
yPos = GET_Y_LPARAM(lParam);
|
||||
|
||||
g_ss.bShowHelp = false;
|
||||
g_ss.nXHelp = 0;
|
||||
g_ss.nYHelp = 0;
|
||||
lstrcpy( g_ss.achHelp, TEXT(""));
|
||||
|
||||
if( xPos >= 3 && xPos <= 55 )
|
||||
{
|
||||
nMenuItem = (yPos -6)/53;
|
||||
g_ss.bShowHelp = true;
|
||||
if( nMenuItem == 8 )
|
||||
{
|
||||
nMenuItem = -1;
|
||||
g_ss.bShowHelp = false;
|
||||
}
|
||||
|
||||
}
|
||||
if( g_ss.bShowHelp )
|
||||
{
|
||||
OutputDebugString("*** WILL show help\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputDebugString("*** WILL NOT show help\n");
|
||||
}
|
||||
|
||||
switch( nMenuItem)
|
||||
{
|
||||
case evxMovieRotateZ:
|
||||
g_ss.nXHelp = 70;
|
||||
g_ss.nYHelp = yPos;
|
||||
lstrcpy( g_ss.achHelp, TEXT("Rotate around Z axis "));
|
||||
break;
|
||||
case evxMovieRotateY:
|
||||
g_ss.nXHelp = 70;
|
||||
g_ss.nYHelp = yPos;
|
||||
lstrcpy( g_ss.achHelp, TEXT("Rotate around Y axis "));
|
||||
break;
|
||||
case evxMovieTwist:
|
||||
g_ss.nXHelp = 70;
|
||||
g_ss.nYHelp = yPos;
|
||||
lstrcpy( g_ss.achHelp, TEXT("Non-linear transformation "));
|
||||
break;
|
||||
case evxExit:
|
||||
g_ss.nXHelp = 70;
|
||||
g_ss.nYHelp = yPos;
|
||||
lstrcpy( g_ss.achHelp, TEXT("Exit application "));
|
||||
break;
|
||||
case evxMoviePause:
|
||||
g_ss.nXHelp = 70;
|
||||
g_ss.nYHelp = yPos;
|
||||
lstrcpy( g_ss.achHelp, TEXT("Pause "));
|
||||
break;
|
||||
case evxMoviePlay:
|
||||
g_ss.nXHelp = 70;
|
||||
g_ss.nYHelp = yPos;
|
||||
lstrcpy( g_ss.achHelp, TEXT("Play "));
|
||||
break;
|
||||
case evxShowInfo:
|
||||
g_ss.nXHelp = 70;
|
||||
g_ss.nYHelp = yPos;
|
||||
lstrcpy( g_ss.achHelp, TEXT("Show statistics "));
|
||||
break;
|
||||
}// switch
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VideoCd_OnPaint
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnPaint(
|
||||
HWND hwnd
|
||||
)
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
HDC hdc;
|
||||
RECT rc2;
|
||||
|
||||
/*
|
||||
** Draw a frame around the movie playback area.
|
||||
*/
|
||||
hdc = BeginPaint( hwnd, &ps );
|
||||
GetClientRect(hwnd, &rc2);
|
||||
FillRect(hdc, &rc2, (HBRUSH)(COLOR_BTNFACE + 1));
|
||||
EndPaint( hwnd, &ps );
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VideoCd_OnDestroy
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnDestroy(
|
||||
HWND hwnd
|
||||
)
|
||||
{
|
||||
PostQuitMessage( 0 );
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VideoCd_OnClose
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnClose(
|
||||
HWND hwnd
|
||||
)
|
||||
{
|
||||
if (pMpegMovie) {
|
||||
pMpegMovie->StopMovie();
|
||||
pMpegMovie->CloseMovie();
|
||||
|
||||
delete pMpegMovie;
|
||||
pMpegMovie = NULL;
|
||||
}
|
||||
|
||||
DestroyWindow( hwnd );
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VideoCd_OnSize
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnSize(
|
||||
HWND hwnd,
|
||||
UINT state,
|
||||
int dx,
|
||||
int dy
|
||||
)
|
||||
{
|
||||
RepositionMovie(hwnd);
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VideoCd_OnGraphNotify
|
||||
*
|
||||
* This is where we get any notifications from the filter graph.
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnGraphNotify(
|
||||
int stream
|
||||
)
|
||||
{
|
||||
long lEventCode;
|
||||
|
||||
lEventCode = pMpegMovie->GetMovieEventCode();
|
||||
|
||||
switch (lEventCode) {
|
||||
case EC_FULLSCREEN_LOST:
|
||||
break;
|
||||
|
||||
case EC_COMPLETE:
|
||||
// when movie is complete, reposition it to the start position
|
||||
pMpegMovie->SeekToPosition(0L,FALSE);
|
||||
break;
|
||||
case EC_USERABORT:
|
||||
case EC_ERRORABORT:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* IdStr
|
||||
*
|
||||
* Loads the given string resource ID into the passed storage.
|
||||
*
|
||||
\**************************************************************************/
|
||||
LPCTSTR
|
||||
IdStr(
|
||||
int idResource
|
||||
)
|
||||
{
|
||||
static TCHAR chBuffer[ STR_MAX_STRING_LEN ];
|
||||
|
||||
if (LoadString(g_hInst, idResource, chBuffer, STR_MAX_STRING_LEN) == 0) {
|
||||
return g_szEmpty;
|
||||
}
|
||||
|
||||
return chBuffer;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* SetFullScreenMode
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
SetFullScreenMode(BOOL bMode)
|
||||
{
|
||||
g_bFullScreen = bMode;
|
||||
|
||||
static HMENU hMenu;
|
||||
static LONG lStyle;
|
||||
static int xs, ys, cxs, cys;
|
||||
|
||||
HDC hdcScreen = GetDC(NULL);
|
||||
int cx = GetDeviceCaps(hdcScreen,HORZRES);
|
||||
int cy = GetDeviceCaps(hdcScreen,VERTRES);
|
||||
ReleaseDC(NULL, hdcScreen);
|
||||
|
||||
if (bMode) {
|
||||
|
||||
hMenu = GetMenu(hwndApp);
|
||||
lStyle = GetWindowStyle(hwndApp);
|
||||
|
||||
WINDOWPLACEMENT wp;
|
||||
GetWindowPlacement(hwndApp, &wp);
|
||||
xs = wp.rcNormalPosition.left;
|
||||
ys = wp.rcNormalPosition.top;
|
||||
cxs = wp.rcNormalPosition.right - xs;
|
||||
cys = wp.rcNormalPosition.bottom - ys;
|
||||
ShowWindow(g_hwndToolbar, SW_HIDE);
|
||||
SetMenu(hwndApp, NULL);
|
||||
SetWindowLong(hwndApp, GWL_STYLE, WS_POPUP|WS_SYSMENU|WS_VISIBLE);
|
||||
SetWindowPos(hwndApp, HWND_TOP, 0, 0, cx, cy, SWP_NOACTIVATE);
|
||||
ShowCursor(FALSE);
|
||||
|
||||
}
|
||||
else {
|
||||
ShowCursor(TRUE);
|
||||
ShowWindow(g_hwndToolbar, SW_SHOW);
|
||||
SetMenu(hwndApp, hMenu);
|
||||
SetWindowLong(hwndApp, GWL_STYLE, lStyle);
|
||||
SetWindowPos(hwndApp, HWND_TOP, xs, ys, cxs, cys, SWP_NOACTIVATE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* IsFullScreenMode()
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
IsFullScreenMode()
|
||||
{
|
||||
return g_bFullScreen;
|
||||
}
|
||||
@@ -0,0 +1,342 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// File: app.h
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Header file for customized video player application
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Functions prototypes
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
DoMainLoop(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
InitApplication(
|
||||
HINSTANCE hInstance
|
||||
);
|
||||
|
||||
BOOL
|
||||
InitInstance(
|
||||
HINSTANCE hInstance,
|
||||
int nCmdShow
|
||||
);
|
||||
|
||||
|
||||
void
|
||||
UpdateMpegMovieRect(
|
||||
void
|
||||
);
|
||||
|
||||
void
|
||||
GetAdjustedClientRect(
|
||||
RECT *prc
|
||||
);
|
||||
|
||||
BOOL
|
||||
DrawStats(
|
||||
HDC hdc
|
||||
);
|
||||
|
||||
void
|
||||
CalcMovieRect(
|
||||
LPRECT lprc
|
||||
);
|
||||
|
||||
LPCTSTR
|
||||
IdStr(
|
||||
int idResource
|
||||
);
|
||||
|
||||
void
|
||||
UpdateSystemColors(
|
||||
void
|
||||
);
|
||||
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Message crackers
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
#define HANDLE_WM_USER(hwnd, wParam, lParam, fn) \
|
||||
((fn)(hwnd, wParam, lParam), 0L)
|
||||
|
||||
#ifndef HANDLE_WM_NOTIFY
|
||||
#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_OnClick(
|
||||
HWND hwnd,
|
||||
WPARAM pParam,
|
||||
LPARAM lParam);
|
||||
|
||||
void
|
||||
VideoCd_OnClickHold(
|
||||
HWND hwnd,
|
||||
WPARAM pParam,
|
||||
LPARAM lParam);
|
||||
|
||||
void
|
||||
VideoCd_OnCommand(
|
||||
HWND hwnd,
|
||||
int id,
|
||||
HWND hwndCtl,
|
||||
UINT codeNotify
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnPaint(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnTimer(
|
||||
HWND hwnd,
|
||||
UINT id
|
||||
);
|
||||
|
||||
BOOL
|
||||
VideoCd_OnCreate(
|
||||
HWND hwnd,
|
||||
LPCREATESTRUCT lpCreateStruct
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnSize(
|
||||
HWND hwnd,
|
||||
UINT state,
|
||||
int cx,
|
||||
int cy
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnKeyUp(
|
||||
HWND hwnd,
|
||||
UINT vk,
|
||||
BOOL fDown,
|
||||
int cRepeat,
|
||||
UINT flags
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnHScroll(
|
||||
HWND hwnd,
|
||||
HWND hwndCtl,
|
||||
UINT code,
|
||||
int pos
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnUser(
|
||||
HWND hwnd,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnSysColorChange(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnMenuSelect(
|
||||
HWND hwnd,
|
||||
HMENU hmenu,
|
||||
int item,
|
||||
HMENU hmenuPopup,
|
||||
UINT flags
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnInitMenuPopup(
|
||||
HWND hwnd,
|
||||
HMENU hMenu,
|
||||
UINT item,
|
||||
BOOL fSystemMenu
|
||||
);
|
||||
|
||||
#ifdef WM_NOTIFY
|
||||
LRESULT
|
||||
VideoCd_OnNotify(
|
||||
HWND hwnd,
|
||||
int idFrom,
|
||||
NMHDR FAR* pnmhdr
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
VideoCd_OnGraphNotify(
|
||||
int stream
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnDropFiles(
|
||||
HWND hwnd,
|
||||
HDROP hdrop);
|
||||
|
||||
void
|
||||
SetPlayButtonsEnableState(
|
||||
void
|
||||
);
|
||||
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Command processing functions
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
BOOL
|
||||
VcdPlayerSetLog(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerSetPerfLogFile(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerOpenCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerCloseCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerPlayCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerStopCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerPauseCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerPauseCmd(
|
||||
void
|
||||
);
|
||||
|
||||
void
|
||||
VcdPlayerSeekCmd(
|
||||
REFTIME rtSeekBy
|
||||
);
|
||||
|
||||
BOOL
|
||||
ProcessOpen(
|
||||
TCHAR *achFileName,
|
||||
BOOL bPlay = FALSE
|
||||
);
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** 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 int cx;
|
||||
extern int cy;
|
||||
extern int xOffset;
|
||||
extern int yOffset;
|
||||
extern DWORD g_State;
|
||||
extern TCHAR g_szPerfLog[];
|
||||
extern int g_TimeFormat;
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Constants
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
#define LEFT_MARGIN 0
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** 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
|
||||
@@ -0,0 +1,143 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// File: commands.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Processes commands from the user.
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------------------
|
||||
#include "project.h"
|
||||
#include <mmreg.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <io.h>
|
||||
#include "resrc1.h"
|
||||
|
||||
// Function prototypes
|
||||
void RepositionMovie(HWND hwnd);
|
||||
bool FindMediaFile(TCHAR * achFileName, TCHAR * achFoundFile);
|
||||
|
||||
// External data
|
||||
extern TCHAR g_achFileName[];
|
||||
extern CMpegMovie * pMpegMovie;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// ProcessOpen
|
||||
//
|
||||
// Creates instance of CMpegMovie and plays it. Called from user UI functions.
|
||||
//
|
||||
// Parameters:
|
||||
// achFileName - path to the file to play
|
||||
// bPlay - start demonstration if true
|
||||
//----------------------------------------------------------------------------
|
||||
BOOL
|
||||
ProcessOpen(
|
||||
TCHAR *achFileName,
|
||||
BOOL bPlay
|
||||
)
|
||||
{
|
||||
TCHAR achFoundFile[MAX_PATH];
|
||||
|
||||
if( !FindMediaFile(achFileName, achFoundFile) )
|
||||
{
|
||||
InvalidateRect( hwndApp, NULL, FALSE );
|
||||
UpdateWindow( hwndApp );
|
||||
return false;
|
||||
}
|
||||
|
||||
lstrcpy(g_achFileName, achFoundFile);
|
||||
pMpegMovie = new CMpegMovie(hwndApp);
|
||||
|
||||
if (pMpegMovie) {
|
||||
|
||||
HRESULT hr = pMpegMovie->OpenMovie(g_achFileName);
|
||||
if (SUCCEEDED(hr)) {
|
||||
|
||||
TCHAR achTmp[MAX_PATH];
|
||||
|
||||
wsprintf(achTmp, IdStr(STR_APP_TITLE_LOADED), g_achFileName );
|
||||
g_State = (VCD_LOADED | VCD_STOPPED);
|
||||
|
||||
RepositionMovie(hwndApp);
|
||||
InvalidateRect(hwndApp, NULL, TRUE);
|
||||
|
||||
if (bPlay) {
|
||||
pMpegMovie->PlayMovie();
|
||||
}
|
||||
}
|
||||
else {
|
||||
MessageBox(hwndApp,
|
||||
TEXT("Failed to open the movie; "),
|
||||
IdStr(STR_APP_TITLE), MB_OK );
|
||||
|
||||
pMpegMovie->CloseMovie();
|
||||
delete pMpegMovie;
|
||||
pMpegMovie = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
InvalidateRect( hwndApp, NULL, FALSE );
|
||||
UpdateWindow( hwndApp );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// FindMediaFile
|
||||
//
|
||||
// Provides FileOpen dialog to select media file or processes command line
|
||||
//
|
||||
// Parameters:
|
||||
// achFileName - command line
|
||||
// achFoundFile - path to the file to play
|
||||
//
|
||||
// Return: true if success
|
||||
//----------------------------------------------------------------------------
|
||||
bool FindMediaFile(TCHAR * achFileName, TCHAR * achFoundFile)
|
||||
{
|
||||
long lFindRes;
|
||||
struct _finddata_t fileinfo;
|
||||
|
||||
lFindRes = _findfirst( achFileName, &fileinfo );
|
||||
if( -1 != lFindRes )
|
||||
{
|
||||
lstrcpy(achFoundFile, achFileName);
|
||||
return true;
|
||||
}
|
||||
|
||||
OPENFILENAME ofn;
|
||||
TCHAR szBuffer[MAX_PATH];
|
||||
|
||||
lstrcpy(szBuffer, TEXT(""));
|
||||
static char szFilter[] = "Video Files (.MOV, .AVI, .MPG, .VOB, .QT)\0*.AVI;*.MOV;*.MPG;*.VOB;*.QT\0" \
|
||||
"All Files (*.*)\0*.*\0\0";
|
||||
ofn.lStructSize = sizeof(OPENFILENAME);
|
||||
ofn.hwndOwner = NULL;
|
||||
ofn.hInstance = NULL;
|
||||
ofn.lpstrFilter = szFilter;
|
||||
ofn.nFilterIndex = 1;
|
||||
ofn.lpstrCustomFilter = NULL;
|
||||
ofn.nMaxCustFilter = 0;
|
||||
ofn.lpstrFile = szBuffer;
|
||||
ofn.nMaxFile = _MAX_PATH;
|
||||
ofn.lpstrFileTitle = NULL;
|
||||
ofn.nMaxFileTitle = 0;
|
||||
ofn.lpstrInitialDir = NULL;
|
||||
ofn.lpstrTitle = "VMRXCL: Select a video file to play...";
|
||||
ofn.Flags = OFN_HIDEREADONLY;
|
||||
ofn.nFileOffset = 0;
|
||||
ofn.nFileExtension = 0;
|
||||
ofn.lpstrDefExt = "mov";
|
||||
ofn.lCustData = 0L;
|
||||
ofn.lpfnHook = NULL;
|
||||
ofn.lpTemplateName = NULL;
|
||||
|
||||
if (GetOpenFileName (&ofn)) // user specified a file
|
||||
{
|
||||
lstrcpy(achFoundFile, ofn.lpstrFile);
|
||||
return true;
|
||||
}// if
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,411 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: D3DFont.cpp
|
||||
//
|
||||
// Desc: Texture-based font class
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <streams.h>
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#include <ddraw.h>
|
||||
#define D3D_OVERLOADS
|
||||
#include <d3d.h>
|
||||
#include "D3DFont.h"
|
||||
|
||||
|
||||
#define D3DFVF_FONT2DVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1)
|
||||
|
||||
inline FONT2DVERTEX InitFont2DVertex( const D3DXVECTOR4& p, D3DCOLOR color,
|
||||
FLOAT tu, FLOAT tv )
|
||||
{
|
||||
FONT2DVERTEX v;
|
||||
|
||||
v.p.x = p.x;
|
||||
v.p.y = p.y;
|
||||
v.p.z = p.z;
|
||||
v.p.w = p.w;
|
||||
v.color = color;
|
||||
v.tu = tu;
|
||||
v.tv = tv;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CD3DFont()
|
||||
// Desc: Font class constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CD3DFont::CD3DFont( TCHAR* strFontName, DWORD dwHeight, DWORD dwFlags )
|
||||
{
|
||||
_tcscpy( m_strFontName, strFontName );
|
||||
m_dwFontHeight = dwHeight;
|
||||
m_dwFontFlags = dwFlags;
|
||||
|
||||
m_pd3dDevice = NULL;
|
||||
m_pTexture = NULL;
|
||||
ZeroMemory(&m_VB, sizeof(m_VB));
|
||||
|
||||
m_dwSavedStateBlock = 0L;
|
||||
m_dwDrawTextStateBlock = 0L;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: ~CD3DFont()
|
||||
// Desc: Font class destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CD3DFont::~CD3DFont()
|
||||
{
|
||||
InvalidateDeviceObjects();
|
||||
DeleteDeviceObjects();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: InitDeviceObjects()
|
||||
// Desc: Initializes device-dependent objects, including the vertex buffer used
|
||||
// for rendering text and the texture map which stores the font image.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CD3DFont::InitDeviceObjects(
|
||||
LPDIRECTDRAW7 pDD,
|
||||
LPDIRECT3DDEVICE7 pd3dDevice
|
||||
)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
// Keep a local copy of the device
|
||||
m_pd3dDevice = pd3dDevice;
|
||||
|
||||
// Establish the font and texture size
|
||||
m_fTextScale = 1.0f; // Draw fonts into texture without scaling
|
||||
|
||||
// Large fonts need larger textures
|
||||
if( m_dwFontHeight > 40 )
|
||||
m_dwTexWidth = m_dwTexHeight = 1024;
|
||||
else if( m_dwFontHeight > 20 )
|
||||
m_dwTexWidth = m_dwTexHeight = 512;
|
||||
else
|
||||
m_dwTexWidth = m_dwTexHeight = 256;
|
||||
|
||||
// If requested texture is too big, use a smaller texture and smaller font,
|
||||
// and scale up when rendering.
|
||||
D3DDEVICEDESC7 d3dCaps;
|
||||
m_pd3dDevice->GetCaps( &d3dCaps );
|
||||
|
||||
if( m_dwTexWidth > d3dCaps.dwMaxTextureWidth )
|
||||
{
|
||||
m_fTextScale = (FLOAT)d3dCaps.dwMaxTextureWidth / (FLOAT)m_dwTexWidth;
|
||||
m_dwTexWidth = m_dwTexHeight = d3dCaps.dwMaxTextureWidth;
|
||||
}
|
||||
|
||||
DDSURFACEDESC2 ddsd;
|
||||
INITDDSTRUCT(ddsd);
|
||||
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
|
||||
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
|
||||
ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE | DDSCAPS2_HINTSTATIC;
|
||||
|
||||
ddsd.dwWidth = m_dwTexWidth;
|
||||
ddsd.dwHeight = m_dwTexHeight;
|
||||
ddsd.ddpfPixelFormat.dwFourCC = BI_RGB;
|
||||
ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
|
||||
ddsd.ddpfPixelFormat.dwRGBBitCount = 16;
|
||||
ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0xF000;
|
||||
ddsd.ddpfPixelFormat.dwRBitMask = 0x0F00;
|
||||
ddsd.ddpfPixelFormat.dwGBitMask = 0x00F0;
|
||||
ddsd.ddpfPixelFormat.dwBBitMask = 0x000F;
|
||||
|
||||
// Create a new texture for the font
|
||||
hr = pDD->CreateSurface(&ddsd, &m_pTexture, NULL);
|
||||
|
||||
if( FAILED(hr) )
|
||||
return hr;
|
||||
|
||||
// Prepare to create a bitmap
|
||||
DWORD* pBitmapBits;
|
||||
BITMAPINFO bmi;
|
||||
ZeroMemory( &bmi.bmiHeader, sizeof(BITMAPINFOHEADER) );
|
||||
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bmi.bmiHeader.biWidth = (int)m_dwTexWidth;
|
||||
bmi.bmiHeader.biHeight = -(int)m_dwTexHeight;
|
||||
bmi.bmiHeader.biPlanes = 1;
|
||||
bmi.bmiHeader.biCompression = BI_RGB;
|
||||
bmi.bmiHeader.biBitCount = 32;
|
||||
|
||||
// Create a DC and a bitmap for the font
|
||||
HDC hDC = CreateCompatibleDC( NULL );
|
||||
HBITMAP hbmBitmap = CreateDIBSection( hDC, &bmi, DIB_RGB_COLORS,
|
||||
(VOID**)&pBitmapBits, NULL, 0 );
|
||||
SetMapMode( hDC, MM_TEXT );
|
||||
|
||||
// Create a font. By specifying ANTIALIASED_QUALITY, we might get an
|
||||
// antialiased font, but this is not guaranteed.
|
||||
INT nHeight = -MulDiv( m_dwFontHeight,
|
||||
(INT)(GetDeviceCaps(hDC, LOGPIXELSY) * m_fTextScale), 72 );
|
||||
DWORD dwBold = (m_dwFontFlags&D3DFONT_BOLD) ? FW_BOLD : FW_NORMAL;
|
||||
DWORD dwItalic = (m_dwFontFlags&D3DFONT_ITALIC) ? TRUE : FALSE;
|
||||
HFONT hFont = CreateFont( nHeight, 0, 0, 0, dwBold, dwItalic,
|
||||
FALSE, FALSE, DEFAULT_CHARSET, OUT_STRING_PRECIS,
|
||||
CLIP_STROKE_PRECIS, ANTIALIASED_QUALITY,
|
||||
VARIABLE_PITCH, m_strFontName );
|
||||
if( NULL==hFont )
|
||||
return E_FAIL;
|
||||
|
||||
SelectObject( hDC, hbmBitmap );
|
||||
SelectObject( hDC, hFont );
|
||||
|
||||
// Set text properties
|
||||
SetTextColor( hDC, RGB(255,255,255) );
|
||||
SetBkColor( hDC, 0x00000000 );
|
||||
SetTextAlign( hDC, TA_TOP );
|
||||
|
||||
// Loop through all printable character and output them to the bitmap..
|
||||
// Meanwhile, keep track of the corresponding tex coords for each character.
|
||||
DWORD x = 0;
|
||||
DWORD y = 0;
|
||||
TCHAR str[2] = _T("x");
|
||||
SIZE size;
|
||||
|
||||
for( TCHAR c=32; c<127; c++ )
|
||||
{
|
||||
str[0] = c;
|
||||
GetTextExtentPoint32( hDC, str, 1, &size );
|
||||
|
||||
if( (DWORD)(x+size.cx+1) > m_dwTexWidth )
|
||||
{
|
||||
x = 0;
|
||||
y += size.cy+1;
|
||||
}
|
||||
|
||||
ExtTextOut( hDC, x+0, y+0, ETO_OPAQUE, NULL, str, 1, NULL );
|
||||
|
||||
m_fTexCoords[c-32][0] = ((FLOAT)(x+0))/m_dwTexWidth;
|
||||
m_fTexCoords[c-32][1] = ((FLOAT)(y+0))/m_dwTexHeight;
|
||||
m_fTexCoords[c-32][2] = ((FLOAT)(x+0+size.cx))/m_dwTexWidth;
|
||||
m_fTexCoords[c-32][3] = ((FLOAT)(y+0+size.cy))/m_dwTexHeight;
|
||||
|
||||
x += size.cx+1;
|
||||
}
|
||||
|
||||
// Lock the surface and write the alpha values for the set pixels
|
||||
m_pTexture->Lock(NULL, &ddsd, DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL);
|
||||
|
||||
WORD* pDst16 = (WORD*)ddsd.lpSurface;
|
||||
BYTE bAlpha; // 4-bit measure of pixel intensity
|
||||
|
||||
for( y=0; y < m_dwTexHeight; y++ )
|
||||
{
|
||||
for( x=0; x < m_dwTexWidth; x++ )
|
||||
{
|
||||
bAlpha = (BYTE)((pBitmapBits[m_dwTexWidth*y + x] & 0xff) >> 4);
|
||||
if (bAlpha > 0)
|
||||
{
|
||||
*pDst16++ = (WORD) ((bAlpha << 12) | 0x0fff);
|
||||
}
|
||||
else
|
||||
{
|
||||
*pDst16++ = 0x0000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Done updating texture, so clean up used objects
|
||||
m_pTexture->Unlock(NULL);
|
||||
DeleteObject( hbmBitmap );
|
||||
DeleteDC( hDC );
|
||||
DeleteObject( hFont );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: RestoreDeviceObjects()
|
||||
// Desc:
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CD3DFont::RestoreDeviceObjects()
|
||||
{
|
||||
// Create vertex buffer for the letters
|
||||
|
||||
ZeroMemory(&m_VB, sizeof(m_VB));
|
||||
|
||||
// Create the state blocks for rendering text
|
||||
m_pd3dDevice->SetTexture(0, m_pTexture);
|
||||
|
||||
m_pd3dDevice->SetRenderState(D3DRENDERSTATE_BLENDENABLE, TRUE);
|
||||
m_pd3dDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
m_pd3dDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
|
||||
m_pd3dDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, TRUE);
|
||||
m_pd3dDevice->SetRenderState(D3DRENDERSTATE_ALPHAREF, 0x08);
|
||||
m_pd3dDevice->SetRenderState(D3DRENDERSTATE_ALPHAFUNC, D3DCMP_GREATEREQUAL);
|
||||
|
||||
m_pd3dDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
|
||||
m_pd3dDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE);
|
||||
|
||||
|
||||
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE );
|
||||
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
|
||||
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
|
||||
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
|
||||
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
|
||||
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
|
||||
|
||||
m_pd3dDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFN_POINT);
|
||||
m_pd3dDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_POINT);
|
||||
m_pd3dDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTFP_NONE);
|
||||
|
||||
m_pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0 );
|
||||
m_pd3dDevice->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );
|
||||
|
||||
m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE );
|
||||
m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: InvalidateDeviceObjects()
|
||||
// Desc: Destroys all device-dependent objects
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CD3DFont::InvalidateDeviceObjects()
|
||||
{
|
||||
ZeroMemory(&m_VB, sizeof(m_VB));
|
||||
|
||||
// Delete the state blocks
|
||||
if( m_pd3dDevice )
|
||||
{
|
||||
if (m_dwSavedStateBlock)
|
||||
m_pd3dDevice->DeleteStateBlock(m_dwSavedStateBlock);
|
||||
|
||||
if (m_dwDrawTextStateBlock)
|
||||
m_pd3dDevice->DeleteStateBlock(m_dwDrawTextStateBlock);
|
||||
}
|
||||
|
||||
m_dwSavedStateBlock = 0L;
|
||||
m_dwDrawTextStateBlock = 0L;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: DeleteDeviceObjects()
|
||||
// Desc: Destroys all device-dependent objects
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CD3DFont::DeleteDeviceObjects()
|
||||
{
|
||||
RELEASE(m_pTexture);
|
||||
m_pd3dDevice = NULL;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: GetTextExtent()
|
||||
// Desc: Get the dimensions of a text string
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CD3DFont::GetTextExtent( TCHAR* strText, SIZE* pSize )
|
||||
{
|
||||
if( NULL==strText || NULL==pSize )
|
||||
return E_FAIL;
|
||||
|
||||
FLOAT fRowWidth = 0.0f;
|
||||
FLOAT fRowHeight = (m_fTexCoords[0][3]-m_fTexCoords[0][1])*m_dwTexHeight;
|
||||
FLOAT fWidth = 0.0f;
|
||||
FLOAT fHeight = fRowHeight;
|
||||
|
||||
while( *strText )
|
||||
{
|
||||
TCHAR c = *strText++;
|
||||
|
||||
if( c == _T('\n') )
|
||||
{
|
||||
fRowWidth = 0.0f;
|
||||
fHeight += fRowHeight;
|
||||
}
|
||||
if( c < _T(' ') )
|
||||
continue;
|
||||
|
||||
FLOAT tx1 = m_fTexCoords[c-32][0];
|
||||
FLOAT tx2 = m_fTexCoords[c-32][2];
|
||||
|
||||
fRowWidth += (tx2-tx1)*m_dwTexWidth;
|
||||
|
||||
if( fRowWidth > fWidth )
|
||||
fWidth = fRowWidth;
|
||||
}
|
||||
|
||||
pSize->cx = (int)fWidth;
|
||||
pSize->cy = (int)fHeight;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: DrawText()
|
||||
// Desc: Draws 2D text
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CD3DFont::DrawText( FLOAT sx, FLOAT sy, DWORD dwColor,
|
||||
TCHAR* strText, DWORD dwFlags )
|
||||
{
|
||||
if( m_pd3dDevice == NULL )
|
||||
return E_FAIL;
|
||||
|
||||
// Setup renderstate
|
||||
RestoreDeviceObjects();
|
||||
|
||||
// Set filter states
|
||||
if( dwFlags & D3DFONT_FILTERED )
|
||||
{
|
||||
m_pd3dDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFN_LINEAR);
|
||||
m_pd3dDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_LINEAR);
|
||||
}
|
||||
|
||||
FLOAT fStartX = sx;
|
||||
|
||||
// Fill vertex buffer
|
||||
FONT2DVERTEX* pVertices = NULL;
|
||||
DWORD dwNumTriangles = 0;
|
||||
pVertices = &m_VB[0];
|
||||
|
||||
while( *strText )
|
||||
{
|
||||
TCHAR c = *strText++;
|
||||
|
||||
if( c == _T('\n') )
|
||||
{
|
||||
sx = fStartX;
|
||||
sy += (m_fTexCoords[0][3]-m_fTexCoords[0][1])*m_dwTexHeight;
|
||||
}
|
||||
if( c < _T(' ') )
|
||||
continue;
|
||||
|
||||
FLOAT tx1 = m_fTexCoords[c-32][0];
|
||||
FLOAT ty1 = m_fTexCoords[c-32][1];
|
||||
FLOAT tx2 = m_fTexCoords[c-32][2];
|
||||
FLOAT ty2 = m_fTexCoords[c-32][3];
|
||||
|
||||
FLOAT w = (tx2-tx1) * m_dwTexWidth / m_fTextScale;
|
||||
FLOAT h = (ty2-ty1) * m_dwTexHeight / m_fTextScale;
|
||||
|
||||
*pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f,sy+h-0.5f,0.5f,2.0f), dwColor, tx1, ty2 );
|
||||
*pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+h-0.5f,0.5f,2.0f), dwColor, tx2, ty2 );
|
||||
*pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f,sy+0-0.5f,0.5f,2.0f), dwColor, tx1, ty1 );
|
||||
*pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+0-0.5f,0.5f,2.0f), dwColor, tx2, ty1 );
|
||||
|
||||
dwNumTriangles += 2;
|
||||
|
||||
m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,
|
||||
D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1,
|
||||
&m_VB[0], dwNumTriangles*2, D3DDP_WAIT);
|
||||
pVertices = &m_VB[0];
|
||||
dwNumTriangles = 0L;
|
||||
|
||||
sx += w;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: D3DFont.h
|
||||
//
|
||||
// Desc: Texture-based font class
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef D3DFONT_H
|
||||
#define D3DFONT_H
|
||||
#include <tchar.h>
|
||||
#include <ddraw.h>
|
||||
#include <d3dxmath.h>
|
||||
#define D3D_OVERLOADS
|
||||
#include <d3d.h>
|
||||
|
||||
|
||||
// Font creation flags
|
||||
#define D3DFONT_BOLD 0x0001
|
||||
#define D3DFONT_ITALIC 0x0002
|
||||
|
||||
// Font rendering flags
|
||||
#define D3DFONT_CENTERED 0x0001
|
||||
#define D3DFONT_TWOSIDED 0x0002
|
||||
#define D3DFONT_FILTERED 0x0004
|
||||
|
||||
|
||||
#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
|
||||
|
||||
|
||||
#define MAX_NUM_VERTICES 50*6
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Custom vertex types for rendering text
|
||||
//-----------------------------------------------------------------------------
|
||||
struct FONT2DVERTEX {
|
||||
D3DXVECTOR4 p;
|
||||
DWORD color;
|
||||
FLOAT tu, tv;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: class CD3DFont
|
||||
// Desc: Texture-based font class for doing text in a 3D scene.
|
||||
//-----------------------------------------------------------------------------
|
||||
class CD3DFont
|
||||
{
|
||||
TCHAR m_strFontName[80]; // Font properties
|
||||
DWORD m_dwFontHeight;
|
||||
DWORD m_dwFontFlags;
|
||||
|
||||
LPDIRECT3DDEVICE7 m_pd3dDevice; // A D3DDevice used for rendering
|
||||
LPDIRECTDRAWSURFACE7 m_pTexture; // The d3d texture for this font
|
||||
FONT2DVERTEX m_VB[MAX_NUM_VERTICES]; // VertexBuffer for rendering text
|
||||
|
||||
DWORD m_dwTexWidth; // Texture dimensions
|
||||
DWORD m_dwTexHeight;
|
||||
FLOAT m_fTextScale;
|
||||
FLOAT m_fTexCoords[128-32][4];
|
||||
|
||||
// Stateblocks for setting and restoring render states
|
||||
DWORD m_dwSavedStateBlock;
|
||||
DWORD m_dwDrawTextStateBlock;
|
||||
|
||||
public:
|
||||
// 2D and 3D text drawing functions
|
||||
HRESULT DrawText( FLOAT x, FLOAT y, DWORD dwColor,
|
||||
TCHAR* strText, DWORD dwFlags=0L );
|
||||
|
||||
// Function to get extent of text
|
||||
HRESULT GetTextExtent( TCHAR* strText, SIZE* pSize );
|
||||
|
||||
// Initializing and destroying device-dependent objects
|
||||
HRESULT InitDeviceObjects(LPDIRECTDRAW7 pDD, LPDIRECT3DDEVICE7 pd3dDevice);
|
||||
HRESULT RestoreDeviceObjects();
|
||||
HRESULT InvalidateDeviceObjects();
|
||||
HRESULT DeleteDeviceObjects();
|
||||
|
||||
// Constructor / destructor
|
||||
CD3DFont( TCHAR* strFontName, DWORD dwHeight, DWORD dwFlags=0L );
|
||||
~CD3DFont();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,836 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: D3DTextr.cpp
|
||||
//
|
||||
// Desc: Functions to manage textures, including creating (loading from a
|
||||
// file), restoring lost surfaces, invalidating, and destroying.
|
||||
//
|
||||
// Note: the implementation of these functions maintains an internal list
|
||||
// of loaded textures. After creation, individual textures are referenced
|
||||
// via their ASCII names.
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "project.h"
|
||||
#include <tchar.h>
|
||||
#include "D3DTextr.h"
|
||||
#include "D3DUtil.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#ifndef _T
|
||||
#define _T TEXT
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Macros, function prototypes and static variable
|
||||
//-----------------------------------------------------------------------------
|
||||
static TCHAR g_strTexturePath[512] = _T(""); // Path for files
|
||||
|
||||
// Local list of textures
|
||||
static TextureContainer* g_ptcTextureList = NULL;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CD3DTextureManager
|
||||
// Desc: Class used to automatically construct and destruct the static
|
||||
// texture engine class.
|
||||
//-----------------------------------------------------------------------------
|
||||
class CD3DTextureManager
|
||||
{
|
||||
public:
|
||||
CD3DTextureManager() {}
|
||||
~CD3DTextureManager() { if( g_ptcTextureList ) delete g_ptcTextureList; }
|
||||
};
|
||||
|
||||
// Global instance
|
||||
CD3DTextureManager g_StaticTextureEngine;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: struct TEXTURESEARCHINFO
|
||||
// Desc: Structure used to search for texture formats
|
||||
//-----------------------------------------------------------------------------
|
||||
struct TEXTURESEARCHINFO
|
||||
{
|
||||
DWORD dwDesiredBPP; // Input for texture format search
|
||||
BOOL bUseAlpha;
|
||||
BOOL bUsePalette;
|
||||
BOOL bFoundGoodFormat;
|
||||
|
||||
DDPIXELFORMAT* pddpf; // Output of texture format search
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: TextureSearchCallback()
|
||||
// Desc: Enumeration callback routine to find a best-matching texture format.
|
||||
// The param data is the DDPIXELFORMAT of the best-so-far matching
|
||||
// texture. Note: the desired BPP is passed in the dwSize field, and the
|
||||
// default BPP is passed in the dwFlags field.
|
||||
//-----------------------------------------------------------------------------
|
||||
static HRESULT CALLBACK TextureSearchCallback( DDPIXELFORMAT* pddpf,
|
||||
VOID* param )
|
||||
{
|
||||
if( NULL==pddpf || NULL==param )
|
||||
return DDENUMRET_OK;
|
||||
|
||||
TEXTURESEARCHINFO* ptsi = (TEXTURESEARCHINFO*)param;
|
||||
|
||||
// Skip any unusual modes
|
||||
if( pddpf->dwFlags & (DDPF_LUMINANCE|DDPF_BUMPLUMINANCE|DDPF_BUMPDUDV) )
|
||||
return DDENUMRET_OK;
|
||||
|
||||
// Check for palettized formats
|
||||
if( ptsi->bUsePalette )
|
||||
{
|
||||
if( !( pddpf->dwFlags & DDPF_PALETTEINDEXED8 ) )
|
||||
return DDENUMRET_OK;
|
||||
|
||||
// Accept the first 8-bit palettized format we get
|
||||
memcpy( ptsi->pddpf, pddpf, sizeof(DDPIXELFORMAT) );
|
||||
ptsi->bFoundGoodFormat = TRUE;
|
||||
return DDENUMRET_CANCEL;
|
||||
}
|
||||
|
||||
// Else, skip any paletized formats (all modes under 16bpp)
|
||||
if( pddpf->dwRGBBitCount < 16 )
|
||||
return DDENUMRET_OK;
|
||||
|
||||
// Skip any FourCC formats
|
||||
if( pddpf->dwFourCC != 0 )
|
||||
return DDENUMRET_OK;
|
||||
|
||||
// Skip any ARGB 4444 formats (which are best used for pre-authored
|
||||
// content designed speciafically for an ARGB 4444 format).
|
||||
if( pddpf->dwRGBAlphaBitMask == 0x0000f000 )
|
||||
return DDENUMRET_OK;
|
||||
|
||||
// Make sure current alpha format agrees with requested format type
|
||||
if( (ptsi->bUseAlpha==TRUE) && !(pddpf->dwFlags&DDPF_ALPHAPIXELS) )
|
||||
return DDENUMRET_OK;
|
||||
if( (ptsi->bUseAlpha==FALSE) && (pddpf->dwFlags&DDPF_ALPHAPIXELS) )
|
||||
return DDENUMRET_OK;
|
||||
|
||||
// Check if we found a good match
|
||||
if( pddpf->dwRGBBitCount == ptsi->dwDesiredBPP )
|
||||
{
|
||||
memcpy( ptsi->pddpf, pddpf, sizeof(DDPIXELFORMAT) );
|
||||
ptsi->bFoundGoodFormat = TRUE;
|
||||
return DDENUMRET_CANCEL;
|
||||
}
|
||||
|
||||
return DDENUMRET_OK;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: FindTexture()
|
||||
// Desc: Searches the internal list of textures for a texture specified by
|
||||
// its name. Returns the structure associated with that texture.
|
||||
//-----------------------------------------------------------------------------
|
||||
static TextureContainer* FindTexture( TCHAR* strTextureName )
|
||||
{
|
||||
TextureContainer* ptcTexture = g_ptcTextureList;
|
||||
|
||||
while( ptcTexture )
|
||||
{
|
||||
if( !lstrcmpi( strTextureName, ptcTexture->m_strName ) )
|
||||
return ptcTexture;
|
||||
ptcTexture = ptcTexture->m_pNext;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: TextureContainer()
|
||||
// Desc: Constructor for a texture object
|
||||
//-----------------------------------------------------------------------------
|
||||
TextureContainer::TextureContainer( TCHAR* strName, DWORD dwStage,
|
||||
DWORD dwFlags, UINT uintRes /*= NULL */ )
|
||||
{
|
||||
lstrcpy( m_strName, strName );
|
||||
m_dwWidth = 0;
|
||||
m_dwHeight = 0;
|
||||
m_dwStage = dwStage;
|
||||
m_dwBPP = 0;
|
||||
m_dwFlags = dwFlags;
|
||||
m_bHasAlpha = 0;
|
||||
m_nRes = uintRes;
|
||||
|
||||
m_pddsSurface = NULL;
|
||||
m_hbmBitmap = NULL;
|
||||
m_pRGBAData = NULL;
|
||||
|
||||
// Add the texture to the head of the global texture list
|
||||
m_pNext = g_ptcTextureList;
|
||||
g_ptcTextureList = this;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: ~TextureContainer()
|
||||
// Desc: Destructs the contents of the texture container
|
||||
//-----------------------------------------------------------------------------
|
||||
TextureContainer::~TextureContainer()
|
||||
{
|
||||
SAFE_RELEASE( m_pddsSurface );
|
||||
SAFE_DELETE( m_pRGBAData );
|
||||
DeleteObject( m_hbmBitmap );
|
||||
|
||||
// Remove the texture container from the global list
|
||||
if( g_ptcTextureList == this )
|
||||
g_ptcTextureList = m_pNext;
|
||||
else
|
||||
{
|
||||
for( TextureContainer* ptc=g_ptcTextureList; ptc; ptc=ptc->m_pNext )
|
||||
if( ptc->m_pNext == this )
|
||||
ptc->m_pNext = m_pNext;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: LoadImageData()
|
||||
// Desc: Loads the texture map's image data
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT TextureContainer::LoadImageData()
|
||||
{
|
||||
TCHAR* strExtension;
|
||||
TCHAR strPathname[256];
|
||||
HFILE file;
|
||||
|
||||
char szAnsiName[256];
|
||||
|
||||
// Check the executable's resource. If it's there, we're done!
|
||||
if( m_nRes )
|
||||
{
|
||||
m_hbmBitmap = (HBITMAP)LoadImage(g_hInst, MAKEINTRESOURCE(m_nRes),
|
||||
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
|
||||
if( m_hbmBitmap )
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
m_hbmBitmap = (HBITMAP)LoadImage(g_hInst, m_strName,
|
||||
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
|
||||
if( m_hbmBitmap )
|
||||
return S_OK;
|
||||
|
||||
// First check if the file exists in the global texture path
|
||||
lstrcpy( strPathname, g_strTexturePath );
|
||||
lstrcat( strPathname, m_strName );
|
||||
|
||||
wsprintfA(szAnsiName, "%ls", strPathname);
|
||||
|
||||
if( NULL == ( file = _lopen(szAnsiName, OF_READ) ) )
|
||||
{
|
||||
// Then check if the file exists in the DirectX SDK media path
|
||||
lstrcpy( strPathname, D3DUtil_GetDXSDKMediaPath() );
|
||||
lstrcat( strPathname, m_strName );
|
||||
|
||||
wsprintfA(szAnsiName, "%ls", strPathname);
|
||||
if( NULL == ( file = _lopen(szAnsiName, OF_READ) ) )
|
||||
return DDERR_NOTFOUND;
|
||||
}
|
||||
_lclose( file );
|
||||
|
||||
// Get the filename extension
|
||||
if( NULL == ( strExtension = _tcsrchr( m_strName, _T('.') ) ) )
|
||||
return DDERR_UNSUPPORTED;
|
||||
|
||||
// Load bitmap files
|
||||
if( !lstrcmpi( strExtension, _T(".bmp") ) )
|
||||
return LoadBitmapFile( strPathname );
|
||||
|
||||
// Can add code here to check for other file formats before failing
|
||||
return DDERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: LoadBitmapFile()
|
||||
// Desc: Loads data from a .bmp file, and stores it in a bitmap structure.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT TextureContainer::LoadBitmapFile( TCHAR* strPathname )
|
||||
{
|
||||
// Try to load the bitmap as a file
|
||||
m_hbmBitmap = (HBITMAP)LoadImage( NULL, strPathname, IMAGE_BITMAP, 0, 0,
|
||||
LR_LOADFROMFILE|LR_CREATEDIBSECTION );
|
||||
if( m_hbmBitmap )
|
||||
return S_OK;
|
||||
|
||||
return DDERR_NOTFOUND;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: Restore()
|
||||
// Desc: Rebuilds the texture surface using the new device.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT TextureContainer::Restore( LPDIRECT3DDEVICE7 pd3dDevice )
|
||||
{
|
||||
// Release any previously created objects
|
||||
SAFE_RELEASE( m_pddsSurface );
|
||||
|
||||
// Check params
|
||||
if( NULL == pd3dDevice )
|
||||
return DDERR_INVALIDPARAMS;
|
||||
|
||||
// Get the device caps
|
||||
D3DDEVICEDESC7 ddDesc;
|
||||
if( FAILED( pd3dDevice->GetCaps( &ddDesc) ) )
|
||||
return E_FAIL;
|
||||
|
||||
// Setup the new surface desc
|
||||
DDSURFACEDESC2 ddsd;
|
||||
D3DUtil_InitSurfaceDesc( ddsd );
|
||||
ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|
|
||||
DDSD_PIXELFORMAT /* |DDSD_TEXTURESTAGE */;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
|
||||
ddsd.dwTextureStage = m_dwStage;
|
||||
ddsd.dwWidth = m_dwWidth;
|
||||
ddsd.dwHeight = m_dwHeight;
|
||||
|
||||
// Turn on texture management for hardware devices
|
||||
ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
|
||||
|
||||
// Adjust width and height to be powers of 2, if the device requires it
|
||||
if( ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2 )
|
||||
{
|
||||
for( ddsd.dwWidth=1; m_dwWidth>ddsd.dwWidth; ddsd.dwWidth<<=1 );
|
||||
for( ddsd.dwHeight=1; m_dwHeight>ddsd.dwHeight; ddsd.dwHeight<<=1 );
|
||||
}
|
||||
|
||||
// Limit max texture sizes, if the driver can't handle large textures
|
||||
DWORD dwMaxWidth = ddDesc.dwMaxTextureWidth;
|
||||
DWORD dwMaxHeight = ddDesc.dwMaxTextureHeight;
|
||||
ddsd.dwWidth = min( ddsd.dwWidth, ( dwMaxWidth ? dwMaxWidth : 256 ) );
|
||||
ddsd.dwHeight = min( ddsd.dwHeight, ( dwMaxHeight ? dwMaxHeight : 256 ) );
|
||||
|
||||
// Make the texture square, if the driver requires it
|
||||
if( ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_SQUAREONLY )
|
||||
{
|
||||
if( ddsd.dwWidth > ddsd.dwHeight ) ddsd.dwHeight = ddsd.dwWidth;
|
||||
else ddsd.dwWidth = ddsd.dwHeight;
|
||||
}
|
||||
|
||||
// Setup the structure to be used for texture enumration.
|
||||
TEXTURESEARCHINFO tsi;
|
||||
tsi.bFoundGoodFormat = FALSE;
|
||||
tsi.pddpf = &ddsd.ddpfPixelFormat;
|
||||
tsi.dwDesiredBPP = m_dwBPP;
|
||||
tsi.bUsePalette = ( m_dwBPP <= 8 );
|
||||
tsi.bUseAlpha = m_bHasAlpha;
|
||||
if( m_dwFlags & D3DTEXTR_16BITSPERPIXEL )
|
||||
tsi.dwDesiredBPP = 16;
|
||||
else if( m_dwFlags & D3DTEXTR_32BITSPERPIXEL )
|
||||
tsi.dwDesiredBPP = 32;
|
||||
|
||||
if( m_dwFlags & (D3DTEXTR_TRANSPARENTWHITE|D3DTEXTR_TRANSPARENTBLACK) )
|
||||
{
|
||||
if( tsi.bUsePalette )
|
||||
{
|
||||
if( ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE )
|
||||
{
|
||||
tsi.bUseAlpha = TRUE;
|
||||
tsi.bUsePalette = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
tsi.bUseAlpha = TRUE;
|
||||
tsi.bUsePalette = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OutputDebugString("Restore: calling EnumTextureFormats\n");
|
||||
|
||||
// Enumerate the texture formats, and find the closest device-supported
|
||||
// texture pixel format
|
||||
pd3dDevice->EnumTextureFormats( TextureSearchCallback, &tsi );
|
||||
|
||||
// If we couldn't find a format, let's try a default format
|
||||
if( FALSE == tsi.bFoundGoodFormat )
|
||||
{
|
||||
tsi.bUsePalette = FALSE;
|
||||
tsi.dwDesiredBPP = 16;
|
||||
pd3dDevice->EnumTextureFormats( TextureSearchCallback, &tsi );
|
||||
|
||||
// If we still fail, we cannot create this texture
|
||||
if( FALSE == tsi.bFoundGoodFormat )
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Get the DirectDraw interface for creating surfaces
|
||||
LPDIRECTDRAW7 pDD;
|
||||
LPDIRECTDRAWSURFACE7 pddsRender;
|
||||
OutputDebugString("Restore: calling GetRenderTarget\n");
|
||||
|
||||
pd3dDevice->GetRenderTarget( &pddsRender );
|
||||
pddsRender->GetDDInterface( (VOID**)&pDD );
|
||||
pddsRender->Release();
|
||||
|
||||
// Create a new surface for the texture
|
||||
OutputDebugString("Restore: calling CreateSurface\n");
|
||||
|
||||
HRESULT hr = pDD->CreateSurface( &ddsd, &m_pddsSurface, NULL );
|
||||
|
||||
// Done with DDraw
|
||||
pDD->Release();
|
||||
|
||||
if( FAILED(hr) )
|
||||
return hr;
|
||||
|
||||
// For bitmap-based textures, copy the bitmap image.
|
||||
OutputDebugString("Restore: calling CopyBitmapToSurface\n");
|
||||
if( m_hbmBitmap )
|
||||
return CopyBitmapToSurface();
|
||||
|
||||
if( m_pRGBAData )
|
||||
return CopyRGBADataToSurface();
|
||||
|
||||
// At this point, code can be added to handle other file formats (such as
|
||||
// .dds files, .jpg files, etc.).
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CopyBitmapToSurface()
|
||||
// Desc: Copies the image of a bitmap into a surface
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT TextureContainer::CopyBitmapToSurface()
|
||||
{
|
||||
// Get a DDraw object to create a temporary surface
|
||||
LPDIRECTDRAW7 pDD;
|
||||
m_pddsSurface->GetDDInterface( (VOID**)&pDD );
|
||||
|
||||
// Get the bitmap structure (to extract width, height, and bpp)
|
||||
BITMAP bm;
|
||||
GetObject( m_hbmBitmap, sizeof(BITMAP), &bm );
|
||||
|
||||
// Setup the new surface desc
|
||||
DDSURFACEDESC2 ddsd;
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
m_pddsSurface->GetSurfaceDesc( &ddsd );
|
||||
ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|
|
||||
DDSD_TEXTURESTAGE;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE|DDSCAPS_SYSTEMMEMORY;
|
||||
ddsd.ddsCaps.dwCaps2 = 0L;
|
||||
ddsd.dwWidth = bm.bmWidth;
|
||||
ddsd.dwHeight = bm.bmHeight;
|
||||
|
||||
// Create a new surface for the texture
|
||||
LPDIRECTDRAWSURFACE7 pddsTempSurface;
|
||||
HRESULT hr;
|
||||
if( FAILED( hr = pDD->CreateSurface( &ddsd, &pddsTempSurface, NULL ) ) )
|
||||
{
|
||||
pDD->Release();
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Get a DC for the bitmap
|
||||
HDC hdcBitmap = CreateCompatibleDC( NULL );
|
||||
if( NULL == hdcBitmap )
|
||||
{
|
||||
pddsTempSurface->Release();
|
||||
pDD->Release();
|
||||
return hr;
|
||||
}
|
||||
SelectObject( hdcBitmap, m_hbmBitmap );
|
||||
|
||||
// Handle palettized textures. Need to attach a palette
|
||||
if( ddsd.ddpfPixelFormat.dwRGBBitCount == 8 )
|
||||
{
|
||||
LPDIRECTDRAWPALETTE pPalette;
|
||||
DWORD dwPaletteFlags = DDPCAPS_8BIT|DDPCAPS_ALLOW256;
|
||||
DWORD pe[256];
|
||||
UINT wNumColors = GetDIBColorTable( hdcBitmap, 0, 256, (RGBQUAD*)pe );
|
||||
|
||||
// Create the color table
|
||||
for( WORD i=0; i<wNumColors; i++ )
|
||||
{
|
||||
pe[i] = RGB( GetBValue(pe[i]), GetGValue(pe[i]), GetRValue(pe[i]) );
|
||||
|
||||
// Handle textures with transparent pixels
|
||||
if( m_dwFlags & (D3DTEXTR_TRANSPARENTWHITE|D3DTEXTR_TRANSPARENTBLACK) )
|
||||
{
|
||||
// Set alpha for opaque pixels
|
||||
if( m_dwFlags & D3DTEXTR_TRANSPARENTBLACK )
|
||||
{
|
||||
if( pe[i] != 0x00000000 )
|
||||
pe[i] |= 0xff000000;
|
||||
}
|
||||
else if( m_dwFlags & D3DTEXTR_TRANSPARENTWHITE )
|
||||
{
|
||||
if( pe[i] != 0x00ffffff )
|
||||
pe[i] |= 0xff000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add DDPCAPS_ALPHA flag for textures with transparent pixels
|
||||
if( m_dwFlags & (D3DTEXTR_TRANSPARENTWHITE|D3DTEXTR_TRANSPARENTBLACK) )
|
||||
dwPaletteFlags |= DDPCAPS_ALPHA;
|
||||
|
||||
// Create & attach a palette
|
||||
pDD->CreatePalette( dwPaletteFlags, (PALETTEENTRY*)pe, &pPalette, NULL );
|
||||
pddsTempSurface->SetPalette( pPalette );
|
||||
m_pddsSurface->SetPalette( pPalette );
|
||||
SAFE_RELEASE( pPalette );
|
||||
}
|
||||
|
||||
// Copy the bitmap image to the surface.
|
||||
HDC hdcSurface;
|
||||
if( SUCCEEDED( pddsTempSurface->GetDC( &hdcSurface ) ) )
|
||||
{
|
||||
BitBlt( hdcSurface, 0, 0, bm.bmWidth, bm.bmHeight, hdcBitmap, 0, 0,
|
||||
SRCCOPY );
|
||||
pddsTempSurface->ReleaseDC( hdcSurface );
|
||||
}
|
||||
DeleteDC( hdcBitmap );
|
||||
|
||||
// Copy the temp surface to the real texture surface
|
||||
m_pddsSurface->Blt( NULL, pddsTempSurface, NULL, DDBLT_WAIT, NULL );
|
||||
|
||||
// Done with the temp surface
|
||||
pddsTempSurface->Release();
|
||||
|
||||
// For textures with real alpha (not palettized), set transparent bits
|
||||
if( ddsd.ddpfPixelFormat.dwRGBAlphaBitMask )
|
||||
{
|
||||
if( m_dwFlags & (D3DTEXTR_TRANSPARENTWHITE|D3DTEXTR_TRANSPARENTBLACK) )
|
||||
{
|
||||
// Lock the texture surface
|
||||
DDSURFACEDESC2 ddsd;
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
while( m_pddsSurface->Lock( NULL, &ddsd, 0, NULL ) ==
|
||||
DDERR_WASSTILLDRAWING );
|
||||
|
||||
DWORD dwAlphaMask = ddsd.ddpfPixelFormat.dwRGBAlphaBitMask;
|
||||
DWORD dwRGBMask = ( ddsd.ddpfPixelFormat.dwRBitMask |
|
||||
ddsd.ddpfPixelFormat.dwGBitMask |
|
||||
ddsd.ddpfPixelFormat.dwBBitMask );
|
||||
DWORD dwColorkey = 0x00000000; // Colorkey on black
|
||||
if( m_dwFlags & D3DTEXTR_TRANSPARENTWHITE )
|
||||
dwColorkey = dwRGBMask; // Colorkey on white
|
||||
|
||||
// Add an opaque alpha value to each non-colorkeyed pixel
|
||||
for( DWORD y=0; y<ddsd.dwHeight; y++ )
|
||||
{
|
||||
WORD* p16 = (WORD*)((BYTE*)ddsd.lpSurface + y*ddsd.lPitch);
|
||||
DWORD* p32 = (DWORD*)((BYTE*)ddsd.lpSurface + y*ddsd.lPitch);
|
||||
|
||||
for( DWORD x=0; x<ddsd.dwWidth; x++ )
|
||||
{
|
||||
if( ddsd.ddpfPixelFormat.dwRGBBitCount == 16 )
|
||||
{
|
||||
if( ( *p16 &= dwRGBMask ) != dwColorkey )
|
||||
*p16 |= dwAlphaMask;
|
||||
p16++;
|
||||
}
|
||||
if( ddsd.ddpfPixelFormat.dwRGBBitCount == 32 )
|
||||
{
|
||||
if( ( *p32 &= dwRGBMask ) != dwColorkey )
|
||||
*p32 |= dwAlphaMask;
|
||||
p32++;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_pddsSurface->Unlock( NULL );
|
||||
}
|
||||
}
|
||||
|
||||
pDD->Release();
|
||||
|
||||
return S_OK;;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CopyRGBADataToSurface()
|
||||
// Desc: Invalidates the current texture objects and rebuilds new ones
|
||||
// using the new device.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT TextureContainer::CopyRGBADataToSurface()
|
||||
{
|
||||
// Get a DDraw object to create a temporary surface
|
||||
LPDIRECTDRAW7 pDD;
|
||||
m_pddsSurface->GetDDInterface( (VOID**)&pDD );
|
||||
|
||||
// Setup the new surface desc
|
||||
DDSURFACEDESC2 ddsd;
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
m_pddsSurface->GetSurfaceDesc( &ddsd );
|
||||
ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|
|
||||
DDSD_TEXTURESTAGE;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE|DDSCAPS_SYSTEMMEMORY;
|
||||
ddsd.ddsCaps.dwCaps2 = 0L;
|
||||
ddsd.dwWidth = m_dwWidth;
|
||||
ddsd.dwHeight = m_dwHeight;
|
||||
|
||||
// Create a new surface for the texture
|
||||
LPDIRECTDRAWSURFACE7 pddsTempSurface;
|
||||
HRESULT hr;
|
||||
if( FAILED( hr = pDD->CreateSurface( &ddsd, &pddsTempSurface, NULL ) ) )
|
||||
{
|
||||
pDD->Release();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while( pddsTempSurface->Lock( NULL, &ddsd, 0, 0 ) == DDERR_WASSTILLDRAWING );
|
||||
DWORD lPitch = ddsd.lPitch;
|
||||
BYTE* pBytes = (BYTE*)ddsd.lpSurface;
|
||||
|
||||
DWORD dwRMask = ddsd.ddpfPixelFormat.dwRBitMask;
|
||||
DWORD dwGMask = ddsd.ddpfPixelFormat.dwGBitMask;
|
||||
DWORD dwBMask = ddsd.ddpfPixelFormat.dwBBitMask;
|
||||
DWORD dwAMask = ddsd.ddpfPixelFormat.dwRGBAlphaBitMask;
|
||||
|
||||
DWORD dwRShiftL = 8, dwRShiftR = 0;
|
||||
DWORD dwGShiftL = 8, dwGShiftR = 0;
|
||||
DWORD dwBShiftL = 8, dwBShiftR = 0;
|
||||
DWORD dwAShiftL = 8, dwAShiftR = 0;
|
||||
|
||||
DWORD dwMask;
|
||||
for( dwMask=dwRMask; dwMask && !(dwMask&0x1); dwMask>>=1 ) dwRShiftR++;
|
||||
for( ; dwMask; dwMask>>=1 ) dwRShiftL--;
|
||||
|
||||
for( dwMask=dwGMask; dwMask && !(dwMask&0x1); dwMask>>=1 ) dwGShiftR++;
|
||||
for( ; dwMask; dwMask>>=1 ) dwGShiftL--;
|
||||
|
||||
for( dwMask=dwBMask; dwMask && !(dwMask&0x1); dwMask>>=1 ) dwBShiftR++;
|
||||
for( ; dwMask; dwMask>>=1 ) dwBShiftL--;
|
||||
|
||||
for( dwMask=dwAMask; dwMask && !(dwMask&0x1); dwMask>>=1 ) dwAShiftR++;
|
||||
for( ; dwMask; dwMask>>=1 ) dwAShiftL--;
|
||||
|
||||
for( DWORD y=0; y<ddsd.dwHeight; y++ )
|
||||
{
|
||||
DWORD* pDstData32 = (DWORD*)pBytes;
|
||||
WORD* pDstData16 = (WORD*)pBytes;
|
||||
|
||||
for( DWORD x=0; x<ddsd.dwWidth; x++ )
|
||||
{
|
||||
DWORD dwPixel = m_pRGBAData[y*ddsd.dwWidth+x];
|
||||
|
||||
BYTE r = (BYTE)((dwPixel>>24)&0x000000ff);
|
||||
BYTE g = (BYTE)((dwPixel>>16)&0x000000ff);
|
||||
BYTE b = (BYTE)((dwPixel>> 8)&0x000000ff);
|
||||
BYTE a = (BYTE)((dwPixel>> 0)&0x000000ff);
|
||||
|
||||
DWORD dr = ((r>>(dwRShiftL))<<dwRShiftR)&dwRMask;
|
||||
DWORD dg = ((g>>(dwGShiftL))<<dwGShiftR)&dwGMask;
|
||||
DWORD db = ((b>>(dwBShiftL))<<dwBShiftR)&dwBMask;
|
||||
DWORD da = ((a>>(dwAShiftL))<<dwAShiftR)&dwAMask;
|
||||
|
||||
if( 32 == ddsd.ddpfPixelFormat.dwRGBBitCount )
|
||||
pDstData32[x] = (DWORD)(dr+dg+db+da);
|
||||
else
|
||||
pDstData16[x] = (WORD)(dr+dg+db+da);
|
||||
}
|
||||
|
||||
pBytes += ddsd.lPitch;
|
||||
}
|
||||
|
||||
pddsTempSurface->Unlock(0);
|
||||
|
||||
// Copy the temp surface to the real texture surface
|
||||
m_pddsSurface->Blt( NULL, pddsTempSurface, NULL, DDBLT_WAIT, NULL );
|
||||
|
||||
// Done with the temp objects
|
||||
pddsTempSurface->Release();
|
||||
pDD->Release();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: D3DTextr_SetTexturePath()
|
||||
// Desc: Enumeration callback routine to find a best-matching texture format.
|
||||
//-----------------------------------------------------------------------------
|
||||
VOID D3DTextr_SetTexturePath( TCHAR* strTexturePath )
|
||||
{
|
||||
if( NULL == strTexturePath )
|
||||
strTexturePath = _T("");
|
||||
lstrcpy( g_strTexturePath, strTexturePath );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: D3DTextr_CreateTextureFromFile()
|
||||
// Desc: Is passed a filename and creates a local Bitmap from that file.
|
||||
// The texture can not be used until it is restored, however.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT D3DTextr_CreateTextureFromFile( TCHAR* strName, DWORD dwStage,
|
||||
DWORD dwFlags )
|
||||
{
|
||||
// Check parameters
|
||||
if( NULL == strName )
|
||||
return E_INVALIDARG;
|
||||
|
||||
// Check first to see if the texture is already loaded
|
||||
if( NULL != FindTexture( strName ) )
|
||||
return S_OK;
|
||||
|
||||
// Allocate and add the texture to the linked list of textures;
|
||||
TextureContainer* ptcTexture = new TextureContainer( strName, dwStage,
|
||||
dwFlags );
|
||||
if( NULL == ptcTexture )
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
// Create a bitmap and load the texture file into it,
|
||||
if( FAILED( ptcTexture->LoadImageData() ) )
|
||||
{
|
||||
delete ptcTexture;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Save the image's dimensions
|
||||
if( ptcTexture->m_hbmBitmap )
|
||||
{
|
||||
BITMAP bm;
|
||||
GetObject( ptcTexture->m_hbmBitmap, sizeof(BITMAP), &bm );
|
||||
ptcTexture->m_dwWidth = (DWORD)bm.bmWidth;
|
||||
ptcTexture->m_dwHeight = (DWORD)bm.bmHeight;
|
||||
ptcTexture->m_dwBPP = (DWORD)bm.bmBitsPixel;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: D3DTextr_CreateEmptyTexture()
|
||||
// Desc: Creates an empty texture.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT D3DTextr_CreateEmptyTexture( TCHAR* strName, DWORD dwWidth,
|
||||
DWORD dwHeight, DWORD dwStage,
|
||||
DWORD dwFlags )
|
||||
{
|
||||
// Check parameters
|
||||
if( NULL == strName )
|
||||
return E_INVALIDARG;
|
||||
|
||||
// Check first to see if the texture is already loaded
|
||||
if( NULL != FindTexture( strName ) )
|
||||
return E_FAIL;
|
||||
|
||||
// Allocate and add the texture to the linked list of textures;
|
||||
TextureContainer* ptcTexture = new TextureContainer( strName, dwStage,
|
||||
dwFlags );
|
||||
if( NULL == ptcTexture )
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
// Save dimensions
|
||||
ptcTexture->m_dwWidth = dwWidth;
|
||||
ptcTexture->m_dwHeight = dwHeight;
|
||||
ptcTexture->m_dwBPP = 16;
|
||||
if( ptcTexture->m_dwFlags & D3DTEXTR_32BITSPERPIXEL )
|
||||
ptcTexture->m_dwBPP = 32;
|
||||
|
||||
// Save alpha usage flag
|
||||
if( dwFlags & D3DTEXTR_CREATEWITHALPHA )
|
||||
ptcTexture->m_bHasAlpha = TRUE;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: D3DTextr_Restore()
|
||||
// Desc: Invalidates the current texture objects and rebuilds new ones
|
||||
// using the new device.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT D3DTextr_Restore( TCHAR* strName, LPDIRECT3DDEVICE7 pd3dDevice )
|
||||
{
|
||||
TextureContainer* ptcTexture = FindTexture( strName );
|
||||
if( NULL == ptcTexture )
|
||||
return DDERR_NOTFOUND;
|
||||
|
||||
// Restore the texture (this recreates the new surface for this device).
|
||||
return ptcTexture->Restore( pd3dDevice );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: D3DTextr_RestoreAllTextures()
|
||||
// Desc: This function is called when a mode is changed. It updates all
|
||||
// texture objects to be valid with the new device.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT D3DTextr_RestoreAllTextures( LPDIRECT3DDEVICE7 pd3dDevice )
|
||||
{
|
||||
TextureContainer* ptcTexture = g_ptcTextureList;
|
||||
|
||||
while( ptcTexture )
|
||||
{
|
||||
D3DTextr_Restore( ptcTexture->m_strName, pd3dDevice );
|
||||
ptcTexture = ptcTexture->m_pNext;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: D3DTextr_Invalidate()
|
||||
// Desc: Used to bump a texture out of (video) memory, this function
|
||||
// actually destroys the d3dtexture and ddsurface of the texture
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT D3DTextr_Invalidate( TCHAR* strName )
|
||||
{
|
||||
TextureContainer* ptcTexture = FindTexture( strName );
|
||||
if( NULL == ptcTexture )
|
||||
return DDERR_NOTFOUND;
|
||||
|
||||
SAFE_RELEASE( ptcTexture->m_pddsSurface );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: D3DTextr_InvalidateAllTextures()
|
||||
// Desc: This function is called when a mode is changed. It invalidates
|
||||
// all texture objects so their device can be safely released.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT D3DTextr_InvalidateAllTextures()
|
||||
{
|
||||
TextureContainer* ptcTexture = g_ptcTextureList;
|
||||
|
||||
while( ptcTexture )
|
||||
{
|
||||
SAFE_RELEASE( ptcTexture->m_pddsSurface );
|
||||
ptcTexture = ptcTexture->m_pNext;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: D3DTextr_DestroyTexture()
|
||||
// Desc: Frees the resources for the specified texture container
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT D3DTextr_DestroyTexture( TCHAR* strName )
|
||||
{
|
||||
TextureContainer* ptcTexture = FindTexture( strName );
|
||||
|
||||
SAFE_DELETE( ptcTexture );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: D3DTextr_GetSurface()
|
||||
// Desc: Returns a pointer to a d3dSurface from the name of the texture
|
||||
//-----------------------------------------------------------------------------
|
||||
LPDIRECTDRAWSURFACE7 D3DTextr_GetSurface( TCHAR* strName )
|
||||
{
|
||||
TextureContainer* ptcTexture = FindTexture( strName );
|
||||
|
||||
return ptcTexture ? ptcTexture->m_pddsSurface : NULL;
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: D3DTextr.h
|
||||
//
|
||||
// Desc: Functions to manage textures, including creating (loading from a
|
||||
// file), restoring lost surfaces, invalidating, and destroying.
|
||||
//
|
||||
// Note: the implementation of these functions maintains an internal list
|
||||
// of loaded textures. After creation, individual textures are referenced
|
||||
// via their ASCII names.
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef D3DTEXTR_H
|
||||
#define D3DTEXTR_H
|
||||
#include <ddraw.h>
|
||||
#include <d3d.h>
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Access functions for loaded textures. Note: these functions search
|
||||
// an internal list of the textures, and use the texture associated with the
|
||||
// ASCII name.
|
||||
//-----------------------------------------------------------------------------
|
||||
LPDIRECTDRAWSURFACE7 D3DTextr_GetSurface( TCHAR* strName );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Texture invalidation and restoration functions
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT D3DTextr_Invalidate( TCHAR* strName );
|
||||
HRESULT D3DTextr_Restore( TCHAR* strName, LPDIRECT3DDEVICE7 pd3dDevice );
|
||||
HRESULT D3DTextr_InvalidateAllTextures();
|
||||
HRESULT D3DTextr_RestoreAllTextures( LPDIRECT3DDEVICE7 pd3dDevice );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Texture creation and deletion functions
|
||||
//-----------------------------------------------------------------------------
|
||||
#define D3DTEXTR_TRANSPARENTWHITE 0x00000001
|
||||
#define D3DTEXTR_TRANSPARENTBLACK 0x00000002
|
||||
#define D3DTEXTR_32BITSPERPIXEL 0x00000004
|
||||
#define D3DTEXTR_16BITSPERPIXEL 0x00000008
|
||||
#define D3DTEXTR_CREATEWITHALPHA 0x00000010
|
||||
|
||||
|
||||
HRESULT D3DTextr_CreateTextureFromFile( TCHAR* strName, DWORD dwStage=0L,
|
||||
DWORD dwFlags=0L );
|
||||
HRESULT D3DTextr_CreateEmptyTexture( TCHAR* strName, DWORD dwWidth,
|
||||
DWORD dwHeight, DWORD dwStage,
|
||||
DWORD dwFlags );
|
||||
HRESULT D3DTextr_DestroyTexture( TCHAR* strName );
|
||||
VOID D3DTextr_SetTexturePath( TCHAR* strTexturePath );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: TextureContainer
|
||||
// Desc: Linked list structure to hold info per texture
|
||||
//-----------------------------------------------------------------------------
|
||||
struct TextureContainer
|
||||
{
|
||||
TextureContainer* m_pNext; // Linked list ptr
|
||||
|
||||
TCHAR m_strName[MAX_PATH]; // Name of texture (doubles as image filename)
|
||||
DWORD m_dwWidth;
|
||||
DWORD m_dwHeight;
|
||||
DWORD m_dwStage; // Texture stage (for multitexture devices)
|
||||
DWORD m_dwBPP;
|
||||
DWORD m_dwFlags;
|
||||
BOOL m_bHasAlpha;
|
||||
UINT m_nRes;
|
||||
|
||||
LPDIRECTDRAWSURFACE7 m_pddsSurface; // Surface of the texture
|
||||
HBITMAP m_hbmBitmap; // Bitmap containing texture image
|
||||
DWORD* m_pRGBAData;
|
||||
|
||||
public:
|
||||
HRESULT LoadImageData();
|
||||
HRESULT LoadBitmapFile( TCHAR* strPathname );
|
||||
HRESULT Restore( LPDIRECT3DDEVICE7 pd3dDevice );
|
||||
HRESULT CopyBitmapToSurface();
|
||||
HRESULT CopyRGBADataToSurface();
|
||||
|
||||
TextureContainer( TCHAR* strName, DWORD dwStage, DWORD dwFlags, UINT nRes = NULL );
|
||||
~TextureContainer();
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // D3DTEXTR_H
|
||||
@@ -0,0 +1,302 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: D3DUtil.cpp
|
||||
//
|
||||
// Desc: Shortcut macros and functions for using DX objects
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <streams.h>
|
||||
|
||||
#define D3D_OVERLOADS
|
||||
#include <math.h>
|
||||
#include "D3DUtil.h"
|
||||
|
||||
#ifndef _T
|
||||
#define _T TEXT
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: D3DUtil_GetDXSDKMediaPath()
|
||||
// Desc: Returns the DirectX SDK media path, as stored in the system registry
|
||||
// during the SDK install.
|
||||
//-----------------------------------------------------------------------------
|
||||
const TCHAR* D3DUtil_GetDXSDKMediaPath()
|
||||
{
|
||||
static TCHAR strNull[2] = _T("");
|
||||
static TCHAR strPath[512];
|
||||
HKEY key;
|
||||
DWORD type, size = 512;
|
||||
|
||||
// Open the appropriate registry key
|
||||
LONG result = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
||||
_T("Software\\Microsoft\\DirectX"),
|
||||
0, KEY_READ, &key );
|
||||
if( ERROR_SUCCESS != result )
|
||||
return strNull;
|
||||
|
||||
result = RegQueryValueEx( key, _T("DX81SDK Samples Path"), NULL,
|
||||
&type, (BYTE*)strPath, &size );
|
||||
RegCloseKey( key );
|
||||
|
||||
if( ERROR_SUCCESS != result )
|
||||
{
|
||||
result = RegQueryValueEx( key, _T("DX8SDK Samples Path"), NULL,
|
||||
&type, (BYTE*)strPath, &size );
|
||||
RegCloseKey( key );
|
||||
|
||||
if( ERROR_SUCCESS != result )
|
||||
{
|
||||
result = RegQueryValueEx( key, _T("DXSDK Samples Path"), NULL,
|
||||
&type, (BYTE*)strPath, &size );
|
||||
RegCloseKey( key );
|
||||
|
||||
if( ERROR_SUCCESS != result )
|
||||
return strNull;
|
||||
}
|
||||
}
|
||||
|
||||
lstrcat( strPath, _T("\\D3DIM\\Media\\") );
|
||||
|
||||
return strPath;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: D3DUtil_InitSurfaceDesc()
|
||||
// Desc: Helper function called to build a DDSURFACEDESC2 structure,
|
||||
// typically before calling CreateSurface() or GetSurfaceDesc()
|
||||
//-----------------------------------------------------------------------------
|
||||
VOID D3DUtil_InitSurfaceDesc( DDSURFACEDESC2& ddsd, DWORD dwFlags,
|
||||
DWORD dwCaps )
|
||||
{
|
||||
ZeroMemory( &ddsd, sizeof(ddsd) );
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
ddsd.dwFlags = dwFlags;
|
||||
ddsd.ddsCaps.dwCaps = dwCaps;
|
||||
ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: D3DUtil_InitMaterial()
|
||||
// Desc: Helper function called to build a D3DMATERIAL7 structure
|
||||
//-----------------------------------------------------------------------------
|
||||
VOID D3DUtil_InitMaterial( D3DMATERIAL7& mtrl, FLOAT r, FLOAT g, FLOAT b,
|
||||
FLOAT a )
|
||||
{
|
||||
ZeroMemory( &mtrl, sizeof(D3DMATERIAL7) );
|
||||
mtrl.dcvDiffuse.r = mtrl.dcvAmbient.r = r;
|
||||
mtrl.dcvDiffuse.g = mtrl.dcvAmbient.g = g;
|
||||
mtrl.dcvDiffuse.b = mtrl.dcvAmbient.b = b;
|
||||
mtrl.dcvDiffuse.a = mtrl.dcvAmbient.a = a;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: D3DUtil_InitLight()
|
||||
// Desc: Initializes a D3DLIGHT7 structure
|
||||
//-----------------------------------------------------------------------------
|
||||
VOID D3DUtil_InitLight( D3DLIGHT7& light, D3DLIGHTTYPE ltType,
|
||||
FLOAT x, FLOAT y, FLOAT z )
|
||||
{
|
||||
ZeroMemory( &light, sizeof(D3DLIGHT7) );
|
||||
light.dltType = ltType;
|
||||
light.dcvDiffuse.r = 1.0f;
|
||||
light.dcvDiffuse.g = 1.0f;
|
||||
light.dcvDiffuse.b = 1.0f;
|
||||
light.dcvSpecular = light.dcvDiffuse;
|
||||
light.dvPosition.x = light.dvDirection.x = x;
|
||||
light.dvPosition.y = light.dvDirection.y = y;
|
||||
light.dvPosition.z = light.dvDirection.z = z;
|
||||
light.dvAttenuation0 = 1.0f;
|
||||
light.dvRange = D3DLIGHT_RANGE_MAX;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: D3DUtil_SetViewMatrix()
|
||||
// Desc: Given an eye point, a lookat point, and an up vector, this
|
||||
// function builds a 4x4 view matrix.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT D3DUtil_SetViewMatrix( D3DMATRIX& mat, D3DVECTOR& vFrom,
|
||||
D3DVECTOR& vAt, D3DVECTOR& vWorldUp )
|
||||
{
|
||||
// Get the z basis vector, which points straight ahead. This is the
|
||||
// difference from the eyepoint to the lookat point.
|
||||
D3DVECTOR vView = vAt - vFrom;
|
||||
|
||||
FLOAT fLength = Magnitude( vView );
|
||||
if( fLength < 1e-6f )
|
||||
return E_INVALIDARG;
|
||||
|
||||
// Normalize the z basis vector
|
||||
vView /= fLength;
|
||||
|
||||
// Get the dot product, and calculate the projection of the z basis
|
||||
// vector onto the up vector. The projection is the y basis vector.
|
||||
FLOAT fDotProduct = DotProduct( vWorldUp, vView );
|
||||
|
||||
D3DVECTOR vUp = vWorldUp - fDotProduct * vView;
|
||||
|
||||
// If this vector has near-zero length because the input specified a
|
||||
// bogus up vector, let's try a default up vector
|
||||
if( 1e-6f > ( fLength = Magnitude( vUp ) ) )
|
||||
{
|
||||
vUp = D3DVECTOR( 0.0f, 1.0f, 0.0f ) - vView.y * vView;
|
||||
|
||||
// If we still have near-zero length, resort to a different axis.
|
||||
if( 1e-6f > ( fLength = Magnitude( vUp ) ) )
|
||||
{
|
||||
vUp = D3DVECTOR( 0.0f, 0.0f, 1.0f ) - vView.z * vView;
|
||||
|
||||
if( 1e-6f > ( fLength = Magnitude( vUp ) ) )
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
|
||||
// Normalize the y basis vector
|
||||
vUp /= fLength;
|
||||
|
||||
// The x basis vector is found simply with the cross product of the y
|
||||
// and z basis vectors
|
||||
D3DVECTOR vRight = CrossProduct( vUp, vView );
|
||||
|
||||
// Start building the matrix. The first three rows contains the basis
|
||||
// vectors used to rotate the view to point at the lookat point
|
||||
D3DUtil_SetIdentityMatrix( mat );
|
||||
mat._11 = vRight.x; mat._12 = vUp.x; mat._13 = vView.x;
|
||||
mat._21 = vRight.y; mat._22 = vUp.y; mat._23 = vView.y;
|
||||
mat._31 = vRight.z; mat._32 = vUp.z; mat._33 = vView.z;
|
||||
|
||||
// Do the translation values (rotations are still about the eyepoint)
|
||||
mat._41 = - DotProduct( vFrom, vRight );
|
||||
mat._42 = - DotProduct( vFrom, vUp );
|
||||
mat._43 = - DotProduct( vFrom, vView );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: D3DUtil_SetProjectionMatrix()
|
||||
// Desc: Sets the passed in 4x4 matrix to a perpsective projection matrix built
|
||||
// from the field-of-view (fov, in y), aspect ratio, near plane (D),
|
||||
// and far plane (F). Note that the projection matrix is normalized for
|
||||
// element [3][4] to be 1.0. This is performed so that W-based range fog
|
||||
// will work correctly.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT D3DUtil_SetProjectionMatrix( D3DMATRIX& mat, FLOAT fFOV, FLOAT fAspect,
|
||||
FLOAT fNearPlane, FLOAT fFarPlane )
|
||||
{
|
||||
if( fabs(fFarPlane-fNearPlane) < 0.01f )
|
||||
return E_INVALIDARG;
|
||||
if( fabs(sin(fFOV/2)) < 0.01f )
|
||||
return E_INVALIDARG;
|
||||
|
||||
FLOAT w = fAspect * ( cosf(fFOV/2)/sinf(fFOV/2) );
|
||||
FLOAT h = 1.0f * ( cosf(fFOV/2)/sinf(fFOV/2) );
|
||||
FLOAT Q = fFarPlane / ( fFarPlane - fNearPlane );
|
||||
|
||||
ZeroMemory( &mat, sizeof(D3DMATRIX) );
|
||||
mat._11 = w;
|
||||
mat._22 = h;
|
||||
mat._33 = Q;
|
||||
mat._34 = 1.0f;
|
||||
mat._43 = -Q*fNearPlane;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: D3DUtil_SetRotateXMatrix()
|
||||
// Desc: Create Rotation matrix about X axis
|
||||
//-----------------------------------------------------------------------------
|
||||
VOID D3DUtil_SetRotateXMatrix( D3DMATRIX& mat, FLOAT fRads )
|
||||
{
|
||||
D3DUtil_SetIdentityMatrix( mat );
|
||||
mat._22 = cosf( fRads );
|
||||
mat._23 = sinf( fRads );
|
||||
mat._32 = -sinf( fRads );
|
||||
mat._33 = cosf( fRads );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: D3DUtil_SetRotateYMatrix()
|
||||
// Desc: Create Rotation matrix about Y axis
|
||||
//-----------------------------------------------------------------------------
|
||||
VOID D3DUtil_SetRotateYMatrix( D3DMATRIX& mat, FLOAT fRads )
|
||||
{
|
||||
D3DUtil_SetIdentityMatrix( mat );
|
||||
mat._11 = cosf( fRads );
|
||||
mat._13 = -sinf( fRads );
|
||||
mat._31 = sinf( fRads );
|
||||
mat._33 = cosf( fRads );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: D3DUtil_SetRotateZMatrix()
|
||||
// Desc: Create Rotation matrix about Z axis
|
||||
//-----------------------------------------------------------------------------
|
||||
VOID D3DUtil_SetRotateZMatrix( D3DMATRIX& mat, FLOAT fRads )
|
||||
{
|
||||
D3DUtil_SetIdentityMatrix( mat );
|
||||
mat._11 = cosf( fRads );
|
||||
mat._12 = sinf( fRads );
|
||||
mat._21 = -sinf( fRads );
|
||||
mat._22 = cosf( fRads );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: D3DUtil_SetRotationMatrix
|
||||
// Desc: Create a Rotation matrix about vector direction
|
||||
//-----------------------------------------------------------------------------
|
||||
VOID D3DUtil_SetRotationMatrix( D3DMATRIX& mat, D3DVECTOR& vDir, FLOAT fRads )
|
||||
{
|
||||
FLOAT fCos = cosf( fRads );
|
||||
FLOAT fSin = sinf( fRads );
|
||||
D3DVECTOR v = Normalize( vDir );
|
||||
|
||||
mat._11 = ( v.x * v.x ) * ( 1.0f - fCos ) + fCos;
|
||||
mat._12 = ( v.x * v.y ) * ( 1.0f - fCos ) - (v.z * fSin);
|
||||
mat._13 = ( v.x * v.z ) * ( 1.0f - fCos ) + (v.y * fSin);
|
||||
|
||||
mat._21 = ( v.y * v.x ) * ( 1.0f - fCos ) + (v.z * fSin);
|
||||
mat._22 = ( v.y * v.y ) * ( 1.0f - fCos ) + fCos ;
|
||||
mat._23 = ( v.y * v.z ) * ( 1.0f - fCos ) - (v.x * fSin);
|
||||
|
||||
mat._31 = ( v.z * v.x ) * ( 1.0f - fCos ) - (v.y * fSin);
|
||||
mat._32 = ( v.z * v.y ) * ( 1.0f - fCos ) + (v.x * fSin);
|
||||
mat._33 = ( v.z * v.z ) * ( 1.0f - fCos ) + fCos;
|
||||
|
||||
mat._14 = mat._24 = mat._34 = 0.0f;
|
||||
mat._41 = mat._42 = mat._43 = 0.0f;
|
||||
mat._44 = 1.0f;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: _DbgOut()
|
||||
// Desc: Outputs a message to the debug stream
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT _DbgOut( CHAR* strFile, DWORD dwLine, HRESULT hr, TCHAR* strMsg )
|
||||
{
|
||||
TCHAR buffer[256];
|
||||
wsprintf( buffer, _T("%hs(%ld): "), strFile, dwLine );
|
||||
OutputDebugString( buffer );
|
||||
OutputDebugString( strMsg );
|
||||
|
||||
if( hr )
|
||||
{
|
||||
wsprintf( buffer, _T("(hr=%08lx)\n"), hr );
|
||||
OutputDebugString( buffer );
|
||||
}
|
||||
|
||||
OutputDebugString( _T("\n") );
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: D3DUtil.h
|
||||
//
|
||||
// Desc: Helper functions and typing shortcuts for Direct3D programming.
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef D3DUTIL_H
|
||||
#define D3DUTIL_H
|
||||
#include <ddraw.h>
|
||||
#include <d3d.h>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Miscellaneous helper functions
|
||||
//-----------------------------------------------------------------------------
|
||||
const TCHAR* D3DUtil_GetDXSDKMediaPath();
|
||||
|
||||
#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
|
||||
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Shortcut functions for creating and using DX structures
|
||||
//-----------------------------------------------------------------------------
|
||||
VOID D3DUtil_InitDeviceDesc( D3DDEVICEDESC7& ddDevDesc );
|
||||
VOID D3DUtil_InitSurfaceDesc( DDSURFACEDESC2& ddsd, DWORD dwFlags=0,
|
||||
DWORD dwCaps=0 );
|
||||
VOID D3DUtil_InitMaterial( D3DMATERIAL7& mtrl, FLOAT r=0.0f, FLOAT g=0.0f,
|
||||
FLOAT b=0.0f, FLOAT a=1.0f );
|
||||
VOID D3DUtil_InitLight( D3DLIGHT7& light, D3DLIGHTTYPE ltType,
|
||||
FLOAT x=0.0f, FLOAT y=0.0f, FLOAT z=0.0f );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// D3D Matrix functions. For performance reasons, some functions are inline.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT D3DUtil_SetViewMatrix( D3DMATRIX& mat, D3DVECTOR& vFrom,
|
||||
D3DVECTOR& vAt, D3DVECTOR& vUp );
|
||||
HRESULT D3DUtil_SetProjectionMatrix( D3DMATRIX& mat, FLOAT fFOV = 1.570795f,
|
||||
FLOAT fAspect = 1.0f,
|
||||
FLOAT fNearPlane = 1.0f,
|
||||
FLOAT fFarPlane = 1000.0f );
|
||||
|
||||
inline VOID D3DUtil_SetIdentityMatrix( D3DMATRIX& m )
|
||||
{
|
||||
m._12 = m._13 = m._14 = m._21 = m._23 = m._24 = 0.0f;
|
||||
m._31 = m._32 = m._34 = m._41 = m._42 = m._43 = 0.0f;
|
||||
m._11 = m._22 = m._33 = m._44 = 1.0f;
|
||||
}
|
||||
|
||||
inline VOID D3DUtil_SetTranslateMatrix( D3DMATRIX& m, FLOAT tx, FLOAT ty,
|
||||
FLOAT tz )
|
||||
{ D3DUtil_SetIdentityMatrix( m ); m._41 = tx; m._42 = ty; m._43 = tz; }
|
||||
|
||||
inline VOID D3DUtil_SetTranslateMatrix( D3DMATRIX& m, D3DVECTOR& v )
|
||||
{ D3DUtil_SetTranslateMatrix( m, v.x, v.y, v.z ); }
|
||||
|
||||
inline VOID D3DUtil_SetScaleMatrix( D3DMATRIX& m, FLOAT sx, FLOAT sy,
|
||||
FLOAT sz )
|
||||
{ D3DUtil_SetIdentityMatrix( m ); m._11 = sx; m._22 = sy; m._33 = sz; }
|
||||
|
||||
inline VOID SetScaleMatrix( D3DMATRIX& m, D3DVECTOR& v )
|
||||
{ D3DUtil_SetScaleMatrix( m, v.x, v.y, v.z ); }
|
||||
|
||||
VOID D3DUtil_SetRotateXMatrix( D3DMATRIX& mat, FLOAT fRads );
|
||||
VOID D3DUtil_SetRotateYMatrix( D3DMATRIX& mat, FLOAT fRads );
|
||||
VOID D3DUtil_SetRotateZMatrix( D3DMATRIX& mat, FLOAT fRads );
|
||||
VOID D3DUtil_SetRotationMatrix( D3DMATRIX& mat, D3DVECTOR& vDir,
|
||||
FLOAT fRads );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Debug printing support
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
HRESULT _DbgOut( CHAR*, DWORD, HRESULT, TCHAR* );
|
||||
|
||||
#if defined(DEBUG) | defined(_DEBUG)
|
||||
#define DEBUG_MSG(str) _DbgOut( __FILE__, (DWORD)__LINE__, 0, str )
|
||||
#define DEBUG_ERR(hr,str) _DbgOut( __FILE__, (DWORD)__LINE__, hr, str )
|
||||
#else
|
||||
#define DEBUG_MSG(str) (0L)
|
||||
#define DEBUG_ERR(hr,str) (hr)
|
||||
#endif
|
||||
|
||||
|
||||
#endif // D3DUTIL_H
|
||||
@@ -0,0 +1,59 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// File: project.h
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Master header file that includes all the other header files
|
||||
// used by the project.
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------------------
|
||||
#include <streams.h>
|
||||
#include <commdlg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <process.h>
|
||||
#include <time.h>
|
||||
#include <objbase.h>
|
||||
#include <ddraw.h>
|
||||
#include <atlbase.h>
|
||||
#include <atlconv.cpp>
|
||||
#include <mmreg.h>
|
||||
#include <commctrl.h>
|
||||
#include <strmif.h>
|
||||
#include <combase.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <uuids.h>
|
||||
|
||||
|
||||
#include "app.h"
|
||||
#include "vcdplyer.h"
|
||||
#include "ddrawsupport.h"
|
||||
#include "resource.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
#ifndef __RELEASE_DEFINED
|
||||
#define __RELEASE_DEFINED
|
||||
template<typename T>
|
||||
__inline void RELEASE( T* &p )
|
||||
{
|
||||
if( p ) {
|
||||
p->Release();
|
||||
p = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CHECK_HR
|
||||
#define CHECK_HR(expr) if (FAILED(expr)) {\
|
||||
OutputDebugString( hresultNameLookup(expr)+"\n");\
|
||||
DbgLog((LOG_ERROR, 0, \
|
||||
TEXT("FAILED: %s\nat Line:%d of %s"), \
|
||||
TEXT(#expr), __LINE__, TEXT(__FILE__) ));__leave; } else
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
// Copyright (c) 1995 - 2001 Microsoft Corporation. All Rights Reserved.
|
||||
//
|
||||
// These are indexes used by the toolbar.
|
||||
//
|
||||
#define IDC_ADEFAULT2 4013
|
||||
#define IDC_STATIC -1
|
||||
|
||||
#define STR_MAX_STRING_LEN 256
|
||||
|
||||
#define IDX_SEPARATOR -1
|
||||
#define IDX_1 0
|
||||
#define IDX_2 1
|
||||
#define IDX_3 2
|
||||
#define IDX_4 3
|
||||
#define IDX_5 4
|
||||
#define IDX_6 5
|
||||
#define IDX_7 6
|
||||
#define IDX_8 7
|
||||
#define IDX_9 8
|
||||
#define IDX_10 9
|
||||
#define IDX_11 10
|
||||
#define DEFAULT_TBAR_SIZE 6
|
||||
#define NUMBER_OF_BITMAPS 11
|
||||
|
||||
#define ID_TOOLBAR 9
|
||||
#define ID_TRACKBAR 10
|
||||
|
||||
#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
|
||||
|
||||
// Toolbar commands
|
||||
#define IDM_MOVIE_STOP 40010
|
||||
#define IDM_MOVIE_PLAY 40011
|
||||
#define IDM_MOVIE_PAUSE 40013
|
||||
#define IDM_FULL_SCREEN 40019
|
||||
|
||||
#define IDM_MOVIE_ALIGN 40020
|
||||
|
||||
#define MENU_STRING_BASE 1000
|
||||
|
||||
// File
|
||||
#define STR_FILE_OPEN IDM_FILE_OPEN + MENU_STRING_BASE
|
||||
#define STR_FILE_CLOSE IDM_FILE_CLOSE + MENU_STRING_BASE
|
||||
#define STR_FILE_EXIT IDM_FILE_EXIT + MENU_STRING_BASE
|
||||
|
||||
// System Menu
|
||||
#define STR_SYSMENU_RESTORE 1800
|
||||
#define STR_SYSMENU_MOVE 1801
|
||||
#define STR_SYSMENU_MINIMIZE 1802
|
||||
#define STR_SYSMENU_CLOSE 1803
|
||||
#define STR_SYSMENU_MAXIMIZE 1804
|
||||
#define STR_SYSMENU_TASK_LIST 1805
|
||||
|
||||
#define STR_FILE_FILTER 2000
|
||||
#define STR_APP_TITLE 2001
|
||||
#define STR_APP_TITLE_LOADED 2002
|
||||
@@ -0,0 +1,18 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by VMRXcl.rc
|
||||
//
|
||||
#define IDB_MENU 102
|
||||
#define IDI_ICON1 103
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NO_MFC 1
|
||||
#define _APS_NEXT_RESOURCE_VALUE 104
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,504 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// File: vcdplyer.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Implementation of CMpegMovie, a customized video player
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------------------
|
||||
#include "project.h"
|
||||
#include <mmreg.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define MY_USER_ID 0x1234ACDE
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// CMpegMovie
|
||||
//
|
||||
// Constructors and destructors
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
CMpegMovie::CMpegMovie(HWND hwndApplication)
|
||||
: CUnknown(NAME("Allocator Presenter"), NULL),
|
||||
m_hwndApp(hwndApplication),
|
||||
m_MediaEvent(NULL),
|
||||
m_Mode(MOVIE_NOTOPENED),
|
||||
m_pBF(NULL),
|
||||
m_Fg(NULL),
|
||||
m_Gb(NULL),
|
||||
m_Mc(NULL),
|
||||
m_Ms(NULL),
|
||||
m_Me(NULL),
|
||||
m_Qp(NULL),
|
||||
m_lpDefSAN(NULL),
|
||||
m_iDuration(-1),
|
||||
m_TimeFormat(TIME_FORMAT_MEDIA_TIME),
|
||||
m_lpDefWC(NULL),
|
||||
m_lpDefIP(NULL),
|
||||
m_lpDefSA(NULL),
|
||||
m_AlphaBlt(NULL)
|
||||
|
||||
{
|
||||
AddRef();
|
||||
}
|
||||
|
||||
CMpegMovie::~CMpegMovie() {
|
||||
;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SetRenderingMode
|
||||
//
|
||||
// Set rendering mode of VMR (Windowless, Windowed, Renderless)
|
||||
//----------------------------------------------------------------------------
|
||||
HRESULT
|
||||
SetRenderingMode(
|
||||
IBaseFilter* pBaseFilter,
|
||||
VMRMode mode
|
||||
)
|
||||
{
|
||||
IVMRFilterConfig* pConfig;
|
||||
HRESULT hr = pBaseFilter->QueryInterface(__uuidof(IVMRFilterConfig),
|
||||
(LPVOID *)&pConfig);
|
||||
|
||||
if( SUCCEEDED( hr )) {
|
||||
pConfig->SetRenderingMode( mode );
|
||||
pConfig->Release();
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CMpegMovie::AllocateAlphaBlt(void)
|
||||
{
|
||||
HRESULT hRes=S_OK;
|
||||
|
||||
m_AlphaBlt = new CAlphaBlt(m_pDDObject.GetBB(), &hRes);
|
||||
return hRes;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// AddVideoMixingRendererToFG()
|
||||
//
|
||||
// creates and adds VMR to the graph
|
||||
//----------------------------------------------------------------------------
|
||||
HRESULT
|
||||
CMpegMovie::AddVideoMixingRendererToFG()
|
||||
{
|
||||
HRESULT hRes = S_OK;
|
||||
|
||||
m_AlphaBlt = NULL;
|
||||
|
||||
__try {
|
||||
CHECK_HR(hRes = m_pDDObject.Initialize(m_hwndApp));
|
||||
|
||||
CHECK_HR(hRes = CoCreateInstance(CLSID_VideoMixingRenderer,
|
||||
NULL, CLSCTX_INPROC,IID_IBaseFilter,
|
||||
(LPVOID *)&m_pBF));
|
||||
|
||||
CHECK_HR(hRes = m_Fg->AddFilter(m_pBF, L"Video Mixing Renderer"));
|
||||
|
||||
CHECK_HR(hRes = SetRenderingMode(m_pBF, VMRMode_Renderless));
|
||||
|
||||
CHECK_HR(hRes = m_pBF->QueryInterface(__uuidof(IVMRSurfaceAllocatorNotify),
|
||||
(LPVOID *)&m_lpDefSAN));
|
||||
|
||||
hRes = AllocateAlphaBlt();
|
||||
if (FAILED(hRes)) {
|
||||
__leave;
|
||||
}
|
||||
|
||||
|
||||
CHECK_HR(hRes = CreateDefaultAllocatorPresenter(m_pDDObject.GetDDObj(),
|
||||
m_pDDObject.GetBB()));
|
||||
|
||||
CHECK_HR(hRes = m_lpDefSAN->AdviseSurfaceAllocator(MY_USER_ID, this));
|
||||
}
|
||||
__finally {
|
||||
|
||||
if (FAILED(hRes)) {
|
||||
delete m_AlphaBlt;
|
||||
m_AlphaBlt= NULL;
|
||||
m_pDDObject.Terminate();
|
||||
}
|
||||
}
|
||||
|
||||
return hRes;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// OpenMovie
|
||||
//
|
||||
// creates the graph, adds VMR, QIs relevant interfaces and renders the file
|
||||
//----------------------------------------------------------------------------
|
||||
HRESULT
|
||||
CMpegMovie::OpenMovie(
|
||||
TCHAR *lpFileName
|
||||
)
|
||||
{
|
||||
IUnknown *pUnk = NULL;
|
||||
HRESULT hres = S_OK;
|
||||
|
||||
WCHAR FileName[MAX_PATH];
|
||||
|
||||
#ifdef UNICODE
|
||||
lstrcpy(FileName, lpFileName);
|
||||
#else
|
||||
// wsprintfA((char*)FileName, "%hs", lpFileName);
|
||||
MultiByteToWideChar(CP_ACP,0,(const char*) lpFileName, -1, FileName, MAX_PATH);
|
||||
#endif
|
||||
|
||||
__try {
|
||||
CHECK_HR(hres = CoCreateInstance(CLSID_FilterGraph,
|
||||
NULL, CLSCTX_INPROC,
|
||||
IID_IUnknown, (LPVOID *)&pUnk));
|
||||
m_Mode = MOVIE_OPENED;
|
||||
CHECK_HR(hres = pUnk->QueryInterface(IID_IFilterGraph, (LPVOID *)&m_Fg));
|
||||
CHECK_HR(hres = AddVideoMixingRendererToFG());
|
||||
CHECK_HR(hres = pUnk->QueryInterface(IID_IGraphBuilder, (LPVOID *)&m_Gb));
|
||||
CHECK_HR(hres = m_Gb->RenderFile(FileName, NULL));
|
||||
CHECK_HR(hres = pUnk->QueryInterface(IID_IMediaControl, (LPVOID *)&m_Mc));
|
||||
CHECK_HR(hres = m_pBF->QueryInterface(IID_IQualProp, (LPVOID*)&m_Qp));
|
||||
|
||||
//
|
||||
// Not being able to get the IMediaEvent interface does
|
||||
// necessarly mean that we can't play the graph.
|
||||
//
|
||||
HRESULT hr = pUnk->QueryInterface(IID_IMediaEvent, (LPVOID *)&m_Me);
|
||||
GetMovieEventHandle();
|
||||
pUnk->QueryInterface(IID_IMediaSeeking, (LPVOID *)&m_Ms);
|
||||
|
||||
}
|
||||
__finally {
|
||||
|
||||
if (FAILED(hres)) {
|
||||
RELEASE(m_Ms);
|
||||
RELEASE(m_Me);
|
||||
RELEASE(m_Mc);
|
||||
RELEASE(m_Gb);
|
||||
RELEASE(m_Fg);
|
||||
|
||||
m_pDDObject.Terminate();
|
||||
}
|
||||
|
||||
RELEASE(pUnk);
|
||||
}
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// CloseMovie
|
||||
//
|
||||
// Releases client-provided allocator-presenter, exits sxclusive mode
|
||||
//----------------------------------------------------------------------------
|
||||
DWORD
|
||||
CMpegMovie::CloseMovie(
|
||||
)
|
||||
{
|
||||
m_Mode = MOVIE_NOTOPENED;
|
||||
|
||||
RELEASE(m_Qp);
|
||||
RELEASE(m_Mc);
|
||||
RELEASE(m_Me);
|
||||
RELEASE(m_Ms);
|
||||
RELEASE(m_Gb);
|
||||
RELEASE(m_Fg);
|
||||
|
||||
if (m_lpDefSAN) {
|
||||
m_lpDefSAN->AdviseSurfaceAllocator(0, NULL);
|
||||
m_lpDefSAN->Release();
|
||||
}
|
||||
|
||||
RELEASE(m_pBF);
|
||||
RELEASE(m_lpDefWC);
|
||||
RELEASE(m_lpDefSA);
|
||||
RELEASE(m_lpDefIP);
|
||||
|
||||
delete m_AlphaBlt;
|
||||
m_pDDObject.Terminate();
|
||||
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// RepaintVideo
|
||||
//----------------------------------------------------------------------------
|
||||
BOOL
|
||||
CMpegMovie::RepaintVideo(
|
||||
HWND hwnd,
|
||||
HDC hdc
|
||||
)
|
||||
{
|
||||
BOOL bRet = FALSE;
|
||||
if (m_lpDefWC) {
|
||||
bRet = (m_lpDefWC->RepaintVideo(hwnd, hdc) == S_OK);
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// PutMoviePosition
|
||||
//----------------------------------------------------------------------------
|
||||
BOOL
|
||||
CMpegMovie::PutMoviePosition(
|
||||
LONG x,
|
||||
LONG y,
|
||||
LONG cx,
|
||||
LONG cy
|
||||
)
|
||||
{
|
||||
HRESULT hr;
|
||||
BOOL bRet = FALSE;
|
||||
|
||||
if (m_lpDefWC) {
|
||||
RECT rc;
|
||||
SetRect(&rc, x, y, x + cx, y + cy);
|
||||
hr = m_lpDefWC->SetVideoPosition(NULL, &rc);
|
||||
bRet = (hr == S_OK);
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// PlayMovie
|
||||
//
|
||||
// Just runs IMediaControl
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
BOOL
|
||||
CMpegMovie::PlayMovie(
|
||||
)
|
||||
{
|
||||
REFTIME rt;
|
||||
REFTIME rtAbs;
|
||||
REFTIME rtDur;
|
||||
|
||||
rt = GetCurrentPosition();
|
||||
rtDur = GetDuration();
|
||||
|
||||
//
|
||||
// If we are near the end of the movie seek to the start, otherwise
|
||||
// stay where we are.
|
||||
//
|
||||
rtAbs = rt - rtDur;
|
||||
if (rtAbs < (REFTIME)0) {
|
||||
rtAbs = -rtAbs;
|
||||
}
|
||||
|
||||
if (rtAbs <= (REFTIME)1) {
|
||||
SeekToPosition((REFTIME)0,FALSE);
|
||||
}
|
||||
|
||||
//
|
||||
// Change mode after setting m_Mode but before starting the graph
|
||||
//
|
||||
m_Mode = MOVIE_PLAYING;
|
||||
HRESULT hr = m_Mc->Run();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// PauseMovie
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
BOOL
|
||||
CMpegMovie::PauseMovie(
|
||||
)
|
||||
{
|
||||
m_Mode = MOVIE_PAUSED;
|
||||
m_Mc->Pause();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// GetStateMovie
|
||||
//
|
||||
// returns state of the media control (running, paused, or stopped)
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
OAFilterState
|
||||
CMpegMovie::GetStateMovie(
|
||||
)
|
||||
{
|
||||
OAFilterState State=0;
|
||||
if (m_Mc)
|
||||
m_Mc->GetState(INFINITE,&State);
|
||||
return State;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// StopMovie
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
BOOL
|
||||
CMpegMovie::StopMovie(
|
||||
)
|
||||
{
|
||||
m_Mode = MOVIE_STOPPED;
|
||||
m_Mc->Stop();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// GetMediaEventHandle
|
||||
//
|
||||
// Returns the IMediaEvent event handle for the filter graph iff the
|
||||
// filter graph exists.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
HANDLE
|
||||
CMpegMovie::GetMovieEventHandle(
|
||||
)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if (m_Me != NULL) {
|
||||
|
||||
if ( m_MediaEvent == NULL) {
|
||||
hr = m_Me->GetEventHandle((OAEVENT *)&m_MediaEvent);
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_MediaEvent = NULL;
|
||||
}
|
||||
return m_MediaEvent;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// GetMovieEventCode
|
||||
//
|
||||
// Retrieves notification events from the graph through IMediaEvent interface
|
||||
//----------------------------------------------------------------------------
|
||||
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)) {
|
||||
return lEventCode;
|
||||
}
|
||||
}
|
||||
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// GetDuration
|
||||
//
|
||||
// Returns the duration of the current movie
|
||||
// NOTE that time format may vary with different media types
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
REFTIME
|
||||
CMpegMovie::GetDuration()
|
||||
{
|
||||
HRESULT hr;
|
||||
LONGLONG Duration;
|
||||
|
||||
// Should we seek using IMediaSelection
|
||||
|
||||
if (m_Ms != NULL && m_TimeFormat != TIME_FORMAT_MEDIA_TIME) {
|
||||
hr = m_Ms->GetDuration(&Duration);
|
||||
if (SUCCEEDED(hr)) {
|
||||
return double(Duration);
|
||||
}
|
||||
} else if (m_Ms != NULL) {
|
||||
hr = m_Ms->GetDuration(&Duration);
|
||||
if (SUCCEEDED(hr)) {
|
||||
return double(Duration) / UNITS;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// GetCurrentPosition
|
||||
//
|
||||
// Returns the duration of the current movie
|
||||
// NOTE that time format may vary with different media types
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
REFTIME
|
||||
CMpegMovie::GetCurrentPosition()
|
||||
{
|
||||
REFTIME rt = (REFTIME)0;
|
||||
HRESULT hr;
|
||||
LONGLONG Position;
|
||||
|
||||
// Should we return a media position
|
||||
|
||||
if (m_Ms != NULL && m_TimeFormat != TIME_FORMAT_MEDIA_TIME) {
|
||||
hr = m_Ms->GetPositions(&Position, NULL);
|
||||
if (SUCCEEDED(hr)) {
|
||||
return double(Position);
|
||||
}
|
||||
} else if (m_Ms != NULL) {
|
||||
hr = m_Ms->GetPositions(&Position, NULL);
|
||||
if (SUCCEEDED(hr)) {
|
||||
return double(Position) / UNITS;
|
||||
}
|
||||
}
|
||||
return rt;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SeekToPosition
|
||||
//
|
||||
// NOTE that time format may vary with different media types
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// File: vcdplyer.h
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Prototype for CMpegMovie, a customized video player
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------------------
|
||||
#include <ddraw.h>
|
||||
#define D3D_OVERLOADS
|
||||
#include <d3d.h>
|
||||
|
||||
#include "DDrawSupport.h"
|
||||
#include "BltAlpha.h"
|
||||
#include "d3dtextr.h"
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** CMpegMovie - a movie playback class.
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
enum EMpegMovieMode { MOVIE_NOTOPENED = 0x00,
|
||||
MOVIE_OPENED = 0x01,
|
||||
MOVIE_PLAYING = 0x02,
|
||||
MOVIE_STOPPED = 0x03,
|
||||
MOVIE_PAUSED = 0x04 };
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------\
|
||||
// CMpegMovie
|
||||
//
|
||||
// A customized video player for exclusive DDraw mode. In fact, it is a
|
||||
// user-provided Allocator-Presenter for VMR
|
||||
//----------------------------------------------------------------------------
|
||||
class CMpegMovie :
|
||||
public CUnknown,
|
||||
public IVMRSurfaceAllocator,
|
||||
public IVMRImagePresenter,
|
||||
public IVMRSurfaceAllocatorNotify
|
||||
{
|
||||
|
||||
private:
|
||||
// Our state variable - records whether we are opened, playing etc.
|
||||
EMpegMovieMode m_Mode;
|
||||
HANDLE m_MediaEvent;
|
||||
HWND m_hwndApp;
|
||||
int m_iDuration;
|
||||
GUID m_TimeFormat;
|
||||
|
||||
CDDrawObject m_pDDObject;
|
||||
CAlphaBlt* m_AlphaBlt;
|
||||
LPDIRECTDRAWSURFACE7 m_lpSurf;
|
||||
|
||||
IBaseFilter* m_pBF; // ptr to the VMR
|
||||
IFilterGraph* m_Fg;
|
||||
IGraphBuilder* m_Gb;
|
||||
IMediaControl* m_Mc;
|
||||
IMediaSeeking* m_Ms;
|
||||
IMediaEvent* m_Me;
|
||||
IQualProp* m_Qp;
|
||||
|
||||
|
||||
IVMRSurfaceAllocator* m_lpDefSA;
|
||||
IVMRImagePresenter* m_lpDefIP;
|
||||
IVMRWindowlessControl* m_lpDefWC;
|
||||
IVMRSurfaceAllocatorNotify* m_lpDefSAN;
|
||||
|
||||
|
||||
HRESULT CreateDefaultAllocatorPresenter(LPDIRECTDRAW7 lpDD, LPDIRECTDRAWSURFACE7 lpPS);
|
||||
HRESULT AddVideoMixingRendererToFG();
|
||||
HRESULT OnSetDDrawDevice(LPDIRECTDRAW7 pDD, HMONITOR hMon);
|
||||
HRESULT AllocateAlphaBlt(void);
|
||||
|
||||
public:
|
||||
CMpegMovie(HWND hwndApplication);
|
||||
~CMpegMovie();
|
||||
|
||||
DECLARE_IUNKNOWN
|
||||
STDMETHODIMP NonDelegatingQueryInterface(REFIID, void**);
|
||||
|
||||
// IVMRSurfaceAllocator
|
||||
STDMETHODIMP AllocateSurface(DWORD_PTR dwUserID,
|
||||
VMRALLOCATIONINFO* lpAllocInfo,
|
||||
DWORD* lpdwActualBackBuffers,
|
||||
LPDIRECTDRAWSURFACE7* lplpSurface);
|
||||
STDMETHODIMP FreeSurface(DWORD_PTR dwUserID);
|
||||
STDMETHODIMP PrepareSurface(DWORD_PTR dwUserID,
|
||||
LPDIRECTDRAWSURFACE7 lplpSurface,
|
||||
DWORD dwSurfaceFlags);
|
||||
STDMETHODIMP AdviseNotify(IVMRSurfaceAllocatorNotify* lpIVMRSurfAllocNotify);
|
||||
|
||||
// IVMRSurfaceAllocatorNotify
|
||||
STDMETHODIMP AdviseSurfaceAllocator(DWORD_PTR dwUserID,
|
||||
IVMRSurfaceAllocator* lpIVRMSurfaceAllocator);
|
||||
STDMETHODIMP SetDDrawDevice(LPDIRECTDRAW7 lpDDrawDevice,HMONITOR hMonitor);
|
||||
STDMETHODIMP ChangeDDrawDevice(LPDIRECTDRAW7 lpDDrawDevice,HMONITOR hMonitor);
|
||||
STDMETHODIMP RestoreDDrawSurfaces();
|
||||
STDMETHODIMP NotifyEvent(LONG EventCode, LONG_PTR lp1, LONG_PTR lp2);
|
||||
STDMETHODIMP SetBorderColor(COLORREF clr);
|
||||
|
||||
|
||||
// IVMRImagePresenter
|
||||
STDMETHODIMP StartPresenting(DWORD_PTR dwUserID);
|
||||
STDMETHODIMP StopPresenting(DWORD_PTR dwUserID);
|
||||
STDMETHODIMP PresentImage(DWORD_PTR dwUserID,
|
||||
VMRPRESENTATIONINFO* lpPresInfo);
|
||||
|
||||
|
||||
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);
|
||||
|
||||
REFTIME GetDuration();
|
||||
REFTIME GetCurrentPosition();
|
||||
BOOL SeekToPosition(REFTIME rt,BOOL bFlushData);
|
||||
|
||||
BOOL RepaintVideo(HWND hwnd, HDC hdc);
|
||||
|
||||
void DisplayModeChanged() {
|
||||
if (m_lpDefWC) {
|
||||
m_lpDefWC->DisplayModeChanged();
|
||||
}
|
||||
}
|
||||
IVMRWindowlessControl* GetWLC() {
|
||||
return m_lpDefWC;
|
||||
}
|
||||
|
||||
void GetPerformance( void);
|
||||
};
|
||||
Reference in New Issue
Block a user