Compare commits

..

29 Commits

Author SHA1 Message Date
38f31530f6 Android 235 2024-02-07 01:00:14 +00:00
aec2a6609d Merge yuzu-emu#12920 2024-02-07 01:00:14 +00:00
7b077b11d4 Merge yuzu-emu#12914 2024-02-07 01:00:14 +00:00
81f45ede66 Merge yuzu-emu#12903 2024-02-07 01:00:14 +00:00
4f069aa827 Merge yuzu-emu#12756 2024-02-07 01:00:14 +00:00
707e928788 Merge yuzu-emu#12749 2024-02-07 01:00:14 +00:00
0dfe24176d Merge yuzu-emu#12461 2024-02-07 01:00:14 +00:00
c10e720ba9 Merge pull request #12883 from FernandoS27/memory_manager_mem
MemoryManager: Reduce the page table size based on last big page address.
2024-02-06 10:25:03 -05:00
5016de3626 Merge pull request #12928 from german77/motion-mp
service: hid: Add multiprocess support to six axis input
2024-02-06 10:24:46 -05:00
d5fb9fd12c Merge pull request #12933 from german77/irs-interface
service: irs: Migrate service to new interface
2024-02-06 10:24:30 -05:00
c79b3af610 Merge pull request #12934 from german77/hid_debug_interface
service: hid: Migrate hid debug service to new interface
2024-02-06 10:24:20 -05:00
b6106604c4 service: hid: Migrate hid debug service to new interface 2024-02-06 00:38:46 -06:00
12b6162852 service: irs: Migrate service to new interface 2024-02-06 00:14:16 -06:00
8f192b494a service: hid: Add multiprocess support to six axis input 2024-02-05 17:19:31 -06:00
372897aac4 service: hid: Ensure aruid data is initialized 2024-02-05 17:17:21 -06:00
a2f23746c2 Merge pull request #12905 from liamwhite/hwc-release
nvnflinger: release buffers before presentation sleep
2024-02-05 13:43:22 -05:00
215b13f2a2 Merge pull request #12924 from liamwhite/pedantic-unsigned
typed_address: test values are unsigned
2024-02-05 13:43:06 -05:00
35ed9425d7 Merge pull request #12925 from german77/linux-tab
yuzu: Fully hide linux tab
2024-02-05 13:41:31 -05:00
74cc8721c7 Merge pull request #12915 from german77/cheat
dmnt: cheats: Update cheat vm to latest version
2024-02-05 13:41:21 -05:00
8ef1db78b0 Merge pull request #12916 from liamwhite/float-fix
gdb: fix load/save of fp values in a32
2024-02-05 13:41:15 -05:00
18c8f10ff2 Merge pull request #12922 from FearlessTobi/lang-mappins
.tx/config: Use language mappings for android "tx pull"
2024-02-05 13:40:53 -05:00
96d881f087 yuzu: Fully hide linux tab 2024-02-05 11:58:20 -06:00
0e950baf41 typed_address: test values are unsigned 2024-02-05 12:47:10 -05:00
8113f55f4b dmnt: cheats: Silence memory errors 2024-02-05 11:08:24 -06:00
ddbefc71cb .tx/config: Use language mappings for android "tx pull"
The language names we are using in the android resources differ from those on Transifex.

We need to manually specify mappings for them, so Transifex is able to place the files in the correct folders.
2024-02-05 15:57:13 +01:00
85143e8376 gdb: fix load/save of fp values in a32 2024-02-04 20:28:43 -05:00
504abbd6e0 dmnt: cheats: Update cheat vm to latest version 2024-02-04 17:46:20 -06:00
5eb5c96750 nvnflinger: release buffers before presentation sleep 2024-02-03 17:14:43 -05:00
f740d8b9be MemoryManager: Reduce the page table size based on last big page address. 2024-02-01 13:00:36 +01:00
32 changed files with 598 additions and 889 deletions

View File

