Add support for multiple disc.

This commit is contained in:
shenweip 2013-11-24 11:02:36 +08:00 committed by Henrik Rydgård
parent 326287a52e
commit 9814b1d6d2
5 changed files with 126 additions and 5 deletions

View File

@ -24,6 +24,9 @@
#include "Core/HLE/sceKernelThread.h"
#include "Core/HLE/sceKernelInterrupt.h"
#include "Core/HLE/KernelWaitHelpers.h"
#include "Core/FileSystems/BlockDevices.h"
#include "Core/FileSystems/ISOFileSystem.h"
#include "Core/FileSystems/VirtualDiscFileSystem.h"
const u64 MICRO_DELAY_ACTIVATE = 4000;
@ -36,6 +39,9 @@ static int umdStatChangeEvent = -1;
static std::vector<SceUID> umdWaitingThreads;
static std::map<SceUID, u64> umdPausedWaits;
extern IFileSystem* currentUMD;
bool UMDReplacePermit = false;
struct PspUmdInfo {
u32_le size;
u32_le type;
@ -266,7 +272,6 @@ u32 sceUmdRegisterUMDCallBack(u32 cbId)
// There's only ever one.
driveCBId = cbId;
}
DEBUG_LOG(SCEIO, "%d=sceUmdRegisterUMDCallback(id=%08x)", retVal, cbId);
return retVal;
}
@ -281,7 +286,6 @@ int sceUmdUnRegisterUMDCallBack(int cbId)
retVal = cbId;
driveCBId = -1;
}
DEBUG_LOG(SCEIO, "%08x=sceUmdUnRegisterUMDCallBack(id=%08x)", retVal, cbId);
return retVal;
}
@ -436,14 +440,42 @@ u32 sceUmdGetErrorStat()
return umdErrorStat;
}
void __UmdReplace(std::string filename) {
pspFileSystem.Unmount("umd0:", currentUMD);
pspFileSystem.Unmount("umd1:", currentUMD);
pspFileSystem.Unmount("disc0:", currentUMD);
pspFileSystem.Unmount("umd:", currentUMD);
IFileSystem* umd2;
PSPFileInfo info = pspFileSystem.GetFileInfo(filename);
if (info.type == FILETYPE_DIRECTORY) {
umd2 = new VirtualDiscFileSystem(&pspFileSystem, filename);
} else {
auto bd = constructBlockDevice(filename.c_str());
if (!bd)
return;
umd2 = new ISOFileSystem(&pspFileSystem, bd);
pspFileSystem.Mount("umd0:", umd2);
pspFileSystem.Mount("umd1:", umd2);
pspFileSystem.Mount("disc0:", umd2);
pspFileSystem.Mount("umd:", umd2);
}
currentUMD = umd2;
u32 notifyArg = PSP_UMD_PRESENT | PSP_UMD_READABLE | PSP_UMD_CHANGED;
if (driveCBId != -1)
__KernelNotifyCallback(driveCBId, notifyArg);
}
u32 sceUmdReplaceProhibit()
{
UMDReplacePermit = false;
DEBUG_LOG(SCEIO,"sceUmdReplaceProhibit()");
return 0;
}
u32 sceUmdReplacePermit()
{
UMDReplacePermit = true;
DEBUG_LOG(SCEIO,"sceUmdReplacePermit()");
return 0;
}

View File

@ -41,4 +41,6 @@ enum pspUmdType {
void __UmdInit();
void __UmdDoState(PointerWrap &p);
void __UmdReplace(std::string filename);
void Register_sceUmdUser();

View File

@ -42,6 +42,7 @@
#include "HLE/sceKernelMemory.h"
#include "ELF/ParamSFO.h"
IFileSystem* currentUMD;
// We gather the game info before actually loading/booting the ISO
// to determine if the emulator should enable extra memory and
// double-sized texture coordinates.
@ -72,6 +73,8 @@ void InitMemoryForGameISO(std::string fileToStart) {
pspFileSystem.Mount("umd1:", umd2);
pspFileSystem.Mount("disc0:", umd2);
pspFileSystem.Mount("umd:", umd2);
currentUMD = umd2;
std::string gameID;
std::string sfoPath("disc0:/PSP_GAME/PARAM.SFO");
@ -205,6 +208,7 @@ bool Load_PSP_ELF_PBP(const char *filename, std::string *error_string)
pspFileSystem.Mount("umd1:", umd2);
pspFileSystem.Mount("disc0:", umd2);
pspFileSystem.Mount("umd:", umd2);
currentUMD = umd2;
}
}

View File

