mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-31 19:47:06 +01:00
A cue sheet, a CloneCD .ccd, or a bare .bin, .img or .iso of a PS1 disc now boots on the firmware's POPS, as the converted EBOOT.PBP popstation would make from it. PS1EbootFileLoader builds the PBP header, PARAM.SFO (the disc ID from SYSTEM.CNF) and the PSISOIMG header, TOC and block index, and serves the disc image from the image's own files. Each block of 16 sectors is a stored DEFLATE block: the manager won't read an image of uncompressed blocks in its own format, but the converted PBP's inflate takes stored ones, and with every block the same size, reads map straight onto the files. Nothing is compressed or written anywhere. Cue sheets can have any number of files, AUDIO tracks, INDEX 00 and PREGAP, and a missing FILE falls back to the cue sheet's own name. A 2048-byte .iso gets Mode 2 Form 1 sectors made around its user data. The EBOOT is mounted as the only file in host0:, through BlobFileSystem, which now saves its open handles in savestates. The game browser lists .cue, .ccd, .bin and .img, leaving out the .bin and .img files a cue sheet or .ccd next to them describes, and a bare image opened directly goes through the cue sheet that names it. GameInfoCache reads the title and ID of these, and of real PS1 EBOOTs, from their PARAM.SFO. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
146 lines
3.9 KiB
C++
146 lines
3.9 KiB
C++
// Copyright (c) 2017- 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 "Common/Serialize/Serializer.h"
|
|
#include "Common/Serialize/SerializeMap.h"
|
|
#include "Core/FileSystems/BlobFileSystem.h"
|
|
|
|
BlobFileSystem::BlobFileSystem(IHandleAllocator *hAlloc, FileLoader *fileLoader, std::string alias)
|
|
: alloc_(hAlloc), fileLoader_(fileLoader), alias_(alias) {
|
|
NOTICE_LOG(Log::FileSystem, "%s", fileLoader->GetPath().c_str());
|
|
}
|
|
|
|
BlobFileSystem::~BlobFileSystem() {
|
|
// TODO: Who deletes fileLoader?
|
|
}
|
|
|
|
void BlobFileSystem::DoState(PointerWrap &p) {
|
|
auto s = p.Section("BlobFileSystem", 1);
|
|
if (!s)
|
|
return;
|
|
// The open handles and their positions. The blob is the one booted.
|
|
Do(p, entries_);
|
|
}
|
|
|
|
std::vector<PSPFileInfo> BlobFileSystem::GetDirListing(std::string_view path, bool *exists) {
|
|
std::vector<PSPFileInfo> listing;
|
|
listing.push_back(GetFileInfo(alias_));
|
|
if (exists)
|
|
*exists = true;
|
|
return listing;
|
|
}
|
|
|
|
int BlobFileSystem::OpenFile(std::string filename, FileAccess access, const char *devicename) {
|
|
u32 newHandle = alloc_->GetNewHandle();
|
|
entries_[newHandle] = 0;
|
|
return newHandle;
|
|
}
|
|
|
|
void BlobFileSystem::CloseFile(u32 handle) {
|
|
alloc_->FreeHandle(handle);
|
|
entries_.erase(handle);
|
|
}
|
|
|
|
size_t BlobFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size) {
|
|
auto entry = entries_.find(handle);
|
|
if (entry != entries_.end()) {
|
|
s64 readSize = (s64)fileLoader_->ReadAt(entry->second, (size_t)size, pointer);
|
|
entry->second += readSize;
|
|
return (size_t)readSize;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
size_t BlobFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size, int &usec) {
|
|
usec = 0;
|
|
return ReadFile(handle, pointer, size);
|
|
}
|
|
|
|
size_t BlobFileSystem::WriteFile(u32 handle, const u8 *pointer, s64 size) {
|
|
return 0;
|
|
}
|
|
|
|
size_t BlobFileSystem::WriteFile(u32 handle, const u8 *pointer, s64 size, int &usec) {
|
|
return 0;
|
|
}
|
|
|
|
size_t BlobFileSystem::SeekFile(u32 handle, s32 position, FileMove type) {
|
|
auto entry = entries_.find(handle);
|
|
if (entry != entries_.end()) {
|
|
switch (type) {
|
|
case FILEMOVE_BEGIN:
|
|
entry->second = position;
|
|
break;
|
|
case FILEMOVE_CURRENT:
|
|
entry->second += position;
|
|
break;
|
|
case FILEMOVE_END:
|
|
entry->second = fileLoader_->FileSize() + position;
|
|
break;
|
|
}
|
|
return (size_t)entry->second;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
PSPFileInfo BlobFileSystem::GetFileInfo(std::string filename) {
|
|
PSPFileInfo info{};
|
|
info.name = alias_;
|
|
info.size = fileLoader_->FileSize();
|
|
info.access = 0666;
|
|
info.exists = true;
|
|
info.type = FILETYPE_NORMAL;
|
|
return info;
|
|
}
|
|
|
|
PSPFileInfo BlobFileSystem::GetFileInfoByHandle(u32 handle) {
|
|
return GetFileInfo("");
|
|
}
|
|
|
|
bool BlobFileSystem::OwnsHandle(u32 handle) {
|
|
auto entry = entries_.find(handle);
|
|
return entry != entries_.end();
|
|
}
|
|
|
|
int BlobFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) {
|
|
return -1;
|
|
}
|
|
|
|
PSPDevType BlobFileSystem::DevType(u32 handle) {
|
|
return PSPDevType::FILE;
|
|
}
|
|
|
|
bool BlobFileSystem::MkDir(const std::string &dirname) {
|
|
return false;
|
|
}
|
|
|
|
bool BlobFileSystem::RmDir(const std::string &dirname) {
|
|
return false;
|
|
}
|
|
|
|
int BlobFileSystem::RenameFile(const std::string &from, const std::string &to) {
|
|
return -1;
|
|
}
|
|
|
|
bool BlobFileSystem::RemoveFile(const std::string &filename) {
|
|
return false;
|
|
}
|
|
|
|
u64 BlobFileSystem::FreeDiskSpace(const std::string &path) {
|
|
return 0;
|
|
}
|