@ -3,11 +3,8 @@
| [12461](https://github.com/yuzu-emu/yuzu-android//pull/12461) | [`4c08a0e6d`](https://github.com/yuzu-emu/yuzu-android//pull/12461/files) | Rework Nvdec and VIC to fix out-of-order videos, and speed up decoding. | [Kelebek1](https://github.com/Kelebek1/) | Yes | | [12461](https://github.com/yuzu-emu/yuzu-android//pull/12461) | [`4c08a0e6d`](https://github.com/yuzu-emu/yuzu-android//pull/12461/files) | Rework Nvdec and VIC to fix out-of-order videos, and speed up decoding. | [Kelebek1](https://github.com/Kelebek1/) | Yes |
| [12749](https://github.com/yuzu-emu/yuzu-android//pull/12749) | [`aad4b0d6f`](https://github.com/yuzu-emu/yuzu-android//pull/12749/files) | general: workarounds for SMMU syncing issues | [liamwhite](https://github.com/liamwhite/) | Yes | | [12749](https://github.com/yuzu-emu/yuzu-android//pull/12749) | [`aad4b0d6f`](https://github.com/yuzu-emu/yuzu-android//pull/12749/files) | general: workarounds for SMMU syncing issues | [liamwhite](https://github.com/liamwhite/) | Yes |
| [12756](https://github.com/yuzu-emu/yuzu-android//pull/12756) | [`cd3de0848`](https://github.com/yuzu-emu/yuzu-android//pull/12756/files) | general: applet multiprocess | [liamwhite](https://github.com/liamwhite/) | Yes | | [12756](https://github.com/yuzu-emu/yuzu-android//pull/12756) | [`cd3de0848`](https://github.com/yuzu-emu/yuzu-android//pull/12756/files) | general: applet multiprocess | [liamwhite](https://github.com/liamwhite/) | Yes |
| [12873](https://github.com/yuzu-emu/yuzu-android//pull/12873) | [`023c3aa65`](https://github.com/yuzu-emu/yuzu-android//pull/12873/files) | GPU: Implement channel scheduling. | [FernandoS27](https://github.com/FernandoS27/) | Yes |
| [12903](https://github.com/yuzu-emu/yuzu-android//pull/12903) | [`f296a9ce9`](https://github.com/yuzu-emu/yuzu-android//pull/12903/files) | shader_recompiler: use only ConstOffset for OpImageFetch | [liamwhite](https://github.com/liamwhite/) | Yes | | [12903](https://github.com/yuzu-emu/yuzu-android//pull/12903) | [`f296a9ce9`](https://github.com/yuzu-emu/yuzu-android//pull/12903/files) | shader_recompiler: use only ConstOffset for OpImageFetch | [liamwhite](https://github.com/liamwhite/) | Yes |
| [12905](https://github.com/yuzu-emu/yuzu-android//pull/12905) | [`5eb5c9675`](https://github.com/yuzu-emu/yuzu-android//pull/12905/files) | nvnflinger: release buffers before presentation sleep | [liamwhite](https://github.com/liamwhite/) | Yes | | [12914](https://github.com/yuzu-emu/yuzu-android//pull/12914) | [`fa47ac1c9`](https://github.com/yuzu-emu/yuzu-android//pull/12914/files) | VideoCore Refactor Part 1. | [FernandoS27](https://github.com/FernandoS27/) | Yes |
| [12914](https://github.com/yuzu-emu/yuzu-android//pull/12914) | [`3a6d8ae2c`](https://github.com/yuzu-emu/yuzu-android//pull/12914/files) | VideoCore Refactor Part 1. | [FernandoS27](https://github.com/FernandoS27/) | Yes |
| [12915](https://github.com/yuzu-emu/yuzu-android//pull/12915) | [`504abbd6e`](https://github.com/yuzu-emu/yuzu-android//pull/12915/files) | dmnt: cheats: Update cheat vm to latest version | [german77](https://github.com/german77/) | Yes |
| [12920](https://github.com/yuzu-emu/yuzu-android//pull/12920) | [`62fc6d5c3`](https://github.com/yuzu-emu/yuzu-android//pull/12920/files) | android: Move JNI setup and helpers to common | [t895](https://github.com/t895/) | Yes | | [12920](https://github.com/yuzu-emu/yuzu-android//pull/12920) | [`62fc6d5c3`](https://github.com/yuzu-emu/yuzu-android//pull/12920/files) | android: Move JNI setup and helpers to common | [t895](https://github.com/t895/) | Yes |

View File

@ -11,3 +11,4 @@ type = QT
file_filter = ../../src/android/app/src/main/res/values-<lang>/strings.xml file_filter = ../../src/android/app/src/main/res/values-<lang>/strings.xml
source_file = ../../src/android/app/src/main/res/values/strings.xml source_file = ../../src/android/app/src/main/res/values/strings.xml
type = ANDROID type = ANDROID
lang_map = ja_JP:ja, ko_KR:ko, pt_BR:pt-rBR, pt_PT:pt-rPT, ru_RU:ru, vi_VN:vi, zh_CN:zh-rCN, zh_TW:zh-rTW

View File

@ -70,4 +70,4 @@ private:
std::unique_ptr<OverlapRangeSetImpl> m_impl; std::unique_ptr<OverlapRangeSetImpl> m_impl;
}; };
} // namespace Common } // namespace Common

View File

@ -301,4 +301,4 @@ void OverlapRangeSet<AddressType>::ForEachInRange(AddressType base_address, size
m_impl->ForEachInRange(base_address, size, std::move(func)); m_impl->ForEachInRange(base_address, size, std::move(func));
} }
} // namespace Common } // namespace Common

View File

@ -186,68 +186,68 @@ static_assert(std::is_trivially_destructible_v<PhysicalAddress>);
static_assert(std::is_trivially_destructible_v<VirtualAddress>); static_assert(std::is_trivially_destructible_v<VirtualAddress>);
static_assert(std::is_trivially_destructible_v<ProcessAddress>); static_assert(std::is_trivially_destructible_v<ProcessAddress>);
static_assert(Null<uint64_t> == 0); static_assert(Null<uint64_t> == 0U);
static_assert(Null<PhysicalAddress> == Null<uint64_t>); static_assert(Null<PhysicalAddress> == Null<uint64_t>);
static_assert(Null<VirtualAddress> == Null<uint64_t>); static_assert(Null<VirtualAddress> == Null<uint64_t>);
static_assert(Null<ProcessAddress> == Null<uint64_t>); static_assert(Null<ProcessAddress> == Null<uint64_t>);
// Constructor/assignment validations. // Constructor/assignment validations.
static_assert([] { static_assert([] {
const PhysicalAddress a(5); const PhysicalAddress a(5U);
PhysicalAddress b(a); PhysicalAddress b(a);
return b; return b;
}() == PhysicalAddress(5)); }() == PhysicalAddress(5U));
static_assert([] { static_assert([] {
const PhysicalAddress a(5); const PhysicalAddress a(5U);
PhysicalAddress b(10); PhysicalAddress b(10U);
b = a; b = a;
return b; return b;
}() == PhysicalAddress(5)); }() == PhysicalAddress(5U));
// Arithmetic validations. // Arithmetic validations.
static_assert(PhysicalAddress(10) + 5 == PhysicalAddress(15)); static_assert(PhysicalAddress(10U) + 5U == PhysicalAddress(15U));
static_assert(PhysicalAddress(10) - 5 == PhysicalAddress(5)); static_assert(PhysicalAddress(10U) - 5U == PhysicalAddress(5U));
static_assert([] { static_assert([] {
PhysicalAddress v(10); PhysicalAddress v(10U);
v += 5; v += 5U;
return v; return v;
}() == PhysicalAddress(15)); }() == PhysicalAddress(15U));
static_assert([] { static_assert([] {
PhysicalAddress v(10); PhysicalAddress v(10U);
v -= 5; v -= 5U;
return v; return v;
}() == PhysicalAddress(5)); }() == PhysicalAddress(5U));
static_assert(PhysicalAddress(10)++ == PhysicalAddress(10)); static_assert(PhysicalAddress(10U)++ == PhysicalAddress(10U));
static_assert(++PhysicalAddress(10) == PhysicalAddress(11)); static_assert(++PhysicalAddress(10U) == PhysicalAddress(11U));
static_assert(PhysicalAddress(10)-- == PhysicalAddress(10)); static_assert(PhysicalAddress(10U)-- == PhysicalAddress(10U));
static_assert(--PhysicalAddress(10) == PhysicalAddress(9)); static_assert(--PhysicalAddress(10U) == PhysicalAddress(9U));
// Logical validations. // Logical validations.
static_assert((PhysicalAddress(0b11111111) >> 1) == 0b01111111); static_assert((PhysicalAddress(0b11111111U) >> 1) == 0b01111111U);
static_assert((PhysicalAddress(0b10101010) >> 1) == 0b01010101); static_assert((PhysicalAddress(0b10101010U) >> 1) == 0b01010101U);
static_assert((PhysicalAddress(0b11111111) << 1) == 0b111111110); static_assert((PhysicalAddress(0b11111111U) << 1) == 0b111111110U);
static_assert((PhysicalAddress(0b01010101) << 1) == 0b10101010); static_assert((PhysicalAddress(0b01010101U) << 1) == 0b10101010U);
static_assert((PhysicalAddress(0b11111111) & 0b01010101) == 0b01010101); static_assert((PhysicalAddress(0b11111111U) & 0b01010101U) == 0b01010101U);
static_assert((PhysicalAddress(0b11111111) & 0b10101010) == 0b10101010); static_assert((PhysicalAddress(0b11111111U) & 0b10101010U) == 0b10101010U);
static_assert((PhysicalAddress(0b01010101) & 0b10101010) == 0b00000000); static_assert((PhysicalAddress(0b01010101U) & 0b10101010U) == 0b00000000U);
static_assert((PhysicalAddress(0b00000000) | 0b01010101) == 0b01010101); static_assert((PhysicalAddress(0b00000000U) | 0b01010101U) == 0b01010101U);
static_assert((PhysicalAddress(0b11111111) | 0b01010101) == 0b11111111); static_assert((PhysicalAddress(0b11111111U) | 0b01010101U) == 0b11111111U);
static_assert((PhysicalAddress(0b10101010) | 0b01010101) == 0b11111111); static_assert((PhysicalAddress(0b10101010U) | 0b01010101U) == 0b11111111U);
// Comparisons. // Comparisons.
static_assert(PhysicalAddress(0) == PhysicalAddress(0)); static_assert(PhysicalAddress(0U) == PhysicalAddress(0U));
static_assert(PhysicalAddress(0) != PhysicalAddress(1)); static_assert(PhysicalAddress(0U) != PhysicalAddress(1U));
static_assert(PhysicalAddress(0) < PhysicalAddress(1)); static_assert(PhysicalAddress(0U) < PhysicalAddress(1U));
static_assert(PhysicalAddress(0) <= PhysicalAddress(1)); static_assert(PhysicalAddress(0U) <= PhysicalAddress(1U));
static_assert(PhysicalAddress(1) > PhysicalAddress(0)); static_assert(PhysicalAddress(1U) > PhysicalAddress(0U));
static_assert(PhysicalAddress(1) >= PhysicalAddress(0)); static_assert(PhysicalAddress(1U) >= PhysicalAddress(0U));
static_assert(!(PhysicalAddress(0) == PhysicalAddress(1))); static_assert(!(PhysicalAddress(0U) == PhysicalAddress(1U)));
static_assert(!(PhysicalAddress(0) != PhysicalAddress(0))); static_assert(!(PhysicalAddress(0U) != PhysicalAddress(0U)));
static_assert(!(PhysicalAddress(1) < PhysicalAddress(0))); static_assert(!(PhysicalAddress(1U) < PhysicalAddress(0U)));
static_assert(!(PhysicalAddress(1) <= PhysicalAddress(0))); static_assert(!(PhysicalAddress(1U) <= PhysicalAddress(0U)));
static_assert(!(PhysicalAddress(0) > PhysicalAddress(1))); static_assert(!(PhysicalAddress(0U) > PhysicalAddress(1U)));
static_assert(!(PhysicalAddress(0) >= PhysicalAddress(1))); static_assert(!(PhysicalAddress(0U) >= PhysicalAddress(1U)));
} // namespace Common } // namespace Common

View File

@ -383,7 +383,7 @@ std::string GDBStubA32::RegRead(const Kernel::KThread* thread, size_t id) const
} else if (id == CPSR_REGISTER) { } else if (id == CPSR_REGISTER) {
return ValueToHex(context.pstate); return ValueToHex(context.pstate);
} else if (id >= D0_REGISTER && id < Q0_REGISTER) { } else if (id >= D0_REGISTER && id < Q0_REGISTER) {
return ValueToHex(fprs[id - D0_REGISTER][0]); return ValueToHex(fprs[(id - D0_REGISTER) / 2][(id - D0_REGISTER) % 2]);
} else if (id >= Q0_REGISTER && id < FPSCR_REGISTER) { } else if (id >= Q0_REGISTER && id < FPSCR_REGISTER) {
return ValueToHex(fprs[id - Q0_REGISTER]); return ValueToHex(fprs[id - Q0_REGISTER]);
} else if (id == FPSCR_REGISTER) { } else if (id == FPSCR_REGISTER) {
@ -406,7 +406,7 @@ void GDBStubA32::RegWrite(Kernel::KThread* thread, size_t id, std::string_view v
} else if (id == CPSR_REGISTER) { } else if (id == CPSR_REGISTER) {
context.pstate = HexToValue<u32>(value); context.pstate = HexToValue<u32>(value);
} else if (id >= D0_REGISTER && id < Q0_REGISTER) { } else if (id >= D0_REGISTER && id < Q0_REGISTER) {
fprs[id - D0_REGISTER] = {HexToValue<u64>(value), 0}; fprs[(id - D0_REGISTER) / 2][(id - D0_REGISTER) % 2] = HexToValue<u64>(value);
} else if (id >= Q0_REGISTER && id < FPSCR_REGISTER) { } else if (id >= Q0_REGISTER && id < FPSCR_REGISTER) {
fprs[id - Q0_REGISTER] = HexToValue<u128>(value); fprs[id - Q0_REGISTER] = HexToValue<u128>(value);
} else if (id == FPSCR_REGISTER) { } else if (id == FPSCR_REGISTER) {

View File

@ -3,6 +3,7 @@
#include <algorithm> #include <algorithm>
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/hid/hid_debug_server.h" #include "core/hle/service/hid/hid_debug_server.h"
#include "core/hle/service/ipc_helpers.h" #include "core/hle/service/ipc_helpers.h"
#include "hid_core/hid_types.h" #include "hid_core/hid_types.h"
@ -11,7 +12,6 @@
#include "hid_core/resources/touch_screen/gesture.h" #include "hid_core/resources/touch_screen/gesture.h"
#include "hid_core/resources/touch_screen/touch_screen.h" #include "hid_core/resources/touch_screen/touch_screen.h"
#include "hid_core/resources/touch_screen/touch_types.h"
namespace Service::HID { namespace Service::HID {
@ -24,14 +24,14 @@ IHidDebugServer::IHidDebugServer(Core::System& system_, std::shared_ptr<Resource
{0, nullptr, "DeactivateDebugPad"}, {0, nullptr, "DeactivateDebugPad"},
{1, nullptr, "SetDebugPadAutoPilotState"}, {1, nullptr, "SetDebugPadAutoPilotState"},
{2, nullptr, "UnsetDebugPadAutoPilotState"}, {2, nullptr, "UnsetDebugPadAutoPilotState"},
{10, &IHidDebugServer::DeactivateTouchScreen, "DeactivateTouchScreen"}, {10, C<&IHidDebugServer::DeactivateTouchScreen>, "DeactivateTouchScreen"},
{11, &IHidDebugServer::SetTouchScreenAutoPilotState, "SetTouchScreenAutoPilotState"}, {11, C<&IHidDebugServer::SetTouchScreenAutoPilotState>, "SetTouchScreenAutoPilotState"},
{12, &IHidDebugServer::UnsetTouchScreenAutoPilotState, "UnsetTouchScreenAutoPilotState"}, {12, C<&IHidDebugServer::UnsetTouchScreenAutoPilotState>, "UnsetTouchScreenAutoPilotState"},
{13, &IHidDebugServer::GetTouchScreenConfiguration, "GetTouchScreenConfiguration"}, {13, C<&IHidDebugServer::GetTouchScreenConfiguration>, "GetTouchScreenConfiguration"},
{14, &IHidDebugServer::ProcessTouchScreenAutoTune, "ProcessTouchScreenAutoTune"}, {14, C<&IHidDebugServer::ProcessTouchScreenAutoTune>, "ProcessTouchScreenAutoTune"},
{15, &IHidDebugServer::ForceStopTouchScreenManagement, "ForceStopTouchScreenManagement"}, {15, C<&IHidDebugServer::ForceStopTouchScreenManagement>, "ForceStopTouchScreenManagement"},
{16, &IHidDebugServer::ForceRestartTouchScreenManagement, "ForceRestartTouchScreenManagement"}, {16, C<&IHidDebugServer::ForceRestartTouchScreenManagement>, "ForceRestartTouchScreenManagement"},
{17, &IHidDebugServer::IsTouchScreenManaged, "IsTouchScreenManaged"}, {17, C<&IHidDebugServer::IsTouchScreenManaged>, "IsTouchScreenManaged"},
{20, nullptr, "DeactivateMouse"}, {20, nullptr, "DeactivateMouse"},
{21, nullptr, "SetMouseAutoPilotState"}, {21, nullptr, "SetMouseAutoPilotState"},
{22, nullptr, "UnsetMouseAutoPilotState"}, {22, nullptr, "UnsetMouseAutoPilotState"},
@ -47,7 +47,7 @@ IHidDebugServer::IHidDebugServer(Core::System& system_, std::shared_ptr<Resource
{60, nullptr, "ClearNpadSystemCommonPolicy"}, {60, nullptr, "ClearNpadSystemCommonPolicy"},
{61, nullptr, "DeactivateNpad"}, {61, nullptr, "DeactivateNpad"},
{62, nullptr, "ForceDisconnectNpad"}, {62, nullptr, "ForceDisconnectNpad"},
{91, &IHidDebugServer::DeactivateGesture, "DeactivateGesture"}, {91, C<&IHidDebugServer::DeactivateGesture>, "DeactivateGesture"},
{110, nullptr, "DeactivateHomeButton"}, {110, nullptr, "DeactivateHomeButton"},
{111, nullptr, "SetHomeButtonAutoPilotState"}, {111, nullptr, "SetHomeButtonAutoPilotState"},
{112, nullptr, "UnsetHomeButtonAutoPilotState"}, {112, nullptr, "UnsetHomeButtonAutoPilotState"},
@ -160,169 +160,122 @@ IHidDebugServer::IHidDebugServer(Core::System& system_, std::shared_ptr<Resource
} }
IHidDebugServer::~IHidDebugServer() = default; IHidDebugServer::~IHidDebugServer() = default;
void IHidDebugServer::DeactivateTouchScreen(HLERequestContext& ctx) {
Result IHidDebugServer::DeactivateTouchScreen() {
LOG_INFO(Service_HID, "called"); LOG_INFO(Service_HID, "called");
Result result = ResultSuccess;
if (!firmware_settings->IsDeviceManaged()) { if (!firmware_settings->IsDeviceManaged()) {
result = GetResourceManager()->GetTouchScreen()->Deactivate(); R_RETURN(GetResourceManager()->GetTouchScreen()->Deactivate());
} }
IPC::ResponseBuilder rb{ctx, 2}; R_SUCCEED();
rb.Push(result);
} }
void IHidDebugServer::SetTouchScreenAutoPilotState(HLERequestContext& ctx) { Result IHidDebugServer::SetTouchScreenAutoPilotState(
InArray<TouchState, BufferAttr_HipcMapAlias> auto_pilot_buffer) {
AutoPilotState auto_pilot{}; AutoPilotState auto_pilot{};
auto_pilot.count = ctx.GetReadBufferNumElements<TouchState>();
const auto buffer = ctx.ReadBuffer();
auto_pilot.count = std::min(auto_pilot.count, static_cast<u64>(auto_pilot.state.size())); auto_pilot.count =
memcpy(auto_pilot.state.data(), buffer.data(), auto_pilot.count * sizeof(TouchState)); static_cast<u64>(std::min(auto_pilot_buffer.size(), auto_pilot.state.size()));
memcpy(auto_pilot.state.data(), auto_pilot_buffer.data(),
auto_pilot.count * sizeof(TouchState));
LOG_INFO(Service_HID, "called, auto_pilot_count={}", auto_pilot.count); LOG_INFO(Service_HID, "called, auto_pilot_count={}", auto_pilot.count);
const Result result = R_RETURN(GetResourceManager()->GetTouchScreen()->SetTouchScreenAutoPilotState(auto_pilot));
GetResourceManager()->GetTouchScreen()->SetTouchScreenAutoPilotState(auto_pilot);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
} }
void IHidDebugServer::UnsetTouchScreenAutoPilotState(HLERequestContext& ctx) { Result IHidDebugServer::UnsetTouchScreenAutoPilotState() {
LOG_INFO(Service_HID, "called"); LOG_INFO(Service_HID, "called");
R_RETURN(GetResourceManager()->GetTouchScreen()->UnsetTouchScreenAutoPilotState());
const Result result = GetResourceManager()->GetTouchScreen()->UnsetTouchScreenAutoPilotState();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
} }
void IHidDebugServer::GetTouchScreenConfiguration(HLERequestContext& ctx) { Result IHidDebugServer::GetTouchScreenConfiguration(
IPC::RequestParser rp{ctx}; Out<Core::HID::TouchScreenConfigurationForNx> out_touchscreen_config,
const auto applet_resource_user_id{rp.Pop<u64>()}; ClientAppletResourceUserId aruid) {
LOG_INFO(Service_HID, "called, applet_resource_user_id={}", aruid.pid);
LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); R_TRY(GetResourceManager()->GetTouchScreen()->GetTouchScreenConfiguration(
*out_touchscreen_config, aruid.pid));
Core::HID::TouchScreenConfigurationForNx touchscreen_config{}; if (out_touchscreen_config->mode != Core::HID::TouchScreenModeForNx::Heat2 &&
const Result result = GetResourceManager()->GetTouchScreen()->GetTouchScreenConfiguration( out_touchscreen_config->mode != Core::HID::TouchScreenModeForNx::Finger) {
touchscreen_config, applet_resource_user_id); out_touchscreen_config->mode = Core::HID::TouchScreenModeForNx::UseSystemSetting;
if (touchscreen_config.mode != Core::HID::TouchScreenModeForNx::Heat2 &&
touchscreen_config.mode != Core::HID::TouchScreenModeForNx::Finger) {
touchscreen_config.mode = Core::HID::TouchScreenModeForNx::UseSystemSetting;
} }
IPC::ResponseBuilder rb{ctx, 6}; R_SUCCEED();
rb.Push(result);
rb.PushRaw(touchscreen_config);
} }
void IHidDebugServer::ProcessTouchScreenAutoTune(HLERequestContext& ctx) { Result IHidDebugServer::ProcessTouchScreenAutoTune() {
LOG_INFO(Service_HID, "called"); LOG_INFO(Service_HID, "called");
R_RETURN(GetResourceManager()->GetTouchScreen()->ProcessTouchScreenAutoTune());
Result result = GetResourceManager()->GetTouchScreen()->ProcessTouchScreenAutoTune();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
} }
void IHidDebugServer::ForceStopTouchScreenManagement(HLERequestContext& ctx) { Result IHidDebugServer::ForceStopTouchScreenManagement() {
LOG_INFO(Service_HID, "called"); LOG_INFO(Service_HID, "called");
if (!firmware_settings->IsDeviceManaged()) { if (!firmware_settings->IsDeviceManaged()) {
IPC::ResponseBuilder rb{ctx, 2}; R_SUCCEED();
rb.Push(ResultSuccess);
return;
} }
Result result = ResultSuccess;
bool is_touch_active{};
bool is_gesture_active{};
auto touch_screen = GetResourceManager()->GetTouchScreen(); auto touch_screen = GetResourceManager()->GetTouchScreen();
auto gesture = GetResourceManager()->GetGesture(); auto gesture = GetResourceManager()->GetGesture();
if (firmware_settings->IsTouchI2cManaged()) { if (firmware_settings->IsTouchI2cManaged()) {
result = touch_screen->IsActive(is_touch_active); bool is_touch_active{};
if (result.IsSuccess()) { bool is_gesture_active{};
result = gesture->IsActive(is_gesture_active); R_TRY(touch_screen->IsActive(is_touch_active));
R_TRY(gesture->IsActive(is_gesture_active));
if (is_touch_active) {
R_TRY(touch_screen->Deactivate());
} }
if (result.IsSuccess() && is_touch_active) { if (is_gesture_active) {
result = touch_screen->Deactivate(); R_TRY(gesture->Deactivate());
}
if (result.IsSuccess() && is_gesture_active) {
result = gesture->Deactivate();
} }
} }
IPC::ResponseBuilder rb{ctx, 2}; R_SUCCEED();
rb.Push(result);
} }
void IHidDebugServer::ForceRestartTouchScreenManagement(HLERequestContext& ctx) { Result IHidDebugServer::ForceRestartTouchScreenManagement(u32 basic_gesture_id,
IPC::RequestParser rp{ctx}; ClientAppletResourceUserId aruid) {
struct Parameters {
u32 basic_gesture_id;
INSERT_PADDING_WORDS_NOINIT(1);
u64 applet_resource_user_id;
};
static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
LOG_INFO(Service_HID, "called, basic_gesture_id={}, applet_resource_user_id={}", LOG_INFO(Service_HID, "called, basic_gesture_id={}, applet_resource_user_id={}",
parameters.basic_gesture_id, parameters.applet_resource_user_id); basic_gesture_id, aruid.pid);
Result result = ResultSuccess;
auto touch_screen = GetResourceManager()->GetTouchScreen(); auto touch_screen = GetResourceManager()->GetTouchScreen();
auto gesture = GetResourceManager()->GetGesture(); auto gesture = GetResourceManager()->GetGesture();
if (firmware_settings->IsDeviceManaged() && firmware_settings->IsTouchI2cManaged()) { if (firmware_settings->IsDeviceManaged() && firmware_settings->IsTouchI2cManaged()) {
result = gesture->Activate(); R_TRY(gesture->Activate());
if (result.IsSuccess()) { R_TRY(gesture->Activate(aruid.pid, basic_gesture_id));
result = R_TRY(touch_screen->Activate());
gesture->Activate(parameters.applet_resource_user_id, parameters.basic_gesture_id); R_TRY(touch_screen->Activate(aruid.pid));
}
if (result.IsSuccess()) {
result = touch_screen->Activate();
}
if (result.IsSuccess()) {
result = touch_screen->Activate(parameters.applet_resource_user_id);
}
} }
IPC::ResponseBuilder rb{ctx, 2}; R_SUCCEED();
rb.Push(result);
} }
void IHidDebugServer::IsTouchScreenManaged(HLERequestContext& ctx) { Result IHidDebugServer::IsTouchScreenManaged(Out<bool> out_is_managed) {
LOG_INFO(Service_HID, "called"); LOG_INFO(Service_HID, "called");
bool is_touch_active{}; bool is_touch_active{};
bool is_gesture_active{}; bool is_gesture_active{};
R_TRY(GetResourceManager()->GetTouchScreen()->IsActive(is_touch_active));
R_TRY(GetResourceManager()->GetGesture()->IsActive(is_gesture_active));
Result result = GetResourceManager()->GetTouchScreen()->IsActive(is_touch_active); *out_is_managed = is_touch_active || is_gesture_active;
if (result.IsSuccess()) { R_SUCCEED();
result = GetResourceManager()->GetGesture()->IsActive(is_gesture_active);
}
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(result);
rb.Push(is_touch_active | is_gesture_active);
} }
void IHidDebugServer::DeactivateGesture(HLERequestContext& ctx) { Result IHidDebugServer::DeactivateGesture() {
LOG_INFO(Service_HID, "called"); LOG_INFO(Service_HID, "called");
Result result = ResultSuccess;
if (!firmware_settings->IsDeviceManaged()) { if (!firmware_settings->IsDeviceManaged()) {
result = GetResourceManager()->GetGesture()->Deactivate(); R_RETURN(GetResourceManager()->GetGesture()->Deactivate());
} }
IPC::ResponseBuilder rb{ctx, 2}; R_SUCCEED();
rb.Push(result);
} }
std::shared_ptr<ResourceManager> IHidDebugServer::GetResourceManager() { std::shared_ptr<ResourceManager> IHidDebugServer::GetResourceManager() {

View File

@ -3,7 +3,9 @@
#pragma once #pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
#include "hid_core/resources/touch_screen/touch_types.h"
namespace Core { namespace Core {
class System; class System;
@ -20,15 +22,19 @@ public:
~IHidDebugServer() override; ~IHidDebugServer() override;
private: private:
void DeactivateTouchScreen(HLERequestContext& ctx); Result DeactivateTouchScreen();
void SetTouchScreenAutoPilotState(HLERequestContext& ctx); Result SetTouchScreenAutoPilotState(
void UnsetTouchScreenAutoPilotState(HLERequestContext& ctx); InArray<TouchState, BufferAttr_HipcMapAlias> auto_pilot_buffer);
void GetTouchScreenConfiguration(HLERequestContext& ctx); Result UnsetTouchScreenAutoPilotState();
void ProcessTouchScreenAutoTune(HLERequestContext& ctx); Result GetTouchScreenConfiguration(
void ForceStopTouchScreenManagement(HLERequestContext& ctx); Out<Core::HID::TouchScreenConfigurationForNx> out_touchscreen_config,
void ForceRestartTouchScreenManagement(HLERequestContext& ctx); ClientAppletResourceUserId aruid);
void IsTouchScreenManaged(HLERequestContext& ctx); Result ProcessTouchScreenAutoTune();
void DeactivateGesture(HLERequestContext& ctx); Result ForceStopTouchScreenManagement();
Result ForceRestartTouchScreenManagement(u32 basic_gesture_id,
ClientAppletResourceUserId aruid);
Result IsTouchScreenManaged(Out<bool> out_is_managed);
Result DeactivateGesture();
std::shared_ptr<ResourceManager> GetResourceManager(); std::shared_ptr<ResourceManager> GetResourceManager();

View File

@ -9,6 +9,7 @@
#include "core/hle/kernel/k_shared_memory.h" #include "core/hle/kernel/k_shared_memory.h"
#include "core/hle/kernel/k_transfer_memory.h" #include "core/hle/kernel/k_transfer_memory.h"
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/hid/irs.h" #include "core/hle/service/hid/irs.h"
#include "core/hle/service/ipc_helpers.h" #include "core/hle/service/ipc_helpers.h"
#include "core/memory.h" #include "core/memory.h"
@ -28,24 +29,24 @@ namespace Service::IRS {
IRS::IRS(Core::System& system_) : ServiceFramework{system_, "irs"} { IRS::IRS(Core::System& system_) : ServiceFramework{system_, "irs"} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{302, &IRS::ActivateIrsensor, "ActivateIrsensor"}, {302, C<&IRS::ActivateIrsensor>, "ActivateIrsensor"},
{303, &IRS::DeactivateIrsensor, "DeactivateIrsensor"}, {303, C<&IRS::DeactivateIrsensor>, "DeactivateIrsensor"},
{304, &IRS::GetIrsensorSharedMemoryHandle, "GetIrsensorSharedMemoryHandle"}, {304, C<&IRS::GetIrsensorSharedMemoryHandle>, "GetIrsensorSharedMemoryHandle"},
{305, &IRS::StopImageProcessor, "StopImageProcessor"}, {305, C<&IRS::StopImageProcessor>, "StopImageProcessor"},
{306, &IRS::RunMomentProcessor, "RunMomentProcessor"}, {306, C<&IRS::RunMomentProcessor>, "RunMomentProcessor"},
{307, &IRS::RunClusteringProcessor, "RunClusteringProcessor"}, {307, C<&IRS::RunClusteringProcessor>, "RunClusteringProcessor"},
{308, &IRS::RunImageTransferProcessor, "RunImageTransferProcessor"}, {308, C<&IRS::RunImageTransferProcessor>, "RunImageTransferProcessor"},
{309, &IRS::GetImageTransferProcessorState, "GetImageTransferProcessorState"}, {309, C<&IRS::GetImageTransferProcessorState>, "GetImageTransferProcessorState"},
{310, &IRS::RunTeraPluginProcessor, "RunTeraPluginProcessor"}, {310, C<&IRS::RunTeraPluginProcessor>, "RunTeraPluginProcessor"},
{311, &IRS::GetNpadIrCameraHandle, "GetNpadIrCameraHandle"}, {311, C<&IRS::GetNpadIrCameraHandle>, "GetNpadIrCameraHandle"},
{312, &IRS::RunPointingProcessor, "RunPointingProcessor"}, {312, C<&IRS::RunPointingProcessor>, "RunPointingProcessor"},
{313, &IRS::SuspendImageProcessor, "SuspendImageProcessor"}, {313, C<&IRS::SuspendImageProcessor>, "SuspendImageProcessor"},
{314, &IRS::CheckFirmwareVersion, "CheckFirmwareVersion"}, {314, C<&IRS::CheckFirmwareVersion>, "CheckFirmwareVersion"},
{315, &IRS::SetFunctionLevel, "SetFunctionLevel"}, {315, C<&IRS::SetFunctionLevel>, "SetFunctionLevel"},
{316, &IRS::RunImageTransferExProcessor, "RunImageTransferExProcessor"}, {316, C<&IRS::RunImageTransferExProcessor>, "RunImageTransferExProcessor"},
{317, &IRS::RunIrLedProcessor, "RunIrLedProcessor"}, {317, C<&IRS::RunIrLedProcessor>, "RunIrLedProcessor"},
{318, &IRS::StopImageProcessorAsync, "StopImageProcessorAsync"}, {318, C<&IRS::StopImageProcessorAsync>, "StopImageProcessorAsync"},
{319, &IRS::ActivateIrsensorWithFunctionLevel, "ActivateIrsensorWithFunctionLevel"}, {319, C<&IRS::ActivateIrsensorWithFunctionLevel>, "ActivateIrsensorWithFunctionLevel"},
}; };
// clang-format on // clang-format on
@ -57,489 +58,292 @@ IRS::IRS(Core::System& system_) : ServiceFramework{system_, "irs"} {
} }
IRS::~IRS() = default; IRS::~IRS() = default;
void IRS::ActivateIrsensor(HLERequestContext& ctx) { Result IRS::ActivateIrsensor(ClientAppletResourceUserId aruid) {
IPC::RequestParser rp{ctx}; LOG_WARNING(Service_IRS, "(STUBBED) called, applet_resource_user_id={}", aruid.pid);
const auto applet_resource_user_id{rp.Pop<u64>()}; R_SUCCEED();
LOG_WARNING(Service_IRS, "(STUBBED) called, applet_resource_user_id={}",
applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
} }
void IRS::DeactivateIrsensor(HLERequestContext& ctx) { Result IRS::DeactivateIrsensor(ClientAppletResourceUserId aruid) {
IPC::RequestParser rp{ctx}; LOG_WARNING(Service_IRS, "(STUBBED) called, applet_resource_user_id={}", aruid.pid);
const auto applet_resource_user_id{rp.Pop<u64>()}; R_SUCCEED();
LOG_WARNING(Service_IRS, "(STUBBED) called, applet_resource_user_id={}",
applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
} }
void IRS::GetIrsensorSharedMemoryHandle(HLERequestContext& ctx) { Result IRS::GetIrsensorSharedMemoryHandle(OutCopyHandle<Kernel::KSharedMemory> out_shared_memory,
IPC::RequestParser rp{ctx}; ClientAppletResourceUserId aruid) {
const auto applet_resource_user_id{rp.Pop<u64>()}; LOG_DEBUG(Service_IRS, "called, applet_resource_user_id={}", aruid.pid);
LOG_DEBUG(Service_IRS, "called, applet_resource_user_id={}", applet_resource_user_id); *out_shared_memory = &system.Kernel().GetIrsSharedMem();
R_SUCCEED();
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
rb.PushCopyObjects(&system.Kernel().GetIrsSharedMem());
} }
void IRS::StopImageProcessor(HLERequestContext& ctx) { Result IRS::StopImageProcessor(Core::IrSensor::IrCameraHandle camera_handle,
IPC::RequestParser rp{ctx}; ClientAppletResourceUserId aruid) {
struct Parameters {
Core::IrSensor::IrCameraHandle camera_handle;
INSERT_PADDING_WORDS_NOINIT(1);
u64 applet_resource_user_id;
};
static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
LOG_WARNING(Service_IRS, LOG_WARNING(Service_IRS,
"(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}", "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, camera_handle.npad_type, camera_handle.npad_id, aruid.pid);
parameters.applet_resource_user_id);
auto result = IsIrCameraHandleValid(parameters.camera_handle); R_TRY(IsIrCameraHandleValid(camera_handle));
if (result.IsSuccess()) {
// TODO: Stop Image processor
npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
Common::Input::PollingMode::Active);
result = ResultSuccess;
}
IPC::ResponseBuilder rb{ctx, 2}; // TODO: Stop Image processor
rb.Push(result); npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
Common::Input::PollingMode::Active);
R_SUCCEED();
} }
void IRS::RunMomentProcessor(HLERequestContext& ctx) { Result IRS::RunMomentProcessor(
IPC::RequestParser rp{ctx}; Core::IrSensor::IrCameraHandle camera_handle, ClientAppletResourceUserId aruid,
struct Parameters { const Core::IrSensor::PackedMomentProcessorConfig& processor_config) {
Core::IrSensor::IrCameraHandle camera_handle;
INSERT_PADDING_WORDS_NOINIT(1);
u64 applet_resource_user_id;
Core::IrSensor::PackedMomentProcessorConfig processor_config;
};
static_assert(sizeof(Parameters) == 0x30, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
LOG_WARNING(Service_IRS, LOG_WARNING(Service_IRS,
"(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}", "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, camera_handle.npad_type, camera_handle.npad_id, aruid.pid);
parameters.applet_resource_user_id);
const auto result = IsIrCameraHandleValid(parameters.camera_handle); R_TRY(IsIrCameraHandleValid(camera_handle));
if (result.IsSuccess()) { auto& device = GetIrCameraSharedMemoryDeviceEntry(camera_handle);
auto& device = GetIrCameraSharedMemoryDeviceEntry(parameters.camera_handle); MakeProcessorWithCoreContext<MomentProcessor>(camera_handle, device);
MakeProcessorWithCoreContext<MomentProcessor>(parameters.camera_handle, device); auto& image_transfer_processor = GetProcessor<MomentProcessor>(camera_handle);
auto& image_transfer_processor = GetProcessor<MomentProcessor>(parameters.camera_handle); image_transfer_processor.SetConfig(processor_config);
image_transfer_processor.SetConfig(parameters.processor_config); npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex, Common::Input::PollingMode::IR);
Common::Input::PollingMode::IR);
}
IPC::ResponseBuilder rb{ctx, 2}; R_SUCCEED();
rb.Push(result);
} }
void IRS::RunClusteringProcessor(HLERequestContext& ctx) { Result IRS::RunClusteringProcessor(
IPC::RequestParser rp{ctx}; Core::IrSensor::IrCameraHandle camera_handle, ClientAppletResourceUserId aruid,
struct Parameters { const Core::IrSensor::PackedClusteringProcessorConfig& processor_config) {
Core::IrSensor::IrCameraHandle camera_handle;
INSERT_PADDING_WORDS_NOINIT(1);
u64 applet_resource_user_id;
Core::IrSensor::PackedClusteringProcessorConfig processor_config;
};
static_assert(sizeof(Parameters) == 0x38, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
LOG_WARNING(Service_IRS, LOG_WARNING(Service_IRS,
"(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}", "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, camera_handle.npad_type, camera_handle.npad_id, aruid.pid);
parameters.applet_resource_user_id);
auto result = IsIrCameraHandleValid(parameters.camera_handle); R_TRY(IsIrCameraHandleValid(camera_handle));
if (result.IsSuccess()) { auto& device = GetIrCameraSharedMemoryDeviceEntry(camera_handle);
auto& device = GetIrCameraSharedMemoryDeviceEntry(parameters.camera_handle); MakeProcessorWithCoreContext<ClusteringProcessor>(camera_handle, device);
MakeProcessorWithCoreContext<ClusteringProcessor>(parameters.camera_handle, device); auto& image_transfer_processor = GetProcessor<ClusteringProcessor>(camera_handle);
auto& image_transfer_processor = image_transfer_processor.SetConfig(processor_config);
GetProcessor<ClusteringProcessor>(parameters.camera_handle); npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
image_transfer_processor.SetConfig(parameters.processor_config); Common::Input::PollingMode::IR);
npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
Common::Input::PollingMode::IR);
}
IPC::ResponseBuilder rb{ctx, 2}; R_SUCCEED();
rb.Push(result);
} }
void IRS::RunImageTransferProcessor(HLERequestContext& ctx) { Result IRS::RunImageTransferProcessor(
IPC::RequestParser rp{ctx}; Core::IrSensor::IrCameraHandle camera_handle, ClientAppletResourceUserId aruid,
struct Parameters { const Core::IrSensor::PackedImageTransferProcessorConfig& processor_config,
Core::IrSensor::IrCameraHandle camera_handle; u64 transfer_memory_size, InCopyHandle<Kernel::KTransferMemory> t_mem) {
INSERT_PADDING_WORDS_NOINIT(1);
u64 applet_resource_user_id;
Core::IrSensor::PackedImageTransferProcessorConfig processor_config;
u32 transfer_memory_size;
};
static_assert(sizeof(Parameters) == 0x30, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()}; ASSERT_MSG(t_mem->GetSize() == transfer_memory_size, "t_mem has incorrect size");
const auto t_mem_handle{ctx.GetCopyHandle(0)};
auto t_mem = ctx.GetObjectFromHandle<Kernel::KTransferMemory>(t_mem_handle);
if (t_mem.IsNull()) {
LOG_ERROR(Service_IRS, "t_mem is a nullptr for handle=0x{:08X}", t_mem_handle);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultUnknown);
return;
}
ASSERT_MSG(t_mem->GetSize() == parameters.transfer_memory_size, "t_mem has incorrect size");
LOG_INFO(Service_IRS, LOG_INFO(Service_IRS,
"called, npad_type={}, npad_id={}, transfer_memory_size={}, transfer_memory_size={}, " "called, npad_type={}, npad_id={}, transfer_memory_size={}, transfer_memory_size={}, "
"applet_resource_user_id={}", "applet_resource_user_id={}",
parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, camera_handle.npad_type, camera_handle.npad_id, transfer_memory_size, t_mem->GetSize(),
parameters.transfer_memory_size, t_mem->GetSize(), parameters.applet_resource_user_id); aruid.pid);
const auto result = IsIrCameraHandleValid(parameters.camera_handle); R_TRY(IsIrCameraHandleValid(camera_handle));
if (result.IsSuccess()) { auto& device = GetIrCameraSharedMemoryDeviceEntry(camera_handle);
auto& device = GetIrCameraSharedMemoryDeviceEntry(parameters.camera_handle); MakeProcessorWithCoreContext<ImageTransferProcessor>(camera_handle, device);
MakeProcessorWithCoreContext<ImageTransferProcessor>(parameters.camera_handle, device); auto& image_transfer_processor = GetProcessor<ImageTransferProcessor>(camera_handle);
auto& image_transfer_processor = image_transfer_processor.SetConfig(processor_config);
GetProcessor<ImageTransferProcessor>(parameters.camera_handle); image_transfer_processor.SetTransferMemoryAddress(t_mem->GetSourceAddress());
image_transfer_processor.SetConfig(parameters.processor_config); npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
image_transfer_processor.SetTransferMemoryAddress(t_mem->GetSourceAddress()); Common::Input::PollingMode::IR);
npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
Common::Input::PollingMode::IR);
}
IPC::ResponseBuilder rb{ctx, 2}; R_SUCCEED();
rb.Push(result);
} }
void IRS::GetImageTransferProcessorState(HLERequestContext& ctx) { Result IRS::GetImageTransferProcessorState(
IPC::RequestParser rp{ctx}; Out<Core::IrSensor::ImageTransferProcessorState> out_state,
struct Parameters { Core::IrSensor::IrCameraHandle camera_handle, ClientAppletResourceUserId aruid,
Core::IrSensor::IrCameraHandle camera_handle; OutBuffer<BufferAttr_HipcMapAlias> out_buffer_data) {
INSERT_PADDING_WORDS_NOINIT(1);
u64 applet_resource_user_id;
};
static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
LOG_DEBUG(Service_IRS, "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}", LOG_DEBUG(Service_IRS, "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, camera_handle.npad_type, camera_handle.npad_id, aruid.pid);
parameters.applet_resource_user_id);
const auto result = IsIrCameraHandleValid(parameters.camera_handle); R_TRY(IsIrCameraHandleValid(camera_handle));
if (result.IsError()) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
return;
}
const auto& device = GetIrCameraSharedMemoryDeviceEntry(parameters.camera_handle); const auto& device = GetIrCameraSharedMemoryDeviceEntry(camera_handle);
if (device.mode != Core::IrSensor::IrSensorMode::ImageTransferProcessor) { R_TRY(IsIrCameraHandleValid(camera_handle));
IPC::ResponseBuilder rb{ctx, 2}; R_UNLESS(device.mode == Core::IrSensor::IrSensorMode::ImageTransferProcessor,
rb.Push(InvalidProcessorState); InvalidProcessorState);
return;
}
std::vector<u8> data{}; *out_state = GetProcessor<ImageTransferProcessor>(camera_handle).GetState(out_buffer_data);
const auto& image_transfer_processor =
GetProcessor<ImageTransferProcessor>(parameters.camera_handle);
const auto& state = image_transfer_processor.GetState(data);
ctx.WriteBuffer(data); R_SUCCEED();
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(ResultSuccess);
rb.PushRaw(state);
} }
void IRS::RunTeraPluginProcessor(HLERequestContext& ctx) { Result IRS::RunTeraPluginProcessor(Core::IrSensor::IrCameraHandle camera_handle,
IPC::RequestParser rp{ctx}; Core::IrSensor::PackedTeraPluginProcessorConfig processor_config,
struct Parameters { ClientAppletResourceUserId aruid) {
Core::IrSensor::IrCameraHandle camera_handle; LOG_WARNING(Service_IRS,
Core::IrSensor::PackedTeraPluginProcessorConfig processor_config; "(STUBBED) called, npad_type={}, npad_id={}, mode={}, mcu_version={}.{}, "
INSERT_PADDING_WORDS_NOINIT(1); "applet_resource_user_id={}",
u64 applet_resource_user_id; camera_handle.npad_type, camera_handle.npad_id, processor_config.mode,
}; processor_config.required_mcu_version.major,
static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); processor_config.required_mcu_version.minor, aruid.pid);
const auto parameters{rp.PopRaw<Parameters>()}; R_TRY(IsIrCameraHandleValid(camera_handle));
LOG_WARNING( auto& device = GetIrCameraSharedMemoryDeviceEntry(camera_handle);
Service_IRS, MakeProcessor<TeraPluginProcessor>(camera_handle, device);
"(STUBBED) called, npad_type={}, npad_id={}, mode={}, mcu_version={}.{}, " auto& image_transfer_processor = GetProcessor<TeraPluginProcessor>(camera_handle);
"applet_resource_user_id={}", image_transfer_processor.SetConfig(processor_config);
parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
parameters.processor_config.mode, parameters.processor_config.required_mcu_version.major, Common::Input::PollingMode::IR);
parameters.processor_config.required_mcu_version.minor, parameters.applet_resource_user_id);
const auto result = IsIrCameraHandleValid(parameters.camera_handle); R_SUCCEED();
if (result.IsSuccess()) {
auto& device = GetIrCameraSharedMemoryDeviceEntry(parameters.camera_handle);
MakeProcessor<TeraPluginProcessor>(parameters.camera_handle, device);
auto& image_transfer_processor =
GetProcessor<TeraPluginProcessor>(parameters.camera_handle);
image_transfer_processor.SetConfig(parameters.processor_config);
npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
Common::Input::PollingMode::IR);
}
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
} }
void IRS::GetNpadIrCameraHandle(HLERequestContext& ctx) { Result IRS::GetNpadIrCameraHandle(Out<Core::IrSensor::IrCameraHandle> out_camera_handle,
IPC::RequestParser rp{ctx}; Core::HID::NpadIdType npad_id) {
const auto npad_id{rp.PopEnum<Core::HID::NpadIdType>()}; R_UNLESS(HID::IsNpadIdValid(npad_id), HID::ResultInvalidNpadId);
if (npad_id > Core::HID::NpadIdType::Player8 && npad_id != Core::HID::NpadIdType::Invalid && *out_camera_handle = {
npad_id != Core::HID::NpadIdType::Handheld) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(Service::HID::ResultInvalidNpadId);
return;
}
Core::IrSensor::IrCameraHandle camera_handle{
.npad_id = static_cast<u8>(HID::NpadIdTypeToIndex(npad_id)), .npad_id = static_cast<u8>(HID::NpadIdTypeToIndex(npad_id)),
.npad_type = Core::HID::NpadStyleIndex::None, .npad_type = Core::HID::NpadStyleIndex::None,
}; };
LOG_INFO(Service_IRS, "called, npad_id={}, camera_npad_id={}, camera_npad_type={}", npad_id, LOG_INFO(Service_IRS, "called, npad_id={}, camera_npad_id={}, camera_npad_type={}", npad_id,
camera_handle.npad_id, camera_handle.npad_type); out_camera_handle->npad_id, out_camera_handle->npad_type);
IPC::ResponseBuilder rb{ctx, 3}; R_SUCCEED();
rb.Push(ResultSuccess);
rb.PushRaw(camera_handle);
} }
void IRS::RunPointingProcessor(HLERequestContext& ctx) { Result IRS::RunPointingProcessor(
IPC::RequestParser rp{ctx}; Core::IrSensor::IrCameraHandle camera_handle,
const auto camera_handle{rp.PopRaw<Core::IrSensor::IrCameraHandle>()}; const Core::IrSensor::PackedPointingProcessorConfig& processor_config,
const auto processor_config{rp.PopRaw<Core::IrSensor::PackedPointingProcessorConfig>()}; ClientAppletResourceUserId aruid) {
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_WARNING( LOG_WARNING(
Service_IRS, Service_IRS,
"(STUBBED) called, npad_type={}, npad_id={}, mcu_version={}.{}, applet_resource_user_id={}", "(STUBBED) called, npad_type={}, npad_id={}, mcu_version={}.{}, applet_resource_user_id={}",
camera_handle.npad_type, camera_handle.npad_id, processor_config.required_mcu_version.major, camera_handle.npad_type, camera_handle.npad_id, processor_config.required_mcu_version.major,
processor_config.required_mcu_version.minor, applet_resource_user_id); processor_config.required_mcu_version.minor, aruid.pid);
auto result = IsIrCameraHandleValid(camera_handle); R_TRY(IsIrCameraHandleValid(camera_handle));
if (result.IsSuccess()) { auto& device = GetIrCameraSharedMemoryDeviceEntry(camera_handle);
auto& device = GetIrCameraSharedMemoryDeviceEntry(camera_handle); MakeProcessor<PointingProcessor>(camera_handle, device);
MakeProcessor<PointingProcessor>(camera_handle, device); auto& image_transfer_processor = GetProcessor<PointingProcessor>(camera_handle);
auto& image_transfer_processor = GetProcessor<PointingProcessor>(camera_handle); image_transfer_processor.SetConfig(processor_config);
image_transfer_processor.SetConfig(processor_config); npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex, Common::Input::PollingMode::IR);
Common::Input::PollingMode::IR);
}
IPC::ResponseBuilder rb{ctx, 2}; R_SUCCEED();
rb.Push(result);
} }
void IRS::SuspendImageProcessor(HLERequestContext& ctx) { Result IRS::SuspendImageProcessor(Core::IrSensor::IrCameraHandle camera_handle,
IPC::RequestParser rp{ctx}; ClientAppletResourceUserId aruid) {
struct Parameters {
Core::IrSensor::IrCameraHandle camera_handle;
INSERT_PADDING_WORDS_NOINIT(1);
u64 applet_resource_user_id;
};
static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
LOG_WARNING(Service_IRS, LOG_WARNING(Service_IRS,
"(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}", "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, camera_handle.npad_type, camera_handle.npad_id, aruid.pid);
parameters.applet_resource_user_id);
auto result = IsIrCameraHandleValid(parameters.camera_handle); R_TRY(IsIrCameraHandleValid(camera_handle));
if (result.IsSuccess()) {
// TODO: Suspend image processor
result = ResultSuccess;
}
IPC::ResponseBuilder rb{ctx, 2}; // TODO: Suspend image processor
rb.Push(result);
R_SUCCEED();
} }
void IRS::CheckFirmwareVersion(HLERequestContext& ctx) { Result IRS::CheckFirmwareVersion(Core::IrSensor::IrCameraHandle camera_handle,
IPC::RequestParser rp{ctx}; Core::IrSensor::PackedMcuVersion mcu_version,
const auto camera_handle{rp.PopRaw<Core::IrSensor::IrCameraHandle>()}; ClientAppletResourceUserId aruid) {
const auto mcu_version{rp.PopRaw<Core::IrSensor::PackedMcuVersion>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_WARNING( LOG_WARNING(
Service_IRS, Service_IRS,
"(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}, mcu_version={}.{}", "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}, mcu_version={}.{}",
camera_handle.npad_type, camera_handle.npad_id, applet_resource_user_id, mcu_version.major, camera_handle.npad_type, camera_handle.npad_id, aruid.pid, mcu_version.major,
mcu_version.minor); mcu_version.minor);
auto result = IsIrCameraHandleValid(camera_handle); R_TRY(IsIrCameraHandleValid(camera_handle));
if (result.IsSuccess()) {
// TODO: Check firmware version
result = ResultSuccess;
}
IPC::ResponseBuilder rb{ctx, 2}; // TODO: Check firmware version
rb.Push(result);
R_SUCCEED();
} }
void IRS::SetFunctionLevel(HLERequestContext& ctx) { Result IRS::SetFunctionLevel(Core::IrSensor::IrCameraHandle camera_handle,
IPC::RequestParser rp{ctx}; Core::IrSensor::PackedFunctionLevel function_level,
const auto camera_handle{rp.PopRaw<Core::IrSensor::IrCameraHandle>()}; ClientAppletResourceUserId aruid) {
const auto function_level{rp.PopRaw<Core::IrSensor::PackedFunctionLevel>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_WARNING( LOG_WARNING(
Service_IRS, Service_IRS,
"(STUBBED) called, npad_type={}, npad_id={}, function_level={}, applet_resource_user_id={}", "(STUBBED) called, npad_type={}, npad_id={}, function_level={}, applet_resource_user_id={}",
camera_handle.npad_type, camera_handle.npad_id, function_level.function_level, camera_handle.npad_type, camera_handle.npad_id, function_level.function_level, aruid.pid);
applet_resource_user_id);
auto result = IsIrCameraHandleValid(camera_handle); R_TRY(IsIrCameraHandleValid(camera_handle));
if (result.IsSuccess()) {
// TODO: Set Function level
result = ResultSuccess;
}
IPC::ResponseBuilder rb{ctx, 2}; // TODO: Set Function level
rb.Push(result);
R_SUCCEED();
} }
void IRS::RunImageTransferExProcessor(HLERequestContext& ctx) { Result IRS::RunImageTransferExProcessor(
IPC::RequestParser rp{ctx}; Core::IrSensor::IrCameraHandle camera_handle, ClientAppletResourceUserId aruid,
struct Parameters { const Core::IrSensor::PackedImageTransferProcessorExConfig& processor_config,
Core::IrSensor::IrCameraHandle camera_handle; u64 transfer_memory_size, InCopyHandle<Kernel::KTransferMemory> t_mem) {
INSERT_PADDING_WORDS_NOINIT(1);
u64 applet_resource_user_id;
Core::IrSensor::PackedImageTransferProcessorExConfig processor_config;
u64 transfer_memory_size;
};
static_assert(sizeof(Parameters) == 0x38, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()}; ASSERT_MSG(t_mem->GetSize() == transfer_memory_size, "t_mem has incorrect size");
const auto t_mem_handle{ctx.GetCopyHandle(0)};
auto t_mem = ctx.GetObjectFromHandle<Kernel::KTransferMemory>(t_mem_handle);
LOG_INFO(Service_IRS, LOG_INFO(Service_IRS,
"called, npad_type={}, npad_id={}, transfer_memory_size={}, " "called, npad_type={}, npad_id={}, transfer_memory_size={}, "
"applet_resource_user_id={}", "applet_resource_user_id={}",
parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, camera_handle.npad_type, camera_handle.npad_id, transfer_memory_size, aruid.pid);
parameters.transfer_memory_size, parameters.applet_resource_user_id);
auto result = IsIrCameraHandleValid(parameters.camera_handle); R_TRY(IsIrCameraHandleValid(camera_handle));
if (result.IsSuccess()) { auto& device = GetIrCameraSharedMemoryDeviceEntry(camera_handle);
auto& device = GetIrCameraSharedMemoryDeviceEntry(parameters.camera_handle); MakeProcessorWithCoreContext<ImageTransferProcessor>(camera_handle, device);
MakeProcessorWithCoreContext<ImageTransferProcessor>(parameters.camera_handle, device); auto& image_transfer_processor = GetProcessor<ImageTransferProcessor>(camera_handle);
auto& image_transfer_processor = image_transfer_processor.SetConfig(processor_config);
GetProcessor<ImageTransferProcessor>(parameters.camera_handle); image_transfer_processor.SetTransferMemoryAddress(t_mem->GetSourceAddress());
image_transfer_processor.SetConfig(parameters.processor_config); npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
image_transfer_processor.SetTransferMemoryAddress(t_mem->GetSourceAddress()); Common::Input::PollingMode::IR);
npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
Common::Input::PollingMode::IR);
}
IPC::ResponseBuilder rb{ctx, 2}; R_SUCCEED();
rb.Push(result);
} }
void IRS::RunIrLedProcessor(HLERequestContext& ctx) { Result IRS::RunIrLedProcessor(Core::IrSensor::IrCameraHandle camera_handle,
IPC::RequestParser rp{ctx}; Core::IrSensor::PackedIrLedProcessorConfig processor_config,
const auto camera_handle{rp.PopRaw<Core::IrSensor::IrCameraHandle>()}; ClientAppletResourceUserId aruid) {
const auto processor_config{rp.PopRaw<Core::IrSensor::PackedIrLedProcessorConfig>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_WARNING(Service_IRS, LOG_WARNING(Service_IRS,
"(STUBBED) called, npad_type={}, npad_id={}, light_target={}, mcu_version={}.{} " "(STUBBED) called, npad_type={}, npad_id={}, light_target={}, mcu_version={}.{} "
"applet_resource_user_id={}", "applet_resource_user_id={}",
camera_handle.npad_type, camera_handle.npad_id, processor_config.light_target, camera_handle.npad_type, camera_handle.npad_id, processor_config.light_target,
processor_config.required_mcu_version.major, processor_config.required_mcu_version.major,
processor_config.required_mcu_version.minor, applet_resource_user_id); processor_config.required_mcu_version.minor, aruid.pid);
auto result = IsIrCameraHandleValid(camera_handle); R_TRY(IsIrCameraHandleValid(camera_handle));
if (result.IsSuccess()) { auto& device = GetIrCameraSharedMemoryDeviceEntry(camera_handle);
auto& device = GetIrCameraSharedMemoryDeviceEntry(camera_handle); MakeProcessor<IrLedProcessor>(camera_handle, device);
MakeProcessor<IrLedProcessor>(camera_handle, device); auto& image_transfer_processor = GetProcessor<IrLedProcessor>(camera_handle);
auto& image_transfer_processor = GetProcessor<IrLedProcessor>(camera_handle); image_transfer_processor.SetConfig(processor_config);
image_transfer_processor.SetConfig(processor_config); npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex, Common::Input::PollingMode::IR);
Common::Input::PollingMode::IR);
}
IPC::ResponseBuilder rb{ctx, 2}; R_SUCCEED();
rb.Push(result);
} }
void IRS::StopImageProcessorAsync(HLERequestContext& ctx) { Result IRS::StopImageProcessorAsync(Core::IrSensor::IrCameraHandle camera_handle,
IPC::RequestParser rp{ctx}; ClientAppletResourceUserId aruid) {
struct Parameters {
Core::IrSensor::IrCameraHandle camera_handle;
INSERT_PADDING_WORDS_NOINIT(1);
u64 applet_resource_user_id;
};
static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
LOG_WARNING(Service_IRS, LOG_WARNING(Service_IRS,
"(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}", "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, camera_handle.npad_type, camera_handle.npad_id, aruid.pid);
parameters.applet_resource_user_id);
auto result = IsIrCameraHandleValid(parameters.camera_handle); R_TRY(IsIrCameraHandleValid(camera_handle));
if (result.IsSuccess()) {
// TODO: Stop image processor async
npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
Common::Input::PollingMode::Active);
result = ResultSuccess;
}
IPC::ResponseBuilder rb{ctx, 2}; // TODO: Stop image processor async
rb.Push(result); npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
Common::Input::PollingMode::Active);
R_SUCCEED();
} }
void IRS::ActivateIrsensorWithFunctionLevel(HLERequestContext& ctx) { Result IRS::ActivateIrsensorWithFunctionLevel(Core::IrSensor::PackedFunctionLevel function_level,
IPC::RequestParser rp{ctx}; ClientAppletResourceUserId aruid) {
struct Parameters {
Core::IrSensor::PackedFunctionLevel function_level;
INSERT_PADDING_WORDS_NOINIT(1);
u64 applet_resource_user_id;
};
static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
LOG_WARNING(Service_IRS, "(STUBBED) called, function_level={}, applet_resource_user_id={}", LOG_WARNING(Service_IRS, "(STUBBED) called, function_level={}, applet_resource_user_id={}",
parameters.function_level.function_level, parameters.applet_resource_user_id); function_level.function_level, aruid.pid);
R_SUCCEED();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
} }
Result IRS::IsIrCameraHandleValid(const Core::IrSensor::IrCameraHandle& camera_handle) const { Result IRS::IsIrCameraHandleValid(const Core::IrSensor::IrCameraHandle& camera_handle) const {

View File

@ -4,6 +4,7 @@
#pragma once #pragma once
#include "core/core.h" #include "core/core.h"
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
#include "hid_core/hid_types.h" #include "hid_core/hid_types.h"
#include "hid_core/irsensor/irs_types.h" #include "hid_core/irsensor/irs_types.h"
@ -35,26 +36,73 @@ private:
}; };
static_assert(sizeof(StatusManager) == 0x8000, "StatusManager is an invalid size"); static_assert(sizeof(StatusManager) == 0x8000, "StatusManager is an invalid size");
void ActivateIrsensor(HLERequestContext& ctx); Result ActivateIrsensor(ClientAppletResourceUserId aruid);
void DeactivateIrsensor(HLERequestContext& ctx);
void GetIrsensorSharedMemoryHandle(HLERequestContext& ctx); Result DeactivateIrsensor(ClientAppletResourceUserId aruid);
void StopImageProcessor(HLERequestContext& ctx);
void RunMomentProcessor(HLERequestContext& ctx); Result GetIrsensorSharedMemoryHandle(OutCopyHandle<Kernel::KSharedMemory> out_shared_memory,
void RunClusteringProcessor(HLERequestContext& ctx); ClientAppletResourceUserId aruid);
void RunImageTransferProcessor(HLERequestContext& ctx); Result StopImageProcessor(Core::IrSensor::IrCameraHandle camera_handle,
void GetImageTransferProcessorState(HLERequestContext& ctx); ClientAppletResourceUserId aruid);
void RunTeraPluginProcessor(HLERequestContext& ctx);
void GetNpadIrCameraHandle(HLERequestContext& ctx); Result RunMomentProcessor(Core::IrSensor::IrCameraHandle camera_handle,
void RunPointingProcessor(HLERequestContext& ctx); ClientAppletResourceUserId aruid,
void SuspendImageProcessor(HLERequestContext& ctx); const Core::IrSensor::PackedMomentProcessorConfig& processor_config);
void CheckFirmwareVersion(HLERequestContext& ctx);
void SetFunctionLevel(HLERequestContext& ctx); Result RunClusteringProcessor(
void RunImageTransferExProcessor(HLERequestContext& ctx); Core::IrSensor::IrCameraHandle camera_handle, ClientAppletResourceUserId aruid,
void RunIrLedProcessor(HLERequestContext& ctx); const Core::IrSensor::PackedClusteringProcessorConfig& processor_config);
void StopImageProcessorAsync(HLERequestContext& ctx);
void ActivateIrsensorWithFunctionLevel(HLERequestContext& ctx); Result RunImageTransferProcessor(
Core::IrSensor::IrCameraHandle camera_handle, ClientAppletResourceUserId aruid,
const Core::IrSensor::PackedImageTransferProcessorConfig& processor_config,
u64 transfer_memory_size, InCopyHandle<Kernel::KTransferMemory> t_mem);
Result GetImageTransferProcessorState(
Out<Core::IrSensor::ImageTransferProcessorState> out_state,
Core::IrSensor::IrCameraHandle camera_handle, ClientAppletResourceUserId aruid,
OutBuffer<BufferAttr_HipcMapAlias> out_buffer_data);
Result RunTeraPluginProcessor(Core::IrSensor::IrCameraHandle camera_handle,
Core::IrSensor::PackedTeraPluginProcessorConfig processor_config,
ClientAppletResourceUserId aruid);
Result GetNpadIrCameraHandle(Out<Core::IrSensor::IrCameraHandle> out_camera_handle,
Core::HID::NpadIdType npad_id);
Result RunPointingProcessor(
Core::IrSensor::IrCameraHandle camera_handle,
const Core::IrSensor::PackedPointingProcessorConfig& processor_config,
ClientAppletResourceUserId aruid);
Result SuspendImageProcessor(Core::IrSensor::IrCameraHandle camera_handle,
ClientAppletResourceUserId aruid);
Result CheckFirmwareVersion(Core::IrSensor::IrCameraHandle camera_handle,
Core::IrSensor::PackedMcuVersion mcu_version,
ClientAppletResourceUserId aruid);
Result SetFunctionLevel(Core::IrSensor::IrCameraHandle camera_handle,
Core::IrSensor::PackedFunctionLevel function_level,
ClientAppletResourceUserId aruid);
Result RunImageTransferExProcessor(
Core::IrSensor::IrCameraHandle camera_handle, ClientAppletResourceUserId aruid,
const Core::IrSensor::PackedImageTransferProcessorExConfig& processor_config,
u64 transfer_memory_size, InCopyHandle<Kernel::KTransferMemory> t_mem);
Result RunIrLedProcessor(Core::IrSensor::IrCameraHandle camera_handle,
Core::IrSensor::PackedIrLedProcessorConfig processor_config,
ClientAppletResourceUserId aruid);
Result StopImageProcessorAsync(Core::IrSensor::IrCameraHandle camera_handle,
ClientAppletResourceUserId aruid);
Result ActivateIrsensorWithFunctionLevel(Core::IrSensor::PackedFunctionLevel function_level,
ClientAppletResourceUserId aruid);
Result IsIrCameraHandleValid(const Core::IrSensor::IrCameraHandle& camera_handle) const; Result IsIrCameraHandleValid(const Core::IrSensor::IrCameraHandle& camera_handle) const;
Core::IrSensor::DeviceFormat& GetIrCameraSharedMemoryDeviceEntry( Core::IrSensor::DeviceFormat& GetIrCameraSharedMemoryDeviceEntry(
const Core::IrSensor::IrCameraHandle& camera_handle); const Core::IrSensor::IrCameraHandle& camera_handle);

