mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Remote ISO: Add working support for streaming CHD files over the network
This commit is contained in:
parent
a5afba2b70
commit
7d114eb29b
4 changed files with 53 additions and 28 deletions
|
@ -525,6 +525,11 @@ struct CHDImpl {
|
|||
const chd_header *header = nullptr;
|
||||
};
|
||||
|
||||
struct ExtendedCoreFile {
|
||||
core_file core; // Must be the first struct member, for some tricky pointer casts.
|
||||
uint64_t seekPos;
|
||||
};
|
||||
|
||||
CHDFileBlockDevice::CHDFileBlockDevice(FileLoader *fileLoader)
|
||||
: BlockDevice(fileLoader), impl_(new CHDImpl())
|
||||
{
|
||||
|
@ -532,6 +537,46 @@ CHDFileBlockDevice::CHDFileBlockDevice(FileLoader *fileLoader)
|
|||
paths[0] = fileLoader->GetPath();
|
||||
int depth = 0;
|
||||
|
||||
core_file_ = new ExtendedCoreFile();
|
||||
core_file_->core.argp = fileLoader;
|
||||
core_file_->core.fsize = [](core_file *file) -> uint64_t {
|
||||
FileLoader *loader = (FileLoader *)file->argp;
|
||||
return loader->FileSize();
|
||||
};
|
||||
core_file_->core.fseek = [](core_file *file, int64_t offset, int seekType) -> int {
|
||||
ExtendedCoreFile *coreFile = (ExtendedCoreFile *)file;
|
||||
switch (seekType) {
|
||||
case SEEK_SET:
|
||||
coreFile->seekPos = offset;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
coreFile->seekPos += offset;
|
||||
break;
|
||||
case SEEK_END:
|
||||
{
|
||||
FileLoader *loader = (FileLoader *)file->argp;
|
||||
coreFile->seekPos = loader->FileSize() + offset;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
core_file_->core.fread = [](void *out_data, size_t size, size_t count, core_file *file) {
|
||||
ExtendedCoreFile *coreFile = (ExtendedCoreFile *)file;
|
||||
FileLoader *loader = (FileLoader *)file->argp;
|
||||
uint64_t totalSize = size * count;
|
||||
loader->ReadAt(coreFile->seekPos, totalSize, out_data);
|
||||
coreFile->seekPos += totalSize;
|
||||
return size * count;
|
||||
};
|
||||
core_file_->core.fclose = [](core_file *file) {
|
||||
ExtendedCoreFile *coreFile = (ExtendedCoreFile *)file;
|
||||
delete coreFile;
|
||||
return 0;
|
||||
};
|
||||
|
||||
/*
|
||||
// TODO: Support parent/child CHD files.
|
||||
|
||||
|
@ -582,36 +627,15 @@ CHDFileBlockDevice::CHDFileBlockDevice(FileLoader *fileLoader)
|
|||
}
|
||||
*/
|
||||
|
||||
chd_file *parent = NULL;
|
||||
chd_file *child = NULL;
|
||||
|
||||
FILE *file = File::OpenCFile(paths[depth], "rb");
|
||||
if (!file) {
|
||||
ERROR_LOG(LOADER, "Error opening CHD file '%s'", paths[depth].c_str());
|
||||
NotifyReadError();
|
||||
return;
|
||||
}
|
||||
chd_error err = chd_open_file(file, CHD_OPEN_READ, NULL, &child);
|
||||
chd_file *file = nullptr;
|
||||
chd_error err = chd_open_core_file(&core_file_->core, CHD_OPEN_READ, NULL, &file);
|
||||
if (err != CHDERR_NONE) {
|
||||
ERROR_LOG(LOADER, "Error loading CHD '%s': %s", paths[depth].c_str(), chd_error_string(err));
|
||||
NotifyReadError();
|
||||
return;
|
||||
}
|
||||
|
||||
// We won't enter this loop until we enable the parent/child stuff above.
|
||||
for (int d = depth - 1; d >= 0; d--) {
|
||||
parent = child;
|
||||
child = NULL;
|
||||
// TODO: Use chd_open_file
|
||||
err = chd_open(paths[d].c_str(), CHD_OPEN_READ, parent, &child);
|
||||
if (err != CHDERR_NONE) {
|
||||
ERROR_LOG(LOADER, "Error loading CHD '%s': %s", paths[d].c_str(), chd_error_string(err));
|
||||
NotifyReadError();
|
||||
return;
|
||||
}
|
||||
}
|
||||
impl_->chd = child;
|
||||
|
||||
impl_->chd = file;
|
||||
impl_->header = chd_get_header(impl_->chd);
|
||||
readBuffer = new u8[impl_->header->hunkbytes];
|
||||
currentHunk = -1;
|
||||
|
|
|
@ -136,6 +136,8 @@ private:
|
|||
|
||||
struct CHDImpl;
|
||||
|
||||
struct ExtendedCoreFile;
|
||||
|
||||
class CHDFileBlockDevice : public BlockDevice {
|
||||
public:
|
||||
CHDFileBlockDevice(FileLoader *fileLoader);
|
||||
|
@ -146,6 +148,7 @@ public:
|
|||
bool IsDisc() const override { return true; }
|
||||
|
||||
private:
|
||||
struct ExtendedCoreFile *core_file_ = nullptr;
|
||||
std::unique_ptr<CHDImpl> impl_;
|
||||
u8 *readBuffer = nullptr;
|
||||
u32 currentHunk = 0;
|
||||
|
|
|
@ -125,9 +125,7 @@ static bool RegisterServer(int port) {
|
|||
|
||||
bool RemoteISOFileSupported(const std::string &filename) {
|
||||
// Disc-like files.
|
||||
// NOTE: chd is temporarily disabled until we can make it use the FileLoader instead of
|
||||
// trying to re-open the file, since otherwise won't work over HTTP.
|
||||
if (endsWithNoCase(filename, ".cso") || endsWithNoCase(filename, ".iso")) {
|
||||
if (endsWithNoCase(filename, ".cso") || endsWithNoCase(filename, ".iso") || endsWithNoCase(filename, ".chd")) {
|
||||
return true;
|
||||
}
|
||||
// May work - but won't have supporting files.
|
||||
|
|
|
@ -252,7 +252,7 @@ static bool LoadGameList(const Path &url, std::vector<Path> &games) {
|
|||
std::vector<File::FileInfo> files;
|
||||
browser.SetUserAgent(StringFromFormat("PPSSPP/%s", PPSSPP_GIT_VERSION));
|
||||
browser.SetRootAlias("ms:", GetSysDirectory(DIRECTORY_MEMSTICK_ROOT).ToVisualString());
|
||||
browser.GetListing(files, "iso:cso:pbp:elf:prx:ppdmp:", &scanCancelled);
|
||||
browser.GetListing(files, "iso:cso:chd:pbp:elf:prx:ppdmp:", &scanCancelled);
|
||||
if (scanCancelled) {
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue