ppsspp/Core/PSPLoaders.cpp

224 lines
7.1 KiB
C++
Raw Normal View History

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
// 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/BlockDevices.h"
2012-11-01 15:19:01 +00:00
#include "FileSystems/DirectoryFileSystem.h"
#include "FileSystems/ISOFileSystem.h"
#include "FileSystems/VirtualDiscFileSystem.h"
2012-11-01 15:19:01 +00:00
#include "MemMap.h"
#include "MIPS/MIPS.h"
#include "MIPS/MIPSAnalyst.h"
#include "MIPS/MIPSCodeUtils.h"
2013-07-23 15:24:33 +00:00
#include "file/file_util.h"
#include "StringUtils.h"
2012-11-01 15:19:01 +00:00
#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"
#include "ELF/ParamSFO.h"
2012-11-01 15:19:01 +00:00
// 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.
void InitMemoryForGameISO(std::string fileToStart) {
2013-07-23 15:24:33 +00:00
IFileSystem* umd2;
// check if it's a disc directory
FileInfo info;
if (!getFileInfo(fileToStart.c_str(), &info)) return;
if (info.isDirectory)
{
umd2 = new VirtualDiscFileSystem(&pspFileSystem, fileToStart);
2013-07-23 15:24:33 +00:00
}
else
{
auto bd = constructBlockDevice(fileToStart.c_str());
// Can't init anything without a block device...
if (!bd)
return;
umd2 = new ISOFileSystem(&pspFileSystem, bd);
}
2012-11-01 15:19:01 +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);
pspFileSystem.Mount("disc0:", umd2);
pspFileSystem.Mount("umd:", umd2);
std::string gameID;
2012-11-01 15:19:01 +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];
u32 fd = pspFileSystem.OpenFile(sfoPath, FILEACCESS_READ);
pspFileSystem.ReadFile(fd, paramsfo, fileInfo.size);
pspFileSystem.CloseFile(fd);
if (g_paramSFO.ReadSFO(paramsfo, (size_t)fileInfo.size))
{
gameID = g_paramSFO.GetValueString("DISC_ID");
2013-07-08 01:24:53 +00:00
for (size_t i = 0; i < ARRAY_SIZE(g_HDRemasters); i++) {
if(g_HDRemasters[i].gameID == gameID) {
g_RemasterMode = true;
Memory::g_MemorySize = g_HDRemasters[i].MemorySize;
if(g_HDRemasters[i].DoubleTextureCoordinates)
g_DoubleTextureCoordinates = true;
break;
}
}
DEBUG_LOG(LOADER, "HDRemaster mode is %s", g_RemasterMode? "true": "false");
}
delete [] paramsfo;
}
}
bool Load_PSP_ISO(const char *filename, std::string *error_string)
{
// Mounting stuff relocated to InitMemoryForGameISO due to HD Remaster restructuring of code.
std::string sfoPath("disc0:/PSP_GAME/PARAM.SFO");
PSPFileInfo fileInfo = pspFileSystem.GetFileInfo(sfoPath.c_str());
if (fileInfo.exists)
{
u8 *paramsfo = new u8[(size_t)fileInfo.size];
u32 fd = pspFileSystem.OpenFile(sfoPath, FILEACCESS_READ);
pspFileSystem.ReadFile(fd, paramsfo, fileInfo.size);
pspFileSystem.CloseFile(fd);
if (g_paramSFO.ReadSFO(paramsfo, (size_t)fileInfo.size))
{
char title[1024];
sprintf(title, "%s : %s", g_paramSFO.GetValueString("DISC_ID").c_str(), g_paramSFO.GetValueString("TITLE").c_str());
INFO_LOG(LOADER, "%s", title);
host->SetWindowTitle(title);
}
delete [] paramsfo;
}
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";
}
2013-02-24 04:16:18 +00:00
// bypass another patchers
if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/EBOOT.DAT").exists) {
bootpath = "disc0:/PSP_GAME/SYSDIR/EBOOT.DAT";
}
2013-03-01 16:48:20 +00:00
// bypass more patchers
if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/EBOOT.BI").exists) {
bootpath = "disc0:/PSP_GAME/SYSDIR/EBOOT.BI";
}
if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/EBOOT.LLD").exists) {
bootpath = "disc0:/PSP_GAME/SYSDIR/EBOOT.LLD";
}
if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/OLD_EBOOT.BIN").exists) {
bootpath = "disc0:/PSP_GAME/SYSDIR/OLD_EBOOT.BIN";
}
if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/EBOOT.123").exists) {
bootpath = "disc0:/PSP_GAME/SYSDIR/EBOOT.123";
}
if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/EBOOT_LRC_CH.BIN").exists) {
bootpath = "disc0:/PSP_GAME/SYSDIR/EBOOT_LRC_CH.BIN";
}
if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/BOOT0.OLD").exists) {
bootpath = "disc0:/PSP_GAME/SYSDIR/BOOT0.OLD";
}
if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/BOOT1.OLD").exists) {
bootpath = "disc0:/PSP_GAME/SYSDIR/BOOT1.OLD";
}
2013-05-16 13:32:08 +00:00
if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/BINOT.BIN").exists) {
bootpath = "disc0:/PSP_GAME/SYSDIR/BINOT.BIN";
}
if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/EBOOT.FRY").exists) {
bootpath = "disc0:/PSP_GAME/SYSDIR/EBOOT.FRY";
}
2013-05-23 14:34:32 +00:00
if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/EBOOT.Z.Y").exists) {
bootpath = "disc0:/PSP_GAME/SYSDIR/EBOOT.Z.Y";
}
if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/EBOOT.LEI").exists) {
bootpath = "disc0:/PSP_GAME/SYSDIR/EBOOT.LEI";
}
2013-07-12 22:46:30 +00:00
if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/EBOOT.DNR").exists) {
bootpath = "disc0:/PSP_GAME/SYSDIR/EBOOT.DNR";
}
2013-03-01 16:48:20 +00:00
bool hasEncrypted = false;
u32 fd;
if ((fd = pspFileSystem.OpenFile(bootpath, FILEACCESS_READ)) != 0)
{
u8 head[4];
pspFileSystem.ReadFile(fd, head, 4);
if (memcmp(head, "~PSP", 4) == 0 || memcmp(head, "\x7F""ELF", 4) == 0) {
hasEncrypted = true;
}
pspFileSystem.CloseFile(fd);
}
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-05-08 15:36:57 +00:00
// This is really just for headless, might need tweaking later.
if (!PSP_CoreParameter().mountIso.empty())
{
auto bd = constructBlockDevice(PSP_CoreParameter().mountIso.c_str());
if (bd != NULL) {
ISOFileSystem *umd2 = new ISOFileSystem(&pspFileSystem, bd);
pspFileSystem.Mount("umd1:", umd2);
pspFileSystem.Mount("disc0:", umd2);
pspFileSystem.Mount("umd:", umd2);
}
2013-05-08 15:36:57 +00:00
}
2013-05-08 15:36:57 +00:00
std::string full_path = filename;
std::string path, file, extension;
SplitPath(ReplaceAll(full_path, "\\", "/"), &path, &file, &extension);
2012-11-01 15:19:01 +00:00
#ifdef _WIN32
2013-05-08 15:36:57 +00:00
path = ReplaceAll(path, "/", "\\");
2012-11-01 15:19:01 +00:00
#endif
2013-05-08 15:36:57 +00:00
DirectoryFileSystem *fs = new DirectoryFileSystem(&pspFileSystem, path);
pspFileSystem.Mount("umd0:", fs);
2013-05-08 15:36:57 +00:00
std::string finalName = "umd0:/" + file + extension;
return __KernelLoadExec(finalName.c_str(), 0, error_string);
2012-11-01 15:19:01 +00:00
}