View File

@ -123,6 +123,8 @@ NvResult nvhost_as_gpu::AllocAsEx(IoctlAllocAsEx& params) {
vm.va_range_end = params.va_range_end; vm.va_range_end = params.va_range_end;
} }
const u64 max_big_page_bits = Common::Log2Ceil64(vm.va_range_end);
const auto start_pages{static_cast<u32>(vm.va_range_start >> VM::PAGE_SIZE_BITS)}; const auto start_pages{static_cast<u32>(vm.va_range_start >> VM::PAGE_SIZE_BITS)};
const auto end_pages{static_cast<u32>(vm.va_range_split >> VM::PAGE_SIZE_BITS)}; const auto end_pages{static_cast<u32>(vm.va_range_split >> VM::PAGE_SIZE_BITS)};
vm.small_page_allocator = std::make_shared<VM::Allocator>(start_pages, end_pages); vm.small_page_allocator = std::make_shared<VM::Allocator>(start_pages, end_pages);
@ -132,8 +134,8 @@ NvResult nvhost_as_gpu::AllocAsEx(IoctlAllocAsEx& params) {
static_cast<u32>((vm.va_range_end - vm.va_range_split) >> vm.big_page_size_bits)}; static_cast<u32>((vm.va_range_end - vm.va_range_split) >> vm.big_page_size_bits)};
vm.big_page_allocator = std::make_unique<VM::Allocator>(start_big_pages, end_big_pages); vm.big_page_allocator = std::make_unique<VM::Allocator>(start_big_pages, end_big_pages);
gmmu = std::make_shared<Tegra::MemoryManager>(system, 40, vm.big_page_size_bits, gmmu = std::make_shared<Tegra::MemoryManager>(system, max_big_page_bits, vm.va_range_split,
VM::PAGE_SIZE_BITS); vm.big_page_size_bits, VM::PAGE_SIZE_BITS);
system.GPU().InitAddressSpace(*gmmu); system.GPU().InitAddressSpace(*gmmu);
vm.initialised = true; vm.initialised = true;

