diff options
Diffstat (limited to 'src/core/hle/service')
23 files changed, 352 insertions, 55 deletions
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 3ec0e1eca..615e20a54 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -508,7 +508,7 @@ public: {1, &IManagerForApplication::GetAccountId, "GetAccountId"}, {2, nullptr, "EnsureIdTokenCacheAsync"}, {3, nullptr, "LoadIdTokenCache"}, - {130, nullptr, "GetNintendoAccountUserResourceCacheForApplication"}, + {130, &IManagerForApplication::GetNintendoAccountUserResourceCacheForApplication, "GetNintendoAccountUserResourceCacheForApplication"}, {150, nullptr, "CreateAuthorizationRequest"}, {160, &IManagerForApplication::StoreOpenContext, "StoreOpenContext"}, {170, nullptr, "LoadNetworkServiceLicenseKindAsync"}, @@ -534,6 +534,22 @@ private: rb.PushRaw<u64>(user_id.GetNintendoID()); } + void GetNintendoAccountUserResourceCacheForApplication(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_ACC, "(STUBBED) called"); + + std::vector<u8> nas_user_base_for_application(0x68); + ctx.WriteBuffer(nas_user_base_for_application, 0); + + if (ctx.CanWriteBuffer(1)) { + std::vector<u8> unknown_out_buffer(ctx.GetWriteBufferSize(1)); + ctx.WriteBuffer(unknown_out_buffer, 1); + } + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(RESULT_SUCCESS); + rb.PushRaw<u64>(user_id.GetNintendoID()); + } + void StoreOpenContext(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_ACC, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index bb77c2569..8e1fe9438 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -1047,20 +1047,21 @@ void IStorageAccessor::Write(Kernel::HLERequestContext& ctx) { const u64 offset{rp.Pop<u64>()}; const std::vector<u8> data{ctx.ReadBuffer()}; + const std::size_t size{std::min(data.size(), backing.GetSize() - offset)}; - LOG_DEBUG(Service_AM, "called, offset={}, size={}", offset, data.size()); + LOG_DEBUG(Service_AM, "called, offset={}, size={}", offset, size); - if (data.size() > backing.GetSize() - offset) { + if (offset > backing.GetSize()) { LOG_ERROR(Service_AM, "offset is out of bounds, backing_buffer_sz={}, data_size={}, offset={}", - backing.GetSize(), data.size(), offset); + backing.GetSize(), size, offset); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ERR_SIZE_OUT_OF_BOUNDS); return; } - std::memcpy(backing.GetData().data() + offset, data.data(), data.size()); + std::memcpy(backing.GetData().data() + offset, data.data(), size); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); @@ -1070,11 +1071,11 @@ void IStorageAccessor::Read(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const u64 offset{rp.Pop<u64>()}; - const std::size_t size{ctx.GetWriteBufferSize()}; + const std::size_t size{std::min(ctx.GetWriteBufferSize(), backing.GetSize() - offset)}; LOG_DEBUG(Service_AM, "called, offset={}, size={}", offset, size); - if (size > backing.GetSize() - offset) { + if (offset > backing.GetSize()) { LOG_ERROR(Service_AM, "offset is out of bounds, backing_buffer_sz={}, size={}, offset={}", backing.GetSize(), size, offset); diff --git a/src/core/hle/service/am/applets/controller.cpp b/src/core/hle/service/am/applets/controller.cpp index d7d3ee99a..c2bfe698f 100644 --- a/src/core/hle/service/am/applets/controller.cpp +++ b/src/core/hle/service/am/applets/controller.cpp @@ -211,7 +211,8 @@ void Controller::Execute() { case ControllerSupportMode::ShowControllerFirmwareUpdate: UNIMPLEMENTED_MSG("ControllerSupportMode={} is not implemented", controller_private_arg.mode); - [[fallthrough]]; + ConfigurationComplete(); + break; default: { ConfigurationComplete(); break; diff --git a/src/core/hle/service/am/applets/software_keyboard.cpp b/src/core/hle/service/am/applets/software_keyboard.cpp index 3022438b1..79b209c6b 100644 --- a/src/core/hle/service/am/applets/software_keyboard.cpp +++ b/src/core/hle/service/am/applets/software_keyboard.cpp @@ -121,6 +121,10 @@ void SoftwareKeyboard::ExecuteInteractive() { std::memcpy(&request, data.data(), sizeof(Request)); switch (request) { + case Request::Finalize: + complete = true; + broker.SignalStateChanged(); + break; case Request::Calc: { broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>{1})); broker.SignalStateChanged(); diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index dbf198345..70b9f3824 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -21,6 +21,7 @@ namespace Service::HID { constexpr s32 HID_JOYSTICK_MAX = 0x7fff; +constexpr s32 HID_TRIGGER_MAX = 0x7fff; [[maybe_unused]] constexpr s32 HID_JOYSTICK_MIN = -0x7fff; constexpr std::size_t NPAD_OFFSET = 0x9A00; constexpr u32 BATTERY_FULL = 2; @@ -48,6 +49,8 @@ Controller_NPad::NPadControllerType Controller_NPad::MapSettingsTypeToNPad( return NPadControllerType::JoyRight; case Settings::ControllerType::Handheld: return NPadControllerType::Handheld; + case Settings::ControllerType::GameCube: + return NPadControllerType::GameCube; default: UNREACHABLE(); return NPadControllerType::ProController; @@ -67,6 +70,8 @@ Settings::ControllerType Controller_NPad::MapNPadToSettingsType( return Settings::ControllerType::RightJoycon; case NPadControllerType::Handheld: return Settings::ControllerType::Handheld; + case NPadControllerType::GameCube: + return Settings::ControllerType::GameCube; default: UNREACHABLE(); return Settings::ControllerType::ProController; @@ -209,6 +214,13 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) { controller.assignment_mode = NpadAssignments::Single; controller.footer_type = AppletFooterUiType::JoyRightHorizontal; break; + case NPadControllerType::GameCube: + controller.style_set.gamecube.Assign(1); + // The GC Controller behaves like a wired Pro Controller + controller.device_type.fullkey.Assign(1); + controller.system_properties.is_vertical.Assign(1); + controller.system_properties.use_plus.Assign(1); + break; case NPadControllerType::Pokeball: controller.style_set.palma.Assign(1); controller.device_type.palma.Assign(1); @@ -259,6 +271,7 @@ void Controller_NPad::OnInit() { style.joycon_right.Assign(1); style.joycon_dual.Assign(1); style.fullkey.Assign(1); + style.gamecube.Assign(1); style.palma.Assign(1); } @@ -339,6 +352,7 @@ void Controller_NPad::RequestPadStateUpdate(u32 npad_id) { auto& pad_state = npad_pad_states[controller_idx].pad_states; auto& lstick_entry = npad_pad_states[controller_idx].l_stick; auto& rstick_entry = npad_pad_states[controller_idx].r_stick; + auto& trigger_entry = npad_trigger_states[controller_idx]; const auto& button_state = buttons[controller_idx]; const auto& analog_state = sticks[controller_idx]; const auto [stick_l_x_f, stick_l_y_f] = @@ -404,6 +418,17 @@ void Controller_NPad::RequestPadStateUpdate(u32 npad_id) { pad_state.left_sl.Assign(button_state[SL - BUTTON_HID_BEGIN]->GetStatus()); pad_state.left_sr.Assign(button_state[SR - BUTTON_HID_BEGIN]->GetStatus()); } + + if (controller_type == NPadControllerType::GameCube) { + trigger_entry.l_analog = static_cast<s32>( + button_state[ZL - BUTTON_HID_BEGIN]->GetStatus() ? HID_TRIGGER_MAX : 0); + trigger_entry.r_analog = static_cast<s32>( + button_state[ZR - BUTTON_HID_BEGIN]->GetStatus() ? HID_TRIGGER_MAX : 0); + pad_state.zl.Assign(false); + pad_state.zr.Assign(button_state[R - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.l.Assign(button_state[ZL - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.r.Assign(button_state[ZR - BUTTON_HID_BEGIN]->GetStatus()); + } } void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, @@ -418,6 +443,11 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* &npad.joy_left_states, &npad.joy_right_states, &npad.palma_states, &npad.system_ext_states}; + // There is the posibility to have more controllers with analog triggers + const std::array<TriggerGeneric*, 1> controller_triggers{ + &npad.gc_trigger_states, + }; + for (auto* main_controller : controller_npads) { main_controller->common.entry_count = 16; main_controller->common.total_entry_count = 17; @@ -435,6 +465,21 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* cur_entry.timestamp2 = cur_entry.timestamp; } + for (auto* analog_trigger : controller_triggers) { + analog_trigger->entry_count = 16; + analog_trigger->total_entry_count = 17; + + const auto& last_entry = analog_trigger->trigger[analog_trigger->last_entry_index]; + + analog_trigger->timestamp = core_timing.GetCPUTicks(); + analog_trigger->last_entry_index = (analog_trigger->last_entry_index + 1) % 17; + + auto& cur_entry = analog_trigger->trigger[analog_trigger->last_entry_index]; + + cur_entry.timestamp = last_entry.timestamp + 1; + cur_entry.timestamp2 = cur_entry.timestamp; + } + const auto& controller_type = connected_controllers[i].type; if (controller_type == NPadControllerType::None || !connected_controllers[i].is_connected) { @@ -444,6 +489,7 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* RequestPadStateUpdate(npad_index); auto& pad_state = npad_pad_states[npad_index]; + auto& trigger_state = npad_trigger_states[npad_index]; auto& main_controller = npad.fullkey_states.npad[npad.fullkey_states.common.last_entry_index]; @@ -456,6 +502,8 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* auto& pokeball_entry = npad.palma_states.npad[npad.palma_states.common.last_entry_index]; auto& libnx_entry = npad.system_ext_states.npad[npad.system_ext_states.common.last_entry_index]; + auto& trigger_entry = + npad.gc_trigger_states.trigger[npad.gc_trigger_states.last_entry_index]; libnx_entry.connection_status.raw = 0; libnx_entry.connection_status.is_connected.Assign(1); @@ -524,6 +572,18 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* libnx_entry.connection_status.is_right_connected.Assign(1); break; + case NPadControllerType::GameCube: + main_controller.connection_status.raw = 0; + main_controller.connection_status.is_connected.Assign(1); + main_controller.connection_status.is_wired.Assign(1); + main_controller.pad.pad_states.raw = pad_state.pad_states.raw; + main_controller.pad.l_stick = pad_state.l_stick; + main_controller.pad.r_stick = pad_state.r_stick; + trigger_entry.l_analog = trigger_state.l_analog; + trigger_entry.r_analog = trigger_state.r_analog; + + libnx_entry.connection_status.is_wired.Assign(1); + break; case NPadControllerType::Pokeball: pokeball_entry.connection_status.raw = 0; pokeball_entry.connection_status.is_connected.Assign(1); @@ -674,6 +734,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing right_sixaxis_entry.orientation = motion_devices[1].orientation; } break; + case NPadControllerType::GameCube: case NPadControllerType::Pokeball: break; } @@ -1135,6 +1196,8 @@ bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const return style.joycon_left; case NPadControllerType::JoyRight: return style.joycon_right; + case NPadControllerType::GameCube: + return style.gamecube; case NPadControllerType::Pokeball: return style.palma; default: diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 48bab988c..bc2e6779d 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -51,6 +51,7 @@ public: JoyDual, JoyLeft, JoyRight, + GameCube, Pokeball, }; @@ -60,6 +61,7 @@ public: JoyconDual = 5, JoyconLeft = 6, JoyconRight = 7, + GameCube = 8, Pokeball = 9, MaxNpadType = 10, }; @@ -389,6 +391,25 @@ private: }; static_assert(sizeof(SixAxisGeneric) == 0x708, "SixAxisGeneric is an invalid size"); + struct TriggerState { + s64_le timestamp{}; + s64_le timestamp2{}; + s32_le l_analog{}; + s32_le r_analog{}; + }; + static_assert(sizeof(TriggerState) == 0x18, "TriggerState is an invalid size"); + + struct TriggerGeneric { + INSERT_PADDING_BYTES(0x4); + s64_le timestamp; + INSERT_PADDING_BYTES(0x4); + s64_le total_entry_count; + s64_le last_entry_index; + s64_le entry_count; + std::array<TriggerState, 17> trigger{}; + }; + static_assert(sizeof(TriggerGeneric) == 0x1C8, "TriggerGeneric is an invalid size"); + struct NPadSystemProperties { union { s64_le raw{}; @@ -509,7 +530,9 @@ private: AppletFooterUiType footer_type; // nfc_states needs to be checked switchbrew does not match with HW NfcXcdHandle nfc_states; - INSERT_PADDING_BYTES(0xdef); + INSERT_PADDING_BYTES(0x8); // Mutex + TriggerGeneric gc_trigger_states; + INSERT_PADDING_BYTES(0xc1f); }; static_assert(sizeof(NPadEntry) == 0x5000, "NPadEntry is an invalid size"); @@ -560,6 +583,7 @@ private: f32 sixaxis_fusion_parameter2{}; bool sixaxis_at_rest{true}; std::array<ControllerPad, 10> npad_pad_states{}; + std::array<TriggerState, 10> npad_trigger_states{}; bool is_in_lr_assignment_mode{false}; Core::System& system; }; diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 51a010a55..ba27bbb05 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -15,9 +15,9 @@ #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_session.h" #include "core/hle/kernel/k_readable_event.h" +#include "core/hle/kernel/k_shared_memory.h" #include "core/hle/kernel/k_writable_event.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/shared_memory.h" #include "core/hle/service/hid/errors.h" #include "core/hle/service/hid/hid.h" #include "core/hle/service/hid/irs.h" @@ -110,6 +110,7 @@ void IAppletResource::DeactivateController(HidController controller) { IAppletResource ::~IAppletResource() { system.CoreTiming().UnscheduleEvent(pad_update_event, 0); + system.CoreTiming().UnscheduleEvent(motion_update_event, 0); } void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) { @@ -272,8 +273,8 @@ Hid::Hid(Core::System& system_) : ServiceFramework{system_, "hid"} { {204, &Hid::PermitVibration, "PermitVibration"}, {205, &Hid::IsVibrationPermitted, "IsVibrationPermitted"}, {206, &Hid::SendVibrationValues, "SendVibrationValues"}, - {207, nullptr, "SendVibrationGcErmCommand"}, - {208, nullptr, "GetActualVibrationGcErmCommand"}, + {207, &Hid::SendVibrationGcErmCommand, "SendVibrationGcErmCommand"}, + {208, &Hid::GetActualVibrationGcErmCommand, "GetActualVibrationGcErmCommand"}, {209, &Hid::BeginPermitVibrationSession, "BeginPermitVibrationSession"}, {210, &Hid::EndPermitVibrationSession, "EndPermitVibrationSession"}, {211, &Hid::IsVibrationDeviceMounted, "IsVibrationDeviceMounted"}, @@ -1092,7 +1093,22 @@ void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) { VibrationDeviceInfo vibration_device_info; - vibration_device_info.type = VibrationDeviceType::LinearResonantActuator; + switch (vibration_device_handle.npad_type) { + case Controller_NPad::NpadType::ProController: + case Controller_NPad::NpadType::Handheld: + case Controller_NPad::NpadType::JoyconDual: + case Controller_NPad::NpadType::JoyconLeft: + case Controller_NPad::NpadType::JoyconRight: + default: + vibration_device_info.type = VibrationDeviceType::LinearResonantActuator; + break; + case Controller_NPad::NpadType::GameCube: + vibration_device_info.type = VibrationDeviceType::GcErm; + break; + case Controller_NPad::NpadType::Pokeball: + vibration_device_info.type = VibrationDeviceType::Unknown; + break; + } switch (vibration_device_handle.device_index) { case Controller_NPad::DeviceIndex::Left: @@ -1214,6 +1230,108 @@ void Hid::SendVibrationValues(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); } +void Hid::SendVibrationGcErmCommand(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + struct Parameters { + Controller_NPad::DeviceHandle vibration_device_handle; + u64 applet_resource_user_id; + VibrationGcErmCommand gc_erm_command; + }; + static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + /** + * Note: This uses yuzu-specific behavior such that the StopHard command produces + * vibrations where freq_low == 0.0f and freq_high == 0.0f, as defined below, + * in order to differentiate between Stop and StopHard commands. + * This is done to reuse the controller vibration functions made for regular controllers. + */ + const auto vibration_value = [parameters] { + switch (parameters.gc_erm_command) { + case VibrationGcErmCommand::Stop: + return Controller_NPad::VibrationValue{ + .amp_low = 0.0f, + .freq_low = 160.0f, + .amp_high = 0.0f, + .freq_high = 320.0f, + }; + case VibrationGcErmCommand::Start: + return Controller_NPad::VibrationValue{ + .amp_low = 1.0f, + .freq_low = 160.0f, + .amp_high = 1.0f, + .freq_high = 320.0f, + }; + case VibrationGcErmCommand::StopHard: + return Controller_NPad::VibrationValue{ + .amp_low = 0.0f, + .freq_low = 0.0f, + .amp_high = 0.0f, + .freq_high = 0.0f, + }; + default: + return Controller_NPad::DEFAULT_VIBRATION_VALUE; + } + }(); + + applet_resource->GetController<Controller_NPad>(HidController::NPad) + .VibrateController(parameters.vibration_device_handle, vibration_value); + + LOG_DEBUG(Service_HID, + "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}, " + "gc_erm_command={}", + parameters.vibration_device_handle.npad_type, + parameters.vibration_device_handle.npad_id, + parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id, + parameters.gc_erm_command); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + +void Hid::GetActualVibrationGcErmCommand(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + struct Parameters { + Controller_NPad::DeviceHandle vibration_device_handle; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + }; + + const auto parameters{rp.PopRaw<Parameters>()}; + + const auto last_vibration = applet_resource->GetController<Controller_NPad>(HidController::NPad) + .GetLastVibration(parameters.vibration_device_handle); + + const auto gc_erm_command = [last_vibration] { + if (last_vibration.amp_low != 0.0f || last_vibration.amp_high != 0.0f) { + return VibrationGcErmCommand::Start; + } + + /** + * Note: This uses yuzu-specific behavior such that the StopHard command produces + * vibrations where freq_low == 0.0f and freq_high == 0.0f, as defined in the HID function + * SendVibrationGcErmCommand, in order to differentiate between Stop and StopHard commands. + * This is done to reuse the controller vibration functions made for regular controllers. + */ + if (last_vibration.freq_low == 0.0f && last_vibration.freq_high == 0.0f) { + return VibrationGcErmCommand::StopHard; + } + + return VibrationGcErmCommand::Stop; + }(); + + LOG_DEBUG(Service_HID, + "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", + parameters.vibration_device_handle.npad_type, + parameters.vibration_device_handle.npad_id, + parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(RESULT_SUCCESS); + rb.PushEnum(gc_erm_command); +} + void Hid::BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto applet_resource_user_id{rp.Pop<u64>()}; diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 7cc0433e2..36ed228c8 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -14,7 +14,7 @@ struct EventType; } namespace Kernel { -class SharedMemory; +class KSharedMemory; } namespace Service::SM { @@ -69,7 +69,7 @@ private: void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); - std::shared_ptr<Kernel::SharedMemory> shared_mem; + std::shared_ptr<Kernel::KSharedMemory> shared_mem; std::shared_ptr<Core::Timing::EventType> pad_update_event; std::shared_ptr<Core::Timing::EventType> motion_update_event; @@ -136,6 +136,8 @@ private: void PermitVibration(Kernel::HLERequestContext& ctx); void IsVibrationPermitted(Kernel::HLERequestContext& ctx); void SendVibrationValues(Kernel::HLERequestContext& ctx); + void SendVibrationGcErmCommand(Kernel::HLERequestContext& ctx); + void GetActualVibrationGcErmCommand(Kernel::HLERequestContext& ctx); void BeginPermitVibrationSession(Kernel::HLERequestContext& ctx); void EndPermitVibrationSession(Kernel::HLERequestContext& ctx); void IsVibrationDeviceMounted(Kernel::HLERequestContext& ctx); @@ -154,7 +156,9 @@ private: void GetNpadCommunicationMode(Kernel::HLERequestContext& ctx); enum class VibrationDeviceType : u32 { + Unknown = 0, LinearResonantActuator = 1, + GcErm = 2, }; enum class VibrationDevicePosition : u32 { @@ -163,6 +167,12 @@ private: Right = 2, }; + enum class VibrationGcErmCommand : u64 { + Stop = 0, + Start = 1, + StopHard = 2, + }; + struct VibrationDeviceInfo { VibrationDeviceType type{}; VibrationDevicePosition position{}; diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp index c8413099f..2dfa936fb 100644 --- a/src/core/hle/service/hid/irs.cpp +++ b/src/core/hle/service/hid/irs.cpp @@ -6,8 +6,8 @@ #include "core/core.h" #include "core/core_timing.h" #include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/k_shared_memory.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/shared_memory.h" #include "core/hle/service/hid/irs.h" namespace Service::HID { diff --git a/src/core/hle/service/hid/irs.h b/src/core/hle/service/hid/irs.h index be0c486ba..b0c8c7168 100644 --- a/src/core/hle/service/hid/irs.h +++ b/src/core/hle/service/hid/irs.h @@ -12,7 +12,7 @@ class System; } namespace Kernel { -class SharedMemory; +class KSharedMemory; } namespace Service::HID { @@ -42,7 +42,7 @@ private: void StopImageProcessorAsync(Kernel::HLERequestContext& ctx); void ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx); - std::shared_ptr<Kernel::SharedMemory> shared_mem; + std::shared_ptr<Kernel::KSharedMemory> shared_mem; const u32 device_handle{0xABCD}; }; diff --git a/src/core/hle/service/ldn/errors.h b/src/core/hle/service/ldn/errors.h new file mode 100644 index 000000000..a718c5c66 --- /dev/null +++ b/src/core/hle/service/ldn/errors.h @@ -0,0 +1,13 @@ +// Copyright 2021 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/result.h" + +namespace Service::LDN { + +constexpr ResultCode ERROR_DISABLED{ErrorModule::LDN, 22}; + +} // namespace Service::LDN diff --git a/src/core/hle/service/ldn/ldn.cpp b/src/core/hle/service/ldn/ldn.cpp index ee908f399..c630d93cd 100644 --- a/src/core/hle/service/ldn/ldn.cpp +++ b/src/core/hle/service/ldn/ldn.cpp @@ -6,6 +6,7 @@ #include "core/hle/ipc_helpers.h" #include "core/hle/result.h" +#include "core/hle/service/ldn/errors.h" #include "core/hle/service/ldn/ldn.h" #include "core/hle/service/sm/sm.h" @@ -103,7 +104,7 @@ public: : ServiceFramework{system_, "IUserLocalCommunicationService"} { // clang-format off static const FunctionInfo functions[] = { - {0, nullptr, "GetState"}, + {0, &IUserLocalCommunicationService::GetState, "GetState"}, {1, nullptr, "GetNetworkInfo"}, {2, nullptr, "GetIpv4Address"}, {3, nullptr, "GetDisconnectReason"}, @@ -138,13 +139,38 @@ public: RegisterHandlers(functions); } - void Initialize2(Kernel::HLERequestContext& ctx) { + void GetState(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_LDN, "(STUBBED) called"); - // Result success seem make this services start network and continue. - // If we just pass result error then it will stop and maybe try again and again. + + IPC::ResponseBuilder rb{ctx, 3}; + + // Indicate a network error, as we do not actually emulate LDN + rb.Push(static_cast<u32>(State::Error)); + + rb.Push(RESULT_SUCCESS); + } + + void Initialize2(Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Service_LDN, "called"); + + is_initialized = true; + IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(RESULT_UNKNOWN); + rb.Push(RESULT_SUCCESS); } + +private: + enum class State { + None, + Initialized, + AccessPointOpened, + AccessPointCreated, + StationOpened, + StationConnected, + Error, + }; + + bool is_initialized{}; }; class LDNS final : public ServiceFramework<LDNS> { diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp index 9da786b4e..d111c1357 100644 --- a/src/core/hle/service/ldr/ldr.cpp +++ b/src/core/hle/service/ldr/ldr.cpp @@ -11,10 +11,10 @@ #include "common/scope_exit.h" #include "core/core.h" #include "core/hle/ipc_helpers.h" -#include "core/hle/kernel/errors.h" -#include "core/hle/kernel/memory/page_table.h" -#include "core/hle/kernel/memory/system_control.h" +#include "core/hle/kernel/k_page_table.h" +#include "core/hle/kernel/k_system_control.h" #include "core/hle/kernel/process.h" +#include "core/hle/kernel/svc_results.h" #include "core/hle/service/ldr/ldr.h" #include "core/hle/service/service.h" #include "core/loader/nro.h" @@ -287,12 +287,11 @@ public: rb.Push(RESULT_SUCCESS); } - bool ValidateRegionForMap(Kernel::Memory::PageTable& page_table, VAddr start, - std::size_t size) const { - constexpr std::size_t padding_size{4 * Kernel::Memory::PageSize}; + bool ValidateRegionForMap(Kernel::KPageTable& page_table, VAddr start, std::size_t size) const { + constexpr std::size_t padding_size{4 * Kernel::PageSize}; const auto start_info{page_table.QueryInfo(start - 1)}; - if (start_info.state != Kernel::Memory::MemoryState::Free) { + if (start_info.state != Kernel::KMemoryState::Free) { return {}; } @@ -302,21 +301,20 @@ public: const auto end_info{page_table.QueryInfo(start + size)}; - if (end_info.state != Kernel::Memory::MemoryState::Free) { + if (end_info.state != Kernel::KMemoryState::Free) { return {}; } return (start + size + padding_size) <= (end_info.GetAddress() + end_info.GetSize()); } - VAddr GetRandomMapRegion(const Kernel::Memory::PageTable& page_table, std::size_t size) const { + VAddr GetRandomMapRegion(const Kernel::KPageTable& page_table, std::size_t size) const { VAddr addr{}; const std::size_t end_pages{(page_table.GetAliasCodeRegionSize() - size) >> - Kernel::Memory::PageBits}; + Kernel::PageBits}; do { addr = page_table.GetAliasCodeRegionStart() + - (Kernel::Memory::SystemControl::GenerateRandomRange(0, end_pages) - << Kernel::Memory::PageBits); + (Kernel::KSystemControl::GenerateRandomRange(0, end_pages) << Kernel::PageBits); } while (!page_table.IsInsideAddressSpace(addr, size) || page_table.IsInsideHeapRegion(addr, size) || page_table.IsInsideAliasRegion(addr, size)); @@ -330,7 +328,7 @@ public: const VAddr addr{GetRandomMapRegion(page_table, size)}; const ResultCode result{page_table.MapProcessCodeMemory(addr, baseAddress, size)}; - if (result == Kernel::ERR_INVALID_ADDRESS_STATE) { + if (result == Kernel::ResultInvalidCurrentMemory) { continue; } @@ -361,7 +359,7 @@ public: const ResultCode result{ page_table.MapProcessCodeMemory(addr + nro_size, bss_addr, bss_size)}; - if (result == Kernel::ERR_INVALID_ADDRESS_STATE) { + if (result == Kernel::ResultInvalidCurrentMemory) { continue; } @@ -387,7 +385,7 @@ public: const VAddr data_start{start + nro_header.segment_headers[DATA_INDEX].memory_offset}; const VAddr bss_start{data_start + nro_header.segment_headers[DATA_INDEX].memory_size}; const VAddr bss_end_addr{ - Common::AlignUp(bss_start + nro_header.bss_size, Kernel::Memory::PageSize)}; + Common::AlignUp(bss_start + nro_header.bss_size, Kernel::PageSize)}; auto CopyCode{[&](VAddr src_addr, VAddr dst_addr, u64 size) { std::vector<u8> source_data(size); @@ -402,12 +400,12 @@ public: nro_header.segment_headers[DATA_INDEX].memory_size); CASCADE_CODE(process->PageTable().SetCodeMemoryPermission( - text_start, ro_start - text_start, Kernel::Memory::MemoryPermission::ReadAndExecute)); - CASCADE_CODE(process->PageTable().SetCodeMemoryPermission( - ro_start, data_start - ro_start, Kernel::Memory::MemoryPermission::Read)); + text_start, ro_start - text_start, Kernel::KMemoryPermission::ReadAndExecute)); + CASCADE_CODE(process->PageTable().SetCodeMemoryPermission(ro_start, data_start - ro_start, + Kernel::KMemoryPermission::Read)); return process->PageTable().SetCodeMemoryPermission( - data_start, bss_end_addr - data_start, Kernel::Memory::MemoryPermission::ReadAndWrite); + data_start, bss_end_addr - data_start, Kernel::KMemoryPermission::ReadAndWrite); } void LoadNro(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp index 5d6d25696..2d1d4d67f 100644 --- a/src/core/hle/service/nfp/nfp.cpp +++ b/src/core/hle/service/nfp/nfp.cpp @@ -215,7 +215,7 @@ private: const auto& amiibo = nfp_interface.GetAmiiboBuffer(); const TagInfo tag_info{ .uuid = amiibo.uuid, - .uuid_length = static_cast<u8>(tag_info.uuid.size()), + .uuid_length = static_cast<u8>(amiibo.uuid.size()), .padding_1 = {}, .protocol = 1, // TODO(ogniK): Figure out actual values .tag_type = 2, diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp index b6ac0a81a..fcd15d81f 100644 --- a/src/core/hle/service/ns/pl_u.cpp +++ b/src/core/hle/service/ns/pl_u.cpp @@ -19,9 +19,9 @@ #include "core/file_sys/romfs.h" #include "core/file_sys/system_archive/system_archive.h" #include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/k_shared_memory.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/physical_memory.h" -#include "core/hle/kernel/shared_memory.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/ns/pl_u.h" @@ -131,7 +131,7 @@ struct PL_U::Impl { } /// Handle to shared memory region designated for a shared font - std::shared_ptr<Kernel::SharedMemory> shared_font_mem; + std::shared_ptr<Kernel::KSharedMemory> shared_font_mem; /// Backing memory for the shared font data std::shared_ptr<Kernel::PhysicalMemory> shared_font; diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp index 36970f828..ecba1dba1 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp @@ -34,8 +34,7 @@ NvResult nvhost_nvdec::Ioctl1(Ioctl command, const std::vector<u8>& input, case 0xa: { if (command.length == 0x1c) { LOG_INFO(Service_NVDRV, "NVDEC video stream ended"); - Tegra::ChCommandHeaderList cmdlist(1); - cmdlist[0] = Tegra::ChCommandHeader{0xDEADB33F}; + Tegra::ChCommandHeaderList cmdlist{{0xDEADB33F}}; system.GPU().PushCommandBuffer(cmdlist); } return UnmapBuffer(input, output); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp index 72499654c..70849a9bd 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp @@ -28,8 +28,13 @@ NvResult nvhost_vic::Ioctl1(Ioctl command, const std::vector<u8>& input, std::ve return GetWaitbase(input, output); case 0x9: return MapBuffer(input, output); - case 0xa: + case 0xa: { + if (command.length == 0x1c) { + Tegra::ChCommandHeaderList cmdlist{{0xDEADB33F}}; + system.GPU().PushCommandBuffer(cmdlist); + } return UnmapBuffer(input, output); + } default: break; } diff --git a/src/core/hle/service/olsc/olsc.cpp b/src/core/hle/service/olsc/olsc.cpp index 4440135ed..e2ac71fa1 100644 --- a/src/core/hle/service/olsc/olsc.cpp +++ b/src/core/hle/service/olsc/olsc.cpp @@ -17,7 +17,7 @@ public: static const FunctionInfo functions[] = { {0, &OLSC::Initialize, "Initialize"}, {10, nullptr, "VerifySaveDataBackupLicenseAsync"}, - {13, nullptr, "GetSaveDataBackupSetting"}, + {13, &OLSC::GetSaveDataBackupSetting, "GetSaveDataBackupSetting"}, {14, &OLSC::SetSaveDataBackupSettingEnabled, "SetSaveDataBackupSettingEnabled"}, {15, nullptr, "SetCustomData"}, {16, nullptr, "DeleteSaveDataBackupSetting"}, @@ -52,6 +52,17 @@ private: rb.Push(RESULT_SUCCESS); } + void GetSaveDataBackupSetting(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_OLSC, "(STUBBED) called"); + + // backup_setting is set to 0 since real value is unknown + constexpr u64 backup_setting = 0; + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(RESULT_SUCCESS); + rb.Push(backup_setting); + } + void SetSaveDataBackupSettingEnabled(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_OLSC, "(STUBBED) called"); diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp index 0b306b87a..78e9cd708 100644 --- a/src/core/hle/service/sockets/bsd.cpp +++ b/src/core/hle/service/sockets/bsd.cpp @@ -453,7 +453,8 @@ std::pair<s32, Errno> BSD::SocketImpl(Domain domain, Type type, Protocol protoco return {-1, Errno::MFILE}; } - FileDescriptor& descriptor = file_descriptors[fd].emplace(); + file_descriptors[fd] = FileDescriptor{}; + FileDescriptor& descriptor = *file_descriptors[fd]; // ENONMEM might be thrown here LOG_INFO(Service, "New socket fd={}", fd); @@ -548,7 +549,8 @@ std::pair<s32, Errno> BSD::AcceptImpl(s32 fd, std::vector<u8>& write_buffer) { return {-1, Translate(bsd_errno)}; } - FileDescriptor& new_descriptor = file_descriptors[new_fd].emplace(); + file_descriptors[new_fd] = FileDescriptor{}; + FileDescriptor& new_descriptor = *file_descriptors[new_fd]; new_descriptor.socket = std::move(result.socket); new_descriptor.is_connection_based = descriptor.is_connection_based; diff --git a/src/core/hle/service/time/time_manager.cpp b/src/core/hle/service/time/time_manager.cpp index 858623e2b..1f7309f6b 100644 --- a/src/core/hle/service/time/time_manager.cpp +++ b/src/core/hle/service/time/time_manager.cpp @@ -279,6 +279,10 @@ const SharedMemory& TimeManager::GetSharedMemory() const { return impl->shared_memory; } +void TimeManager::Shutdown() { + impl.reset(); +} + void TimeManager::UpdateLocalSystemClockTime(s64 posix_time) { impl->UpdateLocalSystemClockTime(system, posix_time); } diff --git a/src/core/hle/service/time/time_manager.h b/src/core/hle/service/time/time_manager.h index 993c7c288..4db8cc0e1 100644 --- a/src/core/hle/service/time/time_manager.h +++ b/src/core/hle/service/time/time_manager.h @@ -61,6 +61,8 @@ public: const SharedMemory& GetSharedMemory() const; + void Shutdown(); + void SetupTimeZoneManager(std::string location_name, Clock::SteadyClockTimePoint time_zone_updated_time_point, std::size_t total_location_name_count, u128 time_zone_rule_version, diff --git a/src/core/hle/service/time/time_sharedmemory.cpp b/src/core/hle/service/time/time_sharedmemory.cpp index e0ae9f874..4d8de81be 100644 --- a/src/core/hle/service/time/time_sharedmemory.cpp +++ b/src/core/hle/service/time/time_sharedmemory.cpp @@ -22,7 +22,7 @@ SharedMemory::SharedMemory(Core::System& system) : system(system) { SharedMemory::~SharedMemory() = default; -std::shared_ptr<Kernel::SharedMemory> SharedMemory::GetSharedMemoryHolder() const { +std::shared_ptr<Kernel::KSharedMemory> SharedMemory::GetSharedMemoryHolder() const { return shared_memory_holder; } diff --git a/src/core/hle/service/time/time_sharedmemory.h b/src/core/hle/service/time/time_sharedmemory.h index e0c3e63da..299680517 100644 --- a/src/core/hle/service/time/time_sharedmemory.h +++ b/src/core/hle/service/time/time_sharedmemory.h @@ -6,8 +6,8 @@ #include "common/common_types.h" #include "common/uuid.h" +#include "core/hle/kernel/k_shared_memory.h" #include "core/hle/kernel/k_thread.h" -#include "core/hle/kernel/shared_memory.h" #include "core/hle/service/time/clock_types.h" namespace Service::Time { @@ -18,7 +18,7 @@ public: ~SharedMemory(); // Return the shared memory handle - std::shared_ptr<Kernel::SharedMemory> GetSharedMemoryHolder() const; + std::shared_ptr<Kernel::KSharedMemory> GetSharedMemoryHolder() const; // TODO(ogniK): We have to properly simulate memory barriers, how are we going to do this? template <typename T, std::size_t Offset> @@ -63,7 +63,7 @@ public: void SetAutomaticCorrectionEnabled(bool is_enabled); private: - std::shared_ptr<Kernel::SharedMemory> shared_memory_holder; + std::shared_ptr<Kernel::KSharedMemory> shared_memory_holder; Core::System& system; Format shared_memory_format{}; }; |