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.
675 lines
18 KiB
675 lines
18 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//=============================================================================// |
|
|
|
|
|
#include "BaseSaveGameDialog.h" |
|
#include "filesystem.h" |
|
#include "savegame_version.h" |
|
#include "vgui_controls/PanelListPanel.h" |
|
#include "vgui_controls/Label.h" |
|
#include "vgui_controls/ImagePanel.h" |
|
#include "vgui_controls/Button.h" |
|
#include "tier1/utlbuffer.h" |
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include "filesystem.h" |
|
|
|
#include "MouseMessageForwardingPanel.h" |
|
#include "TGAImagePanel.h" |
|
|
|
#include <time.h> |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
using namespace vgui; |
|
|
|
#define TGA_IMAGE_PANEL_WIDTH 180 |
|
#define TGA_IMAGE_PANEL_HEIGHT 100 |
|
|
|
#define MAX_LISTED_SAVE_GAMES 128 |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Describes the layout of a same game pic |
|
//----------------------------------------------------------------------------- |
|
class CSaveGamePanel : public vgui::EditablePanel |
|
{ |
|
DECLARE_CLASS_SIMPLE( CSaveGamePanel, vgui::EditablePanel ); |
|
public: |
|
CSaveGamePanel( PanelListPanel *parent, const char *name, int saveGameListItemID ) : BaseClass( parent, name ) |
|
{ |
|
m_iSaveGameListItemID = saveGameListItemID; |
|
m_pParent = parent; |
|
m_pSaveGameImage = new CTGAImagePanel( this, "SaveGameImage" ); |
|
m_pAutoSaveImage = new ImagePanel( this, "AutoSaveImage" ); |
|
m_pSaveGameScreenshotBackground = new ImagePanel( this, "SaveGameScreenshotBackground" ); |
|
m_pChapterLabel = new Label( this, "ChapterLabel", "" ); |
|
m_pTypeLabel = new Label( this, "TypeLabel", "" ); |
|
m_pElapsedTimeLabel = new Label( this, "ElapsedTimeLabel", "" ); |
|
m_pFileTimeLabel = new Label( this, "FileTimeLabel", "" ); |
|
|
|
CMouseMessageForwardingPanel *panel = new CMouseMessageForwardingPanel(this, NULL); |
|
panel->SetZPos(2); |
|
|
|
SetSize( 200, 140 ); |
|
|
|
LoadControlSettings( "resource/SaveGamePanel.res" ); |
|
|
|
m_FillColor = m_pSaveGameScreenshotBackground->GetFillColor(); |
|
} |
|
|
|
void SetSaveGameInfo( SaveGameDescription_t &save ) |
|
{ |
|
// set the bitmap to display |
|
char tga[_MAX_PATH]; |
|
Q_strncpy( tga, save.szFileName, sizeof(tga) ); |
|
char *ext = strstr( tga, ".sav" ); |
|
if ( ext ) |
|
{ |
|
strcpy( ext, ".tga" ); |
|
} |
|
|
|
// If a TGA file exists then it is a user created savegame |
|
if ( g_pFullFileSystem->FileExists( tga ) ) |
|
{ |
|
m_pSaveGameImage->SetTGA( tga ); |
|
} |
|
// If there is no TGA then it is either an autosave or the user TGA file has been deleted |
|
else |
|
{ |
|
m_pSaveGameImage->SetVisible( false ); |
|
m_pAutoSaveImage->SetVisible( true ); |
|
m_pAutoSaveImage->SetImage( "resource\\autosave" ); |
|
} |
|
|
|
// set the title text |
|
m_pChapterLabel->SetText( save.szComment ); |
|
|
|
// type |
|
SetControlString( "TypeLabel", save.szType ); |
|
SetControlString( "ElapsedTimeLabel", save.szElapsedTime ); |
|
SetControlString( "FileTimeLabel", save.szFileTime ); |
|
} |
|
|
|
MESSAGE_FUNC_INT( OnPanelSelected, "PanelSelected", state ) |
|
{ |
|
if ( state ) |
|
{ |
|
// set the text color to be orange, and the pic border to be orange |
|
m_pSaveGameScreenshotBackground->SetFillColor( m_SelectedColor ); |
|
m_pChapterLabel->SetFgColor( m_SelectedColor ); |
|
m_pTypeLabel->SetFgColor( m_SelectedColor ); |
|
m_pElapsedTimeLabel->SetFgColor( m_SelectedColor ); |
|
m_pFileTimeLabel->SetFgColor( m_SelectedColor ); |
|
} |
|
else |
|
{ |
|
m_pSaveGameScreenshotBackground->SetFillColor( m_FillColor ); |
|
m_pChapterLabel->SetFgColor( m_TextColor ); |
|
m_pTypeLabel->SetFgColor( m_TextColor ); |
|
m_pElapsedTimeLabel->SetFgColor( m_TextColor ); |
|
m_pFileTimeLabel->SetFgColor( m_TextColor ); |
|
} |
|
|
|
PostMessage( m_pParent->GetVParent(), new KeyValues("PanelSelected") ); |
|
} |
|
|
|
virtual void OnMousePressed( vgui::MouseCode code ) |
|
{ |
|
m_pParent->SetSelectedPanel( this ); |
|
} |
|
|
|
virtual void ApplySchemeSettings( IScheme *pScheme ) |
|
{ |
|
m_TextColor = pScheme->GetColor( "NewGame.TextColor", Color(255, 255, 255, 255) ); |
|
m_SelectedColor = pScheme->GetColor( "NewGame.SelectionColor", Color(255, 255, 255, 255) ); |
|
|
|
BaseClass::ApplySchemeSettings( pScheme ); |
|
} |
|
|
|
virtual void OnMouseDoublePressed( vgui::MouseCode code ) |
|
{ |
|
// call the panel |
|
OnMousePressed( code ); |
|
PostMessage( m_pParent->GetParent(), new KeyValues("Command", "command", "loadsave") ); |
|
} |
|
|
|
int GetSaveGameListItemID() |
|
{ |
|
return m_iSaveGameListItemID; |
|
} |
|
|
|
private: |
|
vgui::PanelListPanel *m_pParent; |
|
vgui::Label *m_pChapterLabel; |
|
CTGAImagePanel *m_pSaveGameImage; |
|
ImagePanel *m_pAutoSaveImage; |
|
|
|
// things to change color when the selection changes |
|
ImagePanel *m_pSaveGameScreenshotBackground; |
|
Label *m_pTypeLabel; |
|
Label *m_pElapsedTimeLabel; |
|
Label *m_pFileTimeLabel; |
|
Color m_TextColor, m_FillColor, m_SelectedColor; |
|
|
|
int m_iSaveGameListItemID; |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Constructor |
|
//----------------------------------------------------------------------------- |
|
CBaseSaveGameDialog::CBaseSaveGameDialog( vgui::Panel *parent, const char *name ) : BaseClass( parent, name ) |
|
{ |
|
CreateSavedGamesList(); |
|
ScanSavedGames(); |
|
|
|
m_pLoadButton = new vgui::Button( this, "loadsave", "" ); |
|
SetControlEnabled( "loadsave", false ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Creates the load game display list |
|
//----------------------------------------------------------------------------- |
|
void CBaseSaveGameDialog::CreateSavedGamesList() |
|
{ |
|
m_pGameList = new vgui::PanelListPanel( this, "listpanel_loadgame" ); |
|
m_pGameList->SetFirstColumnWidth( 0 ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: returns the save file name of the selected item |
|
//----------------------------------------------------------------------------- |
|
int CBaseSaveGameDialog::GetSelectedItemSaveIndex() |
|
{ |
|
CSaveGamePanel *panel = dynamic_cast<CSaveGamePanel *>(m_pGameList->GetSelectedPanel()); |
|
if ( panel ) |
|
{ |
|
// find the panel in the list |
|
for ( int i = 0; i < m_SaveGames.Count(); i++ ) |
|
{ |
|
if ( i == panel->GetSaveGameListItemID() ) |
|
{ |
|
return i; |
|
} |
|
} |
|
} |
|
return m_SaveGames.InvalidIndex(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: builds save game list from directory |
|
//----------------------------------------------------------------------------- |
|
void CBaseSaveGameDialog::ScanSavedGames() |
|
{ |
|
// populate list box with all saved games on record: |
|
char szDirectory[_MAX_PATH]; |
|
Q_snprintf( szDirectory, sizeof( szDirectory ), "save/*.sav" ); |
|
|
|
// clear the current list |
|
m_pGameList->DeleteAllItems(); |
|
m_SaveGames.RemoveAll(); |
|
|
|
// iterate the saved files |
|
FileFindHandle_t handle; |
|
const char *pFileName = g_pFullFileSystem->FindFirst( szDirectory, &handle ); |
|
while (pFileName) |
|
{ |
|
if ( !Q_strnicmp(pFileName, "HLSave", strlen( "HLSave" ) ) ) |
|
{ |
|
pFileName = g_pFullFileSystem->FindNext( handle ); |
|
continue; |
|
} |
|
|
|
char szFileName[_MAX_PATH]; |
|
Q_snprintf(szFileName, sizeof( szFileName ), "save/%s", pFileName); |
|
|
|
// Only load save games from the current mod's save dir |
|
if( !g_pFullFileSystem->FileExists( szFileName, "MOD" ) ) |
|
{ |
|
pFileName = g_pFullFileSystem->FindNext( handle ); |
|
continue; |
|
} |
|
|
|
SaveGameDescription_t save; |
|
if ( ParseSaveData( szFileName, pFileName, save ) ) |
|
{ |
|
m_SaveGames.AddToTail( save ); |
|
} |
|
|
|
pFileName = g_pFullFileSystem->FindNext( handle ); |
|
} |
|
|
|
g_pFullFileSystem->FindClose( handle ); |
|
|
|
// notify derived classes that save games are being scanned (so they can insert their own) |
|
OnScanningSaveGames(); |
|
|
|
// sort the save list |
|
qsort( m_SaveGames.Base(), m_SaveGames.Count(), sizeof(SaveGameDescription_t), &SaveGameSortFunc ); |
|
|
|
// add to the list |
|
for ( int saveIndex = 0; saveIndex < m_SaveGames.Count() && saveIndex < MAX_LISTED_SAVE_GAMES; saveIndex++ ) |
|
{ |
|
// add the item to the panel |
|
AddSaveGameItemToList( saveIndex ); |
|
} |
|
|
|
// display a message if there are no save games |
|
if ( !m_SaveGames.Count() ) |
|
{ |
|
vgui::Label *pNoSavesLabel = SETUP_PANEL(new Label(m_pGameList, "NoSavesLabel", "#GameUI_NoSaveGamesToDisplay")); |
|
pNoSavesLabel->SetTextColorState(vgui::Label::CS_DULL); |
|
m_pGameList->AddItem( NULL, pNoSavesLabel ); |
|
} |
|
|
|
SetControlEnabled( "loadsave", false ); |
|
SetControlEnabled( "delete", false ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Adds an item to the list |
|
//----------------------------------------------------------------------------- |
|
void CBaseSaveGameDialog::AddSaveGameItemToList( int saveIndex ) |
|
{ |
|
// create the new panel and add to the list |
|
CSaveGamePanel *saveGamePanel = new CSaveGamePanel( m_pGameList, "SaveGamePanel", saveIndex ); |
|
saveGamePanel->SetSaveGameInfo( m_SaveGames[saveIndex] ); |
|
m_pGameList->AddItem( NULL, saveGamePanel ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Parses the save game info out of the .sav file header |
|
//----------------------------------------------------------------------------- |
|
bool CBaseSaveGameDialog::ParseSaveData( char const *pszFileName, char const *pszShortName, SaveGameDescription_t &save ) |
|
{ |
|
char szMapName[SAVEGAME_MAPNAME_LEN]; |
|
char szComment[SAVEGAME_COMMENT_LEN]; |
|
char szElapsedTime[SAVEGAME_ELAPSED_LEN]; |
|
|
|
if ( !pszFileName || !pszShortName ) |
|
return false; |
|
|
|
Q_strncpy( save.szShortName, pszShortName, sizeof(save.szShortName) ); |
|
Q_strncpy( save.szFileName, pszFileName, sizeof(save.szFileName) ); |
|
|
|
FileHandle_t fh = g_pFullFileSystem->Open( pszFileName, "rb", "MOD" ); |
|
if (fh == FILESYSTEM_INVALID_HANDLE) |
|
return false; |
|
|
|
int readok = SaveReadNameAndComment( fh, szMapName, ARRAYSIZE(szMapName), szComment, ARRAYSIZE(szComment) ); |
|
g_pFullFileSystem->Close(fh); |
|
|
|
if ( !readok ) |
|
{ |
|
return false; |
|
} |
|
|
|
Q_strncpy( save.szMapName, szMapName, sizeof(save.szMapName) ); |
|
|
|
// Elapsed time is the last 6 characters in comment. (mmm:ss) |
|
int i; |
|
i = strlen( szComment ); |
|
Q_strncpy( szElapsedTime, "??", sizeof( szElapsedTime ) ); |
|
if (i >= 6) |
|
{ |
|
Q_strncpy( szElapsedTime, (char *)&szComment[i - 6], 7 ); |
|
szElapsedTime[6] = '\0'; |
|
|
|
// parse out |
|
int minutes = atoi( szElapsedTime ); |
|
int seconds = atoi( szElapsedTime + 4); |
|
|
|
// reformat |
|
if ( minutes ) |
|
{ |
|
Q_snprintf( szElapsedTime, sizeof(szElapsedTime), "%d %s %d seconds", minutes, minutes > 1 ? "minutes" : "minute", seconds ); |
|
} |
|
else |
|
{ |
|
Q_snprintf( szElapsedTime, sizeof(szElapsedTime), "%d seconds", seconds ); |
|
} |
|
|
|
// Chop elapsed out of comment. |
|
int n; |
|
|
|
n = i - 6; |
|
szComment[n] = '\0'; |
|
|
|
n--; |
|
|
|
// Strip back the spaces at the end. |
|
while ((n >= 1) && |
|
szComment[n] && |
|
szComment[n] == ' ') |
|
{ |
|
szComment[n--] = '\0'; |
|
} |
|
} |
|
|
|
// calculate the file name to print |
|
const char *pszType = ""; |
|
if (strstr(pszFileName, "quick")) |
|
{ |
|
pszType = "#GameUI_QuickSave"; |
|
} |
|
else if (strstr(pszFileName, "autosave")) |
|
{ |
|
pszType = "#GameUI_AutoSave"; |
|
} |
|
|
|
Q_strncpy( save.szType, pszType, sizeof(save.szType) ); |
|
Q_strncpy( save.szComment, szComment, sizeof(save.szComment) ); |
|
Q_strncpy( save.szElapsedTime, szElapsedTime, sizeof(save.szElapsedTime) ); |
|
|
|
// Now get file time stamp. |
|
time_t fileTime = g_pFullFileSystem->GetFileTime(pszFileName); |
|
char szFileTime[32]; |
|
g_pFullFileSystem->FileTimeToString(szFileTime, sizeof(szFileTime), fileTime); |
|
char *newline = strstr(szFileTime, "\n"); |
|
if (newline) |
|
{ |
|
*newline = 0; |
|
} |
|
Q_strncpy( save.szFileTime, szFileTime, sizeof(save.szFileTime) ); |
|
save.iTimestamp = fileTime; |
|
return true; |
|
} |
|
|
|
void CBaseSaveGameDialog::OnKeyCodeTyped( vgui::KeyCode code ) |
|
{ |
|
if ( code == KEY_ESCAPE ) |
|
{ |
|
OnCommand( "Close" ); |
|
return; |
|
} |
|
|
|
BaseClass::OnKeyCodeTyped( code ); |
|
} |
|
|
|
void CBaseSaveGameDialog::OnKeyCodePressed( vgui::KeyCode code ) |
|
{ |
|
if ( code == KEY_XBUTTON_B ) |
|
{ |
|
OnCommand( "Close" ); |
|
return; |
|
} |
|
else if ( code == KEY_XSTICK1_DOWN || |
|
code == KEY_XSTICK2_DOWN || |
|
code == KEY_XBUTTON_DOWN || |
|
code == KEY_DOWN ) |
|
{ |
|
if ( m_pGameList->GetItemCount() ) |
|
{ |
|
Panel *pSelectedPanel = m_pGameList->GetSelectedPanel(); |
|
if ( !pSelectedPanel ) |
|
{ |
|
m_pGameList->SetSelectedPanel( m_pGameList->GetItemPanel( m_pGameList->FirstItem() ) ); |
|
m_pGameList->ScrollToItem( m_pGameList->FirstItem() ); |
|
return; |
|
} |
|
else |
|
{ |
|
int nNextPanelID = m_pGameList->FirstItem(); |
|
while ( nNextPanelID != m_pGameList->InvalidItemID() ) |
|
{ |
|
if ( m_pGameList->GetItemPanel( nNextPanelID ) == pSelectedPanel ) |
|
{ |
|
nNextPanelID = m_pGameList->NextItem( nNextPanelID ); |
|
if ( nNextPanelID != m_pGameList->InvalidItemID() ) |
|
{ |
|
m_pGameList->SetSelectedPanel( m_pGameList->GetItemPanel( nNextPanelID ) ); |
|
m_pGameList->ScrollToItem( nNextPanelID ); |
|
return; |
|
} |
|
|
|
break; |
|
} |
|
|
|
nNextPanelID = m_pGameList->NextItem( nNextPanelID ); |
|
} |
|
} |
|
} |
|
} |
|
else if ( code == KEY_XSTICK1_UP || |
|
code == KEY_XSTICK2_UP || |
|
code == KEY_XBUTTON_UP || |
|
code == KEY_UP ) |
|
{ |
|
if ( m_pGameList->GetItemCount() ) |
|
{ |
|
Panel *pSelectedPanel = m_pGameList->GetSelectedPanel(); |
|
if ( !pSelectedPanel ) |
|
{ |
|
m_pGameList->SetSelectedPanel( m_pGameList->GetItemPanel( m_pGameList->FirstItem() ) ); |
|
m_pGameList->ScrollToItem( m_pGameList->FirstItem() ); |
|
return; |
|
} |
|
else |
|
{ |
|
int nNextPanelID = m_pGameList->FirstItem(); |
|
if ( m_pGameList->GetItemPanel( nNextPanelID ) != pSelectedPanel ) |
|
{ |
|
while ( nNextPanelID != m_pGameList->InvalidItemID() ) |
|
{ |
|
int nOldPanelID = nNextPanelID; |
|
nNextPanelID = m_pGameList->NextItem( nNextPanelID ); |
|
|
|
if ( nNextPanelID != m_pGameList->InvalidItemID() ) |
|
{ |
|
if ( m_pGameList->GetItemPanel( nNextPanelID ) == pSelectedPanel ) |
|
{ |
|
m_pGameList->SetSelectedPanel( m_pGameList->GetItemPanel( nOldPanelID ) ); |
|
m_pGameList->ScrollToItem( nOldPanelID ); |
|
return; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
else if ( code == KEY_ENTER || code == KEY_XBUTTON_A || code == STEAMCONTROLLER_A ) |
|
{ |
|
Panel *pSelectedPanel = m_pGameList->GetSelectedPanel(); |
|
if ( pSelectedPanel ) |
|
{ |
|
if ( code == KEY_XBUTTON_A || code == STEAMCONTROLLER_A ) |
|
{ |
|
ConVarRef var( "joystick" ); |
|
if ( var.IsValid() && !var.GetBool() ) |
|
{ |
|
var.SetValue( true ); |
|
} |
|
|
|
ConVarRef var2( "hud_fastswitch" ); |
|
if ( var2.IsValid() && var2.GetInt() != 2 ) |
|
{ |
|
var2.SetValue( 2 ); |
|
} |
|
} |
|
|
|
m_pLoadButton->DoClick(); |
|
return; |
|
} |
|
} |
|
|
|
BaseClass::OnKeyCodePressed( code ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: timestamp sort function for savegames |
|
//----------------------------------------------------------------------------- |
|
int CBaseSaveGameDialog::SaveGameSortFunc( const void *lhs, const void *rhs ) |
|
{ |
|
const SaveGameDescription_t *s1 = (const SaveGameDescription_t *)lhs; |
|
const SaveGameDescription_t *s2 = (const SaveGameDescription_t *)rhs; |
|
|
|
if (s1->iTimestamp < s2->iTimestamp) |
|
return 1; |
|
else if (s1->iTimestamp > s2->iTimestamp) |
|
return -1; |
|
|
|
// timestamps are equal, so just sort by filename |
|
return strcmp(s1->szFileName, s2->szFileName); |
|
} |
|
|
|
#define MAKEID(d,c,b,a) ( ((int)(a) << 24) | ((int)(b) << 16) | ((int)(c) << 8) | ((int)(d)) ) |
|
|
|
int SaveReadNameAndComment( FileHandle_t f, OUT_Z_CAP(nameSize) char *name, int nameSize, OUT_Z_CAP(commentSize) char *comment, int commentSize ) |
|
{ |
|
int i, tag, size, tokenSize, tokenCount; |
|
char *pSaveData, *pFieldName, **pTokenList; |
|
|
|
name[0] = '\0'; |
|
comment[0] = '\0'; |
|
|
|
g_pFullFileSystem->Read( &tag, sizeof(int), f ); |
|
if ( tag != MAKEID('J','S','A','V') ) |
|
{ |
|
return 0; |
|
} |
|
|
|
g_pFullFileSystem->Read( &tag, sizeof(int), f ); |
|
if ( tag != SAVEGAME_VERSION ) // Enforce version for now |
|
{ |
|
return 0; |
|
} |
|
|
|
g_pFullFileSystem->Read( &size, sizeof(int), f ); |
|
|
|
g_pFullFileSystem->Read( &tokenCount, sizeof(int), f ); // These two ints are the token list |
|
g_pFullFileSystem->Read( &tokenSize, sizeof(int), f ); |
|
size += tokenSize; |
|
|
|
// Sanity Check. |
|
if ( tokenCount < 0 || tokenCount > 1024*1024*32 ) |
|
{ |
|
return 0; |
|
} |
|
|
|
if ( tokenSize < 0 || tokenSize > 1024*1024*32 ) |
|
{ |
|
return 0; |
|
} |
|
|
|
pSaveData = (char *)new char[size]; |
|
g_pFullFileSystem->Read(pSaveData, size, f); |
|
|
|
int nNumberOfFields; |
|
|
|
char *pData; |
|
short nFieldSize; |
|
|
|
pData = pSaveData; |
|
|
|
// Allocate a table for the strings, and parse the table |
|
if ( tokenSize > 0 ) |
|
{ |
|
pTokenList = new char *[tokenCount]; |
|
|
|
// Make sure the token strings pointed to by the pToken hashtable. |
|
for( i=0; i<tokenCount; i++ ) |
|
{ |
|
pTokenList[i] = *pData ? pData : NULL; // Point to each string in the pToken table |
|
while( *pData++ ); // Find next token (after next null) |
|
} |
|
} |
|
else |
|
pTokenList = NULL; |
|
|
|
// short, short (size, index of field name) |
|
memcpy( &nFieldSize, pData, sizeof(short) ); |
|
|
|
pData += sizeof(short); |
|
short index; |
|
memcpy( &index, pData, sizeof(short) ); |
|
pFieldName = pTokenList[index]; |
|
|
|
if (stricmp(pFieldName, "GameHeader")) |
|
{ |
|
delete[] pSaveData; |
|
return 0; |
|
}; |
|
|
|
// int (fieldcount) |
|
pData += sizeof(short); |
|
memcpy( &nNumberOfFields, pData, sizeof(int) ); |
|
pData += nFieldSize; |
|
|
|
// Each field is a short (size), short (index of name), binary string of "size" bytes (data) |
|
for (i = 0; i < nNumberOfFields; i++) |
|
{ |
|
// Data order is: |
|
// Size |
|
// szName |
|
// Actual Data |
|
|
|
memcpy( &nFieldSize, pData, sizeof(short) ); |
|
pData += sizeof(short); |
|
|
|
short index; |
|
memcpy( &index, pData, sizeof(short)); |
|
pFieldName = pTokenList[index]; |
|
pData += sizeof(short); |
|
|
|
if (!stricmp(pFieldName, "comment")) |
|
{ |
|
int copySize = MAX(commentSize, nFieldSize); |
|
Q_strncpy(comment, pData, copySize); |
|
} |
|
else if (!stricmp(pFieldName, "mapName")) |
|
{ |
|
int copySize = MAX(nameSize, nFieldSize); |
|
Q_strncpy(name, pData, copySize); |
|
}; |
|
|
|
// Move to Start of next field. |
|
pData += nFieldSize; |
|
}; |
|
|
|
// Delete the string table we allocated |
|
delete[] pTokenList; |
|
delete[] pSaveData; |
|
|
|
if (strlen(name) > 0 && strlen(comment) > 0) |
|
return 1; |
|
|
|
return 0; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: deletes an existing save game |
|
//----------------------------------------------------------------------------- |
|
void CBaseSaveGameDialog::DeleteSaveGame( const char *fileName ) |
|
{ |
|
if ( !fileName || !fileName[0] ) |
|
return; |
|
|
|
// delete the save game file |
|
g_pFullFileSystem->RemoveFile( fileName, "MOD" ); |
|
|
|
// delete the associated tga |
|
char tga[_MAX_PATH]; |
|
Q_strncpy( tga, fileName, sizeof(tga) ); |
|
char *ext = strstr( tga, ".sav" ); |
|
if ( ext ) |
|
{ |
|
strcpy( ext, ".tga" ); |
|
} |
|
g_pFullFileSystem->RemoveFile( tga, "MOD" ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: One item has been selected |
|
//----------------------------------------------------------------------------- |
|
void CBaseSaveGameDialog::OnPanelSelected() |
|
{ |
|
SetControlEnabled( "loadsave", true ); |
|
SetControlEnabled( "delete", true ); |
|
} |
|
|
|
|
|
|