service: hid: Implement home, capture and sleep buttons
This commit is contained in:
		@@ -96,6 +96,7 @@ add_library(hid_core STATIC
 | 
			
		||||
    resources/system_buttons/home_button.h
 | 
			
		||||
    resources/system_buttons/sleep_button.cpp
 | 
			
		||||
    resources/system_buttons/sleep_button.h
 | 
			
		||||
    resources/system_buttons/system_button_types.h
 | 
			
		||||
    resources/touch_screen/gesture.cpp
 | 
			
		||||
    resources/touch_screen/gesture.h
 | 
			
		||||
    resources/touch_screen/gesture_types.h
 | 
			
		||||
 
 | 
			
		||||
@@ -437,6 +437,16 @@ struct LedPattern {
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct SleepButtonState {
 | 
			
		||||
    union {
 | 
			
		||||
        u64 raw{};
 | 
			
		||||
 | 
			
		||||
        // Buttons
 | 
			
		||||
        BitField<0, 1, u64> sleep;
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
static_assert(sizeof(SleepButtonState) == 0x8, "SleepButtonState has incorrect size.");
 | 
			
		||||
 | 
			
		||||
struct HomeButtonState {
 | 
			
		||||
    union {
 | 
			
		||||
        u64 raw{};
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@
 | 
			
		||||
#include "hid_core/resources/mouse/mouse_types.h"
 | 
			
		||||
#include "hid_core/resources/npad/npad_types.h"
 | 
			
		||||
#include "hid_core/resources/ring_lifo.h"
 | 
			
		||||
#include "hid_core/resources/system_buttons/system_button_types.h"
 | 
			
		||||
#include "hid_core/resources/touch_screen/touch_types.h"
 | 
			
		||||
 | 
			
		||||
namespace Service::HID {
 | 
			
		||||
@@ -75,24 +76,24 @@ static_assert(sizeof(DigitizerSharedMemoryFormat) == 0x1000,
 | 
			
		||||
 | 
			
		||||
// This is nn::hid::detail::HomeButtonSharedMemoryFormat
 | 
			
		||||
struct HomeButtonSharedMemoryFormat {
 | 
			
		||||
    CommonHeader header;
 | 
			
		||||
    INSERT_PADDING_BYTES(0x1E0);
 | 
			
		||||
    Lifo<HomeButtonState, HidEntryCount> home_lifo{};
 | 
			
		||||
    INSERT_PADDING_BYTES(0x48);
 | 
			
		||||
};
 | 
			
		||||
static_assert(sizeof(HomeButtonSharedMemoryFormat) == 0x200,
 | 
			
		||||
              "HomeButtonSharedMemoryFormat is an invalid size");
 | 
			
		||||
 | 
			
		||||
// This is nn::hid::detail::SleepButtonSharedMemoryFormat
 | 
			
		||||
struct SleepButtonSharedMemoryFormat {
 | 
			
		||||
    CommonHeader header;
 | 
			
		||||
    INSERT_PADDING_BYTES(0x1E0);
 | 
			
		||||
    Lifo<SleepButtonState, HidEntryCount> sleep_lifo{};
 | 
			
		||||
    INSERT_PADDING_BYTES(0x48);
 | 
			
		||||
};
 | 
			
		||||
static_assert(sizeof(SleepButtonSharedMemoryFormat) == 0x200,
 | 
			
		||||
              "SleepButtonSharedMemoryFormat is an invalid size");
 | 
			
		||||
 | 
			
		||||
// This is nn::hid::detail::CaptureButtonSharedMemoryFormat
 | 
			
		||||
struct CaptureButtonSharedMemoryFormat {
 | 
			
		||||
    CommonHeader header;
 | 
			
		||||
    INSERT_PADDING_BYTES(0x1E0);
 | 
			
		||||
    Lifo<CaptureButtonState, HidEntryCount> capture_lifo{};
 | 
			
		||||
    INSERT_PADDING_BYTES(0x48);
 | 
			
		||||
};
 | 
			
		||||
static_assert(sizeof(CaptureButtonSharedMemoryFormat) == 0x200,
 | 
			
		||||
              "CaptureButtonSharedMemoryFormat is an invalid size");
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,8 @@
 | 
			
		||||
// SPDX-License-Identifier: GPL-2.0-or-later
 | 
			
		||||
 | 
			
		||||
#include "core/core_timing.h"
 | 
			
		||||
#include "hid_core/frontend/emulated_controller.h"
 | 
			
		||||
#include "hid_core/hid_core.h"
 | 
			
		||||
#include "hid_core/resources/applet_resource.h"
 | 
			
		||||
#include "hid_core/resources/shared_memory_format.h"
 | 
			
		||||
#include "hid_core/resources/system_buttons/capture_button.h"
 | 
			
		||||
@@ -17,10 +19,6 @@ void CaptureButton::OnInit() {}
 | 
			
		||||
void CaptureButton::OnRelease() {}
 | 
			
		||||
 | 
			
		||||
void CaptureButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
 | 
			
		||||
    if (!smart_update) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::scoped_lock shared_lock{*shared_mutex};
 | 
			
		||||
    const u64 aruid = applet_resource->GetActiveAruid();
 | 
			
		||||
    auto* data = applet_resource->GetAruidData(aruid);
 | 
			
		||||
@@ -29,11 +27,21 @@ void CaptureButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto& header = data->shared_memory_format->capture_button.header;
 | 
			
		||||
    header.timestamp = core_timing.GetGlobalTimeNs().count();
 | 
			
		||||
    header.total_entry_count = 17;
 | 
			
		||||
    header.entry_count = 0;
 | 
			
		||||
    header.last_entry_index = 0;
 | 
			
		||||
    auto& shared_memory = data->shared_memory_format->capture_button;
 | 
			
		||||
 | 
			
		||||
    if (!IsControllerActivated()) {
 | 
			
		||||
        shared_memory.capture_lifo.buffer_count = 0;
 | 
			
		||||
        shared_memory.capture_lifo.buffer_tail = 0;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const auto& last_entry = shared_memory.capture_lifo.ReadCurrentEntry().state;
 | 
			
		||||
    next_state.sampling_number = last_entry.sampling_number + 1;
 | 
			
		||||
 | 
			
		||||
    auto* controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1);
 | 
			
		||||
    next_state.buttons.raw = controller->GetHomeButtons().raw;
 | 
			
		||||
 | 
			
		||||
    shared_memory.capture_lifo.WriteNextEntry(next_state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace Service::HID
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "hid_core/resources/controller_base.h"
 | 
			
		||||
#include "hid_core/resources/system_buttons/system_button_types.h"
 | 
			
		||||
 | 
			
		||||
namespace Service::HID {
 | 
			
		||||
 | 
			
		||||
@@ -22,6 +23,6 @@ public:
 | 
			
		||||
    void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    bool smart_update{};
 | 
			
		||||
    CaptureButtonState next_state{};
 | 
			
		||||
};
 | 
			
		||||
} // namespace Service::HID
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,8 @@
 | 
			
		||||
// SPDX-License-Identifier: GPL-2.0-or-later
 | 
			
		||||
 | 
			
		||||
#include "core/core_timing.h"
 | 
			
		||||
#include "hid_core/frontend/emulated_controller.h"
 | 
			
		||||
#include "hid_core/hid_core.h"
 | 
			
		||||
#include "hid_core/resources/applet_resource.h"
 | 
			
		||||
#include "hid_core/resources/shared_memory_format.h"
 | 
			
		||||
#include "hid_core/resources/system_buttons/home_button.h"
 | 
			
		||||
@@ -17,10 +19,6 @@ void HomeButton::OnInit() {}
 | 
			
		||||
void HomeButton::OnRelease() {}
 | 
			
		||||
 | 
			
		||||
void HomeButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
 | 
			
		||||
    if (!smart_update) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::scoped_lock shared_lock{*shared_mutex};
 | 
			
		||||
    const u64 aruid = applet_resource->GetActiveAruid();
 | 
			
		||||
    auto* data = applet_resource->GetAruidData(aruid);
 | 
			
		||||
@@ -29,11 +27,21 @@ void HomeButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto& header = data->shared_memory_format->home_button.header;
 | 
			
		||||
    header.timestamp = core_timing.GetGlobalTimeNs().count();
 | 
			
		||||
    header.total_entry_count = 17;
 | 
			
		||||
    header.entry_count = 0;
 | 
			
		||||
    header.last_entry_index = 0;
 | 
			
		||||
    auto& shared_memory = data->shared_memory_format->home_button;
 | 
			
		||||
 | 
			
		||||
    if (!IsControllerActivated()) {
 | 
			
		||||
        shared_memory.home_lifo.buffer_count = 0;
 | 
			
		||||
        shared_memory.home_lifo.buffer_tail = 0;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const auto& last_entry = shared_memory.home_lifo.ReadCurrentEntry().state;
 | 
			
		||||
    next_state.sampling_number = last_entry.sampling_number + 1;
 | 
			
		||||
 | 
			
		||||
    auto* controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1);
 | 
			
		||||
    next_state.buttons.raw = controller->GetHomeButtons().raw;
 | 
			
		||||
 | 
			
		||||
    shared_memory.home_lifo.WriteNextEntry(next_state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace Service::HID
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "hid_core/resources/controller_base.h"
 | 
			
		||||
#include "hid_core/resources/system_buttons/system_button_types.h"
 | 
			
		||||
 | 
			
		||||
namespace Service::HID {
 | 
			
		||||
 | 
			
		||||
@@ -22,6 +23,6 @@ public:
 | 
			
		||||
    void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    bool smart_update{};
 | 
			
		||||
    HomeButtonState next_state{};
 | 
			
		||||
};
 | 
			
		||||
} // namespace Service::HID
 | 
			
		||||
 
 | 
			
		||||
@@ -17,10 +17,6 @@ void SleepButton::OnInit() {}
 | 
			
		||||
void SleepButton::OnRelease() {}
 | 
			
		||||
 | 
			
		||||
void SleepButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
 | 
			
		||||
    if (!smart_update) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::scoped_lock shared_lock{*shared_mutex};
 | 
			
		||||
    const u64 aruid = applet_resource->GetActiveAruid();
 | 
			
		||||
    auto* data = applet_resource->GetAruidData(aruid);
 | 
			
		||||
@@ -29,11 +25,20 @@ void SleepButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto& header = data->shared_memory_format->capture_button.header;
 | 
			
		||||
    header.timestamp = core_timing.GetGlobalTimeNs().count();
 | 
			
		||||
    header.total_entry_count = 17;
 | 
			
		||||
    header.entry_count = 0;
 | 
			
		||||
    header.last_entry_index = 0;
 | 
			
		||||
    auto& shared_memory = data->shared_memory_format->sleep_button;
 | 
			
		||||
 | 
			
		||||
    if (!IsControllerActivated()) {
 | 
			
		||||
        shared_memory.sleep_lifo.buffer_count = 0;
 | 
			
		||||
        shared_memory.sleep_lifo.buffer_tail = 0;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const auto& last_entry = shared_memory.sleep_lifo.ReadCurrentEntry().state;
 | 
			
		||||
    next_state.sampling_number = last_entry.sampling_number + 1;
 | 
			
		||||
 | 
			
		||||
    next_state.buttons.raw = 0;
 | 
			
		||||
 | 
			
		||||
    shared_memory.sleep_lifo.WriteNextEntry(next_state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace Service::HID
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "hid_core/resources/controller_base.h"
 | 
			
		||||
#include "hid_core/resources/system_buttons/system_button_types.h"
 | 
			
		||||
 | 
			
		||||
namespace Service::HID {
 | 
			
		||||
 | 
			
		||||
@@ -22,6 +23,6 @@ public:
 | 
			
		||||
    void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    bool smart_update{};
 | 
			
		||||
    SleepButtonState next_state{};
 | 
			
		||||
};
 | 
			
		||||
} // namespace Service::HID
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										31
									
								
								src/hid_core/resources/system_buttons/system_button_types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/hid_core/resources/system_buttons/system_button_types.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 | 
			
		||||
// SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "hid_core/hid_types.h"
 | 
			
		||||
 | 
			
		||||
namespace Service::HID {
 | 
			
		||||
 | 
			
		||||
// This is nn::hid::system::SleepButtonState
 | 
			
		||||
struct SleepButtonState {
 | 
			
		||||
    s64 sampling_number{};
 | 
			
		||||
    Core::HID::SleepButtonState buttons;
 | 
			
		||||
};
 | 
			
		||||
static_assert(sizeof(SleepButtonState) == 0x10, "SleepButtonState is an invalid size");
 | 
			
		||||
 | 
			
		||||
// This is nn::hid::system::HomeButtonState
 | 
			
		||||
struct HomeButtonState {
 | 
			
		||||
    s64 sampling_number{};
 | 
			
		||||
    Core::HID::HomeButtonState buttons;
 | 
			
		||||
};
 | 
			
		||||
static_assert(sizeof(HomeButtonState) == 0x10, "HomeButtonState is an invalid size");
 | 
			
		||||
 | 
			
		||||
// This is nn::hid::system::SleepButtonState
 | 
			
		||||
struct CaptureButtonState {
 | 
			
		||||
    s64 sampling_number{};
 | 
			
		||||
    Core::HID::CaptureButtonState buttons;
 | 
			
		||||
};
 | 
			
		||||
static_assert(sizeof(CaptureButtonState) == 0x10, "CaptureButtonState is an invalid size");
 | 
			
		||||
 | 
			
		||||
} // namespace Service::HID
 | 
			
		||||
@@ -28,7 +28,7 @@ void UniquePad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto& header = data->shared_memory_format->capture_button.header;
 | 
			
		||||
    auto& header = data->shared_memory_format->unique_pad.header;
 | 
			
		||||
    header.timestamp = core_timing.GetGlobalTimeNs().count();
 | 
			
		||||
    header.total_entry_count = 17;
 | 
			
		||||
    header.entry_count = 0;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user