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

  1. //===== Copyright � 1996-2011, Valve Corporation, All rights reserved. ======//
  2. #include "ps3_saveutil_v2.h"
  3. #include "fmtstr.h"
  4. #include "checksum_crc.h"
  5. #include "memdbgon.h"
  6. CON_COMMAND( ps3_saveutil_showtoc, "" )
  7. {
  8. AUTO_LOCK( g_SaveUtilV2TOC.m_mtx );
  9. int numTocEntries = g_SaveUtilV2TOC.m_arrEntries.Count();
  10. Msg( "--------- SAVEUTILTOC -----------\n" );
  11. for ( int k = 0; k < numTocEntries; ++ k )
  12. {
  13. CSaveUtilV2ContainerTOC::TocEntry_t &e = g_SaveUtilV2TOC.m_arrEntries[k].m_entry;
  14. Msg( "%02d : %016llx %s\n"
  15. " '%s' %u/%u\n"
  16. " '%s' %u/%u\n"
  17. " %s\n",
  18. k + 1, e.m_timeModification, e.m_chContainerName,
  19. e.m_chFile[0], e.m_numBytesFile[0], e.m_numBytesDecompressedFile[0],
  20. e.m_chFile[1], e.m_numBytesFile[1], e.m_numBytesDecompressedFile[1],
  21. e.m_chComment
  22. );
  23. }
  24. Msg( "--------- %02d ENTRIES -----------\n", numTocEntries );
  25. }
  26. void SaveUtilV2_GetFileInfoSync( CUtlVector< IPS3SaveRestoreToUI::PS3SaveGameInfo_t > &saveGameInfos, bool bFindAll )
  27. {
  28. // This can be called after starting a save op but before it completes, so this will return old data in that case.
  29. // The caller should be aware that if SaveUtil is busy then it can check the operation TAG and know what is in
  30. // progress and whether it can affect the TOC after it's finished.
  31. // Currently only UI queries the TOC and ensures that writes of savegames are completed before queries.
  32. AUTO_LOCK( g_SaveUtilV2TOC.m_mtx );
  33. if ( !g_SaveUtilV2TOC.m_arrEntries.Count() )
  34. {
  35. saveGameInfos.RemoveAll();
  36. return;
  37. }
  38. int numTocEntries = bFindAll ? g_SaveUtilV2TOC.m_arrEntries.Count() : 1;
  39. saveGameInfos.SetCount( numTocEntries );
  40. for ( int k = 0; k < numTocEntries; ++ k )
  41. {
  42. saveGameInfos[k].m_InternalName = CFmtStr( "!%s", g_SaveUtilV2TOC.m_arrEntries[k].m_entry.m_chContainerName );
  43. saveGameInfos[k].m_Comment = g_SaveUtilV2TOC.m_arrEntries[k].m_entry.m_chComment;
  44. saveGameInfos[k].m_Filename = g_SaveUtilV2TOC.m_arrEntries[k].m_entry.m_chFile[0];
  45. saveGameInfos[k].m_ScreenshotFilename = g_SaveUtilV2TOC.m_arrEntries[k].m_entry.m_chFile[1];
  46. saveGameInfos[k].m_nFileTime = g_SaveUtilV2TOC.m_arrEntries[k].m_entry.m_timeModification;
  47. }
  48. }
  49. //////////////////////////////////////////////////////////////////////////
  50. bool SaveUtilV2_CanStartJob()
  51. {
  52. bool bResult = ( g_pSaveUtilThreadPool && !g_pSaveUtilAsyncStatus );
  53. if ( !bResult )
  54. {
  55. Warning( "SaveUtilV2_CanStartJob : cannot start job now! Invalid usage!\n" );
  56. Assert( 0 );
  57. }
  58. return bResult;
  59. }
  60. void SaveUtilV2_EnqueueJob( CPS3SaveRestoreAsyncStatus *pAsync, ISaveUtilV2Job *pJob )
  61. {
  62. if ( g_pSaveUtilAsyncStatus )
  63. Error( "SaveUtilV2_EnqueueJob while job already running ( %p running, %p attempted )!\n", g_pSaveUtilAsyncStatus, pAsync );
  64. g_pSaveUtilAsyncStatus = pAsync;
  65. // Prepare for saveutil operation
  66. const int numContainers = VALVE_CONTAINER_COUNT;
  67. pJob->m_bufSaveDirList.EnsureCapacity( numContainers * MAX( sizeof( CellSaveDataFileStat ), sizeof( CellSaveDataDirList ) ) );
  68. // Prepare save dir info
  69. memset( &pJob->m_SaveDirInfo, 0, sizeof(CellSaveDataSetBuf) );
  70. pJob->m_SaveDirInfo.dirListMax = numContainers;
  71. pJob->m_SaveDirInfo.fileListMax = numContainers;
  72. pJob->m_SaveDirInfo.bufSize = pJob->m_bufSaveDirList.Size();
  73. pJob->m_SaveDirInfo.buf = pJob->m_bufSaveDirList.Base();
  74. // Mark the job as pending
  75. g_pSaveUtilAsyncStatus->m_nSonyRetValue = CELL_SAVEDATA_ERROR_NOTSUPPORTED;
  76. g_pSaveUtilAsyncStatus->m_bDone = 0;
  77. // 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
  78. g_pFullFileSystem->OnSaveStateChanged( true );
  79. // Add the job to thread pool
  80. pJob->SetFlags( JF_SERIAL | JF_QUEUE );
  81. g_pSaveUtilThreadPool->AddJob( pJob );
  82. pJob->Release();
  83. }
  84. JobStatus_t SaveUtilV2_JobDone( int nErrorCode )
  85. {
  86. // Let's notify the file system that a save is finished, that way the file system can restart using the HDD
  87. g_pFullFileSystem->OnSaveStateChanged( false );
  88. // Set the job error code and set that the job is done
  89. if ( nErrorCode != CELL_SAVEDATA_ERROR_CBRESULT )
  90. g_pSaveUtilAsyncStatus->m_nSonyRetValue = nErrorCode;
  91. else if ( g_pSaveUtilAsyncStatus->m_nSonyRetValue >= 0 )
  92. g_pSaveUtilAsyncStatus->m_nSonyRetValue = CELL_SAVEDATA_ERROR_FAILURE;
  93. CPS3SaveRestoreAsyncStatus *pAsync = g_pSaveUtilAsyncStatus;
  94. g_pSaveUtilAsyncStatus = NULL;
  95. pAsync->m_bDone = 1;
  96. return JOB_OK;
  97. }
  98. uint32 SaveUtilV2_ComputeBufferHash( void const *pvData, uint32 numBytes )
  99. {
  100. return CRC32_ProcessSingleBuffer( pvData, numBytes );
  101. }
  102. //////////////////////////////////////////////////////////////////////////
  103. void ISaveUtilV2Job::csDataStatCallback( SONY_SAVEUTIL_STAT_PARAMS )
  104. {
  105. ISaveUtilV2Job *pSelf = static_cast<ISaveUtilV2Job*>( cbResult->userdata );
  106. pSelf->DoDataStatCallback( SONY_SAVEUTIL_PARAMS );
  107. }
  108. void ISaveUtilV2Job::csDataFileCallback( SONY_SAVEUTIL_FILE_PARAMS )
  109. {
  110. ISaveUtilV2Job *pSelf = static_cast<ISaveUtilV2Job*>( cbResult->userdata );
  111. if ( pSelf->m_pfnDoDataFileCallback )
  112. {
  113. (pSelf->*(pSelf->m_pfnDoDataFileCallback))( SONY_SAVEUTIL_PARAMS );
  114. }
  115. else
  116. {
  117. Msg( "ISaveUtilV2Job::csDataFileCallback finalizing save operation @%.3f\n", Plat_FloatTime() );
  118. cbResult->result = CELL_SAVEDATA_CBRESULT_OK_LAST;
  119. }
  120. }
  121. //////////////////////////////////////////////////////////////////////////
  122. void CSaveUtilV2ContainerTOC::SerializeIntoTocBuffer( void *pvBuffer )
  123. {
  124. uint32 *pui32 = (uint32*) pvBuffer;
  125. *( pui32 ++ ) = m_idxNewSaveName;
  126. *( pui32 ++ ) = m_arrEntries.Count();
  127. V_memcpy( pui32, m_arrEntries.Base(), m_arrEntries.Count() * sizeof( TocStorageReserved_t ) );
  128. }
  129. void CSaveUtilV2ContainerTOC::SerializeFromTocBuffer( void *pvBuffer )
  130. {
  131. uint32 *pui32 = (uint32*) pvBuffer;
  132. m_idxNewSaveName = *( pui32 ++ );
  133. uint32 uiEntriesCount = *( pui32 ++ );
  134. uiEntriesCount = MIN( uiEntriesCount, VALVE_CONTAINER_COUNT );
  135. m_arrEntries.AddMultipleToTail( uiEntriesCount, reinterpret_cast< TocStorageReserved_t * >( pui32 ) );
  136. }
  137. void CSaveUtilV2ContainerTOC::CopyInto( CSaveUtilV2ContainerTOC *pOther )
  138. {
  139. pOther->m_idxNewSaveName = m_idxNewSaveName;
  140. pOther->m_arrEntries.RemoveAll();
  141. pOther->m_arrEntries.AddMultipleToTail( m_arrEntries.Count(), m_arrEntries.Base() );
  142. }
  143. int CSaveUtilV2ContainerTOC::FindByEmbeddedFileName( char const *szFilename, int *pnPartIndex )
  144. {
  145. for ( int k = 0; k < m_arrEntries.Count(); ++ k )
  146. {
  147. if ( szFilename[0] == '!' )
  148. {
  149. if ( V_stricmp( m_arrEntries[k].m_entry.m_chContainerName, szFilename + 1 ) )
  150. continue;
  151. if ( pnPartIndex )
  152. *pnPartIndex = 0;
  153. return k;
  154. }
  155. for ( int iPart = 0; iPart < VALVE_CONTAINER_FPARTS; ++ iPart )
  156. {
  157. if ( !V_stricmp( m_arrEntries[k].m_entry.m_chFile[iPart], szFilename ) )
  158. {
  159. if ( pnPartIndex )
  160. *pnPartIndex = iPart;
  161. return k;
  162. }
  163. }
  164. }
  165. if ( pnPartIndex )
  166. *pnPartIndex = -1;
  167. return -1;
  168. }