1334 lines
38 KiB
C++
1334 lines
38 KiB
C++
//===========================================================================
|
|
// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
|
|
//
|
|
// Component: MemoryCardManager
|
|
//
|
|
// Description: Implementation of the MemoryCardManager class.
|
|
//
|
|
// Authors: Tony Chu
|
|
//
|
|
// Revisions Date Author Revision
|
|
// 2002/09/16 TChu Created for SRR2
|
|
//
|
|
//===========================================================================
|
|
|
|
//===========================================================================
|
|
// Includes
|
|
//===========================================================================
|
|
#include <data/memcard/memorycardmanager.h>
|
|
#include <data/gamedatamanager.h>
|
|
#include <data/savegameinfo.h>
|
|
|
|
#ifndef WORLD_BUILDER
|
|
#include <gameflow/gameflow.h>
|
|
#endif
|
|
|
|
#include <radfile.hpp>
|
|
|
|
#ifndef WORLD_BUILDER
|
|
#include <memory/srrmemory.h>
|
|
#else
|
|
#define MEMTRACK_PUSH_GROUP(x)
|
|
#define MEMTRACK_POP_GROUP(x)
|
|
#define GMA_PERSISTENT 0
|
|
#define GMA_DEFAULT 0
|
|
#define GMA_TEMP 0
|
|
#endif
|
|
|
|
#include <string.h>
|
|
|
|
// Static pointer to instance of singleton.
|
|
MemoryCardManager* MemoryCardManager::spInstance = NULL;
|
|
|
|
//===========================================================================
|
|
// Local Constants
|
|
//===========================================================================
|
|
|
|
#ifdef RAD_PS2
|
|
#ifdef PAL
|
|
const unsigned int MINIMUM_MEMCARD_CHECK_TIME = 3000; // in msec
|
|
#else
|
|
const unsigned int MINIMUM_MEMCARD_CHECK_TIME = 0; // in msec
|
|
#endif
|
|
#elif RAD_WIN32
|
|
const unsigned int MINIMUM_MEMCARD_CHECK_TIME = 0; // in msec
|
|
#else
|
|
const unsigned int MINIMUM_MEMCARD_CHECK_TIME = 1000; // in msec
|
|
#endif
|
|
|
|
const int MAX_SAVED_GAME_TITLE_LENGTH = 32; // # chars
|
|
|
|
#ifdef RAD_WIN32
|
|
char DEFAULT_GAME_DRIVE[radFileDrivenameMax+1]; // for win32, need to store the default.
|
|
#endif
|
|
|
|
const char* SAVE_GAME_DRIVE[] =
|
|
{
|
|
#ifdef RAD_GAMECUBE
|
|
"MEMCARDCHANNELA:",
|
|
"MEMCARDCHANNELB:",
|
|
#endif
|
|
|
|
#ifdef RAD_PS2
|
|
"MEMCARD1A:",
|
|
"MEMCARD1B:",
|
|
"MEMCARD1C:",
|
|
"MEMCARD1D:",
|
|
"MEMCARD2A:",
|
|
"MEMCARD2B:",
|
|
"MEMCARD2C:",
|
|
"MEMCARD2D:",
|
|
#endif
|
|
|
|
#ifdef RAD_XBOX
|
|
// "T:",
|
|
"U:",
|
|
"MEMCARD1A:",
|
|
"MEMCARD1B:",
|
|
"MEMCARD2A:",
|
|
"MEMCARD2B:",
|
|
"MEMCARD3A:",
|
|
"MEMCARD3B:",
|
|
"MEMCARD4A:",
|
|
"MEMCARD4B:",
|
|
#endif
|
|
|
|
#ifdef RAD_WIN32
|
|
DEFAULT_GAME_DRIVE,
|
|
#endif
|
|
|
|
"" // dummy terminator
|
|
};
|
|
|
|
const unsigned int NUM_SAVE_GAME_DRIVES =
|
|
sizeof( SAVE_GAME_DRIVE ) / sizeof( SAVE_GAME_DRIVE[ 0 ] ) - 1;
|
|
|
|
#ifdef RAD_GAMECUBE
|
|
const char* GC_BANNER_FILE = "opening.bnr";
|
|
const char* GC_TPL_FILE = "icon.tpl";
|
|
#endif
|
|
|
|
#ifdef RAD_PS2
|
|
const char* PS2_LIST_ICON_FILE = "list.ico";
|
|
const char* PS2_COPY_ICON_FILE = "copy.ico";
|
|
const char* PS2_DELETE_ICON_FILE = "delete.ico";
|
|
|
|
// this will use the 'list' icon file for all three icons
|
|
//
|
|
#define USE_ONE_ICON_FILE_ONLY
|
|
#endif
|
|
|
|
#ifdef RAD_XBOX
|
|
const char* XBOX_ICON_FILE = "saveimg.xbx";
|
|
|
|
// this will use the default title and save game image icons
|
|
//
|
|
#define USE_DEFAULT_ICONS
|
|
#endif
|
|
|
|
//===========================================================================
|
|
// Public Member Functions
|
|
//===========================================================================
|
|
|
|
//==============================================================================
|
|
// MemoryCardManager::CreateInstance
|
|
//==============================================================================
|
|
//
|
|
// Description: - Creates the Game Data Manager.
|
|
//
|
|
// Parameters: None.
|
|
//
|
|
// Return: Pointer to the MemoryCardManager.
|
|
//
|
|
// Constraints: This is a singleton so only one instance is allowed.
|
|
//
|
|
//==============================================================================
|
|
MemoryCardManager* MemoryCardManager::CreateInstance()
|
|
{
|
|
spInstance = new MemoryCardManager;
|
|
rAssert( spInstance != NULL );
|
|
|
|
return spInstance;
|
|
}
|
|
|
|
//==============================================================================
|
|
// MemoryCardManager::DestroyInstance
|
|
//==============================================================================
|
|
//
|
|
// Description: Destroy the Game Data Manager.
|
|
//
|
|
// Parameters: None.
|
|
//
|
|
// Return: None.
|
|
//
|
|
//==============================================================================
|
|
void MemoryCardManager::DestroyInstance()
|
|
{
|
|
rAssert( spInstance != NULL );
|
|
|
|
delete spInstance;
|
|
spInstance = NULL;
|
|
}
|
|
|
|
//==============================================================================
|
|
// MemoryCardManager::GetInstance
|
|
//==============================================================================
|
|
//
|
|
// Description: - Access point for the MemoryCardManager singleton.
|
|
// - Creates the MemoryCardManager if needed.
|
|
//
|
|
// Parameters: None.
|
|
//
|
|
// Return: Pointer to the MemoryCardManager.
|
|
//
|
|
// Constraints: This is a singleton so only one instance is allowed.
|
|
//
|
|
//==============================================================================
|
|
MemoryCardManager* MemoryCardManager::GetInstance()
|
|
{
|
|
rAssert( spInstance != NULL );
|
|
|
|
return spInstance;
|
|
}
|
|
|
|
//===========================================================================
|
|
// MemoryCardManager::MemoryCardManager
|
|
//===========================================================================
|
|
// Description:
|
|
//
|
|
// Constraints: None.
|
|
//
|
|
// Parameters: None.
|
|
//
|
|
// Return:
|
|
//
|
|
//===========================================================================
|
|
MemoryCardManager::MemoryCardManager()
|
|
: m_currentState( STATE_UNINITIALIZED ),
|
|
m_numDrivesOpened( 0 ),
|
|
m_memcardInfo( NULL ),
|
|
m_memcardInfoLoadState( MEMCARD_INFO_NOT_LOADED ),
|
|
m_memcardInfoLoadCallback( NULL ),
|
|
m_radFile( NULL ),
|
|
m_elapsedMemcardInfoLoadTime( 0 ),
|
|
m_pDrives( NULL ),
|
|
m_currentDrive( NULL ),
|
|
m_radDriveErrorCallback( NULL ),
|
|
m_mediaInfos( NULL ),
|
|
m_currentMediaInfo( -1 ),
|
|
m_nextMediaInfo( 0 ),
|
|
m_formatDriveState( false ),
|
|
m_formatCallback( NULL ),
|
|
m_memcardCheckCallback( NULL ),
|
|
m_memcardCheckingState( MEMCARD_CHECK_NOT_DONE ),
|
|
m_elapsedMemcardCheckTime( 0 ),
|
|
#ifdef RAD_XBOX
|
|
m_savedGameCreationSizeHD( 0 ),
|
|
#endif
|
|
m_savedGameCreationSize( 0 )
|
|
{
|
|
m_pDrives = new IRadDrive*[ NUM_SAVE_GAME_DRIVES ];
|
|
rAssert( m_pDrives != NULL );
|
|
|
|
m_mediaInfos = new IRadDrive::MediaInfo[ NUM_SAVE_GAME_DRIVES ];
|
|
rAssert( m_mediaInfos != NULL );
|
|
|
|
for( unsigned int i = 0; i < NUM_SAVE_GAME_DRIVES; i++ )
|
|
{
|
|
m_pDrives[ i ] = NULL;
|
|
|
|
m_mediaInfos[ i ].m_FreeFiles = 0;
|
|
m_mediaInfos[ i ].m_FreeSpace = 0;
|
|
m_mediaInfos[ i ].m_MediaState = IRadDrive::MediaInfo::MediaNotPresent;
|
|
m_mediaInfos[ i ].m_SectorSize = 0;
|
|
m_mediaInfos[ i ].m_VolumeName[ 0 ] = '\0';
|
|
}
|
|
|
|
/*
|
|
#ifdef RAD_WIN32
|
|
// Algorithm fix which is only needed on PC. If there is only one card,
|
|
// then having m_nextmediainfo = m_currentMediaInfo = 0 won't load anything.
|
|
// We start currentmediainfo at -1 to indicate that nothing has been loaded.
|
|
m_currentMediaInfo = -1;
|
|
#endif
|
|
*/
|
|
}
|
|
|
|
//===========================================================================
|
|
// MemoryCardManager::~MemoryCardManager
|
|
//===========================================================================
|
|
// Description:
|
|
//
|
|
// Constraints: None.
|
|
//
|
|
// Parameters: None.
|
|
//
|
|
// Return:
|
|
//
|
|
//===========================================================================
|
|
MemoryCardManager::~MemoryCardManager()
|
|
{
|
|
if( m_pDrives != NULL )
|
|
{
|
|
// release and un-mount drives
|
|
//
|
|
for( unsigned int i = 0; i < NUM_SAVE_GAME_DRIVES; i++ )
|
|
{
|
|
if( m_pDrives[ i ] != NULL )
|
|
{
|
|
#ifndef RAD_WIN32
|
|
m_pDrives[ i ]->UnregisterErrorHandler( this );
|
|
#endif
|
|
|
|
m_pDrives[ i ]->Release();
|
|
m_pDrives[ i ] = NULL;
|
|
|
|
m_numDrivesOpened--;
|
|
}
|
|
|
|
#ifndef RAD_WIN32
|
|
radDriveUnmount( SAVE_GAME_DRIVE[ i ] );
|
|
#endif
|
|
}
|
|
|
|
rAssert( m_numDrivesOpened == 0 );
|
|
|
|
delete [] m_pDrives;
|
|
m_pDrives = NULL;
|
|
}
|
|
|
|
if( m_mediaInfos != NULL )
|
|
{
|
|
delete [] m_mediaInfos;
|
|
m_mediaInfos = NULL;
|
|
}
|
|
|
|
m_currentState = STATE_UNINITIALIZED;
|
|
}
|
|
|
|
void
|
|
MemoryCardManager::Init( IRadDriveErrorCallback* radDriveErrorCallback )
|
|
{
|
|
m_radDriveErrorCallback = radDriveErrorCallback;
|
|
|
|
#ifdef RAD_WIN32
|
|
radGetDefaultDrive( DEFAULT_GAME_DRIVE );
|
|
#endif
|
|
|
|
// mount and open drives
|
|
//
|
|
for( unsigned int i = 0; i < NUM_SAVE_GAME_DRIVES; i++ )
|
|
{
|
|
#ifndef RAD_WIN32
|
|
bool driveAlreadyMounted = radDriveMount( SAVE_GAME_DRIVE[ i ], GMA_PERSISTENT );
|
|
rAssert( !driveAlreadyMounted );
|
|
#endif
|
|
|
|
radDriveOpenAsync( &m_pDrives[ i ], SAVE_GAME_DRIVE[ i ] );
|
|
rAssert( m_pDrives[ i ] );
|
|
m_pDrives[ i ]->AddCompletionCallback( this, reinterpret_cast<void*>( i ) );
|
|
|
|
// register error handler
|
|
//
|
|
#ifndef RAD_WIN32
|
|
m_pDrives[ i ]->RegisterErrorHandler( this, NULL );
|
|
#endif
|
|
}
|
|
|
|
m_currentState = STATE_OPENING_DRIVES;
|
|
}
|
|
|
|
void
|
|
MemoryCardManager::Update( unsigned int elapsedTime )
|
|
{
|
|
if( m_currentState == STATE_READY )
|
|
{
|
|
if( m_currentMediaInfo != m_nextMediaInfo )
|
|
{
|
|
m_currentMediaInfo = m_nextMediaInfo;
|
|
|
|
// get the next media info asynchronously
|
|
//
|
|
rAssert( m_pDrives[ m_currentMediaInfo ] != NULL );
|
|
m_pDrives[ m_currentMediaInfo ]->GetMediaInfoAsync( &m_mediaInfos[ m_currentMediaInfo ] );
|
|
m_pDrives[ m_currentMediaInfo ]->AddCompletionCallback( this, NULL );
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
MemoryCardManager::StartMemoryCardCheck( IMemoryCardCheckCallback* callback )
|
|
{
|
|
m_memcardCheckCallback = callback;
|
|
m_elapsedMemcardCheckTime = 0;
|
|
|
|
m_currentMediaInfo = -1;
|
|
m_nextMediaInfo = 0;
|
|
|
|
m_memcardCheckingState = MEMCARD_CHECK_IN_PROGRESS;
|
|
}
|
|
|
|
void
|
|
MemoryCardManager::UpdateMemoryCardCheck( unsigned int elapsedTime )
|
|
{
|
|
m_elapsedMemcardCheckTime += elapsedTime;
|
|
if( m_elapsedMemcardCheckTime > MINIMUM_MEMCARD_CHECK_TIME )
|
|
{
|
|
if( m_memcardCheckingState == MEMCARD_CHECK_COMPLETED )
|
|
{
|
|
if( this->IsMemcardInfoLoaded() )
|
|
{
|
|
this->OnMemoryCardCheckCompleted();
|
|
}
|
|
else
|
|
{
|
|
// memory card info must be loaded/loading during memory card check,
|
|
// and should be unloaded when check is completed
|
|
//
|
|
rAssertMsg( m_memcardInfoLoadState != MEMCARD_INFO_NOT_LOADED,
|
|
"ERROR: *** Memory card info not loaded during memory card check!" );
|
|
}
|
|
}
|
|
}
|
|
|
|
if( m_memcardCheckingState == MEMCARD_CHECK_IN_PROGRESS )
|
|
{
|
|
this->Update( elapsedTime );
|
|
}
|
|
}
|
|
|
|
const IRadDrive::MediaInfo*
|
|
MemoryCardManager::GetMediaInfo( unsigned int driveIndex ) const
|
|
{
|
|
rAssert( driveIndex < NUM_SAVE_GAME_DRIVES );
|
|
|
|
return &(m_mediaInfos[ driveIndex ] );
|
|
}
|
|
|
|
void
|
|
MemoryCardManager::LoadMemcardInfo( IMemoryCardInfoLoadCallback* callback )
|
|
{
|
|
#ifndef WORLD_BUILDER
|
|
if( m_memcardInfoLoadState == MEMCARD_INFO_NOT_LOADED )
|
|
{
|
|
MEMTRACK_PUSH_GROUP( "MemcardInfo" );
|
|
bool isIngame = GetGameFlow()->GetCurrentContext() == CONTEXT_GAMEPLAY ||
|
|
GetGameFlow()->GetCurrentContext() == CONTEXT_PAUSE;
|
|
|
|
GameMemoryAllocator heap = isIngame ? GMA_LEVEL_MISSION : GMA_LEVEL_MOVIE;
|
|
|
|
HeapMgr()->PushHeap( heap );
|
|
|
|
m_memcardInfoLoadCallback = callback;
|
|
|
|
rAssert( m_memcardInfo == NULL );
|
|
m_memcardInfo = new radMemcardInfo;
|
|
rAssert( m_memcardInfo != NULL );
|
|
|
|
rTunePrintf( ">> Loading memory card info ... ...\n" );
|
|
|
|
m_elapsedMemcardInfoLoadTime = radTimeGetMilliseconds();
|
|
|
|
#ifdef RAD_GAMECUBE
|
|
this->LoadMemcardInfo_GC( heap );
|
|
#endif
|
|
|
|
#ifdef RAD_PS2
|
|
this->LoadMemcardInfo_PS2( heap );
|
|
#endif
|
|
|
|
#ifdef RAD_XBOX
|
|
this->LoadMemcardInfo_XBOX( heap );
|
|
#endif
|
|
|
|
#ifdef RAD_WIN32
|
|
// go straight to the requests complete method; there is no
|
|
// memcard info.
|
|
OnProcessRequestsComplete( NULL );
|
|
#endif
|
|
|
|
HeapMgr()->PopHeap( heap );
|
|
MEMTRACK_POP_GROUP( "MemcardInfo" );
|
|
}
|
|
else
|
|
{
|
|
rTuneWarningMsg( false, "WARNING: *** Memory card info already loaded! Ignoring request to load again.\n" );
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void
|
|
MemoryCardManager::UnloadMemcardInfo()
|
|
{
|
|
if( m_memcardInfoLoadState == MEMCARD_INFO_LOAD_COMPLETED )
|
|
{
|
|
#ifdef RAD_GAMECUBE
|
|
this->UnloadMemcardInfo_GC();
|
|
#endif
|
|
|
|
#ifdef RAD_PS2
|
|
this->UnloadMemcardInfo_PS2();
|
|
#endif
|
|
|
|
#ifdef RAD_XBOX
|
|
this->UnloadMemcardInfo_XBOX();
|
|
#endif
|
|
|
|
if( m_memcardInfo != NULL )
|
|
{
|
|
delete m_memcardInfo;
|
|
m_memcardInfo = NULL;
|
|
}
|
|
|
|
rTunePrintf( ">> Memory card info unloaded.\n" );
|
|
|
|
m_memcardInfoLoadState = MEMCARD_INFO_NOT_LOADED;
|
|
}
|
|
else
|
|
{
|
|
rTuneWarningMsg( false, "WARNING: *** Memory card info not completely loaded yet! Ignoring request to unload.\n" );
|
|
}
|
|
}
|
|
|
|
bool
|
|
MemoryCardManager::IsMemcardInfoLoaded() const
|
|
{
|
|
return (m_memcardInfoLoadState == MEMCARD_INFO_LOAD_COMPLETED);
|
|
}
|
|
|
|
void
|
|
MemoryCardManager::SetMemcardIconData( char* dataBuffer,
|
|
unsigned int dataSize )
|
|
{
|
|
rAssert( dataBuffer != NULL && dataSize > 0 );
|
|
rAssert( m_memcardInfo != NULL );
|
|
|
|
switch( m_memcardInfoLoadState )
|
|
{
|
|
#ifdef RAD_GAMECUBE
|
|
case MEMCARD_INFO_LOADING_BANNER:
|
|
{
|
|
m_dvdBanner = reinterpret_cast<DVDBanner*>( dataBuffer );
|
|
|
|
// This banner is in RGB format
|
|
//
|
|
m_memcardInfo->m_Banner = m_dvdBanner->image;
|
|
m_memcardInfo->m_BannerFormat = radMemcardInfo::RGB5A3;
|
|
|
|
// Take the comment from the disk too.
|
|
//
|
|
memcpy( m_memcardInfo->m_CommentLine1, m_dvdBanner->shortTitle, 32 );
|
|
strcpy( m_memcardInfo->m_CommentLine2, "" );
|
|
|
|
break;
|
|
}
|
|
case MEMCARD_INFO_LOADING_TEXPALETTE:
|
|
{
|
|
m_texPalette = reinterpret_cast<TEXPalette*>( dataBuffer );
|
|
|
|
// We have a TEXPalette, we need to parse it.
|
|
//
|
|
UnpackTexPalette( m_texPalette );
|
|
|
|
//
|
|
// Set the animation to loop at find number of frames
|
|
//
|
|
m_memcardInfo->m_AnimType = radMemcardInfo::Loop;
|
|
|
|
m_memcardInfo->m_NumFrames = m_texPalette->numDescriptors > 8 ? 8 : m_texPalette->numDescriptors;
|
|
|
|
//
|
|
// Set the info for all frames
|
|
//
|
|
for( unsigned int i = 0; i < m_memcardInfo->m_NumFrames; i++ )
|
|
{
|
|
TEXDescriptorPtr tdp = TEXGet( m_texPalette, (u32) i );
|
|
|
|
rAssertMsg( tdp->textureHeader->height == 32 && tdp->textureHeader->width == 32,
|
|
"Icon is the wrong dimension. Should be 32 by 32." );
|
|
|
|
//
|
|
// Set format and data
|
|
//
|
|
m_memcardInfo->m_pIcon[ i ].m_CLUT = NULL;
|
|
|
|
switch( (GXTexFmt)(tdp->textureHeader->format) )
|
|
{
|
|
case GX_TF_RGB5A3:
|
|
{
|
|
m_memcardInfo->m_pIcon[ i ].m_Format = radMemcardIconData::RGB5A3;
|
|
m_memcardInfo->m_pIcon[ i ].m_Data = (void*) tdp->textureHeader->data;
|
|
|
|
break;
|
|
}
|
|
case GX_TF_C8:
|
|
{
|
|
m_memcardInfo->m_pIcon[ i ].m_Format = radMemcardIconData::C8;
|
|
m_memcardInfo->m_pIcon[ i ].m_Data = (void*) tdp->textureHeader->data;
|
|
|
|
rAssert( tdp->CLUTHeader );
|
|
rAssert( (GXTlutFmt) tdp->CLUTHeader->format == GX_TL_RGB5A3 );
|
|
rAssert( tdp->CLUTHeader->numEntries == 256 );
|
|
|
|
m_memcardInfo->m_pIcon[ i ].m_CLUT = (void*) tdp->CLUTHeader->data;
|
|
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
rAssertMsg( false, "Unsupported icon texture format." );
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Set speed
|
|
//
|
|
m_memcardInfo->m_pIcon[ i ].m_Speed = radMemcardIconData::Slow;
|
|
}
|
|
|
|
break;
|
|
}
|
|
#endif // RAD_GAMECUBE
|
|
|
|
#ifdef RAD_PS2
|
|
case MEMCARD_INFO_LOADING_ICON_LIST:
|
|
{
|
|
m_memcardInfo->m_ListIcon = dataBuffer;
|
|
m_memcardInfo->m_ListIconSize = dataSize;
|
|
|
|
#ifdef USE_ONE_ICON_FILE_ONLY
|
|
m_memcardInfo->m_CopyIcon = dataBuffer;
|
|
m_memcardInfo->m_CopyIconSize = dataSize;
|
|
|
|
m_memcardInfo->m_DelIcon = dataBuffer;
|
|
m_memcardInfo->m_DelIconSize = dataSize;
|
|
|
|
m_memcardInfoLoadState = MEMCARD_INFO_LOADING_ICON_DELETE;
|
|
#endif
|
|
|
|
break;
|
|
}
|
|
case MEMCARD_INFO_LOADING_ICON_COPY:
|
|
{
|
|
m_memcardInfo->m_CopyIcon = dataBuffer;
|
|
m_memcardInfo->m_CopyIconSize = dataSize;
|
|
|
|
break;
|
|
}
|
|
case MEMCARD_INFO_LOADING_ICON_DELETE:
|
|
{
|
|
m_memcardInfo->m_DelIcon = dataBuffer;
|
|
m_memcardInfo->m_DelIconSize = dataSize;
|
|
|
|
break;
|
|
}
|
|
#endif // RAD_PS2
|
|
|
|
#ifdef RAD_XBOX
|
|
case MEMCARD_INFO_LOADING_ICON:
|
|
{
|
|
m_memcardInfo->m_Icon = dataBuffer;
|
|
m_memcardInfo->m_IconSize = dataSize;
|
|
|
|
break;
|
|
}
|
|
#endif // RAD_XBOX
|
|
|
|
case MEMCARD_INFO_NOT_LOADED:
|
|
{
|
|
rAssertMsg( false, "*** ERROR: Invalid MemcardInfo load state!" );
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
MemoryCardManager::OnProcessRequestsComplete( void* pUserData )
|
|
{
|
|
m_memcardInfoLoadState++;
|
|
|
|
if( m_memcardInfoLoadState == MEMCARD_INFO_LOAD_COMPLETED )
|
|
{
|
|
// determine amount of time it took to load memcard info
|
|
//
|
|
m_elapsedMemcardInfoLoadTime = radTimeGetMilliseconds() - m_elapsedMemcardInfoLoadTime;
|
|
|
|
rTunePrintf( ">> Memory card info loaded. (%d msec)\n",
|
|
m_elapsedMemcardInfoLoadTime );
|
|
|
|
if( m_memcardInfoLoadCallback != NULL )
|
|
{
|
|
m_memcardInfoLoadCallback->OnMemcardInfoLoadComplete();
|
|
m_memcardInfoLoadCallback = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
MemoryCardManager::SetCurrentDrive( unsigned int driveIndex )
|
|
{
|
|
rAssert( driveIndex < NUM_SAVE_GAME_DRIVES );
|
|
|
|
this->SetCurrentDrive( m_pDrives[ driveIndex ] );
|
|
}
|
|
void
|
|
MemoryCardManager::ClearCurrentDrive( )
|
|
{
|
|
m_currentDrive = NULL;
|
|
}
|
|
|
|
int
|
|
MemoryCardManager::GetCurrentDriveIndex() const
|
|
{
|
|
return( this->GetDriveIndex( m_currentDrive ) );
|
|
}
|
|
const char *
|
|
MemoryCardManager::GetDriveName(unsigned int driveIndex) const
|
|
{
|
|
rAssert(driveIndex < NUM_SAVE_GAME_DRIVES);
|
|
rAssert(m_pDrives[ driveIndex ]);
|
|
return m_pDrives[driveIndex]->GetDriveName();
|
|
}
|
|
const char *
|
|
MemoryCardManager::GetCurrentDriveVolumeName() const
|
|
{
|
|
return m_mediaInfos[ GetCurrentDriveIndex() ].m_VolumeName;
|
|
}
|
|
|
|
bool
|
|
MemoryCardManager::IsCurrentDrivePresent( unsigned int currentDriveIndex )
|
|
{
|
|
bool isMissing = true;
|
|
if( static_cast<int>( currentDriveIndex ) != -1 )
|
|
{
|
|
isMissing = (m_mediaInfos[ currentDriveIndex ].m_MediaState == IRadDrive::MediaInfo::MediaNotPresent);
|
|
}
|
|
return !isMissing;
|
|
}
|
|
bool
|
|
MemoryCardManager::IsCurrentDriveReady( bool forceSyncUpdate, bool *unformatted , IRadDrive::MediaInfo::MediaState *errorOut)
|
|
{
|
|
bool isReady = false;
|
|
bool card_unformatted = false;
|
|
|
|
int currentDriveIndex = this->GetCurrentDriveIndex();
|
|
if (unformatted!=NULL)
|
|
*unformatted = false;
|
|
if( currentDriveIndex != -1 )
|
|
{
|
|
if( forceSyncUpdate )
|
|
{
|
|
// force synchronous update on current drive's media info
|
|
//
|
|
m_pDrives[ currentDriveIndex ]->GetMediaInfoSync( &m_mediaInfos[ currentDriveIndex ] );
|
|
}
|
|
if (errorOut)
|
|
*errorOut = m_mediaInfos[ currentDriveIndex ].m_MediaState;
|
|
|
|
if ( m_mediaInfos[ currentDriveIndex ].m_MediaState==IRadDrive::MediaInfo::MediaNotFormatted )
|
|
{
|
|
card_unformatted = true;
|
|
}
|
|
#ifdef RAD_GAMECUBE
|
|
if ( m_mediaInfos[ currentDriveIndex ].m_MediaState==IRadDrive::MediaInfo::MediaEncodingErr )
|
|
card_unformatted = true;
|
|
#endif
|
|
isReady = (m_mediaInfos[ currentDriveIndex ].m_MediaState == IRadDrive::MediaInfo::MediaPresent);
|
|
if (unformatted)
|
|
*unformatted = card_unformatted;
|
|
|
|
if( !isReady
|
|
&& card_unformatted==false )
|
|
// we need to keep track of unformatted drive so we can format it
|
|
{
|
|
// memory card must have been pulled out, reset current drive
|
|
//
|
|
m_currentDrive = NULL;
|
|
}
|
|
}
|
|
|
|
return isReady;
|
|
}
|
|
|
|
int
|
|
MemoryCardManager::GetAvailableDrives( IRadDrive** pDrives,
|
|
IRadDrive::MediaInfo** mediaInfos,
|
|
IRadDrive **drive_mounted)
|
|
{
|
|
int numAvailableDrives = 0;
|
|
|
|
// query for all drives currently present
|
|
//
|
|
for( unsigned int i = 0; i < NUM_SAVE_GAME_DRIVES; i++ )
|
|
{
|
|
rAssert( m_pDrives[ i ] );
|
|
|
|
if( m_mediaInfos[ i ].m_MediaState != IRadDrive::MediaInfo::MediaNotPresent )
|
|
{
|
|
if( pDrives != NULL )
|
|
{
|
|
pDrives[ numAvailableDrives ] = m_pDrives[ i ];
|
|
}
|
|
|
|
if( mediaInfos != NULL )
|
|
{
|
|
mediaInfos[ numAvailableDrives ] = &m_mediaInfos[ i ];
|
|
}
|
|
if (drive_mounted)
|
|
{
|
|
drive_mounted[i] = m_pDrives[ i ];
|
|
}
|
|
numAvailableDrives++;
|
|
}
|
|
else
|
|
{
|
|
if (drive_mounted)
|
|
{
|
|
drive_mounted[i] = NULL;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// terminate w/ NULL
|
|
//
|
|
if( pDrives != NULL )
|
|
{
|
|
pDrives[ numAvailableDrives ] = NULL;
|
|
}
|
|
|
|
return numAvailableDrives;
|
|
}
|
|
|
|
bool
|
|
MemoryCardManager::EnoughFreeSpace( unsigned int driveIndex ) const
|
|
{
|
|
rAssert( driveIndex < NUM_SAVE_GAME_DRIVES );
|
|
|
|
const unsigned int NUM_FREE_FILES_REQUIRED = 1;
|
|
|
|
return( m_mediaInfos[ driveIndex ].m_FreeFiles >= NUM_FREE_FILES_REQUIRED &&
|
|
m_mediaInfos[ driveIndex ].m_FreeSpace >= this->GetSavedGameCreationSize( driveIndex ) );
|
|
}
|
|
|
|
void MemoryCardManager::FormatDrive(unsigned int driveIndex, IMemoryCardFormatCallback *callback)
|
|
{
|
|
SetCurrentDrive(driveIndex);
|
|
m_formatDriveState = true;
|
|
rAssert(callback);
|
|
m_formatCallback = callback;
|
|
m_currentDrive->FormatAsync();
|
|
m_currentDrive->AddCompletionCallback( this , NULL);
|
|
}
|
|
void
|
|
MemoryCardManager::UpdateMemcardInfo( const char* savedGameTitle, int lineBreak )
|
|
{
|
|
rAssert( m_memcardInfo != NULL );
|
|
|
|
#ifdef RAD_GAMECUBE
|
|
rAssert( savedGameTitle != NULL );
|
|
strncpy( m_memcardInfo->m_CommentLine2,
|
|
savedGameTitle,
|
|
MAX_SAVED_GAME_TITLE_LENGTH );
|
|
#endif
|
|
|
|
#ifdef RAD_PS2
|
|
rAssert( savedGameTitle != NULL );
|
|
rAssert( lineBreak != -1 );
|
|
|
|
radSJISChar title[ MAX_SAVED_GAME_TITLE_LENGTH ];
|
|
radAsciiToSjis( title, savedGameTitle );
|
|
radSetIconSysTitle( &(m_memcardInfo->m_IconSys),
|
|
title,
|
|
static_cast<unsigned short>( lineBreak ) );
|
|
#endif
|
|
|
|
#ifdef RAD_XBOX
|
|
// TC: stinky XBox! there's is no way to specify a descriptive name
|
|
// that's different from the file name
|
|
//
|
|
rWarningMsg( savedGameTitle == NULL, "Can't specify save game title on Xbox!" );
|
|
#endif
|
|
}
|
|
|
|
void
|
|
MemoryCardManager::OnDriveOperationsComplete( void* pUserData )
|
|
{
|
|
if ( m_formatDriveState )
|
|
{
|
|
m_formatCallback->OnFormatOperationComplete(Success);
|
|
m_formatDriveState = false;
|
|
}
|
|
else if( m_currentState == STATE_OPENING_DRIVES )
|
|
{
|
|
unsigned int driveIndex = reinterpret_cast<unsigned int>( pUserData );
|
|
rAssert( driveIndex < NUM_SAVE_GAME_DRIVES );
|
|
|
|
m_numDrivesOpened++;
|
|
|
|
if( m_numDrivesOpened == NUM_SAVE_GAME_DRIVES )
|
|
{
|
|
// done opening all save game drives
|
|
//
|
|
m_currentState = STATE_READY;
|
|
}
|
|
}
|
|
else // checking memory cards during bootup
|
|
{
|
|
rAssert( m_currentMediaInfo == m_nextMediaInfo );
|
|
m_nextMediaInfo = (m_currentMediaInfo + 1) % NUM_SAVE_GAME_DRIVES;
|
|
|
|
if( m_memcardCheckingState == MEMCARD_CHECK_IN_PROGRESS )
|
|
{
|
|
if( m_nextMediaInfo == 0 )
|
|
{
|
|
#if defined( RAD_GAMECUBE) || defined( RAD_PS2 )
|
|
// continue to poll for media info from all drives
|
|
// during the entire minimum checking time
|
|
//
|
|
if( m_elapsedMemcardCheckTime > MINIMUM_MEMCARD_CHECK_TIME )
|
|
#endif
|
|
{
|
|
// ok, we finished querying media info from all drives
|
|
//
|
|
m_memcardCheckingState = MEMCARD_CHECK_COMPLETED;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool
|
|
MemoryCardManager::HasSaveGame(unsigned int driveIndex)
|
|
{
|
|
rAssert( driveIndex < NUM_SAVE_GAME_DRIVES );
|
|
return GetGameDataManager()->DoesSaveGameExist( m_pDrives[ driveIndex ], false );
|
|
}
|
|
|
|
bool
|
|
MemoryCardManager::OnDriveError( radFileError error,
|
|
const char* pDriveName,
|
|
void* pUserData )
|
|
{
|
|
|
|
rDebugPrintf( "*** MEMCARD: ERROR [%d] occurred on drive [%s]! ***\n",
|
|
error,
|
|
pDriveName );
|
|
|
|
if ( m_formatDriveState )
|
|
{
|
|
m_formatCallback->OnFormatOperationComplete(error);
|
|
}
|
|
else if( m_radDriveErrorCallback != NULL )
|
|
{
|
|
m_radDriveErrorCallback->OnDriveError( error, pDriveName, pUserData );
|
|
}
|
|
|
|
// we should always return false, since we're always going to prompt
|
|
// the user first before attempting to retry any operation
|
|
//
|
|
return false;
|
|
}
|
|
|
|
int
|
|
MemoryCardManager::GetDriveIndex( IRadDrive* pDrive ) const
|
|
{
|
|
int driveIndex = -1;
|
|
|
|
if( pDrive != NULL )
|
|
{
|
|
for( unsigned int i = 0; i < NUM_SAVE_GAME_DRIVES; i++ )
|
|
{
|
|
if( strcmp( pDrive->GetDriveName(), SAVE_GAME_DRIVE[ i ] ) == 0 )
|
|
{
|
|
driveIndex = static_cast<int>( i );
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return driveIndex;
|
|
}
|
|
|
|
//===========================================================================
|
|
// Private Member Functions
|
|
//===========================================================================
|
|
|
|
void
|
|
MemoryCardManager::DetermineSavedGameCreationSize( unsigned int driveIndex )
|
|
{
|
|
#ifdef RAD_XBOX
|
|
if( driveIndex == 0 ) // Xbox hard disk
|
|
{
|
|
rAssert( driveIndex < NUM_SAVE_GAME_DRIVES );
|
|
m_savedGameCreationSizeHD = m_pDrives[ driveIndex ]->GetCreationSize( m_memcardInfo, GetGameDataManager()->GetGameDataSize() );
|
|
|
|
rReleasePrintf( "The Simpsons Hit & Run Saved Game File Size (on HD) = %.2f KB (%d bytes)\n",
|
|
m_savedGameCreationSizeHD / 1024.0f, m_savedGameCreationSizeHD );
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
rAssert( driveIndex < NUM_SAVE_GAME_DRIVES );
|
|
m_savedGameCreationSize = m_pDrives[ driveIndex ]->GetCreationSize( m_memcardInfo, GetGameDataManager()->GetGameDataSize() );
|
|
|
|
rReleasePrintf( "The Simpsons Hit & Run Saved Game File Size = %.2f KB (%d bytes)\n",
|
|
m_savedGameCreationSize / 1024.0f, m_savedGameCreationSize );
|
|
}
|
|
}
|
|
|
|
void
|
|
MemoryCardManager::OnMemoryCardCheckCompleted()
|
|
{
|
|
radFileError errorCode = Success;
|
|
IRadDrive::MediaInfo::MediaState mediaState = IRadDrive::MediaInfo::MediaPresent;
|
|
int driveIndex = -1;
|
|
|
|
// search for a good memory card w/ enough free space to save games
|
|
//
|
|
bool goodCardExists = false;
|
|
bool fullCardExists = false;
|
|
|
|
// and, at the same time, search for most recent save game among
|
|
// all drives
|
|
//
|
|
int mostRecentSaveGameDriveIndex = -1;
|
|
int mostRecentSaveGameSlot = -1;
|
|
radDate mostRecentTimeStamp;
|
|
mostRecentTimeStamp.m_Year = 0;
|
|
|
|
for( unsigned int i = 0; i < NUM_SAVE_GAME_DRIVES; i++ )
|
|
{
|
|
// determine saved game creation size
|
|
//
|
|
this->DetermineSavedGameCreationSize( i );
|
|
|
|
if( m_mediaInfos[ i ].m_MediaState == IRadDrive::MediaInfo::MediaPresent )
|
|
{
|
|
unsigned int slot = 0;
|
|
radDate timeStamp;
|
|
bool saveGameExists = GetGameDataManager()->FindMostRecentSaveGame( m_pDrives[ i ],
|
|
slot,
|
|
timeStamp );
|
|
if( saveGameExists )
|
|
{
|
|
if( SaveGameInfo::CompareTimeStamps( timeStamp, mostRecentTimeStamp ) > 0 )
|
|
{
|
|
mostRecentSaveGameDriveIndex = static_cast<int>( i );
|
|
mostRecentSaveGameSlot = static_cast<int>( slot );
|
|
memcpy( &mostRecentTimeStamp, &timeStamp, sizeof( radDate ) );
|
|
}
|
|
}
|
|
|
|
if( this->EnoughFreeSpace( i ) )
|
|
{
|
|
goodCardExists = true; // we found good card, continue looping to find the latest save game
|
|
}
|
|
else
|
|
{
|
|
#ifdef RAD_GAMECUBE
|
|
// Nintendo TRC: if there is a full memory card, we need to check later to see if
|
|
// all game slots are taken up; if not, then we must display a "full memory card" error message
|
|
//
|
|
fullCardExists = true;
|
|
#endif
|
|
if( saveGameExists )
|
|
{
|
|
goodCardExists = true; // we found good card, continue looping to find the latest save game
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef RAD_XBOX
|
|
// only need to check xbox hard disk, no need to check memory units
|
|
//
|
|
rAssertMsg( m_mediaInfos[ 0 ].m_MediaState == IRadDrive::MediaInfo::MediaPresent,
|
|
"ERROR: *** WTF? The Xbox Hard Disk is not present??" );
|
|
|
|
if( !GetGameDataManager()->DoesSaveGameExist( m_pDrives[ 0 ] ) &&
|
|
!this->EnoughFreeSpace( 0 ) )
|
|
{
|
|
driveIndex = 0;
|
|
errorCode = NoFreeSpace;
|
|
}
|
|
#endif // RAD_XBOX
|
|
|
|
#ifdef RAD_WIN32
|
|
rAssertMsg( m_mediaInfos[ 0 ].m_MediaState == IRadDrive::MediaInfo::MediaPresent,
|
|
"ERROR: Default hard drive didn't mount." );
|
|
#endif // RAD_WIN32
|
|
|
|
#if defined( RAD_GAMECUBE ) || defined( RAD_PS2 )
|
|
if( !goodCardExists || fullCardExists )
|
|
{
|
|
// no good card exists; now search for first card w/ an error
|
|
//
|
|
bool errorExists = false;
|
|
for( unsigned int i = 0; i < NUM_SAVE_GAME_DRIVES; i++ )
|
|
{
|
|
if( m_mediaInfos[ i ].m_MediaState == IRadDrive::MediaInfo::MediaPresent )
|
|
{
|
|
#ifdef RAD_GAMECUBE
|
|
bool saveGameExists = GetGameDataManager()->DoesSaveGameExist( m_pDrives[ i ], true, true );
|
|
#else
|
|
bool saveGameExists = GetGameDataManager()->DoesSaveGameExist( m_pDrives[ i ] );
|
|
#endif
|
|
if( !saveGameExists && !this->EnoughFreeSpace( i ) )
|
|
{
|
|
errorExists = true;
|
|
|
|
errorCode = NoFreeSpace;
|
|
driveIndex = static_cast<int>( i );
|
|
|
|
break;
|
|
}
|
|
}
|
|
else if( m_mediaInfos[ i ].m_MediaState != IRadDrive::MediaInfo::MediaNotPresent )
|
|
{
|
|
errorExists = true;
|
|
|
|
errorCode = m_pDrives[ i ]->GetLastError();
|
|
mediaState = m_mediaInfos[ i ].m_MediaState;
|
|
driveIndex = static_cast<int>( i );
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( !errorExists && !fullCardExists )
|
|
{
|
|
// hmmm... no error exists, that means there are no memory cards attached
|
|
//
|
|
mediaState = IRadDrive::MediaInfo::MediaNotPresent;
|
|
driveIndex = -1;
|
|
|
|
#ifdef RAD_DEBUG
|
|
// let's double check that there are, in fact, no memory cards
|
|
//
|
|
for( unsigned int i = 0; i < NUM_SAVE_GAME_DRIVES; i++ )
|
|
{
|
|
rAssert( m_mediaInfos[ i ].m_MediaState == IRadDrive::MediaInfo::MediaNotPresent );
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
#endif // RAD_GAMECUBE || RAD_PS2
|
|
|
|
if( m_memcardCheckCallback != NULL )
|
|
{
|
|
m_memcardCheckCallback->OnMemoryCardCheckDone( errorCode,
|
|
mediaState,
|
|
driveIndex,
|
|
mostRecentSaveGameDriveIndex,
|
|
mostRecentSaveGameSlot );
|
|
m_memcardCheckCallback = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
#ifdef RAD_GAMECUBE
|
|
//
|
|
// I have no idea what this does ...
|
|
//
|
|
void
|
|
MemoryCardManager::UnpackTexPalette( TEXPalettePtr pal )
|
|
{
|
|
u16 i;
|
|
|
|
rAssertMsg( pal->versionNumber == 2142000, "Invalid version number for texture palette" );
|
|
|
|
pal->descriptorArray = (TEXDescriptorPtr)(((u32)(pal->descriptorArray)) + ((u32)pal));
|
|
|
|
//
|
|
// Go through each of the palette descriptors
|
|
//
|
|
for ( i = 0; i < pal->numDescriptors; i++ )
|
|
{
|
|
if( pal->descriptorArray[ i ].textureHeader )
|
|
{
|
|
//
|
|
// Fill in the texture header
|
|
//
|
|
pal->descriptorArray[ i ].textureHeader =
|
|
reinterpret_cast< TEXHeaderPtr >
|
|
(
|
|
( (u32) pal->descriptorArray[i].textureHeader ) +
|
|
( (u32) pal )
|
|
);
|
|
|
|
//
|
|
// If it is not unpacked, unpack it
|
|
//
|
|
if
|
|
(
|
|
!( pal->descriptorArray[i].textureHeader->unpacked )
|
|
)
|
|
{
|
|
pal->descriptorArray[i].textureHeader->data =
|
|
reinterpret_cast< Ptr >
|
|
(
|
|
( (u32) pal->descriptorArray[ i ].textureHeader->data ) +
|
|
( (u32) pal )
|
|
);
|
|
pal->descriptorArray[i].textureHeader->unpacked = 1;
|
|
}
|
|
}
|
|
|
|
if(pal->descriptorArray[i].CLUTHeader)
|
|
{
|
|
pal->descriptorArray[i].CLUTHeader = (CLUTHeaderPtr)((u32)(pal->descriptorArray[i].CLUTHeader) + (u32)pal);
|
|
|
|
if(!(pal->descriptorArray[i].CLUTHeader->unpacked))
|
|
{
|
|
pal->descriptorArray[i].CLUTHeader->data = (Ptr)((u32)(pal->descriptorArray[i].CLUTHeader->data) + (u32)pal);
|
|
pal->descriptorArray[i].CLUTHeader->unpacked = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
MemoryCardManager::LoadMemcardInfo_GC( GameMemoryAllocator heap )
|
|
{
|
|
m_dvdBanner = NULL;
|
|
m_texPalette = NULL;
|
|
|
|
GetLoadingManager()->AddRequest( FILEHANDLER_ICON,
|
|
GC_BANNER_FILE,
|
|
heap,
|
|
this );
|
|
|
|
GetLoadingManager()->AddRequest( FILEHANDLER_ICON,
|
|
GC_TPL_FILE,
|
|
heap,
|
|
this );
|
|
|
|
m_memcardInfoLoadState = MEMCARD_INFO_LOADING_BANNER;
|
|
}
|
|
|
|
void
|
|
MemoryCardManager::UnloadMemcardInfo_GC()
|
|
{
|
|
if( m_dvdBanner != NULL )
|
|
{
|
|
delete m_dvdBanner;
|
|
m_dvdBanner = NULL;
|
|
}
|
|
|
|
if( m_texPalette != NULL )
|
|
{
|
|
delete [] m_texPalette;
|
|
m_texPalette = NULL;
|
|
}
|
|
}
|
|
#endif // RAD_GAMECUBE
|
|
|
|
#ifdef RAD_PS2
|
|
void
|
|
MemoryCardManager::LoadMemcardInfo_PS2( GameMemoryAllocator heap )
|
|
{
|
|
// make a header structure
|
|
//
|
|
radSJISChar title[ MAX_SAVED_GAME_TITLE_LENGTH ];
|
|
radAsciiToSjis( title, "" );
|
|
rAssert( m_memcardInfo != NULL );
|
|
radMakeIconSys( &(m_memcardInfo->m_IconSys), title, 0 );
|
|
|
|
m_memcardInfo->m_ListIcon = NULL;
|
|
m_memcardInfo->m_CopyIcon = NULL;
|
|
m_memcardInfo->m_DelIcon = NULL;
|
|
|
|
GetLoadingManager()->AddRequest( FILEHANDLER_ICON,
|
|
PS2_LIST_ICON_FILE,
|
|
heap,
|
|
this );
|
|
|
|
#ifndef USE_ONE_ICON_FILE_ONLY
|
|
GetLoadingManager()->AddRequest( FILEHANDLER_ICON,
|
|
PS2_COPY_ICON_FILE,
|
|
heap,
|
|
this );
|
|
|
|
GetLoadingManager()->AddRequest( FILEHANDLER_ICON,
|
|
PS2_DELETE_ICON_FILE,
|
|
heap,
|
|
this );
|
|
#endif
|
|
|
|
m_memcardInfoLoadState = MEMCARD_INFO_LOADING_ICON_LIST;
|
|
}
|
|
|
|
void
|
|
MemoryCardManager::UnloadMemcardInfo_PS2()
|
|
{
|
|
if( m_memcardInfo != NULL )
|
|
{
|
|
if( m_memcardInfo->m_ListIcon != NULL )
|
|
{
|
|
delete [] reinterpret_cast<char*>( m_memcardInfo->m_ListIcon );
|
|
m_memcardInfo->m_ListIcon = NULL;
|
|
}
|
|
|
|
#ifdef USE_ONE_ICON_FILE_ONLY
|
|
m_memcardInfo->m_CopyIcon = NULL;
|
|
m_memcardInfo->m_DelIcon = NULL;
|
|
#else
|
|
if( m_memcardInfo->m_CopyIcon != NULL )
|
|
{
|
|
delete [] reinterpret_cast<char*>( m_memcardInfo->m_CopyIcon );
|
|
m_memcardInfo->m_CopyIcon = NULL;
|
|
}
|
|
|
|
if( m_memcardInfo->m_DelIcon != NULL )
|
|
{
|
|
delete [] reinterpret_cast<char*>( m_memcardInfo->m_DelIcon );
|
|
m_memcardInfo->m_DelIcon = NULL;
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
#endif // RAD_PS2
|
|
|
|
#ifdef RAD_XBOX
|
|
void
|
|
MemoryCardManager::LoadMemcardInfo_XBOX( GameMemoryAllocator heap )
|
|
{
|
|
rAssert( m_memcardInfo != NULL );
|
|
m_memcardInfo->m_Icon = NULL;
|
|
|
|
m_memcardInfoLoadState = MEMCARD_INFO_LOADING_ICON;
|
|
|
|
#ifdef USE_DEFAULT_ICONS
|
|
this->OnProcessRequestsComplete( NULL );
|
|
#else
|
|
GetLoadingManager()->AddRequest( FILEHANDLER_ICON,
|
|
XBOX_ICON_FILE,
|
|
heap,
|
|
this );
|
|
#endif
|
|
}
|
|
|
|
void
|
|
MemoryCardManager::UnloadMemcardInfo_XBOX()
|
|
{
|
|
if( m_memcardInfo != NULL )
|
|
{
|
|
if( m_memcardInfo->m_Icon != NULL )
|
|
{
|
|
delete [] reinterpret_cast<char*>( m_memcardInfo->m_Icon );
|
|
m_memcardInfo->m_Icon = NULL;
|
|
}
|
|
}
|
|
}
|
|
#endif // RAD_XBOX
|
|
|