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.
 
 
 
 
 
 

421 lines
16 KiB

//===== Copyright © 1996-2010, Valve Corporation, All rights reserved. ======//
//
// Purpose: Utility class for discovering and caching path info on the PS3.
//
// $NoKeywords: $
//===========================================================================//
#ifndef SN_TARGET_PS3
#error You're compiling this file on the wrong platform!
#endif
#include <stdlib.h>
#include <string.h>
#include <cell/sysmodule.h>
#include "../public/ps3_pathinfo.h"
#include <sys/tty.h>
#include "errorrenderloop.h"
#include <np.h>
// statically defined because not available in LauncherMain:
#ifndef DBG_H
static void LocalError( const char *fmt, ... )
{
va_list args;
va_start(args, fmt);
vprintf( fmt, args );
ErrorRenderLoop loop;
loop.Run();
exit(1);
}
static void AssertMsg( bool cond, const char *complaint )
{
if (!cond)
{
LocalError(complaint);
}
}
#else
#define LocalError Error
#endif
#define CheckError( x, str ) if ( x < 0 ) { LocalError( "%s: %s\n", str, GetSonyErrorString( x ) ); return x; }
#ifndef _CERT
#define DiagnosticStringMode 1
#define DiagnosticString( x ) do { unsigned int dummy; sys_tty_write( SYS_TTYP15, x, strlen( x ), &dummy ); } while(0)
#else
#define DiagnosticString( x ) ((void)0)
#endif
CPs3ContentPathInfo g_Ps3GameDataPathInfo;
CPs3ContentPathInfo::CPs3ContentPathInfo() :
m_bInitialized(false),
m_nHDDFreeSizeKb( 0 ),
m_nBootType( 0 ),
m_nBootAttribs( 0 ),
m_gameParentalLevel( 0 ),
m_gameResolution( 0 ),
m_gameSoundFormat( 0 )
{
#define GAME_INIT( x ) memset( x, 0, sizeof( x ) )
GAME_INIT( m_gameTitle );
GAME_INIT( m_gameTitleID );
GAME_INIT( m_gameAppVer );
GAME_INIT( m_gamePatchAppVer );
GAME_INIT( m_gameContentPath );
GAME_INIT( m_gamePatchContentPath );
GAME_INIT( m_gameBasePath );
GAME_INIT( m_gamePatchBasePath );
GAME_INIT( m_gameExesPath );
GAME_INIT( m_gameHDDataPath );
GAME_INIT( m_gameImageDataPath );
GAME_INIT( m_gameSystemCachePath );
GAME_INIT( m_gameSavesShadowPath );
#undef GAME_INIT
}
const char *GetSonyErrorString( int errorcode ) ; /// return a description for a CELL_GAME_ERROR code
int CPs3ContentPathInfo::Init( unsigned int uiFlagsMask )
{
AssertMsg( !m_bInitialized, "CPs3ContentPathInfo is being initialized twice!\n" );
/////////////////////////////////////////////////////////////////////////
//
// load sysutil NP
//
//////////////////////////////////////////////////////////////////////////
// we'll need to haul libsysutil into memory ( CELL_SYSMODULE_SYSUTIL_NP )
{
int suc = cellSysmoduleLoadModule( CELL_SYSMODULE_SYSUTIL_NP );
if ( suc != CELL_OK )
{
LocalError( "Failed to load sysutil_np: %s\n", GetSonyErrorString(suc) );
return suc;
}
}
/////////////////////////////////////////////////////////////////////////
//
// load sysutil GAME
//
//////////////////////////////////////////////////////////////////////////
// we'll need to haul libsysutil into memory ( CELL_SYSMODULE_SYSUTIL_GAME )
bool bSysModuleIsLoaded = cellSysmoduleIsLoaded( CELL_SYSMODULE_SYSUTIL_GAME ) == CELL_SYSMODULE_LOADED ;
// if this assert trips, then:
// 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)
// 2) if it's being taken care of somewhere else, we don't need to load the module here.
AssertMsg( !bSysModuleIsLoaded, "The SYSUTIL_GAME module is already loaded -- revist load order logic in CPs3ContentPathInfo::Init()\n");
if ( !bSysModuleIsLoaded )
{
int suc = cellSysmoduleLoadModule( CELL_SYSMODULE_SYSUTIL_GAME );
if ( suc != CELL_OK )
{
LocalError( "Failed to load sysutil_game: %s\n", GetSonyErrorString(suc) );
return suc;
}
}
//////////////////////////////////////////////////////////////////////////
//
// cellGameBootCheck
//
//////////////////////////////////////////////////////////////////////////
// get the base to the content directory.
CellGameContentSize size; // For game content of a disc boot game, sizeKB and sysSizeKB take no meaning – please do not use them
memset(&size, 0, sizeof(CellGameContentSize));
char bootdir[CELL_GAME_DIRNAME_SIZE] = {0};
int success = cellGameBootCheck( &m_nBootType, &m_nBootAttribs, &size, bootdir );
if ( success != CELL_GAME_RET_OK )
{
LocalError("cellGameBootCheck failed (line %d, code %d): %s\n", __LINE__, success, GetSonyErrorString(success) );
return success;
}
#if DiagnosticStringMode
if ( m_nBootAttribs & CELL_GAME_ATTRIBUTE_DEBUG ) { DiagnosticString( "GAME BOOT: DEBUG MODE\n" ); }
if ( m_nBootAttribs & CELL_GAME_ATTRIBUTE_APP_HOME ) { DiagnosticString( "GAME BOOT: HOSTFS MODE (app_home)\n" ); }
if ( m_nBootAttribs & CELL_GAME_ATTRIBUTE_PATCH ) { DiagnosticString( "GAME BOOT: PATCH MODE\n" ); }
if ( m_nBootAttribs & CELL_GAME_ATTRIBUTE_INVITE_MESSAGE ) { DiagnosticString( "GAME BOOT: INVITE MESSAGE\n" ); }
if ( m_nBootAttribs & CELL_GAME_ATTRIBUTE_CUSTOM_DATA_MESSAGE ) { DiagnosticString( "GAME BOOT: CUSTOM DATA MESSAGE\n" ); }
DiagnosticString( "BOOT DIR " ); DiagnosticString( bootdir ); DiagnosticString( "\n" );
#endif
m_bInitialized = true;
m_nHDDFreeSizeKb = size.hddFreeSizeKB;
//////////////////////////////////////////////////////////////////////////
//
// cellGameContentPermit
//
//////////////////////////////////////////////////////////////////////////
if ( !( uiFlagsMask & INIT_RETAIL_MODE ) )
{
DiagnosticString( "BOOT INFO USING NON-RETAIL BOOT\n" );
//
// BOOT MODE required: PARAM.SFO
//
success = cellGameGetParamString( CELL_GAME_PARAMID_TITLE, m_gameTitle, sizeof( m_gameTitle ) ); CheckError( success, "PARAM.SFO getParam( CELL_GAME_PARAMID_TITLE )" );
success = cellGameGetParamString( CELL_GAME_PARAMID_TITLE_ID, m_gameTitleID, sizeof( m_gameTitleID ) ); CheckError( success, "PARAM.SFO getParam( CELL_GAME_PARAMID_TITLE_ID )" );
success = cellGameGetParamString( CELL_GAME_PARAMID_APP_VER, m_gameAppVer, sizeof( m_gameAppVer ) ); CheckError( success, "PARAM.SFO getParam( CELL_GAME_PARAMID_APP_VER )" );
success = cellGameGetParamInt( CELL_GAME_PARAMID_PARENTAL_LEVEL, &m_gameParentalLevel ); CheckError( success, "PARAM.SFO getParam( CELL_GAME_PARAMID_PARENTAL_LEVEL )" );
success = cellGameGetParamInt( CELL_GAME_PARAMID_RESOLUTION, &m_gameResolution ); CheckError( success, "PARAM.SFO getParam( CELL_GAME_PARAMID_RESOLUTION )" );
success = cellGameGetParamInt( CELL_GAME_PARAMID_SOUND_FORMAT, &m_gameSoundFormat ); CheckError( success, "PARAM.SFO getParam( CELL_GAME_PARAMID_SOUND_FORMAT )" );
// Access /app_home/...
success = cellGameContentPermit( m_gameContentPath, m_gameBasePath ) ;
DiagnosticString( "BOOT ROOT " ); DiagnosticString( m_gameContentPath ); DiagnosticString( "\n" );
DiagnosticString( "BOOT USR " ); DiagnosticString( m_gameBasePath ); DiagnosticString( "\n" );
// when running the game from the debugger, the data path returned by ContentPermit contains
// HOSTFS formatted path like /app_home/D:\perforce\...
// Perform the fixup to conform to disk image layout
if ( (m_nBootAttribs & CELL_GAME_ATTRIBUTE_DEBUG) && !strncmp( m_gameBasePath, "/app_home", sizeof( "/app_home" ) - 1 ) )
{
snprintf( m_gameContentPath, sizeof( m_gameContentPath ) - 1, "/app_home/PS3_GAME" );
snprintf( m_gameBasePath, sizeof( m_gameBasePath ) - 1, "/app_home/PS3_GAME/USRDIR" );
DiagnosticString( "BOOT ROOT/ " ); DiagnosticString( m_gameContentPath ); DiagnosticString( "\n" );
DiagnosticString( "BOOT USR// " ); DiagnosticString( m_gameBasePath ); DiagnosticString( "\n" );
}
}
else
{
if ( m_nBootType != CELL_GAME_GAMETYPE_DISC )
{
LocalError("Only disk boot is supported in RETAIL mode! (bootmode=%d)\n", m_nBootType );
return -1;
}
// Finish access to boot executable
{
char tmp_contentInfoPath[CELL_GAME_PATH_MAX] = {0};
char tmp_usrdirPath[CELL_GAME_PATH_MAX] = {0};
success = cellGameContentPermit( tmp_contentInfoPath, tmp_usrdirPath ); // must call this to allow mounting of BDVD
DiagnosticString( "BOOT ROOT " ); DiagnosticString( tmp_contentInfoPath ); DiagnosticString( "\n" );
DiagnosticString( "BOOT USR " ); DiagnosticString( tmp_usrdirPath ); DiagnosticString( "\n" );
}
// in RETAIL mode we always have our assets on BDVD
success = cellGameDataCheck( m_nBootType, NULL, &size);
if ( success == CELL_GAME_RET_OK )
{
//
// BOOT MODE required: PARAM.SFO
//
success = cellGameGetParamString( CELL_GAME_PARAMID_TITLE, m_gameTitle, sizeof( m_gameTitle ) ); CheckError( success, "PARAM.SFO getParam( CELL_GAME_PARAMID_TITLE )" );
success = cellGameGetParamString( CELL_GAME_PARAMID_TITLE_ID, m_gameTitleID, sizeof( m_gameTitleID ) ); CheckError( success, "PARAM.SFO getParam( CELL_GAME_PARAMID_TITLE_ID )" );
success = cellGameGetParamString( CELL_GAME_PARAMID_APP_VER, m_gameAppVer, sizeof( m_gameAppVer ) ); CheckError( success, "PARAM.SFO getParam( CELL_GAME_PARAMID_APP_VER )" );
success = cellGameGetParamInt( CELL_GAME_PARAMID_PARENTAL_LEVEL, &m_gameParentalLevel ); CheckError( success, "PARAM.SFO getParam( CELL_GAME_PARAMID_PARENTAL_LEVEL )" );
success = cellGameGetParamInt( CELL_GAME_PARAMID_RESOLUTION, &m_gameResolution ); CheckError( success, "PARAM.SFO getParam( CELL_GAME_PARAMID_RESOLUTION )" );
success = cellGameGetParamInt( CELL_GAME_PARAMID_SOUND_FORMAT, &m_gameSoundFormat ); CheckError( success, "PARAM.SFO getParam( CELL_GAME_PARAMID_SOUND_FORMAT )" );
// Access BDVD:
success = cellGameContentPermit( m_gameContentPath, m_gameBasePath ) ;
}
else
{
LocalError("cellGameDataCheck failed (line %d, code %d): %s\n", __LINE__, success, GetSonyErrorString(success) );
return success;
}
}
DiagnosticString( "-----------PARAM.SFO----------" );
DiagnosticString( "\nTITLE " ); DiagnosticString( m_gameTitle );
DiagnosticString( "\nTITLE ID " ); DiagnosticString( m_gameTitleID );
DiagnosticString( "\nAPP_VER " ); DiagnosticString( m_gameAppVer );
if ( m_nBootAttribs & CELL_GAME_ATTRIBUTE_PATCH )
{
CellGameContentSize cgcs;
memset( &cgcs, 0, sizeof(CellGameContentSize) );
success = cellGamePatchCheck( &cgcs, NULL );
if ( success == CELL_GAME_RET_OK )
{
success = cellGameGetParamString( CELL_GAME_PARAMID_APP_VER, m_gamePatchAppVer, sizeof( m_gamePatchAppVer ) ); CheckError( success, "PARAM.SFO PATCH getParam( CELL_GAME_PARAMID_APP_VER )" );
DiagnosticString( "\nAPP_VER****" ); DiagnosticString( m_gamePatchAppVer );
success = cellGameContentPermit( m_gamePatchContentPath, m_gamePatchBasePath ) ;
}
else
{
LocalError("cellGamePatchCheck failed (line %d, code %d): %s\n", __LINE__, success, GetSonyErrorString(success) );
return success;
}
}
DiagnosticString( "\n------------------------------\n" );
//////////////////////////////////////////////////////////////////////////
//
// filesystem path setup
//
//////////////////////////////////////////////////////////////////////////
DiagnosticString( "----------FILESYSTEM----------" );
DiagnosticString( "\nPS3_GAME " ); DiagnosticString( m_gameContentPath );
DiagnosticString( "\nUSRDIR " ); DiagnosticString( m_gameBasePath );
if ( m_nBootAttribs & CELL_GAME_ATTRIBUTE_PATCH )
{
DiagnosticString( "\nPS3_GAME***" ); DiagnosticString( m_gamePatchContentPath );
DiagnosticString( "\nUSRDIR*****" ); DiagnosticString( m_gamePatchBasePath );
}
#if 0
// Get the game data directory on the hard disk.
success = cellGameDataCheck( CELL_GAME_GAMETYPE_GAMEDATA, m_gameTitleID, &size );
if ( success == CELL_GAME_RET_NONE )
{
CellGameSetInitParams init; memset( &init, 0, sizeof( init ) );
memcpy( init.title, m_gameTitle, sizeof( m_gameTitle ) );
memcpy( init.titleId, m_gameTitleID, sizeof( m_gameTitleID ) );
memcpy( init.version, m_gameAppVer, sizeof( m_gameAppVer ) );
char tmp_contentInfoPath[CELL_GAME_PATH_MAX] = {0};
char tmp_usrdirPath[CELL_GAME_PATH_MAX] = {0};
success = cellGameCreateGameData( &init, tmp_contentInfoPath, tmp_usrdirPath );
DiagnosticString( "\nTMP_GAME " ); DiagnosticString( tmp_contentInfoPath );
DiagnosticString( "\nTMP_USRD " ); DiagnosticString( tmp_usrdirPath );
}
char contentInfoPath[256];
if ( success == CELL_GAME_RET_OK )
{
success = cellGameContentPermit( contentInfoPath, m_gameHDDataPath );
}
#else
snprintf( m_gameHDDataPath, sizeof( m_gameHDDataPath ), "/dev_hdd0/game/NPUB30589/USRDIR" );
//snprintf( m_gameHDDataPath, sizeof( m_gameHDDataPath ), "/dev_hdd0/game/BLUS30732/USRDIR" );
#endif
DiagnosticString( "\nHDD_PATH " ); DiagnosticString( m_gameHDDataPath );
// Mount system cache
if ( success >= CELL_GAME_RET_OK )
{
CellSysCacheParam sysCacheParams;
memset( &sysCacheParams, 0, sizeof( CellSysCacheParam ) );
memcpy( sysCacheParams.cacheId, GetWWMASTER_TitleID(), 10 );
success = cellSysCacheMount( &sysCacheParams );
if ( success >= CELL_GAME_RET_OK )
{
memcpy( m_gameSystemCachePath, sysCacheParams.getCachePath, sizeof( m_gameSystemCachePath ) );
if ( uiFlagsMask & INIT_SYS_CACHE_CLEAR )
cellSysCacheClear();
}
}
DiagnosticString( "\nSYS_CACH " ); DiagnosticString( m_gameSystemCachePath );
// Determine where image files (maps, zips, etc.) are located:
snprintf( m_gameImageDataPath, sizeof( m_gameImageDataPath ), m_gameBasePath );
if ( uiFlagsMask & INIT_IMAGE_APP_HOME )
snprintf( m_gameImageDataPath, sizeof( m_gameImageDataPath ), "/app_home/PS3_GAME/USRDIR" );
else if ( uiFlagsMask & INIT_IMAGE_ON_HDD )
snprintf( m_gameImageDataPath, sizeof( m_gameImageDataPath ), m_gameHDDataPath );
else if ( uiFlagsMask & INIT_IMAGE_ON_BDVD )
snprintf( m_gameImageDataPath, sizeof( m_gameImageDataPath ), "/dev_bdvd/PS3_GAME/USRDIR" );
DiagnosticString( "\nIMAGE_PATH " ); DiagnosticString( m_gameImageDataPath );
// Determine where PRX files are located:
snprintf( m_gameExesPath, sizeof( m_gameExesPath ), "%s/bin", m_gameBasePath );
if ( uiFlagsMask & INIT_PRX_APP_HOME )
snprintf( m_gameExesPath, sizeof( m_gameExesPath ), "/app_home/PS3_GAME/USRDIR/bin" );
else if ( uiFlagsMask & INIT_PRX_ON_HDD )
snprintf( m_gameExesPath, sizeof( m_gameExesPath ), "%s/bin", m_gameHDDataPath );
else if ( uiFlagsMask & INIT_PRX_ON_BDVD )
snprintf( m_gameExesPath, sizeof( m_gameExesPath ), "/dev_bdvd/PS3_GAME/USRDIR/bin" );
DiagnosticString( "\nPRX_PATH " ); DiagnosticString( m_gameExesPath );
DiagnosticString( "\n------------------------------\n" );
// we cache the saves to a local directory -- keep that info here so it's in a uniform
// place accessible from everywhere.
strncpy( m_gameSavesShadowPath, m_gameSystemCachePath, sizeof(m_gameSavesShadowPath) );
strncat( m_gameSavesShadowPath, "/tempsave/", sizeof(m_gameSavesShadowPath) );
//////////////////////////////////////////////////////////////////////////
//
// finished
//
//////////////////////////////////////////////////////////////////////////
if ( !bSysModuleIsLoaded ) // actually this means it wasn't loaded when we got into the function
{
cellSysmoduleUnloadModule( CELL_SYSMODULE_SYSUTIL_GAME );
}
return success;
}
const char *GetSonyErrorString( int errorcode )
{
switch( errorcode )
{
case CELL_GAME_RET_OK:
return "CELL_GAME_RET_OK";
case CELL_GAME_ERROR_ACCESS_ERROR:
return "HDD access error";
case CELL_GAME_ERROR_BUSY:
return "The call of an access preparing function was repeated";
case CELL_GAME_ERROR_IN_SHUTDOWN:
return "Processing cannot be executed because application termination is being processed";
case CELL_GAME_ERROR_INTERNAL:
return "Fatal error occurred in the utility";
case CELL_GAME_ERROR_PARAM:
return "There is an error in the argument (application bug)";
case CELL_GAME_ERROR_BOOTPATH:
return "Pathname of booted program file is too long" ;
case CELL_SYSMODULE_ERROR_UNKNOWN:
return "Tried to load an unknown PRX";
case CELL_SYSMODULE_ERROR_FATAL:
return "Sysmodule PRX load failed";
case CELL_GAME_ERROR_BROKEN:
return "The specified game content is corrupted";
default:
return "Unknown error code";
}
}
/* The boot attributes member of CPs3ContentPathInfo is some combination of:
CELL_GAME_ATTRIBUTE_PATCH Booted from a patch (only for a disc boot game)
CELL_GAME_ATTRIBUTE_APP_HOME Booted from the host machine (development machine only)
CELL_GAME_ATTRIBUTE_DEBUG Booted from the debugger (development machine only)
CELL_GAME_ATTRIBUTE_XMBBUY Rebooted from the game purchasing feature of the NP DRM utility
CELL_GAME_ATTRIBUTE_COMMERCE2_BROWSER Rebooted from the store browsing feature of the NP IN-GAME commerce 2 utility
CELL_GAME_ATTRIBUTE_INVITE_MESSAGE Booted from the game boot invitation message of the NP basic utility
CELL_GAME_ATTRIBUTE_CUSTOM_DATA_MESSAGE Booted from a message with a custom data attachment of the NP basic utility
CELL_GAME_ATTRIBUTE_WEB_BROWSER Booted from the full browser feature of the web browser utility
*/