summaryrefslogtreecommitdiff
path: root/src/core/hle/service
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service')
-rw-r--r--src/core/hle/service/am/applets/applet_cabinet.cpp177
-rw-r--r--src/core/hle/service/am/applets/applet_cabinet.h104
-rw-r--r--src/core/hle/service/am/applets/applet_error.cpp1
-rw-r--r--src/core/hle/service/am/applets/applet_general_backend.cpp2
-rw-r--r--src/core/hle/service/am/applets/applets.cpp20
-rw-r--r--src/core/hle/service/am/applets/applets.h12
-rw-r--r--src/core/hle/service/hid/hid.cpp32
-rw-r--r--src/core/hle/service/hid/hid.h4
-rw-r--r--src/core/hle/service/nfp/nfp_device.cpp35
-rw-r--r--src/core/hle/service/nfp/nfp_device.h6
-rw-r--r--src/core/hle/service/nfp/nfp_types.h17
-rw-r--r--src/core/hle/service/nfp/nfp_user.cpp2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp5
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue_core.cpp6
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue_core.h5
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue_producer.cpp14
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue_producer.h3
-rw-r--r--src/core/hle/service/service.cpp1
-rw-r--r--src/core/hle/service/time/time_zone_manager.cpp1
20 files changed, 413 insertions, 39 deletions
diff --git a/src/core/hle/service/am/applets/applet_cabinet.cpp b/src/core/hle/service/am/applets/applet_cabinet.cpp
new file mode 100644
index 000000000..d0969b0f1
--- /dev/null
+++ b/src/core/hle/service/am/applets/applet_cabinet.cpp
@@ -0,0 +1,177 @@
1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "common/assert.h"
5#include "common/logging/log.h"
6#include "core/core.h"
7#include "core/frontend/applets/cabinet.h"
8#include "core/hid/hid_core.h"
9#include "core/hle/kernel/k_event.h"
10#include "core/hle/kernel/k_readable_event.h"
11#include "core/hle/service/am/am.h"
12#include "core/hle/service/am/applets/applet_cabinet.h"
13#include "core/hle/service/mii/mii_manager.h"
14#include "core/hle/service/nfp/nfp_device.h"
15
16namespace Service::AM::Applets {
17
18Cabinet::Cabinet(Core::System& system_, LibraryAppletMode applet_mode_,
19 const Core::Frontend::CabinetApplet& frontend_)
20 : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_}, service_context{
21 system_,
22 "CabinetApplet"} {
23
24 availability_change_event =
25 service_context.CreateEvent("CabinetApplet:AvailabilityChangeEvent");
26}
27
28Cabinet::~Cabinet() = default;
29
30void Cabinet::Initialize() {
31 Applet::Initialize();
32
33 LOG_INFO(Service_HID, "Initializing Cabinet Applet.");
34
35 LOG_DEBUG(Service_HID,
36 "Initializing Applet with common_args: arg_version={}, lib_version={}, "
37 "play_startup_sound={}, size={}, system_tick={}, theme_color={}",
38 common_args.arguments_version, common_args.library_version,
39 common_args.play_startup_sound, common_args.size, common_args.system_tick,
40 common_args.theme_color);
41
42 const auto storage = broker.PopNormalDataToApplet();
43 ASSERT(storage != nullptr);
44
45 const auto applet_input_data = storage->GetData();
46 ASSERT(applet_input_data.size() >= sizeof(StartParamForAmiiboSettings));
47
48 std::memcpy(&applet_input_common, applet_input_data.data(),
49 sizeof(StartParamForAmiiboSettings));
50}
51
52bool Cabinet::TransactionComplete() const {
53 return is_complete;
54}
55
56Result Cabinet::GetStatus() const {
57 return ResultSuccess;
58}
59
60void Cabinet::ExecuteInteractive() {
61 ASSERT_MSG(false, "Attempted to call interactive execution on non-interactive applet.");
62}
63
64void Cabinet::Execute() {
65 if (is_complete) {
66 return;
67 }
68
69 const auto callback = [this](bool apply_changes, const std::string& amiibo_name) {
70 DisplayCompleted(apply_changes, amiibo_name);
71 };
72
73 // TODO: listen on all controllers
74 if (nfp_device == nullptr) {
75 nfp_device = std::make_shared<Service::NFP::NfpDevice>(
76 system.HIDCore().GetFirstNpadId(), system, service_context, availability_change_event);
77 nfp_device->Initialize();
78 nfp_device->StartDetection(Service::NFP::TagProtocol::All);
79 }
80
81 const Core::Frontend::CabinetParameters parameters{
82 .tag_info = applet_input_common.tag_info,
83 .register_info = applet_input_common.register_info,
84 .mode = applet_input_common.applet_mode,
85 };
86
87 switch (applet_input_common.applet_mode) {
88 case Service::NFP::CabinetMode::StartNicknameAndOwnerSettings:
89 case Service::NFP::CabinetMode::StartGameDataEraser:
90 case Service::NFP::CabinetMode::StartRestorer:
91 case Service::NFP::CabinetMode::StartFormatter:
92 frontend.ShowCabinetApplet(callback, parameters, nfp_device);
93 break;
94 default:
95 UNIMPLEMENTED_MSG("Unknown CabinetMode={}", applet_input_common.applet_mode);
96 DisplayCompleted(false, {});
97 break;
98 }
99}
100
101void Cabinet::DisplayCompleted(bool apply_changes, std::string_view amiibo_name) {
102 Service::Mii::MiiManager manager;
103 ReturnValueForAmiiboSettings applet_output{};
104
105 if (!apply_changes) {
106 Cancel();
107 }
108
109 if (nfp_device->GetCurrentState() != Service::NFP::DeviceState::TagFound &&
110 nfp_device->GetCurrentState() != Service::NFP::DeviceState::TagMounted) {
111 Cancel();
112 }
113
114 if (nfp_device->GetCurrentState() == Service::NFP::DeviceState::TagFound) {
115 nfp_device->Mount(Service::NFP::MountTarget::All);
116 }
117
118 switch (applet_input_common.applet_mode) {
119 case Service::NFP::CabinetMode::StartNicknameAndOwnerSettings: {
120 Service::NFP::AmiiboName name{};
121 std::memcpy(name.data(), amiibo_name.data(), std::min(amiibo_name.size(), name.size() - 1));
122 nfp_device->SetNicknameAndOwner(name);
123 break;
124 }
125 case Service::NFP::CabinetMode::StartGameDataEraser:
126 nfp_device->DeleteApplicationArea();
127 break;
128 case Service::NFP::CabinetMode::StartRestorer:
129 nfp_device->RestoreAmiibo();
130 break;
131 case Service::NFP::CabinetMode::StartFormatter:
132 nfp_device->DeleteAllData();
133 break;
134 default:
135 UNIMPLEMENTED_MSG("Unknown CabinetMode={}", applet_input_common.applet_mode);
136 break;
137 }
138
139 applet_output.device_handle = applet_input_common.device_handle;
140 applet_output.result = CabinetResult::Cancel;
141 const auto reg_result = nfp_device->GetRegisterInfo(applet_output.register_info);
142 const auto tag_result = nfp_device->GetTagInfo(applet_output.tag_info);
143 nfp_device->Finalize();
144
145 if (reg_result.IsSuccess()) {
146 applet_output.result |= CabinetResult::RegisterInfo;
147 }
148
149 if (tag_result.IsSuccess()) {
150 applet_output.result |= CabinetResult::TagInfo;
151 }
152
153 std::vector<u8> out_data(sizeof(ReturnValueForAmiiboSettings));
154 std::memcpy(out_data.data(), &applet_output, sizeof(ReturnValueForAmiiboSettings));
155
156 is_complete = true;
157
158 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data)));
159 broker.SignalStateChanged();
160}
161
162void Cabinet::Cancel() {
163 ReturnValueForAmiiboSettings applet_output{};
164 applet_output.device_handle = applet_input_common.device_handle;
165 applet_output.result = CabinetResult::Cancel;
166 nfp_device->Finalize();
167
168 std::vector<u8> out_data(sizeof(ReturnValueForAmiiboSettings));
169 std::memcpy(out_data.data(), &applet_output, sizeof(ReturnValueForAmiiboSettings));
170
171 is_complete = true;
172
173 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data)));
174 broker.SignalStateChanged();
175}
176
177} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/am/applets/applet_cabinet.h b/src/core/hle/service/am/applets/applet_cabinet.h
new file mode 100644
index 000000000..84197a807
--- /dev/null
+++ b/src/core/hle/service/am/applets/applet_cabinet.h
@@ -0,0 +1,104 @@
1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <array>
7
8#include "core/hle/result.h"
9#include "core/hle/service/am/applets/applets.h"
10#include "core/hle/service/kernel_helpers.h"
11#include "core/hle/service/nfp/nfp_types.h"
12
13namespace Kernel {
14class KEvent;
15class KReadableEvent;
16} // namespace Kernel
17
18namespace Core {
19class System;
20} // namespace Core
21
22namespace Service::NFP {
23class NfpDevice;
24}
25
26namespace Service::AM::Applets {
27
28enum class CabinetAppletVersion : u32 {
29 Version1 = 0x1,
30};
31
32enum class CabinetResult : u8 {
33 Cancel = 0,
34 TagInfo = 1 << 1,
35 RegisterInfo = 1 << 2,
36 All = TagInfo | RegisterInfo,
37};
38DECLARE_ENUM_FLAG_OPERATORS(CabinetResult)
39
40// This is nn::nfp::AmiiboSettingsStartParam
41struct AmiiboSettingsStartParam {
42 u64 device_handle;
43 std::array<u8, 0x20> param_1;
44 u8 param_2;
45};
46static_assert(sizeof(AmiiboSettingsStartParam) == 0x30,
47 "AmiiboSettingsStartParam is an invalid size");
48
49#pragma pack(push, 1)
50// This is nn::nfp::StartParamForAmiiboSettings
51struct StartParamForAmiiboSettings {
52 u8 param_1;
53 Service::NFP::CabinetMode applet_mode;
54 u8 flags;
55 u8 amiibo_settings_1;
56 u64 device_handle;
57 Service::NFP::TagInfo tag_info;
58 Service::NFP::RegisterInfo register_info;
59 std::array<u8, 0x20> amiibo_settings_3;
60 INSERT_PADDING_BYTES(0x24);
61};
62static_assert(sizeof(StartParamForAmiiboSettings) == 0x1A8,
63 "StartParamForAmiiboSettings is an invalid size");
64
65// This is nn::nfp::ReturnValueForAmiiboSettings
66struct ReturnValueForAmiiboSettings {
67 CabinetResult result;
68 INSERT_PADDING_BYTES(0x3);
69 u64 device_handle;
70 Service::NFP::TagInfo tag_info;
71 Service::NFP::RegisterInfo register_info;
72 INSERT_PADDING_BYTES(0x24);
73};
74static_assert(sizeof(ReturnValueForAmiiboSettings) == 0x188,
75 "ReturnValueForAmiiboSettings is an invalid size");
76#pragma pack(pop)
77
78class Cabinet final : public Applet {
79public:
80 explicit Cabinet(Core::System& system_, LibraryAppletMode applet_mode_,
81 const Core::Frontend::CabinetApplet& frontend_);
82 ~Cabinet() override;
83
84 void Initialize() override;
85
86 bool TransactionComplete() const override;
87 Result GetStatus() const override;
88 void ExecuteInteractive() override;
89 void Execute() override;
90 void DisplayCompleted(bool apply_changes, std::string_view amiibo_name);
91 void Cancel();
92
93private:
94 const Core::Frontend::CabinetApplet& frontend;
95 Core::System& system;
96
97 bool is_complete{false};
98 std::shared_ptr<Service::NFP::NfpDevice> nfp_device;
99 Kernel::KEvent* availability_change_event;
100 KernelHelpers::ServiceContext service_context;
101 StartParamForAmiiboSettings applet_input_common{};
102};
103
104} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/am/applets/applet_error.cpp b/src/core/hle/service/am/applets/applet_error.cpp
index fcf34bf7e..bae0d99a6 100644
--- a/src/core/hle/service/am/applets/applet_error.cpp
+++ b/src/core/hle/service/am/applets/applet_error.cpp
@@ -144,6 +144,7 @@ void Error::Initialize() {
144 break; 144 break;
145 default: 145 default:
146 UNIMPLEMENTED_MSG("Unimplemented LibAppletError mode={:02X}!", mode); 146 UNIMPLEMENTED_MSG("Unimplemented LibAppletError mode={:02X}!", mode);
147 break;
147 } 148 }
148} 149}
149 150
diff --git a/src/core/hle/service/am/applets/applet_general_backend.cpp b/src/core/hle/service/am/applets/applet_general_backend.cpp
index c34ef08b3..e50acdaf6 100644
--- a/src/core/hle/service/am/applets/applet_general_backend.cpp
+++ b/src/core/hle/service/am/applets/applet_general_backend.cpp
@@ -129,6 +129,7 @@ void Auth::Execute() {
129 } 129 }
130 default: 130 default:
131 unimplemented_log(); 131 unimplemented_log();
132 break;
132 } 133 }
133} 134}
134 135
@@ -192,6 +193,7 @@ void PhotoViewer::Execute() {
192 break; 193 break;
193 default: 194 default:
194 UNIMPLEMENTED_MSG("Unimplemented PhotoViewer applet mode={:02X}!", mode); 195 UNIMPLEMENTED_MSG("Unimplemented PhotoViewer applet mode={:02X}!", mode);
196 break;
195 } 197 }
196} 198}
197 199
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp
index 7062df21c..10afbc2da 100644
--- a/src/core/hle/service/am/applets/applets.cpp
+++ b/src/core/hle/service/am/applets/applets.cpp
@@ -5,6 +5,7 @@
5 5
6#include "common/assert.h" 6#include "common/assert.h"
7#include "core/core.h" 7#include "core/core.h"
8#include "core/frontend/applets/cabinet.h"
8#include "core/frontend/applets/controller.h" 9#include "core/frontend/applets/controller.h"
9#include "core/frontend/applets/error.h" 10#include "core/frontend/applets/error.h"
10#include "core/frontend/applets/general_frontend.h" 11#include "core/frontend/applets/general_frontend.h"
@@ -16,6 +17,7 @@
16#include "core/hle/service/am/am.h" 17#include "core/hle/service/am/am.h"
17#include "core/hle/service/am/applet_ae.h" 18#include "core/hle/service/am/applet_ae.h"
18#include "core/hle/service/am/applet_oe.h" 19#include "core/hle/service/am/applet_oe.h"
20#include "core/hle/service/am/applets/applet_cabinet.h"
19#include "core/hle/service/am/applets/applet_controller.h" 21#include "core/hle/service/am/applets/applet_controller.h"
20#include "core/hle/service/am/applets/applet_error.h" 22#include "core/hle/service/am/applets/applet_error.h"
21#include "core/hle/service/am/applets/applet_general_backend.h" 23#include "core/hle/service/am/applets/applet_general_backend.h"
@@ -171,13 +173,15 @@ void Applet::Initialize() {
171 173
172AppletFrontendSet::AppletFrontendSet() = default; 174AppletFrontendSet::AppletFrontendSet() = default;
173 175
174AppletFrontendSet::AppletFrontendSet(ControllerApplet controller_applet, ErrorApplet error_applet, 176AppletFrontendSet::AppletFrontendSet(CabinetApplet cabinet_applet,
177 ControllerApplet controller_applet, ErrorApplet error_applet,
175 MiiEdit mii_edit_, 178 MiiEdit mii_edit_,
176 ParentalControlsApplet parental_controls_applet, 179 ParentalControlsApplet parental_controls_applet,
177 PhotoViewer photo_viewer_, ProfileSelect profile_select_, 180 PhotoViewer photo_viewer_, ProfileSelect profile_select_,
178 SoftwareKeyboard software_keyboard_, WebBrowser web_browser_) 181 SoftwareKeyboard software_keyboard_, WebBrowser web_browser_)
179 : controller{std::move(controller_applet)}, error{std::move(error_applet)}, 182 : cabinet{std::move(cabinet_applet)}, controller{std::move(controller_applet)},
180 mii_edit{std::move(mii_edit_)}, parental_controls{std::move(parental_controls_applet)}, 183 error{std::move(error_applet)}, mii_edit{std::move(mii_edit_)},
184 parental_controls{std::move(parental_controls_applet)},
181 photo_viewer{std::move(photo_viewer_)}, profile_select{std::move(profile_select_)}, 185 photo_viewer{std::move(photo_viewer_)}, profile_select{std::move(profile_select_)},
182 software_keyboard{std::move(software_keyboard_)}, web_browser{std::move(web_browser_)} {} 186 software_keyboard{std::move(software_keyboard_)}, web_browser{std::move(web_browser_)} {}
183 187
@@ -196,6 +200,10 @@ const AppletFrontendSet& AppletManager::GetAppletFrontendSet() const {
196} 200}
197 201
198void AppletManager::SetAppletFrontendSet(AppletFrontendSet set) { 202void AppletManager::SetAppletFrontendSet(AppletFrontendSet set) {
203 if (set.cabinet != nullptr) {
204 frontend.cabinet = std::move(set.cabinet);
205 }
206
199 if (set.controller != nullptr) { 207 if (set.controller != nullptr) {
200 frontend.controller = std::move(set.controller); 208 frontend.controller = std::move(set.controller);
201 } 209 }
@@ -235,6 +243,10 @@ void AppletManager::SetDefaultAppletFrontendSet() {
235} 243}
236 244
237void AppletManager::SetDefaultAppletsIfMissing() { 245void AppletManager::SetDefaultAppletsIfMissing() {
246 if (frontend.cabinet == nullptr) {
247 frontend.cabinet = std::make_unique<Core::Frontend::DefaultCabinetApplet>();
248 }
249
238 if (frontend.controller == nullptr) { 250 if (frontend.controller == nullptr) {
239 frontend.controller = 251 frontend.controller =
240 std::make_unique<Core::Frontend::DefaultControllerApplet>(system.HIDCore()); 252 std::make_unique<Core::Frontend::DefaultControllerApplet>(system.HIDCore());
@@ -279,6 +291,8 @@ std::shared_ptr<Applet> AppletManager::GetApplet(AppletId id, LibraryAppletMode
279 switch (id) { 291 switch (id) {
280 case AppletId::Auth: 292 case AppletId::Auth:
281 return std::make_shared<Auth>(system, mode, *frontend.parental_controls); 293 return std::make_shared<Auth>(system, mode, *frontend.parental_controls);
294 case AppletId::Cabinet:
295 return std::make_shared<Cabinet>(system, mode, *frontend.cabinet);
282 case AppletId::Controller: 296 case AppletId::Controller:
283 return std::make_shared<Controller>(system, mode, *frontend.controller); 297 return std::make_shared<Controller>(system, mode, *frontend.controller);
284 case AppletId::Error: 298 case AppletId::Error:
diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h
index 12c6a5b1a..a22eb62a8 100644
--- a/src/core/hle/service/am/applets/applets.h
+++ b/src/core/hle/service/am/applets/applets.h
@@ -16,6 +16,7 @@ class System;
16} 16}
17 17
18namespace Core::Frontend { 18namespace Core::Frontend {
19class CabinetApplet;
19class ControllerApplet; 20class ControllerApplet;
20class ECommerceApplet; 21class ECommerceApplet;
21class ErrorApplet; 22class ErrorApplet;
@@ -176,6 +177,7 @@ protected:
176}; 177};
177 178
178struct AppletFrontendSet { 179struct AppletFrontendSet {
180 using CabinetApplet = std::unique_ptr<Core::Frontend::CabinetApplet>;
179 using ControllerApplet = std::unique_ptr<Core::Frontend::ControllerApplet>; 181 using ControllerApplet = std::unique_ptr<Core::Frontend::ControllerApplet>;
180 using ErrorApplet = std::unique_ptr<Core::Frontend::ErrorApplet>; 182 using ErrorApplet = std::unique_ptr<Core::Frontend::ErrorApplet>;
181 using MiiEdit = std::unique_ptr<Core::Frontend::MiiEditApplet>; 183 using MiiEdit = std::unique_ptr<Core::Frontend::MiiEditApplet>;
@@ -186,10 +188,11 @@ struct AppletFrontendSet {
186 using WebBrowser = std::unique_ptr<Core::Frontend::WebBrowserApplet>; 188 using WebBrowser = std::unique_ptr<Core::Frontend::WebBrowserApplet>;
187 189
188 AppletFrontendSet(); 190 AppletFrontendSet();
189 AppletFrontendSet(ControllerApplet controller_applet, ErrorApplet error_applet, 191 AppletFrontendSet(CabinetApplet cabinet_applet, ControllerApplet controller_applet,
190 MiiEdit mii_edit_, ParentalControlsApplet parental_controls_applet, 192 ErrorApplet error_applet, MiiEdit mii_edit_,
191 PhotoViewer photo_viewer_, ProfileSelect profile_select_, 193 ParentalControlsApplet parental_controls_applet, PhotoViewer photo_viewer_,
192 SoftwareKeyboard software_keyboard_, WebBrowser web_browser_); 194 ProfileSelect profile_select_, SoftwareKeyboard software_keyboard_,
195 WebBrowser web_browser_);
193 ~AppletFrontendSet(); 196 ~AppletFrontendSet();
194 197
195 AppletFrontendSet(const AppletFrontendSet&) = delete; 198 AppletFrontendSet(const AppletFrontendSet&) = delete;
@@ -198,6 +201,7 @@ struct AppletFrontendSet {
198 AppletFrontendSet(AppletFrontendSet&&) noexcept; 201 AppletFrontendSet(AppletFrontendSet&&) noexcept;
199 AppletFrontendSet& operator=(AppletFrontendSet&&) noexcept; 202 AppletFrontendSet& operator=(AppletFrontendSet&&) noexcept;
200 203
204 CabinetApplet cabinet;
201 ControllerApplet controller; 205 ControllerApplet controller;
202 ErrorApplet error; 206 ErrorApplet error;
203 MiiEdit mii_edit; 207 MiiEdit mii_edit;
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 79375bd2f..bf28440c6 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -36,8 +36,9 @@ namespace Service::HID {
36 36
37// Updating period for each HID device. 37// Updating period for each HID device.
38// Period time is obtained by measuring the number of samples in a second on HW using a homebrew 38// Period time is obtained by measuring the number of samples in a second on HW using a homebrew
39// Correct pad_update_ns is 4ms this is overclocked to lower input lag 39// Correct npad_update_ns is 4ms this is overclocked to lower input lag
40constexpr auto pad_update_ns = std::chrono::nanoseconds{1 * 1000 * 1000}; // (1ms, 1000Hz) 40constexpr auto npad_update_ns = std::chrono::nanoseconds{1 * 1000 * 1000}; // (1ms, 1000Hz)
41constexpr auto default_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 1000Hz)
41constexpr auto mouse_keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz) 42constexpr auto mouse_keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz)
42constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz) 43constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz)
43 44
@@ -75,11 +76,19 @@ IAppletResource::IAppletResource(Core::System& system_,
75 GetController<Controller_Stubbed>(HidController::UniquePad).SetCommonHeaderOffset(0x5A00); 76 GetController<Controller_Stubbed>(HidController::UniquePad).SetCommonHeaderOffset(0x5A00);
76 77
77 // Register update callbacks 78 // Register update callbacks
78 pad_update_event = Core::Timing::CreateEvent( 79 npad_update_event = Core::Timing::CreateEvent(
79 "HID::UpdatePadCallback", 80 "HID::UpdatePadCallback",
80 [this](std::uintptr_t user_data, s64 time, 81 [this](std::uintptr_t user_data, s64 time,
81 std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { 82 std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
82 const auto guard = LockService(); 83 const auto guard = LockService();
84 UpdateNpad(user_data, ns_late);
85 return std::nullopt;
86 });
87 default_update_event = Core::Timing::CreateEvent(
88 "HID::UpdateDefaultCallback",
89 [this](std::uintptr_t user_data, s64 time,
90 std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
91 const auto guard = LockService();
83 UpdateControllers(user_data, ns_late); 92 UpdateControllers(user_data, ns_late);
84 return std::nullopt; 93 return std::nullopt;
85 }); 94 });
@@ -100,7 +109,9 @@ IAppletResource::IAppletResource(Core::System& system_,
100 return std::nullopt; 109 return std::nullopt;
101 }); 110 });
102 111
103 system.CoreTiming().ScheduleLoopingEvent(pad_update_ns, pad_update_ns, pad_update_event); 112 system.CoreTiming().ScheduleLoopingEvent(npad_update_ns, npad_update_ns, npad_update_event);
113 system.CoreTiming().ScheduleLoopingEvent(default_update_ns, default_update_ns,
114 default_update_event);
104 system.CoreTiming().ScheduleLoopingEvent(mouse_keyboard_update_ns, mouse_keyboard_update_ns, 115 system.CoreTiming().ScheduleLoopingEvent(mouse_keyboard_update_ns, mouse_keyboard_update_ns,
105 mouse_keyboard_update_event); 116 mouse_keyboard_update_event);
106 system.CoreTiming().ScheduleLoopingEvent(motion_update_ns, motion_update_ns, 117 system.CoreTiming().ScheduleLoopingEvent(motion_update_ns, motion_update_ns,
@@ -118,7 +129,8 @@ void IAppletResource::DeactivateController(HidController controller) {
118} 129}
119 130
120IAppletResource::~IAppletResource() { 131IAppletResource::~IAppletResource() {
121 system.CoreTiming().UnscheduleEvent(pad_update_event, 0); 132 system.CoreTiming().UnscheduleEvent(npad_update_event, 0);
133 system.CoreTiming().UnscheduleEvent(default_update_event, 0);
122 system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event, 0); 134 system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event, 0);
123 system.CoreTiming().UnscheduleEvent(motion_update_event, 0); 135 system.CoreTiming().UnscheduleEvent(motion_update_event, 0);
124} 136}
@@ -144,10 +156,20 @@ void IAppletResource::UpdateControllers(std::uintptr_t user_data,
144 if (controller == controllers[static_cast<size_t>(HidController::Mouse)]) { 156 if (controller == controllers[static_cast<size_t>(HidController::Mouse)]) {
145 continue; 157 continue;
146 } 158 }
159 // Npad has it's own update event
160 if (controller == controllers[static_cast<size_t>(HidController::NPad)]) {
161 continue;
162 }
147 controller->OnUpdate(core_timing); 163 controller->OnUpdate(core_timing);
148 } 164 }
149} 165}
150 166
167void IAppletResource::UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
168 auto& core_timing = system.CoreTiming();
169
170 controllers[static_cast<size_t>(HidController::NPad)]->OnUpdate(core_timing);
171}
172
151void IAppletResource::UpdateMouseKeyboard(std::uintptr_t user_data, 173void IAppletResource::UpdateMouseKeyboard(std::uintptr_t user_data,
152 std::chrono::nanoseconds ns_late) { 174 std::chrono::nanoseconds ns_late) {
153 auto& core_timing = system.CoreTiming(); 175 auto& core_timing = system.CoreTiming();
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index 340d26fdc..b7c2a23ef 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -71,12 +71,14 @@ private:
71 71
72 void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx); 72 void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx);
73 void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 73 void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
74 void UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
74 void UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 75 void UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
75 void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 76 void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
76 77
77 KernelHelpers::ServiceContext& service_context; 78 KernelHelpers::ServiceContext& service_context;
78 79
79 std::shared_ptr<Core::Timing::EventType> pad_update_event; 80 std::shared_ptr<Core::Timing::EventType> npad_update_event;
81 std::shared_ptr<Core::Timing::EventType> default_update_event;
80 std::shared_ptr<Core::Timing::EventType> mouse_keyboard_update_event; 82 std::shared_ptr<Core::Timing::EventType> mouse_keyboard_update_event;
81 std::shared_ptr<Core::Timing::EventType> motion_update_event; 83 std::shared_ptr<Core::Timing::EventType> motion_update_event;
82 84
diff --git a/src/core/hle/service/nfp/nfp_device.cpp b/src/core/hle/service/nfp/nfp_device.cpp
index 296603764..c860fd1a1 100644
--- a/src/core/hle/service/nfp/nfp_device.cpp
+++ b/src/core/hle/service/nfp/nfp_device.cpp
@@ -75,6 +75,9 @@ void NfpDevice::NpadUpdate(Core::HID::ControllerTriggerType type) {
75 LoadAmiibo(nfc_status.data); 75 LoadAmiibo(nfc_status.data);
76 break; 76 break;
77 case Common::Input::NfcState::AmiiboRemoved: 77 case Common::Input::NfcState::AmiiboRemoved:
78 if (device_state == DeviceState::Initialized || device_state == DeviceState::TagRemoved) {
79 break;
80 }
78 if (device_state != DeviceState::SearchingForTag) { 81 if (device_state != DeviceState::SearchingForTag) {
79 CloseAmiibo(); 82 CloseAmiibo();
80 } 83 }
@@ -95,6 +98,8 @@ bool NfpDevice::LoadAmiibo(std::span<const u8> data) {
95 return false; 98 return false;
96 } 99 }
97 100
101 // TODO: Filter by allowed_protocols here
102
98 memcpy(&encrypted_tag_data, data.data(), sizeof(EncryptedNTAG215File)); 103 memcpy(&encrypted_tag_data, data.data(), sizeof(EncryptedNTAG215File));
99 104
100 device_state = DeviceState::TagFound; 105 device_state = DeviceState::TagFound;
@@ -141,7 +146,7 @@ void NfpDevice::Finalize() {
141 device_state = DeviceState::Unavailable; 146 device_state = DeviceState::Unavailable;
142} 147}
143 148
144Result NfpDevice::StartDetection(s32 protocol_) { 149Result NfpDevice::StartDetection(TagProtocol allowed_protocol) {
145 if (device_state != DeviceState::Initialized && device_state != DeviceState::TagRemoved) { 150 if (device_state != DeviceState::Initialized && device_state != DeviceState::TagRemoved) {
146 LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); 151 LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
147 return WrongDeviceState; 152 return WrongDeviceState;
@@ -153,7 +158,7 @@ Result NfpDevice::StartDetection(s32 protocol_) {
153 } 158 }
154 159
155 device_state = DeviceState::SearchingForTag; 160 device_state = DeviceState::SearchingForTag;
156 protocol = protocol_; 161 allowed_protocols = allowed_protocol;
157 return ResultSuccess; 162 return ResultSuccess;
158} 163}
159 164
@@ -467,6 +472,32 @@ Result NfpDevice::OpenApplicationArea(u32 access_id) {
467 return ResultSuccess; 472 return ResultSuccess;
468} 473}
469 474
475Result NfpDevice::GetApplicationAreaId(u32& application_area_id) const {
476 application_area_id = {};
477
478 if (device_state != DeviceState::TagMounted) {
479 LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
480 if (device_state == DeviceState::TagRemoved) {
481 return TagRemoved;
482 }
483 return WrongDeviceState;
484 }
485
486 if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) {
487 LOG_ERROR(Service_NFP, "Amiibo is read only", device_state);
488 return WrongDeviceState;
489 }
490
491 if (tag_data.settings.settings.appdata_initialized.Value() == 0) {
492 LOG_WARNING(Service_NFP, "Application area is not initialized");
493 return ApplicationAreaIsNotInitialized;
494 }
495
496 application_area_id = tag_data.application_area_id;
497
498 return ResultSuccess;
499}
500
470Result NfpDevice::GetApplicationArea(std::vector<u8>& data) const { 501Result NfpDevice::GetApplicationArea(std::vector<u8>& data) const {
471 if (device_state != DeviceState::TagMounted) { 502 if (device_state != DeviceState::TagMounted) {
472 LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); 503 LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
diff --git a/src/core/hle/service/nfp/nfp_device.h b/src/core/hle/service/nfp/nfp_device.h
index 6d8fc1099..b6a46f2ac 100644
--- a/src/core/hle/service/nfp/nfp_device.h
+++ b/src/core/hle/service/nfp/nfp_device.h
@@ -3,6 +3,7 @@
3 3
4#pragma once 4#pragma once
5 5
6#include <span>
6#include <vector> 7#include <vector>
7 8
8#include "common/common_types.h" 9#include "common/common_types.h"
@@ -36,7 +37,7 @@ public:
36 void Initialize(); 37 void Initialize();
37 void Finalize(); 38 void Finalize();
38 39
39 Result StartDetection(s32 protocol_); 40 Result StartDetection(TagProtocol allowed_protocol);
40 Result StopDetection(); 41 Result StopDetection();
41 Result Mount(MountTarget mount_target); 42 Result Mount(MountTarget mount_target);
42 Result Unmount(); 43 Result Unmount();
@@ -52,6 +53,7 @@ public:
52 Result DeleteAllData(); 53 Result DeleteAllData();
53 54
54 Result OpenApplicationArea(u32 access_id); 55 Result OpenApplicationArea(u32 access_id);
56 Result GetApplicationAreaId(u32& application_area_id) const;
55 Result GetApplicationArea(std::vector<u8>& data) const; 57 Result GetApplicationArea(std::vector<u8>& data) const;
56 Result SetApplicationArea(std::span<const u8> data); 58 Result SetApplicationArea(std::span<const u8> data);
57 Result CreateApplicationArea(u32 access_id, std::span<const u8> data); 59 Result CreateApplicationArea(u32 access_id, std::span<const u8> data);
@@ -87,7 +89,7 @@ private:
87 89
88 bool is_data_moddified{}; 90 bool is_data_moddified{};
89 bool is_app_area_open{}; 91 bool is_app_area_open{};
90 s32 protocol{}; 92 TagProtocol allowed_protocols{};
91 s64 current_posix_time{}; 93 s64 current_posix_time{};
92 MountTarget mount_target{MountTarget::None}; 94 MountTarget mount_target{MountTarget::None};
93 DeviceState device_state{DeviceState::Unavailable}; 95 DeviceState device_state{DeviceState::Unavailable};
diff --git a/src/core/hle/service/nfp/nfp_types.h b/src/core/hle/service/nfp/nfp_types.h
index 63d5917cb..69858096a 100644
--- a/src/core/hle/service/nfp/nfp_types.h
+++ b/src/core/hle/service/nfp/nfp_types.h
@@ -88,11 +88,22 @@ enum class PackedTagType : u8 {
88 Type5, // ISO15693 RW/RO 540 bytes 106kbit/s 88 Type5, // ISO15693 RW/RO 540 bytes 106kbit/s
89}; 89};
90 90
91// Verify this enum. It might be completely wrong default protocol is 0x48
91enum class TagProtocol : u32 { 92enum class TagProtocol : u32 {
92 None, 93 None,
93 TypeA, // ISO14443A 94 TypeA = 1U << 0, // ISO14443A
94 TypeB, // ISO14443B 95 TypeB = 1U << 1, // ISO14443B
95 TypeF, // Sony Felica 96 TypeF = 1U << 2, // Sony Felica
97 Unknown1 = 1U << 3,
98 Unknown2 = 1U << 5,
99 All = 0xFFFFFFFFU,
100};
101
102enum class CabinetMode : u8 {
103 StartNicknameAndOwnerSettings,
104 StartGameDataEraser,
105 StartRestorer,
106 StartFormatter,
96}; 107};
97 108
98using UniqueSerialNumber = std::array<u8, 7>; 109using UniqueSerialNumber = std::array<u8, 7>;
diff --git a/src/core/hle/service/nfp/nfp_user.cpp b/src/core/hle/service/nfp/nfp_user.cpp
index 3f7f17598..2fe3c0ea0 100644
--- a/src/core/hle/service/nfp/nfp_user.cpp
+++ b/src/core/hle/service/nfp/nfp_user.cpp
@@ -131,7 +131,7 @@ void IUser::ListDevices(Kernel::HLERequestContext& ctx) {
131void IUser::StartDetection(Kernel::HLERequestContext& ctx) { 131void IUser::StartDetection(Kernel::HLERequestContext& ctx) {
132 IPC::RequestParser rp{ctx}; 132 IPC::RequestParser rp{ctx};
133 const auto device_handle{rp.Pop<u64>()}; 133 const auto device_handle{rp.Pop<u64>()};
134 const auto nfp_protocol{rp.Pop<s32>()}; 134 const auto nfp_protocol{rp.PopEnum<TagProtocol>()};
135 LOG_INFO(Service_NFP, "called, device_handle={}, nfp_protocol={}", device_handle, nfp_protocol); 135 LOG_INFO(Service_NFP, "called, device_handle={}, nfp_protocol={}", device_handle, nfp_protocol);
136 136
137 if (state == State::NonInitialized) { 137 if (state == State::NonInitialized) {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
index ced57dfe6..b97813fbc 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
@@ -300,11 +300,10 @@ Kernel::KEvent* nvhost_ctrl_gpu::QueryEvent(u32 event_id) {
300 return error_notifier_event; 300 return error_notifier_event;
301 case 2: 301 case 2:
302 return unknown_event; 302 return unknown_event;
303 default: { 303 default:
304 LOG_CRITICAL(Service_NVDRV, "Unknown Ctrl GPU Event {}", event_id); 304 LOG_CRITICAL(Service_NVDRV, "Unknown Ctrl GPU Event {}", event_id);
305 return nullptr;
305 } 306 }
306 }
307 return nullptr;
308} 307}
309 308
310} // namespace Service::Nvidia::Devices 309} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
index 45a759fa8..e123564c6 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
@@ -364,11 +364,10 @@ Kernel::KEvent* nvhost_gpu::QueryEvent(u32 event_id) {
364 return sm_exception_breakpoint_pause_report_event; 364 return sm_exception_breakpoint_pause_report_event;
365 case 3: 365 case 3:
366 return error_notifier_event; 366 return error_notifier_event;
367 default: { 367 default:
368 LOG_CRITICAL(Service_NVDRV, "Unknown Ctrl GPU Event {}", event_id); 368 LOG_CRITICAL(Service_NVDRV, "Unknown Ctrl GPU Event {}", event_id);
369 return nullptr;
369 } 370 }
370 }
371 return nullptr;
372} 371}
373 372
374} // namespace Service::Nvidia::Devices 373} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvflinger/buffer_queue_core.cpp b/src/core/hle/service/nvflinger/buffer_queue_core.cpp
index ea4a14ea4..3d1338e66 100644
--- a/src/core/hle/service/nvflinger/buffer_queue_core.cpp
+++ b/src/core/hle/service/nvflinger/buffer_queue_core.cpp
@@ -23,15 +23,17 @@ void BufferQueueCore::NotifyShutdown() {
23} 23}
24 24
25void BufferQueueCore::SignalDequeueCondition() { 25void BufferQueueCore::SignalDequeueCondition() {
26 dequeue_possible.store(true);
26 dequeue_condition.notify_all(); 27 dequeue_condition.notify_all();
27} 28}
28 29
29bool BufferQueueCore::WaitForDequeueCondition() { 30bool BufferQueueCore::WaitForDequeueCondition(std::unique_lock<std::mutex>& lk) {
30 if (is_shutting_down) { 31 if (is_shutting_down) {
31 return false; 32 return false;
32 } 33 }
33 34
34 dequeue_condition.wait(mutex); 35 dequeue_condition.wait(lk, [&] { return dequeue_possible.load(); });
36 dequeue_possible.store(false);
35 37
36 return true; 38 return true;
37} 39}
diff --git a/src/core/hle/service/nvflinger/buffer_queue_core.h b/src/core/hle/service/nvflinger/buffer_queue_core.h
index ca6baefaf..85b3bc4c1 100644
--- a/src/core/hle/service/nvflinger/buffer_queue_core.h
+++ b/src/core/hle/service/nvflinger/buffer_queue_core.h
@@ -38,7 +38,7 @@ public:
38 38
39private: 39private:
40 void SignalDequeueCondition(); 40 void SignalDequeueCondition();
41 bool WaitForDequeueCondition(); 41 bool WaitForDequeueCondition(std::unique_lock<std::mutex>& lk);
42 42
43 s32 GetMinUndequeuedBufferCountLocked(bool async) const; 43 s32 GetMinUndequeuedBufferCountLocked(bool async) const;
44 s32 GetMinMaxBufferCountLocked(bool async) const; 44 s32 GetMinMaxBufferCountLocked(bool async) const;
@@ -60,7 +60,8 @@ private:
60 BufferQueueDefs::SlotsType slots{}; 60 BufferQueueDefs::SlotsType slots{};
61 std::vector<BufferItem> queue; 61 std::vector<BufferItem> queue;
62 s32 override_max_buffer_count{}; 62 s32 override_max_buffer_count{};
63 mutable std::condition_variable_any dequeue_condition; 63 std::condition_variable dequeue_condition;
64 std::atomic<bool> dequeue_possible{};
64 const bool use_async_buffer{}; // This is always disabled on HOS 65 const bool use_async_buffer{}; // This is always disabled on HOS
65 bool dequeue_buffer_cannot_block{}; 66 bool dequeue_buffer_cannot_block{};
66 PixelFormat default_buffer_format{PixelFormat::Rgba8888}; 67 PixelFormat default_buffer_format{PixelFormat::Rgba8888};
diff --git a/src/core/hle/service/nvflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvflinger/buffer_queue_producer.cpp
index 41ba44b21..e601b5da1 100644
--- a/src/core/hle/service/nvflinger/buffer_queue_producer.cpp
+++ b/src/core/hle/service/nvflinger/buffer_queue_producer.cpp
@@ -121,8 +121,8 @@ Status BufferQueueProducer::SetBufferCount(s32 buffer_count) {
121 return Status::NoError; 121 return Status::NoError;
122} 122}
123 123
124Status BufferQueueProducer::WaitForFreeSlotThenRelock(bool async, s32* found, 124Status BufferQueueProducer::WaitForFreeSlotThenRelock(bool async, s32* found, Status* return_flags,
125 Status* return_flags) const { 125 std::unique_lock<std::mutex>& lk) const {
126 bool try_again = true; 126 bool try_again = true;
127 127
128 while (try_again) { 128 while (try_again) {
@@ -214,7 +214,7 @@ Status BufferQueueProducer::WaitForFreeSlotThenRelock(bool async, s32* found,
214 return Status::WouldBlock; 214 return Status::WouldBlock;
215 } 215 }
216 216
217 if (!core->WaitForDequeueCondition()) { 217 if (!core->WaitForDequeueCondition(lk)) {
218 // We are no longer running 218 // We are no longer running
219 return Status::NoError; 219 return Status::NoError;
220 } 220 }
@@ -237,7 +237,7 @@ Status BufferQueueProducer::DequeueBuffer(s32* out_slot, Fence* out_fence, bool
237 Status return_flags = Status::NoError; 237 Status return_flags = Status::NoError;
238 bool attached_by_consumer = false; 238 bool attached_by_consumer = false;
239 { 239 {
240 std::scoped_lock lock{core->mutex}; 240 std::unique_lock lock{core->mutex};
241 core->WaitWhileAllocatingLocked(); 241 core->WaitWhileAllocatingLocked();
242 242
243 if (format == PixelFormat::NoFormat) { 243 if (format == PixelFormat::NoFormat) {
@@ -248,7 +248,7 @@ Status BufferQueueProducer::DequeueBuffer(s32* out_slot, Fence* out_fence, bool
248 usage |= core->consumer_usage_bit; 248 usage |= core->consumer_usage_bit;
249 249
250 s32 found{}; 250 s32 found{};
251 Status status = WaitForFreeSlotThenRelock(async, &found, &return_flags); 251 Status status = WaitForFreeSlotThenRelock(async, &found, &return_flags, lock);
252 if (status != Status::NoError) { 252 if (status != Status::NoError) {
253 return status; 253 return status;
254 } 254 }
@@ -400,13 +400,13 @@ Status BufferQueueProducer::AttachBuffer(s32* out_slot,
400 return Status::BadValue; 400 return Status::BadValue;
401 } 401 }
402 402
403 std::scoped_lock lock{core->mutex}; 403 std::unique_lock lock{core->mutex};
404 core->WaitWhileAllocatingLocked(); 404 core->WaitWhileAllocatingLocked();
405 405
406 Status return_flags = Status::NoError; 406 Status return_flags = Status::NoError;
407 s32 found{}; 407 s32 found{};
408 408
409 const auto status = WaitForFreeSlotThenRelock(false, &found, &return_flags); 409 const auto status = WaitForFreeSlotThenRelock(false, &found, &return_flags, lock);
410 if (status != Status::NoError) { 410 if (status != Status::NoError) {
411 return status; 411 return status;
412 } 412 }
diff --git a/src/core/hle/service/nvflinger/buffer_queue_producer.h b/src/core/hle/service/nvflinger/buffer_queue_producer.h
index 7526bf8ec..1d380480f 100644
--- a/src/core/hle/service/nvflinger/buffer_queue_producer.h
+++ b/src/core/hle/service/nvflinger/buffer_queue_producer.h
@@ -70,7 +70,8 @@ public:
70private: 70private:
71 BufferQueueProducer(const BufferQueueProducer&) = delete; 71 BufferQueueProducer(const BufferQueueProducer&) = delete;
72 72
73 Status WaitForFreeSlotThenRelock(bool async, s32* found, Status* return_flags) const; 73 Status WaitForFreeSlotThenRelock(bool async, s32* found, Status* return_flags,
74 std::unique_lock<std::mutex>& lk) const;
74 75
75 Kernel::KEvent* buffer_wait_event{}; 76 Kernel::KEvent* buffer_wait_event{};
76 Service::KernelHelpers::ServiceContext& service_context; 77 Service::KernelHelpers::ServiceContext& service_context;
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 5ab41c0c4..0de67f1e1 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -228,6 +228,7 @@ Result ServiceFrameworkBase::HandleSyncRequest(Kernel::KServerSession& session,
228 } 228 }
229 229
230 UNIMPLEMENTED_MSG("command_type={}", ctx.GetCommandType()); 230 UNIMPLEMENTED_MSG("command_type={}", ctx.GetCommandType());
231 break;
231 } 232 }
232 233
233 // If emulation was shutdown, we are closing service threads, do not write the response back to 234 // If emulation was shutdown, we are closing service threads, do not write the response back to
diff --git a/src/core/hle/service/time/time_zone_manager.cpp b/src/core/hle/service/time/time_zone_manager.cpp
index 2aa675df9..f9ada7c93 100644
--- a/src/core/hle/service/time/time_zone_manager.cpp
+++ b/src/core/hle/service/time/time_zone_manager.cpp
@@ -280,6 +280,7 @@ static constexpr int TransitionTime(int year, Rule rule, int offset) {
280 } 280 }
281 default: 281 default:
282 ASSERT(false); 282 ASSERT(false);
283 break;
283 } 284 }
284 return value + rule.transition_time + offset; 285 return value + rule.transition_time + offset;
285} 286}