mirror of
https://github.com/xenia-project/xenia.git
synced 2025-12-06 07:12:03 +01:00
Merge 840dc7acab into 01ae24e46e
This commit is contained in:
commit
b28c7c8401
|
|
@ -316,6 +316,7 @@ X_STATUS Emulator::LaunchXexFile(const std::filesystem::path& path) {
|
||||||
|
|
||||||
// Create symlinks to the device.
|
// Create symlinks to the device.
|
||||||
file_system_->RegisterSymbolicLink("game:", mount_path);
|
file_system_->RegisterSymbolicLink("game:", mount_path);
|
||||||
|
file_system_->RegisterSymbolicLink("update:", mount_path);
|
||||||
file_system_->RegisterSymbolicLink("d:", mount_path);
|
file_system_->RegisterSymbolicLink("d:", mount_path);
|
||||||
|
|
||||||
// Get just the filename (foo.xex).
|
// Get just the filename (foo.xex).
|
||||||
|
|
@ -342,6 +343,7 @@ X_STATUS Emulator::LaunchDiscImage(const std::filesystem::path& path) {
|
||||||
|
|
||||||
// Create symlinks to the device.
|
// Create symlinks to the device.
|
||||||
file_system_->RegisterSymbolicLink("game:", mount_path);
|
file_system_->RegisterSymbolicLink("game:", mount_path);
|
||||||
|
file_system_->RegisterSymbolicLink("update:", mount_path);
|
||||||
file_system_->RegisterSymbolicLink("d:", mount_path);
|
file_system_->RegisterSymbolicLink("d:", mount_path);
|
||||||
|
|
||||||
// Launch the game.
|
// Launch the game.
|
||||||
|
|
@ -365,6 +367,7 @@ X_STATUS Emulator::LaunchStfsContainer(const std::filesystem::path& path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
file_system_->RegisterSymbolicLink("game:", mount_path);
|
file_system_->RegisterSymbolicLink("game:", mount_path);
|
||||||
|
file_system_->RegisterSymbolicLink("update:", mount_path);
|
||||||
file_system_->RegisterSymbolicLink("d:", mount_path);
|
file_system_->RegisterSymbolicLink("d:", mount_path);
|
||||||
|
|
||||||
// Launch the game.
|
// Launch the game.
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
#include "xenia/kernel/xfile.h"
|
#include "xenia/kernel/xfile.h"
|
||||||
#include "xenia/kernel/xobject.h"
|
#include "xenia/kernel/xobject.h"
|
||||||
#include "xenia/vfs/devices/host_path_device.h"
|
#include "xenia/vfs/devices/host_path_device.h"
|
||||||
|
#include "xenia/vfs/devices/stfs_container_device.h"
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
namespace xam {
|
namespace xam {
|
||||||
|
|
@ -32,14 +32,21 @@ static int content_device_id_ = 0;
|
||||||
ContentPackage::ContentPackage(KernelState* kernel_state,
|
ContentPackage::ContentPackage(KernelState* kernel_state,
|
||||||
const std::string_view root_name,
|
const std::string_view root_name,
|
||||||
const XCONTENT_AGGREGATE_DATA& data,
|
const XCONTENT_AGGREGATE_DATA& data,
|
||||||
const std::filesystem::path& package_path)
|
const std::filesystem::path& package_path,
|
||||||
|
bool stfs)
|
||||||
: kernel_state_(kernel_state), root_name_(root_name) {
|
: kernel_state_(kernel_state), root_name_(root_name) {
|
||||||
device_path_ = fmt::format("\\Device\\Content\\{0}\\", ++content_device_id_);
|
device_path_ = fmt::format("\\Device\\Content\\{0}\\", ++content_device_id_);
|
||||||
content_data_ = data;
|
content_data_ = data;
|
||||||
|
|
||||||
auto fs = kernel_state_->file_system();
|
auto fs = kernel_state_->file_system();
|
||||||
auto device =
|
std::unique_ptr<vfs::Device> device;
|
||||||
std::make_unique<vfs::HostPathDevice>(device_path_, package_path, false);
|
if (stfs)
|
||||||
|
device =
|
||||||
|
std::make_unique<vfs::StfsContainerDevice>(device_path_, package_path);
|
||||||
|
else
|
||||||
|
device = std::make_unique<vfs::HostPathDevice>(device_path_, package_path,
|
||||||
|
false);
|
||||||
|
|
||||||
device->Initialize();
|
device->Initialize();
|
||||||
fs->RegisterDevice(std::move(device));
|
fs->RegisterDevice(std::move(device));
|
||||||
fs->RegisterSymbolicLink(root_name_ + ":", device_path_);
|
fs->RegisterSymbolicLink(root_name_ + ":", device_path_);
|
||||||
|
|
@ -153,6 +160,49 @@ X_RESULT ContentManager::CreateContent(const std::string_view root_name,
|
||||||
return X_ERROR_SUCCESS;
|
return X_ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// saves content from vfs to host
|
||||||
|
// if successful, initlisised data thats passed.
|
||||||
|
X_RESULT ContentManager::MountContentToHost(const std::string_view vpath,
|
||||||
|
const std::string_view root_name,
|
||||||
|
XCONTENT_AGGREGATE_DATA& data) {
|
||||||
|
data.content_type =
|
||||||
|
XContentType::kAvatarItem; //? this is what velocity says for
|
||||||
|
// Database,NuiIdentity
|
||||||
|
data.device_id = 4; // DeviceType::ODD;
|
||||||
|
data.set_display_name(to_utf16(root_name));
|
||||||
|
data.title_id = kernel_state_->title_id();
|
||||||
|
data.set_file_name(root_name);
|
||||||
|
|
||||||
|
auto path = ResolvePackagePath(data);
|
||||||
|
if (!std::filesystem::exists(path)) {
|
||||||
|
std::filesystem::create_directories(path.parent_path());
|
||||||
|
auto fs = kernel_state_->file_system();
|
||||||
|
auto hostfile = xe::filesystem::OpenFile(path, "wb");
|
||||||
|
xe::vfs::FileAction action;
|
||||||
|
xe::vfs::File* guestFile;
|
||||||
|
fs->OpenFile(nullptr, vpath, xe::vfs::FileDisposition::kOpen,
|
||||||
|
xe::vfs::FileAccess::kGenericRead, false, true, &guestFile,
|
||||||
|
&action);
|
||||||
|
|
||||||
|
auto size = guestFile->entry()->size();
|
||||||
|
std::vector<uint8_t> buffer(size);
|
||||||
|
size_t read;
|
||||||
|
guestFile->ReadSync(buffer.data(), size, 0, &read);
|
||||||
|
fwrite(buffer.data(), 1, size, hostfile);
|
||||||
|
fclose(hostfile);
|
||||||
|
}
|
||||||
|
if (open_packages_.count(string_key(root_name))) {
|
||||||
|
return X_ERROR_ALREADY_EXISTS;
|
||||||
|
}
|
||||||
|
auto global_lock = global_critical_region_.Acquire();
|
||||||
|
|
||||||
|
auto package = std::make_unique<ContentPackage>(kernel_state_, root_name,
|
||||||
|
data, path, true);
|
||||||
|
open_packages_.insert({string_key::create(root_name), package.release()});
|
||||||
|
|
||||||
|
return X_E_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
X_RESULT ContentManager::OpenContent(const std::string_view root_name,
|
X_RESULT ContentManager::OpenContent(const std::string_view root_name,
|
||||||
const XCONTENT_AGGREGATE_DATA& data) {
|
const XCONTENT_AGGREGATE_DATA& data) {
|
||||||
auto global_lock = global_critical_region_.Acquire();
|
auto global_lock = global_critical_region_.Acquire();
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
#include "xenia/base/mutex.h"
|
#include "xenia/base/mutex.h"
|
||||||
#include "xenia/base/string_key.h"
|
#include "xenia/base/string_key.h"
|
||||||
#include "xenia/base/string_util.h"
|
#include "xenia/base/string_util.h"
|
||||||
|
#include "xenia/vfs/devices/host_path_device.h"
|
||||||
#include "xenia/xbox.h"
|
#include "xenia/xbox.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
|
@ -121,7 +122,7 @@ class ContentPackage {
|
||||||
public:
|
public:
|
||||||
ContentPackage(KernelState* kernel_state, const std::string_view root_name,
|
ContentPackage(KernelState* kernel_state, const std::string_view root_name,
|
||||||
const XCONTENT_AGGREGATE_DATA& data,
|
const XCONTENT_AGGREGATE_DATA& data,
|
||||||
const std::filesystem::path& package_path);
|
const std::filesystem::path& package_path, bool stfs = false);
|
||||||
~ContentPackage();
|
~ContentPackage();
|
||||||
|
|
||||||
const XCONTENT_AGGREGATE_DATA& GetPackageContentData() const {
|
const XCONTENT_AGGREGATE_DATA& GetPackageContentData() const {
|
||||||
|
|
@ -151,6 +152,9 @@ class ContentManager {
|
||||||
bool ContentExists(const XCONTENT_AGGREGATE_DATA& data);
|
bool ContentExists(const XCONTENT_AGGREGATE_DATA& data);
|
||||||
X_RESULT CreateContent(const std::string_view root_name,
|
X_RESULT CreateContent(const std::string_view root_name,
|
||||||
const XCONTENT_AGGREGATE_DATA& data);
|
const XCONTENT_AGGREGATE_DATA& data);
|
||||||
|
X_RESULT MountContentToHost(const std::string_view vpath,
|
||||||
|
const std::string_view root_name,
|
||||||
|
XCONTENT_AGGREGATE_DATA& data);
|
||||||
X_RESULT OpenContent(const std::string_view root_name,
|
X_RESULT OpenContent(const std::string_view root_name,
|
||||||
const XCONTENT_AGGREGATE_DATA& data);
|
const XCONTENT_AGGREGATE_DATA& data);
|
||||||
X_RESULT CloseContent(const std::string_view root_name);
|
X_RESULT CloseContent(const std::string_view root_name);
|
||||||
|
|
|
||||||
|
|
@ -259,8 +259,10 @@ dword_result_t XamContentOpenFile_entry(dword_t user_index,
|
||||||
lpdword_t disposition_ptr,
|
lpdword_t disposition_ptr,
|
||||||
lpdword_t license_mask_ptr,
|
lpdword_t license_mask_ptr,
|
||||||
lpvoid_t overlapped_ptr) {
|
lpvoid_t overlapped_ptr) {
|
||||||
// TODO(gibbed): arguments assumed based on XamContentCreate.
|
auto content_manager = kernel_state()->content_manager();
|
||||||
return X_ERROR_FILE_NOT_FOUND;
|
XCONTENT_AGGREGATE_DATA data;
|
||||||
|
return content_manager->MountContentToHost(path.value(), root_name.value(),
|
||||||
|
data);
|
||||||
}
|
}
|
||||||
DECLARE_XAM_EXPORT1(XamContentOpenFile, kContent, kStub);
|
DECLARE_XAM_EXPORT1(XamContentOpenFile, kContent, kStub);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue