Removing utilities (that were just adding needless layers).
Progress on #294.
This commit is contained in:
parent
246c47f923
commit
abf47b7973
|
@ -15,6 +15,7 @@
|
|||
#include "xenia/apu/xma_decoder.h"
|
||||
#include "xenia/base/assert.h"
|
||||
#include "xenia/base/clock.h"
|
||||
#include "xenia/base/logging.h"
|
||||
#include "xenia/base/string.h"
|
||||
#include "xenia/gpu/graphics_system.h"
|
||||
#include "xenia/hid/input_system.h"
|
||||
|
@ -24,6 +25,9 @@
|
|||
#include "xenia/memory.h"
|
||||
#include "xenia/ui/main_window.h"
|
||||
#include "xenia/vfs/virtual_file_system.h"
|
||||
#include "xenia/vfs/devices/disc_image_device.h"
|
||||
#include "xenia/vfs/devices/host_path_device.h"
|
||||
#include "xenia/vfs/devices/stfs_container_device.h"
|
||||
|
||||
DEFINE_double(time_scalar, 1.0,
|
||||
"Scalar used to speed or slow time (1x, 2x, 1/2x, etc).");
|
||||
|
@ -171,7 +175,27 @@ X_STATUS Emulator::Setup() {
|
|||
return result;
|
||||
}
|
||||
|
||||
X_STATUS Emulator::LaunchXexFile(const std::wstring& path) {
|
||||
X_STATUS Emulator::LaunchPath(std::wstring path) {
|
||||
// Launch based on file type.
|
||||
// This is a silly guess based on file extension.
|
||||
auto last_slash = path.find_last_of(xe::path_separator);
|
||||
auto last_dot = path.find_last_of('.');
|
||||
if (last_dot < last_slash) {
|
||||
last_dot = std::wstring::npos;
|
||||
}
|
||||
if (last_dot == std::wstring::npos) {
|
||||
// Likely an STFS container.
|
||||
return LaunchStfsContainer(path);
|
||||
} else if (path.substr(last_dot) == L".xex") {
|
||||
// Treat as a naked xex file.
|
||||
return LaunchXexFile(path);
|
||||
} else {
|
||||
// Assume a disc image.
|
||||
return LaunchDiscImage(path);
|
||||
}
|
||||
}
|
||||
|
||||
X_STATUS Emulator::LaunchXexFile(std::wstring path) {
|
||||
// We create a virtual filesystem pointing to its directory and symlink
|
||||
// that to the game filesystem.
|
||||
// e.g., /my/files/foo.xex will get a local fs at:
|
||||
|
@ -179,45 +203,67 @@ X_STATUS Emulator::LaunchXexFile(const std::wstring& path) {
|
|||
// and then get that symlinked to game:\, so
|
||||
// -> game:\foo.xex
|
||||
|
||||
int result_code =
|
||||
file_system_->InitializeFromPath(FileSystemType::XEX_FILE, path);
|
||||
if (result_code) {
|
||||
return X_STATUS_INVALID_PARAMETER;
|
||||
auto mount_path = "\\Device\\Harddisk0\\Partition0";
|
||||
|
||||
// Register the local directory in the virtual filesystem.
|
||||
auto parent_path = xe::find_base_path(path);
|
||||
auto device =
|
||||
std::make_unique<vfs::HostPathDevice>(mount_path, parent_path, true);
|
||||
if (!file_system_->RegisterDevice(std::move(device))) {
|
||||
XELOGE("Unable to register host path");
|
||||
return X_STATUS_NO_SUCH_FILE;
|
||||
}
|
||||
|
||||
// Create symlinks to the device.
|
||||
file_system_->RegisterSymbolicLink("game:", mount_path);
|
||||
file_system_->RegisterSymbolicLink("d:", mount_path);
|
||||
|
||||
// Get just the filename (foo.xex).
|
||||
std::wstring file_name;
|
||||
auto last_slash = path.find_last_of(xe::path_separator);
|
||||
if (last_slash == std::string::npos) {
|
||||
// No slash found, whole thing is a file.
|
||||
file_name = path;
|
||||
} else {
|
||||
// Skip slash.
|
||||
file_name = path.substr(last_slash + 1);
|
||||
}
|
||||
auto file_name = xe::find_name_from_path(path);
|
||||
|
||||
// Launch the game.
|
||||
std::string fs_path = "game:\\" + xe::to_string(file_name);
|
||||
return CompleteLaunch(path, fs_path);
|
||||
}
|
||||
|
||||
X_STATUS Emulator::LaunchDiscImage(const std::wstring& path) {
|
||||
int result_code =
|
||||
file_system_->InitializeFromPath(FileSystemType::DISC_IMAGE, path);
|
||||
if (result_code) {
|
||||
return X_STATUS_INVALID_PARAMETER;
|
||||
X_STATUS Emulator::LaunchDiscImage(std::wstring path) {
|
||||
auto mount_path = "\\Device\\Cdrom0";
|
||||
|
||||
// Register the disc image in the virtual filesystem.
|
||||
auto device = std::make_unique<vfs::DiscImageDevice>(mount_path, path);
|
||||
if (!device->Initialize()) {
|
||||
XELOGE("Unable to mount disc image");
|
||||
return X_STATUS_NO_SUCH_FILE;
|
||||
}
|
||||
if (!file_system_->RegisterDevice(std::move(device))) {
|
||||
XELOGE("Unable to register disc image");
|
||||
return X_STATUS_NO_SUCH_FILE;
|
||||
}
|
||||
|
||||
// Create symlinks to the device.
|
||||
file_system_->RegisterSymbolicLink("game:", mount_path);
|
||||
file_system_->RegisterSymbolicLink("d:", mount_path);
|
||||
|
||||
// Launch the game.
|
||||
return CompleteLaunch(path, "game:\\default.xex");
|
||||
}
|
||||
|
||||
X_STATUS Emulator::LaunchSTFSTitle(const std::wstring& path) {
|
||||
int result_code =
|
||||
file_system_->InitializeFromPath(FileSystemType::STFS_TITLE, path);
|
||||
if (result_code) {
|
||||
return X_STATUS_INVALID_PARAMETER;
|
||||
X_STATUS Emulator::LaunchStfsContainer(std::wstring path) {
|
||||
auto mount_path = "\\Device\\Cdrom0";
|
||||
|
||||
// Register the container in the virtual filesystem.
|
||||
auto device = std::make_unique<vfs::STFSContainerDevice>(mount_path, path);
|
||||
if (!device->Initialize()) {
|
||||
XELOGE("Unable to mount STFS container");
|
||||
return X_STATUS_NO_SUCH_FILE;
|
||||
}
|
||||
if (!file_system_->RegisterDevice(std::move(device))) {
|
||||
XELOGE("Unable to register STFS container");
|
||||
return X_STATUS_NO_SUCH_FILE;
|
||||
}
|
||||
|
||||
file_system_->RegisterSymbolicLink("game:", mount_path);
|
||||
file_system_->RegisterSymbolicLink("d:", mount_path);
|
||||
|
||||
// Launch the game.
|
||||
return CompleteLaunch(path, "game:\\default.xex");
|
||||
|
|
|
@ -72,10 +72,10 @@ class Emulator {
|
|||
|
||||
X_STATUS Setup();
|
||||
|
||||
// TODO(benvanik): raw binary.
|
||||
X_STATUS LaunchXexFile(const std::wstring& path);
|
||||
X_STATUS LaunchDiscImage(const std::wstring& path);
|
||||
X_STATUS LaunchSTFSTitle(const std::wstring& path);
|
||||
X_STATUS LaunchPath(std::wstring path);
|
||||
X_STATUS LaunchXexFile(std::wstring path);
|
||||
X_STATUS LaunchDiscImage(std::wstring path);
|
||||
X_STATUS LaunchStfsContainer(std::wstring path);
|
||||
|
||||
private:
|
||||
X_STATUS CompleteLaunch(const std::wstring& path,
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "xenia/base/filesystem.h"
|
||||
#include "xenia/kernel/kernel_state.h"
|
||||
#include "xenia/kernel/xobject.h"
|
||||
#include "xenia/vfs/devices/host_path_device.h"
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
@ -28,14 +29,16 @@ ContentPackage::ContentPackage(KernelState* kernel_state, std::string root_name,
|
|||
: kernel_state_(kernel_state), root_name_(std::move(root_name)) {
|
||||
device_path_ = std::string("\\Device\\Content\\") +
|
||||
std::to_string(++content_device_id_) + "\\";
|
||||
kernel_state_->file_system()->RegisterHostPathDevice(device_path_,
|
||||
package_path, false);
|
||||
kernel_state_->file_system()->CreateSymbolicLink(root_name_ + ":",
|
||||
device_path_);
|
||||
|
||||
auto fs = kernel_state_->file_system();
|
||||
auto device =
|
||||
std::make_unique<vfs::HostPathDevice>(device_path_, package_path, false);
|
||||
fs->RegisterDevice(std::move(device));
|
||||
fs->RegisterSymbolicLink(root_name_ + ":", device_path_);
|
||||
}
|
||||
|
||||
ContentPackage::~ContentPackage() {
|
||||
kernel_state_->file_system()->DeleteSymbolicLink(root_name_ + ":");
|
||||
kernel_state_->file_system()->UnregisterSymbolicLink(root_name_ + ":");
|
||||
// TODO(benvanik): unregister device.
|
||||
}
|
||||
|
||||
|
|
|
@ -262,27 +262,5 @@ void MainWindow::OnCommand(int id) {
|
|||
}
|
||||
}
|
||||
|
||||
X_STATUS MainWindow::LaunchPath(std::wstring path) {
|
||||
X_STATUS result;
|
||||
|
||||
// Launch based on file type.
|
||||
// This is a silly guess based on file extension.
|
||||
// NOTE: this blocks!
|
||||
auto file_system_type = emulator_->file_system()->InferType(path);
|
||||
switch (file_system_type) {
|
||||
case vfs::FileSystemType::STFS_TITLE:
|
||||
result = emulator_->LaunchSTFSTitle(path);
|
||||
break;
|
||||
case vfs::FileSystemType::XEX_FILE:
|
||||
result = emulator_->LaunchXexFile(path);
|
||||
break;
|
||||
case vfs::FileSystemType::DISC_IMAGE:
|
||||
result = emulator_->LaunchDiscImage(path);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
} // namespace xe
|
||||
|
|
|
@ -41,8 +41,6 @@ class MainWindow : public PlatformWindow {
|
|||
|
||||
void Start();
|
||||
|
||||
X_STATUS LaunchPath(std::wstring path);
|
||||
|
||||
private:
|
||||
bool Initialize();
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
namespace xe {
|
||||
namespace vfs {
|
||||
|
||||
Device::Device(const std::string& path) : path_(path) {}
|
||||
Device::Device(const std::string& mount_path) : mount_path_(mount_path) {}
|
||||
|
||||
Device::~Device() = default;
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ class Device {
|
|||
Device(const std::string& path);
|
||||
virtual ~Device();
|
||||
|
||||
const std::string& path() const { return path_; }
|
||||
const std::string& mount_path() const { return mount_path_; }
|
||||
|
||||
virtual bool is_read_only() const { return true; }
|
||||
|
||||
|
@ -37,7 +37,7 @@ class Device {
|
|||
size_t length);
|
||||
|
||||
protected:
|
||||
std::string path_;
|
||||
std::string mount_path_;
|
||||
};
|
||||
|
||||
} // namespace vfs
|
||||
|
|
|
@ -17,29 +17,29 @@
|
|||
namespace xe {
|
||||
namespace vfs {
|
||||
|
||||
DiscImageDevice::DiscImageDevice(const std::string& path,
|
||||
DiscImageDevice::DiscImageDevice(const std::string& mount_path,
|
||||
const std::wstring& local_path)
|
||||
: Device(path), local_path_(local_path), gdfx_(nullptr) {}
|
||||
: Device(mount_path), local_path_(local_path), gdfx_(nullptr) {}
|
||||
|
||||
DiscImageDevice::~DiscImageDevice() { delete gdfx_; }
|
||||
|
||||
int DiscImageDevice::Init() {
|
||||
bool DiscImageDevice::Initialize() {
|
||||
mmap_ = MappedMemory::Open(local_path_, MappedMemory::Mode::kRead);
|
||||
if (!mmap_) {
|
||||
XELOGE("Disc image could not be mapped");
|
||||
return 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
gdfx_ = new GDFX(mmap_.get());
|
||||
GDFX::Error error = gdfx_->Load();
|
||||
if (error != GDFX::kSuccess) {
|
||||
XELOGE("GDFX init failed: %d", error);
|
||||
return 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// gdfx_->Dump();
|
||||
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr<Entry> DiscImageDevice::ResolvePath(const char* path) {
|
||||
|
|
|
@ -23,10 +23,11 @@ class GDFX;
|
|||
|
||||
class DiscImageDevice : public Device {
|
||||
public:
|
||||
DiscImageDevice(const std::string& path, const std::wstring& local_path);
|
||||
DiscImageDevice(const std::string& mount_path,
|
||||
const std::wstring& local_path);
|
||||
~DiscImageDevice() override;
|
||||
|
||||
int Init();
|
||||
bool Initialize();
|
||||
|
||||
std::unique_ptr<Entry> ResolvePath(const char* path) override;
|
||||
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
namespace xe {
|
||||
namespace vfs {
|
||||
|
||||
HostPathDevice::HostPathDevice(const std::string& path,
|
||||
HostPathDevice::HostPathDevice(const std::string& mount_path,
|
||||
const std::wstring& local_path, bool read_only)
|
||||
: Device(path), local_path_(local_path), read_only_(read_only) {}
|
||||
: Device(mount_path), local_path_(local_path), read_only_(read_only) {}
|
||||
|
||||
HostPathDevice::~HostPathDevice() {}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace vfs {
|
|||
|
||||
class HostPathDevice : public Device {
|
||||
public:
|
||||
HostPathDevice(const std::string& path, const std::wstring& local_path,
|
||||
HostPathDevice(const std::string& mount_path, const std::wstring& local_path,
|
||||
bool read_only);
|
||||
~HostPathDevice() override;
|
||||
|
||||
|
|
|
@ -18,29 +18,29 @@
|
|||
namespace xe {
|
||||
namespace vfs {
|
||||
|
||||
STFSContainerDevice::STFSContainerDevice(const std::string& path,
|
||||
STFSContainerDevice::STFSContainerDevice(const std::string& mount_path,
|
||||
const std::wstring& local_path)
|
||||
: Device(path), local_path_(local_path), stfs_(nullptr) {}
|
||||
: Device(mount_path), local_path_(local_path), stfs_(nullptr) {}
|
||||
|
||||
STFSContainerDevice::~STFSContainerDevice() { delete stfs_; }
|
||||
|
||||
int STFSContainerDevice::Init() {
|
||||
bool STFSContainerDevice::Initialize() {
|
||||
mmap_ = MappedMemory::Open(local_path_, MappedMemory::Mode::kRead);
|
||||
if (!mmap_) {
|
||||
XELOGE("STFS container could not be mapped");
|
||||
return 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
stfs_ = new STFS(mmap_.get());
|
||||
STFS::Error error = stfs_->Load();
|
||||
if (error != STFS::kSuccess) {
|
||||
XELOGE("STFS init failed: %d", error);
|
||||
return 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// stfs_->Dump();
|
||||
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr<Entry> STFSContainerDevice::ResolvePath(const char* path) {
|
||||
|
|
|
@ -23,10 +23,11 @@ class STFS;
|
|||
|
||||
class STFSContainerDevice : public Device {
|
||||
public:
|
||||
STFSContainerDevice(const std::string& path, const std::wstring& local_path);
|
||||
STFSContainerDevice(const std::string& mount_path,
|
||||
const std::wstring& local_path);
|
||||
~STFSContainerDevice() override;
|
||||
|
||||
int Init();
|
||||
bool Initialize();
|
||||
|
||||
std::unique_ptr<Entry> ResolvePath(const char* path) override;
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ MemoryMapping::~MemoryMapping() {}
|
|||
Entry::Entry(Device* device, const std::string& path)
|
||||
: device_(device), path_(path) {
|
||||
assert_not_null(device);
|
||||
absolute_path_ = device->path() + path;
|
||||
absolute_path_ = xe::join_paths(device->mount_path(), path);
|
||||
name_ = xe::find_name_from_path(path);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,9 +12,6 @@
|
|||
#include "xenia/base/filesystem.h"
|
||||
#include "xenia/base/logging.h"
|
||||
#include "xenia/base/string.h"
|
||||
#include "xenia/vfs/devices/disc_image_device.h"
|
||||
#include "xenia/vfs/devices/host_path_device.h"
|
||||
#include "xenia/vfs/devices/stfs_container_device.h"
|
||||
|
||||
namespace xe {
|
||||
namespace vfs {
|
||||
|
@ -24,128 +21,28 @@ VirtualFileSystem::VirtualFileSystem() {}
|
|||
VirtualFileSystem::~VirtualFileSystem() {
|
||||
// Delete all devices.
|
||||
// This will explode if anyone is still using data from them.
|
||||
for (std::vector<Device*>::iterator it = devices_.begin();
|
||||
it != devices_.end(); ++it) {
|
||||
delete *it;
|
||||
}
|
||||
devices_.clear();
|
||||
symlinks_.clear();
|
||||
}
|
||||
|
||||
FileSystemType VirtualFileSystem::InferType(const std::wstring& local_path) {
|
||||
auto last_slash = local_path.find_last_of(xe::path_separator);
|
||||
auto last_dot = local_path.find_last_of('.');
|
||||
if (last_dot < last_slash) {
|
||||
last_dot = std::wstring::npos;
|
||||
}
|
||||
if (last_dot == std::wstring::npos) {
|
||||
// Likely an STFS container.
|
||||
return FileSystemType::STFS_TITLE;
|
||||
} else if (local_path.substr(last_dot) == L".xex") {
|
||||
// Treat as a naked xex file.
|
||||
return FileSystemType::XEX_FILE;
|
||||
} else {
|
||||
// Assume a disc image.
|
||||
return FileSystemType::DISC_IMAGE;
|
||||
}
|
||||
bool VirtualFileSystem::RegisterDevice(std::unique_ptr<Device> device) {
|
||||
devices_.emplace_back(std::move(device));
|
||||
return true;
|
||||
}
|
||||
|
||||
int VirtualFileSystem::InitializeFromPath(FileSystemType type,
|
||||
const std::wstring& local_path) {
|
||||
switch (type) {
|
||||
case FileSystemType::STFS_TITLE: {
|
||||
// Register the container in the virtual filesystem.
|
||||
int result_code =
|
||||
RegisterSTFSContainerDevice("\\Device\\Cdrom0", local_path);
|
||||
if (result_code) {
|
||||
XELOGE("Unable to mount STFS container");
|
||||
return result_code;
|
||||
}
|
||||
|
||||
// TODO(benvanik): figure out paths.
|
||||
// Create symlinks to the device.
|
||||
CreateSymbolicLink("game:", "\\Device\\Cdrom0");
|
||||
CreateSymbolicLink("d:", "\\Device\\Cdrom0");
|
||||
break;
|
||||
}
|
||||
case FileSystemType::XEX_FILE: {
|
||||
// Get the parent path of the file.
|
||||
auto last_slash = local_path.find_last_of(xe::path_separator);
|
||||
std::wstring parent_path = local_path.substr(0, last_slash);
|
||||
|
||||
// Register the local directory in the virtual filesystem.
|
||||
int result_code = RegisterHostPathDevice(
|
||||
"\\Device\\Harddisk0\\Partition0", parent_path, true);
|
||||
if (result_code) {
|
||||
XELOGE("Unable to mount local directory");
|
||||
return result_code;
|
||||
}
|
||||
|
||||
// Create symlinks to the device.
|
||||
CreateSymbolicLink("game:", "\\Device\\Harddisk0\\Partition0");
|
||||
CreateSymbolicLink("d:", "\\Device\\Harddisk0\\Partition0");
|
||||
break;
|
||||
}
|
||||
case FileSystemType::DISC_IMAGE: {
|
||||
// Register the disc image in the virtual filesystem.
|
||||
int result_code = RegisterDiscImageDevice("\\Device\\Cdrom0", local_path);
|
||||
if (result_code) {
|
||||
XELOGE("Unable to mount disc image");
|
||||
return result_code;
|
||||
}
|
||||
|
||||
// Create symlinks to the device.
|
||||
CreateSymbolicLink("game:", "\\Device\\Cdrom0");
|
||||
CreateSymbolicLink("d:", "\\Device\\Cdrom0");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int VirtualFileSystem::RegisterDevice(const std::string& path, Device* device) {
|
||||
devices_.push_back(device);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int VirtualFileSystem::RegisterHostPathDevice(const std::string& path,
|
||||
const std::wstring& local_path,
|
||||
bool read_only) {
|
||||
Device* device = new HostPathDevice(path, local_path, read_only);
|
||||
return RegisterDevice(path, device);
|
||||
}
|
||||
|
||||
int VirtualFileSystem::RegisterDiscImageDevice(const std::string& path,
|
||||
const std::wstring& local_path) {
|
||||
DiscImageDevice* device = new DiscImageDevice(path, local_path);
|
||||
if (device->Init()) {
|
||||
return 1;
|
||||
}
|
||||
return RegisterDevice(path, device);
|
||||
}
|
||||
|
||||
int VirtualFileSystem::RegisterSTFSContainerDevice(
|
||||
const std::string& path, const std::wstring& local_path) {
|
||||
STFSContainerDevice* device = new STFSContainerDevice(path, local_path);
|
||||
if (device->Init()) {
|
||||
return 1;
|
||||
}
|
||||
return RegisterDevice(path, device);
|
||||
}
|
||||
|
||||
int VirtualFileSystem::CreateSymbolicLink(const std::string& path,
|
||||
const std::string& target) {
|
||||
bool VirtualFileSystem::RegisterSymbolicLink(std::string path,
|
||||
std::string target) {
|
||||
symlinks_.insert({path, target});
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
int VirtualFileSystem::DeleteSymbolicLink(const std::string& path) {
|
||||
bool VirtualFileSystem::UnregisterSymbolicLink(std::string path) {
|
||||
auto& it = symlinks_.find(path);
|
||||
if (it == symlinks_.end()) {
|
||||
return 1;
|
||||
return false;
|
||||
}
|
||||
symlinks_.erase(it);
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr<Entry> VirtualFileSystem::ResolvePath(const std::string& path) {
|
||||
|
@ -167,8 +64,8 @@ std::unique_ptr<Entry> VirtualFileSystem::ResolvePath(const std::string& path) {
|
|||
// Not to fret, check to see if the path is fully qualified.
|
||||
if (device_path.empty()) {
|
||||
for (auto& device : devices_) {
|
||||
if (xe::find_first_of_case(normalized_path, device->path()) == 0) {
|
||||
device_path = device->path();
|
||||
if (xe::find_first_of_case(normalized_path, device->mount_path()) == 0) {
|
||||
device_path = device->mount_path();
|
||||
relative_path = normalized_path.substr(device_path.size());
|
||||
}
|
||||
}
|
||||
|
@ -181,7 +78,7 @@ std::unique_ptr<Entry> VirtualFileSystem::ResolvePath(const std::string& path) {
|
|||
|
||||
// Scan all devices.
|
||||
for (auto& device : devices_) {
|
||||
if (strcasecmp(device_path.c_str(), device->path().c_str()) == 0) {
|
||||
if (strcasecmp(device_path.c_str(), device->mount_path().c_str()) == 0) {
|
||||
return device->ResolvePath(relative_path.c_str());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,44 +15,28 @@
|
|||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "xenia/vfs/device.h"
|
||||
#include "xenia/vfs/entry.h"
|
||||
|
||||
namespace xe {
|
||||
namespace vfs {
|
||||
|
||||
class Device;
|
||||
|
||||
enum class FileSystemType {
|
||||
STFS_TITLE,
|
||||
DISC_IMAGE,
|
||||
XEX_FILE,
|
||||
};
|
||||
|
||||
class VirtualFileSystem {
|
||||
public:
|
||||
VirtualFileSystem();
|
||||
~VirtualFileSystem();
|
||||
|
||||
FileSystemType InferType(const std::wstring& local_path);
|
||||
int InitializeFromPath(FileSystemType type, const std::wstring& local_path);
|
||||
bool RegisterDevice(std::unique_ptr<Device> device);
|
||||
|
||||
int RegisterDevice(const std::string& path, Device* device);
|
||||
int RegisterHostPathDevice(const std::string& path,
|
||||
const std::wstring& local_path, bool read_only);
|
||||
int RegisterDiscImageDevice(const std::string& path,
|
||||
const std::wstring& local_path);
|
||||
int RegisterSTFSContainerDevice(const std::string& path,
|
||||
const std::wstring& local_path);
|
||||
|
||||
int CreateSymbolicLink(const std::string& path, const std::string& target);
|
||||
int DeleteSymbolicLink(const std::string& path);
|
||||
bool RegisterSymbolicLink(std::string path, std::string target);
|
||||
bool UnregisterSymbolicLink(std::string path);
|
||||
|
||||
std::unique_ptr<Entry> ResolvePath(const std::string& path);
|
||||
X_STATUS Open(std::unique_ptr<Entry> entry, KernelState* kernel_state,
|
||||
Mode mode, bool async, XFile** out_file);
|
||||
|
||||
private:
|
||||
std::vector<Device*> devices_;
|
||||
std::vector<std::unique_ptr<Device>> devices_;
|
||||
std::unordered_map<std::string, std::string> symlinks_;
|
||||
};
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ int xenia_main(std::vector<std::wstring>& args) {
|
|||
// Normalize the path and make absolute.
|
||||
std::wstring abs_path = xe::to_absolute_path(path);
|
||||
|
||||
result = emulator->main_window()->LaunchPath(abs_path);
|
||||
result = emulator->LaunchPath(abs_path);
|
||||
if (XFAILED(result)) {
|
||||
XELOGE("Failed to launch target: %.8X", result);
|
||||
return 1;
|
||||
|
|
Loading…
Reference in New Issue