123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650 |
- /*
- ===========================================================================
- Doom 3 BFG Edition GPL Source Code
- Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
- This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
- Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
- In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
- If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
- ===========================================================================
- */
- #include "PlayerProfile.h"
- #include "PS3_Includes.h"
- #include "PSN/PS3_Session.h"
- const int32 FRAMEWORK_PROFILE_VER = 1;
- // Store master volume settings in archived cvars, becausue we want them to apply
- // even if a user isn't signed in.
- // The range is from 0 to 15, which matches the setting in vanilla DOOM.
- idCVar s_volume_sound( "s_volume_sound", "8", CVAR_ARCHIVE | CVAR_INTEGER, "sound volume", 0, 15 );
- idCVar s_volume_midi( "s_volume_midi", "8", CVAR_ARCHIVE | CVAR_INTEGER, "music volume", 0, 15 );
- /*
- ================================================
- idProfileMgr
- ================================================
- */
- /*
- ========================
- idProfileMgr
- ========================
- */
- idProfileMgr::idProfileMgr() :
- profileSaveProcessor( new (TAG_SAVEGAMES) idSaveGameProcessorSaveProfile ),
- profileLoadProcessor( new (TAG_SAVEGAMES) idSaveGameProcessorLoadProfile ),
- profile( NULL ),
- handle( 0 ) {
- }
- /*
- ================================================
- ~idProfileMgr
- ================================================
- */
- idProfileMgr::~idProfileMgr() {
- delete profileSaveProcessor;
- profileSaveProcessor = NULL;
- delete profileLoadProcessor;
- profileLoadProcessor = NULL;
- }
- /*
- ========================
- idProfileMgr::Init
- ========================
- */
- void idProfileMgr::Init( idPlayerProfile * profile_ ) {
- profile = profile_;
- handle = 0;
- }
- /*
- ========================
- idProfileMgr::Pump
- ========================
- */
- void idProfileMgr::Pump() {
- // profile can be NULL if we forced the user to register as in the case of map-ing into a level from the press start screen
- if ( profile == NULL ) {
- return;
- }
- // See if we are done with saving/loading the profile
- bool saving = profile->GetState() == idPlayerProfile::SAVING;
- bool loading = profile->GetState() == idPlayerProfile::LOADING;
- if ( ( saving || loading ) && psn_session->GetSaveGameManager()->IsSaveGameCompletedFromHandle( handle ) ) {
- profile->SetState( idPlayerProfile::IDLE );
- if ( saving ) {
- // Done saving
- } else if ( loading ) {
- // Done loading
- const idSaveLoadParms & parms = profileLoadProcessor->GetParms();
- if ( parms.GetError() == SAVEGAME_E_FOLDER_NOT_FOUND || parms.GetError() == SAVEGAME_E_FILE_NOT_FOUND ) {
- profile->SaveSettings();
- } else if ( parms.GetError() != SAVEGAME_E_NONE ) {
- profile->SetState( idPlayerProfile::ERR );
- }
- }
- }
- // See if we need to save/load the profile
- if ( profile->GetRequestedState() == idPlayerProfile::SAVE_REQUESTED ) {
- SaveSettings();
- profile->SetRequestedState( idPlayerProfile::IDLE );
- } else if ( profile->GetRequestedState() == idPlayerProfile::LOAD_REQUESTED ) {
- LoadSettings();
- profile->SetRequestedState( idPlayerProfile::IDLE );
- }
- }
- /*
- ========================
- idProfileMgr::GetProfile
- ========================
- */
- idPlayerProfile * idProfileMgr::GetProfile() {
- if ( profile == NULL ) {
- return NULL;
- }
- bool loading = ( profile->GetState() == idPlayerProfile::LOADING ) || ( profile->GetRequestedState() == idPlayerProfile::LOAD_REQUESTED );
- if ( loading ) {
- return NULL;
- }
- return profile;
- }
- /*
- ========================
- idProfileMgr::SaveSettings
- ========================
- */
- void idProfileMgr::SaveSettings() {
- if ( profile != NULL && saveGame_enable.GetBool() ) {
- // Issue the async save...
- if ( profileSaveProcessor->InitSaveProfile( profile, "" ) ) {
- handle = psn_session->GetSaveGameManager()->ExecuteProcessor( profileSaveProcessor );
- profile->SetState( idPlayerProfile::SAVING );
- }
- } else {
- // If not able to save the profile, just change the state and leave
- if ( profile == NULL ) {
- idLib::Warning( "Not saving profile, profile is NULL." );
- }
- if ( !saveGame_enable.GetBool() ) {
- idLib::Warning( "Skipping profile save because saveGame_enable = 0" );
- }
- }
- }
- /*
- ========================
- idProfileMgr::LoadSettings
- ========================
- */
- void idProfileMgr::LoadSettings() {
- if ( profile != NULL && saveGame_enable.GetBool() ) {
- if ( profileLoadProcessor->InitLoadProfile( profile, "" ) ) {
- // Skip the not found error because this might be the first time to play the game!
- profileLoadProcessor->SetSkipSystemErrorDialogMask( SAVEGAME_E_FOLDER_NOT_FOUND | SAVEGAME_E_FILE_NOT_FOUND );
- handle = psn_session->GetSaveGameManager()->ExecuteProcessor( profileLoadProcessor );
- profile->SetState( idPlayerProfile::LOADING );
- }
- } else {
- // If not able to save the profile, just change the state and leave
- if ( profile == NULL ) {
- idLib::Warning( "Not loading profile, profile is NULL." );
- }
- if ( !saveGame_enable.GetBool() ) {
- idLib::Warning( "Skipping profile load because saveGame_enable = 0" );
- }
- }
- }
- /*
- ================================================
- idSaveGameProcessorSaveProfile
- ================================================
- */
- /*
- ========================
- idSaveGameProcessorSaveProfile::idSaveGameProcessorSaveProfile
- ========================
- */
- idSaveGameProcessorSaveProfile::idSaveGameProcessorSaveProfile() {
- profileFile = NULL;
- profile = NULL;
- }
- /*
- ========================
- idSaveGameProcessorSaveProfile::InitSaveProfile
- ========================
- */
- bool idSaveGameProcessorSaveProfile::InitSaveProfile( idPlayerProfile * profile_, const char * folder ) {
- // Serialize the profile and pass a file to the processor
- profileFile = new (TAG_SAVEGAMES) idFile_Memory( SAVEGAME_PROFILE_FILENAME );
- profileFile->MakeWritable();
- profileFile->SetMaxLength( MAX_PROFILE_SIZE );
- idTempArray< byte > buffer( MAX_PROFILE_SIZE );
- idBitMsg msg;
- msg.InitWrite( buffer.Ptr(), MAX_PROFILE_SIZE );
- idSerializer ser( msg, true );
- profile_->SerializeSettings( ser );
- profileFile->Write( msg.GetReadData(), msg.GetSize() );
- profileFile->MakeReadOnly();
- idList< idSaveFileEntry > files;
- files.Append( idSaveFileEntry( profileFile, SAVEGAMEFILE_BINARY | SAVEGAMEFILE_AUTO_DELETE, SAVEGAME_PROFILE_FILENAME ) );
- idSaveGameDetails description;
- if ( !idSaveGameProcessor::Init() ) {
- return false;
- }
- if ( files.Num() == 0 ) {
- idLib::Warning( "No files to save." );
- return false;
- }
- // Setup save system
- parms.directory = AddSaveFolderPrefix( folder, idSaveGameManager::PACKAGE_PROFILE );
- parms.mode = SAVEGAME_MBF_SAVE | SAVEGAME_MBF_HIDDEN; // do NOT delete the existing files
- parms.saveFileType = SAVEFILE_TYPE_AUTO;
- for ( int i = 0; i < files.Num(); ++i ) {
- parms.files.Append( files[i] );
- }
- description.title = idLocalization::GetString( "#str_savegame_title" );
- description.subTitle = idLocalization::GetString( "#str_savegame_profile_heading" );
- description.summary = idLocalization::GetString( "#str_savegame_profile_desc" );
- // Add static image as the thumbnail
- staticScreenshotFile = new (TAG_SAVEGAMES) idFile_Memory( "image" );
- // Open up the Image file and Make it a memory file.
- void* thumbImage = NULL;
- int imagesize = fileSystem->ReadFile( "base/textures/PROFILE.PNG", &thumbImage ); // This file lives at USRData.. i think.
- staticScreenshotFile->MakeWritable();
- staticScreenshotFile->Write( thumbImage, imagesize );
- staticScreenshotFile->MakeReadOnly();
- parms.files.Append( idSaveFileEntry( staticScreenshotFile, SAVEGAMEFILE_THUMB, "image" ) );
- fileSystem->FreeFile( thumbImage );
- this->parms.description = description;
- parms.description.slotName = folder;
- // TODO:KC - what was the purpose of this?
- // JAF idKeyInput::SetUserDeviceNumForBind( profile_->GetDeviceNumForProfile() );
- profile = profile_;
- return true;
- }
- /*
- ========================
- idSaveGameProcessorSaveProfile::Process
- ========================
- */
- bool idSaveGameProcessorSaveProfile::Process() {
- // Files already setup for save, just execute as normal files
- // Platform-specific implementation
- // This will start a worker thread for async operation.
- // It will always signal when it's completed.
- Sys_ExecuteSavegameCommandAsync( &parms );
- return false;
- }
- /*
- ================================================
- idSaveGameProcessorLoadProfile
- ================================================
- */
- /*
- ========================
- idSaveGameProcessorLoadProfile::idSaveGameProcessorLoadProfile
- ========================
- */
- idSaveGameProcessorLoadProfile::idSaveGameProcessorLoadProfile() {
- profileFile = NULL;
- profile = NULL;
- }
- /*
- ========================
- idSaveGameProcessorLoadProfile::~idSaveGameProcessorLoadProfile
- ========================
- */
- idSaveGameProcessorLoadProfile::~idSaveGameProcessorLoadProfile() {
- }
- /*
- ========================
- idSaveGameProcessorLoadProfile::InitLoadFiles
- ========================
- */
- bool idSaveGameProcessorLoadProfile::InitLoadProfile( idPlayerProfile * profile_, const char * folder_ ) {
- if ( !idSaveGameProcessor::Init() ) {
- return false;
- }
- parms.directory = AddSaveFolderPrefix( folder_, idSaveGameManager::PACKAGE_PROFILE );
- parms.description.slotName = folder_;
- parms.mode = SAVEGAME_MBF_LOAD | SAVEGAME_MBF_HIDDEN;
- parms.saveFileType = SAVEFILE_TYPE_AUTO;
- profileFile = new (TAG_SAVEGAMES) idFile_Memory( SAVEGAME_PROFILE_FILENAME );
- parms.files.Append( idSaveFileEntry( profileFile, SAVEGAMEFILE_BINARY, SAVEGAME_PROFILE_FILENAME ) );
- profile = profile_;
- return true;
- }
- /*
- ========================
- idSaveGameProcessorLoadProfile::Process
- ========================
- */
- bool idSaveGameProcessorLoadProfile::Process() {
- Sys_ExecuteSavegameCommandAsync( &parms );
- return false;
- }
- /*
- ========================
- idSaveGameProcessorLoadProfile::PostProcess
- ========================
- */
- void idSaveGameProcessorLoadProfile::PostProcess() {
- // Serialize the loaded profile
- bool foundProfile = profileFile->Length() > 0;
- if ( foundProfile ) {
- idTempArray< byte> buffer( MAX_PROFILE_SIZE );
- // Serialize settings from this buffer
- profileFile->MakeReadOnly();
- profileFile->ReadBigArray( buffer.Ptr(), profileFile->Length() );
- idBitMsg msg;
- msg.InitRead( buffer.Ptr(), (int)buffer.Size() );
- idSerializer ser( msg, false );
- profile->SerializeSettings( ser );
- // JAF idKeyInput::SetUserDeviceNumForBind( profile->GetDeviceNumForProfile() );
- } else {
- parms.errorCode = SAVEGAME_E_FILE_NOT_FOUND;
- }
- delete profileFile;
- }
- /*
- ========================
- Contains data that needs to be saved out on a per player profile basis, global for the lifetime of the player so
- the data can be shared across computers.
- - HUD tint colors
- - key bindings
- - etc...
- ========================
- */
- /*
- ========================
- idPlayerProfile::idPlayerProfile
- ========================
- */
- idPlayerProfile::idPlayerProfile() {
- SetDefaults();
- // Don't have these in SetDefaults because they're used for state management and SetDefaults is called when
- // loading the profile
- state = IDLE;
- requestedState = IDLE;
- }
- /*
- ========================
- idPlayerProfile::SetDefaults
- ========================
- */
- void idPlayerProfile::SetDefaults() {
-
- achievementBits = 0;
- seenInstallMessage = false;
- stats.SetNum( MAX_PLAYER_PROFILE_STATS );
- for ( int i = 0; i < MAX_PLAYER_PROFILE_STATS; ++i ) {
- stats[i].i = 0;
- }
- deviceNum = 0;
- state = IDLE;
- requestedState = IDLE;
- frameScaleX = 0.85f;
- frameScaleY = 0.85f;
- }
- /*
- ========================
- idPlayerProfile::Init
- ========================
- */
- void idPlayerProfile::Init() {
- SetDefaults();
- }
- /*
- ========================
- idPlayerProfile::~idPlayerProfile
- ========================
- */
- idPlayerProfile::~idPlayerProfile() {
- }
- /*
- ========================
- idPlayerProfile::SerializeSettings
- ========================
- */
- bool idPlayerProfile::SerializeSettings( idSerializer & ser ) {
- int flags = cvarSystem->GetModifiedFlags();
- // Default to current tag/version
- int32 tag = GetProfileTag();
- int32 version = FRAMEWORK_PROFILE_VER;
- // Serialize tag/version
- ser.SerializePacked( tag );
- if ( tag != GetProfileTag() ) {
- idLib::Warning( "Profile tag did not match, profile will be re-initialized" );
- SetDefaults();
- SaveSettings(); // Flag the profile to save so we have the latest version stored
- return false;
- }
- ser.SerializePacked( version );
- if ( version != FRAMEWORK_PROFILE_VER ) {
- // For now, don't allow profiles with invalid versions load
- // We could easily support old version by doing a few version checks below to pick and choose what we load as well.
- idLib::Warning( "Profile version did not match. Profile will be replaced" );
- SetDefaults();
- SaveSettings(); // Flag the profile to save so we have the latest version stored
- return false;
- }
- // Serialize audio settings
- SERIALIZE_BOOL( ser, seenInstallMessage );
- // New setting to save to make sure that we have or haven't seen this achievement before used to pass TRC R149d
- ser.Serialize( achievementBits );
- ser.Serialize( frameScaleX );
- ser.Serialize( frameScaleY );
- SERIALIZE_BOOL( ser, alwaysRun );
- // we save all the cvar-based settings in the profile even though some cvars are archived
- // so that we are consistent and don't miss any or get affected when the archive flag is changed
- SERIALIZE_CVAR_INT( ser, s_volume_sound );
- SERIALIZE_CVAR_INT( ser, s_volume_midi );
-
- // Don't trigger profile save due to modified archived cvars during profile load
- cvarSystem->ClearModifiedFlags( CVAR_ARCHIVE ); // must clear because set() is an OR operation, not assignment...
- cvarSystem->SetModifiedFlags( flags );
- return true;
- }
- /*
- ========================
- idPlayerProfile::GetLevel
- ========================
- */
- int idPlayerProfile::GetLevel() const {
- return 1;
- }
- /*
- ========================
- idPlayerProfile::StatSetInt
- ========================
- */
- void idPlayerProfile::StatSetInt( int s, int v ) {
- stats[s].i = v;
- }
- /*
- ========================
- idPlayerProfile::StatSetFloat
- ========================
- */
- void idPlayerProfile::StatSetFloat( int s, float v ) {
- stats[s].f = v;
- }
- /*
- ========================
- idPlayerProfile::StatGetInt
- ========================
- */
- int idPlayerProfile::StatGetInt( int s ) const {
- return stats[s].i;
- }
- /*
- ========================
- idPlayerProfile::StatGetFloat
- ========================
- */
- float idPlayerProfile::StatGetFloat( int s ) const {
- return stats[s].f;
- }
- /*
- ========================
- idPlayerProfile::SaveSettings
- ========================
- */
- void idPlayerProfile::SaveSettings() {
- if ( state != SAVING ) {
- if ( GetRequestedState() == IDLE ) {
- SetRequestedState( SAVE_REQUESTED );
- }
- }
- }
- /*
- ========================
- idPlayerProfile::SaveSettings
- ========================
- */
- void idPlayerProfile::LoadSettings() {
- if ( state != LOADING ) {
- if ( verify( GetRequestedState() == IDLE ) ) {
- SetRequestedState( LOAD_REQUESTED );
- }
- }
- }
- /*
- ========================
- idPlayerProfile::SetAchievementBit
- ========================
- */
- void idPlayerProfile::SetAchievementBit( const int id ) {
- if ( id > 63 ) {
- assert( false ); // FIXME: add another set of achievement bit flags
- return;
- }
- achievementBits |= (int64)1 << id;
- }
- /*
- ========================
- idPlayerProfile::ClearAchievementBit
- ========================
- */
- void idPlayerProfile::ClearAchievementBit( const int id ) {
- if ( id > 63 ) {
- assert( false ); // FIXME: add another set of achievement bit flags
- return;
- }
- achievementBits &= ~( (int64)1 << id );
- }
- /*
- ========================
- idPlayerProfile::GetAchievementBit
- ========================
- */
- bool idPlayerProfile::GetAchievementBit( const int id ) const {
- if ( id > 63 ) {
- assert( false ); // FIXME: add another set of achievement bit flags
- return false;
- }
- return ( achievementBits & (int64)1 << id ) != 0;
- }
- /*
- ========================
- Returns the value stored in the music volume cvar.
- ========================
- */
- int idPlayerProfile::GetMusicVolume() const {
- return s_volume_midi.GetInteger();
- }
- /*
- ========================
- Returns the value stored in the sound volume cvar.
- ========================
- */
- int idPlayerProfile::GetSoundVolume() const {
- return s_volume_sound.GetInteger();
- }
- /*
- ========================
- Sets the music volume cvar.
- ========================
- */
- void idPlayerProfile::SetMusicVolume( int volume ) {
- s_volume_midi.SetInteger( volume );
- }
- /*
- ========================
- Sets the sound volume cvar.
- ========================
- */
- void idPlayerProfile::SetSoundVolume( int volume ) {
- s_volume_sound.SetInteger( volume );
- }
|