diff options
Diffstat (limited to 'src/core/hle/service')
-rw-r--r-- | src/core/hle/service/am/applet_oe.cpp | 2 | ||||
-rw-r--r-- | src/core/hle/service/audio/audio.cpp | 16 | ||||
-rw-r--r-- | src/core/hle/service/audio/audio.h | 16 | ||||
-rw-r--r-- | src/core/hle/service/audio/audout_u.cpp | 26 | ||||
-rw-r--r-- | src/core/hle/service/audio/audout_u.h | 23 | ||||
-rw-r--r-- | src/core/hle/service/hid/hid.cpp | 147 | ||||
-rw-r--r-- | src/core/hle/service/hid/hid.h | 321 | ||||
-rw-r--r-- | src/core/hle/service/lm/lm.cpp | 2 | ||||
-rw-r--r-- | src/core/hle/service/service.cpp | 12 | ||||
-rw-r--r-- | src/core/hle/service/time/time.cpp | 16 | ||||
-rw-r--r-- | src/core/hle/service/time/time.h | 16 | ||||
-rw-r--r-- | src/core/hle/service/time/time_s.cpp | 58 | ||||
-rw-r--r-- | src/core/hle/service/time/time_s.h | 23 | ||||
-rw-r--r-- | src/core/hle/service/vi/vi.cpp | 15 |
14 files changed, 677 insertions, 16 deletions
diff --git a/src/core/hle/service/am/applet_oe.cpp b/src/core/hle/service/am/applet_oe.cpp index e2bb581ff..f3d66ea96 100644 --- a/src/core/hle/service/am/applet_oe.cpp +++ b/src/core/hle/service/am/applet_oe.cpp @@ -81,7 +81,7 @@ private: void ReceiveMessage(Kernel::HLERequestContext& ctx) { IPC::RequestBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - rb.Push<u32>(1); + rb.Push<u32>(15); LOG_WARNING(Service, "(STUBBED) called"); } diff --git a/src/core/hle/service/audio/audio.cpp b/src/core/hle/service/audio/audio.cpp new file mode 100644 index 000000000..2b4c6c5d0 --- /dev/null +++ b/src/core/hle/service/audio/audio.cpp @@ -0,0 +1,16 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/audio/audio.h" +#include "core/hle/service/audio/audout_u.h" + +namespace Service { +namespace Audio { + +void InstallInterfaces(SM::ServiceManager& service_manager) { + std::make_shared<AudOutU>()->InstallAsService(service_manager); +} + +} // namespace Audio +} // namespace Service diff --git a/src/core/hle/service/audio/audio.h b/src/core/hle/service/audio/audio.h new file mode 100644 index 000000000..cbd56b2a8 --- /dev/null +++ b/src/core/hle/service/audio/audio.h @@ -0,0 +1,16 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service { +namespace Audio { + +/// Registers all Audio services with the specified service manager. +void InstallInterfaces(SM::ServiceManager& service_manager); + +} // namespace Audio +} // namespace Service diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp new file mode 100644 index 000000000..c028262c6 --- /dev/null +++ b/src/core/hle/service/audio/audout_u.cpp @@ -0,0 +1,26 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "common/logging/log.h" +#include "core/hle/ipc_helpers.h" +#include "core/hle/service/audio/audout_u.h" + +namespace Service { +namespace Audio { + +void AudOutU::ListAudioOuts(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called"); + IPC::RequestBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + +AudOutU::AudOutU() : ServiceFramework("audout:u") { + static const FunctionInfo functions[] = { + {0x00000000, &AudOutU::ListAudioOuts, "ListAudioOuts"}, + }; + RegisterHandlers(functions); +} + +} // namespace Audio +} // namespace Service diff --git a/src/core/hle/service/audio/audout_u.h b/src/core/hle/service/audio/audout_u.h new file mode 100644 index 000000000..42680af94 --- /dev/null +++ b/src/core/hle/service/audio/audout_u.h @@ -0,0 +1,23 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/kernel/hle_ipc.h" +#include "core/hle/service/service.h" + +namespace Service { +namespace Audio { + +class AudOutU final : public ServiceFramework<AudOutU> { +public: + AudOutU(); + ~AudOutU() = default; + +private: + void ListAudioOuts(Kernel::HLERequestContext& ctx); +}; + +} // namespace Audio +} // namespace Service diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index f838713a3..3c4259d27 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -1,19 +1,160 @@ -// Copyright 2015 Citra Emulator Project +// Copyright 2018 yuzu emulator team // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <atomic> #include "common/logging/log.h" +#include "core/core_timing.h" +#include "core/frontend/input.h" +#include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/client_port.h" +#include "core/hle/kernel/client_session.h" +#include "core/hle/kernel/shared_memory.h" #include "core/hle/service/hid/hid.h" #include "core/hle/service/service.h" namespace Service { namespace HID { -void Init() {} +// Updating period for each HID device. +// TODO(shinyquagsire23): These need better values. +constexpr u64 pad_update_ticks = BASE_CLOCK_RATE / 234; +constexpr u64 accelerometer_update_ticks = BASE_CLOCK_RATE / 104; +constexpr u64 gyroscope_update_ticks = BASE_CLOCK_RATE / 101; -void Shutdown() {} +class IAppletResource final : public ServiceFramework<IAppletResource> { +public: + IAppletResource() : ServiceFramework("IAppletResource") { + static const FunctionInfo functions[] = { + {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"}, + }; + RegisterHandlers(functions); + + shared_mem = Kernel::SharedMemory::Create( + nullptr, 0x40000, Kernel::MemoryPermission::ReadWrite, Kernel::MemoryPermission::Read, + 0, Kernel::MemoryRegion::BASE, "HID:SharedMemory"); + + // Register update callbacks + pad_update_event = CoreTiming::RegisterEvent( + "HID::UpdatePadCallback", + [this](u64 userdata, int cycles_late) { UpdatePadCallback(userdata, cycles_late); }); + + // TODO(shinyquagsire23): Other update callbacks? (accel, gyro?) + + CoreTiming::ScheduleEvent(pad_update_ticks, pad_update_event); + } + +private: + void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) { + IPC::RequestBuilder rb{ctx, 2, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushCopyObjects(shared_mem); + LOG_DEBUG(Service, "called"); + } + + void LoadInputDevices() { + std::transform(Settings::values.buttons.begin() + Settings::NativeButton::BUTTON_HID_BEGIN, + Settings::values.buttons.begin() + Settings::NativeButton::BUTTON_HID_END, + buttons.begin(), Input::CreateDevice<Input::ButtonDevice>); + // TODO(shinyquagsire23): sticks, gyro, touch, mouse, keyboard + } + + void UpdatePadCallback(u64 userdata, int cycles_late) { + SharedMemory* mem = reinterpret_cast<SharedMemory*>(shared_mem->GetPointer()); + + if (is_device_reload_pending.exchange(false)) + LoadInputDevices(); + + // TODO(shinyquagsire23): This is a hack! + ControllerPadState& state = + mem->controllers[Controller_Handheld].layouts[Layout_Default].entries[0].buttons; + using namespace Settings::NativeButton; + state.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus()); + state.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus()); + state.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus()); + state.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus()); + state.lstick.Assign(buttons[LStick - BUTTON_HID_BEGIN]->GetStatus()); + state.rstick.Assign(buttons[RStick - BUTTON_HID_BEGIN]->GetStatus()); + state.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus()); + state.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus()); + state.zl.Assign(buttons[ZL - BUTTON_HID_BEGIN]->GetStatus()); + state.zr.Assign(buttons[ZR - BUTTON_HID_BEGIN]->GetStatus()); + state.plus.Assign(buttons[Plus - BUTTON_HID_BEGIN]->GetStatus()); + state.minus.Assign(buttons[Minus - BUTTON_HID_BEGIN]->GetStatus()); + + state.dleft.Assign(buttons[DLeft - BUTTON_HID_BEGIN]->GetStatus()); + state.dup.Assign(buttons[DUp - BUTTON_HID_BEGIN]->GetStatus()); + state.dright.Assign(buttons[DRight - BUTTON_HID_BEGIN]->GetStatus()); + state.ddown.Assign(buttons[DDown - BUTTON_HID_BEGIN]->GetStatus()); + + state.lstick_left.Assign(buttons[LStick_Left - BUTTON_HID_BEGIN]->GetStatus()); + state.lstick_up.Assign(buttons[LStick_Up - BUTTON_HID_BEGIN]->GetStatus()); + state.lstick_right.Assign(buttons[LStick_Right - BUTTON_HID_BEGIN]->GetStatus()); + state.lstick_down.Assign(buttons[LStick_Down - BUTTON_HID_BEGIN]->GetStatus()); + + state.rstick_left.Assign(buttons[RStick_Left - BUTTON_HID_BEGIN]->GetStatus()); + state.rstick_up.Assign(buttons[RStick_Up - BUTTON_HID_BEGIN]->GetStatus()); + state.rstick_right.Assign(buttons[RStick_Right - BUTTON_HID_BEGIN]->GetStatus()); + state.rstick_down.Assign(buttons[RStick_Down - BUTTON_HID_BEGIN]->GetStatus()); + + state.sl.Assign(buttons[SL - BUTTON_HID_BEGIN]->GetStatus()); + state.sr.Assign(buttons[SR - BUTTON_HID_BEGIN]->GetStatus()); + + // TODO(shinyquagsire23): Analog stick vals + + // TODO(shinyquagsire23): Update pad info proper, (circular buffers, timestamps, layouts) + + // TODO(shinyquagsire23): Update touch info + + // TODO(shinyquagsire23): Signal events + + // Reschedule recurrent event + CoreTiming::ScheduleEvent(pad_update_ticks - cycles_late, pad_update_event); + } + + // Handle to shared memory region designated to HID service + Kernel::SharedPtr<Kernel::SharedMemory> shared_mem; + + // CoreTiming update events + CoreTiming::EventType* pad_update_event; + + // Stored input state info + std::atomic<bool> is_device_reload_pending{true}; + std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::NUM_BUTTONS_HID> + buttons; +}; + +class Hid final : public ServiceFramework<Hid> { +public: + Hid() : ServiceFramework("hid") { + static const FunctionInfo functions[] = { + {0x00000000, &Hid::CreateAppletResource, "CreateAppletResource"}, + }; + RegisterHandlers(functions); + } + ~Hid() = default; + +private: + void CreateAppletResource(Kernel::HLERequestContext& ctx) { + auto client_port = std::make_shared<IAppletResource>()->CreatePort(); + auto session = client_port->Connect(); + if (session.Succeeded()) { + LOG_DEBUG(Service, "called, initialized IAppletResource -> session=%u", + (*session)->GetObjectId()); + IPC::RequestBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushMoveObjects(std::move(session).Unwrap()); + } else { + UNIMPLEMENTED(); + } + } +}; void ReloadInputDevices() {} +void InstallInterfaces(SM::ServiceManager& service_manager) { + std::make_shared<Hid>()->InstallAsService(service_manager); +} + } // namespace HID } // namespace Service diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index a1d227dfe..486e64800 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -1,20 +1,331 @@ -// Copyright 2015 Citra Emulator Project +// Copyright 2018 yuzu emulator team // Licensed under GPLv2 or any later version // Refer to the license.txt file included. #pragma once +#include "core/hle/service/service.h" +#include "core/settings.h" + namespace Service { namespace HID { -/// Initialize HID service -void Init(); +// Begin enums and output structs + +enum ControllerType : u32 { + ControllerType_ProController = 1 << 0, + ControllerType_Handheld = 1 << 1, + ControllerType_JoyconPair = 1 << 2, + ControllerType_JoyconLeft = 1 << 3, + ControllerType_JoyconRight = 1 << 4, +}; + +enum ControllerLayoutType : u32 { + Layout_ProController = 0, // Pro Controller or HID gamepad + Layout_Handheld = 1, // Two Joy-Con docked to rails + Layout_Single = 2, // Horizontal single Joy-Con or pair of Joy-Con, adjusted for orientation + Layout_Left = 3, // Only raw left Joy-Con state, no orientation adjustment + Layout_Right = 4, // Only raw right Joy-Con state, no orientation adjustment + Layout_DefaultDigital = 5, // Same as next, but sticks have 8-direction values only + Layout_Default = 6, // Safe default, single Joy-Con have buttons/sticks rotated for orientation +}; + +enum ControllerColorDescription { + ColorDesc_ColorsNonexistent = 1 << 1, +}; + +enum ControllerConnectionState { + ConnectionState_Connected = 1 << 0, + ConnectionState_Wired = 1 << 1, +}; + +enum ControllerID { + Controller_Player1 = 0, + Controller_Player2 = 1, + Controller_Player3 = 2, + Controller_Player4 = 3, + Controller_Player5 = 4, + Controller_Player6 = 5, + Controller_Player7 = 6, + Controller_Player8 = 7, + Controller_Handheld = 8, + Controller_Unknown = 9, +}; + +// End enums and output structs + +// Begin TouchScreen + +struct TouchScreenHeader { + u64 timestampTicks; + u64 numEntries; + u64 latestEntry; + u64 maxEntryIndex; + u64 timestamp; +}; +static_assert(sizeof(TouchScreenHeader) == 0x28, + "HID touch screen header structure has incorrect size"); + +struct TouchScreenEntryHeader { + u64 timestamp; + u64 numTouches; +}; +static_assert(sizeof(TouchScreenEntryHeader) == 0x10, + "HID touch screen entry header structure has incorrect size"); + +struct TouchScreenEntryTouch { + u64 timestamp; + u32 padding; + u32 touchIndex; + u32 x; + u32 y; + u32 diameterX; + u32 diameterY; + u32 angle; + u32 padding_2; +}; +static_assert(sizeof(TouchScreenEntryTouch) == 0x28, + "HID touch screen touch structure has incorrect size"); + +struct TouchScreenEntry { + TouchScreenEntryHeader header; + std::array<TouchScreenEntryTouch, 16> touches; + u64 unk; +}; +static_assert(sizeof(TouchScreenEntry) == 0x298, + "HID touch screen entry structure has incorrect size"); + +struct TouchScreen { + TouchScreenHeader header; + std::array<TouchScreenEntry, 17> entries; + std::array<u8, 0x3c0> padding; +}; +static_assert(sizeof(TouchScreen) == 0x3000, "HID touch screen structure has incorrect size"); + +// End TouchScreen + +// Begin Mouse + +struct MouseHeader { + u64 timestampTicks; + u64 numEntries; + u64 latestEntry; + u64 maxEntryIndex; +}; +static_assert(sizeof(MouseHeader) == 0x20, "HID mouse header structure has incorrect size"); + +struct MouseButtonState { + union { + u64 hex{}; + + // Buttons + BitField<0, 1, u64> left; + BitField<1, 1, u64> right; + BitField<2, 1, u64> middle; + BitField<3, 1, u64> forward; + BitField<4, 1, u64> back; + }; +}; + +struct MouseEntry { + u64 timestamp; + u64 timestamp_2; + u32 x; + u32 y; + u32 velocityX; + u32 velocityY; + u32 scrollVelocityX; + u32 scrollVelocityY; + MouseButtonState buttons; +}; +static_assert(sizeof(MouseEntry) == 0x30, "HID mouse entry structure has incorrect size"); + +struct Mouse { + MouseHeader header; + std::array<MouseEntry, 17> entries; + std::array<u8, 0xB0> padding; +}; +static_assert(sizeof(Mouse) == 0x400, "HID mouse structure has incorrect size"); + +// End Mouse + +// Begin Keyboard -/// Shutdown HID service -void Shutdown(); +struct KeyboardHeader { + u64 timestampTicks; + u64 numEntries; + u64 latestEntry; + u64 maxEntryIndex; +}; +static_assert(sizeof(KeyboardHeader) == 0x20, "HID keyboard header structure has incorrect size"); + +struct KeyboardModifierKeyState { + union { + u64 hex{}; + + // Buttons + BitField<0, 1, u64> lctrl; + BitField<1, 1, u64> lshift; + BitField<2, 1, u64> lalt; + BitField<3, 1, u64> lmeta; + BitField<4, 1, u64> rctrl; + BitField<5, 1, u64> rshift; + BitField<6, 1, u64> ralt; + BitField<7, 1, u64> rmeta; + BitField<8, 1, u64> capslock; + BitField<9, 1, u64> scrolllock; + BitField<10, 1, u64> numlock; + }; +}; + +struct KeyboardEntry { + u64 timestamp; + u64 timestamp_2; + KeyboardModifierKeyState modifier; + u32 keys[8]; +}; +static_assert(sizeof(KeyboardEntry) == 0x38, "HID keyboard entry structure has incorrect size"); + +struct Keyboard { + KeyboardHeader header; + std::array<KeyboardEntry, 17> entries; + std::array<u8, 0x28> padding; +}; +static_assert(sizeof(Keyboard) == 0x400, "HID keyboard structure has incorrect size"); + +// End Keyboard + +// Begin Controller + +struct ControllerMAC { + u64 timestamp; + std::array<u8, 0x8> mac; + u64 unk; + u64 timestamp_2; +}; +static_assert(sizeof(ControllerMAC) == 0x20, "HID controller MAC structure has incorrect size"); + +struct ControllerHeader { + u32 type; + u32 isHalf; + u32 singleColorsDescriptor; + u32 singleColorBody; + u32 singleColorButtons; + u32 splitColorsDescriptor; + u32 leftColorBody; + u32 leftColorButtons; + u32 rightColorBody; + u32 rightColorbuttons; +}; +static_assert(sizeof(ControllerHeader) == 0x28, + "HID controller header structure has incorrect size"); + +struct ControllerLayoutHeader { + u64 timestampTicks; + u64 numEntries; + u64 latestEntry; + u64 maxEntryIndex; +}; +static_assert(sizeof(ControllerLayoutHeader) == 0x20, + "HID controller layout header structure has incorrect size"); + +struct ControllerPadState { + union { + u64 hex{}; + + // Buttons + BitField<0, 1, u64> a; + BitField<1, 1, u64> b; + BitField<2, 1, u64> x; + BitField<3, 1, u64> y; + BitField<4, 1, u64> lstick; + BitField<5, 1, u64> rstick; + BitField<6, 1, u64> l; + BitField<7, 1, u64> r; + BitField<8, 1, u64> zl; + BitField<9, 1, u64> zr; + BitField<10, 1, u64> plus; + BitField<11, 1, u64> minus; + + // D-pad buttons + BitField<12, 1, u64> dleft; + BitField<13, 1, u64> dup; + BitField<14, 1, u64> dright; + BitField<15, 1, u64> ddown; + + // Left stick directions + BitField<16, 1, u64> lstick_left; + BitField<17, 1, u64> lstick_up; + BitField<18, 1, u64> lstick_right; + BitField<19, 1, u64> lstick_down; + + // Right stick directions + BitField<20, 1, u64> rstick_left; + BitField<21, 1, u64> rstick_up; + BitField<22, 1, u64> rstick_right; + BitField<23, 1, u64> rstick_down; + + BitField<24, 1, u64> sl; + BitField<25, 1, u64> sr; + }; +}; + +struct ControllerInputEntry { + u64 timestamp; + u64 timestamp_2; + ControllerPadState buttons; + u32 joystickLeftX; + u32 joystickLeftY; + u32 joystickRightX; + u32 joystickRightY; + u64 connectionState; +}; +static_assert(sizeof(ControllerInputEntry) == 0x30, + "HID controller input entry structure has incorrect size"); + +struct ControllerLayout { + ControllerLayoutHeader header; + std::array<ControllerInputEntry, 17> entries; +}; +static_assert(sizeof(ControllerLayout) == 0x350, + "HID controller layout structure has incorrect size"); + +struct Controller { + ControllerHeader header; + std::array<ControllerLayout, 7> layouts; + std::array<u8, 0x2a70> unk_1; + ControllerMAC macLeft; + ControllerMAC macRight; + std::array<u8, 0xdf8> unk_2; +}; +static_assert(sizeof(Controller) == 0x5000, "HID controller structure has incorrect size"); + +// End Controller + +struct SharedMemory { + std::array<u8, 0x400> header; + TouchScreen touchscreen; + Mouse mouse; + Keyboard keyboard; + std::array<u8, 0x400> unkSection1; + std::array<u8, 0x400> unkSection2; + std::array<u8, 0x400> unkSection3; + std::array<u8, 0x400> unkSection4; + std::array<u8, 0x200> unkSection5; + std::array<u8, 0x200> unkSection6; + std::array<u8, 0x200> unkSection7; + std::array<u8, 0x800> unkSection8; + std::array<u8, 0x4000> controllerSerials; + std::array<Controller, 10> controllers; + std::array<u8, 0x4600> unkSection9; +}; +static_assert(sizeof(SharedMemory) == 0x40000, "HID Shared Memory structure has incorrect size"); /// Reload input devices. Used when input configuration changed void ReloadInputDevices(); +/// Registers all HID services with the specified service manager. +void InstallInterfaces(SM::ServiceManager& service_manager); + } // namespace HID } // namespace Service diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp index ca429e15f..2d0d2fb65 100644 --- a/src/core/hle/service/lm/lm.cpp +++ b/src/core/hle/service/lm/lm.cpp @@ -144,7 +144,7 @@ void LM::Initialize(Kernel::HLERequestContext& ctx) { if (session.Succeeded()) { LOG_DEBUG(Service_SM, "called, initialized logger -> session=%u", (*session)->GetObjectId()); - IPC::RequestBuilder rb{ctx, 1, 0, 1}; + IPC::RequestBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushMoveObjects(std::move(session).Unwrap()); registered_loggers.emplace_back(std::move(client_port)); diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index b82df6f35..02d434660 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -17,6 +17,7 @@ #include "core/hle/service/am/am.h" #include "core/hle/service/aoc/aoc_u.h" #include "core/hle/service/apm/apm.h" +#include "core/hle/service/audio/audio.h" #include "core/hle/service/hid/hid.h" #include "core/hle/service/lm/lm.h" #include "core/hle/service/nvdrv/nvdrv.h" @@ -24,6 +25,7 @@ #include "core/hle/service/service.h" #include "core/hle/service/sm/controller.h" #include "core/hle/service/sm/sm.h" +#include "core/hle/service/time/time.h" #include "core/hle/service/vi/vi.h" using Kernel::ClientPort; @@ -78,7 +80,8 @@ Kernel::SharedPtr<Kernel::ClientPort> ServiceFrameworkBase::CreatePort() { ASSERT(port == nullptr); Kernel::SharedPtr<Kernel::ServerPort> server_port; Kernel::SharedPtr<Kernel::ClientPort> client_port; - std::tie(server_port, client_port) = Kernel::ServerPort::CreatePortPair(max_sessions, service_name); + std::tie(server_port, client_port) = + Kernel::ServerPort::CreatePortPair(max_sessions, service_name); port = MakeResult<Kernel::SharedPtr<Kernel::ServerPort>>(std::move(server_port)).Unwrap(); port->SetHleHandler(shared_from_this()); return client_port; @@ -164,20 +167,19 @@ void Init() { AM::InstallInterfaces(*SM::g_service_manager); AOC::InstallInterfaces(*SM::g_service_manager); APM::InstallInterfaces(*SM::g_service_manager); + Audio::InstallInterfaces(*SM::g_service_manager); + HID::InstallInterfaces(*SM::g_service_manager); LM::InstallInterfaces(*SM::g_service_manager); NVDRV::InstallInterfaces(*SM::g_service_manager); PCTL::InstallInterfaces(*SM::g_service_manager); + Time::InstallInterfaces(*SM::g_service_manager); VI::InstallInterfaces(*SM::g_service_manager); - HID::Init(); - LOG_DEBUG(Service, "initialized OK"); } /// Shutdown ServiceManager void Shutdown() { - HID::Shutdown(); - SM::g_service_manager = nullptr; g_kernel_named_ports.clear(); LOG_DEBUG(Service, "shutdown OK"); diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp new file mode 100644 index 000000000..e3d58aa60 --- /dev/null +++ b/src/core/hle/service/time/time.cpp @@ -0,0 +1,16 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/time/time.h" +#include "core/hle/service/time/time_s.h" + +namespace Service { +namespace Time { + +void InstallInterfaces(SM::ServiceManager& service_manager) { + std::make_shared<TimeS>()->InstallAsService(service_manager); +} + +} // namespace Time +} // namespace Service diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h new file mode 100644 index 000000000..7d0803e24 --- /dev/null +++ b/src/core/hle/service/time/time.h @@ -0,0 +1,16 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service { +namespace Time { + +/// Registers all Time services with the specified service manager. +void InstallInterfaces(SM::ServiceManager& service_manager); + +} // namespace Time +} // namespace Service diff --git a/src/core/hle/service/time/time_s.cpp b/src/core/hle/service/time/time_s.cpp new file mode 100644 index 000000000..6b0597d8e --- /dev/null +++ b/src/core/hle/service/time/time_s.cpp @@ -0,0 +1,58 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <chrono> +#include "common/logging/log.h" +#include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/client_port.h" +#include "core/hle/kernel/client_session.h" +#include "core/hle/service/time/time_s.h" + +namespace Service { +namespace Time { + +class ISystemClock final : public ServiceFramework<ISystemClock> { +public: + ISystemClock() : ServiceFramework("ISystemClock") { + static const FunctionInfo functions[] = { + {0, &ISystemClock::GetCurrentTime, "GetCurrentTime"}, + }; + RegisterHandlers(functions); + } + +private: + void GetCurrentTime(Kernel::HLERequestContext& ctx) { + const s64 time_since_epoch{std::chrono::duration_cast<std::chrono::milliseconds>( + std::chrono::system_clock::now().time_since_epoch()) + .count()}; + IPC::RequestBuilder rb{ctx, 4}; + rb.Push(RESULT_SUCCESS); + rb.Push<u64>(time_since_epoch); + LOG_DEBUG(Service, "called"); + } +}; + +void TimeS::GetStandardUserSystemClock(Kernel::HLERequestContext& ctx) { + auto client_port = std::make_shared<ISystemClock>()->CreatePort(); + auto session = client_port->Connect(); + if (session.Succeeded()) { + LOG_DEBUG(Service, "called, initialized ISystemClock -> session=%u", + (*session)->GetObjectId()); + IPC::RequestBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushMoveObjects(std::move(session).Unwrap()); + } else { + UNIMPLEMENTED(); + } +} + +TimeS::TimeS() : ServiceFramework("time:s") { + static const FunctionInfo functions[] = { + {0x00000000, &TimeS::GetStandardUserSystemClock, "GetStandardUserSystemClock"}, + }; + RegisterHandlers(functions); +} + +} // namespace Time +} // namespace Service diff --git a/src/core/hle/service/time/time_s.h b/src/core/hle/service/time/time_s.h new file mode 100644 index 000000000..073227910 --- /dev/null +++ b/src/core/hle/service/time/time_s.h @@ -0,0 +1,23 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/kernel/hle_ipc.h" +#include "core/hle/service/service.h" + +namespace Service { +namespace Time { + +class TimeS final : public ServiceFramework<TimeS> { +public: + TimeS(); + ~TimeS() = default; + +private: + void GetStandardUserSystemClock(Kernel::HLERequestContext& ctx); +}; + +} // namespace Time +} // namespace Service diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index d3b63949e..93ebbe75f 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp @@ -12,6 +12,8 @@ #include "core/hle/service/nvdrv/nvdrv_a.h" #include "core/hle/service/vi/vi.h" #include "core/hle/service/vi/vi_m.h" +#include "video_core/renderer_base.h" +#include "video_core/video_core.h" namespace Service { namespace VI { @@ -492,6 +494,7 @@ public: IManagerDisplayService(std::shared_ptr<NVFlinger> nv_flinger) : ServiceFramework("IManagerDisplayService"), nv_flinger(std::move(nv_flinger)) { static const FunctionInfo functions[] = { + {1020, &IManagerDisplayService::CloseDisplay, "CloseDisplay"}, {1102, nullptr, "GetDisplayResolution"}, {2010, &IManagerDisplayService::CreateManagedLayer, "CreateManagedLayer"}, {6000, &IManagerDisplayService::AddToLayerStack, "AddToLayerStack"}, @@ -501,6 +504,15 @@ public: ~IManagerDisplayService() = default; private: + void CloseDisplay(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + u64 display = rp.Pop<u64>(); + + IPC::RequestBuilder rb = rp.MakeBuilder(2, 0, 0, 0); + rb.Push(RESULT_SUCCESS); + } + void CreateManagedLayer(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service, "(STUBBED) called"); IPC::RequestParser rp{ctx}; @@ -743,7 +755,8 @@ void NVFlinger::Compose() { auto buffer = buffer_queue->AcquireBuffer(); if (buffer == boost::none) { - // There was no queued buffer to draw. + // There was no queued buffer to draw, render previous frame + VideoCore::g_renderer->SwapBuffers({}); continue; } |