@ -44,6 +44,8 @@
#include "GPU/GPUInterface.h"
#include "i18n/i18n.h"
#include "Core/HLE/sceUmd.h"
#ifdef _WIN32
#include "Windows/W32Util/ShellUtil.h"
#include "Windows/WndMainWindow.h"
@ -504,14 +506,14 @@ void MainScreen::CreateViews() {
if (vertical) {
root_ = new LinearLayout(ORIENT_VERTICAL);
rightColumn->ReplaceLayoutParams(new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT));
leftColumn->ReplaceLayoutParams(new LinearLayoutParams(1.0));
root_->Add(rightColumn);
leftColumn->ReplaceLayoutParams(new LinearLayoutParams(1.0));
root_->Add(rightColumn);
root_->Add(leftColumn);
} else {
root_ = new LinearLayout(ORIENT_HORIZONTAL);
leftColumn->ReplaceLayoutParams(new LinearLayoutParams(1.0));
rightColumn->ReplaceLayoutParams(new LinearLayoutParams(300, FILL_PARENT, actionMenuMargins));
root_->Add(leftColumn);
root_->Add(leftColumn);
root_->Add(rightColumn);
}
@ -703,6 +705,8 @@ GamePauseScreen::~GamePauseScreen() {
}
}
extern bool UMDReplacePermit;
void GamePauseScreen::CreateViews() {
static const int NUM_SAVESLOTS = 5;
@ -753,6 +757,9 @@ void GamePauseScreen::CreateViews() {
rightColumn->Add(rightColumnItems);
rightColumnItems->SetSpacing(0.0f);
if (UMDReplacePermit) {
rightColumnItems->Add(new Choice(i->T("Switch UMD")))->OnClick.Handle(this, &GamePauseScreen::OnSwitchUMD);
}
rightColumnItems->Add(new Choice(i->T("Continue")))->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
rightColumnItems->Add(new Choice(i->T("Game Settings")))->OnClick.Handle(this, &GamePauseScreen::OnGameSettings);
if (g_Config.bEnableCheats) {
@ -813,6 +820,11 @@ UI::EventReturn GamePauseScreen::OnCwCheat(UI::EventParams &e) {
return UI::EVENT_DONE;
}
UI::EventReturn GamePauseScreen::OnSwitchUMD(UI::EventParams &e) {
screenManager()->push(new UmdReplaceScreen());
return UI::EVENT_DONE;
}
void GamePauseScreen::sendMessage(const char *message, const char *value) {
// Since the language message isn't allowed to be in native, we have to have add this
// to every screen which directly inherits from UIScreen(which are few right now, luckily).
@ -820,3 +832,58 @@ void GamePauseScreen::sendMessage(const char *message, const char *value) {
screenManager()->RecreateAllViews();
}
}
void UmdReplaceScreen::CreateViews() {
I18NCategory *m = GetI18NCategory("MainMenu");
TabHolder *leftColumn = new TabHolder(ORIENT_HORIZONTAL, 64);
leftColumn->SetClip(true);
ScrollView *scrollRecentGames = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT));
ScrollView *scrollAllGames = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT));
GameBrowser *tabRecentGames = new GameBrowser(
"!RECENT", false, &g_Config.bGridView1, "", "",
new LinearLayoutParams(FILL_PARENT, FILL_PARENT));
GameBrowser *tabAllGames = new GameBrowser(g_Config.currentDirectory, true, &g_Config.bGridView2,
m->T("How to get games"), "http://www.ppsspp.org/getgames.html",
new LinearLayoutParams(FILL_PARENT, FILL_PARENT));
scrollRecentGames->Add(tabRecentGames);
scrollAllGames->Add(tabAllGames);
leftColumn->AddTab(m->T("Recent"), scrollRecentGames);
leftColumn->AddTab(m->T("Games"), scrollAllGames);
tabRecentGames->OnChoice.Handle(this, &UmdReplaceScreen::OnGameSelectedInstant);
tabAllGames->OnChoice.Handle(this, &UmdReplaceScreen::OnGameSelectedInstant);
tabRecentGames->OnHoldChoice.Handle(this, &UmdReplaceScreen::OnGameSelected);
tabAllGames->OnHoldChoice.Handle(this, &UmdReplaceScreen::OnGameSelected);
if (g_Config.recentIsos.size() > 0) {
leftColumn->SetCurrentTab(0);
}else{
leftColumn->SetCurrentTab(1);
}
root_ = new LinearLayout(ORIENT_HORIZONTAL);
leftColumn->ReplaceLayoutParams(new LinearLayoutParams(1.0));
root_->Add(leftColumn);
}
void UmdReplaceScreen::update(InputState &input) {
UpdateUIState(UISTATE_PAUSEMENU);
UIScreen::update(input);
}
UI::EventReturn UmdReplaceScreen::OnGameSelected(UI::EventParams &e) {
__UmdReplace(e.s);
screenManager()->finishDialog(this, DR_OK);
return UI::EVENT_DONE;
}
UI::EventReturn UmdReplaceScreen:: OnGameSelectedInstant(UI::EventParams &e) {
__UmdReplace(e.s);
screenManager()->finishDialog(this, DR_OK);
return UI::EVENT_DONE;
}

View File

@ -80,9 +80,25 @@ private:
UI::EventReturn OnStateSelected(UI::EventParams &e);
UI::EventReturn OnCwCheat(UI::EventParams &e);
UI::EventReturn OnSwitchUMD(UI::EventParams &e);
std::string gamePath_;
UI::ChoiceStrip *saveSlots_;
UI::Choice *saveStateButton_;
UI::Choice *loadStateButton_;
};
class UmdReplaceScreen : public UIDialogScreenWithBackground {
public:
UmdReplaceScreen() {}
protected:
virtual void CreateViews();
virtual void update(InputState &input);
//virtual void sendMessage(const char *message, const char *value);
private:
UI::EventReturn OnGameSelected(UI::EventParams &e);
UI::EventReturn OnGameSelectedInstant(UI::EventParams &e);
};