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.

420 lines
16 KiB

  1. //===== Copyright � 1996-2010, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose: Utility class for discovering and caching path info on the PS3.
  4. //
  5. // $NoKeywords: $
  6. //===========================================================================//
  7. #ifndef SN_TARGET_PS3
  8. #error You're compiling this file on the wrong platform!
  9. #endif
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <cell/sysmodule.h>
  13. #include "../public/ps3_pathinfo.h"
  14. #include <sys/tty.h>
  15. #include "errorrenderloop.h"
  16. #include <np.h>
  17. // statically defined because not available in LauncherMain:
  18. #ifndef DBG_H
  19. static void LocalError( const char *fmt, ... )
  20. {
  21. va_list args;
  22. va_start(args, fmt);
  23. vprintf( fmt, args );
  24. ErrorRenderLoop loop;
  25. loop.Run();
  26. exit(1);
  27. }
  28. static void AssertMsg( bool cond, const char *complaint )
  29. {
  30. if (!cond)
  31. {
  32. LocalError(complaint);
  33. }
  34. }
  35. #else
  36. #define LocalError Error
  37. #endif
  38. #define CheckError( x, str ) if ( x < 0 ) { LocalError( "%s: %s\n", str, GetSonyErrorString( x ) ); return x; }
  39. #ifndef _CERT
  40. #define DiagnosticStringMode 1
  41. #define DiagnosticString( x ) do { unsigned int dummy; sys_tty_write( SYS_TTYP15, x, strlen( x ), &dummy ); } while(0)
  42. #else
  43. #define DiagnosticString( x ) ((void)0)
  44. #endif
  45. CPs3ContentPathInfo g_Ps3GameDataPathInfo;
  46. CPs3ContentPathInfo::CPs3ContentPathInfo() :
  47. m_bInitialized(false),
  48. m_nHDDFreeSizeKb( 0 ),
  49. m_nBootType( 0 ),
  50. m_nBootAttribs( 0 ),
  51. m_gameParentalLevel( 0 ),
  52. m_gameResolution( 0 ),
  53. m_gameSoundFormat( 0 )
  54. {
  55. #define GAME_INIT( x ) memset( x, 0, sizeof( x ) )
  56. GAME_INIT( m_gameTitle );
  57. GAME_INIT( m_gameTitleID );
  58. GAME_INIT( m_gameAppVer );
  59. GAME_INIT( m_gamePatchAppVer );
  60. GAME_INIT( m_gameContentPath );
  61. GAME_INIT( m_gamePatchContentPath );
  62. GAME_INIT( m_gameBasePath );
  63. GAME_INIT( m_gamePatchBasePath );
  64. GAME_INIT( m_gameExesPath );
  65. GAME_INIT( m_gameHDDataPath );
  66. GAME_INIT( m_gameImageDataPath );
  67. GAME_INIT( m_gameSystemCachePath );
  68. GAME_INIT( m_gameSavesShadowPath );
  69. #undef GAME_INIT
  70. }
  71. const char *GetSonyErrorString( int errorcode ) ; /// return a description for a CELL_GAME_ERROR code
  72. int CPs3ContentPathInfo::Init( unsigned int uiFlagsMask )
  73. {
  74. AssertMsg( !m_bInitialized, "CPs3ContentPathInfo is being initialized twice!\n" );
  75. /////////////////////////////////////////////////////////////////////////
  76. //
  77. // load sysutil NP
  78. //
  79. //////////////////////////////////////////////////////////////////////////
  80. // we'll need to haul libsysutil into memory ( CELL_SYSMODULE_SYSUTIL_NP )
  81. {
  82. int suc = cellSysmoduleLoadModule( CELL_SYSMODULE_SYSUTIL_NP );
  83. if ( suc != CELL_OK )
  84. {
  85. LocalError( "Failed to load sysutil_np: %s\n", GetSonyErrorString(suc) );
  86. return suc;
  87. }
  88. }
  89. /////////////////////////////////////////////////////////////////////////
  90. //
  91. // load sysutil GAME
  92. //
  93. //////////////////////////////////////////////////////////////////////////
  94. // we'll need to haul libsysutil into memory ( CELL_SYSMODULE_SYSUTIL_GAME )
  95. bool bSysModuleIsLoaded = cellSysmoduleIsLoaded( CELL_SYSMODULE_SYSUTIL_GAME ) == CELL_SYSMODULE_LOADED ;
  96. // if this assert trips, then:
  97. // 1) look at where the sysutil_game module is loaded to make sure it still needs to be loaded at this point (maybe you can dump it to save memory)
  98. // 2) if it's being taken care of somewhere else, we don't need to load the module here.
  99. AssertMsg( !bSysModuleIsLoaded, "The SYSUTIL_GAME module is already loaded -- revist load order logic in CPs3ContentPathInfo::Init()\n");
  100. if ( !bSysModuleIsLoaded )
  101. {
  102. int suc = cellSysmoduleLoadModule( CELL_SYSMODULE_SYSUTIL_GAME );
  103. if ( suc != CELL_OK )
  104. {
  105. LocalError( "Failed to load sysutil_game: %s\n", GetSonyErrorString(suc) );
  106. return suc;
  107. }
  108. }
  109. //////////////////////////////////////////////////////////////////////////
  110. //
  111. // cellGameBootCheck
  112. //
  113. //////////////////////////////////////////////////////////////////////////
  114. // get the base to the content directory.
  115. CellGameContentSize size; // For game content of a disc boot game, sizeKB and sysSizeKB take no meaning � please do not use them
  116. memset(&size, 0, sizeof(CellGameContentSize));
  117. char bootdir[CELL_GAME_DIRNAME_SIZE] = {0};
  118. int success = cellGameBootCheck( &m_nBootType, &m_nBootAttribs, &size, bootdir );
  119. if ( success != CELL_GAME_RET_OK )
  120. {
  121. LocalError("cellGameBootCheck failed (line %d, code %d): %s\n", __LINE__, success, GetSonyErrorString(success) );
  122. return success;
  123. }
  124. #if DiagnosticStringMode
  125. if ( m_nBootAttribs & CELL_GAME_ATTRIBUTE_DEBUG ) { DiagnosticString( "GAME BOOT: DEBUG MODE\n" ); }
  126. if ( m_nBootAttribs & CELL_GAME_ATTRIBUTE_APP_HOME ) { DiagnosticString( "GAME BOOT: HOSTFS MODE (app_home)\n" ); }
  127. if ( m_nBootAttribs & CELL_GAME_ATTRIBUTE_PATCH ) { DiagnosticString( "GAME BOOT: PATCH MODE\n" ); }
  128. if ( m_nBootAttribs & CELL_GAME_ATTRIBUTE_INVITE_MESSAGE ) { DiagnosticString( "GAME BOOT: INVITE MESSAGE\n" ); }
  129. if ( m_nBootAttribs & CELL_GAME_ATTRIBUTE_CUSTOM_DATA_MESSAGE ) { DiagnosticString( "GAME BOOT: CUSTOM DATA MESSAGE\n" ); }
  130. DiagnosticString( "BOOT DIR " ); DiagnosticString( bootdir ); DiagnosticString( "\n" );
  131. #endif
  132. m_bInitialized = true;
  133. m_nHDDFreeSizeKb = size.hddFreeSizeKB;
  134. //////////////////////////////////////////////////////////////////////////
  135. //
  136. // cellGameContentPermit
  137. //
  138. //////////////////////////////////////////////////////////////////////////
  139. if ( !( uiFlagsMask & INIT_RETAIL_MODE ) )
  140. {
  141. DiagnosticString( "BOOT INFO USING NON-RETAIL BOOT\n" );
  142. //
  143. // BOOT MODE required: PARAM.SFO
  144. //
  145. success = cellGameGetParamString( CELL_GAME_PARAMID_TITLE, m_gameTitle, sizeof( m_gameTitle ) ); CheckError( success, "PARAM.SFO getParam( CELL_GAME_PARAMID_TITLE )" );
  146. success = cellGameGetParamString( CELL_GAME_PARAMID_TITLE_ID, m_gameTitleID, sizeof( m_gameTitleID ) ); CheckError( success, "PARAM.SFO getParam( CELL_GAME_PARAMID_TITLE_ID )" );
  147. success = cellGameGetParamString( CELL_GAME_PARAMID_APP_VER, m_gameAppVer, sizeof( m_gameAppVer ) ); CheckError( success, "PARAM.SFO getParam( CELL_GAME_PARAMID_APP_VER )" );
  148. success = cellGameGetParamInt( CELL_GAME_PARAMID_PARENTAL_LEVEL, &m_gameParentalLevel ); CheckError( success, "PARAM.SFO getParam( CELL_GAME_PARAMID_PARENTAL_LEVEL )" );
  149. success = cellGameGetParamInt( CELL_GAME_PARAMID_RESOLUTION, &m_gameResolution ); CheckError( success, "PARAM.SFO getParam( CELL_GAME_PARAMID_RESOLUTION )" );
  150. success = cellGameGetParamInt( CELL_GAME_PARAMID_SOUND_FORMAT, &m_gameSoundFormat ); CheckError( success, "PARAM.SFO getParam( CELL_GAME_PARAMID_SOUND_FORMAT )" );
  151. // Access /app_home/...
  152. success = cellGameContentPermit( m_gameContentPath, m_gameBasePath ) ;
  153. DiagnosticString( "BOOT ROOT " ); DiagnosticString( m_gameContentPath ); DiagnosticString( "\n" );
  154. DiagnosticString( "BOOT USR " ); DiagnosticString( m_gameBasePath ); DiagnosticString( "\n" );
  155. // when running the game from the debugger, the data path returned by ContentPermit contains
  156. // HOSTFS formatted path like /app_home/D:\perforce\...
  157. // Perform the fixup to conform to disk image layout
  158. if ( (m_nBootAttribs & CELL_GAME_ATTRIBUTE_DEBUG) && !strncmp( m_gameBasePath, "/app_home", sizeof( "/app_home" ) - 1 ) )
  159. {
  160. snprintf( m_gameContentPath, sizeof( m_gameContentPath ) - 1, "/app_home/PS3_GAME" );
  161. snprintf( m_gameBasePath, sizeof( m_gameBasePath ) - 1, "/app_home/PS3_GAME/USRDIR" );
  162. DiagnosticString( "BOOT ROOT/ " ); DiagnosticString( m_gameContentPath ); DiagnosticString( "\n" );
  163. DiagnosticString( "BOOT USR// " ); DiagnosticString( m_gameBasePath ); DiagnosticString( "\n" );
  164. }
  165. }
  166. else
  167. {
  168. if ( m_nBootType != CELL_GAME_GAMETYPE_DISC )
  169. {
  170. LocalError("Only disk boot is supported in RETAIL mode! (bootmode=%d)\n", m_nBootType );
  171. return -1;
  172. }
  173. // Finish access to boot executable
  174. {
  175. char tmp_contentInfoPath[CELL_GAME_PATH_MAX] = {0};
  176. char tmp_usrdirPath[CELL_GAME_PATH_MAX] = {0};
  177. success = cellGameContentPermit( tmp_contentInfoPath, tmp_usrdirPath ); // must call this to allow mounting of BDVD
  178. DiagnosticString( "BOOT ROOT " ); DiagnosticString( tmp_contentInfoPath ); DiagnosticString( "\n" );
  179. DiagnosticString( "BOOT USR " ); DiagnosticString( tmp_usrdirPath ); DiagnosticString( "\n" );
  180. }
  181. // in RETAIL mode we always have our assets on BDVD
  182. success = cellGameDataCheck( m_nBootType, NULL, &size);
  183. if ( success == CELL_GAME_RET_OK )
  184. {
  185. //
  186. // BOOT MODE required: PARAM.SFO
  187. //
  188. success = cellGameGetParamString( CELL_GAME_PARAMID_TITLE, m_gameTitle, sizeof( m_gameTitle ) ); CheckError( success, "PARAM.SFO getParam( CELL_GAME_PARAMID_TITLE )" );
  189. success = cellGameGetParamString( CELL_GAME_PARAMID_TITLE_ID, m_gameTitleID, sizeof( m_gameTitleID ) ); CheckError( success, "PARAM.SFO getParam( CELL_GAME_PARAMID_TITLE_ID )" );
  190. success = cellGameGetParamString( CELL_GAME_PARAMID_APP_VER, m_gameAppVer, sizeof( m_gameAppVer ) ); CheckError( success, "PARAM.SFO getParam( CELL_GAME_PARAMID_APP_VER )" );
  191. success = cellGameGetParamInt( CELL_GAME_PARAMID_PARENTAL_LEVEL, &m_gameParentalLevel ); CheckError( success, "PARAM.SFO getParam( CELL_GAME_PARAMID_PARENTAL_LEVEL )" );
  192. success = cellGameGetParamInt( CELL_GAME_PARAMID_RESOLUTION, &m_gameResolution ); CheckError( success, "PARAM.SFO getParam( CELL_GAME_PARAMID_RESOLUTION )" );
  193. success = cellGameGetParamInt( CELL_GAME_PARAMID_SOUND_FORMAT, &m_gameSoundFormat ); CheckError( success, "PARAM.SFO getParam( CELL_GAME_PARAMID_SOUND_FORMAT )" );
  194. // Access BDVD:
  195. success = cellGameContentPermit( m_gameContentPath, m_gameBasePath ) ;
  196. }
  197. else
  198. {
  199. LocalError("cellGameDataCheck failed (line %d, code %d): %s\n", __LINE__, success, GetSonyErrorString(success) );
  200. return success;
  201. }
  202. }
  203. DiagnosticString( "-----------PARAM.SFO----------" );
  204. DiagnosticString( "\nTITLE " ); DiagnosticString( m_gameTitle );
  205. DiagnosticString( "\nTITLE ID " ); DiagnosticString( m_gameTitleID );
  206. DiagnosticString( "\nAPP_VER " ); DiagnosticString( m_gameAppVer );
  207. if ( m_nBootAttribs & CELL_GAME_ATTRIBUTE_PATCH )
  208. {
  209. CellGameContentSize cgcs;
  210. memset( &cgcs, 0, sizeof(CellGameContentSize) );
  211. success = cellGamePatchCheck( &cgcs, NULL );
  212. if ( success == CELL_GAME_RET_OK )
  213. {
  214. success = cellGameGetParamString( CELL_GAME_PARAMID_APP_VER, m_gamePatchAppVer, sizeof( m_gamePatchAppVer ) ); CheckError( success, "PARAM.SFO PATCH getParam( CELL_GAME_PARAMID_APP_VER )" );
  215. DiagnosticString( "\nAPP_VER****" ); DiagnosticString( m_gamePatchAppVer );
  216. success = cellGameContentPermit( m_gamePatchContentPath, m_gamePatchBasePath ) ;
  217. }
  218. else
  219. {
  220. LocalError("cellGamePatchCheck failed (line %d, code %d): %s\n", __LINE__, success, GetSonyErrorString(success) );
  221. return success;
  222. }
  223. }
  224. DiagnosticString( "\n------------------------------\n" );
  225. //////////////////////////////////////////////////////////////////////////
  226. //
  227. // filesystem path setup
  228. //
  229. //////////////////////////////////////////////////////////////////////////
  230. DiagnosticString( "----------FILESYSTEM----------" );
  231. DiagnosticString( "\nPS3_GAME " ); DiagnosticString( m_gameContentPath );
  232. DiagnosticString( "\nUSRDIR " ); DiagnosticString( m_gameBasePath );
  233. if ( m_nBootAttribs & CELL_GAME_ATTRIBUTE_PATCH )
  234. {
  235. DiagnosticString( "\nPS3_GAME***" ); DiagnosticString( m_gamePatchContentPath );
  236. DiagnosticString( "\nUSRDIR*****" ); DiagnosticString( m_gamePatchBasePath );
  237. }
  238. #if 0
  239. // Get the game data directory on the hard disk.
  240. success = cellGameDataCheck( CELL_GAME_GAMETYPE_GAMEDATA, m_gameTitleID, &size );
  241. if ( success == CELL_GAME_RET_NONE )
  242. {
  243. CellGameSetInitParams init; memset( &init, 0, sizeof( init ) );
  244. memcpy( init.title, m_gameTitle, sizeof( m_gameTitle ) );
  245. memcpy( init.titleId, m_gameTitleID, sizeof( m_gameTitleID ) );
  246. memcpy( init.version, m_gameAppVer, sizeof( m_gameAppVer ) );
  247. char tmp_contentInfoPath[CELL_GAME_PATH_MAX] = {0};
  248. char tmp_usrdirPath[CELL_GAME_PATH_MAX] = {0};
  249. success = cellGameCreateGameData( &init, tmp_contentInfoPath, tmp_usrdirPath );
  250. DiagnosticString( "\nTMP_GAME " ); DiagnosticString( tmp_contentInfoPath );
  251. DiagnosticString( "\nTMP_USRD " ); DiagnosticString( tmp_usrdirPath );
  252. }
  253. char contentInfoPath[256];
  254. if ( success == CELL_GAME_RET_OK )
  255. {
  256. success = cellGameContentPermit( contentInfoPath, m_gameHDDataPath );
  257. }
  258. #else
  259. snprintf( m_gameHDDataPath, sizeof( m_gameHDDataPath ), "/dev_hdd0/game/NPUB30589/USRDIR" );
  260. //snprintf( m_gameHDDataPath, sizeof( m_gameHDDataPath ), "/dev_hdd0/game/BLUS30732/USRDIR" );
  261. #endif
  262. DiagnosticString( "\nHDD_PATH " ); DiagnosticString( m_gameHDDataPath );
  263. // Mount system cache
  264. if ( success >= CELL_GAME_RET_OK )
  265. {
  266. CellSysCacheParam sysCacheParams;
  267. memset( &sysCacheParams, 0, sizeof( CellSysCacheParam ) );
  268. memcpy( sysCacheParams.cacheId, GetWWMASTER_TitleID(), 10 );
  269. success = cellSysCacheMount( &sysCacheParams );
  270. if ( success >= CELL_GAME_RET_OK )
  271. {
  272. memcpy( m_gameSystemCachePath, sysCacheParams.getCachePath, sizeof( m_gameSystemCachePath ) );
  273. if ( uiFlagsMask & INIT_SYS_CACHE_CLEAR )
  274. cellSysCacheClear();
  275. }
  276. }
  277. DiagnosticString( "\nSYS_CACH " ); DiagnosticString( m_gameSystemCachePath );
  278. // Determine where image files (maps, zips, etc.) are located:
  279. snprintf( m_gameImageDataPath, sizeof( m_gameImageDataPath ), m_gameBasePath );
  280. if ( uiFlagsMask & INIT_IMAGE_APP_HOME )
  281. snprintf( m_gameImageDataPath, sizeof( m_gameImageDataPath ), "/app_home/PS3_GAME/USRDIR" );
  282. else if ( uiFlagsMask & INIT_IMAGE_ON_HDD )
  283. snprintf( m_gameImageDataPath, sizeof( m_gameImageDataPath ), m_gameHDDataPath );
  284. else if ( uiFlagsMask & INIT_IMAGE_ON_BDVD )
  285. snprintf( m_gameImageDataPath, sizeof( m_gameImageDataPath ), "/dev_bdvd/PS3_GAME/USRDIR" );
  286. DiagnosticString( "\nIMAGE_PATH " ); DiagnosticString( m_gameImageDataPath );
  287. // Determine where PRX files are located:
  288. snprintf( m_gameExesPath, sizeof( m_gameExesPath ), "%s/bin", m_gameBasePath );
  289. if ( uiFlagsMask & INIT_PRX_APP_HOME )
  290. snprintf( m_gameExesPath, sizeof( m_gameExesPath ), "/app_home/PS3_GAME/USRDIR/bin" );
  291. else if ( uiFlagsMask & INIT_PRX_ON_HDD )
  292. snprintf( m_gameExesPath, sizeof( m_gameExesPath ), "%s/bin", m_gameHDDataPath );
  293. else if ( uiFlagsMask & INIT_PRX_ON_BDVD )
  294. snprintf( m_gameExesPath, sizeof( m_gameExesPath ), "/dev_bdvd/PS3_GAME/USRDIR/bin" );
  295. DiagnosticString( "\nPRX_PATH " ); DiagnosticString( m_gameExesPath );
  296. DiagnosticString( "\n------------------------------\n" );
  297. // we cache the saves to a local directory -- keep that info here so it's in a uniform
  298. // place accessible from everywhere.
  299. strncpy( m_gameSavesShadowPath, m_gameSystemCachePath, sizeof(m_gameSavesShadowPath) );
  300. strncat( m_gameSavesShadowPath, "/tempsave/", sizeof(m_gameSavesShadowPath) );
  301. //////////////////////////////////////////////////////////////////////////
  302. //
  303. // finished
  304. //
  305. //////////////////////////////////////////////////////////////////////////
  306. if ( !bSysModuleIsLoaded ) // actually this means it wasn't loaded when we got into the function
  307. {
  308. cellSysmoduleUnloadModule( CELL_SYSMODULE_SYSUTIL_GAME );
  309. }
  310. return success;
  311. }
  312. const char *GetSonyErrorString( int errorcode )
  313. {
  314. switch( errorcode )
  315. {
  316. case CELL_GAME_RET_OK:
  317. return "CELL_GAME_RET_OK";
  318. case CELL_GAME_ERROR_ACCESS_ERROR:
  319. return "HDD access error";
  320. case CELL_GAME_ERROR_BUSY:
  321. return "The call of an access preparing function was repeated";
  322. case CELL_GAME_ERROR_IN_SHUTDOWN:
  323. return "Processing cannot be executed because application termination is being processed";
  324. case CELL_GAME_ERROR_INTERNAL:
  325. return "Fatal error occurred in the utility";
  326. case CELL_GAME_ERROR_PARAM:
  327. return "There is an error in the argument (application bug)";
  328. case CELL_GAME_ERROR_BOOTPATH:
  329. return "Pathname of booted program file is too long" ;
  330. case CELL_SYSMODULE_ERROR_UNKNOWN:
  331. return "Tried to load an unknown PRX";
  332. case CELL_SYSMODULE_ERROR_FATAL:
  333. return "Sysmodule PRX load failed";
  334. case CELL_GAME_ERROR_BROKEN:
  335. return "The specified game content is corrupted";
  336. default:
  337. return "Unknown error code";
  338. }
  339. }
  340. /* The boot attributes member of CPs3ContentPathInfo is some combination of:
  341. CELL_GAME_ATTRIBUTE_PATCH Booted from a patch (only for a disc boot game)
  342. CELL_GAME_ATTRIBUTE_APP_HOME Booted from the host machine (development machine only)
  343. CELL_GAME_ATTRIBUTE_DEBUG Booted from the debugger (development machine only)
  344. CELL_GAME_ATTRIBUTE_XMBBUY Rebooted from the game purchasing feature of the NP DRM utility
  345. CELL_GAME_ATTRIBUTE_COMMERCE2_BROWSER Rebooted from the store browsing feature of the NP IN-GAME commerce 2 utility
  346. CELL_GAME_ATTRIBUTE_INVITE_MESSAGE Booted from the game boot invitation message of the NP basic utility
  347. CELL_GAME_ATTRIBUTE_CUSTOM_DATA_MESSAGE Booted from a message with a custom data attachment of the NP basic utility
  348. CELL_GAME_ATTRIBUTE_WEB_BROWSER Booted from the full browser feature of the web browser utility
  349. */