diff options
| author | kraibse <33869366+kraibse@users.noreply.github.com> | 2026-11-01 12:19:37 +0100 |
|---|---|---|
| committer | kraibse <33869366+kraibse@users.noreply.github.com> | 2026-11-02 00:11:26 +0100 |
| commit | 3fe4f1b189f9e57c1e18f2dc3fad2815943edebb (patch) | |
| tree | 6b3500e14ba0d67bec438c1e4f105461ef070d40 /src/core/hle | |
| parent | 16967eb30e97937f4ac3b200e681adde70089161 (diff) | |
nx2: answer nx2:camera commands without a log line per call
GameChat polls nx2:camera command 29 every frame; it was logged as an
unimplemented function (Critical plus Warning), 40,000 times in one
session. Answer 3, 21 and 29 with the same empty success, logging each
once.
Assisted-by: Claude Sonnet 5.5 (code)
(cherry picked from commit 0b7b562898bba137934420b366e3980476ee221f)
Diffstat (limited to 'src/core/hle')
| -rw-r--r-- | src/core/hle/service/nx2_gsv.h | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/src/core/hle/service/nx2_gsv.h b/src/core/hle/service/nx2_gsv.h index 9d0fd597b2..f4e026a6db 100644 --- a/src/core/hle/service/nx2_gsv.h +++ b/src/core/hle/service/nx2_gsv.h @@ -1511,6 +1511,34 @@ private: std::map<u32, Kernel::KEvent*> m_events; }; +// nn::camera::sdk camera context (gsv 602). GameChat builds its local camera video storage from it +// and polls it every frame. Nothing about the commands is known beyond the arguments seen (3 and +// 21 take the camera name "Default", 29 a u32 0x180 = 384, the width of the 384x216 camera images), +// and the game runs on an empty success, so they answer that without a log line per call. +class INx2CameraSession final : public ServiceFramework<INx2CameraSession> { +public: + explicit INx2CameraSession(Core::System& system_) : ServiceFramework{system_, "nx2:camera"} { + RegisterHandlersTipc({ + {3, &INx2CameraSession::Stub, "Unknown3 (camera name \"Default\")"}, + {21, &INx2CameraSession::Stub, "Unknown21 (camera name \"Default\")"}, + {29, &INx2CameraSession::Stub, "Unknown29 (u32 0x180, polled every frame)"}, + }); + } + +private: + void Stub(HLERequestContext& ctx) { + const u32 command = ctx.GetCommand(); + if (m_logged.insert(command).second) { + LOG_WARNING(Service, "(STUBBED) nx2:camera TIPC {} [2]={:#x} [3]={:#x}, returning success", + command, ctx.CommandBuffer()[2], ctx.CommandBuffer()[3]); + } + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + std::set<u32> m_logged; +}; + // Video decoder output images (nn::codec image pools, gsv 991/911/961). The preference // (MakeDecodeImagePreference) holds an output layout code at word 1 and (width - 1) | // (height - 1) << 16 at word 2. Codes come in pairs, one per CodecMode: 1/4 NV12 (format 3, what @@ -2915,13 +2943,11 @@ private: // nn::camera::sdk::CreateCameraContext sends 601() then 602(u64 1), which returns the camera // context session (handle at word 3, result at word 4). Auto-stubbed, 602 had no handle, the - // SDK sent 603 (destroy) and title 1 (1.8.0) aborted with 2034-0000. Its commands fall - // through to the nx2 auto stub. + // SDK sent 603 (destroy) and title 1 (1.8.0) aborted with 2034-0000. Its commands are + // answered by INx2CameraSession. void OpenCameraSession(HLERequestContext& ctx) { LOG_WARNING(Service, "(STUBBED) nx2:gsv TIPC 602, returning a nx2:camera session"); - ReturnRawSession(system, ctx, - std::make_shared<INx2StubInterface>( - system, INx2StubInterface::InternName("nx2:camera"))); + ReturnRawSession(system, ctx, std::make_shared<INx2CameraSession>(system)); } // nn::chat::gsv::Initialize sends 1201 then 1202, the same pair as 901/902 and 1001/1002. |
