csgo-2018-source/launcher_main/ps3_pathinfo.cpp
2021-07-24 21:11:47 -07:00

421 lines
16 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//===== 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
*/