diff --git a/CMakeLists.txt b/CMakeLists.txt index aa67683c48..f3151d0088 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -605,6 +605,16 @@ add_library(${CoreLibName} ${CoreLinkType} Core/Debugger/DebugInterface.h Core/Debugger/SymbolMap.cpp Core/Debugger/SymbolMap.h + Core/Dialog/PSPDialog.cpp + Core/Dialog/PSPDialog.h + Core/Dialog/PSPMsgDialog.cpp + Core/Dialog/PSPMsgDialog.h + Core/Dialog/PSPPlaceholderDialog.cpp + Core/Dialog/PSPPlaceholderDialog.h + Core/Dialog/PSPSaveDialog.cpp + Core/Dialog/PSPSaveDialog.h + Core/Dialog/SavedataParam.cpp + Core/Dialog/SavedataParam.h Core/ELF/ElfReader.cpp Core/ELF/ElfReader.h Core/ELF/ElfTypes.h diff --git a/Core/Dialog/PSPDialog.cpp b/Core/Dialog/PSPDialog.cpp new file mode 100644 index 0000000000..9356d6de39 --- /dev/null +++ b/Core/Dialog/PSPDialog.cpp @@ -0,0 +1,67 @@ +// Copyright (c) 2012- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#include "../Util/PPGeDraw.h" +#include "PSPDialog.h" + +PSPDialog::PSPDialog() : status(SCE_UTILITY_STATUS_SHUTDOWN) +, lastButtons(0) +, buttons(0) +{ + +} + +PSPDialog::~PSPDialog() { +} + +PSPDialog::DialogStatus PSPDialog::GetStatus() +{ + PSPDialog::DialogStatus retval = status; + if (status == SCE_UTILITY_STATUS_SHUTDOWN) + status = SCE_UTILITY_STATUS_NONE; + if (status == SCE_UTILITY_STATUS_INITIALIZE) + status = SCE_UTILITY_STATUS_RUNNING; + return retval; +} + +void PSPDialog::StartDraw() +{ + PPGeBegin(); + PPGeDraw4Patch(I_BUTTON, 0, 0, 480, 272, 0xcFFFFFFF); +} +void PSPDialog::EndDraw() +{ + PPGeEnd(); +} + +void PSPDialog::Shutdown() +{ + status = SCE_UTILITY_STATUS_SHUTDOWN; +} + +void PSPDialog::Update() +{ + +} + +bool PSPDialog::IsButtonPressed(int checkButton) +{ + INFO_LOG(HLE,"%d %d %d %d",checkButton,lastButtons,buttons,(!(lastButtons & checkButton)) && (buttons & checkButton)); + return (!(lastButtons & checkButton)) && (buttons & checkButton); +} + + diff --git a/Core/Dialog/PSPDialog.h b/Core/Dialog/PSPDialog.h new file mode 100644 index 0000000000..9bbe8019c6 --- /dev/null +++ b/Core/Dialog/PSPDialog.h @@ -0,0 +1,57 @@ +// Copyright (c) 2012- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#pragma once + + +#include "../Config.h" + +#define SCE_UTILITY_DIALOG_RESULT_SUCCESS 0 +#define SCE_UTILITY_DIALOG_RESULT_CANCEL 1 +#define SCE_UTILITY_DIALOG_RESULT_ABORT 2 + + +class PSPDialog +{ +public: + PSPDialog(); + virtual ~PSPDialog(); + + virtual void Update(); + virtual void Shutdown(); + + enum DialogStatus + { + SCE_UTILITY_STATUS_NONE = 0, + SCE_UTILITY_STATUS_INITIALIZE = 1, + SCE_UTILITY_STATUS_RUNNING = 2, + SCE_UTILITY_STATUS_FINISHED = 3, + SCE_UTILITY_STATUS_SHUTDOWN = 4 + }; + + DialogStatus GetStatus(); + + void StartDraw(); + void EndDraw(); +protected: + bool IsButtonPressed(int checkButton); + + DialogStatus status; + + unsigned int lastButtons; + unsigned int buttons; +}; diff --git a/Core/Dialog/PSPMsgDialog.cpp b/Core/Dialog/PSPMsgDialog.cpp new file mode 100644 index 0000000000..0d021e8063 --- /dev/null +++ b/Core/Dialog/PSPMsgDialog.cpp @@ -0,0 +1,207 @@ +// Copyright (c) 2012- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#include "PSPMsgDialog.h" +#include "../Util/PPGeDraw.h" +#include "../HLE/sceCtrl.h" +#include "../Core/MemMap.h" + +PSPMsgDialog::PSPMsgDialog() + : PSPDialog() + , display(DS_NONE) +{ +} + +PSPMsgDialog::~PSPMsgDialog() { +} + +void PSPMsgDialog::Init(unsigned int paramAddr) +{ + messageDialogAddr = paramAddr; + if (!Memory::IsValidAddress(messageDialogAddr)) + { + return; + } + Memory::ReadStruct(messageDialogAddr, &messageDialog); + + yesnoChoice = 1; + if (messageDialog.type == 0) // number + { + INFO_LOG(HLE, "MsgDialog: %08x", messageDialog.errorNum); + display = DS_ERROR; + } + else + { + INFO_LOG(HLE, "MsgDialog: %s", messageDialog.string); + display = DS_MESSAGE; + if(messageDialog.options & SCE_UTILITY_MSGDIALOG_OPTION_YESNO) + display = DS_YESNO; + if(messageDialog.options & SCE_UTILITY_MSGDIALOG_OPTION_DEFAULT_NO) + yesnoChoice = 0; + } + + status = SCE_UTILITY_STATUS_INITIALIZE; + + lastButtons = __CtrlPeekButtons(); + +} + +void PSPMsgDialog::DisplayMessage(std::string text) +{ + PPGeDrawText(text.c_str(), 480/2, 100, PPGE_ALIGN_CENTER, 0.5f, 0xFFFFFFFF); +} + +void PSPMsgDialog::DisplayBack() +{ + PPGeDrawImage(cancelButtonImg, 250, 220, 20, 20, 0, 0xFFFFFFFF); + PPGeDrawText("Back", 270, 220, PPGE_ALIGN_LEFT, 0.5f, 0xFFFFFFFF); +} +void PSPMsgDialog::DisplayYesNo() +{ + + PPGeDrawText("Yes", 200, 150, PPGE_ALIGN_LEFT, 0.5f, (yesnoChoice == 1?0xFF0000FF:0xFFFFFFFF)); + PPGeDrawText("No", 320, 150, PPGE_ALIGN_LEFT, 0.5f, (yesnoChoice == 0?0xFF0000FF:0xFFFFFFFF)); + + if (IsButtonPressed(CTRL_LEFT) && yesnoChoice == 0) + { + yesnoChoice = 1; + } + else if (IsButtonPressed(CTRL_RIGHT) && yesnoChoice == 1) + { + yesnoChoice = 0; + } +} +void PSPMsgDialog::DisplayEnterBack() +{ + + PPGeDrawImage(okButtonImg, 200, 220, 20, 20, 0, 0xFFFFFFFF); + PPGeDrawText("Enter", 230, 220, PPGE_ALIGN_LEFT, 0.5f, 0xFFFFFFFF); + PPGeDrawImage(cancelButtonImg, 290, 220, 20, 20, 0, 0xFFFFFFFF); + PPGeDrawText("Back", 320, 220, PPGE_ALIGN_LEFT, 0.5f, 0xFFFFFFFF); +} + +void PSPMsgDialog::Update() +{ + switch (status) { + case SCE_UTILITY_STATUS_FINISHED: + status = SCE_UTILITY_STATUS_SHUTDOWN; + break; + } + + if (status != SCE_UTILITY_STATUS_RUNNING) + { + return; + } + + + const char *text; + if (messageDialog.type == 0) { + char temp[256]; + sprintf(temp, "Error code: %08x", messageDialog.errorNum); + text = temp; + } else { + text = messageDialog.string; + } + + buttons = __CtrlPeekButtons(); + + okButtonImg = I_CIRCLE; + cancelButtonImg = I_CROSS; + okButtonFlag = CTRL_CIRCLE; + cancelButtonFlag = CTRL_CROSS; + if(messageDialog.common.buttonSwap == 1) + { + okButtonImg = I_CROSS; + cancelButtonImg = I_CIRCLE; + okButtonFlag = CTRL_CROSS; + cancelButtonFlag = CTRL_CIRCLE; + } + + switch(display) + { + case DS_MESSAGE: + StartDraw(); + + DisplayMessage(text); + + // TODO : Dialogs should take control over input and not send them to the game while displaying + DisplayBack(); + if (IsButtonPressed(cancelButtonFlag)) + { + status = SCE_UTILITY_STATUS_FINISHED; + messageDialog.buttonPressed = 0; + } + EndDraw(); + break; + case DS_ERROR: + StartDraw(); + + DisplayMessage(text); + + // TODO : Dialogs should take control over input and not send them to the game while displaying + DisplayBack(); + if (IsButtonPressed(cancelButtonFlag)) + { + status = SCE_UTILITY_STATUS_FINISHED; + messageDialog.buttonPressed = 0; + } + EndDraw(); + break; + case DS_YESNO: + StartDraw(); + + DisplayMessage(text); + DisplayYesNo(); + + // TODO : Dialogs should take control over input and not send them to the game while displaying + DisplayEnterBack(); + if (IsButtonPressed(cancelButtonFlag)) + { + status = SCE_UTILITY_STATUS_FINISHED; + messageDialog.buttonPressed = 3; + } + else if (IsButtonPressed(okButtonFlag)) + { + if(yesnoChoice == 0) + { + status = SCE_UTILITY_STATUS_FINISHED; + messageDialog.buttonPressed = 2; + } + else + { + status = SCE_UTILITY_STATUS_FINISHED; + messageDialog.buttonPressed = 1; + } + } + EndDraw(); + break; + default: + status = SCE_UTILITY_STATUS_FINISHED; + return; + break; + } + + lastButtons = buttons; + + Memory::WriteStruct(messageDialogAddr, &messageDialog); +} + +void PSPMsgDialog::Shutdown() +{ + PSPDialog::Shutdown(); +} + diff --git a/Core/Dialog/PSPMsgDialog.h b/Core/Dialog/PSPMsgDialog.h new file mode 100644 index 0000000000..c0c8315e03 --- /dev/null +++ b/Core/Dialog/PSPMsgDialog.h @@ -0,0 +1,89 @@ +// Copyright (c) 2012- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#pragma once + +#include "PSPDialog.h" + +#define SCE_UTILITY_MSGDIALOG_OPTION_ERROR 0 // Do nothing +#define SCE_UTILITY_MSGDIALOG_OPTION_TEXT 0x00000001 +#define SCE_UTILITY_MSGDIALOG_OPTION_YESNO 0x00000010 +#define SCE_UTILITY_MSGDIALOG_OPTION_DEFAULT_NO 0x00000100 + +typedef struct +{ + unsigned int size; /** Size of the structure */ + int language; /** Language */ + int buttonSwap; /** Set to 1 for X/O button swap */ + int graphicsThread; /** Graphics thread priority */ + int accessThread; /** Access/fileio thread priority (SceJobThread) */ + int fontThread; /** Font thread priority (ScePafThread) */ + int soundThread; /** Sound thread priority */ + int result; /** Result */ + int reserved[4]; /** Set to 0 */ + +} pspUtilityDialogCommon; + +struct pspMessageDialog +{ + pspUtilityDialogCommon common; + int result; + int type; + unsigned int errorNum; + char string[512]; + unsigned int options; + unsigned int buttonPressed; // 0=?, 1=Yes, 2=No, 3=Back +}; + + +class PSPMsgDialog: public PSPDialog { +public: + PSPMsgDialog(); + virtual ~PSPMsgDialog(); + + virtual void Init(unsigned int paramAddr); + virtual void Update(); + void Shutdown(); + +private : + void DisplayMessage(std::string text); + void DisplayBack(); + void DisplayYesNo(); + void DisplayEnterBack(); + + enum DisplayState + { + DS_NONE, + + DS_MESSAGE, + DS_ERROR, + DS_YESNO, + }; + + DisplayState display; + + pspMessageDialog messageDialog; + int messageDialogAddr; + + int yesnoChoice; + + int okButtonImg; + int cancelButtonImg; + int okButtonFlag; + int cancelButtonFlag; +}; + diff --git a/Core/Dialog/PSPPlaceholderDialog.cpp b/Core/Dialog/PSPPlaceholderDialog.cpp new file mode 100644 index 0000000000..ccd26ed8b6 --- /dev/null +++ b/Core/Dialog/PSPPlaceholderDialog.cpp @@ -0,0 +1,48 @@ +// Copyright (c) 2012- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#include "PSPPlaceholderDialog.h" + +PSPPlaceholderDialog::PSPPlaceholderDialog() : PSPDialog() { + +} + +PSPPlaceholderDialog::~PSPPlaceholderDialog() { +} + + +void PSPPlaceholderDialog::Init() +{ + status = SCE_UTILITY_STATUS_INITIALIZE; +} + +void PSPPlaceholderDialog::Update() +{ + //__UtilityUpdate(); + if (status == SCE_UTILITY_STATUS_INITIALIZE) + { + status = SCE_UTILITY_STATUS_RUNNING; + } + else if (status == SCE_UTILITY_STATUS_RUNNING) + { + status = SCE_UTILITY_STATUS_FINISHED; + } + else if (status == SCE_UTILITY_STATUS_FINISHED) + { + status = SCE_UTILITY_STATUS_SHUTDOWN; + } +} diff --git a/Core/Dialog/PSPPlaceholderDialog.h b/Core/Dialog/PSPPlaceholderDialog.h new file mode 100644 index 0000000000..7854b07dc2 --- /dev/null +++ b/Core/Dialog/PSPPlaceholderDialog.h @@ -0,0 +1,30 @@ +// Copyright (c) 2012- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#pragma once + +#include "PSPDialog.h" + +class PSPPlaceholderDialog: public PSPDialog { +public: + PSPPlaceholderDialog(); + virtual ~PSPPlaceholderDialog(); + + virtual void Init(); + virtual void Update(); +}; + diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp new file mode 100644 index 0000000000..995630a1b4 --- /dev/null +++ b/Core/Dialog/PSPSaveDialog.cpp @@ -0,0 +1,609 @@ +// Copyright (c) 2012- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#include "PSPSaveDialog.h" +#include "../Util/PPGeDraw.h" +#include "../HLE/sceCtrl.h" +#include "../Core/MemMap.h" + +PSPSaveDialog::PSPSaveDialog() + : PSPDialog() + , currentSelectedSave(0) + , display(DS_NONE) +{ + param.SetPspParam(0); +} + +PSPSaveDialog::~PSPSaveDialog() { +} + +void PSPSaveDialog::Init(int paramAddr) +{ + param.SetPspParam((SceUtilitySavedataParam*)Memory::GetPointer(paramAddr)); + + DEBUG_LOG(HLE,"sceUtilitySavedataInitStart(%08x)", paramAddr); + DEBUG_LOG(HLE,"Mode: %i", param.GetPspParam()->mode); + + switch(param.GetPspParam()->mode) + { + case SCE_UTILITY_SAVEDATA_TYPE_AUTOLOAD: + case SCE_UTILITY_SAVEDATA_TYPE_LOAD: + DEBUG_LOG(HLE, "Loading. Title: %s Save: %s File: %s", param.GetPspParam()->gameName, param.GetPspParam()->saveName, param.GetPspParam()->fileName); + display = DS_NONE; + break; + case SCE_UTILITY_SAVEDATA_TYPE_LISTLOAD: + DEBUG_LOG(HLE, "Loading. Title: %s Save: %s File: %s", param.GetPspParam()->gameName, param.GetPspParam()->saveName, param.GetPspParam()->fileName); + if(param.GetFilenameCount() == 0) + display = DS_LOAD_NODATA; + else + display = DS_LOAD_LIST_CHOICE; + break; + case SCE_UTILITY_SAVEDATA_TYPE_AUTOSAVE: + case SCE_UTILITY_SAVEDATA_TYPE_SAVE: + DEBUG_LOG(HLE, "Saving. Title: %s Save: %s File: %s", param.GetPspParam()->gameName, param.GetPspParam()->saveName, param.GetPspParam()->fileName); + display = DS_NONE; + break; + case SCE_UTILITY_SAVEDATA_TYPE_LISTSAVE: + DEBUG_LOG(HLE, "Saving. Title: %s Save: %s File: %s", param.GetPspParam()->gameName, param.GetPspParam()->saveName, param.GetPspParam()->fileName); + display = DS_SAVE_LIST_CHOICE; + break; + case SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE: + DEBUG_LOG(HLE, "Delete. Title: %s Save: %s File: %s", param.GetPspParam()->gameName, param.GetPspParam()->saveName, param.GetPspParam()->fileName); + if(param.GetFilenameCount() == 0) + display = DS_DELETE_NODATA; + else + display = DS_DELETE_LIST_CHOICE; + break; + case SCE_UTILITY_SAVEDATA_TYPE_DELETE: // This run on PSP display a list of all save on the PSP. Weird. + case SCE_UTILITY_SAVEDATA_TYPE_SIZES: + default: + { + ERROR_LOG(HLE, "Load/Save function %d not coded. Title: %s Save: %s File: %s", param.GetPspParam()->mode, param.GetPspParam()->gameName, param.GetPspParam()->saveName, param.GetPspParam()->fileName); + display = DS_NONE; + return; // Return 0 should allow the game to continue, but missing function must be implemented and returning the right value or the game can block. + } + break; + } + + status = SCE_UTILITY_STATUS_INITIALIZE; + + currentSelectedSave = 0; + lastButtons = __CtrlPeekButtons(); + + /*INFO_LOG(HLE,"Dump Param :"); + INFO_LOG(HLE,"size : %d",param->size); + INFO_LOG(HLE,"language : %d",param->language); + INFO_LOG(HLE,"buttonSwap : %d",param->buttonSwap); + INFO_LOG(HLE,"result : %d",param->result); + INFO_LOG(HLE,"mode : %d",param->mode); + INFO_LOG(HLE,"bind : %d",param->bind); + INFO_LOG(HLE,"overwriteMode : %d",param->overwriteMode); + INFO_LOG(HLE,"gameName : %s",param->gameName); + INFO_LOG(HLE,"saveName : %s",param->saveName); + INFO_LOG(HLE,"saveNameList : %08x",*((unsigned int*)¶m->saveNameList)); + INFO_LOG(HLE,"fileName : %s",param->fileName); + INFO_LOG(HLE,"dataBuf : %08x",*((unsigned int*)¶m->dataBuf)); + INFO_LOG(HLE,"dataBufSize : %u",param->dataBufSize); + INFO_LOG(HLE,"dataSize : %u",param->dataSize); + + INFO_LOG(HLE,"sfo title : %s",param->sfoParam.title); + INFO_LOG(HLE,"sfo savedataTitle : %s",param->sfoParam.savedataTitle); + INFO_LOG(HLE,"sfo detail : %s",param->sfoParam.detail); + + INFO_LOG(HLE,"icon0 data : %08x",*((unsigned int*)¶m->icon0FileData.buf)); + INFO_LOG(HLE,"icon0 size : %u",param->icon0FileData.bufSize); + + INFO_LOG(HLE,"icon1 data : %08x",*((unsigned int*)¶m->icon1FileData.buf)); + INFO_LOG(HLE,"icon1 size : %u",param->icon1FileData.bufSize); + + INFO_LOG(HLE,"pic1 data : %08x",*((unsigned int*)¶m->pic1FileData.buf)); + INFO_LOG(HLE,"pic1 size : %u",param->pic1FileData.bufSize); + + INFO_LOG(HLE,"snd0 data : %08x",*((unsigned int*)¶m->snd0FileData.buf)); + INFO_LOG(HLE,"snd0 size : %u",param->snd0FileData.bufSize);*/ + +} + +void PSPSaveDialog::DisplaySaveList(bool canMove) +{ + int displayCount = 0; + for(int i = 0; i < param.GetFilenameCount(); i++) + { + int textureColor = 0xFF000000; // Hack for differencing save existing and not while real texture not displayed + + if(param.GetFileInfo(i).size == 0) + { + textureColor = 0xFF777777; + } + + // Calc save image position on screen + int w = 150; + int h = 80; + int x = 20; + if(displayCount != currentSelectedSave) + { + w = 80; + h = 40; + x = 50; + } + int y = 80; + if(displayCount < currentSelectedSave) + y -= 50 * (currentSelectedSave - displayCount); + else if(displayCount > currentSelectedSave) + { + y += 90 + 50 * (displayCount - currentSelectedSave - 1); + } + + PPGeDraw4Patch(I_BUTTON, x, y, w, h, textureColor); // TODO : Display save texture image, or default if no save + + displayCount++; + } + + if(canMove) + { + if (IsButtonPressed(CTRL_UP) && currentSelectedSave > 0) + { + currentSelectedSave--; + } + else if (IsButtonPressed(CTRL_DOWN) && currentSelectedSave < (param.GetFilenameCount()-1)) + { + currentSelectedSave++; + } + } +} + +void PSPSaveDialog::DisplaySaveIcon() +{ + int textureColor = 0xFF000000; // Hack for differencing save existing and not while real texture not displayed + + if(param.GetFileInfo(currentSelectedSave).size == 0) + { + textureColor = 0xFF777777; + } + + // Calc save image position on screen + int w = 150; + int h = 80; + int x = 20; + int y = 80; + + PPGeDraw4Patch(I_BUTTON, x, y, w, h, textureColor); // TODO : Display save texture image, or default if no save + +} + +void PSPSaveDialog::DisplaySaveDataInfo1() +{ + if(param.GetFileInfo(currentSelectedSave).size == 0) + { + PPGeDrawText("New Save", 200, 110, PPGE_ALIGN_LEFT, 0.5f, 0xFFFFFFFF); + } + else + { + char txt[1024]; + sprintf(txt,"%s\nSize : %d",param.GetFilename(currentSelectedSave),param.GetFileInfo(currentSelectedSave).size); + std::string saveinfoTxt = txt; + PPGeDrawText(saveinfoTxt.c_str(), 200, 100, PPGE_ALIGN_LEFT, 0.5f, 0xFFFFFFFF); + } +} + +void PSPSaveDialog::DisplaySaveDataInfo2() +{ + if(param.GetFileInfo(currentSelectedSave).size == 0) + { + } + else + { + char txt[1024]; + sprintf(txt,"%s\nSize : %d",param.GetFilename(currentSelectedSave),param.GetFileInfo(currentSelectedSave).size); + std::string saveinfoTxt = txt; + PPGeDrawText(saveinfoTxt.c_str(), 10, 180, PPGE_ALIGN_LEFT, 0.5f, 0xFFFFFFFF); + } +} + +void PSPSaveDialog::DisplayConfirmationYesNo(std::string text) +{ + PPGeDrawText(text.c_str(), 200, 90, PPGE_ALIGN_LEFT, 0.5f, 0xFFFFFFFF); + + PPGeDrawText("Yes", 250, 150, PPGE_ALIGN_LEFT, 0.5f, (yesnoChoice == 1?0xFF0000FF:0xFFFFFFFF)); + PPGeDrawText("No", 350, 150, PPGE_ALIGN_LEFT, 0.5f, (yesnoChoice == 0?0xFF0000FF:0xFFFFFFFF)); + + if (IsButtonPressed(CTRL_LEFT) && yesnoChoice == 0) + { + yesnoChoice = 1; + } + else if (IsButtonPressed(CTRL_RIGHT) && yesnoChoice == 1) + { + yesnoChoice = 0; + } +} + +void PSPSaveDialog::DisplayInfo(std::string text) +{ + PPGeDrawText(text.c_str(), 200, 90, PPGE_ALIGN_LEFT, 0.5f, 0xFFFFFFFF); +} +void PSPSaveDialog::DisplayTitle(std::string name) +{ + PPGeDrawText(name.c_str(), 10, 10, PPGE_ALIGN_LEFT, 0.5f, 0xFFFFFFFF); +} +void PSPSaveDialog::DisplayEnterBack() +{ + PPGeDrawImage(okButtonImg, 200, 220, 20, 20, 0, 0xFFFFFFFF); + PPGeDrawText("Enter", 230, 220, PPGE_ALIGN_LEFT, 0.5f, 0xFFFFFFFF); + PPGeDrawImage(cancelButtonImg, 290, 220, 20, 20, 0, 0xFFFFFFFF); + PPGeDrawText("Back", 320, 220, PPGE_ALIGN_LEFT, 0.5f, 0xFFFFFFFF); +} +void PSPSaveDialog::DisplayBack() +{ + PPGeDrawImage(cancelButtonImg, 250, 220, 20, 20, 0, 0xFFFFFFFF); + PPGeDrawText("Back", 270, 220, PPGE_ALIGN_LEFT, 0.5f, 0xFFFFFFFF); +} + +void PSPSaveDialog::Update() +{ + switch (status) { + case SCE_UTILITY_STATUS_FINISHED: + status = SCE_UTILITY_STATUS_SHUTDOWN; + break; + } + + if (status != SCE_UTILITY_STATUS_RUNNING) + { + return; + } + + if (!param.GetPspParam()) { + status = SCE_UTILITY_STATUS_SHUTDOWN; + return; + } + + buttons = __CtrlPeekButtons(); + + 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; + } + + switch(display) + { + case DS_SAVE_LIST_CHOICE: + StartDraw(); + DisplayTitle("Save"); + + // TODO : use focus for selected save by default, and don't modify global selected save,use local var + DisplaySaveList(); + DisplaySaveDataInfo1(); + + // TODO : Dialogs should take control over input and not send them to the game while displaying + DisplayEnterBack(); + if (IsButtonPressed(cancelButtonFlag)) + { + status = SCE_UTILITY_STATUS_FINISHED; + param.GetPspParam()->result = SCE_UTILITY_DIALOG_RESULT_CANCEL; + } + 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(); + DisplayTitle("Save"); + + DisplaySaveIcon(); + DisplaySaveDataInfo2(); + + DisplayConfirmationYesNo("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(); + DisplayTitle("Save"); + + DisplaySaveIcon(); + DisplaySaveDataInfo2(); + + DisplayInfo("Saving\nPlease Wait..."); + + EndDraw(); + break; + case DS_SAVE_DONE: + StartDraw(); + DisplayTitle("Save"); + + DisplaySaveIcon(); + DisplaySaveDataInfo2(); + DisplayBack(); + + DisplayInfo("Save completed"); + + if (IsButtonPressed(cancelButtonFlag)) + { + status = SCE_UTILITY_STATUS_FINISHED; + param.GetPspParam()->result = SCE_UTILITY_DIALOG_RESULT_SUCCESS; + // Set the save to use for autosave and autoload + param.SetSelectedSave(param.GetFileInfo(currentSelectedSave).idx); + } + + EndDraw(); + break; + + case DS_LOAD_LIST_CHOICE: + StartDraw(); + DisplayTitle("Load"); + DisplaySaveList(); + DisplaySaveDataInfo1(); + + // TODO : Dialogs should take control over input and not send them to the game while displaying + DisplayEnterBack(); + if (IsButtonPressed(cancelButtonFlag)) + { + status = SCE_UTILITY_STATUS_FINISHED; + param.GetPspParam()->result = SCE_UTILITY_DIALOG_RESULT_CANCEL; + } + 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(); + DisplayTitle("Load"); + + DisplaySaveIcon(); + DisplaySaveDataInfo2(); + + DisplayInfo("Loading\nPlease Wait..."); + + EndDraw(); + break; + case DS_LOAD_DONE: + StartDraw(); + DisplayTitle("Load"); + + DisplaySaveIcon(); + DisplaySaveDataInfo2(); + DisplayBack(); + + DisplayInfo("Load completed"); + + if (IsButtonPressed(cancelButtonFlag)) + { + status = SCE_UTILITY_STATUS_FINISHED; + param.GetPspParam()->result = SCE_UTILITY_DIALOG_RESULT_SUCCESS; + // Set the save to use for autosave and autoload + param.SetSelectedSave(param.GetFileInfo(currentSelectedSave).idx); + } + + EndDraw(); + break; + case DS_LOAD_NODATA: + StartDraw(); + DisplayTitle("Load"); + + DisplayBack(); + + DisplayInfo("There is no data"); + + if (IsButtonPressed(cancelButtonFlag)) + { + status = SCE_UTILITY_STATUS_FINISHED; + param.GetPspParam()->result = SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA; + } + + EndDraw(); + break; + + case DS_DELETE_LIST_CHOICE: + StartDraw(); + DisplayTitle("Delete"); + DisplaySaveList(); + DisplaySaveDataInfo1(); + + // TODO : Dialogs should take control over input and not send them to the game while displaying + DisplayEnterBack(); + if (IsButtonPressed(cancelButtonFlag)) + { + status = SCE_UTILITY_STATUS_FINISHED; + param.GetPspParam()->result = SCE_UTILITY_DIALOG_RESULT_CANCEL; + } + else if (IsButtonPressed(okButtonFlag)) + { + yesnoChoice = 0; + display = DS_DELETE_CONFIRM; + } + + EndDraw(); + break; + case DS_DELETE_CONFIRM: + StartDraw(); + DisplayTitle("Delete"); + + DisplaySaveIcon(); + DisplaySaveDataInfo2(); + + DisplayConfirmationYesNo("The 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(); + DisplayTitle("Delete"); + + DisplayInfo("Deleting\nPlease Wait..."); + + EndDraw(); + break; + case DS_DELETE_DONE: + StartDraw(); + DisplayTitle("Delete"); + + DisplayBack(); + + DisplayInfo("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(); + DisplayTitle("Delete"); + + DisplayBack(); + + DisplayInfo("There is no data"); + + if (IsButtonPressed(cancelButtonFlag)) + { + status = SCE_UTILITY_STATUS_FINISHED; + param.GetPspParam()->result = SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_DATA; + } + + 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: + param.Save(param.GetPspParam(),param.GetSelectedSave()); + status = SCE_UTILITY_STATUS_FINISHED; + return; + break; + case SCE_UTILITY_SAVEDATA_TYPE_SAVE: // Only save and exit + case SCE_UTILITY_SAVEDATA_TYPE_AUTOSAVE: + param.Load(param.GetPspParam(),param.GetSelectedSave()); + status = SCE_UTILITY_STATUS_FINISHED; + return; + break; + default: + status = SCE_UTILITY_STATUS_FINISHED; + return; + break; + } + } + break; + default: + status = SCE_UTILITY_STATUS_FINISHED; + return; + break; + } + + lastButtons = buttons; + + +} + +void PSPSaveDialog::Shutdown() +{ + PSPDialog::Shutdown(); + param.SetPspParam(0); +} + diff --git a/Core/Dialog/PSPSaveDialog.h b/Core/Dialog/PSPSaveDialog.h new file mode 100644 index 0000000000..b5b5c55d86 --- /dev/null +++ b/Core/Dialog/PSPSaveDialog.h @@ -0,0 +1,114 @@ +// Copyright (c) 2012- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#pragma once + +#include "PSPDialog.h" +#include "SavedataParam.h" + +#define SCE_UTILITY_SAVEDATA_ERROR_TYPE (0x80110300) + +#define SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_MS (0x80110301) +#define SCE_UTILITY_SAVEDATA_ERROR_LOAD_EJECT_MS (0x80110302) +#define SCE_UTILITY_SAVEDATA_ERROR_LOAD_ACCESS_ERROR (0x80110305) +#define SCE_UTILITY_SAVEDATA_ERROR_LOAD_DATA_BROKEN (0x80110306) +#define SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA (0x80110307) +#define SCE_UTILITY_SAVEDATA_ERROR_LOAD_PARAM (0x80110308) +#define SCE_UTILITY_SAVEDATA_ERROR_LOAD_INTERNAL (0x8011030b) + +#define SCE_UTILITY_SAVEDATA_ERROR_SAVE_NO_MS (0x80110381) +#define SCE_UTILITY_SAVEDATA_ERROR_SAVE_EJECT_MS (0x80110382) +#define SCE_UTILITY_SAVEDATA_ERROR_SAVE_MS_NOSPACE (0x80110383) +#define SCE_UTILITY_SAVEDATA_ERROR_SAVE_MS_PROTECTED (0x80110384) +#define SCE_UTILITY_SAVEDATA_ERROR_SAVE_ACCESS_ERROR (0x80110385) +#define SCE_UTILITY_SAVEDATA_ERROR_SAVE_PARAM (0x80110388) +#define SCE_UTILITY_SAVEDATA_ERROR_SAVE_NO_UMD (0x80110389) +#define SCE_UTILITY_SAVEDATA_ERROR_SAVE_WRONG_UMD (0x8011038a) +#define SCE_UTILITY_SAVEDATA_ERROR_SAVE_INTERNAL (0x8011038b) + +#define SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_MS (0x80110341) +#define SCE_UTILITY_SAVEDATA_ERROR_DELETE_EJECT_MS (0x80110342) +#define SCE_UTILITY_SAVEDATA_ERROR_DELETE_MS_PROTECTED (0x80110344) +#define SCE_UTILITY_SAVEDATA_ERROR_DELETE_ACCESS_ERROR (0x80110345) +#define SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_DATA (0x80110347) +#define SCE_UTILITY_SAVEDATA_ERROR_DELETE_PARAM (0x80110348) +#define SCE_UTILITY_SAVEDATA_ERROR_DELETE_INTERNAL (0x8011034b) + +#define SCE_UTILITY_SAVEDATA_ERROR_SIZES_NO_MS (0x801103C1) +#define SCE_UTILITY_SAVEDATA_ERROR_SIZES_EJECT_MS (0x801103C2) +#define SCE_UTILITY_SAVEDATA_ERROR_SIZES_ACCESS_ERROR (0x801103C5) +#define SCE_UTILITY_SAVEDATA_ERROR_SIZES_NO_DATA (0x801103C7) +#define SCE_UTILITY_SAVEDATA_ERROR_SIZES_PARAM (0x801103C8) +#define SCE_UTILITY_SAVEDATA_ERROR_SIZES_NO_UMD (0x801103C9) +#define SCE_UTILITY_SAVEDATA_ERROR_SIZES_WRONG_UMD (0x801103Ca) +#define SCE_UTILITY_SAVEDATA_ERROR_SIZES_INTERNAL (0x801103Cb) + +class PSPSaveDialog: public PSPDialog { +public: + PSPSaveDialog(); + virtual ~PSPSaveDialog(); + + virtual void Init(int paramAddr); + virtual void Update(); + void Shutdown(); + +private : + + void DisplaySaveList(bool canMove = true); + void DisplaySaveIcon(); + void DisplayTitle(std::string name); + void DisplayEnterBack(); + void DisplayBack(); + void DisplaySaveDataInfo1(); + void DisplaySaveDataInfo2(); + void DisplayConfirmationYesNo(std::string text); + void DisplayInfo(std::string text); + + enum DisplayState + { + DS_NONE, + + DS_SAVE_LIST_CHOICE, + DS_SAVE_CONFIRM_OVERWRITE, + DS_SAVE_SAVING, + DS_SAVE_DONE, + + DS_LOAD_LIST_CHOICE, + DS_LOAD_LOADING, + DS_LOAD_DONE, + DS_LOAD_NODATA, + + DS_DELETE_LIST_CHOICE, + DS_DELETE_CONFIRM, + DS_DELETE_DELETING, + DS_DELETE_DONE, + DS_DELETE_NODATA + }; + + DisplayState display; + + SavedataParam param; + int currentSelectedSave; + + int yesnoChoice; + + int okButtonImg; + int cancelButtonImg; + int okButtonFlag; + int cancelButtonFlag; +}; + diff --git a/Core/Dialog/SavedataParam.cpp b/Core/Dialog/SavedataParam.cpp new file mode 100644 index 0000000000..98ec53dbdd --- /dev/null +++ b/Core/Dialog/SavedataParam.cpp @@ -0,0 +1,278 @@ +// Copyright (c) 2012- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#include "SavedataParam.h" +#include "../System.h" + +std::string icon0Name = "ICON0.PNG"; +std::string icon1Name = "ICON1.PNG"; +std::string pic1Name = "PIC1.PNG"; +std::string sfoName = "PARAM.SFO"; + +std::string savePath = "ms0://PSP/SAVEDATA/"; + +SavedataParam::SavedataParam() + : pspParam(0) + , selectedSave(0) + , saveNameListData(0) + , saveDataList(0) + , saveNameListDataCount(0) +{ + +} + +void SavedataParam::Init() +{ + if(!pspFileSystem.GetFileInfo(savePath).exists) + { + pspFileSystem.MkDir(savePath); + } +} + + +std::string SavedataParam::GetSaveFilePath(SceUtilitySavedataParam* param, int saveId) +{ + if (!param) { + return ""; + } + + std::string dirPath = std::string(param->gameName)+param->saveName; + if(saveId >= 0 && saveNameListDataCount > 0) // if user selection, use it + dirPath = std::string(param->gameName)+GetFilename(saveId); + + return savePath + dirPath; +} + + +bool SavedataParam::Delete(SceUtilitySavedataParam* param, int saveId) +{ + if (!param) + { + return false; + } + + std::string dirPath = GetSaveFilePath(param,saveId); + if(saveId >= 0 && saveNameListDataCount > 0) // if user selection, use it + { + if(saveDataList[saveId].size == 0) // don't delete no existing file + { + return false; + } + } + + pspFileSystem.RmDir(dirPath); + return true; +} + +bool SavedataParam::Save(SceUtilitySavedataParam* param, int saveId) +{ + if (!param) { + return false; + } + + u8* data_ = (u8*)Memory::GetPointer(*((unsigned int*)¶m->dataBuf)); + + std::string dirPath = GetSaveFilePath(param, saveId); + + if(!pspFileSystem.GetFileInfo(dirPath).exists) + pspFileSystem.MkDir(dirPath); + + std::string filePath = dirPath+"/"+param->fileName; + INFO_LOG(HLE,"Saving file with size %u in %s",param->dataBufSize,filePath.c_str()); + unsigned int handle = pspFileSystem.OpenFile(filePath,(FileAccess)(FILEACCESS_WRITE | FILEACCESS_CREATE)); + if(handle == 0) + { + ERROR_LOG(HLE,"Error opening file %s",filePath.c_str()); + return false; + } + if(!pspFileSystem.WriteFile(handle, data_, param->dataBufSize)) + { + pspFileSystem.CloseFile(handle); + ERROR_LOG(HLE,"Error writing file %s",filePath.c_str()); + return false; + } + else + { + pspFileSystem.CloseFile(handle); + + // TODO SAVE PARAM.SFO + /*data_ = (u8*)Memory::GetPointer(*((unsigned int*)¶m->dataBuf)); + writeDataToFile(false, );*/ + + // SAVE ICON0 + if(param->icon0FileData.buf) + { + data_ = (u8*)Memory::GetPointer(*((unsigned int*)¶m->icon0FileData.buf)); + std::string icon0path = dirPath+"/"+icon0Name; + handle = pspFileSystem.OpenFile(icon0path,(FileAccess)(FILEACCESS_WRITE | FILEACCESS_CREATE)); + if(handle) + { + pspFileSystem.WriteFile(handle, data_, param->icon0FileData.bufSize); + pspFileSystem.CloseFile(handle); + } + } + // SAVE ICON1 + if(param->icon1FileData.buf) + { + data_ = (u8*)Memory::GetPointer(*((unsigned int*)¶m->icon1FileData.buf)); + std::string icon1path = dirPath+"/"+icon1Name; + handle = pspFileSystem.OpenFile(icon1path,(FileAccess)(FILEACCESS_WRITE | FILEACCESS_CREATE)); + if(handle) + { + pspFileSystem.WriteFile(handle, data_, param->icon1FileData.bufSize); + pspFileSystem.CloseFile(handle); + } + } + // SAVE PIC1 + if(param->pic1FileData.buf) + { + data_ = (u8*)Memory::GetPointer(*((unsigned int*)¶m->pic1FileData.buf)); + std::string pic1path = dirPath+"/"+pic1Name; + handle = pspFileSystem.OpenFile(pic1path,(FileAccess)(FILEACCESS_WRITE | FILEACCESS_CREATE)); + if(handle) + { + pspFileSystem.WriteFile(handle, data_, param->pic1FileData.bufSize); + pspFileSystem.CloseFile(handle); + } + } + + // TODO Save SND + } + return true; +} + +bool SavedataParam::Load(SceUtilitySavedataParam* param, int saveId) +{ + if (!param) { + return false; + } + + u8* data_ = (u8*)Memory::GetPointer(*((unsigned int*)¶m->dataBuf)); + + std::string dirPath = GetSaveFilePath(param, saveId); + if(saveId >= 0) // if user selection, use it + { + if(saveDataList[saveId].size == 0) // don't read no existing file + { + return false; + } + } + + std::string filePath = dirPath+"/"+param->fileName; + INFO_LOG(HLE,"Loading file with size %u in %s",param->dataBufSize,filePath.c_str()); + u32 handle = pspFileSystem.OpenFile(filePath,FILEACCESS_READ); + if(!handle) + { + ERROR_LOG(HLE,"Error opening file %s",filePath.c_str()); + return false; + } + if(!pspFileSystem.ReadFile(handle, data_, param->dataBufSize)) + { + ERROR_LOG(HLE,"Error reading file %s",filePath.c_str()); + return false; + } + return true; +} + +void SavedataParam::SetPspParam(SceUtilitySavedataParam* param) +{ + pspParam = param; + if(!pspParam) return; + + bool listEmptyFile = true; + if(param->mode == SCE_UTILITY_SAVEDATA_TYPE_LISTLOAD || + param->mode == SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE) + { + listEmptyFile = false; + } + + if(param->saveNameList != 0) + { + saveNameListData = (char(*)[20])Memory::GetPointer(param->saveNameList); + + // Get number of fileName in array + int count = 0; + do + { + count++; + } while(saveNameListData[count][0] != 0); + + if(saveDataList) + delete[] saveDataList; + saveDataList = new SaveFileInfo[count]; + + // get and stock file info for each file + int realCount = 0; + for(int i = 0; i gameName+saveNameListData[i]+"/"+param->fileName; + PSPFileInfo info = pspFileSystem.GetFileInfo(fileDataPath); + if(info.exists) + { + // TODO : Load PARAM.SFO when saved and save title and save info + saveDataList[realCount].size = info.size; + saveDataList[realCount].saveName = saveNameListData[i]; + saveDataList[realCount].idx = i; + DEBUG_LOG(HLE,"%s Exist",fileDataPath.c_str()); + realCount++; + } + else + { + if(listEmptyFile) + { + saveDataList[realCount].size = 0; + saveDataList[realCount].saveName = saveNameListData[i]; + saveDataList[realCount].idx = i; + DEBUG_LOG(HLE,"Don't Exist"); + realCount++; + } + } + } + saveNameListDataCount = realCount; + } +} + +SceUtilitySavedataParam* SavedataParam::GetPspParam() +{ + return pspParam; +} + +int SavedataParam::GetFilenameCount() +{ + return saveNameListDataCount; +} + +const SaveFileInfo& SavedataParam::GetFileInfo(int idx) +{ + return saveDataList[idx]; +} +char* SavedataParam::GetFilename(int idx) +{ + return saveDataList[idx].saveName; +} + +int SavedataParam::GetSelectedSave() +{ + return selectedSave; +} +void SavedataParam::SetSelectedSave(int idx) +{ + selectedSave = idx; +} + diff --git a/Core/Dialog/SavedataParam.h b/Core/Dialog/SavedataParam.h new file mode 100644 index 0000000000..0fcd1439ba --- /dev/null +++ b/Core/Dialog/SavedataParam.h @@ -0,0 +1,133 @@ +// Copyright (c) 2012- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#pragma once + +#include "../HLE/sceKernel.h" + + +enum SceUtilitySavedataType +{ + SCE_UTILITY_SAVEDATA_TYPE_AUTOLOAD = 0, + SCE_UTILITY_SAVEDATA_TYPE_AUTOSAVE = 1, + SCE_UTILITY_SAVEDATA_TYPE_LOAD = 2, + SCE_UTILITY_SAVEDATA_TYPE_SAVE = 3, + SCE_UTILITY_SAVEDATA_TYPE_LISTLOAD = 4, + SCE_UTILITY_SAVEDATA_TYPE_LISTSAVE = 5, + SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE = 6, + SCE_UTILITY_SAVEDATA_TYPE_DELETE = 7, + SCE_UTILITY_SAVEDATA_TYPE_SIZES = 8 +} ; + +// title, savedataTitle, detail: parts of the unencrypted SFO +// data, it contains what the VSH and standard load screen shows +struct PspUtilitySavedataSFOParam +{ + char title[0x80]; + char savedataTitle[0x80]; + char detail[0x400]; + unsigned char parentalLevel; + unsigned char unknown[3]; +}; + +struct PspUtilitySavedataFileData { + int buf; + SceSize bufSize; // Size of the buffer pointed to by buf + SceSize size; // Actual file size to write / was read + int unknown; +}; + +// Structure to hold the parameters for the sceUtilitySavedataInitStart function. +struct SceUtilitySavedataParam +{ + SceSize size; // Size of the structure + + int language; + + int buttonSwap; + + int unknown[4]; + int result; + int unknown2[4]; + + int mode; // 0 to load, 1 to save + int bind; + + int overwriteMode; // use 0x10 ? + + /** gameName: name used from the game for saves, equal for all saves */ + char gameName[13]; + char unused[3]; + /** saveName: name of the particular save, normally a number */ + char saveName[20]; + int saveNameList; + /** fileName: name of the data file of the game for example DATA.BIN */ + char fileName[13]; + char unused2[3]; + + /** pointer to a buffer that will contain data file unencrypted data */ + int dataBuf; // Initially void*, but void* in 64bit system take 8 bytes. + /** size of allocated space to dataBuf */ + SceSize dataBufSize; + SceSize dataSize; // Size of the actual save data + + PspUtilitySavedataSFOParam sfoParam; + + PspUtilitySavedataFileData icon0FileData; + PspUtilitySavedataFileData icon1FileData; + PspUtilitySavedataFileData pic1FileData; + PspUtilitySavedataFileData snd0FileData; + + unsigned char unknown17[4]; +}; + +struct SaveFileInfo +{ + int size; + char* saveName; + int idx; +}; + +class SavedataParam +{ +public: + static void Init(); + std::string GetSaveFilePath(SceUtilitySavedataParam* param, int saveId = -1); + bool Delete(SceUtilitySavedataParam* param, int saveId = -1); + bool Save(SceUtilitySavedataParam* param, int saveId = -1); + bool Load(SceUtilitySavedataParam* param, int saveId = -1); + + SavedataParam(); + + void SetPspParam(SceUtilitySavedataParam* param); + SceUtilitySavedataParam* GetPspParam(); + + int GetFilenameCount(); + const SaveFileInfo& GetFileInfo(int idx); + char* GetFilename(int idx); + + int GetSelectedSave(); + void SetSelectedSave(int idx); + +private: + SceUtilitySavedataParam* pspParam; + int selectedSave; + char (*saveNameListData)[20]; + SaveFileInfo* saveDataList; + int saveNameListDataCount; + +}; diff --git a/Core/HLE/sceUtility.cpp b/Core/HLE/sceUtility.cpp index dbc3d69210..6b4a7001eb 100644 --- a/Core/HLE/sceUtility.cpp +++ b/Core/HLE/sceUtility.cpp @@ -23,662 +23,45 @@ #include "sceUtility.h" #include "sceCtrl.h" -#include "../Config.h" #include "../Util/PPGeDraw.h" -#include "../System.h" +#include "../Dialog/PSPSaveDialog.h" +#include "../Dialog/PSPMsgDialog.h" +#include "../Dialog/PSPPlaceholderDialog.h" -enum SceUtilitySavedataType -{ - SCE_UTILITY_SAVEDATA_TYPE_AUTOLOAD = 0, - SCE_UTILITY_SAVEDATA_TYPE_AUTOSAVE = 1, - SCE_UTILITY_SAVEDATA_TYPE_LOAD = 2, - SCE_UTILITY_SAVEDATA_TYPE_SAVE = 3, - SCE_UTILITY_SAVEDATA_TYPE_LISTLOAD = 4, - SCE_UTILITY_SAVEDATA_TYPE_LISTSAVE = 5, - SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE = 6, - SCE_UTILITY_SAVEDATA_TYPE_DELETE = 7, - SCE_UTILITY_SAVEDATA_TYPE_SIZES = 8 -} ; - -#define SCE_UTILITY_SAVEDATA_ERROR_TYPE (0x80110300) - -#define SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_MS (0x80110301) -#define SCE_UTILITY_SAVEDATA_ERROR_LOAD_EJECT_MS (0x80110302) -#define SCE_UTILITY_SAVEDATA_ERROR_LOAD_ACCESS_ERROR (0x80110305) -#define SCE_UTILITY_SAVEDATA_ERROR_LOAD_DATA_BROKEN (0x80110306) -#define SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA (0x80110307) -#define SCE_UTILITY_SAVEDATA_ERROR_LOAD_PARAM (0x80110308) -#define SCE_UTILITY_SAVEDATA_ERROR_LOAD_INTERNAL (0x8011030b) - -#define SCE_UTILITY_SAVEDATA_ERROR_SAVE_NO_MS (0x80110381) -#define SCE_UTILITY_SAVEDATA_ERROR_SAVE_EJECT_MS (0x80110382) -#define SCE_UTILITY_SAVEDATA_ERROR_SAVE_MS_NOSPACE (0x80110383) -#define SCE_UTILITY_SAVEDATA_ERROR_SAVE_MS_PROTECTED (0x80110384) -#define SCE_UTILITY_SAVEDATA_ERROR_SAVE_ACCESS_ERROR (0x80110385) -#define SCE_UTILITY_SAVEDATA_ERROR_SAVE_PARAM (0x80110388) -#define SCE_UTILITY_SAVEDATA_ERROR_SAVE_NO_UMD (0x80110389) -#define SCE_UTILITY_SAVEDATA_ERROR_SAVE_WRONG_UMD (0x8011038a) -#define SCE_UTILITY_SAVEDATA_ERROR_SAVE_INTERNAL (0x8011038b) - -#define SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_MS (0x80110341) -#define SCE_UTILITY_SAVEDATA_ERROR_DELETE_EJECT_MS (0x80110342) -#define SCE_UTILITY_SAVEDATA_ERROR_DELETE_MS_PROTECTED (0x80110344) -#define SCE_UTILITY_SAVEDATA_ERROR_DELETE_ACCESS_ERROR (0x80110345) -#define SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_DATA (0x80110347) -#define SCE_UTILITY_SAVEDATA_ERROR_DELETE_PARAM (0x80110348) -#define SCE_UTILITY_SAVEDATA_ERROR_DELETE_INTERNAL (0x8011034b) - -#define SCE_UTILITY_SAVEDATA_ERROR_SIZES_NO_MS (0x801103C1) -#define SCE_UTILITY_SAVEDATA_ERROR_SIZES_EJECT_MS (0x801103C2) -#define SCE_UTILITY_SAVEDATA_ERROR_SIZES_ACCESS_ERROR (0x801103C5) -#define SCE_UTILITY_SAVEDATA_ERROR_SIZES_NO_DATA (0x801103C7) -#define SCE_UTILITY_SAVEDATA_ERROR_SIZES_PARAM (0x801103C8) -#define SCE_UTILITY_SAVEDATA_ERROR_SIZES_NO_UMD (0x801103C9) -#define SCE_UTILITY_SAVEDATA_ERROR_SIZES_WRONG_UMD (0x801103Ca) -#define SCE_UTILITY_SAVEDATA_ERROR_SIZES_INTERNAL (0x801103Cb) - -#define SCE_UTILITY_STATUS_NONE 0 -#define SCE_UTILITY_STATUS_INITIALIZE 1 -#define SCE_UTILITY_STATUS_RUNNING 2 -#define SCE_UTILITY_STATUS_FINISHED 3 -#define SCE_UTILITY_STATUS_SHUTDOWN 4 - - -// title, savedataTitle, detail: parts of the unencrypted SFO -// data, it contains what the VSH and standard load screen shows -struct PspUtilitySavedataSFOParam -{ - char title[0x80]; - char savedataTitle[0x80]; - char detail[0x400]; - unsigned char parentalLevel; - unsigned char unknown[3]; -}; - -struct PspUtilitySavedataFileData { - int buf; - SceSize bufSize; // Size of the buffer pointed to by buf - SceSize size; // Actual file size to write / was read - int unknown; -}; - -// Structure to hold the parameters for the sceUtilitySavedataInitStart function. -struct SceUtilitySavedataParam -{ - SceSize size; // Size of the structure - - int language; - - int buttonSwap; - - int unknown[4]; - int result; - int unknown2[4]; - - int mode; // 0 to load, 1 to save - int bind; - - int overwriteMode; // use 0x10 ? - - /** gameName: name used from the game for saves, equal for all saves */ - char gameName[13]; - char unused[3]; - /** saveName: name of the particular save, normally a number */ - char saveName[20]; - int saveNameList; - /** fileName: name of the data file of the game for example DATA.BIN */ - char fileName[13]; - char unused2[3]; - - /** pointer to a buffer that will contain data file unencrypted data */ - int dataBuf; // Initially void*, but void* in 64bit system take 8 bytes. - /** size of allocated space to dataBuf */ - SceSize dataBufSize; - SceSize dataSize; // Size of the actual save data - - PspUtilitySavedataSFOParam sfoParam; - - PspUtilitySavedataFileData icon0FileData; - PspUtilitySavedataFileData icon1FileData; - PspUtilitySavedataFileData pic1FileData; - PspUtilitySavedataFileData snd0FileData; - - unsigned char unknown17[4]; -}; - -struct SaveFileInfo -{ - int size; -}; - -struct SaveDialogInfo -{ - int paramAddr; - int menuListSelection; - char (*saveNameListData)[20]; - SaveFileInfo (*saveDataList); - int saveNameListDataCount; -}; - - -static u32 utilityDialogState = SCE_UTILITY_STATUS_SHUTDOWN; -static u32 saveDataDialogState = SCE_UTILITY_STATUS_SHUTDOWN; -static u32 oskDialogState = SCE_UTILITY_STATUS_SHUTDOWN; -static u32 msgDialogState = SCE_UTILITY_STATUS_SHUTDOWN; - - -u32 messageDialogAddr; - -SaveDialogInfo saveDialogInfo; -std::string icon0Name = "ICON0.PNG"; -std::string icon1Name = "ICON1.PNG"; -std::string pic1Name = "PIC1.PNG"; -std::string sfoName = "PARAM.SFO"; - -std::string savePath = "ms0://PSP/SAVEDATA/"; +PSPSaveDialog saveDialog; +PSPMsgDialog msgDialog; +PSPPlaceholderDialog oskDialog; +PSPPlaceholderDialog netDialog; void __UtilityInit() { - messageDialogAddr = 0; - utilityDialogState = SCE_UTILITY_STATUS_SHUTDOWN; - saveDataDialogState = SCE_UTILITY_STATUS_SHUTDOWN; - oskDialogState = SCE_UTILITY_STATUS_SHUTDOWN; - msgDialogState = SCE_UTILITY_STATUS_SHUTDOWN; - - saveDialogInfo.paramAddr = 0; - saveDialogInfo.saveDataList = 0; - saveDialogInfo.menuListSelection = 0; - - if(!pspFileSystem.GetFileInfo(savePath).exists) - { - pspFileSystem.MkDir(savePath); - } - + + SavedataParam::Init(); } - -void __UtilityInitStart() -{ - utilityDialogState = SCE_UTILITY_STATUS_INITIALIZE; -} - -void __UtilityShutdownStart() -{ - utilityDialogState = SCE_UTILITY_STATUS_SHUTDOWN; -} - -void __UtilityUpdate() -{ - if (utilityDialogState == SCE_UTILITY_STATUS_INITIALIZE) - { - utilityDialogState = SCE_UTILITY_STATUS_RUNNING; - } - else if (utilityDialogState == SCE_UTILITY_STATUS_RUNNING) - { - utilityDialogState = SCE_UTILITY_STATUS_FINISHED; - } - else if (utilityDialogState == SCE_UTILITY_STATUS_FINISHED) - { - utilityDialogState = SCE_UTILITY_STATUS_SHUTDOWN; - } -} - -u32 __UtilityGetStatus() -{ - u32 ret = utilityDialogState; - if (utilityDialogState == SCE_UTILITY_STATUS_SHUTDOWN) - utilityDialogState = SCE_UTILITY_STATUS_NONE; - if (utilityDialogState == SCE_UTILITY_STATUS_INITIALIZE) - utilityDialogState = SCE_UTILITY_STATUS_RUNNING; - return ret; -} - - int sceUtilitySavedataInitStart(u32 paramAddr) { - saveDialogInfo.paramAddr = paramAddr; - SceUtilitySavedataParam *param = (SceUtilitySavedataParam*)Memory::GetPointer(saveDialogInfo.paramAddr); - - if(param->saveNameList != 0) - { - saveDialogInfo.saveNameListData = (char(*)[20])Memory::GetPointer(param->saveNameList); - - // Get number of fileName in array - int count = 0; - do - { - count++; - } while(saveDialogInfo.saveNameListData[count][0] != 0); - - if(saveDialogInfo.saveDataList) - delete[] saveDialogInfo.saveDataList; - saveDialogInfo.saveDataList = new SaveFileInfo[count]; - saveDialogInfo.saveNameListDataCount = count; - - // get and stock file info for each file - for(int i = 0; i gameName+saveDialogInfo.saveNameListData[i]+"/"+param->fileName; - PSPFileInfo info = pspFileSystem.GetFileInfo(fileDataPath); - if(info.exists) - { - // TODO : Load PARAM.SFO when saved and save title and save info - saveDialogInfo.saveDataList[i].size = info.size; - DEBUG_LOG(HLE,"%s Exist",fileDataPath.c_str()); - } - else - { - saveDialogInfo.saveDataList[i].size = 0; - DEBUG_LOG(HLE,"Don't Exist"); - } - } - } - - - DEBUG_LOG(HLE,"sceUtilitySavedataInitStart(%08x)", paramAddr); - DEBUG_LOG(HLE,"Mode: %i", param->mode); - messageDialogAddr = *((u32*)¶m); - switch(param->mode) - { - case SCE_UTILITY_SAVEDATA_TYPE_AUTOLOAD: - case SCE_UTILITY_SAVEDATA_TYPE_LISTLOAD: - case SCE_UTILITY_SAVEDATA_TYPE_LOAD: - { - DEBUG_LOG(HLE, "Loading. Title: %s Save: %s File: %s", param->gameName, param->saveName, param->fileName); - } - break; - case SCE_UTILITY_SAVEDATA_TYPE_AUTOSAVE: - case SCE_UTILITY_SAVEDATA_TYPE_SAVE: - case SCE_UTILITY_SAVEDATA_TYPE_LISTSAVE: - { - DEBUG_LOG(HLE, "Saving. Title: %s Save: %s File: %s", param->gameName, param->saveName, param->fileName); - } - break; - case SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE: - case SCE_UTILITY_SAVEDATA_TYPE_DELETE: - { - DEBUG_LOG(HLE, "Delete. Title: %s Save: %s File: %s", param->gameName, param->saveName, param->fileName); - } - break; - case SCE_UTILITY_SAVEDATA_TYPE_SIZES: - default: - { - ERROR_LOG(HLE, "Load/Save function %d not coded. Title: %s Save: %s File: %s", param->mode, param->gameName, param->saveName, param->fileName); - return 0; // Return 0 should allow the game to continue, but missing function must be implemented and returning the right value or the game can block. - } - break; - } - - saveDataDialogState = SCE_UTILITY_STATUS_INITIALIZE; - - - /*INFO_LOG(HLE,"Dump Param :"); - INFO_LOG(HLE,"size : %d",param->size); - INFO_LOG(HLE,"language : %d",param->language); - INFO_LOG(HLE,"buttonSwap : %d",param->buttonSwap); - INFO_LOG(HLE,"result : %d",param->result); - INFO_LOG(HLE,"mode : %d",param->mode); - INFO_LOG(HLE,"bind : %d",param->bind); - INFO_LOG(HLE,"overwriteMode : %d",param->overwriteMode); - INFO_LOG(HLE,"gameName : %s",param->gameName); - INFO_LOG(HLE,"saveName : %s",param->saveName); - INFO_LOG(HLE,"saveNameList : %08x",*((unsigned int*)¶m->saveNameList)); - INFO_LOG(HLE,"fileName : %s",param->fileName); - INFO_LOG(HLE,"dataBuf : %08x",*((unsigned int*)¶m->dataBuf)); - INFO_LOG(HLE,"dataBufSize : %u",param->dataBufSize); - INFO_LOG(HLE,"dataSize : %u",param->dataSize); - - INFO_LOG(HLE,"sfo title : %s",param->sfoParam.title); - INFO_LOG(HLE,"sfo savedataTitle : %s",param->sfoParam.savedataTitle); - INFO_LOG(HLE,"sfo detail : %s",param->sfoParam.detail); - - INFO_LOG(HLE,"icon0 data : %08x",*((unsigned int*)¶m->icon0FileData.buf)); - INFO_LOG(HLE,"icon0 size : %u",param->icon0FileData.bufSize); - - INFO_LOG(HLE,"icon1 data : %08x",*((unsigned int*)¶m->icon1FileData.buf)); - INFO_LOG(HLE,"icon1 size : %u",param->icon1FileData.bufSize); - - INFO_LOG(HLE,"pic1 data : %08x",*((unsigned int*)¶m->pic1FileData.buf)); - INFO_LOG(HLE,"pic1 size : %u",param->pic1FileData.bufSize); - - INFO_LOG(HLE,"snd0 data : %08x",*((unsigned int*)¶m->snd0FileData.buf)); - INFO_LOG(HLE,"snd0 size : %u",param->snd0FileData.bufSize);*/ - + saveDialog.Init(paramAddr); return 0; } int sceUtilitySavedataShutdownStart() { DEBUG_LOG(HLE,"sceUtilitySavedataShutdownStart()"); - - saveDataDialogState = SCE_UTILITY_STATUS_SHUTDOWN; - saveDialogInfo.paramAddr = 0; + saveDialog.Shutdown(); return 0; } int sceUtilitySavedataGetStatus() { - if (saveDataDialogState == SCE_UTILITY_STATUS_SHUTDOWN) - saveDataDialogState = SCE_UTILITY_STATUS_NONE; - if (saveDataDialogState == SCE_UTILITY_STATUS_INITIALIZE) - saveDataDialogState = SCE_UTILITY_STATUS_RUNNING; - u32 retval = saveDataDialogState; - DEBUG_LOG(HLE,"%i=sceUtilitySavedataGetStatus()", retval); - return retval; -} - -std::string GetSaveFilePath() -{ - if (!saveDialogInfo.paramAddr) { - return ""; - } - - SceUtilitySavedataParam *param = (SceUtilitySavedataParam*)Memory::GetPointer(saveDialogInfo.paramAddr); - - std::string dirPath = std::string(param->gameName)+param->saveName; - if(saveDialogInfo.saveNameListDataCount > 0) // if user selection, use it - dirPath = std::string(param->gameName)+saveDialogInfo.saveNameListData[saveDialogInfo.menuListSelection]; - - return savePath + dirPath; -} - -bool deleteSaveData() -{ - if (!saveDialogInfo.paramAddr) - { - return false; - } - SceUtilitySavedataParam *param = (SceUtilitySavedataParam*)Memory::GetPointer(saveDialogInfo.paramAddr); - - std::string dirPath = GetSaveFilePath(); - if(saveDialogInfo.saveNameListDataCount > 0) // if user selection, use it - { - if(saveDialogInfo.saveDataList[saveDialogInfo.menuListSelection].size == 0) // don't delete no existing file - { - return false; - } - } - - pspFileSystem.RmDir(dirPath); - return true; -} - -bool saveSaveData() -{ - if (!saveDialogInfo.paramAddr) { - return false; - } - - SceUtilitySavedataParam *param = (SceUtilitySavedataParam*)Memory::GetPointer(saveDialogInfo.paramAddr); - u8* data_ = (u8*)Memory::GetPointer(*((unsigned int*)¶m->dataBuf)); - - std::string dirPath = GetSaveFilePath(); - - if(!pspFileSystem.GetFileInfo(dirPath).exists) - pspFileSystem.MkDir(dirPath); - - std::string filePath = dirPath+"/"+param->fileName; - INFO_LOG(HLE,"Saving file with size %u in %s",param->dataBufSize,filePath.c_str()); - unsigned int handle = pspFileSystem.OpenFile(filePath,(FileAccess)(FILEACCESS_WRITE | FILEACCESS_CREATE)); - if(handle == 0) - { - ERROR_LOG(HLE,"Error opening file %s",filePath.c_str()); - return false; - } - if(!pspFileSystem.WriteFile(handle, data_, param->dataBufSize)) - { - pspFileSystem.CloseFile(handle); - ERROR_LOG(HLE,"Error writing file %s",filePath.c_str()); - return false; - } - else - { - pspFileSystem.CloseFile(handle); - - // TODO SAVE PARAM.SFO - /*data_ = (u8*)Memory::GetPointer(*((unsigned int*)¶m->dataBuf)); - writeDataToFile(false, );*/ - - // SAVE ICON0 - if(param->icon0FileData.buf) - { - data_ = (u8*)Memory::GetPointer(*((unsigned int*)¶m->icon0FileData.buf)); - std::string icon0path = dirPath+"/"+icon0Name; - handle = pspFileSystem.OpenFile(icon0path,(FileAccess)(FILEACCESS_WRITE | FILEACCESS_CREATE)); - if(handle) - { - pspFileSystem.WriteFile(handle, data_, param->icon0FileData.bufSize); - pspFileSystem.CloseFile(handle); - } - } - // SAVE ICON1 - if(param->icon1FileData.buf) - { - data_ = (u8*)Memory::GetPointer(*((unsigned int*)¶m->icon1FileData.buf)); - std::string icon1path = dirPath+"/"+icon1Name; - handle = pspFileSystem.OpenFile(icon1path,(FileAccess)(FILEACCESS_WRITE | FILEACCESS_CREATE)); - if(handle) - { - pspFileSystem.WriteFile(handle, data_, param->icon1FileData.bufSize); - pspFileSystem.CloseFile(handle); - } - } - // SAVE PIC1 - if(param->pic1FileData.buf) - { - data_ = (u8*)Memory::GetPointer(*((unsigned int*)¶m->pic1FileData.buf)); - std::string pic1path = dirPath+"/"+pic1Name; - handle = pspFileSystem.OpenFile(pic1path,(FileAccess)(FILEACCESS_WRITE | FILEACCESS_CREATE)); - if(handle) - { - pspFileSystem.WriteFile(handle, data_, param->pic1FileData.bufSize); - pspFileSystem.CloseFile(handle); - } - } - - // TODO Save SND - } - return true; -} - -bool loadSaveData() -{ - if (!saveDialogInfo.paramAddr) { - return false; - } - SceUtilitySavedataParam *param = (SceUtilitySavedataParam*)Memory::GetPointer(saveDialogInfo.paramAddr); - - u8* data_ = (u8*)Memory::GetPointer(*((unsigned int*)¶m->dataBuf)); - - std::string dirPath = GetSaveFilePath(); - if(saveDialogInfo.saveNameListDataCount > 0) // if user selection, use it - { - if(saveDialogInfo.saveDataList[saveDialogInfo.menuListSelection].size == 0) // don't read no existing file - { - return false; - } - } - - std::string filePath = dirPath+"/"+param->fileName; - INFO_LOG(HLE,"Loading file with size %u in %s",param->dataBufSize,filePath.c_str()); - u32 handle = pspFileSystem.OpenFile(filePath,FILEACCESS_READ); - if(!handle) - { - ERROR_LOG(HLE,"Error opening file %s",filePath.c_str()); - return false; - } - if(!pspFileSystem.ReadFile(handle, data_, param->dataBufSize)) - { - ERROR_LOG(HLE,"Error reading file %s",filePath.c_str()); - return false; - } - return true; + return saveDialog.GetStatus(); } void sceUtilitySavedataUpdate(u32 unknown) { DEBUG_LOG(HLE,"sceUtilitySavedataUpdate()"); - switch (saveDataDialogState) { - case SCE_UTILITY_STATUS_FINISHED: - saveDataDialogState = SCE_UTILITY_STATUS_SHUTDOWN; - break; - } - - if (saveDataDialogState != SCE_UTILITY_STATUS_RUNNING) - { - return; - } - if (!saveDialogInfo.paramAddr) { - saveDataDialogState = SCE_UTILITY_STATUS_SHUTDOWN; - return; - } - - SceUtilitySavedataParam *param = (SceUtilitySavedataParam*)Memory::GetPointer(saveDialogInfo.paramAddr); - - PPGeBegin(); - - PPGeDraw4Patch(I_BUTTON, 0, 0, 480, 272, 0xcFFFFFFF); - switch(param->mode) - { - case SCE_UTILITY_SAVEDATA_TYPE_LISTSAVE: - PPGeDrawText("Save List", 50, 50, PPGE_ALIGN_LEFT, 0.5f, 0xFFFFFFFF); - - for(int i = 0; i < saveDialogInfo.saveNameListDataCount; i++) - { - u32 color = 0xFFFFFFFF; - if(i == saveDialogInfo.menuListSelection) - color = 0xFF0000FF; - else - { - if(saveDialogInfo.saveDataList[i].size > 0) - color = 0xFFFFFFFF; - else - color = 0x888888FF; - } - PPGeDrawText(saveDialogInfo.saveNameListData[i], 70, 70+15*i, PPGE_ALIGN_LEFT, 0.5f, color); - } - - break; - case SCE_UTILITY_SAVEDATA_TYPE_LISTLOAD: - PPGeDrawText("Load List", 50, 50, PPGE_ALIGN_LEFT, 0.5f, 0xFFFFFFFF); - - for(int i = 0; i < saveDialogInfo.saveNameListDataCount; i++) - { - u32 color = 0xFFFFFFFF; - if(i == saveDialogInfo.menuListSelection) - color = 0xFF0000FF; - else - { - if(saveDialogInfo.saveDataList[i].size > 0) - color = 0xFFFFFFFF; - else - color = 0x888888FF; - } - PPGeDrawText(saveDialogInfo.saveNameListData[i], 70, 70+15*i, PPGE_ALIGN_LEFT, 0.5f, color); - } - break; - case SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE: - PPGeDrawText("Delete List", 50, 50, PPGE_ALIGN_LEFT, 0.5f, 0xFFFFFFFF); - - for(int i = 0; i < saveDialogInfo.saveNameListDataCount; i++) - { - u32 color = 0xFFFFFFFF; - if(i == saveDialogInfo.menuListSelection) - color = 0xFF0000FF; - else - { - if(saveDialogInfo.saveDataList[i].size > 0) - color = 0xFFFFFFFF; - else - color = 0x888888FF; - } - PPGeDrawText(saveDialogInfo.saveNameListData[i], 70, 70+15*i, PPGE_ALIGN_LEFT, 0.5f, color); - } - break; - case SCE_UTILITY_SAVEDATA_TYPE_LOAD: // Only load and exit - case SCE_UTILITY_SAVEDATA_TYPE_AUTOLOAD: - loadSaveData(); - saveDataDialogState = SCE_UTILITY_STATUS_FINISHED; - PPGeEnd(); - return; - case SCE_UTILITY_SAVEDATA_TYPE_SAVE: // Only save and exit - case SCE_UTILITY_SAVEDATA_TYPE_AUTOSAVE: - saveSaveData(); - saveDataDialogState = SCE_UTILITY_STATUS_FINISHED; - PPGeEnd(); - return; - case SCE_UTILITY_SAVEDATA_TYPE_DELETE: - deleteSaveData(); - saveDataDialogState = SCE_UTILITY_STATUS_FINISHED; - PPGeEnd(); - return; - default: - saveDataDialogState = SCE_UTILITY_STATUS_FINISHED; - PPGeEnd(); - return; - break; - } - - static u32 lastButtons = 0; - u32 buttons = __CtrlPeekButtons(); - - if(param->mode != SCE_UTILITY_SAVEDATA_TYPE_LISTLOAD || saveDialogInfo.saveDataList[saveDialogInfo.menuListSelection].size > 0) - { - PPGeDrawImage(I_CROSS, 50, 220, 0, 0xFFFFFFFF); - PPGeDrawText("OK", 100, 220, PPGE_ALIGN_LEFT, 1.0f, 0xFFFFFFFF); - } - PPGeDrawImage(I_CIRCLE, 300, 220, 0, 0xFFFFFFFF); - PPGeDrawText("Cancel", 350, 220, PPGE_ALIGN_LEFT, 1.0f, 0xFFFFFFFF); - if (!lastButtons) { - // param contain a variable buttonSwap. Probably need to use this for cross and circle button. - if (buttons & (CTRL_CIRCLE)) { - saveDataDialogState = SCE_UTILITY_STATUS_FINISHED; - param->result = SCE_UTILITY_SAVEDATA_ERROR_LOAD_PARAM; - } - else if (buttons & (CTRL_CROSS)) { - switch(param->mode) - { - case SCE_UTILITY_SAVEDATA_TYPE_LISTSAVE: - { - if(saveSaveData()) - { - saveDataDialogState = SCE_UTILITY_STATUS_FINISHED; - } - } - break; - - case SCE_UTILITY_SAVEDATA_TYPE_LISTLOAD: - { - if(loadSaveData()) - { - saveDataDialogState = SCE_UTILITY_STATUS_FINISHED; - } - } - break; - case SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE: - if(deleteSaveData()) - { - saveDataDialogState = SCE_UTILITY_STATUS_FINISHED; - } - break; - default: - break; - } - } - else if ((buttons & (CTRL_UP)) && saveDialogInfo.menuListSelection > 0) { - saveDialogInfo.menuListSelection--; - } - else if ((buttons & (CTRL_DOWN)) && saveDialogInfo.menuListSelection < (saveDialogInfo.saveNameListDataCount-1)) { - saveDialogInfo.menuListSelection++; - } - } - - lastButtons = buttons; - - PPGeEnd(); + saveDialog.Update(); return; } @@ -709,229 +92,80 @@ void sceUtilityLoadModule(u32 module) __KernelReSchedule("utilityloadmodule"); } -typedef struct -{ - unsigned int size; /** Size of the structure */ - int language; /** Language */ - int buttonSwap; /** Set to 1 for X/O button swap */ - int graphicsThread; /** Graphics thread priority */ - int accessThread; /** Access/fileio thread priority (SceJobThread) */ - int fontThread; /** Font thread priority (ScePafThread) */ - int soundThread; /** Sound thread priority */ - int result; /** Result */ - int reserved[4]; /** Set to 0 */ - -} pspUtilityDialogCommon; - -struct pspMessageDialog -{ - pspUtilityDialogCommon common; - int result; - int type; - u32 errorNum; - char string[512]; - u32 options; - u32 buttonPressed; // 0=?, 1=Yes, 2=No, 3=Back -}; - void sceUtilityMsgDialogInitStart(u32 structAddr) { DEBUG_LOG(HLE,"sceUtilityMsgDialogInitStart(%i)", structAddr); - if (!Memory::IsValidAddress(structAddr)) - { - RETURN(-1); - return; - } - messageDialogAddr = structAddr; - pspMessageDialog messageDialog; - Memory::ReadStruct(messageDialogAddr, &messageDialog); - if (messageDialog.type == 0) // number - { - INFO_LOG(HLE, "MsgDialog: %08x", messageDialog.errorNum); - } - else - { - INFO_LOG(HLE, "MsgDialog: %s", messageDialog.string); - } - //__UtilityInitStart(); - msgDialogState = SCE_UTILITY_STATUS_INITIALIZE; + msgDialog.Init(structAddr); } void sceUtilityMsgDialogShutdownStart(u32 unknown) { DEBUG_LOG(HLE,"FAKE sceUtilityMsgDialogShutdownStart(%i)", unknown); - //__UtilityShutdownStart(); - msgDialogState = SCE_UTILITY_STATUS_SHUTDOWN; - RETURN(0); + msgDialog.Shutdown(); } void sceUtilityMsgDialogUpdate(int animSpeed) { DEBUG_LOG(HLE,"sceUtilityMsgDialogUpdate(%i)", animSpeed); - - switch (msgDialogState) { - case SCE_UTILITY_STATUS_FINISHED: - msgDialogState = SCE_UTILITY_STATUS_SHUTDOWN; - break; - } - - if (msgDialogState != SCE_UTILITY_STATUS_RUNNING) - { - RETURN(0); - return; - } - - if (!Memory::IsValidAddress(messageDialogAddr)) { - ERROR_LOG(HLE, "sceUtilityMsgDialogUpdate: Bad messagedialogaddr %08x", messageDialogAddr); - RETURN(-1); - return; - } - - pspMessageDialog messageDialog; - Memory::ReadStruct(messageDialogAddr, &messageDialog); - const char *text; - if (messageDialog.type == 0) { - char temp[256]; - sprintf(temp, "Error code: %08x", messageDialog.errorNum); - text = temp; - } else { - text = messageDialog.string; - } - - PPGeBegin(); - - PPGeDraw4Patch(I_BUTTON, 0, 0, 480, 272, 0xcFFFFFFF); - PPGeDrawText(text, 50, 50, PPGE_ALIGN_LEFT, 0.5f, 0xFFFFFFFF); - - static u32 lastButtons = 0; - u32 buttons = __CtrlPeekButtons(); - - if (messageDialog.options & 0x10) // yesnobutton - { - PPGeDrawImage(I_CROSS, 80, 220, 0, 0xFFFFFFFF); - PPGeDrawText("Yes", 140, 220, PPGE_ALIGN_HCENTER, 1.0f, 0xFFFFFFFF); - PPGeDrawImage(I_CIRCLE, 200, 220, 0, 0xFFFFFFFF); - PPGeDrawText("No", 260, 220, PPGE_ALIGN_HCENTER, 1.0f, 0xFFFFFFFF); - PPGeDrawImage(I_TRIANGLE, 320, 220, 0, 0xcFFFFFFF); - PPGeDrawText("Back", 380, 220, PPGE_ALIGN_HCENTER, 1.0f, 0xcFFFFFFF); - if (!lastButtons) { - if (buttons & CTRL_TRIANGLE) { - messageDialog.buttonPressed = 3; // back - msgDialogState = SCE_UTILITY_STATUS_FINISHED; - } else if (buttons & CTRL_CROSS) { - messageDialog.buttonPressed = 1; - msgDialogState = SCE_UTILITY_STATUS_FINISHED; - } else if (buttons & CTRL_CIRCLE) { - messageDialog.buttonPressed = 2; - msgDialogState = SCE_UTILITY_STATUS_FINISHED; - } - } - } - else - { - PPGeDrawImage(I_CROSS, 150, 220, 0, 0xFFFFFFFF); - PPGeDrawText("OK", 480/2, 220, PPGE_ALIGN_HCENTER, 1.0f, 0xFFFFFFFF); - if (!lastButtons) { - if (buttons & (CTRL_CROSS | CTRL_CIRCLE)) { // accept both - messageDialog.buttonPressed = 1; - msgDialogState = SCE_UTILITY_STATUS_FINISHED; - } - } - } - - lastButtons = buttons; - - Memory::WriteStruct(messageDialogAddr, &messageDialog); - - PPGeEnd(); - - RETURN(0); + msgDialog.Update(); } u32 sceUtilityMsgDialogGetStatus() { - if (msgDialogState == SCE_UTILITY_STATUS_SHUTDOWN) - msgDialogState = SCE_UTILITY_STATUS_NONE; - if (msgDialogState == SCE_UTILITY_STATUS_INITIALIZE) - msgDialogState = SCE_UTILITY_STATUS_RUNNING; - u32 retval = msgDialogState; - DEBUG_LOG(HLE,"sceUtilityMsgDialogGetStatus()"); - return retval; + return msgDialog.GetStatus(); } // On screen keyboard -void sceUtilityOskInitStart() +int sceUtilityOskInitStart(unsigned int) { DEBUG_LOG(HLE,"FAKE sceUtilityOskInitStart(%i)", PARAM(0)); - //__UtilityInitStart(); - oskDialogState = SCE_UTILITY_STATUS_INITIALIZE; + oskDialog.Init(); + return 0; } -void sceUtilityOskShutdownStart() +int sceUtilityOskShutdownStart() { DEBUG_LOG(HLE,"FAKE sceUtilityOskShutdownStart(%i)", PARAM(0)); - //__UtilityShutdownStart(); - oskDialogState = SCE_UTILITY_STATUS_SHUTDOWN; - RETURN(0); + oskDialog.Shutdown(); + return 0; } -void sceUtilityOskUpdate() +void sceUtilityOskUpdate(unsigned int unknown) { - DEBUG_LOG(HLE,"FAKE sceUtilityOskUpdate(%i)", PARAM(0)); - //__UtilityUpdate(); - if (oskDialogState == SCE_UTILITY_STATUS_INITIALIZE) - { - oskDialogState = SCE_UTILITY_STATUS_RUNNING; - } - else if (oskDialogState == SCE_UTILITY_STATUS_RUNNING) - { - oskDialogState = SCE_UTILITY_STATUS_FINISHED; - } - else if (oskDialogState == SCE_UTILITY_STATUS_FINISHED) - { - oskDialogState = SCE_UTILITY_STATUS_SHUTDOWN; - } - RETURN(0); + DEBUG_LOG(HLE,"FAKE sceUtilityOskUpdate(%i)", unknown); + oskDialog.Update(); } -void sceUtilityOskGetStatus() +int sceUtilityOskGetStatus() { - if (oskDialogState == SCE_UTILITY_STATUS_SHUTDOWN) - oskDialogState = SCE_UTILITY_STATUS_NONE; - if (oskDialogState == SCE_UTILITY_STATUS_INITIALIZE) - oskDialogState = SCE_UTILITY_STATUS_RUNNING; - u32 retval = msgDialogState; - DEBUG_LOG(HLE,"sceUtilityOskGetStatus()"); - RETURN(retval); + return oskDialog.GetStatus(); } -void sceUtilityNetconfInitStart() +void sceUtilityNetconfInitStart(unsigned int unknown) { - DEBUG_LOG(HLE,"FAKE sceUtilityNetconfInitStart(%i)", PARAM(0)); - __UtilityInitStart(); + DEBUG_LOG(HLE,"FAKE sceUtilityNetconfInitStart(%i)", unknown); + netDialog.Init(); } -void sceUtilityNetconfShutdownStart() +void sceUtilityNetconfShutdownStart(unsigned int unknown) { - DEBUG_LOG(HLE,"FAKE sceUtilityNetconfShutdownStart(%i)", PARAM(0)); - __UtilityShutdownStart(); - RETURN(0); + DEBUG_LOG(HLE,"FAKE sceUtilityNetconfShutdownStart(%i)", unknown); + netDialog.Shutdown(); } -void sceUtilityNetconfUpdate() +void sceUtilityNetconfUpdate(int unknown) { - DEBUG_LOG(HLE,"FAKE sceUtilityNetconfUpdate(%i)", PARAM(0)); - __UtilityUpdate(); - RETURN(0); + DEBUG_LOG(HLE,"FAKE sceUtilityNetconfUpdate(%i)", unknown); + netDialog.Update(); } -void sceUtilityNetconfGetStatus() +unsigned int sceUtilityNetconfGetStatus() { DEBUG_LOG(HLE,"sceUtilityNetconfGetStatus()"); - RETURN(__UtilityGetStatus()); + return netDialog.GetStatus(); } int sceUtilityScreenshotGetStatus() @@ -1084,10 +318,10 @@ u32 sceUtilityLoadNetModule(u32 module) const HLEFunction sceUtility[] = { {0x1579a159, &WrapU_U, "sceUtilityLoadNetModule"}, - {0xf88155f6, sceUtilityNetconfShutdownStart, "sceUtilityNetconfShutdownStart"}, - {0x4db1e739, sceUtilityNetconfInitStart, "sceUtilityNetconfInitStart"}, - {0x91e70e35, sceUtilityNetconfUpdate, "sceUtilityNetconfUpdate"}, - {0x6332aa39, sceUtilityNetconfGetStatus, "sceUtilityNetconfGetStatus"}, + {0xf88155f6, &WrapV_U, "sceUtilityNetconfShutdownStart"}, + {0x4db1e739, &WrapV_U, "sceUtilityNetconfInitStart"}, + {0x91e70e35, &WrapV_I, "sceUtilityNetconfUpdate"}, + {0x6332aa39, &WrapU_V, "sceUtilityNetconfGetStatus"}, {0x67af3428, &WrapV_U, "sceUtilityMsgDialogShutdownStart"}, {0x2ad8e239, &WrapV_U, "sceUtilityMsgDialogInitStart"}, @@ -1099,10 +333,10 @@ const HLEFunction sceUtility[] = {0xd4b95ffb, &WrapV_U, "sceUtilitySavedataUpdate"}, {0x8874dbe0, &WrapI_V, "sceUtilitySavedataGetStatus"}, - {0x3dfaeba9, sceUtilityOskShutdownStart, "sceUtilityOskShutdownStart"}, - {0xf6269b82, sceUtilityOskInitStart, "sceUtilityOskInitStart"}, - {0x4b85c861, sceUtilityOskUpdate, "sceUtilityOskUpdate"}, - {0xf3f76017, sceUtilityOskGetStatus, "sceUtilityOskGetStatus"}, + {0x3dfaeba9, &WrapI_V, "sceUtilityOskShutdownStart"}, + {0xf6269b82, &WrapI_U, "sceUtilityOskInitStart"}, + {0x4b85c861, &WrapV_U, "sceUtilityOskUpdate"}, + {0xf3f76017, &WrapI_V, "sceUtilityOskGetStatus"}, {0x41e30674, 0, "sceUtilitySetSystemParamString"}, {0x34b78343, &WrapU_UUU, "sceUtilityGetSystemParamString"}, diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index 9255bfc37f..904b36fcff 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -334,3 +334,15 @@ void PPGeDrawImage(int atlasImage, float x, float y, int align, u32 color) EndVertexDataAndDraw(GE_PRIM_RECTANGLES); } +void PPGeDrawImage(int atlasImage, float x, float y, float w, float h, int align, u32 color) +{ + if (!dlPtr) + return; + + const AtlasImage &img = ppge_atlas.images[atlasImage]; + BeginVertexData(); + Vertex(x, y, img.u1, img.v1, color); + Vertex(x + w, y + h, img.u2, img.v2, color); + EndVertexDataAndDraw(GE_PRIM_RECTANGLES); +} + diff --git a/Core/Util/PPGeDraw.h b/Core/Util/PPGeDraw.h index ef2644fac5..00765bc60d 100644 --- a/Core/Util/PPGeDraw.h +++ b/Core/Util/PPGeDraw.h @@ -67,4 +67,5 @@ void PPGeDraw4Patch(int atlasImage, float x, float y, float w, float h, u32 colo // Just blits an image to the screen, multiplied with the color. void PPGeDrawImage(int atlasImage, float x, float y, int align, u32 color = 0xFFFFFFFF); +void PPGeDrawImage(int atlasImage, float x, float y, float w, float h, int align, u32 color = 0xFFFFFFFF); diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 93e54df222..b691f6b076 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -95,6 +95,11 @@ LOCAL_SRC_FILES := \ $(SRC)/Core/PSPMixer.cpp \ $(SRC)/Core/Debugger/Breakpoints.cpp \ $(SRC)/Core/Debugger/SymbolMap.cpp \ + $(SRC)/Core/Dialog/PSPDialog.cpp \ + $(SRC)/Core/Dialog/PSPMsgDialog.cpp \ + $(SRC)/Core/Dialog/PSPPlaceholderDialog.cpp \ + $(SRC)/Core/Dialog/PSPSaveDialog.cpp \ + $(SRC)/Core/Dialog/SavedataParam.cpp \ $(SRC)/Core/HLE/HLETables.cpp \ $(SRC)/Core/HLE/HLE.cpp \ $(SRC)/Core/HLE/sceAtrac.cpp \