View File

@ -47,12 +47,23 @@ StandardVmCallbacks::StandardVmCallbacks(System& system_, const CheatProcessMeta
StandardVmCallbacks::~StandardVmCallbacks() = default; StandardVmCallbacks::~StandardVmCallbacks() = default;
void StandardVmCallbacks::MemoryRead(VAddr address, void* data, u64 size) { void StandardVmCallbacks::MemoryReadUnsafe(VAddr address, void* data, u64 size) {
system.ApplicationMemory().ReadBlock(SanitizeAddress(address), data, size); // Return zero on invalid address
if (!IsAddressInRange(address) || !system.ApplicationMemory().IsValidVirtualAddress(address)) {
std::memset(data, 0, size);
return;
}
system.ApplicationMemory().ReadBlock(address, data, size);
} }
void StandardVmCallbacks::MemoryWrite(VAddr address, const void* data, u64 size) { void StandardVmCallbacks::MemoryWriteUnsafe(VAddr address, const void* data, u64 size) {
system.ApplicationMemory().WriteBlock(SanitizeAddress(address), data, size); // Skip invalid memory write address
if (!IsAddressInRange(address) || !system.ApplicationMemory().IsValidVirtualAddress(address)) {
return;
}
system.ApplicationMemory().WriteBlock(address, data, size);
} }
u64 StandardVmCallbacks::HidKeysDown() { u64 StandardVmCallbacks::HidKeysDown() {
@ -82,7 +93,7 @@ void StandardVmCallbacks::CommandLog(std::string_view data) {
data.back() == '\n' ? data.substr(0, data.size() - 1) : data); data.back() == '\n' ? data.substr(0, data.size() - 1) : data);
} }
VAddr StandardVmCallbacks::SanitizeAddress(VAddr in) const { bool StandardVmCallbacks::IsAddressInRange(VAddr in) const {
if ((in < metadata.main_nso_extents.base || if ((in < metadata.main_nso_extents.base ||
in >= metadata.main_nso_extents.base + metadata.main_nso_extents.size) && in >= metadata.main_nso_extents.base + metadata.main_nso_extents.size) &&
(in < metadata.heap_extents.base || (in < metadata.heap_extents.base ||
@ -97,10 +108,10 @@ VAddr StandardVmCallbacks::SanitizeAddress(VAddr in) const {
"the cheat may be incorrect. However, this may be normal early in execution if " "the cheat may be incorrect. However, this may be normal early in execution if "
"the game has not properly set up yet.", "the game has not properly set up yet.",
in); in);
return 0; ///< Invalid addresses will hard crash return false; ///< Invalid addresses will hard crash
} }
return in; return true;
} }
CheatParser::~CheatParser() = default; CheatParser::~CheatParser() = default;

View File

@ -27,14 +27,14 @@ public:
StandardVmCallbacks(System& system_, const CheatProcessMetadata& metadata_); StandardVmCallbacks(System& system_, const CheatProcessMetadata& metadata_);
~StandardVmCallbacks() override; ~StandardVmCallbacks() override;
void MemoryRead(VAddr address, void* data, u64 size) override; void MemoryReadUnsafe(VAddr address, void* data, u64 size) override;
void MemoryWrite(VAddr address, const void* data, u64 size) override; void MemoryWriteUnsafe(VAddr address, const void* data, u64 size) override;
u64 HidKeysDown() override; u64 HidKeysDown() override;
void DebugLog(u8 id, u64 value) override; void DebugLog(u8 id, u64 value) override;
void CommandLog(std::string_view data) override; void CommandLog(std::string_view data) override;
private: private:
VAddr SanitizeAddress(VAddr address) const; bool IsAddressInRange(VAddr address) const;
const CheatProcessMetadata& metadata; const CheatProcessMetadata& metadata;
Core::System& system; Core::System& system;

View File

@ -773,7 +773,7 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) {
case 2: case 2:
case 4: case 4:
case 8: case 8:
callbacks->MemoryWrite(dst_address, &dst_value, store_static->bit_width); callbacks->MemoryWriteUnsafe(dst_address, &dst_value, store_static->bit_width);
break; break;
} }
} else if (auto begin_cond = std::get_if<BeginConditionalOpcode>(&cur_opcode.opcode)) { } else if (auto begin_cond = std::get_if<BeginConditionalOpcode>(&cur_opcode.opcode)) {
@ -786,7 +786,7 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) {
case 2: case 2:
case 4: case 4:
case 8: case 8:
callbacks->MemoryRead(src_address, &src_value, begin_cond->bit_width); callbacks->MemoryReadUnsafe(src_address, &src_value, begin_cond->bit_width);
break; break;
} }
// Check against condition. // Check against condition.
@ -857,8 +857,8 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) {
case 2: case 2:
case 4: case 4:
case 8: case 8:
callbacks->MemoryRead(src_address, &registers[ldr_memory->reg_index], callbacks->MemoryReadUnsafe(src_address, &registers[ldr_memory->reg_index],
ldr_memory->bit_width); ldr_memory->bit_width);
break; break;
} }
} else if (auto str_static = std::get_if<StoreStaticToAddressOpcode>(&cur_opcode.opcode)) { } else if (auto str_static = std::get_if<StoreStaticToAddressOpcode>(&cur_opcode.opcode)) {
@ -874,7 +874,7 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) {
case 2: case 2:
case 4: case 4:
case 8: case 8:
callbacks->MemoryWrite(dst_address, &dst_value, str_static->bit_width); callbacks->MemoryWriteUnsafe(dst_address, &dst_value, str_static->bit_width);
break; break;
} }
// Increment register if relevant. // Increment register if relevant.
@ -1032,7 +1032,7 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) {
case 2: case 2:
case 4: case 4:
case 8: case 8:
callbacks->MemoryWrite(dst_address, &dst_value, str_register->bit_width); callbacks->MemoryWriteUnsafe(dst_address, &dst_value, str_register->bit_width);
break; break;
} }
@ -1111,7 +1111,8 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) {
case 2: case 2:
case 4: case 4:
case 8: case 8:
callbacks->MemoryRead(cond_address, &cond_value, begin_reg_cond->bit_width); callbacks->MemoryReadUnsafe(cond_address, &cond_value,
begin_reg_cond->bit_width);
break; break;
} }
} }
@ -1253,7 +1254,7 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) {
case 2: case 2:
case 4: case 4:
case 8: case 8:
callbacks->MemoryRead(val_address, &log_value, debug_log->bit_width); callbacks->MemoryReadUnsafe(val_address, &log_value, debug_log->bit_width);
break; break;
} }
} }

