示例#1
0
int PSPSaveDialog::Update()
{
	switch (status) {
	case SCE_UTILITY_STATUS_FINISHED:
		status = SCE_UTILITY_STATUS_SHUTDOWN;
		break;
	default:
		break;
	}

	if (status != SCE_UTILITY_STATUS_RUNNING)
		return SCE_ERROR_UTILITY_INVALID_STATUS;

	if (!param.GetPspParam()) {
		status = SCE_UTILITY_STATUS_SHUTDOWN;
		return 0;
	}

	// The struct may have been updated by the game.  This happens in "Where Is My Heart?"
	// Check if it has changed, reload it.
	// TODO: Cut down on preloading?  This rebuilds the list from scratch.
	int size = Memory::Read_U32(requestAddr);
	if (memcmp(Memory::GetPointer(requestAddr), &originalRequest, size) != 0) {
		memset(&request, 0, sizeof(request));
		Memory::Memcpy(&request, requestAddr, size);
		Memory::Memcpy(&originalRequest, requestAddr, size);
		param.SetPspParam(&request);
	}

	buttons = __CtrlPeekButtons();
	UpdateFade();

	okButtonImg = I_CIRCLE;
	cancelButtonImg = I_CROSS;
	okButtonFlag = CTRL_CIRCLE;
	cancelButtonFlag = CTRL_CROSS;
	if (param.GetPspParam()->common.buttonSwap == 1) {
		okButtonImg = I_CROSS;
		cancelButtonImg = I_CIRCLE;
		okButtonFlag = CTRL_CROSS;
		cancelButtonFlag = CTRL_CIRCLE;
	}

	I18NCategory *d = GetI18NCategory("Dialog");

	switch (display)
	{
		case DS_SAVE_LIST_CHOICE:
			StartDraw();

			DisplaySaveList();
			DisplaySaveDataInfo1();

			DisplayButtons(DS_BUTTON_OK | DS_BUTTON_CANCEL);
			DisplayBanner(DB_SAVE);

			if (IsButtonPressed(cancelButtonFlag)) {
				param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_CANCEL;
				StartFade(false);
			} else if (IsButtonPressed(okButtonFlag)) {
				// Save exist, ask user confirm
				if (param.GetFileInfo(currentSelectedSave).size > 0) {
					yesnoChoice = 0;
					display = DS_SAVE_CONFIRM_OVERWRITE;
				} else {
					display = DS_SAVE_SAVING;
					if (param.Save(param.GetPspParam(), GetSelectedSaveDirName())) {
						param.SetPspParam(param.GetPspParam()); // Optim : Just Update modified save
						display = DS_SAVE_DONE;
					} else
						display = DS_SAVE_LIST_CHOICE; // This will probably need error message ?
				}
			}
			EndDraw();
		break;
		case DS_SAVE_CONFIRM:
			StartDraw();

			DisplaySaveIcon();
			DisplaySaveDataInfo2();

			DisplayMessage(d->T("Confirm Save", "Do you want to save this data?"), true);

			DisplayButtons(DS_BUTTON_OK | DS_BUTTON_CANCEL);
			DisplayBanner(DB_SAVE);

			if (IsButtonPressed(cancelButtonFlag) || (IsButtonPressed(okButtonFlag) && yesnoChoice == 0)) {
				param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_CANCEL;
				StartFade(false);
			} else if (IsButtonPressed(okButtonFlag)) {
				display = DS_SAVE_SAVING;
				if (param.Save(param.GetPspParam(), GetSelectedSaveDirName())) {
					param.SetPspParam(param.GetPspParam()); // Optim : Just Update modified save
					display = DS_SAVE_DONE;
				} else {
					// TODO: This should probably show an error message?
					StartFade(false);
				}
			}

			EndDraw();
		break;
		case DS_SAVE_CONFIRM_OVERWRITE:
			StartDraw();

			DisplaySaveIcon();
			DisplaySaveDataInfo2();

			DisplayMessage(d->T("Confirm Overwrite","Do you want to overwrite the data?"), true);

			DisplayButtons(DS_BUTTON_OK | DS_BUTTON_CANCEL);
			DisplayBanner(DB_SAVE);

			if (IsButtonPressed(cancelButtonFlag) || (IsButtonPressed(okButtonFlag) && yesnoChoice == 0)) {
				if (param.GetPspParam()->mode != SCE_UTILITY_SAVEDATA_TYPE_SAVE)
					display = DS_SAVE_LIST_CHOICE;
				else {
					param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_CANCEL;
					StartFade(false);
				}
			} else if (IsButtonPressed(okButtonFlag)) {
				display = DS_SAVE_SAVING;
				if (param.Save(param.GetPspParam(), GetSelectedSaveDirName())) {
					param.SetPspParam(param.GetPspParam()); // Optim : Just Update modified save
					display = DS_SAVE_DONE;
				} else {
					// TODO: This should probably show an error message?
					if (param.GetPspParam()->mode != SCE_UTILITY_SAVEDATA_TYPE_SAVE)
						display = DS_SAVE_LIST_CHOICE;
					else
						StartFade(false);
				}
			}

			EndDraw();
		break;
		case DS_SAVE_SAVING:
			StartDraw();

			DisplaySaveIcon();
			DisplaySaveDataInfo2();

			DisplayMessage(d->T("Saving","Saving\nPlease Wait..."));

			DisplayBanner(DB_SAVE);

			EndDraw();
		break;
		case DS_SAVE_DONE:
			StartDraw();

			DisplaySaveIcon();
			DisplaySaveDataInfo2();

			DisplayMessage(d->T("Save completed"));

			DisplayButtons(DS_BUTTON_CANCEL);
			DisplayBanner(DB_SAVE);

			if (IsButtonPressed(cancelButtonFlag)) {
				param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_SUCCESS;
				// Set the save to use for autosave and autoload
				param.SetSelectedSave(param.GetFileInfo(currentSelectedSave).idx);
				StartFade(false);
			}

			EndDraw();
		break;

		case DS_LOAD_LIST_CHOICE:
			StartDraw();
			
			DisplaySaveList();
			DisplaySaveDataInfo1();

			DisplayButtons(DS_BUTTON_OK | DS_BUTTON_CANCEL);
			DisplayBanner(DB_LOAD);

			if (IsButtonPressed(cancelButtonFlag)) {
				param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_CANCEL;
				StartFade(false);
			} else if (IsButtonPressed(okButtonFlag)) {
				display = DS_LOAD_LOADING;
				if (param.Load(param.GetPspParam(), GetSelectedSaveDirName(), currentSelectedSave))
					display = DS_LOAD_DONE;
			}

			EndDraw();
		break;
		case DS_LOAD_CONFIRM:
			StartDraw();

			DisplaySaveIcon();
			DisplaySaveDataInfo2();

			DisplayMessage(d->T("ConfirmLoad", "Load this data?"), true);

			DisplayButtons(DS_BUTTON_OK | DS_BUTTON_CANCEL);
			DisplayBanner(DB_LOAD);

			if (IsButtonPressed(cancelButtonFlag) || (IsButtonPressed(okButtonFlag) && yesnoChoice == 0)) {
				param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_CANCEL;
				StartFade(false);
			} else if (IsButtonPressed(okButtonFlag)) {
				display = DS_LOAD_LOADING;
				if (param.Load(param.GetPspParam(), GetSelectedSaveDirName(), currentSelectedSave))
					display = DS_LOAD_DONE;
				else {
					param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_CANCEL;
					StartFade(false);
				}
			}

			EndDraw();
		break;
		case DS_LOAD_LOADING:
			StartDraw();

			DisplaySaveIcon();
			DisplaySaveDataInfo2();

			DisplayMessage(d->T("Loading","Loading\nPlease Wait..."));

			DisplayBanner(DB_LOAD);

			EndDraw();
		break;
		case DS_LOAD_DONE:
			StartDraw();
			
			DisplaySaveIcon();
			DisplaySaveDataInfo2();

			DisplayMessage(d->T("Load completed"));

			DisplayButtons(DS_BUTTON_CANCEL);
			DisplayBanner(DB_LOAD);

			if (IsButtonPressed(cancelButtonFlag)) {
				param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_SUCCESS;
				// Set the save to use for autosave and autoload
				param.SetSelectedSave(param.GetFileInfo(currentSelectedSave).idx);
				StartFade(false);
			}

			EndDraw();
		break;
		case DS_LOAD_NODATA:
			StartDraw();

			DisplayMessage(d->T("There is no data"));

			DisplayButtons(DS_BUTTON_CANCEL);
			DisplayBanner(DB_LOAD);

			if (IsButtonPressed(cancelButtonFlag)) {
				param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA;
				StartFade(false);
			}

			EndDraw();
		break;

		case DS_DELETE_LIST_CHOICE:
			StartDraw();
			
			DisplaySaveList();
			DisplaySaveDataInfo1();

			DisplayButtons(DS_BUTTON_OK | DS_BUTTON_CANCEL);
			DisplayBanner(DB_DELETE);

			if (IsButtonPressed(cancelButtonFlag)) {
				param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_CANCEL;
				StartFade(false);
			} else if (IsButtonPressed(okButtonFlag)) {
				yesnoChoice = 0;
				display = DS_DELETE_CONFIRM;
			}

			EndDraw();
		break;
		case DS_DELETE_CONFIRM:
			StartDraw();

			DisplaySaveIcon();
			DisplaySaveDataInfo2();

			DisplayMessage(d->T("DeleteConfirm", 
						"This save data will be deleted.\nAre you sure you want to continue?"), 
						true);

			DisplayButtons(DS_BUTTON_OK | DS_BUTTON_CANCEL);
			DisplayBanner(DB_DELETE);

			if (IsButtonPressed(cancelButtonFlag))
				display = DS_DELETE_LIST_CHOICE;
			else if (IsButtonPressed(okButtonFlag)) {
				if (yesnoChoice == 0)
					display = DS_DELETE_LIST_CHOICE;
				else {
					display = DS_DELETE_DELETING;
					if (param.Delete(param.GetPspParam(),currentSelectedSave)) {
						param.SetPspParam(param.GetPspParam()); // Optim : Just Update modified save
						display = DS_DELETE_DONE;
					} else 		
						display = DS_DELETE_LIST_CHOICE; // This will probably need error message ?
				}
			}

			EndDraw();
		break;
		case DS_DELETE_DELETING:
			StartDraw();

			DisplayMessage(d->T("Deleting","Deleting\nPlease Wait..."));

			DisplayBanner(DB_DELETE);

			EndDraw();
		break;
		case DS_DELETE_DONE:
			StartDraw();
			
			DisplayMessage(d->T("Delete completed"));

			DisplayButtons(DS_BUTTON_CANCEL);
			DisplayBanner(DB_DELETE);

			if (IsButtonPressed(cancelButtonFlag)) {
				if (param.GetFilenameCount() == 0)
					display = DS_DELETE_NODATA;
				else
					display = DS_DELETE_LIST_CHOICE;
			}

			EndDraw();
		break;
		case DS_DELETE_NODATA:
			StartDraw();
			
			DisplayMessage(d->T("There is no data"));

			DisplayButtons(DS_BUTTON_CANCEL);
			DisplayBanner(DB_DELETE);

			if (IsButtonPressed(cancelButtonFlag)) {
				param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_DATA;
				StartFade(false);
			}

			EndDraw();
		break;

		case DS_NONE: // For action which display nothing
		{
			switch ((SceUtilitySavedataType)(u32)param.GetPspParam()->mode)
			{
				case SCE_UTILITY_SAVEDATA_TYPE_LOAD: // Only load and exit
				case SCE_UTILITY_SAVEDATA_TYPE_AUTOLOAD:
					if (param.Load(param.GetPspParam(), GetSelectedSaveDirName(), currentSelectedSave))
						param.GetPspParam()->common.result = 0;
					else
						param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA;
					status = SCE_UTILITY_STATUS_FINISHED;
				break;
				case SCE_UTILITY_SAVEDATA_TYPE_SAVE: // Only save and exit
				case SCE_UTILITY_SAVEDATA_TYPE_AUTOSAVE:
					if (param.Save(param.GetPspParam(), GetSelectedSaveDirName()))
						param.GetPspParam()->common.result = 0;
					else
						param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_SAVE_MS_NOSPACE;
					status = SCE_UTILITY_STATUS_FINISHED;
				break;
				case SCE_UTILITY_SAVEDATA_TYPE_SIZES:
					param.GetPspParam()->common.result = param.GetSizes(param.GetPspParam());
					status = SCE_UTILITY_STATUS_FINISHED;
				break;
				case SCE_UTILITY_SAVEDATA_TYPE_LIST:
					param.GetList(param.GetPspParam());
					param.GetPspParam()->common.result = 0;
					status = SCE_UTILITY_STATUS_FINISHED;
				break;
				case SCE_UTILITY_SAVEDATA_TYPE_FILES:
					param.GetPspParam()->common.result = param.GetFilesList(param.GetPspParam());
					status = SCE_UTILITY_STATUS_FINISHED;
				break;
				case SCE_UTILITY_SAVEDATA_TYPE_GETSIZE:
					{
						bool result = param.GetSize(param.GetPspParam());
						// TODO: According to JPCSP, should test/verify this part but seems edge casey.
						if (MemoryStick_State() != PSP_MEMORYSTICK_STATE_DRIVER_READY)
							param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_MEMSTICK;
						else if (result)
							param.GetPspParam()->common.result = 0;
						else
							param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA;
						status = SCE_UTILITY_STATUS_FINISHED;
					}
				break;
				case SCE_UTILITY_SAVEDATA_TYPE_DELETEDATA:
					// TODO: This should probably actually delete something.
					// For now, always say it couldn't be deleted.
					WARN_LOG(SCEUTILITY, "FAKE sceUtilitySavedata DELETEDATA: %s", param.GetPspParam()->saveName);
					param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_BAD_STATUS;
					status = SCE_UTILITY_STATUS_FINISHED;
				break;
				//case SCE_UTILITY_SAVEDATA_TYPE_AUTODELETE:
				case SCE_UTILITY_SAVEDATA_TYPE_SINGLEDELETE:
					if (param.Delete(param.GetPspParam(), param.GetSelectedSave()))
						param.GetPspParam()->common.result = 0;
					else
						param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_DATA;
					status = SCE_UTILITY_STATUS_FINISHED;
				break;
				// TODO: Should reset the directory's other files.
				case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATA:
				case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE:
					if (param.Save(param.GetPspParam(), GetSelectedSaveDirName(), param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE))
						param.GetPspParam()->common.result = 0;
					else
						param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA;
					status = SCE_UTILITY_STATUS_FINISHED;
				break;
				case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATA:
				case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE:
					if (param.Save(param.GetPspParam(), GetSelectedSaveDirName(), param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE))
						param.GetPspParam()->common.result = 0;
					else
						param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA;
					status = SCE_UTILITY_STATUS_FINISHED;
				break;
				case SCE_UTILITY_SAVEDATA_TYPE_READDATA:
				case SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE:
					if (param.Load(param.GetPspParam(), GetSelectedSaveDirName(), currentSelectedSave, param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE))
						param.GetPspParam()->common.result = 0;
					else
						param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA; // not sure if correct code
					status = SCE_UTILITY_STATUS_FINISHED;
				break;
				default:
					status = SCE_UTILITY_STATUS_FINISHED;
				break;
			}
		}
		break;
		default:
			status = SCE_UTILITY_STATUS_FINISHED;
		break;
	}

	lastButtons = buttons;

	if (status == SCE_UTILITY_STATUS_FINISHED)
		Memory::Memcpy(requestAddr, &request, request.common.size);
	
	return 0;
}
示例#2
0
void PSPSaveDialog::ExecuteNotVisibleIOAction() {
	switch ((SceUtilitySavedataType)(u32)param.GetPspParam()->mode) {
	case SCE_UTILITY_SAVEDATA_TYPE_LOAD: // Only load and exit
	case SCE_UTILITY_SAVEDATA_TYPE_AUTOLOAD:
		if (param.Load(param.GetPspParam(), GetSelectedSaveDirName(), currentSelectedSave)) {
			param.GetPspParam()->common.result = 0;
		} else {
			param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA;
		}
		break;
	case SCE_UTILITY_SAVEDATA_TYPE_SAVE: // Only save and exit
	case SCE_UTILITY_SAVEDATA_TYPE_AUTOSAVE:
		if (param.Save(param.GetPspParam(), GetSelectedSaveDirName())) {
			param.GetPspParam()->common.result = 0;
		} else {
			param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_SAVE_MS_NOSPACE;
		}
		break;
	case SCE_UTILITY_SAVEDATA_TYPE_SIZES:
		param.GetPspParam()->common.result = param.GetSizes(param.GetPspParam());
		break;
	case SCE_UTILITY_SAVEDATA_TYPE_LIST:
		param.GetList(param.GetPspParam());
		param.GetPspParam()->common.result = 0;
		break;
	case SCE_UTILITY_SAVEDATA_TYPE_FILES:
		param.GetPspParam()->common.result = param.GetFilesList(param.GetPspParam());
		break;
	case SCE_UTILITY_SAVEDATA_TYPE_GETSIZE:
		{
			bool result = param.GetSize(param.GetPspParam());
			// TODO: According to JPCSP, should test/verify this part but seems edge casey.
			if (MemoryStick_State() != PSP_MEMORYSTICK_STATE_DRIVER_READY) {
				param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_MEMSTICK;
			} else if (result) {
				param.GetPspParam()->common.result = 0;
			} else {
				param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA;
			}
		}
		break;
	case SCE_UTILITY_SAVEDATA_TYPE_DELETEDATA:
		DEBUG_LOG(SCEUTILITY, "sceUtilitySavedata DELETEDATA: %s", param.GetPspParam()->saveName);
		param.GetPspParam()->common.result = param.DeleteData(param.GetPspParam());
		break;
	//case SCE_UTILITY_SAVEDATA_TYPE_AUTODELETE:
	case SCE_UTILITY_SAVEDATA_TYPE_SINGLEDELETE:
		if (param.Delete(param.GetPspParam(), param.GetSelectedSave())) {
			param.GetPspParam()->common.result = 0;
		} else {
			param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_DATA;
		}
		break;
	// TODO: Should reset the directory's other files.
	case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATA:
	case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE:
		if (param.Save(param.GetPspParam(), GetSelectedSaveDirName(), param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE)) {
			param.GetPspParam()->common.result = 0;
		} else if (MemoryStick_FreeSpace() == 0) {
			param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_MEMSTICK_FULL;
		} else {
			param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA;
		}
		break;
	case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATA:
	case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE:
		if (param.Save(param.GetPspParam(), GetSelectedSaveDirName(), param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE)) {
			param.GetPspParam()->common.result = 0;
		} else {
			param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA;
		}
		break;
	case SCE_UTILITY_SAVEDATA_TYPE_READDATA:
	case SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE:
		if (!param.IsSaveDirectoryExist(param.GetPspParam())){
			param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA;
		} else if (!param.IsSfoFileExist(param.GetPspParam())) {
			param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_DATA_BROKEN;
		} else if (param.Load(param.GetPspParam(), GetSelectedSaveDirName(), currentSelectedSave, param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE)) {
			param.GetPspParam()->common.result = 0;
		} else {
			param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_FILE_NOT_FOUND;
		}
		break;
	default:
		break;
	}
}
示例#3
0
文件: sceIo.cpp 项目: Ryalian/ppsspp
void sceIoDevctl() //(const char *name, int cmd, void *arg, size_t arglen, void *buf, size_t *buflen); 
{
	const char *name = Memory::GetCharPointer(PARAM(0));
	int cmd = PARAM(1);
	u32 argAddr = PARAM(2);
	int argLen = PARAM(3);
	u32 outPtr = PARAM(4);
	int outLen = PARAM(5);

	if (strcmp(name, "emulator:")) {
		DEBUG_LOG(HLE,"sceIoDevctl(\"%s\", %08x, %08x, %i, %08x, %i)", name, cmd,argAddr,argLen,outPtr,outLen);
	}

	// UMD checks
	switch (cmd) {
	case 0x01F20001:  // Get Disc Type.
		if (Memory::IsValidAddress(outPtr)) {
			Memory::Write_U32(0x10, outPtr);  // Game disc
			RETURN(0); return;
		} else {
			RETURN(-1); return;
		}
		break;
	case 0x01F20002:  // Get current LBA.
		if (Memory::IsValidAddress(outPtr)) {
			Memory::Write_U32(0, outPtr);  // Game disc
			RETURN(0); return;
		} else {
			RETURN(-1); return;
		}
		break;
	case 0x01F100A3:  // Seek
		RETURN(0); return;
		break;
	}
	
	// This should really send it on to a FileSystem implementation instead.

	if (!strcmp(name, "mscmhc0:") || !strcmp(name, "ms0:"))
	{
		switch (cmd)
		{
		// does one of these set a callback as well? (see coded arms)
		case 0x02015804:	// Register callback
			if (Memory::IsValidAddress(argAddr) && argLen == 4) {
				u32 cbId = Memory::Read_U32(argAddr);
				if (0 == __KernelRegisterCallback(THREAD_CALLBACK_MEMORYSTICK, cbId)) {
					DEBUG_LOG(HLE, "sceIoDevCtl: Memstick callback %i registered, notifying immediately.", cbId);
					__KernelNotifyCallbackType(THREAD_CALLBACK_MEMORYSTICK, cbId, MemoryStick_State());
					RETURN(0);
				} else {
					RETURN(ERROR_MEMSTICK_DEVCTL_BAD_PARAMS);
				}
				return;
			}
			break;

		case 0x02025805:	// Unregister callback
			if (Memory::IsValidAddress(argAddr) && argLen == 4) {
				u32 cbId = Memory::Read_U32(argAddr);
				if (0 == __KernelUnregisterCallback(THREAD_CALLBACK_MEMORYSTICK, cbId)) {
					DEBUG_LOG(HLE, "sceIoDevCtl: Unregistered memstick callback %i", cbId);
					RETURN(0);
				} else {
					RETURN(ERROR_MEMSTICK_DEVCTL_BAD_PARAMS);
				}
				return;
			}
			break;

		case 0x02025806:	// Memory stick inserted?
		case 0x02025801:	// Memstick Driver status?
			if (Memory::IsValidAddress(outPtr)) {
				Memory::Write_U32(1, outPtr);
				RETURN(0);
			} else {
				RETURN(ERROR_MEMSTICK_DEVCTL_BAD_PARAMS);
			}
			return;

		case 0x02425818:  // Get memstick size etc
			// Pretend we have a 2GB memory stick.
			if (Memory::IsValidAddress(argAddr)) {  // "Should" be outPtr but isn't
				u32 pointer = Memory::Read_U32(argAddr);

				u64 totalSize = (u32)2 * 1024 * 1024 * 1024;
				u64 freeSize	= 1 * 1024 * 1024 * 1024;
				DeviceSize deviceSize;
				deviceSize.maxSectors				= 512;
				deviceSize.sectorSize				= 0x200;
				deviceSize.sectorsPerCluster = 0x08;
				deviceSize.totalClusters		 = (u32)((totalSize * 95 / 100) / (deviceSize.sectorSize * deviceSize.sectorsPerCluster));
				deviceSize.freeClusters			= (u32)((freeSize	* 95 / 100) / (deviceSize.sectorSize * deviceSize.sectorsPerCluster));
				Memory::WriteStruct(pointer, &deviceSize);
				RETURN(0);
			} else {
				RETURN(ERROR_MEMSTICK_DEVCTL_BAD_PARAMS);
			}
			return;
		}
	}

	if (!strcmp(name, "fatms0:"))
	{
		switch (cmd) {
		case 0x02415821:  // MScmRegisterMSInsertEjectCallback
			{
				u32 cbId = Memory::Read_U32(argAddr);
				if (0 == __KernelRegisterCallback(THREAD_CALLBACK_MEMORYSTICK_FAT, cbId)) {
					DEBUG_LOG(HLE, "sceIoDevCtl: Memstick FAT callback %i registered, notifying immediately.", cbId);
					__KernelNotifyCallbackType(THREAD_CALLBACK_MEMORYSTICK_FAT, cbId, MemoryStick_FatState());
					RETURN(0);
				} else {
					RETURN(-1);
				}
				return;
			}
			break;
		case 0x02415822: // MScmUnregisterMSInsertEjectCallback
			{
				u32 cbId = Memory::Read_U32(argAddr);
				if (0 == __KernelUnregisterCallback(THREAD_CALLBACK_MEMORYSTICK_FAT, cbId)) {
					DEBUG_LOG(HLE, "sceIoDevCtl: Unregistered memstick FAT callback %i", cbId);
					RETURN(0);
				} else {
					RETURN(-1);
				}
				return;
			}

		case 0x02415823:  // Set FAT as enabled
			if (Memory::IsValidAddress(argAddr) && argLen == 4) {
				MemoryStick_SetFatState((MemStickFatState)Memory::Read_U32(argAddr));
				RETURN(0);
			} else {
				ERROR_LOG(HLE, "Failed 0x02415823 fat");
				RETURN(-1);
			}
			break;

		case 0x02425823:  // Check if FAT enabled
			if (Memory::IsValidAddress(outPtr) && outLen == 4) {
				Memory::Write_U32(MemoryStick_FatState(), outPtr);
				RETURN(0);
			} else {
				ERROR_LOG(HLE, "Failed 0x02425823 fat");
				RETURN(-1);
			}
			break;

		case 0x02425818:  // Get memstick size etc
			// Pretend we have a 2GB memory stick.
			{
				if (Memory::IsValidAddress(argAddr)) {  // "Should" be outPtr but isn't
					u32 pointer = Memory::Read_U32(argAddr);

					u64 totalSize = (u32)2 * 1024 * 1024 * 1024;
					u64 freeSize	= 1 * 1024 * 1024 * 1024;
					DeviceSize deviceSize;
					deviceSize.maxSectors				= 512;
					deviceSize.sectorSize				= 0x200;
					deviceSize.sectorsPerCluster = 0x08;
					deviceSize.totalClusters		 = (u32)((totalSize * 95 / 100) / (deviceSize.sectorSize * deviceSize.sectorsPerCluster));
					deviceSize.freeClusters			= (u32)((freeSize	* 95 / 100) / (deviceSize.sectorSize * deviceSize.sectorsPerCluster));
					Memory::WriteStruct(pointer, &deviceSize);
					RETURN(0);
				} else {
					RETURN(ERROR_MEMSTICK_DEVCTL_BAD_PARAMS);
				}
				return;
			}
		}
	}


	if (!strcmp(name, "kemulator:") || !strcmp(name, "emulator:"))
	{
		// Emulator special tricks!
		switch (cmd)
		{
		case 1:	// EMULATOR_DEVCTL__GET_HAS_DISPLAY
			if (Memory::IsValidAddress(outPtr))
				Memory::Write_U32(0, outPtr);	 // TODO: Make a headless mode for running tests!
			RETURN(0);
			return;
		case 2:	// EMULATOR_DEVCTL__SEND_OUTPUT
			{
				std::string data(Memory::GetCharPointer(argAddr), argLen);
				if (PSP_CoreParameter().printfEmuLog)
				{
					printf("%s", data.c_str());
#ifdef _WIN32
					OutputDebugString(data.c_str());
#endif
					// Also collect the debug output
					emuDebugOutput += data;
				}
				else
				{
					DEBUG_LOG(HLE, "%s", data.c_str());
				}
				RETURN(0);
				return;
			}
		case 3:	// EMULATOR_DEVCTL__IS_EMULATOR
			if (Memory::IsValidAddress(outPtr))
				Memory::Write_U32(1, outPtr);	 // TODO: Make a headless mode for running tests!
			RETURN(0);
			return;
		}

		ERROR_LOG(HLE, "sceIoDevCtl: UNKNOWN PARAMETERS");
		
		RETURN(0);
		return;
	}

	//089c6d1c weird branch
	/*
	089c6bdc ]: HLE: sceKernelCreateCallback(name= MemoryStick Detection ,entry= 089c7484 ) (z_un_089c6bc4)
	089c6c18 ]: HLE: sceIoDevctl("mscmhc0:", 02015804, 09ffb9c0, 4, 00000000, 0) (z_un_089c6bc4)
	089c6c40 ]: HLE: sceKernelCreateCallback(name= MemoryStick Assignment ,entry= 089c7534 ) (z_un_089c6bc4)
	089c6c78 ]: HLE: sceIoDevctl("fatms0:", 02415821, 09ffb9c4, 4, 00000000, 0) (z_un_089c6bc4)
	089c6cac ]: HLE: sceIoDevctl("mscmhc0:", 02025806, 00000000, 0, 09ffb9c8, 4) (z_un_089c6bc4)
	*/
	RETURN(SCE_KERNEL_ERROR_UNSUP);
}
示例#4
0
u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 outPtr, int outLen) {
	if (strcmp(name, "emulator:")) {
		DEBUG_LOG(HLE,"sceIoDevctl(\"%s\", %08x, %08x, %i, %08x, %i)", name, cmd, argAddr, argLen, outPtr, outLen);
	}

	// UMD checks
	switch (cmd) {
	case 0x01F20001:  // Get Disc Type.
		if (Memory::IsValidAddress(outPtr)) {
			Memory::Write_U32(0x10, outPtr);  // Game disc
			return 0;
		} else {
			return -1;
		}
		break;
	case 0x01F20002:  // Get current LBA.
		if (Memory::IsValidAddress(outPtr)) {
			Memory::Write_U32(0, outPtr);  // Game disc
			return 0;
		} else {
			return -1;
		}
		break;
	case 0x01F100A3:  // Seek
		return 0;
	}

	// This should really send it on to a FileSystem implementation instead.

	if (!strcmp(name, "mscmhc0:") || !strcmp(name, "ms0:"))
	{
		switch (cmd)
		{
		// does one of these set a callback as well? (see coded arms)
		case 0x02015804:	// Register callback
			if (Memory::IsValidAddress(argAddr) && argLen == 4) {
				u32 cbId = Memory::Read_U32(argAddr);
				if (0 == __KernelRegisterCallback(THREAD_CALLBACK_MEMORYSTICK, cbId)) {
					DEBUG_LOG(HLE, "sceIoDevCtl: Memstick callback %i registered, notifying immediately.", cbId);
					__KernelNotifyCallbackType(THREAD_CALLBACK_MEMORYSTICK, cbId, MemoryStick_State());
					return 0;
				} else {
					return ERROR_MEMSTICK_DEVCTL_BAD_PARAMS;
				}
			}
			break;

		case 0x02025805:	// Unregister callback
			if (Memory::IsValidAddress(argAddr) && argLen == 4) {
				u32 cbId = Memory::Read_U32(argAddr);
				if (0 == __KernelUnregisterCallback(THREAD_CALLBACK_MEMORYSTICK, cbId)) {
					DEBUG_LOG(HLE, "sceIoDevCtl: Unregistered memstick callback %i", cbId);
					return 0;
				} else {
					return ERROR_MEMSTICK_DEVCTL_BAD_PARAMS;
				}
			}
			break;

		case 0x02025801:	// Memstick Driver status?
			if (Memory::IsValidAddress(outPtr) && outLen >= 4) {
				Memory::Write_U32(4, outPtr);  // JPSCP: The right return value is 4 for some reason
				return 0;
			} else {
				return ERROR_MEMSTICK_DEVCTL_BAD_PARAMS;
			}

		case 0x02025806:	// Memory stick inserted?
			if (Memory::IsValidAddress(outPtr) && outLen >= 4) {
				Memory::Write_U32(1, outPtr);
				return 0;
			} else {
				return ERROR_MEMSTICK_DEVCTL_BAD_PARAMS;
			}

		case 0x02425818:  // Get memstick size etc
			// Pretend we have a 2GB memory stick.
			if (Memory::IsValidAddress(argAddr) && argLen >= 4) {  // "Should" be outPtr but isn't
				u32 pointer = Memory::Read_U32(argAddr);
				u32 sectorSize = 0x200;
				u32 memStickSectorSize = 32 * 1024;
				u32 sectorCount = memStickSectorSize / sectorSize;
				u64 freeSize = 1 * 1024 * 1024 * 1024;
				DeviceSize deviceSize;
				deviceSize.maxClusters = (u32)((freeSize  * 95 / 100) / (sectorSize * sectorCount));
				deviceSize.freeClusters = deviceSize.maxClusters;
				deviceSize.maxSectors = deviceSize.maxClusters;
				deviceSize.sectorSize = sectorSize;
				deviceSize.sectorCount = sectorCount;
				Memory::WriteStruct(pointer, &deviceSize);
				DEBUG_LOG(HLE, "Returned memstick size: maxSectors=%i", deviceSize.maxSectors);
				return 0;
			} else {
				ERROR_LOG(HLE, "memstick size query: bad params");
				return ERROR_MEMSTICK_DEVCTL_BAD_PARAMS;
			}
		}
	}

	if (!strcmp(name, "fatms0:"))
	{
		switch (cmd) {
		case 0x02415821:  // MScmRegisterMSInsertEjectCallback
			{
				u32 cbId = Memory::Read_U32(argAddr);
				if (0 == __KernelRegisterCallback(THREAD_CALLBACK_MEMORYSTICK_FAT, cbId)) {
					DEBUG_LOG(HLE, "sceIoDevCtl: Memstick FAT callback %i registered, notifying immediately.", cbId);
					__KernelNotifyCallbackType(THREAD_CALLBACK_MEMORYSTICK_FAT, cbId, MemoryStick_FatState());
					return 0;
				} else {
					return -1;
				}
			}
			break;
		case 0x02415822: // MScmUnregisterMSInsertEjectCallback
			{
				u32 cbId = Memory::Read_U32(argAddr);
				if (0 == __KernelUnregisterCallback(THREAD_CALLBACK_MEMORYSTICK_FAT, cbId)) {
					DEBUG_LOG(HLE, "sceIoDevCtl: Unregistered memstick FAT callback %i", cbId);
					return 0;
				} else {
					return -1;
				}
			}

		case 0x02415823:  // Set FAT as enabled
			if (Memory::IsValidAddress(argAddr) && argLen == 4) {
				MemoryStick_SetFatState((MemStickFatState)Memory::Read_U32(argAddr));
				return 0;
			} else {
				ERROR_LOG(HLE, "Failed 0x02415823 fat");
				return -1;
			}
			break;

		case 0x02425823:  // Check if FAT enabled
			if (Memory::IsValidAddress(outPtr) && outLen == 4) {
				Memory::Write_U32(MemoryStick_FatState(), outPtr);
				return 0;
			} else {
				ERROR_LOG(HLE, "Failed 0x02425823 fat");
				return -1;
			}
			break;

		case 0x02425818:  // Get memstick size etc
			// Pretend we have a 2GB memory stick.
			{
				if (Memory::IsValidAddress(argAddr) && argLen >= 4) {  // NOTE: not outPtr
					u32 pointer = Memory::Read_U32(argAddr);
					u32 sectorSize = 0x200;
					u32 memStickSectorSize = 32 * 1024;
					u32 sectorCount = memStickSectorSize / sectorSize;
					u64 freeSize = 1 * 1024 * 1024 * 1024;
					DeviceSize deviceSize;
					deviceSize.maxClusters = (u32)((freeSize  * 95 / 100) / (sectorSize * sectorCount));
					deviceSize.freeClusters = deviceSize.maxClusters;
					deviceSize.maxSectors = deviceSize.maxClusters;
					deviceSize.sectorSize = sectorSize;
					deviceSize.sectorCount = sectorCount;
					Memory::WriteStruct(pointer, &deviceSize);
					return 0;
				} else {
					return ERROR_MEMSTICK_DEVCTL_BAD_PARAMS;
				}
			}
		}
	}

	if (!strcmp(name, "kemulator:") || !strcmp(name, "emulator:"))
	{
		// Emulator special tricks!
		switch (cmd)
		{
		case 1:	// EMULATOR_DEVCTL__GET_HAS_DISPLAY
			if (Memory::IsValidAddress(outPtr))
				Memory::Write_U32(0, outPtr);	 // TODO: Make a headless mode for running tests!
			return 0;
		case 2:	// EMULATOR_DEVCTL__SEND_OUTPUT
			{
				std::string data(Memory::GetCharPointer(argAddr), argLen);
				if (PSP_CoreParameter().printfEmuLog)
				{
					host->SendDebugOutput(data.c_str());
				}
				else
				{
					DEBUG_LOG(HLE, "%s", data.c_str());
				}
				return 0;
			}
		case 3:	// EMULATOR_DEVCTL__IS_EMULATOR
			if (Memory::IsValidAddress(outPtr))
				Memory::Write_U32(1, outPtr);
			return 0;
		case 4: // EMULATOR_DEVCTL__VERIFY_STATE
			// Note that this is async, and makes sure the save state matches up.
			SaveState::Verify();
			// TODO: Maybe save/load to a file just to be sure?
			return 0;
		}

		ERROR_LOG(HLE, "sceIoDevCtl: UNKNOWN PARAMETERS");

		return 0;
	}

	//089c6d1c weird branch
	/*
	089c6bdc ]: HLE: sceKernelCreateCallback(name= MemoryStick Detection ,entry= 089c7484 ) (z_un_089c6bc4)
	089c6c18 ]: HLE: sceIoDevctl("mscmhc0:", 02015804, 09ffb9c0, 4, 00000000, 0) (z_un_089c6bc4)
	089c6c40 ]: HLE: sceKernelCreateCallback(name= MemoryStick Assignment ,entry= 089c7534 ) (z_un_089c6bc4)
	089c6c78 ]: HLE: sceIoDevctl("fatms0:", 02415821, 09ffb9c4, 4, 00000000, 0) (z_un_089c6bc4)
	089c6cac ]: HLE: sceIoDevctl("mscmhc0:", 02025806, 00000000, 0, 09ffb9c8, 4) (z_un_089c6bc4)
	*/
	return SCE_KERNEL_ERROR_UNSUP;
}
示例#5
0
int PSPSaveDialog::Update()
{
	switch (status) {
	case SCE_UTILITY_STATUS_FINISHED:
		status = SCE_UTILITY_STATUS_SHUTDOWN;
		break;
	default:
		break;
	}

	if (status != SCE_UTILITY_STATUS_RUNNING)
	{
		return SCE_ERROR_UTILITY_INVALID_STATUS;
	}

	if (!param.GetPspParam()) {
		status = SCE_UTILITY_STATUS_SHUTDOWN;
		return 0;
	}

	buttons = __CtrlPeekButtons();
	UpdateFade();

	okButtonImg = I_CIRCLE;
	cancelButtonImg = I_CROSS;
	okButtonFlag = CTRL_CIRCLE;
	cancelButtonFlag = CTRL_CROSS;
	if(param.GetPspParam()->buttonSwap == 1)
	{
		okButtonImg = I_CROSS;
		cancelButtonImg = I_CIRCLE;
		okButtonFlag = CTRL_CROSS;
		cancelButtonFlag = CTRL_CIRCLE;
	}

	I18NCategory *d = GetI18NCategory("Dialog");

	switch(display)
	{
		case DS_SAVE_LIST_CHOICE:
			StartDraw();
			
			// TODO : use focus param for selected save by default
			DisplaySaveList();
			DisplaySaveDataInfo1();

			DisplayEnterBack();
			if (IsButtonPressed(cancelButtonFlag))
			{
				param.GetPspParam()->result = SCE_UTILITY_DIALOG_RESULT_CANCEL;
				StartFade(false);
			}
			else if (IsButtonPressed(okButtonFlag))
			{
				// Save exist, ask user confirm
				if(param.GetFileInfo(currentSelectedSave).size > 0)
				{
					yesnoChoice = 0;
					display = DS_SAVE_CONFIRM_OVERWRITE;
				}
				else
				{
					display = DS_SAVE_SAVING;
					if(param.Save(param.GetPspParam(),currentSelectedSave))
					{
						param.SetPspParam(param.GetPspParam()); // Optim : Just Update modified save
						display = DS_SAVE_DONE;
					}
					else
					{
						display = DS_SAVE_LIST_CHOICE; // This will probably need error message ?
					}
				}
			}
			EndDraw();
		break;
		case DS_SAVE_CONFIRM_OVERWRITE:
			StartDraw();
			

			DisplaySaveIcon();
			DisplaySaveDataInfo2();

			DisplayConfirmationYesNo(d->T("Do you want to overwrite the data?"));

			DisplayEnterBack();
			if (IsButtonPressed(cancelButtonFlag))
			{
				display = DS_SAVE_LIST_CHOICE;
			}
			else if (IsButtonPressed(okButtonFlag))
			{
				if(yesnoChoice == 0)
				{
					display = DS_SAVE_LIST_CHOICE;
				}
				else
				{
					display = DS_SAVE_SAVING;
					if(param.Save(param.GetPspParam(),currentSelectedSave))
					{
						param.SetPspParam(param.GetPspParam()); // Optim : Just Update modified save
						display = DS_SAVE_DONE;
					}
					else
					{
						display = DS_SAVE_LIST_CHOICE; // This will probably need error message ?
					}
				}
			}

			EndDraw();
		break;
		case DS_SAVE_SAVING:
			StartDraw();
			

			DisplaySaveIcon();
			DisplaySaveDataInfo2();

			DisplayInfo(d->T("Saving\nPlease Wait..."));

			EndDraw();
		break;
		case DS_SAVE_DONE:
			StartDraw();
			

			DisplaySaveIcon();
			DisplaySaveDataInfo2();
			DisplayBack();

			DisplayInfo(d->T("Save completed"));

			if (IsButtonPressed(cancelButtonFlag))
			{
				param.GetPspParam()->result = SCE_UTILITY_DIALOG_RESULT_SUCCESS;
				// Set the save to use for autosave and autoload
				param.SetSelectedSave(param.GetFileInfo(currentSelectedSave).idx);
				StartFade(false);
			}

			EndDraw();
		break;

		case DS_LOAD_LIST_CHOICE:
			StartDraw();
			
			DisplaySaveList();
			DisplaySaveDataInfo1();

			DisplayEnterBack();
			if (IsButtonPressed(cancelButtonFlag))
			{
				param.GetPspParam()->result = SCE_UTILITY_DIALOG_RESULT_CANCEL;
				StartFade(false);
			}
			else if (IsButtonPressed(okButtonFlag))
			{
				display = DS_LOAD_LOADING;
				if(param.Load(param.GetPspParam(),currentSelectedSave))
				{
					display = DS_LOAD_DONE;
				}
			}

			EndDraw();
		break;
		case DS_LOAD_LOADING:
			StartDraw();
			

			DisplaySaveIcon();
			DisplaySaveDataInfo2();

			DisplayInfo(d->T("Loading\nPlease Wait..."));

			EndDraw();
		break;
		case DS_LOAD_DONE:
			StartDraw();
			

			DisplaySaveIcon();
			DisplaySaveDataInfo2();
			DisplayBack();

			DisplayInfo(d->T("Load completed"));

			if (IsButtonPressed(cancelButtonFlag))
			{
				param.GetPspParam()->result = SCE_UTILITY_DIALOG_RESULT_SUCCESS;
				// Set the save to use for autosave and autoload
				param.SetSelectedSave(param.GetFileInfo(currentSelectedSave).idx);
				StartFade(false);
			}

			EndDraw();
		break;
		case DS_LOAD_NODATA:
			StartDraw();
			

			DisplayBack();

			DisplayInfo(d->T("There is no data"));

			if (IsButtonPressed(cancelButtonFlag))
			{
				param.GetPspParam()->result = SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA;
				StartFade(false);
			}

			EndDraw();
		break;

		case DS_DELETE_LIST_CHOICE:
			StartDraw();
			
			DisplaySaveList();
			DisplaySaveDataInfo1();

			DisplayEnterBack();
			if (IsButtonPressed(cancelButtonFlag))
			{
				param.GetPspParam()->result = SCE_UTILITY_DIALOG_RESULT_CANCEL;
				StartFade(false);
			}
			else if (IsButtonPressed(okButtonFlag))
			{
				yesnoChoice = 0;
				display = DS_DELETE_CONFIRM;
			}

			EndDraw();
		break;
		case DS_DELETE_CONFIRM:
			StartDraw();
			

			DisplaySaveIcon();
			DisplaySaveDataInfo2();

			DisplayConfirmationYesNo(d->T("This save data will be deleted.\nAre you sure you want to continue?", "    This save data will be deleted.\nAre you sure you want to continue?"));


			DisplayEnterBack();
			if (IsButtonPressed(cancelButtonFlag))
			{
				display = DS_DELETE_LIST_CHOICE;
			}
			else if (IsButtonPressed(okButtonFlag))
			{
				if(yesnoChoice == 0)
				{
					display = DS_DELETE_LIST_CHOICE;
				}
				else
				{
					display = DS_DELETE_DELETING;
					if(param.Delete(param.GetPspParam(),currentSelectedSave))
					{
						param.SetPspParam(param.GetPspParam()); // Optim : Just Update modified save
						display = DS_DELETE_DONE;
					}
					else
					{
						display = DS_DELETE_LIST_CHOICE; // This will probably need error message ?
					}
				}
			}

			EndDraw();
		break;
		case DS_DELETE_DELETING:
			StartDraw();
			

			DisplayInfo(d->T("Deleting\nPlease Wait..."));

			EndDraw();
		break;
		case DS_DELETE_DONE:
			StartDraw();
			

			DisplayBack();

			DisplayInfo(d->T("Delete completed"));

			if (IsButtonPressed(cancelButtonFlag))
			{
				if(param.GetFilenameCount() == 0)
					display = DS_DELETE_NODATA;
				else
					display = DS_DELETE_LIST_CHOICE;
			}

			EndDraw();
		break;
		case DS_DELETE_NODATA:
			StartDraw();
			

			DisplayBack();

			DisplayInfo(d->T("There is no data"));

			if (IsButtonPressed(cancelButtonFlag))
			{
				param.GetPspParam()->result = SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_DATA;
				StartFade(false);
			}

			EndDraw();
		break;

		case DS_NONE: // For action which display nothing
		{
			switch(param.GetPspParam()->mode)
			{
				case SCE_UTILITY_SAVEDATA_TYPE_LOAD: // Only load and exit
				case SCE_UTILITY_SAVEDATA_TYPE_AUTOLOAD:
					if(param.Load(param.GetPspParam(),param.GetSelectedSave()))
						param.GetPspParam()->result = 0;
					else
						param.GetPspParam()->result = SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA;
					status = SCE_UTILITY_STATUS_FINISHED;
				break;
				case SCE_UTILITY_SAVEDATA_TYPE_SAVE: // Only save and exit
				case SCE_UTILITY_SAVEDATA_TYPE_AUTOSAVE:
					if(param.Save(param.GetPspParam(),param.GetSelectedSave()))
						param.GetPspParam()->result = 0;
					else
						param.GetPspParam()->result = SCE_UTILITY_SAVEDATA_ERROR_SAVE_MS_NOSPACE;
					status = SCE_UTILITY_STATUS_FINISHED;
				break;
				case SCE_UTILITY_SAVEDATA_TYPE_SIZES:
					if(param.GetSizes(param.GetPspParam()))
					{
						param.GetPspParam()->result = 0;
					}
					else
					{
						param.GetPspParam()->result = SCE_UTILITY_SAVEDATA_ERROR_SIZES_NO_DATA;
					}
					status = SCE_UTILITY_STATUS_FINISHED;
				break;
				case SCE_UTILITY_SAVEDATA_TYPE_LIST:
					param.GetList(param.GetPspParam());
					param.GetPspParam()->result = 0;
					status = SCE_UTILITY_STATUS_FINISHED;
				break;
				case SCE_UTILITY_SAVEDATA_TYPE_FILES:
					if(param.GetFilesList(param.GetPspParam()))
					{
						param.GetPspParam()->result = 0;
					}
					else
					{
						param.GetPspParam()->result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA;
					}
					status = SCE_UTILITY_STATUS_FINISHED;
				break;
				case SCE_UTILITY_SAVEDATA_TYPE_GETSIZE:
					{
						bool result = param.GetSize(param.GetPspParam());
						// TODO: According to JPCSP, should test/verify this part but seems edge casey.
						if (MemoryStick_State() != PSP_MEMORYSTICK_STATE_DRIVER_READY)
							param.GetPspParam()->result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_MEMSTICK;
						else if (result)
							param.GetPspParam()->result = 0;
						else
							param.GetPspParam()->result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA;
						status = SCE_UTILITY_STATUS_FINISHED;
					}
				break;
				case SCE_UTILITY_SAVEDATA_TYPE_DELETEDATA:
					// TODO: This should probably actually delete something.
					// For now, since MAKEDATA doesn't work anyway, always say it couldn't be deleted.
					WARN_LOG(HLE, "FAKE sceUtilitySavedata DELETEDATA: %s", param.GetPspParam()->saveName);
					param.GetPspParam()->result = SCE_UTILITY_SAVEDATA_ERROR_RW_BAD_STATUS;
					status = SCE_UTILITY_STATUS_FINISHED;
				break;
				//case SCE_UTILITY_SAVEDATA_TYPE_AUTODELETE:
				case SCE_UTILITY_SAVEDATA_TYPE_SINGLEDELETE:
					if(param.Delete(param.GetPspParam(), param.GetSelectedSave()))
					{
						param.GetPspParam()->result = 0;
					}
					else
					{
						param.GetPspParam()->result = SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_DATA;
					}
					status = SCE_UTILITY_STATUS_FINISHED;
				break;
				//case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATA:
				case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE:
					if(param.Save(param.GetPspParam(),param.GetSelectedSave()))
						param.GetPspParam()->result = 0;
					else
						param.GetPspParam()->result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA;
					status = SCE_UTILITY_STATUS_FINISHED;
				break;
				//case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATA:
				case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE:
					if(param.Save(param.GetPspParam(),param.GetSelectedSave()))
						param.GetPspParam()->result = 0;
					else
						param.GetPspParam()->result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA;
					status = SCE_UTILITY_STATUS_FINISHED;
				break;
				//case SCE_UTILITY_SAVEDATA_TYPE_READDATA:
				case SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE:
					if(param.Load(param.GetPspParam(),param.GetSelectedSave()))
						param.GetPspParam()->result = 0;
					else
						param.GetPspParam()->result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA; // not sure if correct code
					status = SCE_UTILITY_STATUS_FINISHED;
				break;
				default:
					status = SCE_UTILITY_STATUS_FINISHED;
				break;
			}
		}
		break;
		default:
			status = SCE_UTILITY_STATUS_FINISHED;
		break;
	}

	lastButtons = buttons;

	if(status == SCE_UTILITY_STATUS_FINISHED)
	{
		Memory::Memcpy(requestAddr,&request,request.size);
	}
	
	return 0;
}