2012-11-01 15:19:01 +00:00
|
|
|
// 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
|
2012-11-04 22:01:49 +00:00
|
|
|
// the Free Software Foundation, version 2.0 or later versions.
|
2012-11-01 15:19:01 +00:00
|
|
|
|
|
|
|
// 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 "ELF/ElfReader.h"
|
|
|
|
|
|
|
|
#include "FileSystems/DirectoryFileSystem.h"
|
|
|
|
#include "FileSystems/ISOFileSystem.h"
|
|
|
|
|
|
|
|
#include "MemMap.h"
|
|
|
|
|
|
|
|
#include "MIPS/MIPS.h"
|
|
|
|
#include "MIPS/MIPSAnalyst.h"
|
|
|
|
#include "MIPS/MIPSCodeUtils.h"
|
|
|
|
|
|
|
|
#include "StringUtil.h"
|
|
|
|
|
|
|
|
#include "Host.h"
|
|
|
|
|
|
|
|
#include "System.h"
|
|
|
|
#include "PSPLoaders.h"
|
|
|
|
#include "HLE/HLE.h"
|
|
|
|
#include "HLE/sceKernel.h"
|
|
|
|
#include "HLE/sceKernelThread.h"
|
|
|
|
#include "HLE/sceKernelModule.h"
|
|
|
|
#include "HLE/sceKernelMemory.h"
|
2012-11-30 20:49:59 +00:00
|
|
|
#include "ELF/ParamSFO.h"
|
2012-11-01 15:19:01 +00:00
|
|
|
|
|
|
|
BlockDevice *constructBlockDevice(const char *filename)
|
|
|
|
{
|
2013-01-12 10:31:32 +00:00
|
|
|
// Check for CISO
|
|
|
|
FILE *f = fopen(filename, "rb");
|
|
|
|
char buffer[4];
|
2013-01-12 13:35:51 +00:00
|
|
|
auto size = fread(buffer, 1, 4, f); //size_t
|
2013-01-12 10:31:32 +00:00
|
|
|
fclose(f);
|
2013-01-12 13:35:51 +00:00
|
|
|
if (!memcmp(buffer, "CISO", 4) && size == 4)
|
2012-11-01 15:19:01 +00:00
|
|
|
return new CISOFileBlockDevice(filename);
|
|
|
|
else
|
|
|
|
return new FileBlockDevice(filename);
|
|
|
|
}
|
|
|
|
|
2012-11-30 20:49:59 +00:00
|
|
|
|
2012-11-01 15:19:01 +00:00
|
|
|
bool Load_PSP_ISO(const char *filename, std::string *error_string)
|
|
|
|
{
|
|
|
|
ISOFileSystem *umd2 = new ISOFileSystem(&pspFileSystem, constructBlockDevice(filename));
|
|
|
|
|
2012-11-30 20:49:59 +00:00
|
|
|
// Parse PARAM.SFO
|
|
|
|
|
2012-11-01 15:19:01 +00:00
|
|
|
//pspFileSystem.Mount("host0:",umd2);
|
|
|
|
pspFileSystem.Mount("umd0:", umd2);
|
|
|
|
pspFileSystem.Mount("umd1:", umd2);
|
2013-01-09 08:46:47 +00:00
|
|
|
pspFileSystem.Mount("disc0:", umd2);
|
2012-11-30 16:47:04 +00:00
|
|
|
pspFileSystem.Mount("umd:", umd2);
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2012-11-30 20:49:59 +00:00
|
|
|
std::string sfoPath("disc0:/PSP_GAME/PARAM.SFO");
|
|
|
|
PSPFileInfo fileInfo = pspFileSystem.GetFileInfo(sfoPath.c_str());
|
|
|
|
if (fileInfo.exists)
|
|
|
|
{
|
2012-11-30 21:32:15 +00:00
|
|
|
u8 *paramsfo = new u8[(size_t)fileInfo.size];
|
2012-11-30 20:49:59 +00:00
|
|
|
u32 fd = pspFileSystem.OpenFile(sfoPath, FILEACCESS_READ);
|
|
|
|
pspFileSystem.ReadFile(fd, paramsfo, fileInfo.size);
|
|
|
|
pspFileSystem.CloseFile(fd);
|
2013-01-02 20:00:10 +00:00
|
|
|
if (g_paramSFO.ReadSFO(paramsfo, (size_t)fileInfo.size))
|
2012-11-30 20:49:59 +00:00
|
|
|
{
|
2012-11-30 21:32:15 +00:00
|
|
|
char title[1024];
|
2013-01-02 20:00:10 +00:00
|
|
|
sprintf(title, "%s : %s", g_paramSFO.GetValueString("DISC_ID").c_str(), g_paramSFO.GetValueString("TITLE").c_str());
|
2012-11-30 21:32:15 +00:00
|
|
|
INFO_LOG(LOADER, "%s", title);
|
|
|
|
host->SetWindowTitle(title);
|
2012-11-30 20:49:59 +00:00
|
|
|
}
|
|
|
|
delete [] paramsfo;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-11-05 13:54:28 +00:00
|
|
|
std::string bootpath("disc0:/PSP_GAME/SYSDIR/EBOOT.BIN");
|
2012-11-15 09:15:40 +00:00
|
|
|
// bypass patchers
|
|
|
|
if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/EBOOT.OLD").exists) {
|
|
|
|
bootpath = "disc0:/PSP_GAME/SYSDIR/EBOOT.OLD";
|
|
|
|
}
|
2012-11-05 13:54:28 +00:00
|
|
|
bool hasEncrypted = false;
|
|
|
|
u32 fd;
|
|
|
|
if ((fd = pspFileSystem.OpenFile(bootpath, FILEACCESS_READ)) != 0)
|
|
|
|
{
|
|
|
|
u8 head[4];
|
|
|
|
pspFileSystem.ReadFile(fd, head, 4);
|
2012-11-06 15:20:13 +00:00
|
|
|
if (memcmp(head, "~PSP", 4) == 0 || memcmp(head, "\x7F""ELF", 4) == 0) {
|
2012-11-05 13:54:28 +00:00
|
|
|
hasEncrypted = true;
|
|
|
|
}
|
2012-11-30 20:49:59 +00:00
|
|
|
pspFileSystem.CloseFile(fd);
|
2012-11-05 13:54:28 +00:00
|
|
|
}
|
|
|
|
if (!hasEncrypted)
|
|
|
|
{
|
|
|
|
// try unencrypted BOOT.BIN
|
|
|
|
bootpath = "disc0:/PSP_GAME/SYSDIR/BOOT.BIN";
|
|
|
|
}
|
2012-11-01 15:19:01 +00:00
|
|
|
|
|
|
|
INFO_LOG(LOADER,"Loading %s...", bootpath.c_str());
|
|
|
|
return __KernelLoadExec(bootpath.c_str(), 0, error_string);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Load_PSP_ELF_PBP(const char *filename, std::string *error_string)
|
|
|
|
{
|
2013-01-09 08:46:47 +00:00
|
|
|
// This is really just for headless, might need tweaking later.
|
|
|
|
if (!PSP_CoreParameter().mountIso.empty())
|
|
|
|
{
|
|
|
|
ISOFileSystem *umd2 = new ISOFileSystem(&pspFileSystem, constructBlockDevice(PSP_CoreParameter().mountIso.c_str()));
|
|
|
|
|
|
|
|
pspFileSystem.Mount("umd1:", umd2);
|
|
|
|
pspFileSystem.Mount("disc0:", umd2);
|
|
|
|
pspFileSystem.Mount("umd:", umd2);
|
|
|
|
}
|
|
|
|
|
2012-11-01 15:19:01 +00:00
|
|
|
std::string full_path = filename;
|
|
|
|
std::string path, file, extension;
|
|
|
|
SplitPath(ReplaceAll(full_path, "\\", "/"), &path, &file, &extension);
|
|
|
|
#ifdef _WIN32
|
|
|
|
path = ReplaceAll(path, "/", "\\");
|
|
|
|
#endif
|
|
|
|
DirectoryFileSystem *fs = new DirectoryFileSystem(&pspFileSystem, path);
|
2013-01-20 23:20:48 +00:00
|
|
|
pspFileSystem.Mount("umd0:", fs);
|
2012-11-01 15:19:01 +00:00
|
|
|
|
|
|
|
std::string finalName = "umd0:/" + file + extension;
|
|
|
|
return __KernelLoadExec(finalName.c_str(), 0, error_string);
|
|
|
|
}
|