View File

@ -266,8 +266,8 @@ public:
public: public:
virtual ~Callbacks(); virtual ~Callbacks();
virtual void MemoryRead(VAddr address, void* data, u64 size) = 0; virtual void MemoryReadUnsafe(VAddr address, void* data, u64 size) = 0;
virtual void MemoryWrite(VAddr address, const void* data, u64 size) = 0; virtual void MemoryWriteUnsafe(VAddr address, const void* data, u64 size) = 0;
virtual u64 HidKeysDown() = 0; virtual u64 HidKeysDown() = 0;

View File

@ -145,9 +145,8 @@ void ImageTransferProcessor::SetTransferMemoryAddress(Common::ProcessAddress t_m
} }
Core::IrSensor::ImageTransferProcessorState ImageTransferProcessor::GetState( Core::IrSensor::ImageTransferProcessorState ImageTransferProcessor::GetState(
std::vector<u8>& data) const { std::span<u8> data) const {
const auto size = GetDataSize(current_config.trimming_format); const auto size = std::min(GetDataSize(current_config.trimming_format), data.size());
data.resize(size);
system.ApplicationMemory().ReadBlock(transfer_memory, data.data(), size); system.ApplicationMemory().ReadBlock(transfer_memory, data.data(), size);
return processor_state; return processor_state;
} }

