
///////////////////////////////////////////////////////////////////////////////
//
// File   : Asura_PSP_SCEUtilityWrapper.cpp
// Author : Andy Tate
// Date   : 16-Mar-2005
//
// Copyright (C) 2005 Rebellion, All Rights Reserved.
//
///////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Include files...
////////////////////////////////////////////////////////////////////////////////

#include "Core/Asura.h"

// This file's header...
#include "SCEUtility/Asura_PSP_SCEUtilityWrapper.h"

// Asura headers...
#include "Core/Asura_Checksum.h"
#include "Core/Asura_LocalisedText.h"
#include "Core/Asura_Maths.h"
#include "Core/Asura_String.h"
#include "Core/Memory/Asura_Mem.h"
#include "Debugging/Asura_Assert.h"
#include "Debugging/Asura_Logfile.h"
#include "Rendering/Asura_Render.h"

// Platform headers...
#include "Core/Asura_PSP_KernelManagement.h"
#include "Core/Asura_PSP_Thread_Priorities.h"
#include "FileAccess/Asura_PSP_FileIO.h"
#include "Rendering/Asura_PSP_GU.h"

#include <impose.h>
#include <iofilemgr.h>
#include <fatms.h>
#ifdef ASURA_PSP_GAMESHARING
#include <pspnet_adhoc_matching.h>
#include <pspnet_adhoc.h>
#endif
#include <utility/utility_sysparam.h>

////////////////////////////////////////////////////////////////////////////////
// Constant declarations...
////////////////////////////////////////////////////////////////////////////////

static const char	szTITLE_ID []		= ASURA_PSP_PRODUCT_CODE;
static const char	szFILENAME []		= "DATA.BIN";

static const u_int	uASURA_PSP_MEMSTICK_INVALID_FREE_BLOCKS = 0xffffffff;

////////////////////////////////////////////////////////////////////////////////
// Static variable declarations...
////////////////////////////////////////////////////////////////////////////////

// What we're currently doing...

Asura_PSP_SCEUtilityWrapper::Command		Asura_PSP_SCEUtilityWrapper::s_eCommand					= Asura_PSP_SCEUtilityWrapper::NONE;
Asura_PSP_SCEUtilityWrapper::CommandState	Asura_PSP_SCEUtilityWrapper::s_eCommandState			= Asura_PSP_SCEUtilityWrapper::COMMAND_INACTIVE;

Asura_PSP_SCEUtilityWrapper::CommandState	Asura_PSP_SCEUtilityWrapper::s_eShutdownCommandState	= Asura_PSP_SCEUtilityWrapper::COMMAND_INACTIVE;
u_int										Asura_PSP_SCEUtilityWrapper::s_uShutdownErrorNumber		= SCE_UTILITY_COMMON_RESULT_OK;


// Sony's on-screen keyboard structures...

SceUtilityOskInputFieldInfo	Asura_PSP_SCEUtilityWrapper::s_xSceUtilityOskInputFieldInfo;
SceUtilityOskParam			Asura_PSP_SCEUtilityWrapper::s_xSceUtilityOskParam;


// Sony's save-data structures...

void*								Asura_PSP_SCEUtilityWrapper::s_pvDestinationForSavedataLoad	= NULL;
u_int								Asura_PSP_SCEUtilityWrapper::s_uExpectedSizeOfSavedataLoad	= 0;

char								Asura_PSP_SCEUtilityWrapper::s_szSavedataNewDataTitle [SCE_UTILITY_SD_SYSF_TITLE_SIZE];

char								Asura_PSP_SCEUtilityWrapper::s_szSavedataAutosaveUserID [SCE_UTILITY_SD_USERID_SIZE]							= "";
char								Asura_PSP_SCEUtilityWrapper::s_aszSavedataUserIDs [SCE_UTILITY_SD_LISTITEM_MAX][SCE_UTILITY_SD_USERID_SIZE]	= {""};

SceUtilitySDExtFile					Asura_PSP_SCEUtilityWrapper::s_xSceUtilitySDExtFileBackground;
SceUtilitySDExtFile					Asura_PSP_SCEUtilityWrapper::s_xSceUtilitySDExtFileIcon;

SceUtilitySavedataListSaveNewData	Asura_PSP_SCEUtilityWrapper::s_xSceUtilitySavedataListSaveNewData;

SceUtilitySavedataParam				Asura_PSP_SCEUtilityWrapper::s_xSceUtilitySavedataParam;

#ifdef ASURA_PSP_SUPPORT_INFRASTRUCTURE_NETWORK
SceUtilityNetconfParam				Asura_PSP_SCEUtilityWrapper::s_xSceUtilityNetconfParam;
#endif

#ifdef ASURA_PSP_GAMESHARING
SceUtilityGameSharingParam			Asura_PSP_SCEUtilityWrapper::s_xGameSharingParam;
SceNetAdhocctlAdhocId				Asura_PSP_SCEUtilityWrapper::s_xGameSharingID = {
	/* .type    = */ SCE_NET_ADHOCCTL_ADHOCTYPE_SYSTEM,
	/* .data    = */ {'0','0','0','0','0','0','0','0','1'},	// "000000001"
	/* .padding = */ {0, 0, 0}
};
SceNetAdhocctlGroupName				Asura_PSP_SCEUtilityWrapper::s_xGamesharingGroupName = {
	/* .data = */	{'G', 'a', 'm', 'e', 'S', 'h', 'a', 'r'} // "GameShar"
};
#endif


// Sony's message-dialog strutures...

SceUtilityMsgDialogParam	Asura_PSP_SCEUtilityWrapper::s_xSceUtilityMsgDialogParam;


// Utility data that holds the calculated save sizes (AN 13/09/07)
SceUtilitySavedataUtilityDataSize	Asura_PSP_SCEUtilityWrapper::s_xSceUtilitySavedataUtilityDataSize;



// Circle button variables...

int	Asura_PSP_SCEUtilityWrapper::s_iSceUtilitySystemParamCtrlAssign	= SCE_UTILITY_CTRL_ASSIGN_CROSS_IS_ENTER;

// Language variables...

int Asura_PSP_SCEUtilityWrapper::s_iSceUtilitySystemLanguage = SCE_UTILITY_LANG_ENGLISH;

// Nickname variables...

Asura_UnicodeChar	Asura_PSP_SCEUtilityWrapper::s_wszNickname [uASURA_PSP_NICKNAME_MAX_CHARS];


// Project-specific variables...

const Asura_UnicodeChar*	Asura_PSP_SCEUtilityWrapper::s_wszTitleName	= NULL;

Asura_PSP_SCEUtilityWrapper::LoadDataValidationFunction (*Asura_PSP_SCEUtilityWrapper::s_pfnValidation)	= NULL;
bool Asura_PSP_SCEUtilityWrapper::s_bNeedDelete = false;

bool Asura_PSP_SCEUtilityWrapper::s_bGoToDeleteIfNoSpace = false;	// Off by default
bool Asura_PSP_SCEUtilityWrapper::s_bMemoryStickChanged;
u_int Asura_PSP_SCEUtilityWrapper::s_uMemoryStickFreeBlocks = uASURA_PSP_MEMSTICK_INVALID_FREE_BLOCKS;

Asura_Mutex Asura_PSP_SCEUtilityWrapper::s_xUtilityMutex;

Asura_Hash_ID Asura_PSP_SCEUtilityWrapper::s_uBackgroundMenuPage;

////////////////////////////////////////////////////////////////////////////////
// Functions...
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::LoadSceUtilitySDExtFile
// Author       : Andy Tate
// Date         : 16-Mar-2005
//
// Description  : Initialises the specified structure - used for setting the
//				  language displayed, button state, etc...
//
// Parameters   : A reference to the structure to be initialised.
//
// Return value : "true" if loaded successfully, "false" if failed.
////////////////////////////////////////////////////////////////////////////////

