mirror of
https://github.com/libretro/ppsspp.git
synced 2025-02-06 09:06:55 +00:00
Use a FileLoader for PBPs.
Improves consistency, caching, etc.
This commit is contained in:
parent
a53f0360f3
commit
f3df6b307f
@ -21,37 +21,32 @@
|
||||
|
||||
#include "Common/Log.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Core/Loaders.h"
|
||||
#include "Core/ELF/PBPReader.h"
|
||||
|
||||
PBPReader::PBPReader(const char *filename) : header_(), isELF_(false) {
|
||||
file_ = File::OpenCFile(filename, "rb");
|
||||
if (!file_) {
|
||||
ERROR_LOG(LOADER, "Failed to open PBP file %s", filename);
|
||||
PBPReader::PBPReader(FileLoader *fileLoader) : file_(nullptr), header_(), isELF_(false) {
|
||||
if (!fileLoader->Exists()) {
|
||||
ERROR_LOG(LOADER, "Failed to open PBP file %s", fileLoader->Path().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
fseek(file_, 0, SEEK_END);
|
||||
fileSize_ = ftell(file_);
|
||||
fseek(file_, 0, SEEK_SET);
|
||||
if (fread((char *)&header_, 1, sizeof(header_), file_) != sizeof(header_)) {
|
||||
ERROR_LOG(LOADER, "PBP is too small to be valid: %s", filename);
|
||||
fclose(file_);
|
||||
file_ = nullptr;
|
||||
fileSize_ = (size_t)fileLoader->FileSize();
|
||||
if (fileLoader->ReadAt(0, sizeof(header_), (u8 *)&header_) != sizeof(header_)) {
|
||||
ERROR_LOG(LOADER, "PBP is too small to be valid: %s", fileLoader->Path().c_str());
|
||||
return;
|
||||
}
|
||||
if (memcmp(header_.magic, "\0PBP", 4) != 0) {
|
||||
if (memcmp(header_.magic, "\nFLE", 4) != 0) {
|
||||
DEBUG_LOG(LOADER, "%s: File actually an ELF, not a PBP", filename);
|
||||
DEBUG_LOG(LOADER, "%s: File actually an ELF, not a PBP", fileLoader->Path().c_str());
|
||||
isELF_ = true;
|
||||
} else {
|
||||
ERROR_LOG(LOADER, "Magic number in %s indicated no PBP: %s", filename, header_.magic);
|
||||
ERROR_LOG(LOADER, "Magic number in %s indicated no PBP: %s", fileLoader->Path().c_str(), header_.magic);
|
||||
}
|
||||
fclose(file_);
|
||||
file_ = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_LOG(LOADER, "Loading PBP, version = %08x", header_.version);
|
||||
file_ = fileLoader;
|
||||
}
|
||||
|
||||
bool PBPReader::GetSubFile(PBPSubFile file, std::vector<u8> *out) {
|
||||
@ -62,20 +57,15 @@ bool PBPReader::GetSubFile(PBPSubFile file, std::vector<u8> *out) {
|
||||
const size_t expected = GetSubFileSize(file);
|
||||
const u32 off = header_.offsets[(int)file];
|
||||
|
||||
if (fseek(file_, off, SEEK_SET) != 0) {
|
||||
ERROR_LOG(LOADER, "PBP file offset invalid: %d", off);
|
||||
return false;
|
||||
} else {
|
||||
out->resize(expected);
|
||||
size_t bytes = fread((void *)out->data(), 1, expected, file_);
|
||||
if (bytes != expected) {
|
||||
ERROR_LOG(LOADER, "PBP file read truncated: %d -> %d", (int)expected, (int)bytes);
|
||||
if (bytes < expected) {
|
||||
out->resize(bytes);
|
||||
}
|
||||
out->resize(expected);
|
||||
size_t bytes = file_->ReadAt(off, expected, (void *)out->data());
|
||||
if (bytes != expected) {
|
||||
ERROR_LOG(LOADER, "PBP file read truncated: %d -> %d", (int)expected, (int)bytes);
|
||||
if (bytes < expected) {
|
||||
out->resize(bytes);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void PBPReader::GetSubFileAsString(PBPSubFile file, std::string *out) {
|
||||
@ -88,21 +78,16 @@ void PBPReader::GetSubFileAsString(PBPSubFile file, std::string *out) {
|
||||
const u32 off = header_.offsets[(int)file];
|
||||
|
||||
out->resize(expected);
|
||||
if (fseek(file_, off, SEEK_SET) != 0) {
|
||||
ERROR_LOG(LOADER, "PBP file offset invalid: %d", off);
|
||||
out->clear();
|
||||
} else {
|
||||
size_t bytes = fread((void *)out->data(), 1, expected, file_);
|
||||
if (bytes != expected) {
|
||||
ERROR_LOG(LOADER, "PBP file read truncated: %d -> %d", (int)expected, (int)bytes);
|
||||
if (bytes < expected) {
|
||||
out->resize(bytes);
|
||||
}
|
||||
size_t bytes = file_->ReadAt(off, expected, (void *)out->data());
|
||||
if (bytes != expected) {
|
||||
ERROR_LOG(LOADER, "PBP file read truncated: %d -> %d", (int)expected, (int)bytes);
|
||||
if (bytes < expected) {
|
||||
out->resize(bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PBPReader::~PBPReader() {
|
||||
if (file_)
|
||||
fclose(file_);
|
||||
// Does not take ownership.
|
||||
file_ = nullptr;
|
||||
}
|
||||
|
@ -37,13 +37,15 @@ struct PBPHeader {
|
||||
u32_le offsets[8];
|
||||
};
|
||||
|
||||
class FileLoader;
|
||||
|
||||
class PBPReader {
|
||||
public:
|
||||
PBPReader(const char *filename);
|
||||
PBPReader(FileLoader *fileLoader);
|
||||
~PBPReader();
|
||||
|
||||
bool IsValid() const { return file_ != 0; }
|
||||
bool IsELF() const { return file_ == 0 && isELF_; }
|
||||
bool IsValid() const { return file_ != nullptr; }
|
||||
bool IsELF() const { return file_ == nullptr && isELF_; }
|
||||
|
||||
bool GetSubFile(PBPSubFile file, std::vector<u8> *out);
|
||||
void GetSubFileAsString(PBPSubFile file, std::string *out);
|
||||
@ -58,7 +60,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
FILE *file_;
|
||||
FileLoader *file_;
|
||||
size_t fileSize_;
|
||||
const PBPHeader header_;
|
||||
bool isELF_;
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "Core/HLE/ReplaceTables.h"
|
||||
#include "Core/Reporting.h"
|
||||
#include "Core/Host.h"
|
||||
#include "Core/Loaders.h"
|
||||
#include "Core/MIPS/MIPS.h"
|
||||
#include "Core/MIPS/MIPSAnalyst.h"
|
||||
#include "Core/MIPS/MIPSCodeUtils.h"
|
||||
@ -1368,11 +1369,11 @@ static Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, bool fromT
|
||||
return module;
|
||||
}
|
||||
|
||||
static bool __KernelLoadPBP(const char *filename, std::string *error_string)
|
||||
static bool __KernelLoadPBP(FileLoader *fileLoader, std::string *error_string)
|
||||
{
|
||||
PBPReader pbp(filename);
|
||||
PBPReader pbp(fileLoader);
|
||||
if (!pbp.IsValid()) {
|
||||
ERROR_LOG(LOADER,"%s is not a valid homebrew PSP1.0 PBP",filename);
|
||||
ERROR_LOG(LOADER, "%s is not a valid homebrew PSP1.0 PBP", fileLoader->Path().c_str());
|
||||
*error_string = "Not a valid homebrew PBP";
|
||||
return false;
|
||||
}
|
||||
|
@ -141,9 +141,7 @@ IdentifiedFileType Identify_File(FileLoader *fileLoader) {
|
||||
else if (id == 'PBP\x00') {
|
||||
// Do this PS1 eboot check FIRST before checking other eboot types.
|
||||
// It seems like some are malformed and slip through the PSAR check below.
|
||||
// TODO: Change PBPReader to read FileLoader objects?
|
||||
std::string filename = fileLoader->Path();
|
||||
PBPReader pbp(filename.c_str());
|
||||
PBPReader pbp(fileLoader);
|
||||
if (pbp.IsValid() && !pbp.IsELF()) {
|
||||
std::vector<u8> sfoData;
|
||||
if (pbp.GetSubFile(PBP_PARAM_SFO, &sfoData)) {
|
||||
@ -166,11 +164,10 @@ IdentifiedFileType Identify_File(FileLoader *fileLoader) {
|
||||
|
||||
// Let's check if we got pointed to a PBP within such a directory.
|
||||
// If so we just move up and return the directory itself as the game.
|
||||
std::string path = File::GetDir(filename);
|
||||
std::string path = File::GetDir(fileLoader->Path());
|
||||
// If loading from memstick...
|
||||
size_t pos = path.find("/PSP/GAME/");
|
||||
if (pos != std::string::npos) {
|
||||
filename = path;
|
||||
return FILETYPE_PSP_PBP_DIRECTORY;
|
||||
}
|
||||
return FILETYPE_PSP_PBP;
|
||||
|
@ -131,9 +131,7 @@ void InitMemoryForGamePBP(FileLoader *fileLoader) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Change PBPReader to read FileLoader objects?
|
||||
std::string filename = fileLoader->Path();
|
||||
PBPReader pbp(filename.c_str());
|
||||
PBPReader pbp(fileLoader);
|
||||
if (pbp.IsValid() && !pbp.IsELF()) {
|
||||
std::vector<u8> sfoData;
|
||||
if (pbp.GetSubFile(PBP_PARAM_SFO, &sfoData)) {
|
||||
|
@ -322,16 +322,19 @@ public:
|
||||
case FILETYPE_PSP_PBP:
|
||||
case FILETYPE_PSP_PBP_DIRECTORY:
|
||||
{
|
||||
std::string pbpFile = filename;
|
||||
if (info_->fileType == FILETYPE_PSP_PBP_DIRECTORY)
|
||||
pbpFile += "/EBOOT.PBP";
|
||||
FileLoader *pbpLoader = info_->GetFileLoader();
|
||||
std::unique_ptr<FileLoader> altLoader;
|
||||
if (info_->fileType == FILETYPE_PSP_PBP_DIRECTORY) {
|
||||
pbpLoader = ConstructFileLoader(pbpLoader->Path() + "/EBOOT.PBP");
|
||||
altLoader.reset(pbpLoader);
|
||||
}
|
||||
|
||||
PBPReader pbp(pbpFile.c_str());
|
||||
PBPReader pbp(pbpLoader);
|
||||
if (!pbp.IsValid()) {
|
||||
if (pbp.IsELF()) {
|
||||
goto handleELF;
|
||||
}
|
||||
ERROR_LOG(LOADER, "invalid pbp %s\n", pbpFile.c_str());
|
||||
ERROR_LOG(LOADER, "invalid pbp %s\n", pbpLoader->Path().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user