Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

198 lines
6.7 KiB

//===== Copyright © 1996-2011, Valve Corporation, All rights reserved. ======//
#include "ps3_saveutil_v2.h"
#include "fmtstr.h"
#include "checksum_crc.h"
#include "memdbgon.h"
CON_COMMAND( ps3_saveutil_showtoc, "" )
{
AUTO_LOCK( g_SaveUtilV2TOC.m_mtx );
int numTocEntries = g_SaveUtilV2TOC.m_arrEntries.Count();
Msg( "--------- SAVEUTILTOC -----------\n" );
for ( int k = 0; k < numTocEntries; ++ k )
{
CSaveUtilV2ContainerTOC::TocEntry_t &e = g_SaveUtilV2TOC.m_arrEntries[k].m_entry;
Msg( "%02d : %016llx %s\n"
" '%s' %u/%u\n"
" '%s' %u/%u\n"
" %s\n",
k + 1, e.m_timeModification, e.m_chContainerName,
e.m_chFile[0], e.m_numBytesFile[0], e.m_numBytesDecompressedFile[0],
e.m_chFile[1], e.m_numBytesFile[1], e.m_numBytesDecompressedFile[1],
e.m_chComment
);
}
Msg( "--------- %02d ENTRIES -----------\n", numTocEntries );
}
void SaveUtilV2_GetFileInfoSync( CUtlVector< IPS3SaveRestoreToUI::PS3SaveGameInfo_t > &saveGameInfos, bool bFindAll )
{
// This can be called after starting a save op but before it completes, so this will return old data in that case.
// The caller should be aware that if SaveUtil is busy then it can check the operation TAG and know what is in
// progress and whether it can affect the TOC after it's finished.
// Currently only UI queries the TOC and ensures that writes of savegames are completed before queries.
AUTO_LOCK( g_SaveUtilV2TOC.m_mtx );
if ( !g_SaveUtilV2TOC.m_arrEntries.Count() )
{
saveGameInfos.RemoveAll();
return;
}
int numTocEntries = bFindAll ? g_SaveUtilV2TOC.m_arrEntries.Count() : 1;
saveGameInfos.SetCount( numTocEntries );
for ( int k = 0; k < numTocEntries; ++ k )
{
saveGameInfos[k].m_InternalName = CFmtStr( "!%s", g_SaveUtilV2TOC.m_arrEntries[k].m_entry.m_chContainerName );
saveGameInfos[k].m_Comment = g_SaveUtilV2TOC.m_arrEntries[k].m_entry.m_chComment;
saveGameInfos[k].m_Filename = g_SaveUtilV2TOC.m_arrEntries[k].m_entry.m_chFile[0];
saveGameInfos[k].m_ScreenshotFilename = g_SaveUtilV2TOC.m_arrEntries[k].m_entry.m_chFile[1];
saveGameInfos[k].m_nFileTime = g_SaveUtilV2TOC.m_arrEntries[k].m_entry.m_timeModification;
}
}
//////////////////////////////////////////////////////////////////////////
bool SaveUtilV2_CanStartJob()
{
bool bResult = ( g_pSaveUtilThreadPool && !g_pSaveUtilAsyncStatus );
if ( !bResult )
{
Warning( "SaveUtilV2_CanStartJob : cannot start job now! Invalid usage!\n" );
Assert( 0 );
}
return bResult;
}
void SaveUtilV2_EnqueueJob( CPS3SaveRestoreAsyncStatus *pAsync, ISaveUtilV2Job *pJob )
{
if ( g_pSaveUtilAsyncStatus )
Error( "SaveUtilV2_EnqueueJob while job already running ( %p running, %p attempted )!\n", g_pSaveUtilAsyncStatus, pAsync );
g_pSaveUtilAsyncStatus = pAsync;
// Prepare for saveutil operation
const int numContainers = VALVE_CONTAINER_COUNT;
pJob->m_bufSaveDirList.EnsureCapacity( numContainers * MAX( sizeof( CellSaveDataFileStat ), sizeof( CellSaveDataDirList ) ) );
// Prepare save dir info
memset( &pJob->m_SaveDirInfo, 0, sizeof(CellSaveDataSetBuf) );
pJob->m_SaveDirInfo.dirListMax = numContainers;
pJob->m_SaveDirInfo.fileListMax = numContainers;
pJob->m_SaveDirInfo.bufSize = pJob->m_bufSaveDirList.Size();
pJob->m_SaveDirInfo.buf = pJob->m_bufSaveDirList.Base();
// Mark the job as pending
g_pSaveUtilAsyncStatus->m_nSonyRetValue = CELL_SAVEDATA_ERROR_NOTSUPPORTED;
g_pSaveUtilAsyncStatus->m_bDone = 0;
// Let's notify the file system that a save is starting, that way the file system can try to reduce HDD accesses and use BluRay instead
g_pFullFileSystem->OnSaveStateChanged( true );
// Add the job to thread pool
pJob->SetFlags( JF_SERIAL | JF_QUEUE );
g_pSaveUtilThreadPool->AddJob( pJob );
pJob->Release();
}
JobStatus_t SaveUtilV2_JobDone( int nErrorCode )
{
// Let's notify the file system that a save is finished, that way the file system can restart using the HDD
g_pFullFileSystem->OnSaveStateChanged( false );
// Set the job error code and set that the job is done
if ( nErrorCode != CELL_SAVEDATA_ERROR_CBRESULT )
g_pSaveUtilAsyncStatus->m_nSonyRetValue = nErrorCode;
else if ( g_pSaveUtilAsyncStatus->m_nSonyRetValue >= 0 )
g_pSaveUtilAsyncStatus->m_nSonyRetValue = CELL_SAVEDATA_ERROR_FAILURE;
CPS3SaveRestoreAsyncStatus *pAsync = g_pSaveUtilAsyncStatus;
g_pSaveUtilAsyncStatus = NULL;
pAsync->m_bDone = 1;
return JOB_OK;
}
uint32 SaveUtilV2_ComputeBufferHash( void const *pvData, uint32 numBytes )
{
return CRC32_ProcessSingleBuffer( pvData, numBytes );
}
//////////////////////////////////////////////////////////////////////////
void ISaveUtilV2Job::csDataStatCallback( SONY_SAVEUTIL_STAT_PARAMS )
{
ISaveUtilV2Job *pSelf = static_cast<ISaveUtilV2Job*>( cbResult->userdata );
pSelf->DoDataStatCallback( SONY_SAVEUTIL_PARAMS );
}
void ISaveUtilV2Job::csDataFileCallback( SONY_SAVEUTIL_FILE_PARAMS )
{
ISaveUtilV2Job *pSelf = static_cast<ISaveUtilV2Job*>( cbResult->userdata );
if ( pSelf->m_pfnDoDataFileCallback )
{
(pSelf->*(pSelf->m_pfnDoDataFileCallback))( SONY_SAVEUTIL_PARAMS );
}
else
{
Msg( "ISaveUtilV2Job::csDataFileCallback finalizing save operation @%.3f\n", Plat_FloatTime() );
cbResult->result = CELL_SAVEDATA_CBRESULT_OK_LAST;
}
}
//////////////////////////////////////////////////////////////////////////
void CSaveUtilV2ContainerTOC::SerializeIntoTocBuffer( void *pvBuffer )
{
uint32 *pui32 = (uint32*) pvBuffer;
*( pui32 ++ ) = m_idxNewSaveName;
*( pui32 ++ ) = m_arrEntries.Count();
V_memcpy( pui32, m_arrEntries.Base(), m_arrEntries.Count() * sizeof( TocStorageReserved_t ) );
}
void CSaveUtilV2ContainerTOC::SerializeFromTocBuffer( void *pvBuffer )
{
uint32 *pui32 = (uint32*) pvBuffer;
m_idxNewSaveName = *( pui32 ++ );
uint32 uiEntriesCount = *( pui32 ++ );
uiEntriesCount = MIN( uiEntriesCount, VALVE_CONTAINER_COUNT );
m_arrEntries.AddMultipleToTail( uiEntriesCount, reinterpret_cast< TocStorageReserved_t * >( pui32 ) );
}
void CSaveUtilV2ContainerTOC::CopyInto( CSaveUtilV2ContainerTOC *pOther )
{
pOther->m_idxNewSaveName = m_idxNewSaveName;
pOther->m_arrEntries.RemoveAll();
pOther->m_arrEntries.AddMultipleToTail( m_arrEntries.Count(), m_arrEntries.Base() );
}
int CSaveUtilV2ContainerTOC::FindByEmbeddedFileName( char const *szFilename, int *pnPartIndex )
{
for ( int k = 0; k < m_arrEntries.Count(); ++ k )
{
if ( szFilename[0] == '!' )
{
if ( V_stricmp( m_arrEntries[k].m_entry.m_chContainerName, szFilename + 1 ) )
continue;
if ( pnPartIndex )
*pnPartIndex = 0;
return k;
}
for ( int iPart = 0; iPart < VALVE_CONTAINER_FPARTS; ++ iPart )
{
if ( !V_stricmp( m_arrEntries[k].m_entry.m_chFile[iPart], szFilename ) )
{
if ( pnPartIndex )
*pnPartIndex = iPart;
return k;
}
}
}
if ( pnPartIndex )
*pnPartIndex = -1;
return -1;
}