diff --git a/src/xenia/cpu/ppc/ppc_emit_control.cc b/src/xenia/cpu/ppc/ppc_emit_control.cc index 15c990339..4db762606 100644 --- a/src/xenia/cpu/ppc/ppc_emit_control.cc +++ b/src/xenia/cpu/ppc/ppc_emit_control.cc @@ -609,6 +609,10 @@ int InstrEmit_mfspr(PPCHIRBuilder& f, const InstrData& i) { // TBU v = f.Shr(f.LoadClock(), 32); break; + case 287: + // PVR + v = f.LoadConstantUint64(0x710800); + break; default: XEINSTRNOTIMPLEMENTED(); return 1; diff --git a/src/xenia/emulator.cc b/src/xenia/emulator.cc index 6e2767dd3..3f7e06555 100644 --- a/src/xenia/emulator.cc +++ b/src/xenia/emulator.cc @@ -276,24 +276,32 @@ X_STATUS Emulator::LaunchXexFile(std::wstring path) { // and then get that symlinked to game:\, so // -> game:\foo.xex - auto mount_path = "\\Device\\Harddisk0\\Partition0"; + // Register local directory as some commonly used mount paths + std::string mount_paths[] = { + "\\Device\\Harddisk0\\Partition0", + "\\Device\\Harddisk0\\Partition1", + "\\Device\\Harddisk0\\Partition1\\DEVKIT", + "\\Device\\LauncherData", + "\\SystemRoot", + }; - // Register the local directory in the virtual filesystem. auto parent_path = xe::find_base_path(path); - auto device = - std::make_unique(mount_path, parent_path, true); - if (!device->Initialize()) { - XELOGE("Unable to scan host path"); - return X_STATUS_NO_SUCH_FILE; - } - if (!file_system_->RegisterDevice(std::move(device))) { - XELOGE("Unable to register host path"); - return X_STATUS_NO_SUCH_FILE; + for (auto path : mount_paths) { + auto device = + std::make_unique(path, parent_path, true); + if (!device->Initialize()) { + XELOGE("Unable to scan host path"); + return X_STATUS_NO_SUCH_FILE; + } + if (!file_system_->RegisterDevice(std::move(device))) { + XELOGE("Unable to register host path as %s", path.c_str()); + return X_STATUS_NO_SUCH_FILE; + } } // Create symlinks to the device. - file_system_->RegisterSymbolicLink("game:", mount_path); - file_system_->RegisterSymbolicLink("d:", mount_path); + file_system_->RegisterSymbolicLink("game:", mount_paths[0]); + file_system_->RegisterSymbolicLink("d:", mount_paths[0]); // Get just the filename (foo.xex). auto file_name = xe::find_name_from_path(path); diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_xconfig.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_xconfig.cc index cad856f8f..f751b5ed1 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_xconfig.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_xconfig.cc @@ -15,6 +15,9 @@ #include "xenia/kernel/xboxkrnl/xboxkrnl_private.h" #include "xenia/xbox.h" +DEFINE_bool(xconfig_initial_setup, false, + "Enable the dashboard initial setup/OOBE", "Kernel"); + DEFINE_int32(user_language, 1, "User language ID. " "1=en / 2=ja / 3=de / 4=fr / 5=es / 6=it / 7=ko / 8=zh / 9=pt / " @@ -56,6 +59,9 @@ X_STATUS xeExGetXConfigSetting(uint16_t category, uint16_t setting, case 0x0002: // XCONFIG_SECURED_CATEGORY switch (setting) { + case 0x0001: // XCONFIG_SECURED_MAC_ADDRESS (6 bytes) + return X_STATUS_SUCCESS; // Just return, easier than setting up code + // for different size configs case 0x0002: // XCONFIG_SECURED_AV_REGION setting_size = 4; xe::store_and_swap(value, 0x00001000); // USA/Canada @@ -90,12 +96,24 @@ X_STATUS xeExGetXConfigSetting(uint16_t category, uint16_t setting, case 0x000C: // XCONFIG_USER_RETAIL_FLAGS setting_size = 4; // TODO(benvanik): get this value. - xe::store_and_swap(value, 0); + // 0x40 = dashboard initial setup complete + xe::store_and_swap(value, + cvars::xconfig_initial_setup ? 0 : 0x40); break; case 0x000E: // XCONFIG_USER_COUNTRY setting_size = 1; value[0] = static_cast(cvars::user_country); break; + case 0x000F: // XCONFIG_USER_PC_FLAGS (parental control?) + setting_size = 1; + xe::store_and_swap(value, 0); // value[0]? + break; + case 0x0010: // XCONFIG_USER_SMB_CONFIG (0x100 byte string) + // Just set the start of the buffer to 0 so that callers + // don't error from an un-inited buffer + setting_size = 4; + xe::store_and_swap(value, 0); + break; default: assert_unhandled_case(setting); return X_STATUS_INVALID_PARAMETER_2; diff --git a/src/xenia/vfs/virtual_file_system.cc b/src/xenia/vfs/virtual_file_system.cc index aae42a1f0..15f37702b 100644 --- a/src/xenia/vfs/virtual_file_system.cc +++ b/src/xenia/vfs/virtual_file_system.cc @@ -66,6 +66,15 @@ bool VirtualFileSystem::UnregisterSymbolicLink(const std::string& path) { return true; } +bool VirtualFileSystem::IsSymbolicLink(const std::string& path) { + auto global_lock = global_critical_region_.Acquire(); + auto it = symlinks_.find(path); + if (it == symlinks_.end()) { + return false; + } + return true; +} + bool VirtualFileSystem::FindSymbolicLink(const std::string& path, std::string& target) { auto it = diff --git a/src/xenia/vfs/virtual_file_system.h b/src/xenia/vfs/virtual_file_system.h index 523299ad7..2d84525ac 100644 --- a/src/xenia/vfs/virtual_file_system.h +++ b/src/xenia/vfs/virtual_file_system.h @@ -33,6 +33,7 @@ class VirtualFileSystem { bool RegisterSymbolicLink(const std::string& path, const std::string& target); bool UnregisterSymbolicLink(const std::string& path); + bool VirtualFileSystem::IsSymbolicLink(const std::string& path); bool FindSymbolicLink(const std::string& path, std::string& target); Entry* ResolvePath(const std::string& path);