[Kernel] - swapdisc fixes for gtav

This commit is contained in:
Cancerous 2019-12-19 17:29:24 -05:00 committed by illusion98
parent 96a75cefe3
commit 7fefb79339
3 changed files with 57 additions and 47 deletions

View File

@ -431,14 +431,16 @@ void EmulatorWindow::RecentList(int index) {
}
}
std::wstring EmulatorWindow::SwapNext() {
std::wstring EmulatorWindow::SwapNext(int8_t disc_number) {
std::wstring path = L"";
auto file_picker = xe::ui::FilePicker::Create();
file_picker->set_mode(ui::FilePicker::Mode::kOpen);
file_picker->set_type(ui::FilePicker::Type::kFile);
file_picker->set_multi_selection(false);
file_picker->set_title(L"Select Content Package");
char titlebar[16];
sprintf(titlebar, "Select Disc:(%d)", disc_number);
file_picker->set_title(xe::to_wstring(titlebar));
file_picker->set_extensions({
{L"Supported Files", L"*.iso;*.xex;*.xcp;*.*"},
{L"Disc Image (*.iso)", L"*.iso"},
@ -452,6 +454,11 @@ std::wstring EmulatorWindow::SwapNext() {
path = selected_files[0];
}
}
if (path != L"") {
// Normalize the path and make absolute.
std::wstring abs_path = xe::to_absolute_path(path);
}
XELOGD("SwapNext Return Path:(%S)", path.c_str());
return path;
}

View File

@ -37,7 +37,7 @@ class EmulatorWindow {
void UpdateTitle();
void ToggleFullscreen();
static std::wstring SwapNext();
static std::wstring SwapNext(int8_t disc_number);
private:
explicit EmulatorWindow(Emulator* emulator);

View File

@ -488,54 +488,55 @@ DECLARE_XAM_EXPORT1(XamContentDelete, kContent, kImplemented);
dword_result_t XamSwapDisc(dword_t disc_number,
pointer_t<kernel::X_KEVENT> completion_handle,
lpstring_t error_message) {
auto filesystem = kernel_state()->file_system();
auto mount_path = "\\Device\\LauncherData";
if (filesystem->ResolveDevice(mount_path) != NULL) {
filesystem->UnregisterDevice(mount_path);
}
// error_message not correct type/ptr
XELOGI("XamSwapDisc requests disc %d.", disc_number);
std::wstring local_path = app::EmulatorWindow::SwapNext();
XELOGI("SwapNext returned path %S.", local_path.c_str());
XELOGI("XamSwapDisc requests disc:(%d)", disc_number);
std::wstring local_path = app::EmulatorWindow::SwapNext(disc_number);
XELOGD("XamSwapDisc SwapNext returned path:( %S )", local_path.c_str());
if (local_path != L"") {
auto filesystem = kernel_state()->file_system();
auto mount_path = "\\Device\\LauncherData";
auto last_slash = local_path.find_last_of(xe::kPathSeparator);
auto last_dot = local_path.find_last_of('.');
auto last_slash = local_path.find_last_of(xe::kPathSeparator);
auto last_dot = local_path.find_last_of('.');
if (filesystem->ResolveDevice(mount_path) != NULL) {
filesystem->UnregisterDevice(mount_path);
}
if (last_dot < last_slash) {
last_dot = std::wstring::npos;
}
if (last_dot == std::wstring::npos) {
// Likely an STFS container.
auto dev =
std::make_unique<vfs::StfsContainerDevice>(mount_path, local_path);
dev->Initialize();
filesystem->RegisterDevice(std::move(dev));
};
auto extension = local_path.substr(last_dot);
std::transform(extension.begin(), extension.end(), extension.begin(),
tolower);
if (extension == L".xex" || extension == L".elf" || extension == L".exe") {
// Treat as a naked xex file.
auto parent_path = xe::find_base_path(local_path);
auto dev =
std::make_unique<vfs::HostPathDevice>(mount_path, parent_path, true);
dev->Initialize();
filesystem->RegisterDevice(std::move(dev));
} else {
// Assume a disc image.
auto dev = std::make_unique<vfs::DiscImageDevice>(mount_path, local_path);
dev->Initialize();
filesystem->RegisterDevice(std::move(dev));
}
// Register the new device to d: and game:
filesystem->UnregisterSymbolicLink("d:");
filesystem->UnregisterSymbolicLink("game:");
filesystem->RegisterSymbolicLink("d:", mount_path);
filesystem->RegisterSymbolicLink("game:", mount_path);
if (last_dot < last_slash) {
last_dot = std::wstring::npos;
}
if (last_dot == std::wstring::npos) {
// Likely an STFS container.
auto dev =
std::make_unique<vfs::StfsContainerDevice>(mount_path, local_path);
dev->Initialize();
filesystem->RegisterDevice(std::move(dev));
};
auto extension = local_path.substr(last_dot);
std::transform(extension.begin(), extension.end(), extension.begin(),
tolower);
if (extension == L".xex" || extension == L".elf" || extension == L".exe") {
// Treat as a naked xex file.
auto parent_path = xe::find_base_path(local_path);
auto dev =
std::make_unique<vfs::HostPathDevice>(mount_path, parent_path, true);
dev->Initialize();
filesystem->RegisterDevice(std::move(dev));
} else {
// Assume a disc image.
auto dev = std::make_unique<vfs::DiscImageDevice>(mount_path, local_path);
dev->Initialize();
filesystem->RegisterDevice(std::move(dev));
}
// Register the new device to d: and game:
filesystem->UnregisterSymbolicLink("d:");
filesystem->UnregisterSymbolicLink("game:");
filesystem->RegisterSymbolicLink("d:", mount_path);
filesystem->RegisterSymbolicLink("game:", mount_path);
// Resolve the pending disc swap event
auto kevent = xboxkrnl::xeKeSetEvent(completion_handle, 1, 0);
@ -543,8 +544,10 @@ dword_result_t XamSwapDisc(dword_t disc_number,
auto object = XObject::GetNativeObject<XObject>(
kernel_state(),
kernel_memory()->virtual_membase() + (dword_t)completion_handle);
if (object) {
object->Release();
XELOGI("XamSwapDisc Release object");
object->ReleaseHandle();
}
return 0;