summaryrefslogtreecommitdiff
path: root/gameui/SaveGameDialog_Xbox.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /gameui/SaveGameDialog_Xbox.cpp
downloadarchived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.tar.xz
archived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.zip
Diffstat (limited to 'gameui/SaveGameDialog_Xbox.cpp')
-rw-r--r--gameui/SaveGameDialog_Xbox.cpp295
1 files changed, 295 insertions, 0 deletions
diff --git a/gameui/SaveGameDialog_Xbox.cpp b/gameui/SaveGameDialog_Xbox.cpp
new file mode 100644
index 0000000..610c0a0
--- /dev/null
+++ b/gameui/SaveGameDialog_Xbox.cpp
@@ -0,0 +1,295 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "BasePanel.h"
+#include "SaveGameDialog.h"
+
+#include "winlite.h" // FILETIME
+#include "vgui/ILocalize.h"
+#include "vgui/ISurface.h"
+#include "vgui/ISystem.h"
+#include "vgui/IVGui.h"
+
+#include "vgui_controls/AnimationController.h"
+#include "vgui_controls/ImagePanel.h"
+#include "filesystem.h"
+#include "KeyValues.h"
+#include "ModInfo.h"
+#include "EngineInterface.h"
+#include "GameUI_Interface.h"
+#include "vstdlib/random.h"
+
+#include "BaseSaveGameDialog.h"
+#include "SaveGameBrowserDialog.h"
+
+using namespace vgui;
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+#include "vgui_controls/Frame.h"
+#include "utlvector.h"
+
+extern const char *COM_GetModDirectory();
+
+using namespace vgui;
+
+CSaveGameDialogXbox::CSaveGameDialogXbox( vgui::Panel *parent )
+: BaseClass( parent ),
+ m_bGameSaving ( false ),
+ m_bNewSaveAvailable( false )
+{
+ m_bFilterAutosaves = true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CSaveGameDialogXbox::PerformSelectedAction( void )
+{
+ BaseClass::PerformSelectedAction();
+
+ // If there are no panels, don't allow this
+ if ( GetNumPanels() == 0 )
+ return;
+
+ SetControlDisabled( true );
+
+ // Decide if this is an overwrite or a new save game
+ bool bNewSave = ( GetActivePanelIndex() == 0 ) && m_bNewSaveAvailable;
+ if ( bNewSave )
+ {
+ OnCommand( "SaveGame" );
+ }
+ else
+ {
+ BasePanel()->ShowMessageDialog( MD_SAVE_OVERWRITE, this );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : bNewSaveSelected -
+//-----------------------------------------------------------------------------
+void CSaveGameDialogXbox::UpdateFooterOptions( void )
+{
+ CFooterPanel *pFooter = GetFooterPanel();
+
+ // Show available buttons
+ pFooter->ClearButtons();
+
+ bool bSavePanelsActive = ( GetNumPanels() != 0 );
+ if ( bSavePanelsActive )
+ {
+ bool bNewSaveSelected = ( GetActivePanelIndex() == 0 ) && m_bNewSaveAvailable;
+ if ( bNewSaveSelected )
+ {
+ pFooter->AddNewButtonLabel( "#GameUI_SaveGame_NewSave", "#GameUI_Icons_A_BUTTON" );
+ }
+ else
+ {
+ pFooter->AddNewButtonLabel( "#GameUI_SaveGame_Overwrite", "#GameUI_Icons_A_BUTTON" );
+ }
+ }
+
+ // Always available
+ pFooter->AddNewButtonLabel( "#GameUI_Close", "#GameUI_Icons_B_BUTTON" );
+ pFooter->AddNewButtonLabel( "#GameUI_Console_StorageChange", "#GameUI_Icons_Y_BUTTON" );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: perfrom the save on a separate thread
+//-----------------------------------------------------------------------------
+class CAsyncCtxSaveGame : public CBasePanel::CAsyncJobContext
+{
+public:
+ explicit CAsyncCtxSaveGame( CSaveGameDialogXbox *pDlg );
+ ~CAsyncCtxSaveGame() {}
+
+public:
+ virtual void ExecuteAsync();
+ virtual void Completed();
+
+public:
+ char m_szFilename[MAX_PATH];
+ CSaveGameDialogXbox *m_pSaveGameDlg;
+};
+
+CAsyncCtxSaveGame::CAsyncCtxSaveGame( CSaveGameDialogXbox *pDlg ) :
+ CBasePanel::CAsyncJobContext( 3.0f ), // Storage device info for at least 3 seconds
+ m_pSaveGameDlg( pDlg )
+{
+ NULL;
+}
+
+void CAsyncCtxSaveGame::ExecuteAsync()
+{
+ // Sit and wait for the async save to finish
+ for ( ; ; )
+ {
+ if ( !engine->IsSaveInProgress() )
+ // Save operation is no longer in progress
+ break;
+ else
+ ThreadSleep( 50 );
+ }
+}
+
+void CAsyncCtxSaveGame::Completed()
+{
+ m_pSaveGameDlg->SaveCompleted( this );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: kicks off the async save (called on the main thread)
+//-----------------------------------------------------------------------------
+void CSaveGameDialogXbox::InitiateSaving()
+{
+ // Determine whether this is a new save or overwrite
+ bool bNewSave = ( GetActivePanelIndex() == 0 ) && m_bNewSaveAvailable;
+
+ // Allocate the async context for saving
+ CAsyncCtxSaveGame *pAsyncCtx = new CAsyncCtxSaveGame( this );
+
+ // If this is an overwrite then there was an overwrite warning displayed
+ if ( !bNewSave )
+ BasePanel()->CloseMessageDialog( DIALOG_STACK_IDX_WARNING );
+ // Now display the saving warning
+ BasePanel()->ShowMessageDialog( MD_SAVING_WARNING, this );
+
+ // Kick off saving
+ char *szFilename = pAsyncCtx->m_szFilename;
+ const int maxFilenameLen = sizeof( pAsyncCtx->m_szFilename );
+ char szCmd[MAX_PATH];
+
+ // See if this is the "new save game" slot
+ if ( bNewSave )
+ {
+ // Create a new save game (name is created from the current time, which should be pretty unique)
+#ifdef WIN32
+ FILETIME currentTime;
+ GetSystemTimeAsFileTime( &currentTime );
+ Q_snprintf( szFilename, maxFilenameLen, "%s_%u", COM_GetModDirectory(), currentTime.dwLowDateTime );
+#else
+ time_t currentTime = time( NULL );
+ Q_snprintf( szFilename, maxFilenameLen, "%s_%u", COM_GetModDirectory(), (unsigned)currentTime );
+#endif
+ Q_snprintf( szCmd, sizeof( szCmd ), "xsave %s", szFilename );
+ engine->ExecuteClientCmd( szCmd );
+ Q_strncat( szFilename, ".360.sav", maxFilenameLen );
+ }
+ else
+ {
+ const SaveGameDescription_t *pDesc = GetActivePanelSaveDescription();
+ Q_strncpy( szFilename, pDesc->szShortName, maxFilenameLen );
+ Q_snprintf( szCmd, sizeof( szCmd ), "xsave %s", szFilename );
+ engine->ExecuteClientCmd( szCmd );
+ }
+
+ // Enqueue waiting
+ BasePanel()->ExecuteAsync( pAsyncCtx );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: handles the end of async save (called on the main thread)
+//-----------------------------------------------------------------------------
+void CSaveGameDialogXbox::SaveCompleted( CAsyncCtxSaveGame *pCtx )
+{
+ char const *szFilename = pCtx->m_szFilename;
+
+ // We should now be saved so get the new desciption back from the file
+ char szDirectory[MAX_PATH];
+ Q_snprintf( szDirectory, sizeof( szDirectory ), "%s:/%s", COM_GetModDirectory(), szFilename );
+
+ ParseSaveData( szDirectory, szFilename, &m_NewSaveDesc );
+
+ // Close the progress dialog
+ BasePanel()->CloseMessageDialog( DIALOG_STACK_IDX_WARNING );
+
+ bool bNewSave = ( GetActivePanelIndex() == 0 ) && m_bNewSaveAvailable;
+ if ( bNewSave )
+ {
+ AnimateInsertNewPanel( &m_NewSaveDesc );
+ }
+ else
+ {
+ AnimateOverwriteActivePanel( &m_NewSaveDesc );
+ }
+
+ m_bGameSaving = false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: handles button commands
+//-----------------------------------------------------------------------------
+void CSaveGameDialogXbox::OnCommand( const char *command )
+{
+ m_KeyRepeat.Reset();
+
+ if ( !Q_stricmp( command, "SaveGame" ) )
+ {
+ if ( m_bGameSaving )
+ return;
+ m_bGameSaving = true;
+
+ SetControlDisabled( true );
+
+ // Initiate the saving operation
+ InitiateSaving();
+ }
+ else if ( !Q_stricmp( command, "SaveSuccess" ) )
+ {
+ vgui::surface()->PlaySound( "UI/buttonclick.wav" );
+ GameUI().SetSavedThisMenuSession( true );
+ }
+ else if ( !Q_stricmp( command, "CloseAndSelectResume" ) )
+ {
+ BasePanel()->ArmFirstMenuItem();
+ OnCommand( "Close" );
+ }
+ else if ( !Q_stricmp( command, "OverwriteGameCancelled" ) )
+ {
+ SetControlDisabled( false );
+ }
+ else if ( !Q_stricmp( command, "RefreshSaveGames" ) )
+ {
+ RefreshSaveGames();
+ }
+ else if ( !Q_stricmp( command, "ReleaseModalWindow" ) )
+ {
+ vgui::surface()->RestrictPaintToSinglePanel( NULL );
+ }
+ else if ( !m_bGameSaving )
+ {
+ BaseClass::OnCommand(command);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: On completion of scanning, prepend a utility slot on the stack
+//-----------------------------------------------------------------------------
+void CSaveGameDialogXbox::OnDoneScanningSaveGames( void )
+{
+ ConVarRef save_history_count("save_history_count" );
+
+ m_bNewSaveAvailable = false;
+#ifdef _X360
+ if ( XBX_GetStorageDeviceId() == XBX_INVALID_STORAGE_ID || XBX_GetStorageDeviceId() == XBX_STORAGE_DECLINED )
+ return;
+
+ // We only allow 10 save games minus the number of autosaves, autosavedangerous, and autosave0?'s at once
+ if ( GetNumPanels() >= 10 - ( 2 + (unsigned)save_history_count.GetInt() ) )
+ return;
+
+ if ( GetStorageSpaceUsed() + XBX_SAVEGAME_BYTES > XBX_PERSISTENT_BYTES_NEEDED )
+ return;
+
+ m_bNewSaveAvailable = true;
+ SaveGameDescription_t bogusDesc = { "#GameUI_SaveGame_NewSavedGame", "#GameUI_SaveGame_NewSave", "#GameUI_SaveGame_NewSave", "#GameUI_SaveGame_NewSave", "#GameUI_SaveGame_NewSave", "#GameUI_SaveGame_NewSave", "#GameUI_SaveGame_NewSave", 0, 0 };
+ CGameSavePanel *newSavePanel = SETUP_PANEL( new CGameSavePanel( this, &bogusDesc, true ) );
+ AddPanel( newSavePanel );
+#endif // _X360
+}