View File

@ -3,6 +3,8 @@
#pragma once #pragma once
#include <span>
#include "common/typed_address.h" #include "common/typed_address.h"
#include "hid_core/irsensor/irs_types.h" #include "hid_core/irsensor/irs_types.h"
#include "hid_core/irsensor/processor_base.h" #include "hid_core/irsensor/processor_base.h"
@ -39,7 +41,7 @@ public:
// Transfer memory where the image data will be stored // Transfer memory where the image data will be stored
void SetTransferMemoryAddress(Common::ProcessAddress t_mem); void SetTransferMemoryAddress(Common::ProcessAddress t_mem);
Core::IrSensor::ImageTransferProcessorState GetState(std::vector<u8>& data) const; Core::IrSensor::ImageTransferProcessorState GetState(std::span<u8> data) const;
private: private:
// This is nn::irsensor::ImageTransferProcessorConfig // This is nn::irsensor::ImageTransferProcessorConfig

View File

@ -57,7 +57,7 @@ Result NpadAbstractSixAxisHandler::UpdateSixAxisState() {
Core::HID::NpadIdType npad_id = properties_handler->GetNpadId(); Core::HID::NpadIdType npad_id = properties_handler->GetNpadId();
for (std::size_t i = 0; i < AruidIndexMax; i++) { for (std::size_t i = 0; i < AruidIndexMax; i++) {
auto* data = applet_resource_holder->applet_resource->GetAruidDataByIndex(i); auto* data = applet_resource_holder->applet_resource->GetAruidDataByIndex(i);
if (data->flag.is_assigned) { if (data == nullptr || !data->flag.is_assigned) {
continue; continue;
} }
auto& npad_entry = data->shared_memory_format->npad.npad_entry[NpadIdTypeToIndex(npad_id)]; auto& npad_entry = data->shared_memory_format->npad.npad_entry[NpadIdTypeToIndex(npad_id)];

View File

@ -131,7 +131,7 @@ void NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t c
auto* data = applet_resource_holder.applet_resource->GetAruidDataByIndex(aruid_index); auto* data = applet_resource_holder.applet_resource->GetAruidDataByIndex(aruid_index);
if (!data->flag.is_assigned) { if (data == nullptr || !data->flag.is_assigned) {
continue; continue;
} }
@ -463,13 +463,13 @@ void NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
std::scoped_lock lock{*applet_resource_holder.shared_mutex}; std::scoped_lock lock{*applet_resource_holder.shared_mutex};
for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; ++aruid_index) { for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; ++aruid_index) {
const auto* data = applet_resource_holder.applet_resource->GetAruidDataByIndex(aruid_index); const auto* data = applet_resource_holder.applet_resource->GetAruidDataByIndex(aruid_index);
const auto aruid = data->aruid;
if (!data->flag.is_assigned) { if (data == nullptr || !data->flag.is_assigned) {
continue; continue;
} }
bool is_set{}; bool is_set{};
const auto aruid = data->aruid;
npad_resource.IsSupportedNpadStyleSet(is_set, aruid); npad_resource.IsSupportedNpadStyleSet(is_set, aruid);
// Wait until style is defined // Wait until style is defined
if (!is_set) { if (!is_set) {

View File

@ -28,142 +28,148 @@ void SixAxis::OnRelease() {}
void SixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) { void SixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
std::scoped_lock shared_lock{*shared_mutex}; std::scoped_lock shared_lock{*shared_mutex};
const u64 aruid = applet_resource->GetActiveAruid();
auto* data = applet_resource->GetAruidData(aruid);
if (data == nullptr || !data->flag.is_assigned) { for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; ++aruid_index) {
return; const auto* data = applet_resource->GetAruidDataByIndex(aruid_index);
}
if (!IsControllerActivated()) { if (data == nullptr || !data->flag.is_assigned) {
return;
}
for (std::size_t i = 0; i < controller_data.size(); ++i) {
NpadSharedMemoryEntry& shared_memory = data->shared_memory_format->npad.npad_entry[i];
auto& controller = controller_data[i];
const auto& controller_type = controller.device->GetNpadStyleIndex();
if (controller_type == Core::HID::NpadStyleIndex::None ||
!controller.device->IsConnected()) {
continue; continue;
} }
const auto& motion_state = controller.device->GetMotions(); if (!IsControllerActivated()) {
auto& sixaxis_fullkey_state = controller.sixaxis_fullkey_state; return;
auto& sixaxis_handheld_state = controller.sixaxis_handheld_state;
auto& sixaxis_dual_left_state = controller.sixaxis_dual_left_state;
auto& sixaxis_dual_right_state = controller.sixaxis_dual_right_state;
auto& sixaxis_left_lifo_state = controller.sixaxis_left_lifo_state;
auto& sixaxis_right_lifo_state = controller.sixaxis_right_lifo_state;
auto& sixaxis_fullkey_lifo = shared_memory.internal_state.sixaxis_fullkey_lifo;
auto& sixaxis_handheld_lifo = shared_memory.internal_state.sixaxis_handheld_lifo;
auto& sixaxis_dual_left_lifo = shared_memory.internal_state.sixaxis_dual_left_lifo;
auto& sixaxis_dual_right_lifo = shared_memory.internal_state.sixaxis_dual_right_lifo;
auto& sixaxis_left_lifo = shared_memory.internal_state.sixaxis_left_lifo;
auto& sixaxis_right_lifo = shared_memory.internal_state.sixaxis_right_lifo;
// Clear previous state
sixaxis_fullkey_state = {};
sixaxis_handheld_state = {};
sixaxis_dual_left_state = {};
sixaxis_dual_right_state = {};
sixaxis_left_lifo_state = {};
sixaxis_right_lifo_state = {};
if (controller.sixaxis_sensor_enabled && Settings::values.motion_enabled.GetValue()) {
controller.sixaxis_at_rest = true;
for (std::size_t e = 0; e < motion_state.size(); ++e) {
controller.sixaxis_at_rest =
controller.sixaxis_at_rest && motion_state[e].is_at_rest;
}
} }
const auto set_motion_state = [&](Core::HID::SixAxisSensorState& state, for (std::size_t i = 0; i < controller_data.size(); ++i) {
const Core::HID::ControllerMotion& hid_state) { NpadSharedMemoryEntry& shared_memory = data->shared_memory_format->npad.npad_entry[i];
using namespace std::literals::chrono_literals; auto& controller = controller_data[i];
static constexpr Core::HID::SixAxisSensorState default_motion_state = { const auto& controller_type = controller.device->GetNpadStyleIndex();
.delta_time = std::chrono::nanoseconds(5ms).count(),
.accel = {0, 0, -1.0f}, if (!data->flag.enable_six_axis_sensor) {
.orientation = continue;
{ }
Common::Vec3f{1.0f, 0, 0},
Common::Vec3f{0, 1.0f, 0}, if (controller_type == Core::HID::NpadStyleIndex::None ||
Common::Vec3f{0, 0, 1.0f}, !controller.device->IsConnected()) {
}, continue;
.attribute = {1}, }
const auto& motion_state = controller.device->GetMotions();
auto& sixaxis_fullkey_state = controller.sixaxis_fullkey_state;
auto& sixaxis_handheld_state = controller.sixaxis_handheld_state;
auto& sixaxis_dual_left_state = controller.sixaxis_dual_left_state;
auto& sixaxis_dual_right_state = controller.sixaxis_dual_right_state;
auto& sixaxis_left_lifo_state = controller.sixaxis_left_lifo_state;
auto& sixaxis_right_lifo_state = controller.sixaxis_right_lifo_state;
auto& sixaxis_fullkey_lifo = shared_memory.internal_state.sixaxis_fullkey_lifo;
auto& sixaxis_handheld_lifo = shared_memory.internal_state.sixaxis_handheld_lifo;
auto& sixaxis_dual_left_lifo = shared_memory.internal_state.sixaxis_dual_left_lifo;
auto& sixaxis_dual_right_lifo = shared_memory.internal_state.sixaxis_dual_right_lifo;
auto& sixaxis_left_lifo = shared_memory.internal_state.sixaxis_left_lifo;
auto& sixaxis_right_lifo = shared_memory.internal_state.sixaxis_right_lifo;
// Clear previous state
sixaxis_fullkey_state = {};
sixaxis_handheld_state = {};
sixaxis_dual_left_state = {};
sixaxis_dual_right_state = {};
sixaxis_left_lifo_state = {};
sixaxis_right_lifo_state = {};
if (controller.sixaxis_sensor_enabled && Settings::values.motion_enabled.GetValue()) {
controller.sixaxis_at_rest = true;
for (std::size_t e = 0; e < motion_state.size(); ++e) {
controller.sixaxis_at_rest =
controller.sixaxis_at_rest && motion_state[e].is_at_rest;
}
}
const auto set_motion_state = [&](Core::HID::SixAxisSensorState& state,
const Core::HID::ControllerMotion& hid_state) {
using namespace std::literals::chrono_literals;
static constexpr Core::HID::SixAxisSensorState default_motion_state = {
.delta_time = std::chrono::nanoseconds(5ms).count(),
.accel = {0, 0, -1.0f},
.orientation =
{
Common::Vec3f{1.0f, 0, 0},
Common::Vec3f{0, 1.0f, 0},
Common::Vec3f{0, 0, 1.0f},
},
.attribute = {1},
};
if (!controller.sixaxis_sensor_enabled) {
state = default_motion_state;
return;
}
if (!Settings::values.motion_enabled.GetValue()) {
state = default_motion_state;
return;
}
state.attribute.is_connected.Assign(1);
state.delta_time = std::chrono::nanoseconds(5ms).count();
state.accel = hid_state.accel;
state.gyro = hid_state.gyro;
state.rotation = hid_state.rotation;
state.orientation = hid_state.orientation;
}; };
if (!controller.sixaxis_sensor_enabled) {
state = default_motion_state; switch (controller_type) {
return; case Core::HID::NpadStyleIndex::None:
ASSERT(false);
break;
case Core::HID::NpadStyleIndex::Fullkey:
set_motion_state(sixaxis_fullkey_state, motion_state[0]);
break;
case Core::HID::NpadStyleIndex::Handheld:
set_motion_state(sixaxis_handheld_state, motion_state[0]);
break;
case Core::HID::NpadStyleIndex::JoyconDual:
set_motion_state(sixaxis_dual_left_state, motion_state[0]);
set_motion_state(sixaxis_dual_right_state, motion_state[1]);
break;
case Core::HID::NpadStyleIndex::JoyconLeft:
set_motion_state(sixaxis_left_lifo_state, motion_state[0]);
break;
case Core::HID::NpadStyleIndex::JoyconRight:
set_motion_state(sixaxis_right_lifo_state, motion_state[1]);
break;
case Core::HID::NpadStyleIndex::Pokeball:
using namespace std::literals::chrono_literals;
set_motion_state(sixaxis_fullkey_state, motion_state[0]);
sixaxis_fullkey_state.delta_time = std::chrono::nanoseconds(15ms).count();
break;
default:
break;
} }
if (!Settings::values.motion_enabled.GetValue()) {
state = default_motion_state; sixaxis_fullkey_state.sampling_number =
return; sixaxis_fullkey_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1;
sixaxis_handheld_state.sampling_number =
sixaxis_handheld_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1;
sixaxis_dual_left_state.sampling_number =
sixaxis_dual_left_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1;
sixaxis_dual_right_state.sampling_number =
sixaxis_dual_right_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1;
sixaxis_left_lifo_state.sampling_number =
sixaxis_left_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1;
sixaxis_right_lifo_state.sampling_number =
sixaxis_right_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1;
if (IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) {
// This buffer only is updated on handheld on HW
sixaxis_handheld_lifo.lifo.WriteNextEntry(sixaxis_handheld_state);
} else {
// Handheld doesn't update this buffer on HW
sixaxis_fullkey_lifo.lifo.WriteNextEntry(sixaxis_fullkey_state);
} }
state.attribute.is_connected.Assign(1);
state.delta_time = std::chrono::nanoseconds(5ms).count();
state.accel = hid_state.accel;
state.gyro = hid_state.gyro;
state.rotation = hid_state.rotation;
state.orientation = hid_state.orientation;
};
switch (controller_type) { sixaxis_dual_left_lifo.lifo.WriteNextEntry(sixaxis_dual_left_state);
case Core::HID::NpadStyleIndex::None: sixaxis_dual_right_lifo.lifo.WriteNextEntry(sixaxis_dual_right_state);
ASSERT(false); sixaxis_left_lifo.lifo.WriteNextEntry(sixaxis_left_lifo_state);
break; sixaxis_right_lifo.lifo.WriteNextEntry(sixaxis_right_lifo_state);
case Core::HID::NpadStyleIndex::Fullkey:
set_motion_state(sixaxis_fullkey_state, motion_state[0]);
break;
case Core::HID::NpadStyleIndex::Handheld:
set_motion_state(sixaxis_handheld_state, motion_state[0]);
break;
case Core::HID::NpadStyleIndex::JoyconDual:
set_motion_state(sixaxis_dual_left_state, motion_state[0]);
set_motion_state(sixaxis_dual_right_state, motion_state[1]);
break;
case Core::HID::NpadStyleIndex::JoyconLeft:
set_motion_state(sixaxis_left_lifo_state, motion_state[0]);
break;
case Core::HID::NpadStyleIndex::JoyconRight:
set_motion_state(sixaxis_right_lifo_state, motion_state[1]);
break;
case Core::HID::NpadStyleIndex::Pokeball:
using namespace std::literals::chrono_literals;
set_motion_state(sixaxis_fullkey_state, motion_state[0]);
sixaxis_fullkey_state.delta_time = std::chrono::nanoseconds(15ms).count();
break;
default:
break;
} }
sixaxis_fullkey_state.sampling_number =
sixaxis_fullkey_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1;
sixaxis_handheld_state.sampling_number =
sixaxis_handheld_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1;
sixaxis_dual_left_state.sampling_number =
sixaxis_dual_left_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1;
sixaxis_dual_right_state.sampling_number =
sixaxis_dual_right_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1;
sixaxis_left_lifo_state.sampling_number =
sixaxis_left_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1;
sixaxis_right_lifo_state.sampling_number =
sixaxis_right_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1;
if (IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) {
// This buffer only is updated on handheld on HW
sixaxis_handheld_lifo.lifo.WriteNextEntry(sixaxis_handheld_state);
} else {
// Handheld doesn't update this buffer on HW
sixaxis_fullkey_lifo.lifo.WriteNextEntry(sixaxis_fullkey_state);
}
sixaxis_dual_left_lifo.lifo.WriteNextEntry(sixaxis_dual_left_state);
sixaxis_dual_right_lifo.lifo.WriteNextEntry(sixaxis_dual_right_state);
sixaxis_left_lifo.lifo.WriteNextEntry(sixaxis_left_lifo_state);
sixaxis_right_lifo.lifo.WriteNextEntry(sixaxis_right_lifo_state);
} }
} }

View File

@ -63,7 +63,7 @@ Result TouchResource::ActivateTouch(u64 aruid) {
auto* applet_data = applet_resource->GetAruidDataByIndex(aruid_index); auto* applet_data = applet_resource->GetAruidDataByIndex(aruid_index);
TouchAruidData& touch_data = aruid_data[aruid_index]; TouchAruidData& touch_data = aruid_data[aruid_index];
if (!applet_data->flag.is_assigned) { if (applet_data == nullptr || !applet_data->flag.is_assigned) {
touch_data = {}; touch_data = {};
continue; continue;
} }
@ -124,7 +124,7 @@ Result TouchResource::ActivateGesture(u64 aruid, u32 basic_gesture_id) {
auto* applet_data = applet_resource->GetAruidDataByIndex(aruid_index); auto* applet_data = applet_resource->GetAruidDataByIndex(aruid_index);
TouchAruidData& touch_data = aruid_data[aruid_index]; TouchAruidData& touch_data = aruid_data[aruid_index];
if (!applet_data->flag.is_assigned) { if (applet_data == nullptr || !applet_data->flag.is_assigned) {
touch_data = {}; touch_data = {};
continue; continue;
} }
@ -324,7 +324,7 @@ Result TouchResource::SetTouchScreenConfiguration(
const auto* applet_data = applet_resource->GetAruidDataByIndex(aruid_index); const auto* applet_data = applet_resource->GetAruidDataByIndex(aruid_index);
TouchAruidData& data = aruid_data[aruid_index]; TouchAruidData& data = aruid_data[aruid_index];
if (!applet_data->flag.is_assigned) { if (applet_data == nullptr || !applet_data->flag.is_assigned) {
continue; continue;
} }
if (aruid != data.aruid) { if (aruid != data.aruid) {
@ -344,7 +344,7 @@ Result TouchResource::GetTouchScreenConfiguration(
const auto* applet_data = applet_resource->GetAruidDataByIndex(aruid_index); const auto* applet_data = applet_resource->GetAruidDataByIndex(aruid_index);
const TouchAruidData& data = aruid_data[aruid_index]; const TouchAruidData& data = aruid_data[aruid_index];
if (!applet_data->flag.is_assigned) { if (applet_data == nullptr || !applet_data->flag.is_assigned) {
continue; continue;
} }
if (aruid != data.aruid) { if (aruid != data.aruid) {

View File

@ -13,102 +13,20 @@ Scheduler::Scheduler(GPU& gpu_) : gpu{gpu_} {}
Scheduler::~Scheduler() = default; Scheduler::~Scheduler() = default;
void Scheduler::Init() {
master_control = Common::Fiber::ThreadToFiber();
}
void Scheduler::Resume() {
bool nothing_pending;
do {
nothing_pending = true;
current_fifo = nullptr;
{
std::unique_lock lk(scheduling_guard);
size_t num_iters = gpfifos.size();
for (size_t i = 0; i < num_iters; i++) {
size_t current_id = (current_fifo_rotation_id + i) % gpfifos.size();
auto& fifo = gpfifos[current_id];
if (!fifo.is_active) {
continue;
}
std::scoped_lock lk2(fifo.guard);
if (!fifo.pending_work.empty() || fifo.working.load(std::memory_order_acquire)) {
current_fifo = &fifo;
current_fifo_rotation_id = current_id;
nothing_pending = false;
break;
}
}
}
if (current_fifo) {
Common::Fiber::YieldTo(master_control, *current_fifo->context);
current_fifo = nullptr;
}
} while (!nothing_pending);
}
void Scheduler::Yield() {
ASSERT(current_fifo != nullptr);
Common::Fiber::YieldTo(current_fifo->context, *master_control);
gpu.BindChannel(current_fifo->bind_id);
}
void Scheduler::Push(s32 channel, CommandList&& entries) { void Scheduler::Push(s32 channel, CommandList&& entries) {
std::unique_lock lk(scheduling_guard); std::unique_lock lk(scheduling_guard);
auto it = channel_gpfifo_ids.find(channel); auto it = channels.find(channel);
ASSERT(it != channel_gpfifo_ids.end()); ASSERT(it != channels.end());
auto gpfifo_id = it->second; auto channel_state = it->second;
auto& fifo = gpfifos[gpfifo_id]; gpu.BindChannel(channel_state->bind_id);
{ channel_state->dma_pusher->Push(std::move(entries));
std::scoped_lock lk2(fifo.guard); channel_state->dma_pusher->DispatchCalls();
fifo.pending_work.emplace_back(std::move(entries));
}
}
void Scheduler::ChannelLoop(size_t gpfifo_id, s32 channel_id) {
gpu.BindChannel(channel_id);
auto& fifo = gpfifos[gpfifo_id];
while (true) {
auto* channel_state = channels[channel_id].get();
fifo.guard.lock();
while (!fifo.pending_work.empty()) {
{
fifo.working.store(true, std::memory_order_release);
CommandList&& entries = std::move(fifo.pending_work.front());
channel_state->dma_pusher->Push(std::move(entries));
fifo.pending_work.pop_front();
}
fifo.guard.unlock();
channel_state->dma_pusher->DispatchCalls();
fifo.guard.lock();
}
fifo.working.store(false, std::memory_order_relaxed);
fifo.guard.unlock();
Common::Fiber::YieldTo(fifo.context, *master_control);
gpu.BindChannel(channel_id);
}
} }
void Scheduler::DeclareChannel(std::shared_ptr<ChannelState> new_channel) { void Scheduler::DeclareChannel(std::shared_ptr<ChannelState> new_channel) {
s32 channel = new_channel->bind_id; s32 channel = new_channel->bind_id;
std::unique_lock lk(scheduling_guard); std::unique_lock lk(scheduling_guard);
channels.emplace(channel, new_channel); channels.emplace(channel, new_channel);
size_t new_fifo_id;
if (!free_fifos.empty()) {
new_fifo_id = free_fifos.front();
free_fifos.pop_front();
} else {
new_fifo_id = gpfifos.size();
gpfifos.emplace_back();
}
auto& new_fifo = gpfifos[new_fifo_id];
channel_gpfifo_ids[channel] = new_fifo_id;
new_fifo.is_active = true;
new_fifo.bind_id = channel;
new_fifo.pending_work.clear();
std::function<void()> callback = std::bind(&Scheduler::ChannelLoop, this, new_fifo_id, channel);
new_fifo.context = std::make_shared<Common::Fiber>(std::move(callback));
} }
} // namespace Tegra::Control } // namespace Tegra::Control

View File

@ -3,13 +3,10 @@
#pragma once #pragma once
#include <atomic>
#include <deque>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <unordered_map> #include <unordered_map>
#include "common/fiber.h"
#include "video_core/dma_pusher.h" #include "video_core/dma_pusher.h"
namespace Tegra { namespace Tegra {
@ -25,36 +22,14 @@ public:
explicit Scheduler(GPU& gpu_); explicit Scheduler(GPU& gpu_);
~Scheduler(); ~Scheduler();
void Init();
void Resume();
void Yield();
void Push(s32 channel, CommandList&& entries); void Push(s32 channel, CommandList&& entries);
void DeclareChannel(std::shared_ptr<ChannelState> new_channel); void DeclareChannel(std::shared_ptr<ChannelState> new_channel);
private: private:
void ChannelLoop(size_t gpfifo_id, s32 channel_id);
std::unordered_map<s32, std::shared_ptr<ChannelState>> channels; std::unordered_map<s32, std::shared_ptr<ChannelState>> channels;
std::unordered_map<s32, size_t> channel_gpfifo_ids;
std::mutex scheduling_guard; std::mutex scheduling_guard;
std::shared_ptr<Common::Fiber> master_control;
struct GPFifoContext {
bool is_active;
std::shared_ptr<Common::Fiber> context;
std::deque<CommandList> pending_work;
std::atomic<bool> working{};
std::mutex guard;
s32 bind_id;
};
std::deque<GPFifoContext> gpfifos;
std::deque<size_t> free_fifos;
GPU& gpu; GPU& gpu;
size_t current_fifo_rotation_id{};
GPFifoContext* current_fifo{};
}; };
} // namespace Control } // namespace Control

View File

@ -6,7 +6,6 @@
#include "common/settings.h" #include "common/settings.h"
#include "core/core.h" #include "core/core.h"
#include "video_core/control/channel_state.h" #include "video_core/control/channel_state.h"
#include "video_core/control/scheduler.h"
#include "video_core/dma_pusher.h" #include "video_core/dma_pusher.h"
#include "video_core/engines/fermi_2d.h" #include "video_core/engines/fermi_2d.h"
#include "video_core/engines/kepler_compute.h" #include "video_core/engines/kepler_compute.h"
@ -15,8 +14,6 @@
#include "video_core/engines/maxwell_dma.h" #include "video_core/engines/maxwell_dma.h"
#include "video_core/engines/puller.h" #include "video_core/engines/puller.h"
#include "video_core/gpu.h" #include "video_core/gpu.h"
#include "video_core/host1x/host1x.h"
#include "video_core/host1x/syncpoint_manager.h"
#include "video_core/memory_manager.h" #include "video_core/memory_manager.h"
#include "video_core/rasterizer_interface.h" #include "video_core/rasterizer_interface.h"
@ -63,14 +60,11 @@ void Puller::ProcessBindMethod(const MethodCall& method_call) {
} }
void Puller::ProcessFenceActionMethod() { void Puller::ProcessFenceActionMethod() {
auto& syncpoint_manager = gpu.Host1x().GetSyncpointManager();
switch (regs.fence_action.op) { switch (regs.fence_action.op) {
case Puller::FenceOperation::Acquire: case Puller::FenceOperation::Acquire:
while (regs.fence_value > // UNIMPLEMENTED_MSG("Channel Scheduling pending.");
syncpoint_manager.GetGuestSyncpointValue(regs.fence_action.syncpoint_id)) { // WaitFence(regs.fence_action.syncpoint_id, regs.fence_value);
rasterizer->ReleaseFences(); rasterizer->ReleaseFences();
gpu.Scheduler().Yield();
}
break; break;
case Puller::FenceOperation::Increment: case Puller::FenceOperation::Increment:
rasterizer->SignalSyncPoint(regs.fence_action.syncpoint_id); rasterizer->SignalSyncPoint(regs.fence_action.syncpoint_id);

View File

@ -387,14 +387,6 @@ std::shared_ptr<Control::ChannelState> GPU::AllocateChannel() {
return impl->AllocateChannel(); return impl->AllocateChannel();
} }
Tegra::Control::Scheduler& GPU::Scheduler() {
return *impl->scheduler;
}
const Tegra::Control::Scheduler& GPU::Scheduler() const {
return *impl->scheduler;
}
void GPU::InitChannel(Control::ChannelState& to_init) { void GPU::InitChannel(Control::ChannelState& to_init) {
impl->InitChannel(to_init); impl->InitChannel(to_init);
} }

View File

@ -124,8 +124,7 @@ class KeplerCompute;
namespace Control { namespace Control {
struct ChannelState; struct ChannelState;
class Scheduler; }
} // namespace Control
namespace Host1x { namespace Host1x {
class Host1x; class Host1x;
@ -205,12 +204,6 @@ public:
/// Returns a const reference to the shader notifier. /// Returns a const reference to the shader notifier.
[[nodiscard]] const VideoCore::ShaderNotify& ShaderNotify() const; [[nodiscard]] const VideoCore::ShaderNotify& ShaderNotify() const;
/// Returns GPU Channel Scheduler.
[[nodiscard]] Tegra::Control::Scheduler& Scheduler();
/// Returns GPU Channel Scheduler.
[[nodiscard]] const Tegra::Control::Scheduler& Scheduler() const;
[[nodiscard]] u64 GetTicks() const; [[nodiscard]] u64 GetTicks() const;
[[nodiscard]] bool IsAsync() const; [[nodiscard]] bool IsAsync() const;

View File

@ -34,15 +34,13 @@ static void RunThread(std::stop_token stop_token, Core::System& system,
CommandDataContainer next; CommandDataContainer next;
scheduler.Init();
while (!stop_token.stop_requested()) { while (!stop_token.stop_requested()) {
state.queue.PopWait(next, stop_token); state.queue.PopWait(next, stop_token);
if (stop_token.stop_requested()) { if (stop_token.stop_requested()) {
break; break;
} }
if (std::holds_alternative<SubmitListCommand>(next.data)) { if (auto* submit_list = std::get_if<SubmitListCommand>(&next.data)) {
scheduler.Resume(); scheduler.Push(submit_list->channel, std::move(submit_list->entries));
} else if (std::holds_alternative<GPUTickCommand>(next.data)) { } else if (std::holds_alternative<GPUTickCommand>(next.data)) {
system.GPU().TickWork(); system.GPU().TickWork();
} else if (const auto* flush = std::get_if<FlushRegionCommand>(&next.data)) { } else if (const auto* flush = std::get_if<FlushRegionCommand>(&next.data)) {
@ -69,16 +67,14 @@ ThreadManager::~ThreadManager() = default;
void ThreadManager::StartThread(VideoCore::RendererBase& renderer, void ThreadManager::StartThread(VideoCore::RendererBase& renderer,
Core::Frontend::GraphicsContext& context, Core::Frontend::GraphicsContext& context,
Tegra::Control::Scheduler& scheduler_) { Tegra::Control::Scheduler& scheduler) {
rasterizer = renderer.ReadRasterizer(); rasterizer = renderer.ReadRasterizer();
scheduler = &scheduler_;
thread = std::jthread(RunThread, std::ref(system), std::ref(renderer), std::ref(context), thread = std::jthread(RunThread, std::ref(system), std::ref(renderer), std::ref(context),
std::ref(scheduler_), std::ref(state)); std::ref(scheduler), std::ref(state));
} }
void ThreadManager::SubmitList(s32 channel, Tegra::CommandList&& entries) { void ThreadManager::SubmitList(s32 channel, Tegra::CommandList&& entries) {
scheduler->Push(channel, std::move(entries)); PushCommand(SubmitListCommand(channel, std::move(entries)));
PushCommand(SubmitListCommand());
} }
void ThreadManager::FlushRegion(DAddr addr, u64 size) { void ThreadManager::FlushRegion(DAddr addr, u64 size) {

View File

@ -36,7 +36,13 @@ class RendererBase;
namespace VideoCommon::GPUThread { namespace VideoCommon::GPUThread {
/// Command to signal to the GPU thread that a command list is ready for processing /// Command to signal to the GPU thread that a command list is ready for processing
struct SubmitListCommand final {}; struct SubmitListCommand final {
explicit SubmitListCommand(s32 channel_, Tegra::CommandList&& entries_)
: channel{channel_}, entries{std::move(entries_)} {}
s32 channel;
Tegra::CommandList entries;
};
/// Command to signal to the GPU thread to flush a region /// Command to signal to the GPU thread to flush a region
struct FlushRegionCommand final { struct FlushRegionCommand final {
@ -118,7 +124,6 @@ public:
private: private:
/// Pushes a command to be executed by the GPU thread /// Pushes a command to be executed by the GPU thread
u64 PushCommand(CommandData&& command_data, bool block = false); u64 PushCommand(CommandData&& command_data, bool block = false);
Tegra::Control::Scheduler* scheduler;
Core::System& system; Core::System& system;
const bool is_async; const bool is_async;

View File

@ -10,7 +10,7 @@ namespace Tegra::Host1x {
Host1x::Host1x(Core::System& system_) Host1x::Host1x(Core::System& system_)
: system{system_}, syncpoint_manager{}, : system{system_}, syncpoint_manager{},
memory_manager(system.DeviceMemory()), gmmu_manager{system, memory_manager, 32, 12}, memory_manager(system.DeviceMemory()), gmmu_manager{system, memory_manager, 32, 0, 12},
allocator{std::make_unique<Common::FlatAllocator<u32, 0, 32>>(1 << 12)} {} allocator{std::make_unique<Common::FlatAllocator<u32, 0, 32>>(1 << 12)} {}
Host1x::~Host1x() = default; Host1x::~Host1x() = default;

View File

@ -22,11 +22,12 @@ using Tegra::Memory::GuestMemoryFlags;
std::atomic<size_t> MemoryManager::unique_identifier_generator{}; std::atomic<size_t> MemoryManager::unique_identifier_generator{};
MemoryManager::MemoryManager(Core::System& system_, MaxwellDeviceMemoryManager& memory_, MemoryManager::MemoryManager(Core::System& system_, MaxwellDeviceMemoryManager& memory_,
u64 address_space_bits_, u64 big_page_bits_, u64 page_bits_) u64 address_space_bits_, GPUVAddr split_address_, u64 big_page_bits_,
u64 page_bits_)
: system{system_}, memory{memory_}, address_space_bits{address_space_bits_}, : system{system_}, memory{memory_}, address_space_bits{address_space_bits_},
page_bits{page_bits_}, big_page_bits{big_page_bits_}, entries{}, big_entries{}, split_address{split_address_}, page_bits{page_bits_}, big_page_bits{big_page_bits_},
page_table{address_space_bits, address_space_bits + page_bits - 38, entries{}, big_entries{}, page_table{address_space_bits, address_space_bits + page_bits - 38,
page_bits != big_page_bits ? page_bits : 0}, page_bits != big_page_bits ? page_bits : 0},
kind_map{PTEKind::INVALID}, unique_identifier{unique_identifier_generator.fetch_add( kind_map{PTEKind::INVALID}, unique_identifier{unique_identifier_generator.fetch_add(
1, std::memory_order_acq_rel)}, 1, std::memory_order_acq_rel)},
accumulator{std::make_unique<VideoCommon::InvalidationAccumulator>()} { accumulator{std::make_unique<VideoCommon::InvalidationAccumulator>()} {
@ -48,10 +49,10 @@ MemoryManager::MemoryManager(Core::System& system_, MaxwellDeviceMemoryManager&
entries.resize(page_table_size / 32, 0); entries.resize(page_table_size / 32, 0);
} }
MemoryManager::MemoryManager(Core::System& system_, u64 address_space_bits_, u64 big_page_bits_, MemoryManager::MemoryManager(Core::System& system_, u64 address_space_bits_,
u64 page_bits_) GPUVAddr split_address_, u64 big_page_bits_, u64 page_bits_)
: MemoryManager(system_, system_.Host1x().MemoryManager(), address_space_bits_, big_page_bits_, : MemoryManager(system_, system_.Host1x().MemoryManager(), address_space_bits_, split_address_,
page_bits_) {} big_page_bits_, page_bits_) {}
MemoryManager::~MemoryManager() = default; MemoryManager::~MemoryManager() = default;

View File

@ -36,10 +36,11 @@ namespace Tegra {
class MemoryManager final { class MemoryManager final {
public: public:
explicit MemoryManager(Core::System& system_, u64 address_space_bits_ = 40, explicit MemoryManager(Core::System& system_, u64 address_space_bits_ = 40,
u64 big_page_bits_ = 16, u64 page_bits_ = 12); GPUVAddr split_address = 1ULL << 34, u64 big_page_bits_ = 16,
explicit MemoryManager(Core::System& system_, MaxwellDeviceMemoryManager& memory_,
u64 address_space_bits_ = 40, u64 big_page_bits_ = 16,
u64 page_bits_ = 12); u64 page_bits_ = 12);
explicit MemoryManager(Core::System& system_, MaxwellDeviceMemoryManager& memory_,
u64 address_space_bits_ = 40, GPUVAddr split_address = 1ULL << 34,
u64 big_page_bits_ = 16, u64 page_bits_ = 12);
~MemoryManager(); ~MemoryManager();
static constexpr bool HAS_FLUSH_INVALIDATION = true; static constexpr bool HAS_FLUSH_INVALIDATION = true;
@ -194,6 +195,7 @@ private:
MaxwellDeviceMemoryManager& memory; MaxwellDeviceMemoryManager& memory;
const u64 address_space_bits; const u64 address_space_bits;
GPUVAddr split_address;
const u64 page_bits; const u64 page_bits;
u64 address_space_size; u64 address_space_size;
u64 page_size; u64 page_size;

View File

@ -73,8 +73,11 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st
ui->tabWidget->addTab(graphics_advanced_tab.get(), tr("Adv. Graphics")); ui->tabWidget->addTab(graphics_advanced_tab.get(), tr("Adv. Graphics"));
ui->tabWidget->addTab(audio_tab.get(), tr("Audio")); ui->tabWidget->addTab(audio_tab.get(), tr("Audio"));
ui->tabWidget->addTab(input_tab.get(), tr("Input Profiles")); ui->tabWidget->addTab(input_tab.get(), tr("Input Profiles"));
// Only show Linux tab on Unix // Only show Linux tab on Unix
linux_tab->setVisible(false);
#ifdef __unix__ #ifdef __unix__
linux_tab->setVisible(true);
ui->tabWidget->addTab(linux_tab.get(), tr("Linux")); ui->tabWidget->addTab(linux_tab.get(), tr("Linux"));
#endif #endif