1
|
After Width: | Height: | Size: 900 KiB |
BIN
utils/xbox/xbox_loader/LoaderMedia_Source/LegalScreen_french.tga
Normal file
|
After Width: | Height: | Size: 900 KiB |
BIN
utils/xbox/xbox_loader/LoaderMedia_Source/LegalScreen_german.tga
Normal file
|
After Width: | Height: | Size: 900 KiB |
|
After Width: | Height: | Size: 900 KiB |
|
After Width: | Height: | Size: 900 KiB |
BIN
utils/xbox/xbox_loader/LoaderMedia_Source/LoadingIcon.tga
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
utils/xbox/xbox_loader/LoaderMedia_Source/SourceScreen.tga
Normal file
|
After Width: | Height: | Size: 900 KiB |
BIN
utils/xbox/xbox_loader/LoaderMedia_Source/Tahoma_16.abc
Normal file
BIN
utils/xbox/xbox_loader/LoaderMedia_Source/Tahoma_16.tga
Normal file
|
After Width: | Height: | Size: 512 KiB |
BIN
utils/xbox/xbox_loader/LoaderMedia_Source/footer.tga
Normal file
|
After Width: | Height: | Size: 128 KiB |
BIN
utils/xbox/xbox_loader/LoaderMedia_Source/loader_icon.bmp
Normal file
|
After Width: | Height: | Size: 48 KiB |
@@ -0,0 +1,7 @@
|
||||
Texture MyTex
|
||||
{
|
||||
Source loader_icon.bmp
|
||||
Format D3DFMT_DXT1
|
||||
Width 128
|
||||
Height 128
|
||||
}
|
||||
BIN
utils/xbox/xbox_loader/LoaderMedia_Source/slideshow1_english.tga
Normal file
|
After Width: | Height: | Size: 900 KiB |
BIN
utils/xbox/xbox_loader/LoaderMedia_Source/slideshow1_french.tga
Normal file
|
After Width: | Height: | Size: 900 KiB |
BIN
utils/xbox/xbox_loader/LoaderMedia_Source/slideshow1_german.tga
Normal file
|
After Width: | Height: | Size: 900 KiB |
BIN
utils/xbox/xbox_loader/LoaderMedia_Source/slideshow1_italian.tga
Normal file
|
After Width: | Height: | Size: 900 KiB |
BIN
utils/xbox/xbox_loader/LoaderMedia_Source/slideshow1_spanish.tga
Normal file
|
After Width: | Height: | Size: 900 KiB |
BIN
utils/xbox/xbox_loader/LoaderMedia_Source/slideshow2.tga
Normal file
|
After Width: | Height: | Size: 900 KiB |
BIN
utils/xbox/xbox_loader/LoaderMedia_Source/slideshow3.tga
Normal file
|
After Width: | Height: | Size: 900 KiB |
BIN
utils/xbox/xbox_loader/LoaderMedia_Source/slideshow4.tga
Normal file
|
After Width: | Height: | Size: 900 KiB |
BIN
utils/xbox/xbox_loader/LoaderMedia_Source/slideshow5.tga
Normal file
|
After Width: | Height: | Size: 900 KiB |
BIN
utils/xbox/xbox_loader/LoaderMedia_Source/slideshow6.tga
Normal file
|
After Width: | Height: | Size: 900 KiB |
BIN
utils/xbox/xbox_loader/LoaderMedia_Source/slideshow7.tga
Normal file
|
After Width: | Height: | Size: 900 KiB |
BIN
utils/xbox/xbox_loader/LoaderMedia_Source/slideshow8.tga
Normal file
|
After Width: | Height: | Size: 900 KiB |
BIN
utils/xbox/xbox_loader/LoaderMedia_Source/slideshow9.tga
Normal file
|
After Width: | Height: | Size: 900 KiB |
173
utils/xbox/xbox_loader/loader.rdf
Normal file
@@ -0,0 +1,173 @@
|
||||
// List of resources to bundle.
|
||||
//
|
||||
// The output will be a header file (.h) used at compile time,
|
||||
// and a packed resource file (.xpr) used at runtime.
|
||||
|
||||
out_packedresource LoaderMedia\loader.xpr
|
||||
out_error loader.err
|
||||
|
||||
Texture Font
|
||||
{
|
||||
Source LoaderMedia_Source\Tahoma_16.tga
|
||||
Format D3DFMT_A4R4G4B4
|
||||
Levels 1
|
||||
}
|
||||
|
||||
UserData FontData
|
||||
{
|
||||
DataFile LoaderMedia_Source\Tahoma_16.abc
|
||||
}
|
||||
|
||||
Texture Footer
|
||||
{
|
||||
Source LoaderMedia_Source\Footer.tga
|
||||
Format D3DFMT_LIN_A8R8G8B8
|
||||
Levels 1
|
||||
}
|
||||
|
||||
Texture MainLegal_english
|
||||
{
|
||||
Source LoaderMedia_Source\LegalScreen_english.tga
|
||||
Format D3DFMT_LIN_A8R8G8B8
|
||||
Levels 1
|
||||
}
|
||||
|
||||
Texture MainLegal_french
|
||||
{
|
||||
Source LoaderMedia_Source\LegalScreen_french.tga
|
||||
Format D3DFMT_LIN_A8R8G8B8
|
||||
Levels 1
|
||||
}
|
||||
|
||||
Texture MainLegal_italian
|
||||
{
|
||||
Source LoaderMedia_Source\LegalScreen_italian.tga
|
||||
Format D3DFMT_LIN_A8R8G8B8
|
||||
Levels 1
|
||||
}
|
||||
|
||||
Texture MainLegal_german
|
||||
{
|
||||
Source LoaderMedia_Source\LegalScreen_german.tga
|
||||
Format D3DFMT_LIN_A8R8G8B8
|
||||
Levels 1
|
||||
}
|
||||
|
||||
Texture MainLegal_spanish
|
||||
{
|
||||
Source LoaderMedia_Source\LegalScreen_spanish.tga
|
||||
Format D3DFMT_LIN_A8R8G8B8
|
||||
Levels 1
|
||||
}
|
||||
|
||||
Texture SourceLegal
|
||||
{
|
||||
Source LoaderMedia_Source\SourceScreen.tga
|
||||
Format D3DFMT_LIN_A8R8G8B8
|
||||
Levels 1
|
||||
}
|
||||
|
||||
Texture LoadingIcon
|
||||
{
|
||||
Source LoaderMedia_Source\LoadingIcon.tga
|
||||
Format D3DFMT_LIN_A8R8G8B8
|
||||
Levels 1
|
||||
}
|
||||
|
||||
Texture SlideShow1_english
|
||||
{
|
||||
Source LoaderMedia_Source\SlideShow1_english.tga
|
||||
Format D3DFMT_LIN_A8R8G8B8
|
||||
Levels 1
|
||||
}
|
||||
|
||||
Texture SlideShow1_french
|
||||
{
|
||||
Source LoaderMedia_Source\SlideShow1_french.tga
|
||||
Format D3DFMT_LIN_A8R8G8B8
|
||||
Levels 1
|
||||
}
|
||||
|
||||
Texture SlideShow1_italian
|
||||
{
|
||||
Source LoaderMedia_Source\SlideShow1_italian.tga
|
||||
Format D3DFMT_LIN_A8R8G8B8
|
||||
Levels 1
|
||||
}
|
||||
|
||||
Texture SlideShow1_german
|
||||
{
|
||||
Source LoaderMedia_Source\SlideShow1_german.tga
|
||||
Format D3DFMT_LIN_A8R8G8B8
|
||||
Levels 1
|
||||
}
|
||||
|
||||
Texture SlideShow1_spanish
|
||||
{
|
||||
Source LoaderMedia_Source\SlideShow1_spanish.tga
|
||||
Format D3DFMT_LIN_A8R8G8B8
|
||||
Levels 1
|
||||
}
|
||||
|
||||
Texture SlideShow2
|
||||
{
|
||||
Source LoaderMedia_Source\SlideShow2.tga
|
||||
Format D3DFMT_LIN_A8R8G8B8
|
||||
Levels 1
|
||||
}
|
||||
|
||||
Texture SlideShow3
|
||||
{
|
||||
Source LoaderMedia_Source\SlideShow3.tga
|
||||
Format D3DFMT_LIN_A8R8G8B8
|
||||
Levels 1
|
||||
}
|
||||
|
||||
Texture SlideShow4
|
||||
{
|
||||
Source LoaderMedia_Source\SlideShow4.tga
|
||||
Format D3DFMT_LIN_A8R8G8B8
|
||||
Levels 1
|
||||
}
|
||||
|
||||
Texture SlideShow5
|
||||
{
|
||||
Source LoaderMedia_Source\SlideShow5.tga
|
||||
Format D3DFMT_LIN_A8R8G8B8
|
||||
Levels 1
|
||||
}
|
||||
|
||||
Texture SlideShow6
|
||||
{
|
||||
Source LoaderMedia_Source\SlideShow6.tga
|
||||
Format D3DFMT_LIN_A8R8G8B8
|
||||
Levels 1
|
||||
}
|
||||
|
||||
Texture SlideShow7
|
||||
{
|
||||
Source LoaderMedia_Source\SlideShow7.tga
|
||||
Format D3DFMT_LIN_A8R8G8B8
|
||||
Levels 1
|
||||
}
|
||||
|
||||
Texture SlideShow8
|
||||
{
|
||||
Source LoaderMedia_Source\SlideShow8.tga
|
||||
Format D3DFMT_LIN_A8R8G8B8
|
||||
Levels 1
|
||||
}
|
||||
|
||||
Texture SlideShow9
|
||||
{
|
||||
Source LoaderMedia_Source\SlideShow9.tga
|
||||
Format D3DFMT_LIN_A8R8G8B8
|
||||
Levels 1
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
595
utils/xbox/xbox_loader/xbox_fileCopy.cpp
Normal file
@@ -0,0 +1,595 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Copies a file using overlapped async IO.
|
||||
//
|
||||
// Stub executeable
|
||||
//=====================================================================================//
|
||||
#include "xbox_loader.h"
|
||||
|
||||
#define BUFFER_SIZE (1*1024*1024)
|
||||
#define NUM_BUFFERS 4
|
||||
#define ALIGN(x,y) (((x)+(y)-1) & ~((y)-1))
|
||||
|
||||
struct CopyFile_t
|
||||
{
|
||||
// source file
|
||||
HANDLE m_hSrcFile;
|
||||
DWORD m_srcFileSize;
|
||||
int m_readBufferSize;
|
||||
unsigned int m_numReadCycles;
|
||||
|
||||
// target file
|
||||
HANDLE m_hDstFile;
|
||||
DWORD m_dstFileSize;
|
||||
|
||||
// source file gets decompressed
|
||||
bool m_bInflate;
|
||||
unsigned char *m_pInflateBuffer;
|
||||
int m_inflateBufferSize;
|
||||
|
||||
bool m_bCopyError;
|
||||
CopyStats_t *m_pCopyStats;
|
||||
};
|
||||
|
||||
struct Buffer_t
|
||||
{
|
||||
unsigned char *pData;
|
||||
DWORD dwSize;
|
||||
Buffer_t* pNext;
|
||||
int id;
|
||||
};
|
||||
|
||||
Buffer_t *g_pReadBuffers = NULL;
|
||||
Buffer_t *g_pWriteBuffers = NULL;
|
||||
|
||||
CRITICAL_SECTION g_criticalSection;
|
||||
HANDLE g_hReadEvent;
|
||||
HANDLE g_hWriteEvent;
|
||||
DWORD *g_pNumReadBuffers;
|
||||
DWORD *g_pNumWriteBuffers;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CreateFilePath
|
||||
//
|
||||
// Create full path to specified file.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CreateFilePath( const char *inPath )
|
||||
{
|
||||
char* ptr;
|
||||
char dirPath[MAX_PATH];
|
||||
BOOL bSuccess;
|
||||
|
||||
// prime and skip to first seperator after the drive path
|
||||
strcpy( dirPath, inPath );
|
||||
ptr = strchr( dirPath, '\\' );
|
||||
while ( ptr )
|
||||
{
|
||||
ptr = strchr( ptr+1, '\\' );
|
||||
if ( ptr )
|
||||
{
|
||||
*ptr = '\0';
|
||||
bSuccess = ::CreateDirectory( dirPath, NULL );
|
||||
*ptr = '\\';
|
||||
}
|
||||
}
|
||||
|
||||
// ensure read-only is cleared
|
||||
SetFileAttributes( inPath, FILE_ATTRIBUTE_NORMAL );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LockBufferForRead
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
Buffer_t *LockBufferForRead()
|
||||
{
|
||||
if ( !g_pReadBuffers )
|
||||
{
|
||||
// out of data, wait for it
|
||||
WaitForSingleObject( g_hReadEvent, INFINITE );
|
||||
}
|
||||
else
|
||||
{
|
||||
ResetEvent( g_hReadEvent );
|
||||
}
|
||||
|
||||
EnterCriticalSection( &g_criticalSection );
|
||||
|
||||
Buffer_t *pBuffer = g_pReadBuffers;
|
||||
g_pReadBuffers = pBuffer->pNext;
|
||||
|
||||
(*g_pNumReadBuffers)--;
|
||||
|
||||
LeaveCriticalSection( &g_criticalSection );
|
||||
|
||||
return pBuffer;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LockBufferForWrite
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
Buffer_t* LockBufferForWrite()
|
||||
{
|
||||
if ( !g_pWriteBuffers )
|
||||
{
|
||||
// out of data, wait for more
|
||||
WaitForSingleObject( g_hWriteEvent, INFINITE );
|
||||
}
|
||||
else
|
||||
{
|
||||
ResetEvent( g_hWriteEvent );
|
||||
}
|
||||
|
||||
EnterCriticalSection( &g_criticalSection );
|
||||
|
||||
Buffer_t *pBuffer = g_pWriteBuffers;
|
||||
g_pWriteBuffers = pBuffer->pNext;
|
||||
|
||||
(*g_pNumWriteBuffers)--;
|
||||
|
||||
LeaveCriticalSection( &g_criticalSection );
|
||||
|
||||
return pBuffer;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// AddBufferForRead
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void AddBufferForRead( Buffer_t *pBuffer )
|
||||
{
|
||||
EnterCriticalSection( &g_criticalSection );
|
||||
|
||||
// add to end of list
|
||||
Buffer_t *pCurrent = g_pReadBuffers;
|
||||
while ( pCurrent && pCurrent->pNext )
|
||||
{
|
||||
pCurrent = pCurrent->pNext;
|
||||
}
|
||||
if ( pCurrent )
|
||||
{
|
||||
pBuffer->pNext = pCurrent->pNext;
|
||||
pCurrent->pNext = pBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
pBuffer->pNext = NULL;
|
||||
g_pReadBuffers = pBuffer;
|
||||
}
|
||||
|
||||
(*g_pNumReadBuffers)++;
|
||||
|
||||
LeaveCriticalSection( &g_criticalSection );
|
||||
|
||||
SetEvent( g_hReadEvent );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// AddBufferForWrite
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void AddBufferForWrite( Buffer_t *pBuffer )
|
||||
{
|
||||
EnterCriticalSection( &g_criticalSection );
|
||||
|
||||
// add to end of list
|
||||
Buffer_t* pCurrent = g_pWriteBuffers;
|
||||
while ( pCurrent && pCurrent->pNext )
|
||||
{
|
||||
pCurrent = pCurrent->pNext;
|
||||
}
|
||||
if ( pCurrent )
|
||||
{
|
||||
pBuffer->pNext = pCurrent->pNext;
|
||||
pCurrent->pNext = pBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
pBuffer->pNext = NULL;
|
||||
g_pWriteBuffers = pBuffer;
|
||||
}
|
||||
|
||||
(*g_pNumWriteBuffers)++;
|
||||
|
||||
LeaveCriticalSection( &g_criticalSection );
|
||||
|
||||
SetEvent( g_hWriteEvent );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ReadFileThread
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
DWORD WINAPI ReadFileThread( LPVOID lParam )
|
||||
{
|
||||
CopyFile_t *pCopyFile;
|
||||
OVERLAPPED overlappedRead = {0};
|
||||
DWORD startTime;
|
||||
DWORD dwBytesRead;
|
||||
DWORD dwError;
|
||||
BOOL bResult;
|
||||
Buffer_t *pBuffer;
|
||||
|
||||
pCopyFile = (CopyFile_t*)lParam;
|
||||
|
||||
// Copy from the buffer to the Hard Drive
|
||||
for ( unsigned int readCycle = 0; readCycle < pCopyFile->m_numReadCycles; ++readCycle )
|
||||
{
|
||||
pBuffer = LockBufferForRead();
|
||||
|
||||
startTime = GetTickCount();
|
||||
dwBytesRead = 0;
|
||||
|
||||
int numAttempts = 0;
|
||||
retry:
|
||||
// read file from DVD
|
||||
bResult = ReadFile( pCopyFile->m_hSrcFile, pBuffer->pData, pCopyFile->m_readBufferSize, NULL, &overlappedRead );
|
||||
dwError = GetLastError();
|
||||
if ( !bResult && dwError != ERROR_IO_PENDING )
|
||||
{
|
||||
if ( dwError == ERROR_HANDLE_EOF )
|
||||
{
|
||||
// nothing more to read
|
||||
break;
|
||||
}
|
||||
|
||||
numAttempts++;
|
||||
if ( numAttempts == 3 )
|
||||
{
|
||||
// error
|
||||
pCopyFile->m_bCopyError = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wait for the operation to finish
|
||||
GetOverlappedResult( pCopyFile->m_hSrcFile, &overlappedRead, &dwBytesRead, TRUE );
|
||||
overlappedRead.Offset += dwBytesRead;
|
||||
}
|
||||
|
||||
if ( !dwBytesRead )
|
||||
{
|
||||
pCopyFile->m_bCopyError = true;
|
||||
break;
|
||||
}
|
||||
|
||||
pCopyFile->m_pCopyStats->m_bufferReadSize = dwBytesRead;
|
||||
pCopyFile->m_pCopyStats->m_bufferReadTime = GetTickCount() - startTime;
|
||||
pCopyFile->m_pCopyStats->m_totalReadSize += pCopyFile->m_pCopyStats->m_bufferReadSize;
|
||||
pCopyFile->m_pCopyStats->m_totalReadTime += pCopyFile->m_pCopyStats->m_bufferReadTime;
|
||||
|
||||
pBuffer->dwSize = dwBytesRead;
|
||||
AddBufferForWrite( pBuffer );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// WriteFileThread
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
DWORD WINAPI WriteFileThread( LPVOID lParam )
|
||||
{
|
||||
CopyFile_t *pCopyFile;
|
||||
OVERLAPPED overlappedWrite = {0};
|
||||
DWORD startTime;
|
||||
DWORD dwBytesWrite;
|
||||
DWORD dwWriteSize;
|
||||
DWORD dwError;
|
||||
BOOL bResult;
|
||||
Buffer_t *pBuffer;
|
||||
unsigned char *pWriteBuffer;
|
||||
|
||||
pCopyFile = (CopyFile_t*)lParam;
|
||||
|
||||
while ( overlappedWrite.Offset < pCopyFile->m_dstFileSize )
|
||||
{
|
||||
// wait for wake-up event
|
||||
pBuffer = LockBufferForWrite();
|
||||
|
||||
if ( pCopyFile->m_bInflate )
|
||||
{
|
||||
startTime = GetTickCount();
|
||||
|
||||
DWORD dwSkip = overlappedWrite.Offset ? 0 : sizeof( xCompressHeader );
|
||||
dwWriteSize = JCALG1_Decompress_Formatted_Buffer( pBuffer->dwSize - dwSkip, pBuffer->pData + dwSkip, pCopyFile->m_inflateBufferSize, pCopyFile->m_pInflateBuffer );
|
||||
if ( dwWriteSize == (DWORD)-1 )
|
||||
{
|
||||
pCopyFile->m_bCopyError = true;
|
||||
break;
|
||||
}
|
||||
|
||||
pCopyFile->m_pCopyStats->m_inflateSize = dwWriteSize;
|
||||
pCopyFile->m_pCopyStats->m_inflateTime = GetTickCount() - startTime;
|
||||
|
||||
pWriteBuffer = pCopyFile->m_pInflateBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
// straight copy
|
||||
dwWriteSize = pBuffer->dwSize;
|
||||
pWriteBuffer = pBuffer->pData;
|
||||
}
|
||||
|
||||
if ( overlappedWrite.Offset + dwWriteSize >= pCopyFile->m_dstFileSize )
|
||||
{
|
||||
// last buffer, ensure all data is written
|
||||
dwWriteSize = ALIGN( dwWriteSize, 512 );
|
||||
}
|
||||
|
||||
startTime = GetTickCount();
|
||||
dwBytesWrite = 0;
|
||||
|
||||
int numAttempts = 0;
|
||||
retry:
|
||||
// write file to HDD
|
||||
bResult = WriteFile( pCopyFile->m_hDstFile, pWriteBuffer, (dwWriteSize/512) * 512, NULL, &overlappedWrite );
|
||||
dwError = GetLastError();
|
||||
if ( !bResult && dwError != ERROR_IO_PENDING )
|
||||
{
|
||||
numAttempts++;
|
||||
if ( numAttempts == 3 )
|
||||
{
|
||||
// error
|
||||
pCopyFile->m_bCopyError = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wait for the operation to finish
|
||||
GetOverlappedResult( pCopyFile->m_hDstFile, &overlappedWrite, &dwBytesWrite, TRUE );
|
||||
overlappedWrite.Offset += dwBytesWrite;
|
||||
}
|
||||
|
||||
if ( dwBytesWrite )
|
||||
{
|
||||
// track expected size
|
||||
pCopyFile->m_pCopyStats->m_bytesCopied += dwBytesWrite;
|
||||
pCopyFile->m_pCopyStats->m_writeSize += dwBytesWrite;
|
||||
}
|
||||
else
|
||||
{
|
||||
pCopyFile->m_bCopyError = true;
|
||||
break;
|
||||
}
|
||||
|
||||
pCopyFile->m_pCopyStats->m_bufferWriteSize = dwBytesWrite;
|
||||
pCopyFile->m_pCopyStats->m_bufferWriteTime = GetTickCount() - startTime;
|
||||
pCopyFile->m_pCopyStats->m_totalWriteSize += pCopyFile->m_pCopyStats->m_bufferWriteSize;
|
||||
pCopyFile->m_pCopyStats->m_totalWriteTime += pCopyFile->m_pCopyStats->m_bufferWriteTime;
|
||||
|
||||
AddBufferForRead( pBuffer );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CopyFileInit
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CopyFileInit()
|
||||
{
|
||||
static bool init = false;
|
||||
if ( !init )
|
||||
{
|
||||
InitializeCriticalSection( &g_criticalSection );
|
||||
g_hReadEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
|
||||
g_hWriteEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
|
||||
init = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// expected startup state
|
||||
ResetEvent( g_hReadEvent );
|
||||
ResetEvent( g_hWriteEvent );
|
||||
|
||||
g_pReadBuffers = NULL;
|
||||
g_pWriteBuffers = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CopyFileOverlapped
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CopyFileOverlapped( const char *pSrcFilename, const char *pDstFilename, xCompressHeader *pxcHeader, CopyStats_t *pCopyStats )
|
||||
{
|
||||
CopyFile_t copyFile = {0};
|
||||
Buffer_t buffers[NUM_BUFFERS] = {0};
|
||||
HANDLE hReadThread = NULL;
|
||||
HANDLE hWriteThread = NULL;
|
||||
bool bSuccess = false;
|
||||
DWORD startCopyTime;
|
||||
DWORD dwResult;
|
||||
int i;
|
||||
|
||||
startCopyTime = GetTickCount();
|
||||
|
||||
CopyFileInit();
|
||||
|
||||
g_pNumReadBuffers = &pCopyStats->m_numReadBuffers;
|
||||
g_pNumWriteBuffers = &pCopyStats->m_numWriteBuffers;
|
||||
|
||||
strcpy( pCopyStats->m_srcFilename, pSrcFilename );
|
||||
strcpy( pCopyStats->m_dstFilename, pDstFilename );
|
||||
|
||||
copyFile.m_hSrcFile = INVALID_HANDLE_VALUE;
|
||||
copyFile.m_hDstFile = INVALID_HANDLE_VALUE;
|
||||
copyFile.m_pCopyStats = pCopyStats;
|
||||
copyFile.m_bCopyError = false;
|
||||
|
||||
// validate the source file
|
||||
copyFile.m_hSrcFile = CreateFile( pSrcFilename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED|FILE_FLAG_NO_BUFFERING, NULL );
|
||||
if ( copyFile.m_hSrcFile == INVALID_HANDLE_VALUE )
|
||||
{
|
||||
// failure
|
||||
goto cleanUp;
|
||||
}
|
||||
|
||||
copyFile.m_srcFileSize = GetFileSize( copyFile.m_hSrcFile, NULL );
|
||||
if ( copyFile.m_srcFileSize == (DWORD)-1 )
|
||||
{
|
||||
// failure
|
||||
goto cleanUp;
|
||||
}
|
||||
|
||||
// ensure the target file path exists
|
||||
CreateFilePath( pDstFilename );
|
||||
|
||||
// validate the target file
|
||||
copyFile.m_hDstFile = CreateFile( pDstFilename, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED|FILE_FLAG_NO_BUFFERING, NULL );
|
||||
if ( copyFile.m_hDstFile == INVALID_HANDLE_VALUE )
|
||||
{
|
||||
// failure
|
||||
goto cleanUp;
|
||||
}
|
||||
|
||||
pCopyStats->m_readSize = copyFile.m_srcFileSize;
|
||||
pCopyStats->m_writeSize = 0;
|
||||
|
||||
if ( pxcHeader )
|
||||
{
|
||||
// read in chunks of compressed blocks
|
||||
copyFile.m_readBufferSize = pxcHeader->nReadBlockSize;
|
||||
copyFile.m_dstFileSize = pxcHeader->nUncompressedFileSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
// setup for copy
|
||||
copyFile.m_readBufferSize = BUFFER_SIZE;
|
||||
copyFile.m_dstFileSize = copyFile.m_srcFileSize;
|
||||
}
|
||||
|
||||
// setup read buffers
|
||||
for ( i=0; i<NUM_BUFFERS; i++)
|
||||
{
|
||||
buffers[i].pData = new unsigned char[copyFile.m_readBufferSize];
|
||||
buffers[i].dwSize = 0;
|
||||
buffers[i].pNext = NULL;
|
||||
AddBufferForRead( &buffers[i] );
|
||||
}
|
||||
copyFile.m_numReadCycles = (copyFile.m_srcFileSize + copyFile.m_readBufferSize - 1)/copyFile.m_readBufferSize;
|
||||
|
||||
// setup write buffer
|
||||
if ( pxcHeader )
|
||||
{
|
||||
copyFile.m_pInflateBuffer = new unsigned char[pxcHeader->nDecompressionBufferSize];
|
||||
copyFile.m_inflateBufferSize = pxcHeader->nDecompressionBufferSize;
|
||||
copyFile.m_bInflate = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
copyFile.m_bInflate = false;
|
||||
}
|
||||
|
||||
// pre-size the target file in aligned buffers
|
||||
DWORD dwAligned = ALIGN( copyFile.m_dstFileSize, 512 );
|
||||
dwResult = SetFilePointer( copyFile.m_hDstFile, dwAligned, NULL, FILE_BEGIN );
|
||||
if ( dwResult == INVALID_SET_FILE_POINTER )
|
||||
{
|
||||
// failure
|
||||
goto cleanUp;
|
||||
}
|
||||
SetEndOfFile( copyFile.m_hDstFile );
|
||||
|
||||
// start the read thread
|
||||
hReadThread = CreateThread( 0, 0, &ReadFileThread, ©File, 0, 0 );
|
||||
if ( !hReadThread )
|
||||
{
|
||||
// failure
|
||||
goto cleanUp;
|
||||
}
|
||||
|
||||
// wait for buffers to populate
|
||||
|
||||
// start the write thread
|
||||
hWriteThread = CreateThread( 0, 0, &WriteFileThread, ©File, 0, 0 );
|
||||
if ( !hWriteThread )
|
||||
{
|
||||
// failure
|
||||
goto cleanUp;
|
||||
}
|
||||
|
||||
// wait for write thread to finish
|
||||
WaitForSingleObject( hWriteThread, INFINITE );
|
||||
WaitForSingleObject( hReadThread, INFINITE );
|
||||
|
||||
if ( copyFile.m_bCopyError )
|
||||
{
|
||||
goto cleanUp;
|
||||
}
|
||||
|
||||
// Fixup the file size
|
||||
CloseHandle( copyFile.m_hDstFile );
|
||||
copyFile.m_hDstFile = INVALID_HANDLE_VALUE;
|
||||
|
||||
if ( copyFile.m_dstFileSize % 512 )
|
||||
{
|
||||
// re-open file as non-buffered to adjust to correct file size
|
||||
HANDLE hFile = CreateFile( pDstFilename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
|
||||
SetFilePointer( hFile, copyFile.m_dstFileSize, NULL, FILE_BEGIN );
|
||||
SetEndOfFile( hFile );
|
||||
CloseHandle( hFile );
|
||||
}
|
||||
|
||||
// finished
|
||||
bSuccess = true;
|
||||
|
||||
cleanUp:
|
||||
if ( copyFile.m_hSrcFile != INVALID_HANDLE_VALUE )
|
||||
{
|
||||
CloseHandle( copyFile.m_hSrcFile );
|
||||
}
|
||||
|
||||
if ( copyFile.m_hDstFile != INVALID_HANDLE_VALUE )
|
||||
{
|
||||
CloseHandle( copyFile.m_hDstFile );
|
||||
}
|
||||
|
||||
if ( hReadThread )
|
||||
{
|
||||
CloseHandle( hReadThread );
|
||||
}
|
||||
|
||||
if ( hWriteThread )
|
||||
{
|
||||
CloseHandle( hWriteThread );
|
||||
}
|
||||
|
||||
for ( i=0; i<NUM_BUFFERS; i++ )
|
||||
{
|
||||
if ( buffers[i].pData )
|
||||
{
|
||||
delete [] buffers[i].pData;
|
||||
}
|
||||
}
|
||||
|
||||
if ( copyFile.m_pInflateBuffer )
|
||||
{
|
||||
delete [] copyFile.m_pInflateBuffer;
|
||||
}
|
||||
|
||||
if ( !bSuccess )
|
||||
{
|
||||
pCopyStats->m_copyErrors++;
|
||||
}
|
||||
|
||||
pCopyStats->m_copyTime = GetTickCount() - startCopyTime;
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
2019
utils/xbox/xbox_loader/xbox_loader.cpp
Normal file
171
utils/xbox/xbox_loader/xbox_loader.h
Normal file
@@ -0,0 +1,171 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// XBOX_LOADER.H
|
||||
//
|
||||
// Master Include
|
||||
//=====================================================================================//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <xtl.h>
|
||||
#include <XBApp.h>
|
||||
#include <XBFont.h>
|
||||
#include <XBHelp.h>
|
||||
#include <xgraphics.h>
|
||||
#include <xfont.h>
|
||||
#include <xmv.h>
|
||||
#include <xbdm.h>
|
||||
#include <math.h>
|
||||
#include "XBResource.h"
|
||||
#include "xmvhelper.h"
|
||||
#include "toollib.h"
|
||||
#include "scriplib.h"
|
||||
#include "loader.h"
|
||||
#include "jcalg1.h"
|
||||
#include "xbox/xbox_launch.h"
|
||||
|
||||
#define XBOX_FORENSIC_LOG
|
||||
|
||||
#define SCREEN_WIDTH 640
|
||||
#define SCREEN_HEIGHT 480
|
||||
#define MAX_FILES 500
|
||||
#define MAX_SLIDESHOW_TEXTURES 9
|
||||
|
||||
#define LEGAL_DISPLAY_TIME 6000
|
||||
#define LOADINGBAR_UPTIME 500.0f // slid up or down
|
||||
#define LOADINGBAR_SLIDETIME 1500.0f // progress speed
|
||||
#define LOADINGBAR_WAITTIME 500.0f // delay after up to begin slide
|
||||
#define SLIDESHOW_SLIDETIME 7000
|
||||
#define SLIDESHOW_FLIPTIME 1000
|
||||
|
||||
#define LEGAL_MAIN 0
|
||||
#define LEGAL_SOURCE 1
|
||||
|
||||
#define FOOTER_W 512
|
||||
|
||||
#define SEGMENT_W 10
|
||||
#define SEGMENT_GAP 1
|
||||
#define SEGMENT_COUNT 26
|
||||
|
||||
#define PROGRESS_Y 405
|
||||
#define PROGRESS_W (SEGMENT_COUNT*(SEGMENT_W+SEGMENT_GAP))
|
||||
#define PROGRESS_H 15
|
||||
#define PROGRESS_X 124
|
||||
|
||||
#define PROGRESS_FOOTER_COLOR 0x88FFFFFF
|
||||
#define PROGRESS_INSET_COLOR 0xFF222222
|
||||
#define PROGRESS_SEGMENT_COLOR 0xFFCC6C00
|
||||
#define PROGRESS_TEXT_COLOR 0xFFFFFFFF
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Main class to run this application. Most functionality is inherited
|
||||
// from the CXBApplication base class.
|
||||
//-----------------------------------------------------------------------------
|
||||
class CXBoxLoader : public CXBApplication
|
||||
{
|
||||
public:
|
||||
CXBoxLoader();
|
||||
|
||||
virtual HRESULT Initialize( void );
|
||||
virtual HRESULT Render( void );
|
||||
virtual HRESULT FrameMove( void );
|
||||
|
||||
void DrawRect( int x, int y, int w, int h, DWORD color );
|
||||
void DrawLegals();
|
||||
void DrawDebug();
|
||||
BOOL PlayVideoFrame();
|
||||
HRESULT StartVideo( const CHAR* strFilename, bool bFromMemory, bool bFatalOnError );
|
||||
void StopVideo();
|
||||
bool StartInstall( void );
|
||||
bool LoadInstallScript( void );
|
||||
D3DTexture *LoadTexture( int resourceID );
|
||||
HRESULT LoadFont( CXBFont *pFont, int resourceID );
|
||||
void DrawTexture( D3DTexture *pD3DTexture, int x, int y, int w, int h, int color );
|
||||
void StartLegalScreen( int legal );
|
||||
void DrawProgressBar();
|
||||
void DrawLoadingMarquee();
|
||||
void DrawSlideshow();
|
||||
bool VerifyInstall();
|
||||
void StartDashboard( bool bGotoMemory );
|
||||
void LoadLogFile();
|
||||
void DrawLog();
|
||||
void FatalMediaError();
|
||||
void LaunchHL2( unsigned int contextCode );
|
||||
void TickVideo();
|
||||
|
||||
private:
|
||||
IDirect3DTexture8 *m_pLastMovieFrame;
|
||||
D3DTexture *m_pFooterTexture;
|
||||
D3DTexture *m_pLoadingIconTexture;
|
||||
D3DTexture *m_pMainLegalTexture;
|
||||
D3DTexture *m_pSourceLegalTexture;
|
||||
D3DTexture *m_pLegalTexture;
|
||||
D3DTexture *m_pSlideShowTextures[MAX_SLIDESHOW_TEXTURES];
|
||||
|
||||
CXMVPlayer m_player;
|
||||
|
||||
D3DVertexBuffer *m_pVB;
|
||||
CXBPackedResource m_xprResource;
|
||||
|
||||
CXBFont m_Font;
|
||||
|
||||
int m_contextCode;
|
||||
|
||||
char *m_fileSrc[MAX_FILES];
|
||||
char *m_fileDest[MAX_FILES];
|
||||
xCompressHeader *m_fileCompressionHeaders[MAX_FILES];
|
||||
DWORD m_fileDestSizes[MAX_FILES];
|
||||
int m_numFiles;
|
||||
|
||||
bool m_bAllowAttractAbort;
|
||||
bool m_bDrawLoading;
|
||||
bool m_bDrawProgress;
|
||||
bool m_bDrawDebug;
|
||||
bool m_bLaunch;
|
||||
DWORD m_dwLoading;
|
||||
bool m_bDrawLegal;
|
||||
HANDLE m_installThread;
|
||||
DWORD m_LegalTime;
|
||||
int m_State;
|
||||
DWORD m_LoadingBarStartTime;
|
||||
DWORD m_LoadingBarEndTime;
|
||||
DWORD m_LegalStartTime;
|
||||
bool m_bInstallComplete;
|
||||
int m_Version;
|
||||
int m_FrameCounter;
|
||||
int m_MovieCount;
|
||||
bool m_bMovieErrorIsFatal;
|
||||
bool m_bCaptureLastMovieFrame;
|
||||
DWORD m_SlideShowStartTime;
|
||||
bool m_bDrawSlideShow;
|
||||
int m_SlideShowCount;
|
||||
bool m_bFinalSlide;
|
||||
char *m_pLogData;
|
||||
XFONT* m_pDefaultTrueTypeFont;
|
||||
};
|
||||
|
||||
struct CopyStats_t
|
||||
{
|
||||
char m_srcFilename[MAX_PATH];
|
||||
char m_dstFilename[MAX_PATH];
|
||||
DWORD m_readSize;
|
||||
DWORD m_writeSize;
|
||||
DWORD m_bytesCopied;
|
||||
DWORD m_totalReadTime;
|
||||
DWORD m_totalWriteTime;
|
||||
DWORD m_totalReadSize;
|
||||
DWORD m_totalWriteSize;
|
||||
DWORD m_bufferReadSize;
|
||||
DWORD m_bufferWriteSize;
|
||||
DWORD m_bufferReadTime;
|
||||
DWORD m_bufferWriteTime;
|
||||
DWORD m_inflateSize;
|
||||
DWORD m_inflateTime;
|
||||
DWORD m_copyTime;
|
||||
DWORD m_copyErrors;
|
||||
DWORD m_numReadBuffers;
|
||||
DWORD m_numWriteBuffers;
|
||||
};
|
||||
|
||||
extern bool CopyFileOverlapped( const char *pSrc, const char *pDest, xCompressHeader *pxcHeader, CopyStats_t *pCopyStats );
|
||||
extern bool CreateFilePath( const char *inPath );
|
||||
24
utils/xbox/xbox_loader/xbox_loader.sln
Normal file
@@ -0,0 +1,24 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 8.00
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xbox_loader", "xbox_loader.vcproj", "{652C7D60-BC02-4E09-96DD-9300FFFF3403}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug_XBox = Debug_XBox
|
||||
Release_XBox = Release_XBox
|
||||
Retail_XBox = Retail_XBox
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfiguration) = postSolution
|
||||
{652C7D60-BC02-4E09-96DD-9300FFFF3403}.Debug_XBox.ActiveCfg = Debug_XBox|Xbox
|
||||
{652C7D60-BC02-4E09-96DD-9300FFFF3403}.Debug_XBox.Build.0 = Debug_XBox|Xbox
|
||||
{652C7D60-BC02-4E09-96DD-9300FFFF3403}.Release_XBox.ActiveCfg = Release_XBox|Xbox
|
||||
{652C7D60-BC02-4E09-96DD-9300FFFF3403}.Release_XBox.Build.0 = Release_XBox|Xbox
|
||||
{652C7D60-BC02-4E09-96DD-9300FFFF3403}.Retail_XBox.ActiveCfg = Retail_XBox|Xbox
|
||||
{652C7D60-BC02-4E09-96DD-9300FFFF3403}.Retail_XBox.Build.0 = Retail_XBox|Xbox
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
366
utils/xbox/xbox_loader/xbox_loader.vcproj
Normal file
@@ -0,0 +1,366 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="xbox_loader"
|
||||
ProjectGUID="{652C7D60-BC02-4E09-96DD-9300FFFF3403}"
|
||||
RootNamespace="xbox_loader"
|
||||
SccProjectName=""
|
||||
SccLocalPath="">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Xbox"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug_XBox|Xbox"
|
||||
OutputDirectory=".\Debug_XBox"
|
||||
IntermediateDirectory=".\Debug_XBox"
|
||||
ConfigurationType="1"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
OptimizeForProcessor="2"
|
||||
AdditionalIncludeDirectories="..\..\..\public;..\..\..\common;..\Common\include;..\toollib"
|
||||
PreprocessorDefinitions="_USE_XGMATH,_XBOX,XBOX_SAMPLE,_DEBUG,"
|
||||
ExceptionHandling="FALSE"
|
||||
RuntimeLibrary="1"
|
||||
EnableEnhancedInstructionSet="1"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderThrough="xtl.h"
|
||||
PrecompiledHeaderFile="$(IntDir)/apploader.pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="0"
|
||||
DisableSpecificWarnings="4244"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386 /FIXED:NO"
|
||||
AdditionalDependencies="xperf.lib xbdm.lib xapilibd.lib d3d8d.lib d3dx8d.lib xmv.lib xgraphicsd.lib dsoundd.lib xboxkrnl.lib"
|
||||
OutputFile="$(OutDir)/xbox_loader.exe"
|
||||
LinkIncremental="2"
|
||||
SuppressStartupBanner="TRUE"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/xbox_loader.pdb"
|
||||
GenerateMapFile="TRUE"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
Description="Copying LoaderMedia to \\Fileserver"
|
||||
CommandLine="copy LoaderMedia\*.* \\FileServer\user\XBox\DVD\LoaderMedia
|
||||
|
||||
"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine="bundler LoaderMedia_Source\loader_icon.rdf -o LoaderMedia_Source\loader_icon.xbx"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="XboxDeploymentTool"
|
||||
RemotePath="xe:\hl2\default.xbe"
|
||||
AdditionalFiles=""/>
|
||||
<Tool
|
||||
Name="XboxImageTool"
|
||||
StackSize="0x10000"
|
||||
IncludeDebugInfo="TRUE"
|
||||
LimitAvailableMemoryTo64MB="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
NoLibWarn="TRUE"
|
||||
TitleID="0x45410091"
|
||||
TitleName="Half - Life 2 (Debug Build)"
|
||||
TitleImage="LoaderMedia_Source\loader_icon.xbx"
|
||||
XBEVersion="4096"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release_XBox|Xbox"
|
||||
OutputDirectory="$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
OmitFramePointers="TRUE"
|
||||
OptimizeForProcessor="2"
|
||||
AdditionalIncludeDirectories="..\..\..\public;..\..\..\common;..\Common\include;..\toollib"
|
||||
PreprocessorDefinitions="_USE_XGMATH;_XBOX;NDEBUG"
|
||||
StringPooling="TRUE"
|
||||
ExceptionHandling="FALSE"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
EnableEnhancedInstructionSet="1"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderThrough=""
|
||||
PrecompiledHeaderFile=""
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
DisableSpecificWarnings="4244"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386 /FIXED:NO"
|
||||
AdditionalDependencies="xapilib.lib d3d8.lib d3dx8.lib xgraphics.lib dsound.lib xmv.lib xboxkrnl.lib"
|
||||
OutputFile="$(OutDir)/xbox_loader.exe"
|
||||
SuppressStartupBanner="TRUE"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/xbox_loader.pdb"
|
||||
GenerateMapFile="TRUE"
|
||||
MapExports="TRUE"
|
||||
MapLines="TRUE"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
SetChecksum="TRUE"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
Description="Copying LoaderMedia to \\Fileserver"
|
||||
CommandLine="copy LoaderMedia\*.* \\FileServer\user\XBox\DVD\LoaderMedia
|
||||
copy $(TargetDir)$(TargetName).xbe \\FileServer\user\XBox\DVD\default.xbe
|
||||
"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine="bundler LoaderMedia_Source\loader_icon.rdf -o LoaderMedia_Source\loader_icon.xbx"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="XboxDeploymentTool"
|
||||
RemotePath="xe:\hl2\default.xbe"
|
||||
AdditionalFiles=""/>
|
||||
<Tool
|
||||
Name="XboxImageTool"
|
||||
StackSize="0x10000"
|
||||
LimitAvailableMemoryTo64MB="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TitleID="0x45410091"
|
||||
TitleName="Half - Life 2 (Release Build)"
|
||||
TitleImage="LoaderMedia_Source\loader_icon.xbx"
|
||||
XBEVersion="4096"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Retail_XBox|Xbox"
|
||||
OutputDirectory="$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
OmitFramePointers="TRUE"
|
||||
OptimizeForProcessor="2"
|
||||
AdditionalIncludeDirectories="..\..\..\public;..\..\..\common;..\Common\include;..\toollib"
|
||||
PreprocessorDefinitions="_USE_XGMATH;_XBOX;NDEBUG;_RETAIL"
|
||||
StringPooling="TRUE"
|
||||
ExceptionHandling="FALSE"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
EnableEnhancedInstructionSet="1"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderThrough="xtl.h"
|
||||
PrecompiledHeaderFile="$(IntDir)/apploader.pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
DisableSpecificWarnings="4244"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386 /FIXED:NO"
|
||||
AdditionalDependencies="xapilib.lib d3d8.lib d3dx8.lib xgraphics.lib dsound.lib xmv.lib xboxkrnl.lib"
|
||||
OutputFile="$(OutDir)/xbox_loader.exe"
|
||||
SuppressStartupBanner="TRUE"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/xbox_loader.pdb"
|
||||
GenerateMapFile="TRUE"
|
||||
MapExports="TRUE"
|
||||
MapLines="TRUE"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
SetChecksum="TRUE"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
Description="Copying LoaderMedia to \\Fileserver"
|
||||
CommandLine="copy LoaderMedia\*.* \\FileServer\user\XBox\DVD\LoaderMedia
|
||||
copy $(TargetDir)$(TargetName).xbe \\FileServer\user\XBox\DVD\default.xbe
|
||||
"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine="bundler LoaderMedia_Source\loader_icon.rdf -o LoaderMedia_Source\loader_icon.xbx"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="XboxDeploymentTool"
|
||||
RemotePath="xe:\hl2\default.xbe"
|
||||
AdditionalFiles=""/>
|
||||
<Tool
|
||||
Name="XboxImageTool"
|
||||
StackSize="0x10000"
|
||||
LimitAvailableMemoryTo64MB="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TitleID="0x45410091"
|
||||
TitleName="Half - Life 2"
|
||||
TitleImage="LoaderMedia_Source\loader_icon.xbx"
|
||||
XBEVersion="4096"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
|
||||
<File
|
||||
RelativePath=".\xbox_fileCopy.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\xbox_loader.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\xmvhelper.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc">
|
||||
<File
|
||||
RelativePath=".\font.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\public\jcalg1.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\loader.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\common\xbox\xbox_launch.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\xbox_loader.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\xmvhelper.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Common Files"
|
||||
Filter="">
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
|
||||
<File
|
||||
RelativePath="..\toollib\scriplib.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\toollib\scriplib.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\toollib\toollib.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\toollib\toollib.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\Common\src\XBApp.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\Common\src\XBFont.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\Common\src\XBInput.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\Common\src\XBMesh.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\Common\src\XBResource.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\Common\src\XBUtil.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc">
|
||||
<File
|
||||
RelativePath="..\Common\include\XBApp.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\Common\include\XBFont.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\Common\include\XBHelp.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\Common\include\XBInput.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\Common\include\XBMesh.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\Common\include\XBProfiling.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\Common\include\XBResource.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\Common\include\XBUtil.h">
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resources"
|
||||
Filter="*.rdf">
|
||||
<File
|
||||
RelativePath=".\loader.rdf">
|
||||
<FileConfiguration
|
||||
Name="Debug_XBox|Xbox">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="bundler "$(InputPath)""
|
||||
CommandLine="bundler "$(InputPath)""
|
||||
Outputs="$(ProjectDir)Media\$(InputName).xpr;$(ProjectDir)$(InputName).h"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release_XBox|Xbox">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="bundler "$(InputPath)""
|
||||
CommandLine="bundler "$(InputPath)""
|
||||
Outputs="$(ProjectDir)Media\$(InputName).xpr;$(ProjectDir)$(InputName).h"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Retail_XBox|Xbox">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="bundler "$(InputPath)""
|
||||
CommandLine="bundler "$(InputPath)""
|
||||
Outputs="$(ProjectDir)Media\$(InputName).xpr;$(ProjectDir)$(InputName).h"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\LoaderMedia_Source\loader_icon.rdf">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Libraries"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\..\lib\public\jcalg1_static.lib">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
788
utils/xbox/xbox_loader/xmvhelper.cpp
Normal file
@@ -0,0 +1,788 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: WMVPlayer.cpp
|
||||
//
|
||||
// Desc: This helper class provides simple WMV decoding and playback
|
||||
// functionality. It will be expanded as new playback methods are
|
||||
// exposed
|
||||
//
|
||||
// Hist: 2.7.03 - Created, based on work by Jeff Sullivan
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "xbox_loader.h"
|
||||
#include <xtl.h>
|
||||
#include "XMVHelper.h"
|
||||
#include "XBUtil.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
// Funtion Prototypes for packet loading functions for loading from a file.
|
||||
HRESULT CALLBACK GetNextPacket( DWORD dwContext,
|
||||
void **ppPacket,
|
||||
DWORD* pOffsetToNextPacket );
|
||||
|
||||
HRESULT CALLBACK ReleasePreviousPacket( DWORD dwContext,
|
||||
LONGLONG llNextReadByteOffset,
|
||||
DWORD dwNextPacketSize );
|
||||
|
||||
// Funtion Prototypes for packet loading functions for loading from a block of memory.
|
||||
HRESULT CALLBACK GetNextMemoryPacket( DWORD dwContext,
|
||||
void **ppPacket,
|
||||
DWORD* pOffsetToNextPacket );
|
||||
|
||||
HRESULT CALLBACK ReleasePreviousMemoryPacket( DWORD dwContext,
|
||||
LONGLONG llNextReadByteOffset,
|
||||
DWORD dwNextPacketSize );
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CXMVPlayer()
|
||||
// Desc: Constructor for CXMVPlayer
|
||||
//-----------------------------------------------------------------------------
|
||||
CXMVPlayer::CXMVPlayer()
|
||||
{
|
||||
m_pXMVDecoder = NULL;
|
||||
ZeroMemory( &m_VideoDesc, sizeof( m_VideoDesc ) );
|
||||
ZeroMemory( &m_AudioDesc, sizeof( m_AudioDesc ) );
|
||||
for ( UINT i=0; i<XMVPLAYER_NUMTEXTURES; i++ )
|
||||
{
|
||||
m_pTextures[i] = NULL;
|
||||
}
|
||||
|
||||
m_dwCurrentFrame = -1; // Will be zero after we decode the first frame.
|
||||
|
||||
m_bPlaying = FALSE;
|
||||
m_bOverlaysEnabled = FALSE;
|
||||
|
||||
m_loadContext.hFile = INVALID_HANDLE_VALUE;
|
||||
m_loadContext.pInputBuffer = 0;
|
||||
m_physicalBuffer = 0;
|
||||
m_bError = FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: ~CXMVPlayer()
|
||||
// Desc: Destructor for CXMVPlayer
|
||||
//-----------------------------------------------------------------------------
|
||||
CXMVPlayer::~CXMVPlayer()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: Destroy()
|
||||
// Desc: Free all resources and clear are resource pointers and handles.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CXMVPlayer::Destroy()
|
||||
{
|
||||
// Disable overlays if we were using them.
|
||||
if ( m_bOverlaysEnabled )
|
||||
{
|
||||
m_pDevice->EnableOverlay( FALSE );
|
||||
m_bOverlaysEnabled = FALSE;
|
||||
}
|
||||
|
||||
// Free the XMV decoder.
|
||||
if ( NULL != m_pXMVDecoder )
|
||||
{
|
||||
m_pXMVDecoder->CloseDecoder();
|
||||
m_pXMVDecoder = NULL;
|
||||
}
|
||||
|
||||
ZeroMemory( &m_VideoDesc, sizeof( m_VideoDesc ) );
|
||||
ZeroMemory( &m_AudioDesc, sizeof( m_AudioDesc ) );
|
||||
|
||||
// Release our textures.
|
||||
for ( UINT i=0; i<XMVPLAYER_NUMTEXTURES; i++ )
|
||||
{
|
||||
if ( m_pTextures[i] )
|
||||
m_pTextures[i]->Release();
|
||||
m_pTextures[i] = 0;
|
||||
}
|
||||
|
||||
m_dwCurrentFrame = -1;
|
||||
m_dwStartTime = 0;
|
||||
|
||||
m_bPlaying = FALSE;
|
||||
|
||||
// Release any file handles we were using.
|
||||
if( INVALID_HANDLE_VALUE != m_loadContext.hFile )
|
||||
{
|
||||
CloseHandle( m_loadContext.hFile );
|
||||
m_loadContext.hFile = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
// Free up memory used for playing a movie from memory.
|
||||
if ( m_loadContext.pInputBuffer )
|
||||
{
|
||||
free( m_loadContext.pInputBuffer );
|
||||
m_loadContext.pInputBuffer = 0;
|
||||
}
|
||||
|
||||
// Be sure to release the physical memory last!
|
||||
if( m_physicalBuffer )
|
||||
{
|
||||
XPhysicalFree( m_physicalBuffer );
|
||||
m_physicalBuffer = 0;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: FinishOpeningFile()
|
||||
// Desc: Helper function for the three Open functions. Enables the audio streams,
|
||||
// initializes the video descriptor, and allocates textures if needed.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CXMVPlayer::FinishOpeningFile( D3DFORMAT format, LPDIRECT3DDEVICE8 pDevice, BOOL bAllocateTextures )
|
||||
{
|
||||
assert( format == D3DFMT_YUY2 || format == D3DFMT_LIN_A8R8G8B8 );
|
||||
assert( XMVPLAYER_NUMTEXTURES >= 2);
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
m_pXMVDecoder->GetVideoDescriptor( &m_VideoDesc );
|
||||
|
||||
// Enable the audio streams
|
||||
for ( unsigned i=0; i < m_VideoDesc.AudioStreamCount; i++ )
|
||||
{
|
||||
m_pXMVDecoder->GetAudioDescriptor( i, &m_AudioDesc );
|
||||
hr = m_pXMVDecoder->EnableAudioStream( i, 0, NULL, NULL);
|
||||
if ( FAILED( hr ) )
|
||||
{
|
||||
XBUtil_DebugPrint( "Unable to enable audio stream 0 (error %x)\n", hr );
|
||||
Destroy();
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
for ( int i = 0; i < XMVPLAYER_NUMTEXTURES; i++ )
|
||||
{
|
||||
m_pTextures[i] = 0;
|
||||
if ( bAllocateTextures )
|
||||
{
|
||||
hr = pDevice->CreateTexture( m_VideoDesc.Width, m_VideoDesc.Height, 1, 0, format, 0, &m_pTextures[i] );
|
||||
if ( FAILED( hr ) )
|
||||
{
|
||||
XBUtil_DebugPrint( "Unable to create texture %d (error %x)\n", i, hr );
|
||||
Destroy();
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize what texture we are decoding to, if decoding for texture mapping.
|
||||
m_nDecodeTextureIndex = 0;
|
||||
|
||||
// Initialize the various texture pointers for use when decoding for overlays.
|
||||
pShowingTexture = m_pTextures[0];
|
||||
pDecodingTexture = m_pTextures[1];
|
||||
pSubmittedTexture = 0;
|
||||
|
||||
m_bPlaying = TRUE;
|
||||
m_dwStartTime = GetTickCount();
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: OpenFile()
|
||||
// Desc: Create an XMV decoder object that reads from a file.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CXMVPlayer::OpenFile( const CHAR* lpFilename, D3DFORMAT format, LPDIRECT3DDEVICE8 pDevice, BOOL bAllocateTextures )
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
m_bError = FALSE;
|
||||
|
||||
if ( NULL == lpFilename || NULL == pDevice )
|
||||
{
|
||||
XBUtil_DebugPrint( "Bad parameter to OpenFile()\n" );
|
||||
m_bError = TRUE;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
hr = XMVDecoder_CreateDecoderForFile( XMVFLAG_SYNC_ON_NEXT_VBLANK, ( CHAR* )lpFilename, &m_pXMVDecoder );
|
||||
if ( FAILED( hr ) )
|
||||
{
|
||||
XBUtil_DebugPrint( "Unable to create XMV Decoder for %s (error: %x)\n", lpFilename, hr );
|
||||
m_bError = TRUE;
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = FinishOpeningFile( format, pDevice, bAllocateTextures );
|
||||
|
||||
if ( FAILED( hr ) )
|
||||
{
|
||||
m_bError = TRUE;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: OpenFileForPackets()
|
||||
// Desc: Create an XMV decoder object that uses the packet reading interface.
|
||||
// Currently this just reads from a file, but it can be altered to read from
|
||||
// custom formats, start partway through a file, etc.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CXMVPlayer::OpenFileForPackets( const CHAR* lpFilename, D3DFORMAT format, LPDIRECT3DDEVICE8 pDevice, BOOL bAllocateTextures )
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
// We need to read in the first 4K of data for the XMV player to initialize
|
||||
// itself from. This is most conveniently read as an array of DWORDS.
|
||||
DWORD first4Kbytes[4096 / sizeof( DWORD )];
|
||||
|
||||
// Clear entire context struct to zero
|
||||
ZeroMemory( &m_loadContext, sizeof( m_loadContext ) );
|
||||
|
||||
// Open the input file.
|
||||
m_loadContext.hFile = CreateFile( lpFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING,
|
||||
NULL );
|
||||
|
||||
if( m_loadContext.hFile == INVALID_HANDLE_VALUE )
|
||||
{
|
||||
Destroy();
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
// Read the first page from the file. We opened it for
|
||||
// overlapped IO so we do a pair of reads.
|
||||
m_loadContext.Overlapped.Offset = 0;
|
||||
m_loadContext.Overlapped.OffsetHigh = 0;
|
||||
|
||||
// Start the read.
|
||||
if( 0 == ReadFile( m_loadContext.hFile, first4Kbytes, sizeof( first4Kbytes ), NULL, &m_loadContext.Overlapped ) )
|
||||
{
|
||||
if( GetLastError() != ERROR_IO_PENDING )
|
||||
{
|
||||
Destroy();
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for the read to finish.
|
||||
DWORD dwBytesRead;
|
||||
if( !GetOverlappedResult( m_loadContext.hFile, &m_loadContext.Overlapped, &dwBytesRead, TRUE ) )
|
||||
{
|
||||
Destroy();
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Check size to make sure input is a valid XMV file.
|
||||
if( dwBytesRead != 4096 )
|
||||
{
|
||||
Destroy();
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Create an XMV decoder
|
||||
hr = XMVDecoder_CreateDecoderForPackets( XMVFLAG_SYNC_ON_NEXT_VBLANK, first4Kbytes, ( DWORD )&m_loadContext,
|
||||
GetNextPacket, ReleasePreviousPacket, &m_pXMVDecoder );
|
||||
if( FAILED( hr ) )
|
||||
{
|
||||
Destroy();
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// The size of the first packet and the minimum size of the two packet buffers are stored in the
|
||||
// second and third DWORDS of the file. From xmv.h:
|
||||
// * DWORD NextPacketSize // The size of the next packet
|
||||
// * DWORD ThisPacketSize // The size of this packet
|
||||
// * DWORD MaxPacketSize // The size of the largest packet in the file
|
||||
DWORD dwThisPacketSize = first4Kbytes[1];
|
||||
DWORD dwRequiredPacketSize = first4Kbytes[2];
|
||||
|
||||
// Check for illegal parameters.
|
||||
if( dwThisPacketSize > dwRequiredPacketSize )
|
||||
{
|
||||
Destroy();
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// XPhysicalAlloc is used so that 5.1 or compressed audio streams can be played.
|
||||
m_physicalBuffer = ( BYTE* )XPhysicalAlloc( dwRequiredPacketSize * 2, MAXULONG_PTR, 0, PAGE_READWRITE );
|
||||
|
||||
// Save our information.
|
||||
m_loadContext.dwPacketSize = dwRequiredPacketSize;
|
||||
m_loadContext.pLoadingPacket = m_physicalBuffer;
|
||||
m_loadContext.pDecodingPacket = m_physicalBuffer + dwRequiredPacketSize;
|
||||
|
||||
// Read the first packet. We wind up re-reading the first 4096
|
||||
// bytes but it makes the logic for figuring out how much we read
|
||||
// a little bit easier...
|
||||
m_loadContext.Overlapped.Offset = 0;
|
||||
m_loadContext.Overlapped.OffsetHigh = 0;
|
||||
|
||||
if( 0 == ReadFile( m_loadContext.hFile, m_physicalBuffer, dwThisPacketSize, NULL,
|
||||
&m_loadContext.Overlapped ) )
|
||||
{
|
||||
if( GetLastError() != ERROR_IO_PENDING )
|
||||
{
|
||||
Destroy();
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
// Note - at this point the preceding read has *not* necessarily completed.
|
||||
// Don't try reading anything from that buffer until GetNextPacket has been
|
||||
// successfully called.
|
||||
|
||||
hr = FinishOpeningFile( format, pDevice, bAllocateTextures );
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: OpenMovieFromMemory()
|
||||
// Desc: Create an XMV decoder object that uses the packet reading interface to
|
||||
// read from a block of memory. To simplify the memory management this function
|
||||
// also allocates this block of memory and initializes it from a file.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CXMVPlayer::OpenMovieFromMemory( const CHAR* lpFilename, D3DFORMAT format, LPDIRECT3DDEVICE8 pDevice, BOOL bAllocateTextures )
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
m_bError = FALSE;
|
||||
|
||||
// Read the entire file into memory.
|
||||
void* data;
|
||||
hr = XBUtil_LoadFile( lpFilename, &data, &m_loadContext.inputSize );
|
||||
if ( FAILED( hr ) )
|
||||
{
|
||||
m_bError = TRUE;
|
||||
return hr;
|
||||
}
|
||||
|
||||
m_loadContext.pInputBuffer = ( BYTE* )data;
|
||||
|
||||
// Check size to make sure input is a valid XMV file.
|
||||
if( m_loadContext.inputSize < 4096 )
|
||||
{
|
||||
Destroy();
|
||||
m_bError = TRUE;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Get a DWORD pointer to the first 4K - needed by CreateDecoderForPackets
|
||||
DWORD* first4Kbytes = ( DWORD* )data;
|
||||
|
||||
// Create an XMV decoder
|
||||
hr = XMVDecoder_CreateDecoderForPackets( XMVFLAG_SYNC_ON_NEXT_VBLANK, first4Kbytes, ( DWORD )&m_loadContext, GetNextMemoryPacket,
|
||||
ReleasePreviousMemoryPacket, &m_pXMVDecoder );
|
||||
if ( FAILED( hr ) )
|
||||
{
|
||||
Destroy();
|
||||
m_bError = TRUE;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// The size of the first packet and the minimum size of the two packet buffers are stored in the
|
||||
// second and third DWORDS of the file. From xmv.h:
|
||||
// * DWORD NextPacketSize // The size of the next packet
|
||||
// * DWORD ThisPacketSize // The size of this packet
|
||||
// * DWORD MaxPacketSize // The size of the largest packet in the file
|
||||
DWORD dwThisPacketSize = first4Kbytes[1];
|
||||
DWORD dwRequiredPacketSize = first4Kbytes[2];
|
||||
|
||||
// Check for illegal parameters.
|
||||
if( dwThisPacketSize > dwRequiredPacketSize )
|
||||
{
|
||||
Destroy();
|
||||
m_bError = TRUE;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// XPhysicalAlloc is used so that 5.1 or compressed audio streams can be played.
|
||||
m_physicalBuffer = ( BYTE* )XPhysicalAlloc( dwRequiredPacketSize * 2, MAXULONG_PTR, 0, PAGE_READWRITE );
|
||||
|
||||
// Save our information for the callback functions.
|
||||
// The size of our two memory blocks.
|
||||
m_loadContext.dwPacketSize = dwRequiredPacketSize;
|
||||
// The addresses of our two memory blocks.
|
||||
m_loadContext.pLoadingPacket = m_physicalBuffer;
|
||||
m_loadContext.pDecodingPacket = m_physicalBuffer + dwRequiredPacketSize;
|
||||
|
||||
// Information about the block of memory the movie is stored in.
|
||||
m_loadContext.pInputBuffer = ( BYTE* )data;
|
||||
m_loadContext.inputSize = m_loadContext.inputSize;
|
||||
m_loadContext.readOffset = 0;
|
||||
m_loadContext.currentPacketSize = dwThisPacketSize;
|
||||
|
||||
hr = FinishOpeningFile( format, pDevice, bAllocateTextures );
|
||||
|
||||
if ( FAILED( hr ) )
|
||||
{
|
||||
m_bError = TRUE;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: AdvanceFrameForTexturing()
|
||||
// Desc: Unpack the appropriate frames of data for use as textures.
|
||||
//-----------------------------------------------------------------------------
|
||||
LPDIRECT3DTEXTURE8 CXMVPlayer::AdvanceFrameForTexturing( LPDIRECT3DDEVICE8 pDevice )
|
||||
{
|
||||
// You must pass bAllocateTextures==TRUE to Open if you're going to use GetTexture/AdvanceFrame.
|
||||
assert( m_pTextures[0] );
|
||||
|
||||
LPDIRECT3DSURFACE8 pSurface;
|
||||
pDecodingTexture->GetSurfaceLevel( 0, &pSurface );
|
||||
|
||||
// Decode some information to the current draw texture.
|
||||
XMVRESULT xr = XMV_NOFRAME;
|
||||
m_pXMVDecoder->GetNextFrame( pSurface, &xr, NULL );
|
||||
|
||||
switch ( xr )
|
||||
{
|
||||
case XMV_NOFRAME:
|
||||
// Do nothing - we didn't get a frame.
|
||||
break;
|
||||
|
||||
case XMV_NEWFRAME:
|
||||
++m_dwCurrentFrame;
|
||||
// GetNextFrame produced a new frame. So, the texture we were decoding
|
||||
// to becomes available for drawing as a texture.
|
||||
pShowingTexture = pDecodingTexture;
|
||||
|
||||
// Setup for decoding to the next texture.
|
||||
m_nDecodeTextureIndex = ( m_nDecodeTextureIndex + 1 ) % XMVPLAYER_NUMTEXTURES;
|
||||
pDecodingTexture = m_pTextures[ m_nDecodeTextureIndex ];
|
||||
break;
|
||||
|
||||
case XMV_ENDOFFILE:
|
||||
m_bPlaying = FALSE;
|
||||
break;
|
||||
|
||||
case XMV_FAIL:
|
||||
// Data corruption or file read error. We'll treat that the same as
|
||||
// end of file.
|
||||
m_bPlaying = FALSE;
|
||||
m_bError = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
SAFE_RELEASE( pSurface );
|
||||
|
||||
// If we haven't decoded the first frame then return zero.
|
||||
if ( m_dwCurrentFrame < 0 )
|
||||
return 0;
|
||||
|
||||
return pShowingTexture;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: AdvanceFrameForOverlays()
|
||||
// Desc: Unpack the appropriate frames of data for use as an overlay.
|
||||
//-----------------------------------------------------------------------------
|
||||
LPDIRECT3DTEXTURE8 CXMVPlayer::AdvanceFrameForOverlays( LPDIRECT3DDEVICE8 pDevice )
|
||||
{
|
||||
// You must pass bAllocateTextures==TRUE to Open if you're going to use GetTexture/AdvanceFrame.
|
||||
assert( m_pTextures[0] );
|
||||
|
||||
// You have to call CXMVPlayer::EnableOverlays() if you are going to use overlays.
|
||||
assert( m_bOverlaysEnabled );
|
||||
|
||||
// If a texture has been submitted to be used as an overlay then we have to
|
||||
// wait for GetUpdateOverlayState() to return TRUE before we can assume that
|
||||
// the previous texture has *stopped* being displayed. Once GetUpdateOverlayState()
|
||||
// returns TRUE then we know that pSubmittedTexture is being displayed, which
|
||||
// means that, pShowingTexture is available as a decoding target.
|
||||
if ( pSubmittedTexture )
|
||||
{
|
||||
// If GetOverlayUpdateStatus() returns FALSE then we can still proceed and
|
||||
// call GetNextFrame(), but we will pass NULL for the surface parameter.
|
||||
// Some work will still be done, but none of the surfaces will be altered.
|
||||
if ( pDevice->GetOverlayUpdateStatus() )
|
||||
{
|
||||
// The call to UpdateOverlay() with pSubmittedTexture must have taken
|
||||
// effect now, so pShowingTexture is available as a decoding target.
|
||||
assert( !pDecodingTexture );
|
||||
pDecodingTexture = pShowingTexture;
|
||||
pShowingTexture = pSubmittedTexture;
|
||||
pSubmittedTexture = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
LPDIRECT3DSURFACE8 pSurface = NULL;
|
||||
if ( pDecodingTexture )
|
||||
pDecodingTexture->GetSurfaceLevel( 0, &pSurface );
|
||||
|
||||
// Decode some information to the current draw texture, which may be NULL.
|
||||
// pDecodingTexture will be NULL if one texture has been submitted as a new
|
||||
// overlay but the other one is still being displayed as an overlay.
|
||||
// If pSurface is NULL GetNextFrame() will still do some work.
|
||||
XMVRESULT xr = XMV_NOFRAME;
|
||||
m_pXMVDecoder->GetNextFrame( pSurface, &xr, NULL );
|
||||
|
||||
switch ( xr )
|
||||
{
|
||||
case XMV_NOFRAME:
|
||||
// Do nothing - we didn't get a frame.
|
||||
break;
|
||||
|
||||
case XMV_NEWFRAME:
|
||||
++m_dwCurrentFrame;
|
||||
// GetNextFrame produced a new frame. So, the texture we were decoding
|
||||
// to becomes available for displaying as an overlay.
|
||||
|
||||
// The other texture is not ready to be a decoding target. It is still
|
||||
// being displayed as an overlay. So, we assign the newly decoded
|
||||
// texture to pSubmittedTexture for the program to submit as an overlay,
|
||||
// but we don't yet move the previously submitted texture from pShowing
|
||||
// to pDecoding. That happens on a subsequent call to this function, after
|
||||
// GetOverlayUpdateStatus() returns TRUE to tell us that there are no
|
||||
// overlay swaps pending.
|
||||
assert( pDecodingTexture );
|
||||
assert( !pSubmittedTexture );
|
||||
pSubmittedTexture = pDecodingTexture;
|
||||
pDecodingTexture = NULL;
|
||||
break;
|
||||
|
||||
case XMV_ENDOFFILE:
|
||||
m_bPlaying = FALSE;
|
||||
break;
|
||||
|
||||
case XMV_FAIL:
|
||||
// Data corruption or file read error. We'll treat that the same as
|
||||
// end of file.
|
||||
m_bPlaying = FALSE;
|
||||
m_bError = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
SAFE_RELEASE( pSurface );
|
||||
|
||||
// If we just unpacked a new frame then we return that texture
|
||||
// and the program must call UpdateOverlay() with the surface
|
||||
// from that texture.
|
||||
// If we didn't unpack a frame then the program should do nothing -
|
||||
// the previous overlay will continue to be displayed.
|
||||
if ( XMV_NEWFRAME == xr )
|
||||
return pSubmittedTexture;
|
||||
|
||||
// No new frame to display.
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: TerminatePlayback()
|
||||
// Desc: Calls XMVDecoder::TerminatePlayback()
|
||||
//-----------------------------------------------------------------------------
|
||||
void CXMVPlayer::TerminatePlayback()
|
||||
{
|
||||
m_pXMVDecoder->TerminatePlayback();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: Play()
|
||||
// Desc: Calls XMVDecoder::Play() to play the entire movie.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CXMVPlayer::Play( DWORD Flags, RECT* pRect )
|
||||
{
|
||||
// You have to call Open before calling Play.
|
||||
assert( m_pXMVDecoder );
|
||||
|
||||
// Don't pass bAllocateTextures==TRUE to Open if you're going to use Play.
|
||||
assert( !m_pTextures[0] );
|
||||
|
||||
return m_pXMVDecoder->Play( Flags, pRect );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: EnableOverlays()
|
||||
// Desc: Enable the overlay planes for playing the movie in them, and record
|
||||
// that the overlays should be disabled when Destroy() is called.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CXMVPlayer::EnableOverlays( LPDIRECT3DDEVICE8 pDevice )
|
||||
{
|
||||
m_pDevice = pDevice;
|
||||
pDevice->EnableOverlay( TRUE );
|
||||
m_bOverlaysEnabled = TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: GetNextPacket()
|
||||
// Desc: Callback function to get next packet from a file
|
||||
//-----------------------------------------------------------------------------
|
||||
static HRESULT CALLBACK GetNextPacket( DWORD dwContext, VOID** ppPacket,
|
||||
DWORD* pOffsetToNextPacket )
|
||||
{
|
||||
LOAD_CONTEXT* pContext = ( LOAD_CONTEXT* )dwContext;
|
||||
if( NULL == pContext )
|
||||
return E_FAIL;
|
||||
|
||||
// If the next packet is fully loaded then return it,
|
||||
// otherwise return NULL.
|
||||
DWORD dwBytesRead;
|
||||
if( GetOverlappedResult( pContext->hFile, &pContext->Overlapped,
|
||||
&dwBytesRead, FALSE ) )
|
||||
{
|
||||
// Make the old decoding packet pending.
|
||||
pContext->pPendingReleasePacket = pContext->pDecodingPacket;
|
||||
pContext->pDecodingPacket = pContext->pLoadingPacket;
|
||||
pContext->pLoadingPacket = NULL;
|
||||
|
||||
// Offset to the next packet.
|
||||
*pOffsetToNextPacket = dwBytesRead;
|
||||
|
||||
// Set *ppPacket to the data we just loaded.
|
||||
*ppPacket = pContext->pDecodingPacket;
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD dwError = GetLastError();
|
||||
|
||||
// If we're waiting on the IO to finish, just do nothing.
|
||||
if( dwError != ERROR_IO_INCOMPLETE )
|
||||
return HRESULT_FROM_WIN32( dwError );
|
||||
|
||||
*ppPacket = NULL;
|
||||
*pOffsetToNextPacket = 0;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: ReleasePreviousPacket()
|
||||
// Desc: Callback function to release previous packet from a file
|
||||
//-----------------------------------------------------------------------------
|
||||
static HRESULT CALLBACK ReleasePreviousPacket( DWORD dwContext, LONGLONG llNextReadByteOffset,
|
||||
DWORD dwNextPacketSize )
|
||||
{
|
||||
LOAD_CONTEXT* pContext = ( LOAD_CONTEXT* )dwContext;
|
||||
if( NULL == pContext )
|
||||
return E_FAIL;
|
||||
|
||||
if( dwNextPacketSize != 0 )
|
||||
{
|
||||
// Start the next load.
|
||||
pContext->Overlapped.Offset = ( DWORD )( llNextReadByteOffset & 0xFFFFFFFF );
|
||||
pContext->Overlapped.OffsetHigh = ( DWORD )( llNextReadByteOffset >> 32 );
|
||||
|
||||
// Check for bad input file - buffer overrun
|
||||
if( dwNextPacketSize > pContext->dwPacketSize )
|
||||
return E_FAIL;
|
||||
|
||||
pContext->pLoadingPacket = pContext->pPendingReleasePacket;
|
||||
pContext->pPendingReleasePacket = NULL;
|
||||
|
||||
if( 0 == ReadFile( pContext->hFile, pContext->pLoadingPacket,
|
||||
dwNextPacketSize, NULL, &pContext->Overlapped ) )
|
||||
{
|
||||
if( GetLastError() != ERROR_IO_PENDING )
|
||||
return HRESULT_FROM_WIN32( GetLastError() );
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: GetNextMemoryPacket()
|
||||
// Desc: Callback function to get next packet from a file,
|
||||
// and setup for the next packet.
|
||||
//-----------------------------------------------------------------------------
|
||||
static HRESULT CALLBACK GetNextMemoryPacket( DWORD dwContext, VOID** ppPacket,
|
||||
DWORD* pOffsetToNextPacket )
|
||||
{
|
||||
LOAD_CONTEXT* pContext = ( LOAD_CONTEXT* )dwContext;
|
||||
if( NULL == pContext )
|
||||
return E_FAIL;
|
||||
|
||||
DWORD dwBytesRead = pContext->inputSize - pContext->readOffset;
|
||||
if ( pContext->currentPacketSize < dwBytesRead )
|
||||
dwBytesRead = pContext->currentPacketSize;
|
||||
|
||||
memcpy( pContext->pLoadingPacket, pContext->pInputBuffer + pContext->readOffset , dwBytesRead );
|
||||
pContext->readOffset +=dwBytesRead;
|
||||
|
||||
// Swap pointers so that next time we load it goes into the other packet block.
|
||||
BYTE* temp = pContext->pLoadingPacket;
|
||||
pContext->pLoadingPacket = pContext->pDecodingPacket;
|
||||
pContext->pDecodingPacket = temp;
|
||||
|
||||
// Offset to the next packet.
|
||||
*pOffsetToNextPacket = dwBytesRead;
|
||||
|
||||
// Set *ppPacket to the data we just loaded.
|
||||
*ppPacket = pContext->pDecodingPacket;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: ReleasePreviousMemoryPacket()
|
||||
// Desc: Callback function to release previous packet from a block of memory,
|
||||
// and setup for the next packet.
|
||||
//-----------------------------------------------------------------------------
|
||||
static HRESULT CALLBACK ReleasePreviousMemoryPacket( DWORD dwContext, LONGLONG llNextReadByteOffset,
|
||||
DWORD dwNextPacketSize )
|
||||
{
|
||||
LOAD_CONTEXT* pContext = ( LOAD_CONTEXT* )dwContext;
|
||||
if( NULL == pContext )
|
||||
return E_FAIL;
|
||||
|
||||
// Check for bad input file - buffer overrun
|
||||
if( dwNextPacketSize > pContext->dwPacketSize )
|
||||
return E_FAIL;
|
||||
|
||||
// Record the size of the next packet we are supposed to read, for GetNextMemoryPacket.
|
||||
pContext->currentPacketSize = dwNextPacketSize;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
177
utils/xbox/xbox_loader/xmvhelper.h
Normal file
@@ -0,0 +1,177 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: XMVHelper.h
|
||||
//
|
||||
// Desc: Definition of XMV playback helper class for playing XMVs in a number
|
||||
// of different ways.
|
||||
//
|
||||
// Hist: 2.7.03 - Created, based on work by Jeff Sullivan
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _XMVHELPER_H_
|
||||
#define _XMVHELPER_H_
|
||||
|
||||
#include <xtl.h>
|
||||
#include <xmv.h>
|
||||
|
||||
// Number of textures to allocate for decoding. A larger number may help to
|
||||
// smooth out any frame rate variations if you are decoding to a texture.
|
||||
// When decoding to overlays two textures are always used.
|
||||
const DWORD XMVPLAYER_NUMTEXTURES = 2;
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: LOAD_CONTEXT
|
||||
// Desc: This structure is used to hold information used by the packet callbacks.
|
||||
//-----------------------------------------------------------------------------
|
||||
struct LOAD_CONTEXT
|
||||
{
|
||||
// Memory available for loading packets - maximum packet size.
|
||||
DWORD dwPacketSize;
|
||||
|
||||
// Packet that XMV was decoding out of, and might still be, that
|
||||
// we want to load into as soon as we can.
|
||||
BYTE* pPendingReleasePacket;
|
||||
// Packet that XMV is decoding out of.
|
||||
BYTE* pDecodingPacket;
|
||||
// Packet we are currently loading into.
|
||||
BYTE* pLoadingPacket;
|
||||
|
||||
|
||||
// Information for when reading packets out of a file.
|
||||
// Handle to the file we are reading from.
|
||||
HANDLE hFile;
|
||||
|
||||
// Overlapped structure to control asynchronous reading.
|
||||
OVERLAPPED Overlapped;
|
||||
|
||||
|
||||
// Information for when copying packets out of a memory buffer.
|
||||
// The size and location of the buffer we are reading from if we are
|
||||
// playing a movie from memory.
|
||||
BYTE* pInputBuffer;
|
||||
DWORD inputSize;
|
||||
// The offset in the memory buffer that we are currently reading from.
|
||||
DWORD readOffset;
|
||||
// The size of the packet that we have 'queued up' for reading. This
|
||||
// is a packet that we have warned about via ReleasePreviousMemoryPacket
|
||||
// but have not yet been asked to load.
|
||||
DWORD currentPacketSize;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class CXMVPlayer
|
||||
{
|
||||
public:
|
||||
CXMVPlayer();
|
||||
~CXMVPlayer();
|
||||
|
||||
// Open a .wmv file and prepare it for playing.
|
||||
// The format parameter specifies what type of texture it should be unpacked into ( if allocateTextures
|
||||
// is TRUE ). Only YUY2, LIN_X8R8G8B8 and LIN_A8R8G8B8 are supported as formats.
|
||||
// If you plan to play the movie with Play() or otherwise use overlays then format must be D3DFMT_YUY2
|
||||
// pDevice is needed in order to create textures.
|
||||
// allocateTextures should be TRUE if you plan to play the movie manually with AdvanceFrame.
|
||||
// It should be FALSE if you plan to play the movie with Play().
|
||||
// IsPlaying() will return TRUE if the movie opened successfully.
|
||||
HRESULT OpenFile( const CHAR* lpFilename, D3DFORMAT format, LPDIRECT3DDEVICE8 pDevice, BOOL bAllocateTextures );
|
||||
|
||||
// Open a file using the packet interface. This method of opening a .wmv file can be easily
|
||||
// customized to read the data from game specific file formats. The GetNextPacket and
|
||||
// ReleasePreviousPacket functions from XMVHelper.cpp are used to read the packets. See above for
|
||||
// information about the other parameters.
|
||||
HRESULT OpenFileForPackets( const CHAR* lpFilename, D3DFORMAT format, LPDIRECT3DDEVICE8 pDevice, BOOL bAllocateTextures );
|
||||
|
||||
// Open a block of memory for playing using the packet interface. This method of opening a .wmv file can be easily
|
||||
// customized to read the data from game specific file formats, or to retain the block of data in memory.
|
||||
// The GetNextMemoryPacket and ReleasePreviousMemoryPacket functions from XMVHelper.cpp are used to read
|
||||
// the packets. See above for information about the other parameters.
|
||||
HRESULT OpenMovieFromMemory( const CHAR* lpFilename, D3DFORMAT format, LPDIRECT3DDEVICE8 pDevice, BOOL bAllocateTextures );
|
||||
|
||||
// Destroy frees up all the movie resources. IsPlaying() will return FALSE afterwards. Destroy()
|
||||
// can be called during movie playback, but is not thread safe.
|
||||
HRESULT Destroy();
|
||||
|
||||
// The AdvanceFrame functions move to the next frame if it is time for that. Call this
|
||||
// function frequently - typically 30-60 times per second.
|
||||
|
||||
// AdvanceFrameForTexturing returns the most recent frame decoded, for texturing.
|
||||
// It will return zero if the first frame has not been decoded, but otherwise
|
||||
// will always return a texture.
|
||||
LPDIRECT3DTEXTURE8 AdvanceFrameForTexturing( LPDIRECT3DDEVICE8 pDevice );
|
||||
|
||||
// AdvanceFrameForOverlays returns newly decoded frames, for use as an overlays.
|
||||
// You MUST call UpdateOverlay() with the texture's surface.
|
||||
// It will return zero if there is not a *new* frame available.
|
||||
LPDIRECT3DTEXTURE8 AdvanceFrameForOverlays( LPDIRECT3DDEVICE8 pDevice );
|
||||
|
||||
// Get information about the movie playing.
|
||||
DWORD GetWidth() const { return m_VideoDesc.Width; }
|
||||
DWORD GetHeight() const { return m_VideoDesc.Height; }
|
||||
DWORD GetCurrentFrame() const { return m_dwCurrentFrame; }
|
||||
DWORD GetElapsedTime() const { return m_bPlaying ? GetTickCount() - m_dwStartTime : 0; }
|
||||
|
||||
// IsPlaying returns TRUE if a movie has been opened but has not ended or been destroyed.
|
||||
BOOL IsPlaying() const { return m_bPlaying; }
|
||||
BOOL IsFailed() const { return m_bError; }
|
||||
|
||||
// Call TerminatePlayback on the decoder. It may take a few hundred ms before the movie stops.
|
||||
// This function is thread safe, as long as you ensure that you don't call Destroy() in another
|
||||
// thread simultaneously.
|
||||
void TerminatePlayback();
|
||||
HRESULT Play( DWORD Flags, RECT* pRect );
|
||||
|
||||
// Call this to enable overlays if you will be playing the movie in an overlay using
|
||||
// AdvanceFrame. The overlays will be disabled when Destroy() is called.
|
||||
void EnableOverlays( LPDIRECT3DDEVICE8 pDevice );
|
||||
|
||||
private:
|
||||
XMVDecoder* m_pXMVDecoder; // Pointer to the XMV decoder object.
|
||||
XMVVIDEO_DESC m_VideoDesc; // Description of the .xmv files video data.
|
||||
XMVAUDIO_DESC m_AudioDesc; // Description of the .xmv files audio data.
|
||||
LPDIRECT3DTEXTURE8 m_pTextures[XMVPLAYER_NUMTEXTURES]; // Textures to cycle through.
|
||||
DWORD m_nDecodeTextureIndex; // Index of the current texture to decode to.
|
||||
|
||||
// These texture pointers are copies of the values in m_pTextures. They are used to track
|
||||
// the decode/display/pending status.
|
||||
// When displaying using textures pShowingTexture points to the texture to display,
|
||||
// pDecodingTexture points to the texture to decode into, and pSubmittedTexture is always
|
||||
// zero.
|
||||
// When displaying using overlays pShowingTexture points to the texture that the hardware
|
||||
// is currently displaying, pDecodingTexture points to the texture to decode into, and
|
||||
// pSubmittedTexture is a surface that has been submitted to the overlay system, but not
|
||||
// necessarily displayed yet. At any given time one of these is always zero. When
|
||||
// pDecodingTexture is zero that means that pShowingTexture might be being displayed, or
|
||||
// the hardware might have switched to pSubmittedTexture, we don't know yet.
|
||||
LPDIRECT3DTEXTURE8 pShowingTexture;
|
||||
LPDIRECT3DTEXTURE8 pDecodingTexture;
|
||||
LPDIRECT3DTEXTURE8 pSubmittedTexture;
|
||||
|
||||
int m_dwCurrentFrame; // Current frame number - minus one if not yet started.
|
||||
DWORD m_dwStartTime;
|
||||
|
||||
BOOL m_bPlaying; // Is a movie currently playing?
|
||||
BOOL m_bOverlaysEnabled; // Are overlays enabled? For disabling them on destroy.
|
||||
LPDIRECT3DDEVICE8 m_pDevice; // For use by Destroy to disable overlays.
|
||||
BOOL m_bError;
|
||||
|
||||
LOAD_CONTEXT m_loadContext; // Data for communicating with packet callback functions.
|
||||
|
||||
BYTE* m_physicalBuffer; // Pointer to block of physical memory used for loading packets.
|
||||
|
||||
// Helper function for opening files.
|
||||
HRESULT FinishOpeningFile( D3DFORMAT Format, LPDIRECT3DDEVICE8 pDevice, BOOL bAllocateTextures );
|
||||
|
||||
// Copy constructor and assignment operator are private and unimplemented
|
||||
// to prevent unintentional, unsupported, and disastrous copying.
|
||||
CXMVPlayer( const CXMVPlayer& source );
|
||||
CXMVPlayer& operator=( const CXMVPlayer& source );
|
||||
};
|
||||
|
||||
#endif //#ifndef _XMVPLAYER_H_
|
||||