am: activate button poller

This commit is contained in:
Liam 2024-02-12 01:03:41 -05:00
parent 65c0746f89
commit a9b298e9df
4 changed files with 138 additions and 0 deletions

View File

@ -405,6 +405,8 @@ add_library(core STATIC
hle/service/am/applet_data_broker.cpp hle/service/am/applet_data_broker.cpp
hle/service/am/applet_data_broker.h hle/service/am/applet_data_broker.h
hle/service/am/applet_manager.h hle/service/am/applet_manager.h
hle/service/am/button_poller.cpp
hle/service/am/button_poller.h
hle/service/am/display_layer_manager.cpp hle/service/am/display_layer_manager.cpp
hle/service/am/display_layer_manager.h hle/service/am/display_layer_manager.h
hle/service/am/frontend/applet_cabinet.cpp hle/service/am/frontend/applet_cabinet.cpp

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/am/am.h" #include "core/hle/service/am/am.h"
#include "core/hle/service/am/button_poller.h"
#include "core/hle/service/am/service/all_system_applet_proxies_service.h" #include "core/hle/service/am/service/all_system_applet_proxies_service.h"
#include "core/hle/service/am/service/application_proxy_service.h" #include "core/hle/service/am/service/application_proxy_service.h"
#include "core/hle/service/server_manager.h" #include "core/hle/service/server_manager.h"
@ -9,6 +10,8 @@
namespace Service::AM { namespace Service::AM {
void LoopProcess(Core::System& system) { void LoopProcess(Core::System& system) {
ButtonPoller button_poller(system);
auto server_manager = std::make_unique<ServerManager>(system); auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("appletAE", server_manager->RegisterNamedService("appletAE",

View File

@ -0,0 +1,94 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/core.h"
#include "core/hle/service/am/button_poller.h"
#include "hid_core/frontend/emulated_controller.h"
#include "hid_core/hid_core.h"
#include "hid_core/hid_types.h"
namespace Service::AM {
namespace {
enum class ButtonPressDuration {
ShortPressing,
MiddlePressing,
LongPressing,
};
[[maybe_unused]] ButtonPressDuration ClassifyPressDuration(
std::chrono::steady_clock::time_point start) {
using namespace std::chrono_literals;
const auto dur = std::chrono::steady_clock::now() - start;
// TODO: determine actual thresholds
// TODO: these are likely different for each button
if (dur < 500ms) {
return ButtonPressDuration::ShortPressing;
} else if (dur < 1000ms) {
return ButtonPressDuration::MiddlePressing;
} else {
return ButtonPressDuration::LongPressing;
}
}
} // namespace
ButtonPoller::ButtonPoller(Core::System& system) {
// TODO: am reads this from the home button state in hid, which is controller-agnostic.
Core::HID::ControllerUpdateCallback engine_callback{
.on_change =
[this](Core::HID::ControllerTriggerType type) {
if (type == Core::HID::ControllerTriggerType::Button) {
this->OnButtonStateChanged();
}
},
.is_npad_service = true,
};
m_handheld = system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld);
m_handheld_key = m_handheld->SetCallback(engine_callback);
m_player1 = system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
m_player1_key = m_player1->SetCallback(engine_callback);
}
ButtonPoller::~ButtonPoller() {
m_handheld->DeleteCallback(m_handheld_key);
m_player1->DeleteCallback(m_player1_key);
}
void ButtonPoller::OnButtonStateChanged() {
const bool home_button =
m_handheld->GetHomeButtons().home.Value() || m_player1->GetHomeButtons().home.Value();
const bool capture_button = m_handheld->GetCaptureButtons().capture.Value() ||
m_player1->GetCaptureButtons().capture.Value();
// Buttons pressed which were not previously pressed
if (home_button && !m_home_button_press_start) {
m_home_button_press_start = std::chrono::steady_clock::now();
}
if (capture_button && !m_capture_button_press_start) {
m_capture_button_press_start = std::chrono::steady_clock::now();
}
// if (power_button && !m_power_button_press_start) {
// m_power_button_press_start = std::chrono::steady_clock::now();
// }
// Buttons released which were previously held
if (!home_button && m_home_button_press_start) {
// TODO
m_home_button_press_start = std::nullopt;
}
if (!capture_button && m_capture_button_press_start) {
// TODO
m_capture_button_press_start = std::nullopt;
}
// if (!power_button && m_power_button_press_start) {
// // TODO
// m_power_button_press_start = std::nullopt;
// }
}
} // namespace Service::AM

View File

@ -0,0 +1,39 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <chrono>
#include <optional>
#include "hid_core/frontend/emulated_controller.h"
namespace Core {
namespace HID {
class EmulatedController;
}
class System;
} // namespace Core
namespace Service::AM {
class ButtonPoller {
public:
explicit ButtonPoller(Core::System& system);
~ButtonPoller();
private:
void OnButtonStateChanged();
private:
Core::HID::EmulatedController* m_handheld{};
int m_handheld_key{};
Core::HID::EmulatedController* m_player1{};
int m_player1_key{};
std::optional<std::chrono::steady_clock::time_point> m_home_button_press_start{};
std::optional<std::chrono::steady_clock::time_point> m_capture_button_press_start{};
std::optional<std::chrono::steady_clock::time_point> m_power_button_press_start{};
};
} // namespace Service::AM