bool Asura_PSP_SCEUtilityWrapper::LoadSceUtilitySDExtFile (char const* szFilename,
														   SceUtilitySDExtFile& rSceUtilitySDExtFile)
{
	char	szFixedFilename[256];
	int		hFile;
	
	// Open the file...
	Asura_PSP_FileIO::GetFullPath(szFilename, 256, szFixedFilename);
	hFile	= Asura_PSP_FileIO::Open (szFixedFilename, SCE_O_RDONLY, 0);

	// Blank the structure...
	Asura_Mem::Set(&rSceUtilitySDExtFile, 0, sizeof(rSceUtilitySDExtFile));

	// Did we succeed?
	if (hFile < 0)
	{
		// No - report the error...
		Asura_Assert	(false, "Asura_PSP_SCEUtilityWrapper::LoadSceUtilitySDExtFile(): Failed to open file.");
		return			(false);
	}
	else
	{
		int		iSize	= Asura_PSP_FileIO::Lseek (hFile, 0, SCE_SEEK_END);
		void*	pData	= new char [iSize];

		// Yes - read the file...
		Asura_PSP_FileIO::Lseek	(hFile, 0, SCE_SEEK_SET);

		iSize	= Asura_PSP_FileIO::Read (hFile, pData, iSize);
		
		// Initialise the variables...
		rSceUtilitySDExtFile.pDataBuf		= pData;
		rSceUtilitySDExtFile.dataBufSize	= iSize;
		rSceUtilitySDExtFile.dataFileSize	= iSize;

		// Close the file and return...
		Asura_PSP_FileIO::Close	(hFile);
		return					(true);
	}
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::LoadSceUtilitySDExtFile'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::InitialiseStructure
// Author       : Andy Tate
// Date         : 16-Mar-2005
//
// Description  : Initialises the specified structure - used for setting the
//				  language displayed, button state, etc...
//
// Parameters   : A reference to the structure to be initialised.
//
// Return value : None.
////////////////////////////////////////////////////////////////////////////////

void Asura_PSP_SCEUtilityWrapper::InitialiseStructure (const int iSize,
													   void* pvStructure,
													   SceUtilityParamBase& rBase)
{
	// Clear the structure...

	Asura_Mem::Set(pvStructure, 0, iSize);


	// Initialise the data...

	rBase.size					= iSize;
	rBase.ctrl_assign			= s_iSceUtilitySystemParamCtrlAssign;
	rBase.main_thread_priority	= iASURA_THREAD_PRIORITY_UTILITY_BASE + 1;
	rBase.sub_thread_priority	= iASURA_THREAD_PRIORITY_UTILITY_BASE + 3;
	rBase.font_thread_priority	= iASURA_THREAD_PRIORITY_UTILITY_BASE + 2;
	rBase.sound_thread_priority	= iASURA_THREAD_PRIORITY_UTILITY_BASE;
	rBase.message_lang			= s_iSceUtilitySystemLanguage;
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::InitialiseStructure'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::InitialiseUserIDs
// Author       : Andy Tate
// Date         : 4-Oct-2005
//
// Description  : Initialises the user IDs for use in saving/loading.
//
// Parameters   : The number of user IDs to be initialised.
//
// Return value : None.
////////////////////////////////////////////////////////////////////////////////

void Asura_PSP_SCEUtilityWrapper::InitialiseUserIDs (const int iNumUserIDs)
{
	// Create the range of possible user IDs...
	for (int i = 0; i < iNumUserIDs; i++)
	{
		sprintf	(s_aszSavedataUserIDs [i], "%04d", i);
	}

	// Add the terminator ID...
	strcpy	(s_aszSavedataUserIDs [iNumUserIDs], "");
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::InitialiseUserIDs'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::HandleLoadCommencing
// Author       : Andy Tate
// Date         : 28-Apr-2005
//
// Description  : Handles the commencement of the loading.
//
// Parameters   : A pointer to the data AND the sizes to be loaded.
//
// Return value : None.
////////////////////////////////////////////////////////////////////////////////

void Asura_PSP_SCEUtilityWrapper::HandleLoadCommencing (void* pData,
														const u_int uDataSize,
														const u_int uBufferSize)
{
	// Add the title and filename to the parameters...
    
	strncpy	(s_xSceUtilitySavedataParam.titleId,	szTITLE_ID,	SCE_UTILITY_SD_TITLEID_SIZE);
	strncpy	(s_xSceUtilitySavedataParam.fileName,	szFILENAME,	SCE_UTILITY_SD_FILENAME_SIZE);


	// Initialise the load-buffer...

	s_xSceUtilitySavedataParam.pDataBuf		= new char [uBufferSize];
	s_xSceUtilitySavedataParam.dataBufSize	= uBufferSize;

	s_pvDestinationForSavedataLoad			= pData;
	s_uExpectedSizeOfSavedataLoad			= uDataSize;
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::HandleLoadCommencing'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::HandleSaveCommencing
// Author       : Andy Tate
// Date         : 28-Apr-2005
//
// Description  : Handles the commencement of saving.
//
// Parameters   : 
//
// Return value : None.
////////////////////////////////////////////////////////////////////////////////

void Asura_PSP_SCEUtilityWrapper::HandleSaveCommencing (const Asura_UnicodeChar* wszSaveTitle,
														const Asura_UnicodeChar* wszSaveDescription,
														const void* pData,
														const u_int uDataSize,
														const u_int uBufferSize)
{
	Asura_Assert( uBufferSize >= uDataSize + Asura_Checksum::CHECKSUM_LENGTH, "buffer too small");
	u_char*	aucBuffer	= new u_char [uBufferSize];

	// Initialise the filenames and icons...
	strncpy	(s_xSceUtilitySavedataParam.titleId,	szTITLE_ID,	SCE_UTILITY_SD_TITLEID_SIZE);
	strncpy	(s_xSceUtilitySavedataParam.fileName,	szFILENAME,	SCE_UTILITY_SD_FILENAME_SIZE);
	
	Asura_Mem::Copy	(&s_xSceUtilitySavedataParam.icon0,	&s_xSceUtilitySDExtFileIcon,		sizeof(s_xSceUtilitySDExtFileIcon));
	Asura_Mem::Copy	(&s_xSceUtilitySavedataParam.pic1,	&s_xSceUtilitySDExtFileBackground,	sizeof(s_xSceUtilitySDExtFileBackground));

	// Set the buffer where the data to be saved is stored...
	s_xSceUtilitySavedataParam.pDataBuf		= aucBuffer;
	s_xSceUtilitySavedataParam.dataBufSize	= uBufferSize;
	s_xSceUtilitySavedataParam.dataFileSize	= uBufferSize;

	Asura_Mem::Set						(aucBuffer, 0x00, uBufferSize);
	Asura_Checksum::EncodeFromBuffer	(static_cast<u_char const*>(pData), uDataSize, aucBuffer);
	Asura_Mem::Copy						(&aucBuffer [Asura_Checksum::CHECKSUM_LENGTH], pData, uDataSize);

	// Initialise the system file data...
	Asura_Assert(wcslen(s_wszTitleName) < SCE_UTILITY_SD_SYSF_TITLE_SIZE, "Save game title size too large");
	Asura_UnicodeToUTF8 (s_wszTitleName,		s_xSceUtilitySavedataParam.systemFile.title);
	Asura_UnicodeToUTF8	(wszSaveTitle,			s_xSceUtilitySavedataParam.systemFile.savedataTitle);
	Asura_UnicodeToUTF8	(wszSaveDescription,	s_xSceUtilitySavedataParam.systemFile.detail);

	s_xSceUtilitySavedataParam.systemFile.parentalLev	= ASURA_PSP_PARENTAL_CONTROL_LEVEL;

	// Initialise the new-data icon AND text...
	s_xSceUtilitySavedataListSaveNewData.pTitle	= s_szSavedataNewDataTitle;
	s_xSceUtilitySavedataParam.pNewData			= &s_xSceUtilitySavedataListSaveNewData;
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::HandleSaveCommencing'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::HandleCheckSizeCommencing
// Author       : Attila Novak
// Date         : 12-Sept-2007
//
// Description  : Handles the commencement of size check.
//
// Parameters   : 
//
// Return value : None.
////////////////////////////////////////////////////////////////////////////////

void Asura_PSP_SCEUtilityWrapper::HandleCheckSizeCommencing (	const u_int uDataSize,
																const u_int uBufferSize)
{
	Asura_Assert( uBufferSize >= uDataSize + Asura_Checksum::CHECKSUM_LENGTH, "buffer too small");
	u_char*	aucBuffer	= new u_char [uBufferSize];

	// Initialise the filenames and icons...
	strncpy	(s_xSceUtilitySavedataParam.fileName,	szFILENAME,	SCE_UTILITY_SD_FILENAME_SIZE);

	// Note: not the whole structure, only pDataBuf & dataBufSize are used
	Asura_Mem::Copy	(&s_xSceUtilitySavedataParam.icon0,	&s_xSceUtilitySDExtFileIcon,		sizeof(s_xSceUtilitySDExtFileIcon));
	Asura_Mem::Copy	(&s_xSceUtilitySavedataParam.pic1,	&s_xSceUtilitySDExtFileBackground,	sizeof(s_xSceUtilitySDExtFileBackground));

	// Set the buffer size
	s_xSceUtilitySavedataParam.dataFileSize	= uBufferSize;

	// Reset utility data
	Asura_Mem::Set(&s_xSceUtilitySavedataUtilityDataSize, 0x00, sizeof(SceUtilitySavedataUtilityDataSize));

	// Set utility data pointer
	s_xSceUtilitySavedataParam.pUtilityData = &s_xSceUtilitySavedataUtilityDataSize;
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::HandleCheckSizeCommencing'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::HandleOSKCompletion
// Author       : Andy Tate
// Date         : 28-Apr-2005
//
// Description  : Handles completion of OSK text entry.
//
// Return value : None.
////////////////////////////////////////////////////////////////////////////////

void Asura_PSP_SCEUtilityWrapper::HandleOSKCompletion (void)
{
	// Was the text entry successful?

	if (s_xSceUtilityOskParam.base.result != SCE_UTILITY_COMMON_RESULT_OK)
	{
		const Asura_UnicodeChar*	wszTextBeforeEdit	= reinterpret_cast<const Asura_UnicodeChar*>(s_xSceUtilityOskInputFieldInfo.init_text);
		Asura_UnicodeChar*			wszTextAfterEdit	= reinterpret_cast<Asura_UnicodeChar*>(s_xSceUtilityOskInputFieldInfo.result_text_buffer);


		// No - copy the original text...
		Asura_Assert(wszTextAfterEdit != wszTextBeforeEdit, "overlapping buffers");
		wcscpy	(wszTextAfterEdit, wszTextBeforeEdit);

		s_eShutdownCommandState	= COMMAND_CANCELLED;
	}
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::HandleOSKCompletion'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::HandleDeleteCompletion
// Author       : Andy Tate
// Date         : 28-Apr-2005
//
// Description  : Handles completion of deleting saves from the memory stick.
//
// Return value : None.
////////////////////////////////////////////////////////////////////////////////

void Asura_PSP_SCEUtilityWrapper::HandleDeleteCompletion (void)
{
	// recheck free blocks
	s_uMemoryStickFreeBlocks = GetMemoryStickFreeBlocks();
	// Did we complete successfully?
	if (s_xSceUtilitySavedataParam.base.result != SCE_UTILITY_COMMON_RESULT_OK)
	{
		// No - report that we cancelled...
		s_eShutdownCommandState	= COMMAND_CANCELLED;
	}
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::HandleDeleteCompletion'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::HandleLoadCompletion
// Author       : Andy Tate
// Date         : 28-Apr-2005
//
// Description  : Handles the completion of the current load.
//
// Return value : None.
////////////////////////////////////////////////////////////////////////////////

void Asura_PSP_SCEUtilityWrapper::HandleLoadCompletion (void)
{
	// Did we complete successfully?

	// Check for a situation which would require a retry
	
	// If SafeFailure is true it means that, despite the load process being terminated unexpectedly, the data
	// is correctly loaded and therefore we may proceed as if it were successful.
	bool bSafeFailure = false;
	bool bRetry = false;

	if(SCE_UTILITY_COMMON_RESULT_ABORTED == s_xSceUtilitySavedataParam.base.result)
	{
		if(SCE_UTILITY_COMMON_RESULT_OK == s_xSceUtilitySavedataParam.abortedStatus)
		{
			// All's well after all; press on as if we'd got an 'OK' result from the base result
			bSafeFailure = true;
		}
		else
		{
			// attempt a retry
			bRetry = true;			
		}
	}


	if (SCE_UTILITY_COMMON_RESULT_OK == s_xSceUtilitySavedataParam.base.result || bSafeFailure)
	{
		u_char*	aucBuffer	= static_cast<u_char*>(s_xSceUtilitySavedataParam.pDataBuf);
		u_char	aucActualChecksum [Asura_Checksum::CHECKSUM_LENGTH];

		// Yes - calculate the actual checksum...
		Asura_Checksum::EncodeFromBuffer	(&aucBuffer [Asura_Checksum::CHECKSUM_LENGTH], s_uExpectedSizeOfSavedataLoad, aucActualChecksum);

		// Are the checksums the same?
		bool bSuccess = Asura_Checksum::Compare(aucActualChecksum, aucBuffer);
		Asura_Assert( bSuccess, "File data failed checksum test.");
		if( bSuccess )
		{
			// Yes - do we need to validate the data?
			if( NULL != s_pfnValidation )
			{
				// Yes - do so...
				bSuccess	= s_pfnValidation( &aucBuffer [Asura_Checksum::CHECKSUM_LENGTH], s_uExpectedSizeOfSavedataLoad, s_uExpectedSizeOfSavedataLoad );
				Asura_Assert( bSuccess, "File data vaildation failed.");
			}
		}

		if ( bSuccess )
		{
			// Yes - mark as successful...
			if (s_eCommand != SAVEDATA_LOAD_SINGLE &&
				s_eCommand != SAVEDATA_SAVE_SINGLE &&
				s_eCommand != SAVEDATA_AUTOLOAD_SINGLE &&
				s_eCommand != SAVEDATA_AUTOSAVE_SINGLE)
			{
				strncpy	(s_szSavedataAutosaveUserID, s_xSceUtilitySavedataParam.userId, SCE_UTILITY_SD_USERID_SIZE);
			}
			Asura_Mem::Copy (s_pvDestinationForSavedataLoad, &aucBuffer [Asura_Checksum::CHECKSUM_LENGTH], s_uExpectedSizeOfSavedataLoad);
			s_bMemoryStickChanged = false;
			s_uMemoryStickFreeBlocks = GetMemoryStickFreeBlocks();
		}

		else
		{
			// No - mark the loaded data as corrupt...
			s_eShutdownCommandState	= COMMAND_ERROR;
			s_uShutdownErrorNumber	= SCE_UTILITY_SAVEDATA_ERROR_LOAD_DATA_BROKEN;
		}
	}

	else
	{
		// No - were we autoloading?
		if (SAVEDATA_AUTOLOAD == s_eCommand)
		{
			// Yes - report the error using the message-dialog...
			s_eShutdownCommandState	= COMMAND_ERROR;
			s_uShutdownErrorNumber	= s_xSceUtilitySavedataParam.base.result;
		}
		else if (SAVEDATA_AUTOLOAD_SINGLE == s_eCommand &&
			s_xSceUtilitySavedataParam.base.result != SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA &&
			s_xSceUtilitySavedataParam.base.result != SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_MS)
		{
			// Yes - report the error using the message-dialog...
			s_eShutdownCommandState	= COMMAND_ERROR;
			s_uShutdownErrorNumber	= s_xSceUtilitySavedataParam.base.result;
		}
		else
		{
			// No - ignore the error, simply mark the load as canceled...
			s_eShutdownCommandState	= COMMAND_CANCELLED;
		}
	}

	if(bRetry)
	{
		s_eShutdownCommandState	= COMMAND_RETRY;
	}

	// Delete the previously allocated data...
	delete []	(s_xSceUtilitySavedataParam.pDataBuf);

	s_xSceUtilitySavedataParam.pDataBuf	= NULL;
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::HandleLoadCompletion'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::HandleSaveCompletion
// Author       : Andy Tate
// Date         : 28-Apr-2005
//
// Description  : Handles the completion of the current save.
//
// Return value : None.
////////////////////////////////////////////////////////////////////////////////

void Asura_PSP_SCEUtilityWrapper::HandleSaveCompletion (void)
{
	// Was the save/load successful?
	switch (s_xSceUtilitySavedataParam.base.result)
	{
		case SCE_UTILITY_COMMON_RESULT_ABORTED:
		{
			if(s_xSceUtilitySavedataParam.abortedStatus != SCE_UTILITY_COMMON_RESULT_OK)
			{
				// attempt a retry
				s_eShutdownCommandState	= COMMAND_RETRY;
				break;
			}
			//else fallthrough and treat as OK
		}
		case SCE_UTILITY_COMMON_RESULT_OK:
		{
			// Yes - mark as successful...

			if (s_eCommand != SAVEDATA_LOAD_SINGLE &&
				s_eCommand != SAVEDATA_SAVE_SINGLE &&
				s_eCommand != SAVEDATA_AUTOLOAD_SINGLE &&
				s_eCommand != SAVEDATA_AUTOSAVE_SINGLE)
			{
				strncpy	(s_szSavedataAutosaveUserID, s_xSceUtilitySavedataParam.userId, SCE_UTILITY_SD_USERID_SIZE);
			}
			s_bMemoryStickChanged = false;
			s_uMemoryStickFreeBlocks = GetMemoryStickFreeBlocks();
			break;
		}

		// If no space, go to delete
		case SCE_UTILITY_SAVEDATA_ERROR_SAVE_MS_NOSPACE:
		{
			// No - report the error using the message-dialog...
			s_eShutdownCommandState	= COMMAND_ERROR;
			s_uShutdownErrorNumber	= s_xSceUtilitySavedataParam.base.result;
			break;
		}

//		case SCE_UTILITY_SAVEDATA_ERROR_SAVE_NO_MS:
		case SCE_UTILITY_SAVEDATA_ERROR_SAVE_EJECT_MS:
		case SCE_UTILITY_SAVEDATA_ERROR_SAVE_MS_PROTECTED:
		case SCE_UTILITY_SAVEDATA_ERROR_SAVE_ACCESS_ERROR:
		case SCE_UTILITY_SAVEDATA_ERROR_SAVE_PARAM:
#if 0
		// JG: new Sony libraries 2.00 don't support this anynore
		case SCE_UTILITY_SAVEDATA_ERROR_SAVE_NO_UMD:
		case SCE_UTILITY_SAVEDATA_ERROR_SAVE_WRONG_UMD:
#endif

		case SCE_UTILITY_SAVEDATA_ERROR_SAVE_INTERNAL:
		default:
		{
			// No - were we autosaving?
			if (SAVEDATA_AUTOSAVE == s_eCommand || SAVEDATA_AUTOSAVE_SINGLE == s_eCommand)
			{
				// Yes - report the error using the message-dialog...
				s_eShutdownCommandState	= COMMAND_ERROR;
				s_uShutdownErrorNumber	= s_xSceUtilitySavedataParam.base.result;
			}
			else
			{
				// No - ignore the error, simply mark the save as canceled...
				s_eShutdownCommandState	= COMMAND_CANCELLED;
			}
			break;
		}
	}		// End of switch.

	// Begin shutting down the save-data...
	delete []	(s_xSceUtilitySavedataParam.pDataBuf);
	s_xSceUtilitySavedataParam.pDataBuf	= NULL;
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::HandleSaveCompletion'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::HandleCheckSizeCompletion
// Author       : Attila Novak
// Date         : 12-Sept-2007
//
// Description  : Handles the completion of the current memory stick size check.
//
// Return value : None.
////////////////////////////////////////////////////////////////////////////////

void Asura_PSP_SCEUtilityWrapper::HandleCheckSizeCompletion (void)
{
	// Was the size check successful?
	switch (s_xSceUtilitySavedataParam.base.result)
	{
		case SCE_UTILITY_COMMON_RESULT_ABORTED:
		{
			// Aborted - retry?
			if(s_xSceUtilitySavedataParam.abortedStatus != SCE_UTILITY_COMMON_RESULT_OK)
			{
				// attempt a retry
				s_eShutdownCommandState	= COMMAND_RETRY;
				break;
			}
			//else fallthrough and treat as OK
		}
		case SCE_UTILITY_COMMON_RESULT_OK:
		case SCE_UTILITY_SAVEDATA_ERROR_SIZES_NO_MS:
		{
			// Yes - mark as successful...
			// (Save size calculated based on 32K cluster size is still valid, even if command failed)
			s_bMemoryStickChanged = false;
			s_uMemoryStickFreeBlocks = GetMemoryStickFreeBlocks();
			break;
		}

		case SCE_UTILITY_SAVEDATA_ERROR_SIZES_EJECT_MS:
		case SCE_UTILITY_SAVEDATA_ERROR_SIZES_ACCESS_ERROR:
		case SCE_UTILITY_SAVEDATA_ERROR_SIZES_DATA_BROKEN:
		case SCE_UTILITY_SAVEDATA_ERROR_SIZES_NO_DATA:
		case SCE_UTILITY_SAVEDATA_ERROR_SIZES_PARAM:
		case SCE_UTILITY_SAVEDATA_ERROR_SIZES_INTERNAL:
		default:
		{
			// No - mark as cancelled...
			s_eShutdownCommandState	= COMMAND_CANCELLED;
			break;
		}
	}		// End of switch.

	// Begin shutting down the save-data...
	delete []	(s_xSceUtilitySavedataParam.pDataBuf);
	s_xSceUtilitySavedataParam.pDataBuf	= NULL;
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::HandleSaveCompletion'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::InitialiseUtilityLibrary
// Author       : Andy Tate
// Date         : 16-Mar-2005
//
// Description  : Initialises the approriate part of Sony's Utility library
//				  depending upon the command currently being executed.
//
// Parameters	: The command we're about to initialise.
//
// Return value : The current state of the command being updated.
////////////////////////////////////////////////////////////////////////////////

Asura_PSP_SCEUtilityWrapper::CommandState Asura_PSP_SCEUtilityWrapper::InitialiseUtilityLibrary (const Command eCommand,
																								 void* pvStructure)
{
	Asura_Assert(NONE == s_eCommand, "already using Utility library");
	if (NONE != s_eCommand)
	{
		return COMMAND_ERROR;
	}

	int	iStatus;

	// Reset the shutdown variables...
	s_eShutdownCommandState	= COMMAND_COMPLETED;
	s_uShutdownErrorNumber	= SCE_UTILITY_COMMON_RESULT_OK;

	// Send the kernel to sleep...
	Asura_PSP_KernelManagement::Suspend(Asura_PSP_KernelManagement::UTILITY_LIBRARY);

	s_xUtilityMutex.Lock();

	// What sort of command are we performing?
	switch (eCommand)
	{
		case ON_SCREEN_KEYBOARD:
		{
			// Initialise the OSK...
			iStatus	= sceUtilityOskInitStart (static_cast<SceUtilityOskParam*>(pvStructure));
			break;
		}
#ifdef ASURA_PSP_GAMESHARING
		case GAME_SHARING:
		{	
			//MKR 23/11/06: start up the game sharing utility
			iStatus = sceUtilityGameSharingInitStart(static_cast<SceUtilityGameSharingParam*>(pvStructure));
			break;
		}
#endif

		case SAVEDATA_AUTOLOAD:
		case SAVEDATA_AUTOSAVE:
		case SAVEDATA_DELETE:
		case SAVEDATA_LOAD_LIST:
		case SAVEDATA_SAVE_LIST:
		case SAVEDATA_LOAD_SINGLE:
		case SAVEDATA_SAVE_SINGLE:
		case SAVEDATA_AUTOLOAD_SINGLE:
		case SAVEDATA_AUTOSAVE_SINGLE:
		// Check save size (AN 12/09/07)
		case SAVEDATA_CHECKSAVESIZE:
		{
			// Initialise the save-data...
			iStatus	= sceUtilitySavedataInitStart (static_cast<SceUtilitySavedataParam*>(pvStructure));
			break;
		}

		case MESSAGE_DIALOG:
		{
			// Initialise the message-dialog...
			iStatus	= sceUtilityMsgDialogInitStart (static_cast<SceUtilityMsgDialogParam*>(pvStructure));
			break;
		}

#ifdef ASURA_PSP_SUPPORT_INFRASTRUCTURE_NETWORK
		case INFRASTRUCTURE_CONNNECTION:
		{
			Asura_Assert( pvStructure == &s_xSceUtilityNetconfParam, "unexpected pointer");
			iStatus = sceUtilityNetconfInitStart(&s_xSceUtilityNetconfParam);
			break;
		}
#endif // #ifdef ASURA_PSP_SUPPORT_INFRASTRUCTURE_NETWORK
	
		default:
		{
			// Shouldn't reach here...
			Asura_Assert(false, "Asura_PSP_SCEUtilityWrapper::InitialiseUtilityLibrary(): Unexpected command.");
			s_xUtilityMutex.Unlock();
			return(COMMAND_ERROR);
		}
	}		// End of switch.

	s_xUtilityMutex.Unlock();

	// Were we successful?
	if (iStatus >= 0)
	{
		// Yes - set the command and return that we're now in progress...
		s_eCommand	= eCommand;
		return(COMMAND_IN_PROGRESS);
	}
	else
	{
		// No - better report this...
		Asura_PSP_KernelManagement::Resume(Asura_PSP_KernelManagement::UTILITY_LIBRARY);
		Asura_Assert(false, "Asura_PSP_SCEUtilityWrapper::InitialiseUtilityLibrary(): Failed to initialise.");
		return(COMMAND_ERROR);
	}
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::InitialiseUtilityLibrary'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::GetUtilityLibraryStatus
// Author       : Andy Tate
// Date         : 16-Mar-2005
//
// Description  : Queries the approriate part of Sony's Utility library depending
//				  upon the command currently being executed.
//
// Return value : The appropriate Sony Utility status.
////////////////////////////////////////////////////////////////////////////////

int Asura_PSP_SCEUtilityWrapper::GetUtilityLibraryStatus (void)
{
	int iRet;
	s_xUtilityMutex.Lock();

	// What sort of command are we performing?
	switch (s_eCommand)
	{
		case NONE:
		{
			// Not doing anything - return no status...
			iRet = (SCE_UTILITY_COMMON_STATUS_NONE);
			break;
		}

#ifdef ASURA_PSP_GAMESHARING
		case GAME_SHARING:
		{
			iRet = sceUtilityGameSharingGetStatus();
			break;
		}
#endif

		case ON_SCREEN_KEYBOARD:
		{
			// Return the OSK status...
			iRet = (sceUtilityOskGetStatus());
			break;
		}

		case SAVEDATA_AUTOLOAD:
		case SAVEDATA_AUTOSAVE:
		case SAVEDATA_DELETE:
		case SAVEDATA_LOAD_LIST:
		case SAVEDATA_SAVE_LIST:
		case SAVEDATA_LOAD_SINGLE:
		case SAVEDATA_SAVE_SINGLE:
		case SAVEDATA_AUTOLOAD_SINGLE:
		case SAVEDATA_AUTOSAVE_SINGLE:
		// Check save size (AN 12/09/07)
		case SAVEDATA_CHECKSAVESIZE:
		{
			// Return the save-data status...
			iRet = (sceUtilitySavedataGetStatus());
			break;
		}

		case MESSAGE_DIALOG:
		{
			// Return the message-dialog status...
			iRet = (sceUtilityMsgDialogGetStatus());
			break;
		}

#ifdef ASURA_PSP_SUPPORT_INFRASTRUCTURE_NETWORK
		case INFRASTRUCTURE_CONNNECTION:
		{
			iRet = sceUtilityNetconfGetStatus();
			break;
		}
#endif // #ifdef ASURA_PSP_SUPPORT_INFRASTRUCTURE_NETWORK

		default:
		{
			// Shouldn't reach here...
			Asura_Assert(false, "Asura_PSP_SCEUtilityWrapper::GetUtilityLibraryStatus(): Unexpected command.");
			iRet = (SCE_UTILITY_COMMON_ERROR_INVALID_STATUS);
			break;
		}
	}		// End of switch.
	s_xUtilityMutex.Unlock();

	return iRet;
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::GetUtilityLibraryStatus'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::UpdateUtilityLibrary
// Author       : Andy Tate
// Date         : 16-Mar-2005
//
// Description  : Queries the approriate part of Sony's Utility library depending
//				  upon the command currently being executed.
//
// Parameters	: The number of frames to be updated at once (based on 60fps).
//
// Return value : The current state of the command being updated.
////////////////////////////////////////////////////////////////////////////////

Asura_PSP_SCEUtilityWrapper::CommandState Asura_PSP_SCEUtilityWrapper::UpdateUtilityLibrary (const int iNumFrames)
{
	u_int	uErrorNum;

	s_xUtilityMutex.Lock();
	// What sort of command are we performing?
	switch (s_eCommand)
	{
		case NONE:
		{
			// Not doing anything - return no status...
			s_xUtilityMutex.Unlock();
			return(COMMAND_INACTIVE);
		}

#ifdef ASURA_PSP_GAMESHARING
		case GAME_SHARING:
		{
			uErrorNum = sceUtilityGameSharingUpdate (iNumFrames);
			break;
		}
#endif

		case ON_SCREEN_KEYBOARD:
		{
			// Return the OSK status...
			Asura_Assert(!Asura_Render::IsRendering(), "Asura_PSP_SCEUtilityWrapper::EndFrame()/UpdateUtilityLibrary() should be called after rendering");
			GU_Sync(SCEGU_SYNC_FINISH, SCEGU_SYNC_WAIT);
			uErrorNum	= sceUtilityOskUpdate (iNumFrames);
			break;
		}

		case SAVEDATA_AUTOLOAD:
		case SAVEDATA_AUTOSAVE:
		{
			// Return the save-data status...
			Asura_Assert(!Asura_Render::IsRendering(), "Asura_PSP_SCEUtilityWrapper::EndFrame()/UpdateUtilityLibrary() should be called after rendering");
			GU_Sync(SCEGU_SYNC_FINISH, SCEGU_SYNC_WAIT);
			uErrorNum	= sceUtilitySavedataUpdate (iNumFrames);
			break;
		}

		case SAVEDATA_DELETE:
		case SAVEDATA_LOAD_LIST:
		case SAVEDATA_SAVE_LIST:
		case SAVEDATA_LOAD_SINGLE:
		case SAVEDATA_SAVE_SINGLE:
		case SAVEDATA_AUTOLOAD_SINGLE:
		case SAVEDATA_AUTOSAVE_SINGLE:
		// Check save size (AN 12/09/07)
		case SAVEDATA_CHECKSAVESIZE:
		{
			// Return the save-data status...
			Asura_Assert(!Asura_Render::IsRendering(), "Asura_PSP_SCEUtilityWrapper::EndFrame()/UpdateUtilityLibrary() should be called after rendering");
			GU_Sync(SCEGU_SYNC_FINISH, SCEGU_SYNC_WAIT);
			sceUtilitySavedataUpdate(iNumFrames);
			s_xUtilityMutex.Unlock();
			return(COMMAND_IN_PROGRESS);
		}

		case MESSAGE_DIALOG:
		{
			// Return the save-data status...
			Asura_Assert(!Asura_Render::IsRendering(), "Asura_PSP_SCEUtilityWrapper::EndFrame()/UpdateUtilityLibrary() should be called after rendering");
			GU_Sync(SCEGU_SYNC_FINISH, SCEGU_SYNC_WAIT);
			sceUtilityMsgDialogUpdate(iNumFrames);
			s_xUtilityMutex.Unlock();
			return(COMMAND_IN_PROGRESS);
		}

#ifdef ASURA_PSP_SUPPORT_INFRASTRUCTURE_NETWORK
		case INFRASTRUCTURE_CONNNECTION:
		{
			Asura_Assert(!Asura_Render::IsRendering(), "Asura_PSP_SCEUtilityWrapper::EndFrame()/UpdateUtilityLibrary() should be called after rendering");
			GU_Sync(SCEGU_SYNC_FINISH, SCEGU_SYNC_WAIT);
			sceUtilityNetconfUpdate(iNumFrames);
			s_xUtilityMutex.Unlock();
			return(COMMAND_IN_PROGRESS);
		}
#endif // #ifdef ASURA_PSP_SUPPORT_INFRASTRUCTURE_NETWORK

		default:
		{
			// Shouldn't reach here...
			Asura_Assert(false, "Asura_PSP_SCEUtilityWrapper::UpdateUtilityLibrary(): Unexpected command.");
			s_xUtilityMutex.Unlock();
			return(COMMAND_ERROR);
		}
	}		// End of switch.

	s_xUtilityMutex.Unlock();
	// Return whether we have an error...
	Asura_Assertf(0 == uErrorNum, ("sceUtility error %x", uErrorNum));
	return	((0 == uErrorNum) ? COMMAND_IN_PROGRESS : COMMAND_ERROR);
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::UpdateUtilityLibrary'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::ShutdownUtilityLibrary
// Author       : Andy Tate
// Date         : 16-Mar-2005
//
// Description  : Begins the shutdown of Sony's Utility library depending upon
//				  the command being currently executed.
//
// Return value : The appropriate Sony Utility status.
////////////////////////////////////////////////////////////////////////////////

Asura_PSP_SCEUtilityWrapper::CommandState Asura_PSP_SCEUtilityWrapper::ShutdownUtilityLibrary ()
{
	Asura_PSP_SCEUtilityWrapper::CommandState eRet;
	s_xUtilityMutex.Lock();
	// What sort of command are we performing?
	switch (s_eCommand)
	{
		case NONE:
		{
			// Not doing anything - return no status...
			eRet = (COMMAND_INACTIVE);
			break;
		}

#ifdef ASURA_PSP_GAMESHARING
		case GAME_SHARING:
		{
			//MKR 23/11/06: start its shutdown sequence. When it reaches the SHUTDOWN state then the GameSharingNetTerm() func will be called
			sceUtilityGameSharingShutdownStart();			
			eRet = (COMMAND_IN_PROGRESS);
			break;
		}
#endif

		case ON_SCREEN_KEYBOARD:
		{
			// Begin shutting down the OSK...
			HandleOSKCompletion	();
			sceUtilityOskShutdownStart();
			eRet = (COMMAND_IN_PROGRESS);
			break;
		}

		case SAVEDATA_AUTOLOAD:
		case SAVEDATA_AUTOLOAD_SINGLE:
		{
			// Begin shutting down the save-data...
			HandleLoadCompletion();
			sceUtilitySavedataShutdownStart();
			eRet = (COMMAND_IN_PROGRESS);
			break;
		}

		case SAVEDATA_AUTOSAVE:
		case SAVEDATA_AUTOSAVE_SINGLE:
		{
			// Begin shutting down the save-data...
			HandleSaveCompletion();
			sceUtilitySavedataShutdownStart();
			eRet = (COMMAND_IN_PROGRESS);
			break;
		}

		case SAVEDATA_DELETE:
		{
			// Begin shutting down the save-data...
			HandleDeleteCompletion();
			sceUtilitySavedataShutdownStart();
			eRet = (COMMAND_IN_PROGRESS);
			break;
		}

		case SAVEDATA_LOAD_LIST:
		case SAVEDATA_LOAD_SINGLE:
		{
			// Begin shutting down the save-data...
			HandleLoadCompletion();
			sceUtilitySavedataShutdownStart();
			eRet = (COMMAND_IN_PROGRESS);
			break;
		}

		case SAVEDATA_SAVE_LIST:
		case SAVEDATA_SAVE_SINGLE:
		{
			// Begin shutting down the save-data...
			HandleSaveCompletion();
			sceUtilitySavedataShutdownStart();
			eRet = (COMMAND_IN_PROGRESS);
			break;
		}

		// Check save size (AN 12/09/07)
		case SAVEDATA_CHECKSAVESIZE:
		{
			// Begin shutting down the save-data...
			HandleCheckSizeCompletion();
			sceUtilitySavedataShutdownStart();
			eRet = (COMMAND_IN_PROGRESS);
			break;
		}

		case MESSAGE_DIALOG:
		{
			// Begin shutting down the message-dialog...
			sceUtilityMsgDialogShutdownStart();
			eRet = (COMMAND_IN_PROGRESS);
			break;
		}

#ifdef ASURA_PSP_SUPPORT_INFRASTRUCTURE_NETWORK
		case INFRASTRUCTURE_CONNNECTION:
		{
			if (s_xSceUtilityNetconfParam.base.result != SCE_UTILITY_COMMON_RESULT_OK)
			{
				s_eShutdownCommandState	= COMMAND_CANCELLED;
			}
			sceUtilityNetconfShutdownStart();
			eRet = COMMAND_IN_PROGRESS;
			break;
		}
#endif // #ifdef ASURA_PSP_SUPPORT_INFRASTRUCTURE_NETWORK

		default:
		{
			// Shouldn't reach here...
			Asura_Assert(false, "Asura_PSP_SCEUtilityWrapper::ShutdownUtilityLibrary(): Unexpected command.");
			eRet = (COMMAND_ERROR);
			break;
		}
	}		// End of switch.

	s_xUtilityMutex.Unlock();
	return eRet;
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::ShutdownUtilityLibrary'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::Initialise
// Author       : Andy Tate
// Date         : 16-Mar-2005
//
// Description  : Handles the once-off initialisation of this wrapper.
// 
// Parameters	: Strings for the name of the title and it's product code.
//
// Return value : None.
////////////////////////////////////////////////////////////////////////////////

void Asura_PSP_SCEUtilityWrapper::Initialise (const Asura_UnicodeChar* wszTitleName)
{
	char	szNickname [uASURA_PSP_NICKNAME_MAX_CHARS];

	// Load the appropriate data...
	LoadSceUtilitySDExtFile	("Graphics/NewData.png",	s_xSceUtilitySavedataListSaveNewData.icon0);
	LoadSceUtilitySDExtFile	("Graphics/Icon0.png",		s_xSceUtilitySDExtFileIcon);

	// Get the necessary data from the PSP hardware...
	sceUtilityGetSystemParamInt		(SCE_UTILITY_SYSTEM_PARAM_CTRL_ASSIGN,	&s_iSceUtilitySystemParamCtrlAssign);
	sceUtilityGetSystemParamString	(SCE_UTILITY_SYSTEM_PARAM_NICKNAME,		szNickname,	uASURA_PSP_NICKNAME_MAX_CHARS);
	sceUtilityGetSystemParamInt		(SCE_UTILITY_SYSTEM_PARAM_LANGUAGE,		&s_iSceUtilitySystemLanguage);	

	Asura_Assert( Asura_LocalisedText::IsOperational(), "Asura_LocalisedText system not initialised. SCE utilities will use PSP system language." );
	if( Asura_LocalisedText::IsOperational() )
	{
		// convert from Asura language to sce utility language
		// accounts for all PSP-supported system languages other than the two chinese settings (which Asura doesn't support yet)
		switch( Asura_LocalisedText::GetCurrentLanguage() )
		{
			case ASURA_LT_L_ENGLISH  : // falls through
			case ASURA_LT_L_AMERICAN : // falls through
			default : s_iSceUtilitySystemLanguage = SCE_UTILITY_LANG_ENGLISH; break;

			case ASURA_LT_L_FRENCH		: s_iSceUtilitySystemLanguage = SCE_UTILITY_LANG_FRENCH;	 break;
			case ASURA_LT_L_GERMAN		: s_iSceUtilitySystemLanguage = SCE_UTILITY_LANG_GERMAN;	 break;
			case ASURA_LT_L_ITALIAN		: s_iSceUtilitySystemLanguage = SCE_UTILITY_LANG_ITALIAN;	 break;
			case ASURA_LT_L_SPANISH		: s_iSceUtilitySystemLanguage = SCE_UTILITY_LANG_SPANISH;	 break;
			case ASURA_LT_L_RUSSIAN		: s_iSceUtilitySystemLanguage = SCE_UTILITY_LANG_RUSSIAN;	 break;
			case ASURA_LT_L_JAPANESE	: s_iSceUtilitySystemLanguage = SCE_UTILITY_LANG_JAPANESE;	 break;
			case ASURA_LT_L_DUTCH		: s_iSceUtilitySystemLanguage = SCE_UTILITY_LANG_DUTCH;		 break;
			case ASURA_LT_L_PORTUGUESE	: s_iSceUtilitySystemLanguage = SCE_UTILITY_LANG_PORTUGUESE; break;
		}
	
		// Set impose language for UMD and battery screens, etc. Apparently this is a TRC requirement
		// in TRC 3.5 or later. It should prevent the game appearing in one language and the system 
		// utilities in another.
		sceImposeSetLanguageMode( s_iSceUtilitySystemLanguage, s_iSceUtilitySystemParamCtrlAssign );
	}

	// Create the nick-name...
	Asura_UTF8ToUnicode	(szNickname, s_wszNickname);

	// Store the project-specific data...
	s_wszTitleName	= wszTitleName;
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::Initialise'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::Shutdown
// Author       : Andy Tate
// Date         : 16-Mar-2005
//
// Description  : Handles the once-off shutdown of this wrapper.
//
// Return value : None.
////////////////////////////////////////////////////////////////////////////////

void Asura_PSP_SCEUtilityWrapper::Shutdown (void)
{
	// Delete the data...

	delete []	(s_xSceUtilitySavedataListSaveNewData.icon0.pDataBuf);
	delete []	(s_xSceUtilitySDExtFileIcon.pDataBuf);
	delete []	(s_xSceUtilitySDExtFileBackground.pDataBuf);
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::Shutdown'. ///

#ifdef ASURA_PSP_GAMESHARING

//MKR 23/11/06: these defines are the stack sizes and priorities for the network library when it is used to support
//the game sharing utility. They most likely will never be changed
#define PSPNET_POOLSIZE		(192*1024)	/* 192KB */
#define CALLOUT_TPL			32
#define CALLOUT_STACKSIZE	(4*1024)	/* 4KB */
#define NETINTR_TPL			32
#define NETINTR_STACKSIZE	(4*1024)	/* 4KB */
#define ADHOCCTL_TPL		48
#define ADHOCCTL_STACKSIZE 	(8*1024)	/* 8KB */
#define MATCHING_POOLSIZE   (128*1024)	/* 128KB */

//MKR 23/11/06: shuts down the network libraries that the game sharing utility relies on 
void Asura_PSP_SCEUtilityWrapper::GameSharingNetTerm()
{
	sceNetAdhocctlDisconnect();
	sceNetAdhocMatchingTerm();	
	sceNetAdhocctlTerm();
	sceNetAdhocTerm();
	sceNetTerm();
}

Asura_PSP_SCEUtilityWrapper::CommandState Asura_PSP_SCEUtilityWrapper::InitialiseGameSharing(const Asura_Char* const szFileName)
{
	// Are we currently executing a command?
	if (NONE == s_eCommand)
	{
		int iRet = sceNetInit(PSPNET_POOLSIZE,
			CALLOUT_TPL, CALLOUT_STACKSIZE,
			NETINTR_TPL, NETINTR_STACKSIZE);
		if(iRet < 0)
		{
			Asura_Assert(0, "Could not initialise network library for game sharing: sceNetInit() failed.");
			sceKernelPrintf("sceNetInit() failed: 0x%x\n", iRet);
			goto error;
		}

		iRet = sceNetAdhocInit();
		if(iRet < 0)
		{
			Asura_Assert(0, "Could not initialise adhoc library for game sharing: sceNetAdhocInit() failed.");
			sceKernelPrintf("sceNetAdhocInit() failed: 0x%x\n", iRet);
			goto error;
		}

		iRet = sceNetAdhocctlInit(ADHOCCTL_STACKSIZE, ADHOCCTL_TPL, &s_xGameSharingID);
		if(iRet < 0)
		{
			Asura_Assert(0, "Could not initialise adhoc library for game sharing: sceNetAdhocctlInit() failed.");
			sceKernelPrintf("sceNetAdhocInit() failed: 0x%x\n", iRet);
			goto error;
		}	

		iRet = sceNetAdhocMatchingInit(MATCHING_POOLSIZE);
		if (iRet < 0)
		{
			Asura_Assert(0, "sceNetAdhocMatchingInit() failed.");	
			sceKernelPrintf("sceNetAdhocMatchingInit() failed: 0x%x\n", iRet);
			goto error;
		}

		iRet = sceNetAdhocctlConnect(&s_xGamesharingGroupName);
		if(iRet < 0)
		{
			Asura_Assert(0, "sceNetAdhocctlConnect() failed.");	
			sceKernelPrintf("sceNetAdhocctlConnect() failed: 0x%x\n", iRet);	
			goto error;
		}	

		Asura_Mem::Set(&s_xGameSharingParam, 0x00, sizeof(SceUtilityGameSharingParam));
		s_xGameSharingParam.base.size		= sizeof(SceUtilityGameSharingParam);
		s_xGameSharingParam.base.ctrl_assign = s_iSceUtilitySystemParamCtrlAssign;
		s_xGameSharingParam.base.main_thread_priority = SCE_KERNEL_USER_HIGHEST_PRIORITY + 1;
		s_xGameSharingParam.base.sub_thread_priority = SCE_KERNEL_USER_HIGHEST_PRIORITY + 3;
		s_xGameSharingParam.base.font_thread_priority = SCE_KERNEL_USER_HIGHEST_PRIORITY + 2;
		s_xGameSharingParam.base.sound_thread_priority = SCE_KERNEL_USER_HIGHEST_PRIORITY;		
		s_xGameSharingParam.base.message_lang = s_iSceUtilitySystemLanguage;

		Asura_PrintfToBfr((char *)s_xGameSharingParam.group_name.data, szTITLE_ID);
		s_xGameSharingParam.serverType = SCE_UTILITY_GAMESHARING_SERVER_TYPE_DIST;

		s_xGameSharingParam.dataLocationType = SCE_UTILITY_GAMESHARING_LOCATION_TYPE_FILE;
		s_xGameSharingParam.uploadData = NULL;
		s_xGameSharingParam.uploadDataSize = 0;
		s_xGameSharingParam.filePath = szFileName;

		// Initialise Sony's Utility library...

		s_eCommandState	= InitialiseUtilityLibrary (GAME_SHARING, &s_xGameSharingParam);
		
error:
		if(iRet < 0 || s_eCommandState == COMMAND_ERROR)
		{
			GameSharingNetTerm();
			s_eCommandState	= COMMAND_ERROR;
		}		
	}

	else
	{
		// Yes - we're already doing something else...

		s_eCommandState	= COMMAND_ERROR;

		Asura_Assert	(false, "Asura_PSP_SCEUtilityWrapper::InitialiseGameSharing(): Already using part of Sony's Utility library.");
	}

	// Return the command state...

	return	(s_eCommandState);
}
#endif

////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::InitialiseOnScreenKeyboard
// Author       : Andy Tate
// Date         : 16-Mar-2005
//
// Description  : Handles the initialisation of Sony's Utility library on-screen
//				  keyboard (OSK).
//
// Parameters	: 
//
// Return value : The current state of the command being updated.
////////////////////////////////////////////////////////////////////////////////

Asura_PSP_SCEUtilityWrapper::CommandState Asura_PSP_SCEUtilityWrapper::InitialiseOnScreenKeyboard (const Asura_UnicodeChar* wszMessage,
																								   const Asura_UnicodeChar* wszTextBeforeEdit,
																								   Asura_UnicodeChar* wszTextAfterEdit,
																								   const int iMaxCharsInclNul,
																								   const OSKCharacterSet eCharacterSet)
{
	// Are we currently executing a command?

	Asura_Assert(wszTextBeforeEdit != wszTextAfterEdit, "overlapping buffers");

	if (NONE == s_eCommand)
	{
		int	iInputCharacterType;


		// No - ensure that we point to the appropriate input fields...

		InitialiseStructure	(sizeof(s_xSceUtilityOskParam), &s_xSceUtilityOskParam, s_xSceUtilityOskParam.base);

		s_xSceUtilityOskParam.num_input_fields	= 1;
		s_xSceUtilityOskParam.input_field_info	= &s_xSceUtilityOskInputFieldInfo;


		// What sort of character set are we to use?

		switch (eCharacterSet)
		{
			case LATIN_ALPHABET:
			{
				iInputCharacterType	= SCE_UTILITY_OSK_INPUT_CHARACTER_TYPE_LATIN_LOWERCASE_ALPHABET | SCE_UTILITY_OSK_INPUT_CHARACTER_TYPE_LATIN_UPPERCASE_ALPHABET;
				break;
			}

			case LATIN_ALPHABET_UPPERCASE:
			{
				iInputCharacterType	= SCE_UTILITY_OSK_INPUT_CHARACTER_TYPE_LATIN_UPPERCASE_ALPHABET;
				break;
			}

			case LATIN_ALPHABET_LOWERCASE:
			{
				iInputCharacterType	= SCE_UTILITY_OSK_INPUT_CHARACTER_TYPE_LATIN_LOWERCASE_ALPHABET;
				break;
			}

			case LATIN_NUMERALS:
			{
				iInputCharacterType	= SCE_UTILITY_OSK_INPUT_CHARACTER_TYPE_LATIN_NUMBER;
				break;
			}

			case LATIN_ALPHANUMERIC:
			{
				iInputCharacterType	= SCE_UTILITY_OSK_INPUT_CHARACTER_TYPE_LATIN_NUMBER | SCE_UTILITY_OSK_INPUT_CHARACTER_TYPE_LATIN_LOWERCASE_ALPHABET | SCE_UTILITY_OSK_INPUT_CHARACTER_TYPE_LATIN_UPPERCASE_ALPHABET;
				break;
			}

			case LATIN_ALPHANUMERIC_UPPERCASE:
			{
				iInputCharacterType	= SCE_UTILITY_OSK_INPUT_CHARACTER_TYPE_LATIN_NUMBER | SCE_UTILITY_OSK_INPUT_CHARACTER_TYPE_LATIN_UPPERCASE_ALPHABET;
				break;
			}

			case LATIN_ALPHANUMERIC_LOWERCASE:
			{
				iInputCharacterType	= SCE_UTILITY_OSK_INPUT_CHARACTER_TYPE_LATIN_NUMBER | SCE_UTILITY_OSK_INPUT_CHARACTER_TYPE_LATIN_LOWERCASE_ALPHABET;
				break;
			}

			default:
			{
				iInputCharacterType	= SCE_UTILITY_OSK_INPUT_CHARACTER_TYPE_ALL_TYPE;
				break;
			}
		}		// End of switch.


		// Initialise our current input-field...

		Asura_Mem::Set(&s_xSceUtilityOskInputFieldInfo, 0, sizeof(s_xSceUtilityOskInputFieldInfo));

		s_xSceUtilityOskInputFieldInfo.input_method_type		= SCE_UTILITY_OSK_INPUT_METHOD_NONE;
		s_xSceUtilityOskInputFieldInfo.input_method_attributes	= 0;
		s_xSceUtilityOskInputFieldInfo.writing_language_type	= SCE_UTILITY_OSK_WRITING_LANGUAGE_TYPE_DEFAULT;
		s_xSceUtilityOskInputFieldInfo.input_character_type		= iInputCharacterType;
		s_xSceUtilityOskInputFieldInfo.num_lines				= 1;
		s_xSceUtilityOskInputFieldInfo.message					= const_cast<SceWChar16*>(reinterpret_cast<SceWChar16 const*>(wszMessage));
		s_xSceUtilityOskInputFieldInfo.init_text				= const_cast<SceWChar16*>(reinterpret_cast<SceWChar16 const*>(wszTextBeforeEdit));
		s_xSceUtilityOskInputFieldInfo.result_text_buffer_size	= iMaxCharsInclNul;
		s_xSceUtilityOskInputFieldInfo.result_text_buffer		= reinterpret_cast<SceWChar16*>(wszTextAfterEdit);

		// Copy the text before edit into the text after edit...
		Asura_Assert(wszTextAfterEdit != wszTextBeforeEdit, "overlapping buffers");
		wcscpy	(wszTextAfterEdit, wszTextBeforeEdit);


		// Initialise Sony's Utility library...
		s_eCommandState	= InitialiseUtilityLibrary (ON_SCREEN_KEYBOARD, &s_xSceUtilityOskParam);
	}

	else
	{
		// Yes - we're already doing something else...
		s_eCommandState	= COMMAND_ERROR;
		Asura_Assert	(false, "Asura_PSP_SCEUtilityWrapper::InitialiseOnScreenKeyboard(): Already using part of Sony's Utility library.");
	}

	// Return the command state...
	return	(s_eCommandState);
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::InitialiseOnScreenKeyboard'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataAutoload
// Author       : Andy Tate
// Date         : 16-Mar-2005
//
// Description  : Handles the initialisation of Sony's Utility library save-data
//				  save list.
//
// Parameters	: A pointer to the data to be loaded and it's size.
//
// Return value : The current state of the command being updated.
////////////////////////////////////////////////////////////////////////////////

Asura_PSP_SCEUtilityWrapper::CommandState Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataAutoload (void* pData,
																								   const u_int uDataSize,
																								   const u_int uBufferSize,
																								   LoadDataValidationFunction* pfnValidation)
{
	// Are we currently executing a command?
	if (NONE == s_eCommand)
	{
		// No - initialise the type of save-data...
		InitialiseStructure	(sizeof(s_xSceUtilitySavedataParam), &s_xSceUtilitySavedataParam, s_xSceUtilitySavedataParam.base);

		s_xSceUtilitySavedataParam.type			= SCE_UTILITY_SAVEDATA_TYPE_AUTOLOAD;
		s_xSceUtilitySavedataParam.initFocus	= SCE_UTILITY_SAVEDATA_INITFOCUS_DATALATEST;

		strncpy	(s_xSceUtilitySavedataParam.userId, s_szSavedataAutosaveUserID, SCE_UTILITY_SD_USERID_SIZE);

		// KOR - 15/11/2005 - new for 2.5.0
		s_xSceUtilitySavedataParam.dataVersion = SCE_UTILITY_SAVEDATA_VERSION_CURRENT;
		strncpy(reinterpret_cast<char*>(s_xSceUtilitySavedataParam.secureFileId), "TODO:PerProject", 16);

		// Set the Load Data Validation function
		s_pfnValidation = pfnValidation;

		// Commence the loading...
		HandleLoadCommencing	(pData, uDataSize, uBufferSize);

		// Initialise Sony's Utility library...
		s_eCommandState	= InitialiseUtilityLibrary (SAVEDATA_AUTOLOAD, &s_xSceUtilitySavedataParam);
	}
	else
	{
		// Yes - we're already doing something else...
		s_eCommandState	= COMMAND_ERROR;
		Asura_Assert	(false, "Asura_PSP_SCEUtilityWrapper::InitialiseSavedataAutoload(): Already using part of Sony's Utility library.");
	}

	// Return the current state...
	return	(s_eCommandState);
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataAutoload'. ///


////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataAutosave
// Author       : Andy Tate
// Date         : 16-Mar-2005
//
// Description  : Handles the initialisation of Sony's Utility library save-data
//				  save list.
//
// Parameters	: The text to be displayed on the save screen, along with a pointer
//				  to the data to be saved and it's size.
//
// Return value : The current state of the command being updated.
////////////////////////////////////////////////////////////////////////////////

Asura_PSP_SCEUtilityWrapper::CommandState Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataAutosave (const Asura_UnicodeChar* wszSaveTitle,
																								   const Asura_UnicodeChar* wszSaveDescription,
																								   const Asura_UnicodeChar* wszNewData,
																								   const void* pData,
																								   const u_int uDataSize,
																								   const u_int uBufferSize)
{
	// Are we currently executing a command?
	if (NONE == s_eCommand)
	{
		// No - initialise the type of save-data...
		InitialiseStructure	(sizeof(s_xSceUtilitySavedataParam), &s_xSceUtilitySavedataParam, s_xSceUtilitySavedataParam.base);

		s_xSceUtilitySavedataParam.type				= SCE_UTILITY_SAVEDATA_TYPE_AUTOSAVE;
		s_xSceUtilitySavedataParam.overWriteMode	= SCE_UTILITY_SAVEDATA_OVERWRITEMODE_OFF;

		strncpy	(s_xSceUtilitySavedataParam.userId, s_szSavedataAutosaveUserID, SCE_UTILITY_SD_USERID_SIZE);

		// KOR - 15/11/2005 - new for 2.5.0
		s_xSceUtilitySavedataParam.dataVersion = SCE_UTILITY_SAVEDATA_VERSION_CURRENT;
		strncpy(reinterpret_cast<char*>(s_xSceUtilitySavedataParam.secureFileId), "TODO:PerProject", 16);

		// Create the new data string...
		Asura_UnicodeToUTF8	(wszNewData, s_szSavedataNewDataTitle);

		// Commence the saving...
		HandleSaveCommencing	(wszSaveTitle, wszSaveDescription, pData, uDataSize, uBufferSize);

		// Initialise Sony's Utility library...
		s_eCommandState	= InitialiseUtilityLibrary (SAVEDATA_AUTOSAVE, &s_xSceUtilitySavedataParam);
	}
	else
	{
		// Yes - we're already doing something else...
		s_eCommandState	= COMMAND_ERROR;
		Asura_Assert	(false, "Asura_PSP_SCEUtilityWrapper::InitialiseSavedataAutosave(): Already using part of Sony's Utility library.");
	}

	// Return the current state...
	return	(s_eCommandState);
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataAutosave'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataDelete
// Author       : Andy Tate
// Date         : 16-Mar-2005
//
// Description  : Handles the initialisation of Sony's Utility library save-data
//				  delete list.
//
// Return value : The current state of the command being updated.
////////////////////////////////////////////////////////////////////////////////

Asura_PSP_SCEUtilityWrapper::CommandState Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataDelete (void)
{
	// Are we currently executing a command?
	if (NONE == s_eCommand)
	{
		// No - initialise the type of save-data...
		InitialiseStructure	(sizeof(s_xSceUtilitySavedataParam), &s_xSceUtilitySavedataParam, s_xSceUtilitySavedataParam.base);

		s_xSceUtilitySavedataParam.type	= SCE_UTILITY_SAVEDATA_TYPE_DELETE;

		// Initialise Sony's Utility library...
		s_eCommandState	= InitialiseUtilityLibrary (SAVEDATA_DELETE, &s_xSceUtilitySavedataParam);
	}
	else
	{
		// Yes - we're already doing something else...
		s_eCommandState	= COMMAND_ERROR;
		Asura_Assert	(false, "Asura_PSP_SCEUtilityWrapper::InitialiseSavedataDeleteList(): Already using part of Sony's Utility library.");
	}

	// Return the current state...
	return	(s_eCommandState);
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataDelete'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataLoadList
// Author       : Andy Tate
// Date         : 16-Mar-2005
//
// Description  : Handles the initialisation of Sony's Utility library save-data
//				  load list.
//
// Parameters	: The pointer to the data to be loaded and the maximum size of
//				  the load.
//
// Return value : The current state of the command being updated.
////////////////////////////////////////////////////////////////////////////////

Asura_PSP_SCEUtilityWrapper::CommandState Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataLoadList (const int iNumSaveSlots,
																								   void* pData,
																								   const u_int uDataSize,
																								   const u_int uBufferSize,
																								   LoadDataValidationFunction* pfnValidation)
{
	// Are we currently executing a command?
	if (NONE == s_eCommand)
	{
		// No - initialise the type of save-data...
		InitialiseStructure	(sizeof(s_xSceUtilitySavedataParam), &s_xSceUtilitySavedataParam, s_xSceUtilitySavedataParam.base);
		InitialiseUserIDs	(iNumSaveSlots);

		s_xSceUtilitySavedataParam.type			= SCE_UTILITY_SAVEDATA_TYPE_LISTLOAD;
		s_xSceUtilitySavedataParam.pUserIds		= s_aszSavedataUserIDs;
		s_xSceUtilitySavedataParam.initFocus	= SCE_UTILITY_SAVEDATA_INITFOCUS_DATALATEST;

		// KOR - 15/11/2005 - new for 2.5.0
		s_xSceUtilitySavedataParam.dataVersion = SCE_UTILITY_SAVEDATA_VERSION_CURRENT;
		strncpy(reinterpret_cast<char*>(s_xSceUtilitySavedataParam.secureFileId), "TODO:PerProject", 16);

		// Set the Load Data Validation function
		s_pfnValidation = pfnValidation;

		// Commence the loading...
		HandleLoadCommencing	(pData, uDataSize, uBufferSize);

		// Initialise Sony's Utility library...
		s_eCommandState	= InitialiseUtilityLibrary (SAVEDATA_LOAD_LIST, &s_xSceUtilitySavedataParam);
	}
	else
	{
		// Yes - we're already doing something else...
		s_eCommandState	= COMMAND_ERROR;
		Asura_Assert	(false, "Asura_PSP_SCEUtilityWrapper::InitialiseSavedataLoadList(): Already using part of Sony's Utility library.");
	}

	// Return the current state...
	return	(s_eCommandState);
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataLoadList'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataSaveList
// Author       : Andy Tate
// Date         : 16-Mar-2005
//
// Description  : Handles the initialisation of Sony's Utility library save-data
//				  save list.
//
// Parameters	: The text to be displayed on the save screen, along with a pointer
//				  to the data to be saved and it's size.
//
// Return value : The current state of the command being updated.
////////////////////////////////////////////////////////////////////////////////

Asura_PSP_SCEUtilityWrapper::CommandState Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataSaveList (const int iNumSaveSlots,
																								   const Asura_UnicodeChar* wszSaveTitle,
																								   const Asura_UnicodeChar* wszSaveDescription,
																								   const Asura_UnicodeChar* wszNewData,
																								   const void* pData,
																								   const u_int uDataSize,
																								   const u_int uBufferSize)
{
	// Are we currently executing a command?
	if (NONE == s_eCommand)
	{
		// No - initialise the type of save-data...
		InitialiseStructure	(sizeof(s_xSceUtilitySavedataParam), &s_xSceUtilitySavedataParam, s_xSceUtilitySavedataParam.base);
		InitialiseUserIDs	(iNumSaveSlots);

		s_xSceUtilitySavedataParam.type				= SCE_UTILITY_SAVEDATA_TYPE_LISTSAVE;
		s_xSceUtilitySavedataParam.overWriteMode	= SCE_UTILITY_SAVEDATA_OVERWRITEMODE_ON;
		s_xSceUtilitySavedataParam.pUserIds			= s_aszSavedataUserIDs;
		s_xSceUtilitySavedataParam.initFocus		= SCE_UTILITY_SAVEDATA_INITFOCUS_DATALATEST;

		// KOR - 15/11/2005 - new for 2.5.0
		s_xSceUtilitySavedataParam.dataVersion = SCE_UTILITY_SAVEDATA_VERSION_CURRENT;
		strncpy(reinterpret_cast<char*>(s_xSceUtilitySavedataParam.secureFileId), "TODO:PerProject", 16);

		// Create the new data string...
		Asura_UnicodeToUTF8	(wszNewData, s_szSavedataNewDataTitle);

		// Commence the saving...
		HandleSaveCommencing	(wszSaveTitle, wszSaveDescription, pData, uDataSize, uBufferSize);

		// Initialise Sony's Utility library...
		s_eCommandState	= InitialiseUtilityLibrary (SAVEDATA_SAVE_LIST, &s_xSceUtilitySavedataParam);
	}
	else
	{
		// Yes - we're already doing something else...
		s_eCommandState	= COMMAND_ERROR;
		Asura_Assert	(false, "Asura_PSP_SCEUtilityWrapper::InitialiseSavedataSaveList(): Already using part of Sony's Utility library.");
	}

	// Return the current state...
	return	(s_eCommandState);
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataSaveList'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataLoadSingle
// Author       : Neil Young
// Date         : 25-Jan-2006
//
// Description  : Handles the initialisation of Sony's Utility library save-data
//				  load.
//
// Parameters	: The pointer to the data to be loaded and the maximum size of
//				  the load, plus the user id of the save (equivalent to a file name)
//
// Return value : The current state of the command being updated.
////////////////////////////////////////////////////////////////////////////////

Asura_PSP_SCEUtilityWrapper::CommandState Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataLoadSingle (const char* szUserID,
																								   void* pData,
																								   const u_int uDataSize,
																								   const u_int uBufferSize,
																								   LoadDataValidationFunction* pfnValidation)
{
	// Are we currently executing a command?
	if (NONE == s_eCommand)
	{
		// No - initialise the type of save-data...
		InitialiseStructure	(sizeof(s_xSceUtilitySavedataParam), &s_xSceUtilitySavedataParam, s_xSceUtilitySavedataParam.base);

		s_xSceUtilitySavedataParam.type			= SCE_UTILITY_SAVEDATA_TYPE_LOAD;
		Asura_PrintfToBfr(s_xSceUtilitySavedataParam.userId, "%s", SCE_UTILITY_SD_USERID_SIZE, true, szUserID);

		// KOR - 15/11/2005 - new for 2.5.0
		s_xSceUtilitySavedataParam.dataVersion = SCE_UTILITY_SAVEDATA_VERSION_CURRENT;
		strncpy(reinterpret_cast<char*>(s_xSceUtilitySavedataParam.secureFileId), "TODO:PerProject", 16);

		// Set the Load Data Validation function
		s_pfnValidation = pfnValidation;

		// Commence the loading...
		HandleLoadCommencing	(pData, uDataSize, uBufferSize);

		// Initialise Sony's Utility library...
		s_eCommandState	= InitialiseUtilityLibrary (SAVEDATA_LOAD_SINGLE, &s_xSceUtilitySavedataParam);
	}
	else
	{
		// Yes - we're already doing something else...
		s_eCommandState	= COMMAND_ERROR;
		Asura_Assert	(false, "Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataLoadSingle(): Already using part of Sony's Utility library.");
	}

	// Return the current state...
	return	(s_eCommandState);
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataLoadSingle'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataSaveSingle
// Author       : Neil Young
// Date         : 25-Jan-2006
//
// Description  : Handles the initialisation of Sony's Utility library save-data
//				  save.
//
// Parameters	: The text to be displayed on the save screen, along with a pointer
//				  to the data to be saved and it's size, plus the user id of the save (equivalent to a file name)
//
// Return value : The current state of the command being updated.
////////////////////////////////////////////////////////////////////////////////

Asura_PSP_SCEUtilityWrapper::CommandState Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataSaveSingle (const char* szUserID,
																								   const Asura_UnicodeChar* wszSaveTitle,
																								   const Asura_UnicodeChar* wszSaveDescription,
																								   const Asura_UnicodeChar* wszNewData,
																								   const void* pData,
																								   const u_int uDataSize,
																								   const u_int uBufferSize)
{
	// Are we currently executing a command?
	if (NONE == s_eCommand)
	{
		// No - initialise the type of save-data...
		InitialiseStructure	(sizeof(s_xSceUtilitySavedataParam), &s_xSceUtilitySavedataParam, s_xSceUtilitySavedataParam.base);

		s_xSceUtilitySavedataParam.type				= SCE_UTILITY_SAVEDATA_TYPE_SAVE;
		s_xSceUtilitySavedataParam.overWriteMode	= SCE_UTILITY_SAVEDATA_OVERWRITEMODE_ON;

		Asura_PrintfToBfr(s_xSceUtilitySavedataParam.userId, "%s", SCE_UTILITY_SD_USERID_SIZE, true, szUserID);

		// KOR - 15/11/2005 - new for 2.5.0
		s_xSceUtilitySavedataParam.dataVersion = SCE_UTILITY_SAVEDATA_VERSION_CURRENT;
		strncpy(reinterpret_cast<char*>(s_xSceUtilitySavedataParam.secureFileId), "TODO:PerProject", 16);

		// Create the new data string...
		Asura_UnicodeToUTF8	(wszNewData, s_szSavedataNewDataTitle);

		// Commence the saving...
		HandleSaveCommencing	(wszSaveTitle, wszSaveDescription, pData, uDataSize, uBufferSize);

		// Initialise Sony's Utility library...
		s_eCommandState	= InitialiseUtilityLibrary (SAVEDATA_SAVE_SINGLE, &s_xSceUtilitySavedataParam);
	}
	else
	{
		// Yes - we're already doing something else...
		s_eCommandState	= COMMAND_ERROR;
		Asura_Assert	(false, "Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataSaveSingle(): Already using part of Sony's Utility library.");
	}

	// Return the current state...
	return	(s_eCommandState);
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataSaveSingle'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataAutoloadSingle
// Author       : Neil Young
// Date         : 25-Jan-2006
//
// Description  : Handles the initialisation of Sony's Utility library save-data
//				  autoload.
//
// Parameters	: A pointer to the data to be loaded and it's size, plus the user id of the save (equivalent to a file name)
//
// Return value : The current state of the command being updated.
////////////////////////////////////////////////////////////////////////////////

Asura_PSP_SCEUtilityWrapper::CommandState Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataAutoloadSingle (const char* szUserID,
																								   void* pData,
																								   const u_int uDataSize,
																								   const u_int uBufferSize,
																								   LoadDataValidationFunction* pfnValidation)
{
	// Are we currently executing a command?
	if (NONE == s_eCommand)
	{
		// No - initialise the type of save-data...
		InitialiseStructure	(sizeof(s_xSceUtilitySavedataParam), &s_xSceUtilitySavedataParam, s_xSceUtilitySavedataParam.base);

		s_xSceUtilitySavedataParam.type			= SCE_UTILITY_SAVEDATA_TYPE_AUTOLOAD;
		s_xSceUtilitySavedataParam.initFocus	= SCE_UTILITY_SAVEDATA_INITFOCUS_DATALATEST;

		Asura_PrintfToBfr(s_xSceUtilitySavedataParam.userId, "%s", SCE_UTILITY_SD_USERID_SIZE, true, szUserID);

		// KOR - 15/11/2005 - new for 2.5.0
		s_xSceUtilitySavedataParam.dataVersion = SCE_UTILITY_SAVEDATA_VERSION_CURRENT;
		strncpy(reinterpret_cast<char*>(s_xSceUtilitySavedataParam.secureFileId), "TODO:PerProject", 16);

		// Set the Load Data Validation function
		s_pfnValidation = pfnValidation;

		// Commence the loading...
		HandleLoadCommencing	(pData, uDataSize, uBufferSize);

		// Initialise Sony's Utility library...
		s_eCommandState	= InitialiseUtilityLibrary (SAVEDATA_AUTOLOAD_SINGLE, &s_xSceUtilitySavedataParam);
	}
	else
	{
		// Yes - we're already doing something else...
		s_eCommandState	= COMMAND_ERROR;
		Asura_Assert	(false, "Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataAutoloadSingle(): Already using part of Sony's Utility library.");
	}

	// Return the current state...
	return	(s_eCommandState);
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataAutoloadSingle'. ///


////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataAutosaveSingle
// Author       : Neil Young
// Date         : 25-Jan-2006
//
// Description  : Handles the initialisation of Sony's Utility library save-data
//				  autosave.
//
// Parameters	: The text to be displayed on the save screen, along with a pointer
//				  to the data to be saved and it's size, plus the user id of the save (equivalent to a file name)
//
// Return value : The current state of the command being updated.
////////////////////////////////////////////////////////////////////////////////

Asura_PSP_SCEUtilityWrapper::CommandState Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataAutosaveSingle (const char* szUserID,
																								   const Asura_UnicodeChar* wszSaveTitle,
																								   const Asura_UnicodeChar* wszSaveDescription,
																								   const Asura_UnicodeChar* wszNewData,
																								   const void* pData,
																								   const u_int uDataSize,
																								   const u_int uBufferSize)
{
	// Are we currently executing a command?
	if (NONE == s_eCommand)
	{
		// No - initialise the type of save-data...
		InitialiseStructure	(sizeof(s_xSceUtilitySavedataParam), &s_xSceUtilitySavedataParam, s_xSceUtilitySavedataParam.base);

		s_xSceUtilitySavedataParam.type				= SCE_UTILITY_SAVEDATA_TYPE_AUTOSAVE;
		s_xSceUtilitySavedataParam.overWriteMode	= SCE_UTILITY_SAVEDATA_OVERWRITEMODE_ON;

		Asura_PrintfToBfr(s_xSceUtilitySavedataParam.userId, "%s", SCE_UTILITY_SD_USERID_SIZE, true, szUserID);

		// KOR - 15/11/2005 - new for 2.5.0
		s_xSceUtilitySavedataParam.dataVersion = SCE_UTILITY_SAVEDATA_VERSION_CURRENT;
		strncpy(reinterpret_cast<char*>(s_xSceUtilitySavedataParam.secureFileId), "TODO:PerProject", 16);

		// Create the new data string...
		Asura_UnicodeToUTF8	(wszNewData, s_szSavedataNewDataTitle);

		// Commence the saving...
		HandleSaveCommencing	(wszSaveTitle, wszSaveDescription, pData, uDataSize, uBufferSize);

		// Initialise Sony's Utility library...
		s_eCommandState	= InitialiseUtilityLibrary (SAVEDATA_AUTOSAVE_SINGLE, &s_xSceUtilitySavedataParam);
	}

	else
	{
		// Yes - we're already doing something else...
		s_eCommandState	= COMMAND_ERROR;
		Asura_Assert	(false, "Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataAutosaveSingle(): Already using part of Sony's Utility library.");
	}

	// Return the current state...
	return	(s_eCommandState);
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataAutosaveSingle'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataCheckSize
// Author       : Attila Novak
// Date         : 12-Sept-2007
//
// Description  : Handles the initialisation of Sony's Utility library save-data
//				  checksize.
//
// Parameters	: 
//
// Return value : The current state of the command being updated.
////////////////////////////////////////////////////////////////////////////////

Asura_PSP_SCEUtilityWrapper::CommandState Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataCheckSize (	const u_int uDataSize,
																										const u_int uBufferSize)
{
	// Are we currently executing a command?
	if (NONE == s_eCommand)
	{
		// No - initialise the type of save-data...
		InitialiseStructure	(sizeof(s_xSceUtilitySavedataParam), &s_xSceUtilitySavedataParam, s_xSceUtilitySavedataParam.base);

		s_xSceUtilitySavedataParam.type				= SCE_UTILITY_SAVEDATA_TYPE_SIZES;
		s_xSceUtilitySavedataParam.overWriteMode	= SCE_UTILITY_SAVEDATA_OVERWRITEMODE_ON;

		// KOR - 15/11/2005 - new for 2.5.0
		s_xSceUtilitySavedataParam.dataVersion = SCE_UTILITY_SAVEDATA_VERSION_CURRENT;
		strncpy(reinterpret_cast<char*>(s_xSceUtilitySavedataParam.secureFileId), "TODO:PerProject", 16);

		// Commence the saving...
		HandleCheckSizeCommencing	(uDataSize, uBufferSize);

		// Initialise Sony's Utility library...
		s_eCommandState	= InitialiseUtilityLibrary (SAVEDATA_CHECKSAVESIZE, &s_xSceUtilitySavedataParam);
	}
	else
	{
		// Yes - we're already doing something else...
		s_eCommandState	= COMMAND_ERROR;
		Asura_Assert	(false, "Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataCheckSize(): Already using part of Sony's Utility library.");
	}

	// Return the current state...
	return	(s_eCommandState);
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::InitialiseSaveDataCheckSize'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::InitialiseMessageDialog
// Author       : Andy Tate
// Date         : 21-Apr-2005
//
// Description  : Handles the initialisation of Sony's Utility library message-
//				  dialog.
//
// Parameters   : The SCE error number to display the message for.
//
// Return value : The current command state being updated.
////////////////////////////////////////////////////////////////////////////////

Asura_PSP_SCEUtilityWrapper::CommandState Asura_PSP_SCEUtilityWrapper::InitialiseMessageDialog (const u_int uErrorNumber)
{
	// Are we currently in a message-dialog?
	if (MESSAGE_DIALOG == s_eCommand)
	{
		// Yes - we're already doing something else...
		s_eCommandState	= COMMAND_ERROR;
		Asura_Assert	(false, "Asura_PSP_SCEUtilityWrapper::InitialiseMessageDialog(): Already using part of Sony's Utility library.");
	}
	else
	{
		// No - initialise the type of message-dialog...
		InitialiseStructure	(sizeof(s_xSceUtilityMsgDialogParam), &s_xSceUtilityMsgDialogParam, s_xSceUtilityMsgDialogParam.base);

		s_xSceUtilityMsgDialogParam.type		= SCE_UTILITY_MSGDIALOG_TYPE_NUMBER;
		s_xSceUtilityMsgDialogParam.errorNum	= uErrorNumber;

		// Initialise Sony's Utility library...
		s_eCommandState	= InitialiseUtilityLibrary (MESSAGE_DIALOG, &s_xSceUtilityMsgDialogParam);
	}

	// Return the current state...
	return	(s_eCommandState);
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::InitialiseMessageDialog'. ///

#ifdef ASURA_PSP_SUPPORT_INFRASTRUCTURE_NETWORK
////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::InitialiseInfrastructureMode
// Author       : Mike Healey
// Date         : 7-Nov-2006
//
// Description  : Initialises infrastructure connection.
//
// Return value : The current state of the command being executed.
////////////////////////////////////////////////////////////////////////////////

Asura_PSP_SCEUtilityWrapper::CommandState Asura_PSP_SCEUtilityWrapper::InitialiseInfrastructureMode	(void)
{
	if (NONE == s_eCommand)
	{
		InitialiseStructure	(sizeof(s_xSceUtilityNetconfParam), &s_xSceUtilityNetconfParam, s_xSceUtilityNetconfParam.base);

		s_xSceUtilityNetconfParam.type = SCE_UTILITY_NETCONF_TYPE_RECONNECT_APNET;
		s_xSceUtilityNetconfParam.browser_available = SCE_UTILITY_NETCONF_BROWSER_UNAVAILABLE;

		s_eCommandState = InitialiseUtilityLibrary( INFRASTRUCTURE_CONNNECTION, &s_xSceUtilityNetconfParam );
	}
	else
	{
		// we're already doing something else...
		s_eCommandState	= COMMAND_ERROR;
		Asura_Assert(false, "Asura_PSP_SCEUtilityWrapper::InitialiseSavedataAutoload(): Already using part of Sony's Utility library.");
	}

	return s_eCommandState;
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::InitialiseInfrastructureMode'. ///
#endif



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::EndFrame
// Author       : Andy Tate
// Date         : 5-Oct-2005
//
// Description  : Handles the end of the current frame.
//
// Return value : The current state of the command being executed.
////////////////////////////////////////////////////////////////////////////////

Asura_PSP_SCEUtilityWrapper::CommandState Asura_PSP_SCEUtilityWrapper::EndFrame ()
{
	const float	fFrameRate	= Asura_Timers::GetFrameRate();
	const int	iNumFrames	= (fFrameRate == 0.0f)
							? 1
							: Asura_Maths::FloatToInt(60.0f / fFrameRate);
	const int	iStatus		= GetUtilityLibraryStatus ();

	// What is the current status?
	switch (iStatus)
	{
		case SCE_UTILITY_COMMON_STATUS_NONE:
		{
			// Are we performing a command?
			if (NONE == s_eCommand)
			{
				// No - the return inactive...
				s_eCommandState	= COMMAND_INACTIVE;
			}
			else if (SCE_UTILITY_COMMON_RESULT_OK == s_uShutdownErrorNumber)
			{
				// Yes - set us back to not executing a command...
				s_eCommand		= NONE;
				s_eCommandState	= s_eShutdownCommandState;

				// Resume kernel functionality...
				Asura_PSP_KernelManagement::Resume(Asura_PSP_KernelManagement::UTILITY_LIBRARY);
			}
			else if (SAVEDATA_SAVE_LIST == s_eCommand || SAVEDATA_SAVE_SINGLE == s_eCommand)
			{
				s_eCommand	= NONE;
				
				// Resume kernel functionality...
				Asura_PSP_KernelManagement::Resume(Asura_PSP_KernelManagement::UTILITY_LIBRARY);
				
				if (s_bGoToDeleteIfNoSpace)
				{
					// We've got an error during saving - bring up the delete save menu...
					s_eCommandState			= InitialiseSaveDataDelete ();

					s_eShutdownCommandState	= COMMAND_ERROR;
					s_uShutdownErrorNumber	= SCE_UTILITY_COMMON_RESULT_OK;
				}
				else
				{
					// Just set the s_bNeedDelete to be true, and then the games menu system can offer the player the delete option
					s_eCommandState	= COMMAND_CANCELLED;
					s_bNeedDelete	= true;
				}
			}
			else
			{
				// We've got an error - use the message dialog...
                // (MH - 24.04.2007) first reset some vars and state.
				s_eCommand	= NONE;
				// Resume kernel functionality...
				Asura_PSP_KernelManagement::Resume(Asura_PSP_KernelManagement::UTILITY_LIBRARY);

                // (MH - 24.04.2007) now init the message dialog
				s_eCommandState			= InitialiseMessageDialog(s_uShutdownErrorNumber);

				s_eShutdownCommandState	= COMMAND_ERROR;
				s_uShutdownErrorNumber	= SCE_UTILITY_COMMON_RESULT_OK;
			}

			break;
		}

		case SCE_UTILITY_COMMON_STATUS_INITIALIZE:
            // (MH - 24.04.2007) added break here - the docs say only to call UpdateUtilityLibrary()
			// for the RUNNING status and without it autosave doesn't work.
			s_eCommandState = COMMAND_IN_PROGRESS;
			break;

		case SCE_UTILITY_COMMON_STATUS_RUNNING:
		{
			// Running - update the library...
			s_eCommandState	= UpdateUtilityLibrary(iNumFrames);

			// Running - was our update successful?
			if (COMMAND_ERROR == s_eCommandState)
			{
				// No - begin the shutdown...
				s_eCommandState	= ShutdownUtilityLibrary();
			}
			break;
		}

		case SCE_UTILITY_COMMON_STATUS_FINISHED:
		{
			// Finished running - time to shutdown the library...
			s_eCommandState	= ShutdownUtilityLibrary();
			break;
		}

		case SCE_UTILITY_COMMON_STATUS_SHUTDOWN:
		{
			// Shutting-down - perform the update...
//			s_eCommandState	= UpdateUtilityLibrary(1);
			// AJG - 19/02/07 - The utility library update should only be called in running status, fades and so on occur without the update
			//                  and we get error returns if we try to update in any other status.
			s_eCommandState = COMMAND_IN_PROGRESS;

#ifdef ASURA_PSP_GAMESHARING
			if(s_eCommand == GAME_SHARING)
			{
				//MKR 23/11/06: the game sharing utility has finished shutting down, so shutdown the network 
				//libraries that it relies on 
				GameSharingNetTerm();
			}
#endif

			break;
		}

		default:
		{
			// Shouldn't get here...
			s_eCommandState	= COMMAND_ERROR;

			Asura_Assert(false, "Asura_PSP_SCEUtilityWrapper::Update(): Unexpected status.");
			break;
		}
	}		// End of switch.

	// Return the current state...
	return(s_eCommandState);
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::EndFrame'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::IsMemoryStickPresent
// Author       : Andy Tate
// Date         : 22-Apr-2005
//
// Description  : Returns whether we currently have a memory stick inserted in
//				  the PSP.
//
// Return value : "true" there is a memory stick, "false" if not.
////////////////////////////////////////////////////////////////////////////////

bool Asura_PSP_SCEUtilityWrapper::IsMemoryStickPresent (void)
{
	// Is there a memory-stick?

#if 0
	// JG: new Sony libraries 2.00 don't support this anynore
	return	(0 < sceMScmIsMediumInserted());
#else
	// (AW - 02/12/05) - This is the currently approved equivalent function.
	return (1 == sceFatmsIsAssigned());
#endif
}

/// End of function 'Asura_PSP_SCEUtilityWrapper::IsMemoryStickPresent'. ///

////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_PSP_SCEUtilityWrapper::ShouldHaveFocus
// Author       : Mike Healey
// Date         : 25-Apr-2007
//
// Description  : Returns whether we are displaying an interactive screen.
////////////////////////////////////////////////////////////////////////////////
bool Asura_PSP_SCEUtilityWrapper::ShouldHaveFocus(void)
{
	if (s_eCommandState != COMMAND_IN_PROGRESS)
	{
		return false;
	}

	return s_eCommand != SAVEDATA_AUTOLOAD && s_eCommand != SAVEDATA_AUTOSAVE;
}
/// End of function 'Asura_PSP_SCEUtilityWrapper::ShouldHaveFocus'. ///


void Asura_PSP_SCEUtilityWrapper::NotifyMemoryStickInserted(void)
{
	u_int uCurBlocks = GetMemoryStickFreeBlocks();
	if (uCurBlocks != s_uMemoryStickFreeBlocks)
	{
		s_bMemoryStickChanged = true;
	}
}

u_int Asura_PSP_SCEUtilityWrapper::GetMemoryStickFreeBlocks(void)
{
	SceDevInf xMsInfo;
	Sce_getdev_command_t xMsInfoCommand;
	xMsInfoCommand.dev_inf = &xMsInfo;

	int iRet = sceIoDevctl( SCE_FATMS_ALIAS_NAME, SCE_PR_GETDEV, &xMsInfoCommand, 
						sizeof(Sce_getdev_command_t), NULL, 0);
	if( iRet < 0 )
	{
//		if (!Asura_PSP_KernelManagement::IsSuspended())
//		{
//			Asura_Assertf(false, ("*** ERROR: sceIoDevctl(0x%x)\n", iRet));
//		}
		Asura_OutputToDebugger_Retail(("*** ERROR: sceIoDevctl(0x%x)\n", iRet));
		return uASURA_PSP_MEMSTICK_INVALID_FREE_BLOCKS;
	}

	return xMsInfo.ecl;
}

/// End of file. ///
