umd0 solution: Add "OnlyEntireISOFileSystem"

Wraps around an ISOFileSystem, redirecting all the filenames to "" to
achieve the desired effect (should fix Bleach Soul Carnival 2 without resorting
to CPkmn's hack from #6638)

Probably breaks savestates as-is...
This commit is contained in:
Henrik Rydgard 2014-07-27 23:42:46 +02:00
parent 82421f4dcf
commit 8146ff85f3
3 changed files with 89 additions and 33 deletions

View file

@ -299,9 +299,8 @@ void ISOFileSystem::ReadDirectory(u32 startsector, u32 dirsize, TreeEntry *root,
ISOFileSystem::TreeEntry *ISOFileSystem::GetFromPath(std::string path, bool catchError)
{
if (path.length() == 0)
{
//Ah, the device! "umd0:"
if (path.length() == 0) {
// Ah, the device! "umd0:"
return &entireISO;
}
@ -311,9 +310,6 @@ ISOFileSystem::TreeEntry *ISOFileSystem::GetFromPath(std::string path, bool catc
if (path[0] == '/')
path.erase(0,1);
if (path == "umd0")
return &entireISO;
TreeEntry *e = treeroot;
if (path.length() == 0)
return e;
@ -726,6 +722,12 @@ std::string ISOFileSystem::EntryFullPath(TreeEntry *e)
return path;
}
ISOFileSystem::TreeEntry::~TreeEntry() {
for (size_t i = 0; i < children.size(); ++i)
delete children[i];
children.clear();
}
void ISOFileSystem::DoState(PointerWrap &p)
{
auto s = p.Section("ISOFileSystem", 1);

View file

@ -31,35 +31,31 @@ class ISOFileSystem : public IFileSystem
public:
ISOFileSystem(IHandleAllocator *_hAlloc, BlockDevice *_blockDevice, std::string _restrictPath = "");
~ISOFileSystem();
void DoState(PointerWrap &p);
std::vector<PSPFileInfo> GetDirListing(std::string path);
u32 OpenFile(std::string filename, FileAccess access, const char *devicename=NULL);
void CloseFile(u32 handle);
size_t ReadFile(u32 handle, u8 *pointer, s64 size);
size_t SeekFile(u32 handle, s32 position, FileMove type);
PSPFileInfo GetFileInfo(std::string filename);
bool OwnsHandle(u32 handle);
int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec);
int DevType(u32 handle);
int Flags() { return 0; }
size_t WriteFile(u32 handle, const u8 *pointer, s64 size);
void DoState(PointerWrap &p) override;
std::vector<PSPFileInfo> GetDirListing(std::string path) override;
u32 OpenFile(std::string filename, FileAccess access, const char *devicename = NULL) override;
void CloseFile(u32 handle) override;
size_t ReadFile(u32 handle, u8 *pointer, s64 size) override;
size_t SeekFile(u32 handle, s32 position, FileMove type) override;
PSPFileInfo GetFileInfo(std::string filename) override;
bool OwnsHandle(u32 handle) override;
int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override;
int DevType(u32 handle) override;
int Flags() override { return 0; }
size_t WriteFile(u32 handle, const u8 *pointer, s64 size) override;
bool GetHostPath(const std::string &inpath, std::string &outpath) {return false;}
virtual bool MkDir(const std::string &dirname) {return false;}
virtual bool RmDir(const std::string &dirname) {return false;}
virtual int RenameFile(const std::string &from, const std::string &to) {return -1;}
virtual bool RemoveFile(const std::string &filename) {return false;}
bool MkDir(const std::string &dirname) override {return false;}
bool RmDir(const std::string &dirname) override { return false; }
int RenameFile(const std::string &from, const std::string &to) override { return -1; }
bool RemoveFile(const std::string &filename) override { return false; }
private:
struct TreeEntry
{
TreeEntry(){}
~TreeEntry()
{
for (size_t i = 0; i < children.size(); ++i)
delete children[i];
children.clear();
}
~TreeEntry();
std::string name;
u32 flags;
@ -81,7 +77,6 @@ private:
u32 openSize;
};
typedef std::map<u32,OpenFileEntry> EntryMap;
EntryMap entries;
IHandleAllocator *hAlloc;
@ -94,6 +89,55 @@ private:
std::vector<std::string> restrictTree;
void ReadDirectory(u32 startsector, u32 dirsize, TreeEntry *root, size_t level);
TreeEntry *GetFromPath(std::string path, bool catchError=true);
TreeEntry *GetFromPath(std::string path, bool catchError = true);
std::string EntryFullPath(TreeEntry *e);
};
// On the "umd0:" device, any file you open is the entire ISO.
// Simply wrap around an ISOFileSystem which has all the necessary machinery, while changing
// the filenames to "", to achieve this.
class OnlyEntireISOFileSystem : public IFileSystem {
public:
OnlyEntireISOFileSystem(ISOFileSystem *isoFileSystem) : isoFileSystem_(isoFileSystem) {}
void DoState(PointerWrap &p) override {}
std::vector<PSPFileInfo> GetDirListing(std::string path) override { return std::vector<PSPFileInfo>(); }
u32 OpenFile(std::string filename, FileAccess access, const char *devicename = NULL) override {
return isoFileSystem_->OpenFile("", access, devicename);
}
void CloseFile(u32 handle) override {
isoFileSystem_->CloseFile(handle);
}
size_t ReadFile(u32 handle, u8 *pointer, s64 size) override {
return isoFileSystem_->ReadFile(handle, pointer, size);
}
size_t SeekFile(u32 handle, s32 position, FileMove type) override {
return isoFileSystem_->SeekFile(handle, position, type);
}
PSPFileInfo GetFileInfo(std::string filename) override {
return isoFileSystem_->GetFileInfo("");
}
bool OwnsHandle(u32 handle) override {
return isoFileSystem_->OwnsHandle(handle);
}
int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override {
return isoFileSystem_->Ioctl(handle, cmd, indataPtr, inlen, outdataPtr, outlen, usec);
}
int DevType(u32 handle) override {
return isoFileSystem_->DevType(handle);
}
int Flags() override { return isoFileSystem_->Flags(); }
size_t WriteFile(u32 handle, const u8 *pointer, s64 size) override {
return isoFileSystem_->WriteFile(handle, pointer, size);
}
bool GetHostPath(const std::string &inpath, std::string &outpath) { return false; }
bool MkDir(const std::string &dirname) override { return false; }
bool RmDir(const std::string &dirname) override { return false; }
int RenameFile(const std::string &from, const std::string &to) override { return -1; }
bool RemoveFile(const std::string &filename) override { return false; }
private:
ISOFileSystem *isoFileSystem_;
};

View file

@ -60,6 +60,7 @@ void InitMemoryForGameISO(std::string fileToStart) {
FileInfo info;
if (!getFileInfo(fileToStart.c_str(), &info)) return;
bool actualIso = false;
if (info.isDirectory)
{
umd2 = new VirtualDiscFileSystem(&pspFileSystem, fileToStart);
@ -71,15 +72,24 @@ void InitMemoryForGameISO(std::string fileToStart) {
if (!bd)
return;
umd2 = new ISOFileSystem(&pspFileSystem, bd);
actualIso = true;
}
// Parse PARAM.SFO
//pspFileSystem.Mount("host0:",umd2);
pspFileSystem.Mount("umd0:", umd2);
pspFileSystem.Mount("umd1:", umd2);
IFileSystem *entireIso = 0;
if (actualIso) {
entireIso = new OnlyEntireISOFileSystem(static_cast<ISOFileSystem *>(umd2));
} else {
entireIso = umd2;
}
pspFileSystem.Mount("umd0:", entireIso);
pspFileSystem.Mount("umd1:", entireIso);
pspFileSystem.Mount("disc0:", umd2);
pspFileSystem.Mount("umd:", umd2);
pspFileSystem.Mount("umd:", entireIso);
std::string gameID;