summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/audio_core/audio_renderer.cpp3
-rw-r--r--src/audio_core/audio_renderer.h1
-rw-r--r--src/common/CMakeLists.txt1
-rw-r--r--src/common/div_ceil.h26
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp11
-rw-r--r--src/core/core.cpp41
-rw-r--r--src/core/cpu_manager.cpp1
-rw-r--r--src/core/file_sys/savedata_factory.cpp18
-rw-r--r--src/core/file_sys/savedata_factory.h11
-rw-r--r--src/core/frontend/emu_window.h4
-rw-r--r--src/core/frontend/input.h9
-rw-r--r--src/core/gdbstub/gdbstub.cpp1397
-rw-r--r--src/core/gdbstub/gdbstub.h114
-rw-r--r--src/core/hle/service/acc/acc.cpp88
-rw-r--r--src/core/hle/service/acc/acc.h5
-rw-r--r--src/core/hle/service/am/am.cpp74
-rw-r--r--src/core/hle/service/am/am.h30
-rw-r--r--src/core/hle/service/am/applet_ae.cpp49
-rw-r--r--src/core/hle/service/am/applet_ae.h5
-rw-r--r--src/core/hle/service/am/applet_oe.cpp24
-rw-r--r--src/core/hle/service/am/applet_oe.h5
-rw-r--r--src/core/hle/service/am/applets/controller.cpp4
-rw-r--r--src/core/hle/service/am/applets/controller.h1
-rw-r--r--src/core/hle/service/am/applets/error.cpp4
-rw-r--r--src/core/hle/service/am/applets/general_backend.cpp24
-rw-r--r--src/core/hle/service/am/applets/general_backend.h3
-rw-r--r--src/core/hle/service/am/applets/profile_select.cpp6
-rw-r--r--src/core/hle/service/am/applets/profile_select.h1
-rw-r--r--src/core/hle/service/am/applets/software_keyboard.cpp14
-rw-r--r--src/core/hle/service/am/applets/software_keyboard.h1
-rw-r--r--src/core/hle/service/am/applets/web_browser.cpp2
-rw-r--r--src/core/hle/service/am/idle.cpp2
-rw-r--r--src/core/hle/service/am/idle.h6
-rw-r--r--src/core/hle/service/am/omm.cpp2
-rw-r--r--src/core/hle/service/am/omm.h6
-rw-r--r--src/core/hle/service/am/spsm.cpp2
-rw-r--r--src/core/hle/service/am/spsm.h6
-rw-r--r--src/core/hle/service/am/tcap.cpp2
-rw-r--r--src/core/hle/service/am/tcap.h6
-rw-r--r--src/core/hle/service/aoc/aoc_u.cpp4
-rw-r--r--src/core/hle/service/aoc/aoc_u.h5
-rw-r--r--src/core/hle/service/apm/apm.cpp9
-rw-r--r--src/core/hle/service/apm/apm.h4
-rw-r--r--src/core/hle/service/apm/interface.cpp15
-rw-r--r--src/core/hle/service/apm/interface.h5
-rw-r--r--src/core/hle/service/audio/audctl.cpp2
-rw-r--r--src/core/hle/service/audio/audctl.h6
-rw-r--r--src/core/hle/service/audio/auddbg.cpp2
-rw-r--r--src/core/hle/service/audio/auddbg.h6
-rw-r--r--src/core/hle/service/audio/audin_a.cpp2
-rw-r--r--src/core/hle/service/audio/audin_a.h6
-rw-r--r--src/core/hle/service/audio/audin_u.cpp6
-rw-r--r--src/core/hle/service/audio/audin_u.h6
-rw-r--r--src/core/hle/service/audio/audio.cpp26
-rw-r--r--src/core/hle/service/audio/audout_a.cpp2
-rw-r--r--src/core/hle/service/audio/audout_a.h6
-rw-r--r--src/core/hle/service/audio/audout_u.cpp12
-rw-r--r--src/core/hle/service/audio/audout_u.h2
-rw-r--r--src/core/hle/service/audio/audrec_a.cpp2
-rw-r--r--src/core/hle/service/audio/audrec_a.h6
-rw-r--r--src/core/hle/service/audio/audrec_u.cpp5
-rw-r--r--src/core/hle/service/audio/audrec_u.h6
-rw-r--r--src/core/hle/service/audio/audren_a.cpp2
-rw-r--r--src/core/hle/service/audio/audren_a.h6
-rw-r--r--src/core/hle/service/audio/audren_u.cpp8
-rw-r--r--src/core/hle/service/audio/audren_u.h1
-rw-r--r--src/core/hle/service/audio/codecctl.cpp5
-rw-r--r--src/core/hle/service/audio/codecctl.h6
-rw-r--r--src/core/hle/service/audio/hwopus.cpp9
-rw-r--r--src/core/hle/service/audio/hwopus.h6
-rw-r--r--src/core/hle/service/bcat/module.cpp40
-rw-r--r--src/core/hle/service/bcat/module.h3
-rw-r--r--src/core/hle/service/bpc/bpc.cpp10
-rw-r--r--src/core/hle/service/bpc/bpc.h6
-rw-r--r--src/core/hle/service/btdrv/btdrv.cpp6
-rw-r--r--src/core/hle/service/btm/btm.cpp22
-rw-r--r--src/core/hle/service/caps/caps.cpp14
-rw-r--r--src/core/hle/service/caps/caps.h6
-rw-r--r--src/core/hle/service/caps/caps_a.cpp5
-rw-r--r--src/core/hle/service/caps/caps_a.h6
-rw-r--r--src/core/hle/service/caps/caps_c.cpp5
-rw-r--r--src/core/hle/service/caps/caps_c.h6
-rw-r--r--src/core/hle/service/caps/caps_sc.cpp2
-rw-r--r--src/core/hle/service/caps/caps_sc.h6
-rw-r--r--src/core/hle/service/caps/caps_ss.cpp2
-rw-r--r--src/core/hle/service/caps/caps_ss.h6
-rw-r--r--src/core/hle/service/caps/caps_su.cpp2
-rw-r--r--src/core/hle/service/caps/caps_su.h6
-rw-r--r--src/core/hle/service/caps/caps_u.cpp6
-rw-r--r--src/core/hle/service/caps/caps_u.h6
-rw-r--r--src/core/hle/service/erpt/erpt.cpp10
-rw-r--r--src/core/hle/service/erpt/erpt.h6
-rw-r--r--src/core/hle/service/es/es.cpp6
-rw-r--r--src/core/hle/service/es/es.h6
-rw-r--r--src/core/hle/service/eupld/eupld.cpp10
-rw-r--r--src/core/hle/service/eupld/eupld.h6
-rw-r--r--src/core/hle/service/fatal/fatal.cpp5
-rw-r--r--src/core/hle/service/fatal/fatal.h4
-rw-r--r--src/core/hle/service/fatal/fatal_p.cpp4
-rw-r--r--src/core/hle/service/fatal/fatal_p.h2
-rw-r--r--src/core/hle/service/fatal/fatal_u.cpp4
-rw-r--r--src/core/hle/service/fatal/fatal_u.h2
-rw-r--r--src/core/hle/service/fgm/fgm.cpp18
-rw-r--r--src/core/hle/service/fgm/fgm.h6
-rw-r--r--src/core/hle/service/filesystem/filesystem.cpp11
-rw-r--r--src/core/hle/service/filesystem/fsp_ldr.cpp2
-rw-r--r--src/core/hle/service/filesystem/fsp_ldr.h6
-rw-r--r--src/core/hle/service/filesystem/fsp_pr.cpp2
-rw-r--r--src/core/hle/service/filesystem/fsp_pr.h6
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.cpp57
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.h3
-rw-r--r--src/core/hle/service/friend/friend.cpp13
-rw-r--r--src/core/hle/service/friend/friend.h4
-rw-r--r--src/core/hle/service/friend/interface.cpp4
-rw-r--r--src/core/hle/service/friend/interface.h2
-rw-r--r--src/core/hle/service/glue/arp.cpp13
-rw-r--r--src/core/hle/service/glue/arp.h6
-rw-r--r--src/core/hle/service/glue/bgtc.cpp4
-rw-r--r--src/core/hle/service/glue/bgtc.h8
-rw-r--r--src/core/hle/service/glue/glue.cpp4
-rw-r--r--src/core/hle/service/grc/grc.cpp6
-rw-r--r--src/core/hle/service/grc/grc.h6
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp8
-rw-r--r--src/core/hle/service/hid/controllers/npad.h12
-rw-r--r--src/core/hle/service/hid/hid.cpp72
-rw-r--r--src/core/hle/service/hid/hid.h8
-rw-r--r--src/core/hle/service/hid/irs.cpp4
-rw-r--r--src/core/hle/service/hid/irs.h10
-rw-r--r--src/core/hle/service/hid/xcd.cpp2
-rw-r--r--src/core/hle/service/hid/xcd.h6
-rw-r--r--src/core/hle/service/lbl/lbl.cpp6
-rw-r--r--src/core/hle/service/lbl/lbl.h6
-rw-r--r--src/core/hle/service/ldn/ldn.cpp29
-rw-r--r--src/core/hle/service/ldn/ldn.h6
-rw-r--r--src/core/hle/service/ldr/ldr.cpp15
-rw-r--r--src/core/hle/service/ldr/ldr.h4
-rw-r--r--src/core/hle/service/lm/lm.cpp16
-rw-r--r--src/core/hle/service/mig/mig.cpp6
-rw-r--r--src/core/hle/service/mig/mig.h6
-rw-r--r--src/core/hle/service/mii/mii.cpp18
-rw-r--r--src/core/hle/service/mii/mii.h6
-rw-r--r--src/core/hle/service/mm/mm_u.cpp7
-rw-r--r--src/core/hle/service/mm/mm_u.h10
-rw-r--r--src/core/hle/service/ncm/ncm.cpp20
-rw-r--r--src/core/hle/service/ncm/ncm.h6
-rw-r--r--src/core/hle/service/nfc/nfc.cpp34
-rw-r--r--src/core/hle/service/nfc/nfc.h6
-rw-r--r--src/core/hle/service/nfp/nfp.cpp9
-rw-r--r--src/core/hle/service/nfp/nfp.h4
-rw-r--r--src/core/hle/service/nfp/nfp_user.cpp4
-rw-r--r--src/core/hle/service/nfp/nfp_user.h2
-rw-r--r--src/core/hle/service/nifm/nifm.cpp25
-rw-r--r--src/core/hle/service/nifm/nifm.h8
-rw-r--r--src/core/hle/service/nim/nim.cpp34
-rw-r--r--src/core/hle/service/nim/nim.h8
-rw-r--r--src/core/hle/service/npns/npns.cpp10
-rw-r--r--src/core/hle/service/npns/npns.h6
-rw-r--r--src/core/hle/service/ns/ns.cpp45
-rw-r--r--src/core/hle/service/ns/ns.h20
-rw-r--r--src/core/hle/service/ns/pl_u.cpp4
-rw-r--r--src/core/hle/service/ns/pl_u.h3
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdevice.h9
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp9
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdisp_disp0.h8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp9
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp19
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.h11
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp10
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.h8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp9
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.h8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h9
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp9
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.cpp8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.h8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.cpp8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.h8
-rw-r--r--src/core/hle/service/nvdrv/interface.cpp97
-rw-r--r--src/core/hle/service/nvdrv/interface.h4
-rw-r--r--src/core/hle/service/nvdrv/nvdata.h11
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.cpp23
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.h8
-rw-r--r--src/core/hle/service/nvdrv/nvmemp.cpp2
-rw-r--r--src/core/hle/service/nvdrv/nvmemp.h6
-rw-r--r--src/core/hle/service/nvdrv/syncpoint_manager.h4
-rw-r--r--src/core/hle/service/olsc/olsc.cpp6
-rw-r--r--src/core/hle/service/olsc/olsc.h6
-rw-r--r--src/core/hle/service/pcie/pcie.cpp8
-rw-r--r--src/core/hle/service/pcie/pcie.h6
-rw-r--r--src/core/hle/service/pctl/module.cpp21
-rw-r--r--src/core/hle/service/pctl/module.h9
-rw-r--r--src/core/hle/service/pctl/pctl.cpp4
-rw-r--r--src/core/hle/service/pctl/pctl.h6
-rw-r--r--src/core/hle/service/pcv/pcv.cpp14
-rw-r--r--src/core/hle/service/pcv/pcv.h6
-rw-r--r--src/core/hle/service/pm/pm.cpp23
-rw-r--r--src/core/hle/service/prepo/prepo.cpp5
-rw-r--r--src/core/hle/service/prepo/prepo.h8
-rw-r--r--src/core/hle/service/psc/psc.cpp14
-rw-r--r--src/core/hle/service/psc/psc.h6
-rw-r--r--src/core/hle/service/ptm/psm.cpp6
-rw-r--r--src/core/hle/service/ptm/psm.h6
-rw-r--r--src/core/hle/service/service.cpp69
-rw-r--r--src/core/hle/service/service.h18
-rw-r--r--src/core/hle/service/set/set.cpp2
-rw-r--r--src/core/hle/service/set/set.h6
-rw-r--r--src/core/hle/service/set/set_cal.cpp2
-rw-r--r--src/core/hle/service/set/set_cal.h6
-rw-r--r--src/core/hle/service/set/set_fd.cpp2
-rw-r--r--src/core/hle/service/set/set_fd.h6
-rw-r--r--src/core/hle/service/set/set_sys.cpp2
-rw-r--r--src/core/hle/service/set/set_sys.h6
-rw-r--r--src/core/hle/service/set/settings.cpp11
-rw-r--r--src/core/hle/service/set/settings.h10
-rw-r--r--src/core/hle/service/sm/controller.cpp2
-rw-r--r--src/core/hle/service/sm/controller.h6
-rw-r--r--src/core/hle/service/sm/sm.cpp14
-rw-r--r--src/core/hle/service/sm/sm.h8
-rw-r--r--src/core/hle/service/sockets/bsd.cpp6
-rw-r--r--src/core/hle/service/sockets/bsd.h4
-rw-r--r--src/core/hle/service/sockets/ethc.cpp4
-rw-r--r--src/core/hle/service/sockets/ethc.h8
-rw-r--r--src/core/hle/service/sockets/nsd.cpp2
-rw-r--r--src/core/hle/service/sockets/nsd.h7
-rw-r--r--src/core/hle/service/sockets/sfdnsres.cpp38
-rw-r--r--src/core/hle/service/sockets/sfdnsres.h6
-rw-r--r--src/core/hle/service/sockets/sockets.cpp12
-rw-r--r--src/core/hle/service/spl/csrng.cpp3
-rw-r--r--src/core/hle/service/spl/csrng.h6
-rw-r--r--src/core/hle/service/spl/module.cpp11
-rw-r--r--src/core/hle/service/spl/module.h9
-rw-r--r--src/core/hle/service/spl/spl.cpp3
-rw-r--r--src/core/hle/service/spl/spl.h6
-rw-r--r--src/core/hle/service/ssl/ssl.cpp14
-rw-r--r--src/core/hle/service/ssl/ssl.h6
-rw-r--r--src/core/hle/service/time/interface.cpp2
-rw-r--r--src/core/hle/service/time/time.cpp18
-rw-r--r--src/core/hle/service/time/time.h4
-rw-r--r--src/core/hle/service/time/time_zone_service.cpp5
-rw-r--r--src/core/hle/service/time/time_zone_service.h7
-rw-r--r--src/core/hle/service/usb/usb.cpp39
-rw-r--r--src/core/hle/service/usb/usb.h6
-rw-r--r--src/core/hle/service/vi/vi.cpp41
-rw-r--r--src/core/hle/service/vi/vi.h11
-rw-r--r--src/core/hle/service/vi/vi_m.cpp5
-rw-r--r--src/core/hle/service/vi/vi_m.h6
-rw-r--r--src/core/hle/service/vi/vi_s.cpp5
-rw-r--r--src/core/hle/service/vi/vi_s.h6
-rw-r--r--src/core/hle/service/vi/vi_u.cpp5
-rw-r--r--src/core/hle/service/vi/vi_u.h6
-rw-r--r--src/core/hle/service/wlan/wlan.cpp22
-rw-r--r--src/core/hle/service/wlan/wlan.h6
-rw-r--r--src/core/loader/deconstructed_rom_directory.cpp3
-rw-r--r--src/core/loader/kip.cpp3
-rw-r--r--src/core/loader/nro.cpp6
-rw-r--r--src/core/loader/nso.cpp5
-rw-r--r--src/core/settings.cpp17
-rw-r--r--src/core/settings.h12
-rw-r--r--src/input_common/CMakeLists.txt10
-rw-r--r--src/input_common/main.cpp75
-rw-r--r--src/input_common/main.h41
-rw-r--r--src/input_common/motion_emu.cpp179
-rw-r--r--src/input_common/motion_emu.h46
-rw-r--r--src/input_common/mouse/mouse_input.cpp127
-rw-r--r--src/input_common/mouse/mouse_input.h99
-rw-r--r--src/input_common/mouse/mouse_poller.cpp261
-rw-r--r--src/input_common/mouse/mouse_poller.h109
-rw-r--r--src/input_common/udp/client.cpp143
-rw-r--r--src/input_common/udp/client.h40
-rw-r--r--src/input_common/udp/udp.cpp64
-rw-r--r--src/tests/common/bit_field.cpp4
-rw-r--r--src/video_core/command_classes/codecs/codec.cpp33
-rw-r--r--src/video_core/command_classes/codecs/codec.h12
-rw-r--r--src/video_core/command_classes/codecs/h264.cpp2
-rw-r--r--src/video_core/command_classes/codecs/h264.h4
-rw-r--r--src/video_core/command_classes/codecs/vp9.cpp333
-rw-r--r--src/video_core/command_classes/codecs/vp9.h7
-rw-r--r--src/video_core/command_classes/codecs/vp9_types.h160
-rw-r--r--src/video_core/command_classes/nvdec.cpp6
-rw-r--r--src/video_core/command_classes/nvdec.h3
-rw-r--r--src/video_core/command_classes/vic.cpp15
-rw-r--r--src/video_core/engines/maxwell_3d.h7
-rw-r--r--src/video_core/gpu.cpp29
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp2
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.cpp12
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.h9
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.cpp4
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp7
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.cpp50
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.h3
-rw-r--r--src/yuzu/bootmanager.cpp28
-rw-r--r--src/yuzu/bootmanager.h2
-rw-r--r--src/yuzu/configuration/config.cpp23
-rw-r--r--src/yuzu/configuration/configure_dialog.cpp3
-rw-r--r--src/yuzu/configuration/configure_input_player.cpp87
-rw-r--r--src/yuzu/configuration/configure_motion_touch.cpp134
-rw-r--r--src/yuzu/configuration/configure_motion_touch.h5
-rw-r--r--src/yuzu/configuration/configure_motion_touch.ui269
-rw-r--r--src/yuzu/configuration/configure_per_game.cpp2
-rw-r--r--src/yuzu/configuration/configure_profile_manager.cpp2
-rw-r--r--src/yuzu/configuration/configure_system.cpp12
-rw-r--r--src/yuzu/configuration/configure_ui.cpp3
-rw-r--r--src/yuzu/main.cpp42
-rw-r--r--src/yuzu_cmd/config.cpp6
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2.cpp108
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2.h20
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp1
-rw-r--r--src/yuzu_cmd/yuzu.cpp11
-rw-r--r--src/yuzu_tester/emu_window/emu_window_sdl2_hide.cpp2
-rw-r--r--src/yuzu_tester/emu_window/emu_window_sdl2_hide.h3
-rw-r--r--src/yuzu_tester/service/yuzutest.cpp15
-rw-r--r--src/yuzu_tester/service/yuzutest.h6
-rw-r--r--src/yuzu_tester/yuzu.cpp10
319 files changed, 3245 insertions, 3607 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index dbda528ce..a22b564d6 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -66,6 +66,7 @@ else()
66 -Wextra 66 -Wextra
67 -Wmissing-declarations 67 -Wmissing-declarations
68 -Wno-attributes 68 -Wno-attributes
69 -Wno-invalid-offsetof
69 -Wno-unused-parameter 70 -Wno-unused-parameter
70 ) 71 )
71 72
diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp
index 75ab9ea0b..179560cd7 100644
--- a/src/audio_core/audio_renderer.cpp
+++ b/src/audio_core/audio_renderer.cpp
@@ -79,8 +79,7 @@ AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory
79 sink_context(params.sink_count), splitter_context(), 79 sink_context(params.sink_count), splitter_context(),
80 voices(params.voice_count), memory{memory_}, 80 voices(params.voice_count), memory{memory_},
81 command_generator(worker_params, voice_context, mix_context, splitter_context, effect_context, 81 command_generator(worker_params, voice_context, mix_context, splitter_context, effect_context,
82 memory), 82 memory) {
83 temp_mix_buffer(AudioCommon::TOTAL_TEMP_MIX_SIZE) {
84 behavior_info.SetUserRevision(params.revision); 83 behavior_info.SetUserRevision(params.revision);
85 splitter_context.Initialize(behavior_info, params.splitter_count, 84 splitter_context.Initialize(behavior_info, params.splitter_count,
86 params.num_splitter_send_channels); 85 params.num_splitter_send_channels);
diff --git a/src/audio_core/audio_renderer.h b/src/audio_core/audio_renderer.h
index 1f96013f7..90f7eafa4 100644
--- a/src/audio_core/audio_renderer.h
+++ b/src/audio_core/audio_renderer.h
@@ -74,7 +74,6 @@ private:
74 Core::Memory::Memory& memory; 74 Core::Memory::Memory& memory;
75 CommandGenerator command_generator; 75 CommandGenerator command_generator;
76 std::size_t elapsed_frame_count{}; 76 std::size_t elapsed_frame_count{};
77 std::vector<s32> temp_mix_buffer{};
78}; 77};
79 78
80} // namespace AudioCore 79} // namespace AudioCore
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index d20e6c3b5..56c7e21f5 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -112,6 +112,7 @@ add_library(common STATIC
112 common_paths.h 112 common_paths.h
113 common_types.h 113 common_types.h
114 concepts.h 114 concepts.h
115 div_ceil.h
115 dynamic_library.cpp 116 dynamic_library.cpp
116 dynamic_library.h 117 dynamic_library.h
117 fiber.cpp 118 fiber.cpp
diff --git a/src/common/div_ceil.h b/src/common/div_ceil.h
new file mode 100644
index 000000000..6b2c48f91
--- /dev/null
+++ b/src/common/div_ceil.h
@@ -0,0 +1,26 @@
1// Copyright 2020 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <cstddef>
8#include <type_traits>
9
10namespace Common {
11
12/// Ceiled integer division.
13template <typename N, typename D>
14requires std::is_integral_v<N>&& std::is_unsigned_v<D>[[nodiscard]] constexpr auto DivCeil(
15 N number, D divisor) {
16 return (static_cast<D>(number) + divisor - 1) / divisor;
17}
18
19/// Ceiled integer division with logarithmic divisor in base 2
20template <typename N, typename D>
21requires std::is_integral_v<N>&& std::is_unsigned_v<D>[[nodiscard]] constexpr auto DivCeilLog2(
22 N value, D alignment_log2) {
23 return (static_cast<D>(value) + (D(1) << alignment_log2) - 1) >> alignment_log2;
24}
25
26} // namespace Common
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index e370fd225..66de33799 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -135,8 +135,6 @@ add_library(core STATIC
135 frontend/framebuffer_layout.cpp 135 frontend/framebuffer_layout.cpp
136 frontend/framebuffer_layout.h 136 frontend/framebuffer_layout.h
137 frontend/input.h 137 frontend/input.h
138 gdbstub/gdbstub.cpp
139 gdbstub/gdbstub.h
140 hardware_interrupt_manager.cpp 138 hardware_interrupt_manager.cpp
141 hardware_interrupt_manager.h 139 hardware_interrupt_manager.h
142 hle/ipc.h 140 hle/ipc.h
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index 9f170a224..5c2060d78 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -14,7 +14,6 @@
14#include "core/arm/dynarmic/arm_exclusive_monitor.h" 14#include "core/arm/dynarmic/arm_exclusive_monitor.h"
15#include "core/core.h" 15#include "core/core.h"
16#include "core/core_timing.h" 16#include "core/core_timing.h"
17#include "core/gdbstub/gdbstub.h"
18#include "core/hardware_properties.h" 17#include "core/hardware_properties.h"
19#include "core/hle/kernel/process.h" 18#include "core/hle/kernel/process.h"
20#include "core/hle/kernel/scheduler.h" 19#include "core/hle/kernel/scheduler.h"
@@ -96,16 +95,6 @@ public:
96 case Dynarmic::A64::Exception::Yield: 95 case Dynarmic::A64::Exception::Yield:
97 return; 96 return;
98 case Dynarmic::A64::Exception::Breakpoint: 97 case Dynarmic::A64::Exception::Breakpoint:
99 if (GDBStub::IsServerEnabled()) {
100 parent.jit->HaltExecution();
101 parent.SetPC(pc);
102 Kernel::Thread* const thread = parent.system.CurrentScheduler().GetCurrentThread();
103 parent.SaveContext(thread->GetContext64());
104 GDBStub::Break();
105 GDBStub::SendTrap(thread, 5);
106 return;
107 }
108 [[fallthrough]];
109 default: 98 default:
110 ASSERT_MSG(false, "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X})", 99 ASSERT_MSG(false, "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X})",
111 static_cast<std::size_t>(exception), pc, MemoryReadCode(pc)); 100 static_cast<std::size_t>(exception), pc, MemoryReadCode(pc));
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 7ca3652af..76a38ea2a 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -25,7 +25,6 @@
25#include "core/file_sys/sdmc_factory.h" 25#include "core/file_sys/sdmc_factory.h"
26#include "core/file_sys/vfs_concat.h" 26#include "core/file_sys/vfs_concat.h"
27#include "core/file_sys/vfs_real.h" 27#include "core/file_sys/vfs_real.h"
28#include "core/gdbstub/gdbstub.h"
29#include "core/hardware_interrupt_manager.h" 28#include "core/hardware_interrupt_manager.h"
30#include "core/hle/kernel/client_port.h" 29#include "core/hle/kernel/client_port.h"
31#include "core/hle/kernel/kernel.h" 30#include "core/hle/kernel/kernel.h"
@@ -92,33 +91,43 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
92 std::string dir_name; 91 std::string dir_name;
93 std::string filename; 92 std::string filename;
94 Common::SplitPath(path, &dir_name, &filename, nullptr); 93 Common::SplitPath(path, &dir_name, &filename, nullptr);
94
95 if (filename == "00") { 95 if (filename == "00") {
96 const auto dir = vfs->OpenDirectory(dir_name, FileSys::Mode::Read); 96 const auto dir = vfs->OpenDirectory(dir_name, FileSys::Mode::Read);
97 std::vector<FileSys::VirtualFile> concat; 97 std::vector<FileSys::VirtualFile> concat;
98 for (u8 i = 0; i < 0x10; ++i) { 98
99 auto next = dir->GetFile(fmt::format("{:02X}", i)); 99 for (u32 i = 0; i < 0x10; ++i) {
100 if (next != nullptr) 100 const auto file_name = fmt::format("{:02X}", i);
101 auto next = dir->GetFile(file_name);
102
103 if (next != nullptr) {
101 concat.push_back(std::move(next)); 104 concat.push_back(std::move(next));
102 else { 105 } else {
103 next = dir->GetFile(fmt::format("{:02x}", i)); 106 next = dir->GetFile(file_name);
104 if (next != nullptr) 107
105 concat.push_back(std::move(next)); 108 if (next == nullptr) {
106 else
107 break; 109 break;
110 }
111
112 concat.push_back(std::move(next));
108 } 113 }
109 } 114 }
110 115
111 if (concat.empty()) 116 if (concat.empty()) {
112 return nullptr; 117 return nullptr;
118 }
113 119
114 return FileSys::ConcatenatedVfsFile::MakeConcatenatedFile(concat, dir->GetName()); 120 return FileSys::ConcatenatedVfsFile::MakeConcatenatedFile(std::move(concat),
121 dir->GetName());
115 } 122 }
116 123
117 if (Common::FS::IsDirectory(path)) 124 if (Common::FS::IsDirectory(path)) {
118 return vfs->OpenFile(path + "/" + "main", FileSys::Mode::Read); 125 return vfs->OpenFile(path + "/main", FileSys::Mode::Read);
126 }
119 127
120 return vfs->OpenFile(path, FileSys::Mode::Read); 128 return vfs->OpenFile(path, FileSys::Mode::Read);
121} 129}
130
122struct System::Impl { 131struct System::Impl {
123 explicit Impl(System& system) 132 explicit Impl(System& system)
124 : kernel{system}, fs_controller{system}, memory{system}, 133 : kernel{system}, fs_controller{system}, memory{system},
@@ -186,11 +195,8 @@ struct System::Impl {
186 } 195 }
187 196
188 service_manager = std::make_shared<Service::SM::ServiceManager>(kernel); 197 service_manager = std::make_shared<Service::SM::ServiceManager>(kernel);
189
190 services = std::make_unique<Service::Services>(service_manager, system); 198 services = std::make_unique<Service::Services>(service_manager, system);
191 GDBStub::DeferStart(); 199 interrupt_manager = std::make_unique<Hardware::InterruptManager>(system);
192
193 interrupt_manager = std::make_unique<Core::Hardware::InterruptManager>(system);
194 200
195 // Initialize time manager, which must happen after kernel is created 201 // Initialize time manager, which must happen after kernel is created
196 time_manager.Initialize(); 202 time_manager.Initialize();
@@ -297,7 +303,6 @@ struct System::Impl {
297 } 303 }
298 304
299 // Shutdown emulation session 305 // Shutdown emulation session
300 GDBStub::Shutdown();
301 services.reset(); 306 services.reset();
302 service_manager.reset(); 307 service_manager.reset();
303 cheat_engine.reset(); 308 cheat_engine.reset();
diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp
index 100e90d82..eeeb6e8df 100644
--- a/src/core/cpu_manager.cpp
+++ b/src/core/cpu_manager.cpp
@@ -10,7 +10,6 @@
10#include "core/core.h" 10#include "core/core.h"
11#include "core/core_timing.h" 11#include "core/core_timing.h"
12#include "core/cpu_manager.h" 12#include "core/cpu_manager.h"
13#include "core/gdbstub/gdbstub.h"
14#include "core/hle/kernel/kernel.h" 13#include "core/hle/kernel/kernel.h"
15#include "core/hle/kernel/physical_core.h" 14#include "core/hle/kernel/physical_core.h"
16#include "core/hle/kernel/scheduler.h" 15#include "core/hle/kernel/scheduler.h"
diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp
index ba4efee3a..b7bfe0928 100644
--- a/src/core/file_sys/savedata_factory.cpp
+++ b/src/core/file_sys/savedata_factory.cpp
@@ -70,7 +70,8 @@ std::string SaveDataAttribute::DebugInfo() const {
70 static_cast<u8>(rank), index); 70 static_cast<u8>(rank), index);
71} 71}
72 72
73SaveDataFactory::SaveDataFactory(VirtualDir save_directory) : dir(std::move(save_directory)) { 73SaveDataFactory::SaveDataFactory(Core::System& system_, VirtualDir save_directory_)
74 : dir{std::move(save_directory_)}, system{system_} {
74 // Delete all temporary storages 75 // Delete all temporary storages
75 // On hardware, it is expected that temporary storage be empty at first use. 76 // On hardware, it is expected that temporary storage be empty at first use.
76 dir->DeleteSubdirectoryRecursive("temp"); 77 dir->DeleteSubdirectoryRecursive("temp");
@@ -83,7 +84,7 @@ ResultVal<VirtualDir> SaveDataFactory::Create(SaveDataSpaceId space,
83 PrintSaveDataAttributeWarnings(meta); 84 PrintSaveDataAttributeWarnings(meta);
84 85
85 const auto save_directory = 86 const auto save_directory =
86 GetFullPath(space, meta.type, meta.title_id, meta.user_id, meta.save_id); 87 GetFullPath(system, space, meta.type, meta.title_id, meta.user_id, meta.save_id);
87 88
88 auto out = dir->CreateDirectoryRelative(save_directory); 89 auto out = dir->CreateDirectoryRelative(save_directory);
89 90
@@ -100,7 +101,7 @@ ResultVal<VirtualDir> SaveDataFactory::Open(SaveDataSpaceId space,
100 const SaveDataAttribute& meta) const { 101 const SaveDataAttribute& meta) const {
101 102
102 const auto save_directory = 103 const auto save_directory =
103 GetFullPath(space, meta.type, meta.title_id, meta.user_id, meta.save_id); 104 GetFullPath(system, space, meta.type, meta.title_id, meta.user_id, meta.save_id);
104 105
105 auto out = dir->GetDirectoryRelative(save_directory); 106 auto out = dir->GetDirectoryRelative(save_directory);
106 107
@@ -135,13 +136,14 @@ std::string SaveDataFactory::GetSaveDataSpaceIdPath(SaveDataSpaceId space) {
135 } 136 }
136} 137}
137 138
138std::string SaveDataFactory::GetFullPath(SaveDataSpaceId space, SaveDataType type, u64 title_id, 139std::string SaveDataFactory::GetFullPath(Core::System& system, SaveDataSpaceId space,
139 u128 user_id, u64 save_id) { 140 SaveDataType type, u64 title_id, u128 user_id,
141 u64 save_id) {
140 // According to switchbrew, if a save is of type SaveData and the title id field is 0, it should 142 // According to switchbrew, if a save is of type SaveData and the title id field is 0, it should
141 // be interpreted as the title id of the current process. 143 // be interpreted as the title id of the current process.
142 if (type == SaveDataType::SaveData || type == SaveDataType::DeviceSaveData) { 144 if (type == SaveDataType::SaveData || type == SaveDataType::DeviceSaveData) {
143 if (title_id == 0) { 145 if (title_id == 0) {
144 title_id = Core::System::GetInstance().CurrentProcess()->GetTitleID(); 146 title_id = system.CurrentProcess()->GetTitleID();
145 } 147 }
146 } 148 }
147 149
@@ -167,7 +169,7 @@ std::string SaveDataFactory::GetFullPath(SaveDataSpaceId space, SaveDataType typ
167 169
168SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id, 170SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id,
169 u128 user_id) const { 171 u128 user_id) const {
170 const auto path = GetFullPath(SaveDataSpaceId::NandUser, type, title_id, user_id, 0); 172 const auto path = GetFullPath(system, SaveDataSpaceId::NandUser, type, title_id, user_id, 0);
171 const auto dir = GetOrCreateDirectoryRelative(this->dir, path); 173 const auto dir = GetOrCreateDirectoryRelative(this->dir, path);
172 174
173 const auto size_file = dir->GetFile(SAVE_DATA_SIZE_FILENAME); 175 const auto size_file = dir->GetFile(SAVE_DATA_SIZE_FILENAME);
@@ -182,7 +184,7 @@ SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id,
182 184
183void SaveDataFactory::WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id, 185void SaveDataFactory::WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id,
184 SaveDataSize new_value) const { 186 SaveDataSize new_value) const {
185 const auto path = GetFullPath(SaveDataSpaceId::NandUser, type, title_id, user_id, 0); 187 const auto path = GetFullPath(system, SaveDataSpaceId::NandUser, type, title_id, user_id, 0);
186 const auto dir = GetOrCreateDirectoryRelative(this->dir, path); 188 const auto dir = GetOrCreateDirectoryRelative(this->dir, path);
187 189
188 const auto size_file = dir->CreateFile(SAVE_DATA_SIZE_FILENAME); 190 const auto size_file = dir->CreateFile(SAVE_DATA_SIZE_FILENAME);
diff --git a/src/core/file_sys/savedata_factory.h b/src/core/file_sys/savedata_factory.h
index 6625bbbd8..17f774baa 100644
--- a/src/core/file_sys/savedata_factory.h
+++ b/src/core/file_sys/savedata_factory.h
@@ -12,6 +12,10 @@
12#include "core/file_sys/vfs.h" 12#include "core/file_sys/vfs.h"
13#include "core/hle/result.h" 13#include "core/hle/result.h"
14 14
15namespace Core {
16class System;
17}
18
15namespace FileSys { 19namespace FileSys {
16 20
17enum class SaveDataSpaceId : u8 { 21enum class SaveDataSpaceId : u8 {
@@ -84,7 +88,7 @@ struct SaveDataSize {
84/// File system interface to the SaveData archive 88/// File system interface to the SaveData archive
85class SaveDataFactory { 89class SaveDataFactory {
86public: 90public:
87 explicit SaveDataFactory(VirtualDir dir); 91 explicit SaveDataFactory(Core::System& system_, VirtualDir save_directory_);
88 ~SaveDataFactory(); 92 ~SaveDataFactory();
89 93
90 ResultVal<VirtualDir> Create(SaveDataSpaceId space, const SaveDataAttribute& meta) const; 94 ResultVal<VirtualDir> Create(SaveDataSpaceId space, const SaveDataAttribute& meta) const;
@@ -93,8 +97,8 @@ public:
93 VirtualDir GetSaveDataSpaceDirectory(SaveDataSpaceId space) const; 97 VirtualDir GetSaveDataSpaceDirectory(SaveDataSpaceId space) const;
94 98
95 static std::string GetSaveDataSpaceIdPath(SaveDataSpaceId space); 99 static std::string GetSaveDataSpaceIdPath(SaveDataSpaceId space);
96 static std::string GetFullPath(SaveDataSpaceId space, SaveDataType type, u64 title_id, 100 static std::string GetFullPath(Core::System& system, SaveDataSpaceId space, SaveDataType type,
97 u128 user_id, u64 save_id); 101 u64 title_id, u128 user_id, u64 save_id);
98 102
99 SaveDataSize ReadSaveDataSize(SaveDataType type, u64 title_id, u128 user_id) const; 103 SaveDataSize ReadSaveDataSize(SaveDataType type, u64 title_id, u128 user_id) const;
100 void WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id, 104 void WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id,
@@ -102,6 +106,7 @@ public:
102 106
103private: 107private:
104 VirtualDir dir; 108 VirtualDir dir;
109 Core::System& system;
105}; 110};
106 111
107} // namespace FileSys 112} // namespace FileSys
diff --git a/src/core/frontend/emu_window.h b/src/core/frontend/emu_window.h
index 3e8780243..276d2b906 100644
--- a/src/core/frontend/emu_window.h
+++ b/src/core/frontend/emu_window.h
@@ -102,8 +102,8 @@ public:
102 float render_surface_scale = 1.0f; 102 float render_surface_scale = 1.0f;
103 }; 103 };
104 104
105 /// Polls window events 105 /// Called from GPU thread when a frame is displayed.
106 virtual void PollEvents() = 0; 106 virtual void OnFrameDisplayed() {}
107 107
108 /** 108 /**
109 * Returns a GraphicsContext that the frontend provides to be used for rendering. 109 * Returns a GraphicsContext that the frontend provides to be used for rendering.
diff --git a/src/core/frontend/input.h b/src/core/frontend/input.h
index 11c2e96ca..de51a754e 100644
--- a/src/core/frontend/input.h
+++ b/src/core/frontend/input.h
@@ -163,10 +163,15 @@ using MotionStatus = std::tuple<Common::Vec3<float>, Common::Vec3<float>, Common
163using MotionDevice = InputDevice<MotionStatus>; 163using MotionDevice = InputDevice<MotionStatus>;
164 164
165/** 165/**
166 * A touch device is an input device that returns a tuple of two floats and a bool. The floats are 166 * A touch status is an object that returns a tuple of two floats and a bool. The floats are
167 * x and y coordinates in the range 0.0 - 1.0, and the bool indicates whether it is pressed. 167 * x and y coordinates in the range 0.0 - 1.0, and the bool indicates whether it is pressed.
168 */ 168 */
169using TouchDevice = InputDevice<std::tuple<float, float, bool>>; 169using TouchStatus = std::tuple<float, float, bool>;
170
171/**
172 * A touch device is an input device that returns a touch status object
173 */
174using TouchDevice = InputDevice<TouchStatus>;
170 175
171/** 176/**
172 * A mouse device is an input device that returns a tuple of two floats and four ints. 177 * A mouse device is an input device that returns a tuple of two floats and four ints.
diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp
deleted file mode 100644
index 97ee65464..000000000
--- a/src/core/gdbstub/gdbstub.cpp
+++ /dev/null
@@ -1,1397 +0,0 @@
1// Copyright 2013 Dolphin Emulator Project
2// Licensed under GPLv2+
3// Refer to the license.txt file included.
4
5// Originally written by Sven Peter <sven@fail0verflow.com> for anergistic.
6
7#include <algorithm>
8#include <atomic>
9#include <climits>
10#include <csignal>
11#include <cstdarg>
12#include <cstdio>
13#include <cstring>
14#include <map>
15#include <numeric>
16#include <fcntl.h>
17
18#ifdef _WIN32
19#include <winsock2.h>
20// winsock2.h needs to be included first to prevent winsock.h being included by other includes
21#include <io.h>
22#include <iphlpapi.h>
23#include <ws2tcpip.h>
24#define SHUT_RDWR 2
25#else
26#include <netinet/in.h>
27#include <sys/select.h>
28#include <sys/socket.h>
29#include <sys/un.h>
30#include <unistd.h>
31#endif
32
33#include "common/logging/log.h"
34#include "common/string_util.h"
35#include "common/swap.h"
36#include "core/arm/arm_interface.h"
37#include "core/core.h"
38#include "core/gdbstub/gdbstub.h"
39#include "core/hle/kernel/memory/page_table.h"
40#include "core/hle/kernel/process.h"
41#include "core/hle/kernel/scheduler.h"
42#include "core/loader/loader.h"
43#include "core/memory.h"
44
45namespace GDBStub {
46namespace {
47constexpr int GDB_BUFFER_SIZE = 10000;
48
49constexpr char GDB_STUB_START = '$';
50constexpr char GDB_STUB_END = '#';
51constexpr char GDB_STUB_ACK = '+';
52constexpr char GDB_STUB_NACK = '-';
53
54#ifndef SIGTRAP
55constexpr u32 SIGTRAP = 5;
56#endif
57
58#ifndef SIGTERM
59constexpr u32 SIGTERM = 15;
60#endif
61
62#ifndef MSG_WAITALL
63constexpr u32 MSG_WAITALL = 8;
64#endif
65
66constexpr u32 LR_REGISTER = 30;
67constexpr u32 SP_REGISTER = 31;
68constexpr u32 PC_REGISTER = 32;
69constexpr u32 PSTATE_REGISTER = 33;
70constexpr u32 UC_ARM64_REG_Q0 = 34;
71constexpr u32 FPCR_REGISTER = 66;
72
73// For sample XML files see the GDB source /gdb/features
74// GDB also wants the l character at the start
75// This XML defines what the registers are for this specific ARM device
76constexpr char target_xml[] =
77 R"(l<?xml version="1.0"?>
78<!DOCTYPE target SYSTEM "gdb-target.dtd">
79<target version="1.0">
80 <feature name="org.gnu.gdb.aarch64.core">
81 <reg name="x0" bitsize="64"/>
82 <reg name="x1" bitsize="64"/>
83 <reg name="x2" bitsize="64"/>
84 <reg name="x3" bitsize="64"/>
85 <reg name="x4" bitsize="64"/>
86 <reg name="x5" bitsize="64"/>
87 <reg name="x6" bitsize="64"/>
88 <reg name="x7" bitsize="64"/>
89 <reg name="x8" bitsize="64"/>
90 <reg name="x9" bitsize="64"/>
91 <reg name="x10" bitsize="64"/>
92 <reg name="x11" bitsize="64"/>
93 <reg name="x12" bitsize="64"/>
94 <reg name="x13" bitsize="64"/>
95 <reg name="x14" bitsize="64"/>
96 <reg name="x15" bitsize="64"/>
97 <reg name="x16" bitsize="64"/>
98 <reg name="x17" bitsize="64"/>
99 <reg name="x18" bitsize="64"/>
100 <reg name="x19" bitsize="64"/>
101 <reg name="x20" bitsize="64"/>
102 <reg name="x21" bitsize="64"/>
103 <reg name="x22" bitsize="64"/>
104 <reg name="x23" bitsize="64"/>
105 <reg name="x24" bitsize="64"/>
106 <reg name="x25" bitsize="64"/>
107 <reg name="x26" bitsize="64"/>
108 <reg name="x27" bitsize="64"/>
109 <reg name="x28" bitsize="64"/>
110 <reg name="x29" bitsize="64"/>
111 <reg name="x30" bitsize="64"/>
112 <reg name="sp" bitsize="64" type="data_ptr"/>
113
114 <reg name="pc" bitsize="64" type="code_ptr"/>
115
116 <flags id="pstate_flags" size="4">
117 <field name="SP" start="0" end="0"/>
118 <field name="" start="1" end="1"/>
119 <field name="EL" start="2" end="3"/>
120 <field name="nRW" start="4" end="4"/>
121 <field name="" start="5" end="5"/>
122 <field name="F" start="6" end="6"/>
123 <field name="I" start="7" end="7"/>
124 <field name="A" start="8" end="8"/>
125 <field name="D" start="9" end="9"/>
126
127 <field name="IL" start="20" end="20"/>
128 <field name="SS" start="21" end="21"/>
129
130 <field name="V" start="28" end="28"/>
131 <field name="C" start="29" end="29"/>
132 <field name="Z" start="30" end="30"/>
133 <field name="N" start="31" end="31"/>
134 </flags>
135 <reg name="pstate" bitsize="32" type="pstate_flags"/>
136 </feature>
137 <feature name="org.gnu.gdb.aarch64.fpu">
138 </feature>
139</target>
140)";
141
142int gdbserver_socket = -1;
143bool defer_start = false;
144
145u8 command_buffer[GDB_BUFFER_SIZE];
146u32 command_length;
147
148u32 latest_signal = 0;
149bool memory_break = false;
150
151Kernel::Thread* current_thread = nullptr;
152u32 current_core = 0;
153
154// Binding to a port within the reserved ports range (0-1023) requires root permissions,
155// so default to a port outside of that range.
156u16 gdbstub_port = 24689;
157
158bool halt_loop = true;
159bool step_loop = false;
160bool send_trap = false;
161
162// If set to false, the server will never be started and no
163// gdbstub-related functions will be executed.
164std::atomic<bool> server_enabled(false);
165
166#ifdef _WIN32
167WSADATA InitData;
168#endif
169
170struct Breakpoint {
171 bool active;
172 VAddr addr;
173 u64 len;
174 std::array<u8, 4> inst;
175};
176
177using BreakpointMap = std::map<VAddr, Breakpoint>;
178BreakpointMap breakpoints_execute;
179BreakpointMap breakpoints_read;
180BreakpointMap breakpoints_write;
181
182struct Module {
183 std::string name;
184 VAddr beg;
185 VAddr end;
186};
187
188std::vector<Module> modules;
189} // Anonymous namespace
190
191void RegisterModule(std::string name, VAddr beg, VAddr end, bool add_elf_ext) {
192 Module module;
193 if (add_elf_ext) {
194 Common::SplitPath(name, nullptr, &module.name, nullptr);
195 module.name += ".elf";
196 } else {
197 module.name = std::move(name);
198 }
199 module.beg = beg;
200 module.end = end;
201 modules.push_back(std::move(module));
202}
203
204static Kernel::Thread* FindThreadById(s64 id) {
205 const auto& threads = Core::System::GetInstance().GlobalScheduler().GetThreadList();
206 for (auto& thread : threads) {
207 if (thread->GetThreadID() == static_cast<u64>(id)) {
208 current_core = thread->GetProcessorID();
209 return thread.get();
210 }
211 }
212 return nullptr;
213}
214
215static u64 RegRead(std::size_t id, Kernel::Thread* thread = nullptr) {
216 if (!thread) {
217 return 0;
218 }
219
220 const auto& thread_context = thread->GetContext64();
221
222 if (id < SP_REGISTER) {
223 return thread_context.cpu_registers[id];
224 } else if (id == SP_REGISTER) {
225 return thread_context.sp;
226 } else if (id == PC_REGISTER) {
227 return thread_context.pc;
228 } else if (id == PSTATE_REGISTER) {
229 return thread_context.pstate;
230 } else if (id > PSTATE_REGISTER && id < FPCR_REGISTER) {
231 return thread_context.vector_registers[id - UC_ARM64_REG_Q0][0];
232 } else {
233 return 0;
234 }
235}
236
237static void RegWrite(std::size_t id, u64 val, Kernel::Thread* thread = nullptr) {
238 if (!thread) {
239 return;
240 }
241
242 auto& thread_context = thread->GetContext64();
243
244 if (id < SP_REGISTER) {
245 thread_context.cpu_registers[id] = val;
246 } else if (id == SP_REGISTER) {
247 thread_context.sp = val;
248 } else if (id == PC_REGISTER) {
249 thread_context.pc = val;
250 } else if (id == PSTATE_REGISTER) {
251 thread_context.pstate = static_cast<u32>(val);
252 } else if (id > PSTATE_REGISTER && id < FPCR_REGISTER) {
253 thread_context.vector_registers[id - (PSTATE_REGISTER + 1)][0] = val;
254 }
255}
256
257static u128 FpuRead(std::size_t id, Kernel::Thread* thread = nullptr) {
258 if (!thread) {
259 return u128{0};
260 }
261
262 auto& thread_context = thread->GetContext64();
263
264 if (id >= UC_ARM64_REG_Q0 && id < FPCR_REGISTER) {
265 return thread_context.vector_registers[id - UC_ARM64_REG_Q0];
266 } else if (id == FPCR_REGISTER) {
267 return u128{thread_context.fpcr, 0};
268 } else {
269 return u128{0};
270 }
271}
272
273static void FpuWrite(std::size_t id, u128 val, Kernel::Thread* thread = nullptr) {
274 if (!thread) {
275 return;
276 }
277
278 auto& thread_context = thread->GetContext64();
279
280 if (id >= UC_ARM64_REG_Q0 && id < FPCR_REGISTER) {
281 thread_context.vector_registers[id - UC_ARM64_REG_Q0] = val;
282 } else if (id == FPCR_REGISTER) {
283 thread_context.fpcr = static_cast<u32>(val[0]);
284 }
285}
286
287/**
288 * Turns hex string character into the equivalent byte.
289 *
290 * @param hex Input hex character to be turned into byte.
291 */
292static u8 HexCharToValue(u8 hex) {
293 if (hex >= '0' && hex <= '9') {
294 return static_cast<u8>(hex - '0');
295 } else if (hex >= 'a' && hex <= 'f') {
296 return static_cast<u8>(hex - 'a' + 0xA);
297 } else if (hex >= 'A' && hex <= 'F') {
298 return static_cast<u8>(hex - 'A' + 0xA);
299 }
300
301 LOG_ERROR(Debug_GDBStub, "Invalid nibble: {} ({:02X})", hex, hex);
302 return 0;
303}
304
305/**
306 * Turn nibble of byte into hex string character.
307 *
308 * @param n Nibble to be turned into hex character.
309 */
310static u8 NibbleToHex(u8 n) {
311 n &= 0xF;
312 if (n < 0xA) {
313 return static_cast<u8>('0' + n);
314 } else {
315 return static_cast<u8>('a' + n - 0xA);
316 }
317}
318
319/**
320 * Converts input hex string characters into an array of equivalent of u8 bytes.
321 *
322 * @param src Pointer to array of output hex string characters.
323 * @param len Length of src array.
324 */
325static u32 HexToInt(const u8* src, std::size_t len) {
326 u32 output = 0;
327 while (len-- > 0) {
328 output = (output << 4) | HexCharToValue(src[0]);
329 src++;
330 }
331 return output;
332}
333
334/**
335 * Converts input hex string characters into an array of equivalent of u8 bytes.
336 *
337 * @param src Pointer to array of output hex string characters.
338 * @param len Length of src array.
339 */
340static u64 HexToLong(const u8* src, std::size_t len) {
341 u64 output = 0;
342 while (len-- > 0) {
343 output = (output << 4) | HexCharToValue(src[0]);
344 src++;
345 }
346 return output;
347}
348
349/**
350 * Converts input array of u8 bytes into their equivalent hex string characters.
351 *
352 * @param dest Pointer to buffer to store output hex string characters.
353 * @param src Pointer to array of u8 bytes.
354 * @param len Length of src array.
355 */
356static void MemToGdbHex(u8* dest, const u8* src, std::size_t len) {
357 while (len-- > 0) {
358 const u8 tmp = *src++;
359 *dest++ = NibbleToHex(static_cast<u8>(tmp >> 4));
360 *dest++ = NibbleToHex(tmp);
361 }
362}
363
364/**
365 * Converts input gdb-formatted hex string characters into an array of equivalent of u8 bytes.
366 *
367 * @param dest Pointer to buffer to store u8 bytes.
368 * @param src Pointer to array of output hex string characters.
369 * @param len Length of src array.
370 */
371static void GdbHexToMem(u8* dest, const u8* src, std::size_t len) {
372 while (len-- > 0) {
373 *dest++ = static_cast<u8>((HexCharToValue(src[0]) << 4) | HexCharToValue(src[1]));
374 src += 2;
375 }
376}
377
378/**
379 * Convert a u32 into a gdb-formatted hex string.
380 *
381 * @param dest Pointer to buffer to store output hex string characters.
382 * @param v Value to convert.
383 */
384static void IntToGdbHex(u8* dest, u32 v) {
385 for (int i = 0; i < 8; i += 2) {
386 dest[i + 1] = NibbleToHex(static_cast<u8>(v >> (4 * i)));
387 dest[i] = NibbleToHex(static_cast<u8>(v >> (4 * (i + 1))));
388 }
389}
390
391/**
392 * Convert a u64 into a gdb-formatted hex string.
393 *
394 * @param dest Pointer to buffer to store output hex string characters.
395 * @param v Value to convert.
396 */
397static void LongToGdbHex(u8* dest, u64 v) {
398 for (int i = 0; i < 16; i += 2) {
399 dest[i + 1] = NibbleToHex(static_cast<u8>(v >> (4 * i)));
400 dest[i] = NibbleToHex(static_cast<u8>(v >> (4 * (i + 1))));
401 }
402}
403
404/**
405 * Convert a gdb-formatted hex string into a u32.
406 *
407 * @param src Pointer to hex string.
408 */
409static u32 GdbHexToInt(const u8* src) {
410 u32 output = 0;
411
412 for (int i = 0; i < 8; i += 2) {
413 output = (output << 4) | HexCharToValue(src[7 - i - 1]);
414 output = (output << 4) | HexCharToValue(src[7 - i]);
415 }
416
417 return output;
418}
419
420/**
421 * Convert a gdb-formatted hex string into a u64.
422 *
423 * @param src Pointer to hex string.
424 */
425static u64 GdbHexToLong(const u8* src) {
426 u64 output = 0;
427
428 for (int i = 0; i < 16; i += 2) {
429 output = (output << 4) | HexCharToValue(src[15 - i - 1]);
430 output = (output << 4) | HexCharToValue(src[15 - i]);
431 }
432
433 return output;
434}
435
436/**
437 * Convert a gdb-formatted hex string into a u128.
438 *
439 * @param src Pointer to hex string.
440 */
441static u128 GdbHexToU128(const u8* src) {
442 u128 output;
443
444 for (int i = 0; i < 16; i += 2) {
445 output[0] = (output[0] << 4) | HexCharToValue(src[15 - i - 1]);
446 output[0] = (output[0] << 4) | HexCharToValue(src[15 - i]);
447 }
448
449 for (int i = 0; i < 16; i += 2) {
450 output[1] = (output[1] << 4) | HexCharToValue(src[16 + 15 - i - 1]);
451 output[1] = (output[1] << 4) | HexCharToValue(src[16 + 15 - i]);
452 }
453
454 return output;
455}
456
457/// Read a byte from the gdb client.
458static u8 ReadByte() {
459 u8 c;
460 std::size_t received_size = recv(gdbserver_socket, reinterpret_cast<char*>(&c), 1, MSG_WAITALL);
461 if (received_size != 1) {
462 LOG_ERROR(Debug_GDBStub, "recv failed: {}", received_size);
463 Shutdown();
464 }
465
466 return c;
467}
468
469/// Calculate the checksum of the current command buffer.
470static u8 CalculateChecksum(const u8* buffer, std::size_t length) {
471 return static_cast<u8>(std::accumulate(buffer, buffer + length, u8{0},
472 [](u8 lhs, u8 rhs) { return u8(lhs + rhs); }));
473}
474
475/**
476 * Get the map of breakpoints for a given breakpoint type.
477 *
478 * @param type Type of breakpoint map.
479 */
480static BreakpointMap& GetBreakpointMap(BreakpointType type) {
481 switch (type) {
482 case BreakpointType::Execute:
483 return breakpoints_execute;
484 case BreakpointType::Read:
485 return breakpoints_read;
486 case BreakpointType::Write:
487 return breakpoints_write;
488 default:
489 return breakpoints_read;
490 }
491}
492
493/**
494 * Remove the breakpoint from the given address of the specified type.
495 *
496 * @param type Type of breakpoint.
497 * @param addr Address of breakpoint.
498 */
499static void RemoveBreakpoint(BreakpointType type, VAddr addr) {
500 BreakpointMap& p = GetBreakpointMap(type);
501
502 const auto bp = p.find(addr);
503 if (bp == p.end()) {
504 return;
505 }
506
507 LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {}",
508 bp->second.len, bp->second.addr, static_cast<int>(type));
509
510 if (type == BreakpointType::Execute) {
511 auto& system = Core::System::GetInstance();
512 system.Memory().WriteBlock(bp->second.addr, bp->second.inst.data(), bp->second.inst.size());
513 system.InvalidateCpuInstructionCaches();
514 }
515 p.erase(addr);
516}
517
518BreakpointAddress GetNextBreakpointFromAddress(VAddr addr, BreakpointType type) {
519 const BreakpointMap& p = GetBreakpointMap(type);
520 const auto next_breakpoint = p.lower_bound(addr);
521 BreakpointAddress breakpoint;
522
523 if (next_breakpoint != p.end()) {
524 breakpoint.address = next_breakpoint->first;
525 breakpoint.type = type;
526 } else {
527 breakpoint.address = 0;
528 breakpoint.type = BreakpointType::None;
529 }
530
531 return breakpoint;
532}
533
534bool CheckBreakpoint(VAddr addr, BreakpointType type) {
535 if (!IsConnected()) {
536 return false;
537 }
538
539 const BreakpointMap& p = GetBreakpointMap(type);
540 const auto bp = p.find(addr);
541
542 if (bp == p.end()) {
543 return false;
544 }
545
546 u64 len = bp->second.len;
547
548 // IDA Pro defaults to 4-byte breakpoints for all non-hardware breakpoints
549 // no matter if it's a 4-byte or 2-byte instruction. When you execute a
550 // Thumb instruction with a 4-byte breakpoint set, it will set a breakpoint on
551 // two instructions instead of the single instruction you placed the breakpoint
552 // on. So, as a way to make sure that execution breakpoints are only breaking
553 // on the instruction that was specified, set the length of an execution
554 // breakpoint to 1. This should be fine since the CPU should never begin executing
555 // an instruction anywhere except the beginning of the instruction.
556 if (type == BreakpointType::Execute) {
557 len = 1;
558 }
559
560 if (bp->second.active && (addr >= bp->second.addr && addr < bp->second.addr + len)) {
561 LOG_DEBUG(Debug_GDBStub,
562 "Found breakpoint type {} @ {:016X}, range: {:016X}"
563 " - {:016X} ({:X} bytes)",
564 static_cast<int>(type), addr, bp->second.addr, bp->second.addr + len, len);
565 return true;
566 }
567
568 return false;
569}
570
571/**
572 * Send packet to gdb client.
573 *
574 * @param packet Packet to be sent to client.
575 */
576static void SendPacket(const char packet) {
577 std::size_t sent_size = send(gdbserver_socket, &packet, 1, 0);
578 if (sent_size != 1) {
579 LOG_ERROR(Debug_GDBStub, "send failed");
580 }
581}
582
583/**
584 * Send reply to gdb client.
585 *
586 * @param reply Reply to be sent to client.
587 */
588static void SendReply(const char* reply) {
589 if (!IsConnected()) {
590 return;
591 }
592
593 LOG_DEBUG(Debug_GDBStub, "Reply: {}", reply);
594
595 memset(command_buffer, 0, sizeof(command_buffer));
596
597 command_length = static_cast<u32>(strlen(reply));
598 if (command_length + 4 > sizeof(command_buffer)) {
599 LOG_ERROR(Debug_GDBStub, "command_buffer overflow in SendReply");
600 return;
601 }
602
603 memcpy(command_buffer + 1, reply, command_length);
604
605 const u8 checksum = CalculateChecksum(command_buffer, command_length + 1);
606 command_buffer[0] = GDB_STUB_START;
607 command_buffer[command_length + 1] = GDB_STUB_END;
608 command_buffer[command_length + 2] = NibbleToHex(static_cast<u8>(checksum >> 4));
609 command_buffer[command_length + 3] = NibbleToHex(checksum);
610
611 u8* ptr = command_buffer;
612 u32 left = command_length + 4;
613 while (left > 0) {
614 const auto sent_size = send(gdbserver_socket, reinterpret_cast<char*>(ptr), left, 0);
615 if (sent_size < 0) {
616 LOG_ERROR(Debug_GDBStub, "gdb: send failed");
617 return Shutdown();
618 }
619
620 left -= static_cast<u32>(sent_size);
621 ptr += sent_size;
622 }
623}
624
625/// Handle query command from gdb client.
626static void HandleQuery() {
627 LOG_DEBUG(Debug_GDBStub, "gdb: query '{}'", command_buffer + 1);
628
629 const char* query = reinterpret_cast<const char*>(command_buffer + 1);
630
631 if (strcmp(query, "TStatus") == 0) {
632 SendReply("T0");
633 } else if (strncmp(query, "Supported", strlen("Supported")) == 0) {
634 // PacketSize needs to be large enough for target xml
635 std::string buffer = "PacketSize=2000;qXfer:features:read+;qXfer:threads:read+";
636 if (!modules.empty()) {
637 buffer += ";qXfer:libraries:read+";
638 }
639 SendReply(buffer.c_str());
640 } else if (strncmp(query, "Xfer:features:read:target.xml:",
641 strlen("Xfer:features:read:target.xml:")) == 0) {
642 SendReply(target_xml);
643 } else if (strncmp(query, "Offsets", strlen("Offsets")) == 0) {
644 const VAddr base_address =
645 Core::System::GetInstance().CurrentProcess()->PageTable().GetCodeRegionStart();
646 std::string buffer = fmt::format("TextSeg={:0x}", base_address);
647 SendReply(buffer.c_str());
648 } else if (strncmp(query, "fThreadInfo", strlen("fThreadInfo")) == 0) {
649 std::string val = "m";
650 const auto& threads = Core::System::GetInstance().GlobalScheduler().GetThreadList();
651 for (const auto& thread : threads) {
652 val += fmt::format("{:x},", thread->GetThreadID());
653 }
654 val.pop_back();
655 SendReply(val.c_str());
656 } else if (strncmp(query, "sThreadInfo", strlen("sThreadInfo")) == 0) {
657 SendReply("l");
658 } else if (strncmp(query, "Xfer:threads:read", strlen("Xfer:threads:read")) == 0) {
659 std::string buffer;
660 buffer += "l<?xml version=\"1.0\"?>";
661 buffer += "<threads>";
662 const auto& threads = Core::System::GetInstance().GlobalScheduler().GetThreadList();
663 for (const auto& thread : threads) {
664 buffer +=
665 fmt::format(R"*(<thread id="{:x}" core="{:d}" name="Thread {:x}"></thread>)*",
666 thread->GetThreadID(), thread->GetProcessorID(), thread->GetThreadID());
667 }
668 buffer += "</threads>";
669 SendReply(buffer.c_str());
670 } else if (strncmp(query, "Xfer:libraries:read", strlen("Xfer:libraries:read")) == 0) {
671 std::string buffer;
672 buffer += "l<?xml version=\"1.0\"?>";
673 buffer += "<library-list>";
674 for (const auto& module : modules) {
675 buffer +=
676 fmt::format(R"*("<library name = "{}"><segment address = "0x{:x}"/></library>)*",
677 module.name, module.beg);
678 }
679 buffer += "</library-list>";
680 SendReply(buffer.c_str());
681 } else {
682 SendReply("");
683 }
684}
685
686/// Handle set thread command from gdb client.
687static void HandleSetThread() {
688 int thread_id = -1;
689 if (command_buffer[2] != '-') {
690 thread_id = static_cast<int>(HexToInt(command_buffer + 2, command_length - 2));
691 }
692 if (thread_id >= 1) {
693 current_thread = FindThreadById(thread_id);
694 }
695 if (!current_thread) {
696 thread_id = 1;
697 current_thread = FindThreadById(thread_id);
698 }
699 if (current_thread) {
700 SendReply("OK");
701 return;
702 }
703 SendReply("E01");
704}
705
706/// Handle thread alive command from gdb client.
707static void HandleThreadAlive() {
708 int thread_id = static_cast<int>(HexToInt(command_buffer + 1, command_length - 1));
709 if (thread_id == 0) {
710 thread_id = 1;
711 }
712 if (FindThreadById(thread_id)) {
713 SendReply("OK");
714 return;
715 }
716 SendReply("E01");
717}
718
719/**
720 * Send signal packet to client.
721 *
722 * @param signal Signal to be sent to client.
723 */
724static void SendSignal(Kernel::Thread* thread, u32 signal, bool full = true) {
725 if (gdbserver_socket == -1) {
726 return;
727 }
728
729 latest_signal = signal;
730
731 if (!thread) {
732 full = false;
733 }
734
735 std::string buffer;
736 if (full) {
737 buffer = fmt::format("T{:02x}{:02x}:{:016x};{:02x}:{:016x};{:02x}:{:016x}", latest_signal,
738 PC_REGISTER, Common::swap64(RegRead(PC_REGISTER, thread)), SP_REGISTER,
739 Common::swap64(RegRead(SP_REGISTER, thread)), LR_REGISTER,
740 Common::swap64(RegRead(LR_REGISTER, thread)));
741 } else {
742 buffer = fmt::format("T{:02x}", latest_signal);
743 }
744
745 if (thread) {
746 buffer += fmt::format(";thread:{:x};", thread->GetThreadID());
747 }
748
749 SendReply(buffer.c_str());
750}
751
752/// Read command from gdb client.
753static void ReadCommand() {
754 command_length = 0;
755 memset(command_buffer, 0, sizeof(command_buffer));
756
757 u8 c = ReadByte();
758 if (c == '+') {
759 // ignore ack
760 return;
761 } else if (c == 0x03) {
762 LOG_INFO(Debug_GDBStub, "gdb: found break command");
763 halt_loop = true;
764 SendSignal(current_thread, SIGTRAP);
765 return;
766 } else if (c != GDB_STUB_START) {
767 LOG_DEBUG(Debug_GDBStub, "gdb: read invalid byte {:02X}", c);
768 return;
769 }
770
771 while ((c = ReadByte()) != GDB_STUB_END) {
772 if (command_length >= sizeof(command_buffer)) {
773 LOG_ERROR(Debug_GDBStub, "gdb: command_buffer overflow");
774 SendPacket(GDB_STUB_NACK);
775 return;
776 }
777 command_buffer[command_length++] = c;
778 }
779
780 auto checksum_received = static_cast<u32>(HexCharToValue(ReadByte()) << 4);
781 checksum_received |= static_cast<u32>(HexCharToValue(ReadByte()));
782
783 const u32 checksum_calculated = CalculateChecksum(command_buffer, command_length);
784
785 if (checksum_received != checksum_calculated) {
786 LOG_ERROR(Debug_GDBStub,
787 "gdb: invalid checksum: calculated {:02X} and read {:02X} for ${}# (length: {})",
788 checksum_calculated, checksum_received, command_buffer, command_length);
789
790 command_length = 0;
791
792 SendPacket(GDB_STUB_NACK);
793 return;
794 }
795
796 SendPacket(GDB_STUB_ACK);
797}
798
799/// Check if there is data to be read from the gdb client.
800static bool IsDataAvailable() {
801 if (!IsConnected()) {
802 return false;
803 }
804
805 fd_set fd_socket;
806
807 FD_ZERO(&fd_socket);
808 FD_SET(static_cast<u32>(gdbserver_socket), &fd_socket);
809
810 struct timeval t;
811 t.tv_sec = 0;
812 t.tv_usec = 0;
813
814 if (select(gdbserver_socket + 1, &fd_socket, nullptr, nullptr, &t) < 0) {
815 LOG_ERROR(Debug_GDBStub, "select failed");
816 return false;
817 }
818
819 return FD_ISSET(gdbserver_socket, &fd_socket) != 0;
820}
821
822/// Send requested register to gdb client.
823static void ReadRegister() {
824 static u8 reply[64];
825 memset(reply, 0, sizeof(reply));
826
827 u32 id = HexCharToValue(command_buffer[1]);
828 if (command_buffer[2] != '\0') {
829 id <<= 4;
830 id |= HexCharToValue(command_buffer[2]);
831 }
832
833 if (id <= SP_REGISTER) {
834 LongToGdbHex(reply, RegRead(id, current_thread));
835 } else if (id == PC_REGISTER) {
836 LongToGdbHex(reply, RegRead(id, current_thread));
837 } else if (id == PSTATE_REGISTER) {
838 IntToGdbHex(reply, static_cast<u32>(RegRead(id, current_thread)));
839 } else if (id >= UC_ARM64_REG_Q0 && id < FPCR_REGISTER) {
840 u128 r = FpuRead(id, current_thread);
841 LongToGdbHex(reply, r[0]);
842 LongToGdbHex(reply + 16, r[1]);
843 } else if (id == FPCR_REGISTER) {
844 u128 r = FpuRead(id, current_thread);
845 IntToGdbHex(reply, static_cast<u32>(r[0]));
846 } else if (id == FPCR_REGISTER + 1) {
847 u128 r = FpuRead(id, current_thread);
848 IntToGdbHex(reply, static_cast<u32>(r[0] >> 32));
849 }
850
851 SendReply(reinterpret_cast<char*>(reply));
852}
853
854/// Send all registers to the gdb client.
855static void ReadRegisters() {
856 static u8 buffer[GDB_BUFFER_SIZE - 4];
857 memset(buffer, 0, sizeof(buffer));
858
859 u8* bufptr = buffer;
860
861 for (u32 reg = 0; reg <= SP_REGISTER; reg++) {
862 LongToGdbHex(bufptr + reg * 16, RegRead(reg, current_thread));
863 }
864
865 bufptr += 32 * 16;
866
867 LongToGdbHex(bufptr, RegRead(PC_REGISTER, current_thread));
868
869 bufptr += 16;
870
871 IntToGdbHex(bufptr, static_cast<u32>(RegRead(PSTATE_REGISTER, current_thread)));
872
873 bufptr += 8;
874
875 u128 r;
876
877 for (u32 reg = UC_ARM64_REG_Q0; reg < FPCR_REGISTER; reg++) {
878 r = FpuRead(reg, current_thread);
879 LongToGdbHex(bufptr + reg * 32, r[0]);
880 LongToGdbHex(bufptr + reg * 32 + 16, r[1]);
881 }
882
883 bufptr += 32 * 32;
884
885 r = FpuRead(FPCR_REGISTER, current_thread);
886 IntToGdbHex(bufptr, static_cast<u32>(r[0]));
887
888 bufptr += 8;
889
890 SendReply(reinterpret_cast<char*>(buffer));
891}
892
893/// Modify data of register specified by gdb client.
894static void WriteRegister() {
895 const u8* buffer_ptr = command_buffer + 3;
896
897 u32 id = HexCharToValue(command_buffer[1]);
898 if (command_buffer[2] != '=') {
899 ++buffer_ptr;
900 id <<= 4;
901 id |= HexCharToValue(command_buffer[2]);
902 }
903
904 if (id <= SP_REGISTER) {
905 RegWrite(id, GdbHexToLong(buffer_ptr), current_thread);
906 } else if (id == PC_REGISTER) {
907 RegWrite(id, GdbHexToLong(buffer_ptr), current_thread);
908 } else if (id == PSTATE_REGISTER) {
909 RegWrite(id, GdbHexToInt(buffer_ptr), current_thread);
910 } else if (id >= UC_ARM64_REG_Q0 && id < FPCR_REGISTER) {
911 FpuWrite(id, GdbHexToU128(buffer_ptr), current_thread);
912 } else if (id == FPCR_REGISTER) {
913 } else if (id == FPCR_REGISTER + 1) {
914 }
915
916 // Update ARM context, skipping scheduler - no running threads at this point
917 Core::System::GetInstance()
918 .ArmInterface(current_core)
919 .LoadContext(current_thread->GetContext64());
920
921 SendReply("OK");
922}
923
924/// Modify all registers with data received from the client.
925static void WriteRegisters() {
926 const u8* buffer_ptr = command_buffer + 1;
927
928 if (command_buffer[0] != 'G')
929 return SendReply("E01");
930
931 for (u32 i = 0, reg = 0; reg <= FPCR_REGISTER; i++, reg++) {
932 if (reg <= SP_REGISTER) {
933 RegWrite(reg, GdbHexToLong(buffer_ptr + i * 16), current_thread);
934 } else if (reg == PC_REGISTER) {
935 RegWrite(PC_REGISTER, GdbHexToLong(buffer_ptr + i * 16), current_thread);
936 } else if (reg == PSTATE_REGISTER) {
937 RegWrite(PSTATE_REGISTER, GdbHexToInt(buffer_ptr + i * 16), current_thread);
938 } else if (reg >= UC_ARM64_REG_Q0 && reg < FPCR_REGISTER) {
939 RegWrite(reg, GdbHexToLong(buffer_ptr + i * 16), current_thread);
940 } else if (reg == FPCR_REGISTER) {
941 RegWrite(FPCR_REGISTER, GdbHexToLong(buffer_ptr + i * 16), current_thread);
942 } else if (reg == FPCR_REGISTER + 1) {
943 RegWrite(FPCR_REGISTER, GdbHexToLong(buffer_ptr + i * 16), current_thread);
944 }
945 }
946
947 // Update ARM context, skipping scheduler - no running threads at this point
948 Core::System::GetInstance()
949 .ArmInterface(current_core)
950 .LoadContext(current_thread->GetContext64());
951
952 SendReply("OK");
953}
954
955/// Read location in memory specified by gdb client.
956static void ReadMemory() {
957 static u8 reply[GDB_BUFFER_SIZE - 4];
958
959 auto start_offset = command_buffer + 1;
960 const auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
961 const VAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset));
962
963 start_offset = addr_pos + 1;
964 const u64 len =
965 HexToLong(start_offset, static_cast<u64>((command_buffer + command_length) - start_offset));
966
967 LOG_DEBUG(Debug_GDBStub, "gdb: addr: {:016X} len: {:016X}", addr, len);
968
969 if (len * 2 > sizeof(reply)) {
970 SendReply("E01");
971 }
972
973 auto& memory = Core::System::GetInstance().Memory();
974 if (!memory.IsValidVirtualAddress(addr)) {
975 return SendReply("E00");
976 }
977
978 std::vector<u8> data(len);
979 memory.ReadBlock(addr, data.data(), len);
980
981 MemToGdbHex(reply, data.data(), len);
982 reply[len * 2] = '\0';
983 SendReply(reinterpret_cast<char*>(reply));
984}
985
986/// Modify location in memory with data received from the gdb client.
987static void WriteMemory() {
988 auto start_offset = command_buffer + 1;
989 const auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
990 const VAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset));
991
992 start_offset = addr_pos + 1;
993 const auto len_pos = std::find(start_offset, command_buffer + command_length, ':');
994 const u64 len = HexToLong(start_offset, static_cast<u64>(len_pos - start_offset));
995
996 auto& system = Core::System::GetInstance();
997 auto& memory = system.Memory();
998 if (!memory.IsValidVirtualAddress(addr)) {
999 return SendReply("E00");
1000 }
1001
1002 std::vector<u8> data(len);
1003 GdbHexToMem(data.data(), len_pos + 1, len);
1004 memory.WriteBlock(addr, data.data(), len);
1005 system.InvalidateCpuInstructionCaches();
1006 SendReply("OK");
1007}
1008
1009void Break(bool is_memory_break) {
1010 send_trap = true;
1011
1012 memory_break = is_memory_break;
1013}
1014
1015/// Tell the CPU that it should perform a single step.
1016static void Step() {
1017 if (command_length > 1) {
1018 RegWrite(PC_REGISTER, GdbHexToLong(command_buffer + 1), current_thread);
1019 // Update ARM context, skipping scheduler - no running threads at this point
1020 Core::System::GetInstance()
1021 .ArmInterface(current_core)
1022 .LoadContext(current_thread->GetContext64());
1023 }
1024 step_loop = true;
1025 halt_loop = true;
1026 send_trap = true;
1027 Core::System::GetInstance().InvalidateCpuInstructionCaches();
1028}
1029
1030/// Tell the CPU if we hit a memory breakpoint.
1031bool IsMemoryBreak() {
1032 if (!IsConnected()) {
1033 return false;
1034 }
1035
1036 return memory_break;
1037}
1038
1039/// Tell the CPU to continue executing.
1040static void Continue() {
1041 memory_break = false;
1042 step_loop = false;
1043 halt_loop = false;
1044 Core::System::GetInstance().InvalidateCpuInstructionCaches();
1045}
1046
1047/**
1048 * Commit breakpoint to list of breakpoints.
1049 *
1050 * @param type Type of breakpoint.
1051 * @param addr Address of breakpoint.
1052 * @param len Length of breakpoint.
1053 */
1054static bool CommitBreakpoint(BreakpointType type, VAddr addr, u64 len) {
1055 BreakpointMap& p = GetBreakpointMap(type);
1056
1057 Breakpoint breakpoint;
1058 breakpoint.active = true;
1059 breakpoint.addr = addr;
1060 breakpoint.len = len;
1061
1062 auto& system = Core::System::GetInstance();
1063 auto& memory = system.Memory();
1064 memory.ReadBlock(addr, breakpoint.inst.data(), breakpoint.inst.size());
1065
1066 static constexpr std::array<u8, 4> btrap{0x00, 0x7d, 0x20, 0xd4};
1067 if (type == BreakpointType::Execute) {
1068 memory.WriteBlock(addr, btrap.data(), btrap.size());
1069 system.InvalidateCpuInstructionCaches();
1070 }
1071 p.insert({addr, breakpoint});
1072
1073 LOG_DEBUG(Debug_GDBStub, "gdb: added {} breakpoint: {:016X} bytes at {:016X}",
1074 static_cast<int>(type), breakpoint.len, breakpoint.addr);
1075
1076 return true;
1077}
1078
1079/// Handle add breakpoint command from gdb client.
1080static void AddBreakpoint() {
1081 BreakpointType type;
1082
1083 u8 type_id = HexCharToValue(command_buffer[1]);
1084 switch (type_id) {
1085 case 0:
1086 case 1:
1087 type = BreakpointType::Execute;
1088 break;
1089 case 2:
1090 type = BreakpointType::Write;
1091 break;
1092 case 3:
1093 type = BreakpointType::Read;
1094 break;
1095 case 4:
1096 type = BreakpointType::Access;
1097 break;
1098 default:
1099 return SendReply("E01");
1100 }
1101
1102 auto start_offset = command_buffer + 3;
1103 auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
1104 VAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset));
1105
1106 start_offset = addr_pos + 1;
1107 u64 len =
1108 HexToLong(start_offset, static_cast<u64>((command_buffer + command_length) - start_offset));
1109
1110 if (type == BreakpointType::Access) {
1111 // Access is made up of Read and Write types, so add both breakpoints
1112 type = BreakpointType::Read;
1113
1114 if (!CommitBreakpoint(type, addr, len)) {
1115 return SendReply("E02");
1116 }
1117
1118 type = BreakpointType::Write;
1119 }
1120
1121 if (!CommitBreakpoint(type, addr, len)) {
1122 return SendReply("E02");
1123 }
1124
1125 SendReply("OK");
1126}
1127
1128/// Handle remove breakpoint command from gdb client.
1129static void RemoveBreakpoint() {
1130 BreakpointType type;
1131
1132 u8 type_id = HexCharToValue(command_buffer[1]);
1133 switch (type_id) {
1134 case 0:
1135 case 1:
1136 type = BreakpointType::Execute;
1137 break;
1138 case 2:
1139 type = BreakpointType::Write;
1140 break;
1141 case 3:
1142 type = BreakpointType::Read;
1143 break;
1144 case 4:
1145 type = BreakpointType::Access;
1146 break;
1147 default:
1148 return SendReply("E01");
1149 }
1150
1151 auto start_offset = command_buffer + 3;
1152 auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
1153 VAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset));
1154
1155 if (type == BreakpointType::Access) {
1156 // Access is made up of Read and Write types, so add both breakpoints
1157 type = BreakpointType::Read;
1158 RemoveBreakpoint(type, addr);
1159
1160 type = BreakpointType::Write;
1161 }
1162
1163 RemoveBreakpoint(type, addr);
1164 SendReply("OK");
1165}
1166
1167void HandlePacket() {
1168 if (!IsConnected()) {
1169 if (defer_start) {
1170 ToggleServer(true);
1171 }
1172 return;
1173 }
1174
1175 if (!IsDataAvailable()) {
1176 return;
1177 }
1178
1179 ReadCommand();
1180 if (command_length == 0) {
1181 return;
1182 }
1183
1184 LOG_DEBUG(Debug_GDBStub, "Packet: {}", command_buffer);
1185
1186 switch (command_buffer[0]) {
1187 case 'q':
1188 HandleQuery();
1189 break;
1190 case 'H':
1191 HandleSetThread();
1192 break;
1193 case '?':
1194 SendSignal(current_thread, latest_signal);
1195 break;
1196 case 'k':
1197 Shutdown();
1198 LOG_INFO(Debug_GDBStub, "killed by gdb");
1199 return;
1200 case 'g':
1201 ReadRegisters();
1202 break;
1203 case 'G':
1204 WriteRegisters();
1205 break;
1206 case 'p':
1207 ReadRegister();
1208 break;
1209 case 'P':
1210 WriteRegister();
1211 break;
1212 case 'm':
1213 ReadMemory();
1214 break;
1215 case 'M':
1216 WriteMemory();
1217 break;
1218 case 's':
1219 Step();
1220 return;
1221 case 'C':
1222 case 'c':
1223 Continue();
1224 return;
1225 case 'z':
1226 RemoveBreakpoint();
1227 break;
1228 case 'Z':
1229 AddBreakpoint();
1230 break;
1231 case 'T':
1232 HandleThreadAlive();
1233 break;
1234 default:
1235 SendReply("");
1236 break;
1237 }
1238}
1239
1240void SetServerPort(u16 port) {
1241 gdbstub_port = port;
1242}
1243
1244void ToggleServer(bool status) {
1245 if (status) {
1246 server_enabled = status;
1247
1248 // Start server
1249 if (!IsConnected() && Core::System::GetInstance().IsPoweredOn()) {
1250 Init();
1251 }
1252 } else {
1253 // Stop server
1254 if (IsConnected()) {
1255 Shutdown();
1256 }
1257
1258 server_enabled = status;
1259 }
1260}
1261
1262void DeferStart() {
1263 defer_start = true;
1264}
1265
1266static void Init(u16 port) {
1267 if (!server_enabled) {
1268 // Set the halt loop to false in case the user enabled the gdbstub mid-execution.
1269 // This way the CPU can still execute normally.
1270 halt_loop = false;
1271 step_loop = false;
1272 return;
1273 }
1274
1275 // Setup initial gdbstub status
1276 halt_loop = true;
1277 step_loop = false;
1278
1279 breakpoints_execute.clear();
1280 breakpoints_read.clear();
1281 breakpoints_write.clear();
1282
1283 modules.clear();
1284
1285 // Start gdb server
1286 LOG_INFO(Debug_GDBStub, "Starting GDB server on port {}...", port);
1287
1288 sockaddr_in saddr_server = {};
1289 saddr_server.sin_family = AF_INET;
1290 saddr_server.sin_port = htons(port);
1291 saddr_server.sin_addr.s_addr = INADDR_ANY;
1292
1293#ifdef _WIN32
1294 WSAStartup(MAKEWORD(2, 2), &InitData);
1295#endif
1296
1297 int tmpsock = static_cast<int>(socket(PF_INET, SOCK_STREAM, 0));
1298 if (tmpsock == -1) {
1299 LOG_ERROR(Debug_GDBStub, "Failed to create gdb socket");
1300 }
1301
1302 // Set socket to SO_REUSEADDR so it can always bind on the same port
1303 int reuse_enabled = 1;
1304 if (setsockopt(tmpsock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse_enabled,
1305 sizeof(reuse_enabled)) < 0) {
1306 LOG_ERROR(Debug_GDBStub, "Failed to set gdb socket option");
1307 }
1308
1309 const sockaddr* server_addr = reinterpret_cast<const sockaddr*>(&saddr_server);
1310 socklen_t server_addrlen = sizeof(saddr_server);
1311 if (bind(tmpsock, server_addr, server_addrlen) < 0) {
1312 LOG_ERROR(Debug_GDBStub, "Failed to bind gdb socket");
1313 }
1314
1315 if (listen(tmpsock, 1) < 0) {
1316 LOG_ERROR(Debug_GDBStub, "Failed to listen to gdb socket");
1317 }
1318
1319 // Wait for gdb to connect
1320 LOG_INFO(Debug_GDBStub, "Waiting for gdb to connect...");
1321 sockaddr_in saddr_client;
1322 sockaddr* client_addr = reinterpret_cast<sockaddr*>(&saddr_client);
1323 socklen_t client_addrlen = sizeof(saddr_client);
1324 gdbserver_socket = static_cast<int>(accept(tmpsock, client_addr, &client_addrlen));
1325 if (gdbserver_socket < 0) {
1326 // In the case that we couldn't start the server for whatever reason, just start CPU
1327 // execution like normal.
1328 halt_loop = false;
1329 step_loop = false;
1330
1331 LOG_ERROR(Debug_GDBStub, "Failed to accept gdb client");
1332 } else {
1333 LOG_INFO(Debug_GDBStub, "Client connected.");
1334 saddr_client.sin_addr.s_addr = ntohl(saddr_client.sin_addr.s_addr);
1335 }
1336
1337 // Clean up temporary socket if it's still alive at this point.
1338 if (tmpsock != -1) {
1339 shutdown(tmpsock, SHUT_RDWR);
1340 }
1341}
1342
1343void Init() {
1344 Init(gdbstub_port);
1345}
1346
1347void Shutdown() {
1348 if (!server_enabled) {
1349 return;
1350 }
1351 defer_start = false;
1352
1353 LOG_INFO(Debug_GDBStub, "Stopping GDB ...");
1354 if (gdbserver_socket != -1) {
1355 shutdown(gdbserver_socket, SHUT_RDWR);
1356 gdbserver_socket = -1;
1357 }
1358
1359#ifdef _WIN32
1360 WSACleanup();
1361#endif
1362
1363 LOG_INFO(Debug_GDBStub, "GDB stopped.");
1364}
1365
1366bool IsServerEnabled() {
1367 return server_enabled;
1368}
1369
1370bool IsConnected() {
1371 return IsServerEnabled() && gdbserver_socket != -1;
1372}
1373
1374bool GetCpuHaltFlag() {
1375 return halt_loop;
1376}
1377
1378bool GetCpuStepFlag() {
1379 return step_loop;
1380}
1381
1382void SetCpuStepFlag(bool is_step) {
1383 step_loop = is_step;
1384}
1385
1386void SendTrap(Kernel::Thread* thread, int trap) {
1387 if (!send_trap) {
1388 return;
1389 }
1390
1391 current_thread = thread;
1392 SendSignal(thread, trap);
1393
1394 halt_loop = true;
1395 send_trap = false;
1396}
1397}; // namespace GDBStub
diff --git a/src/core/gdbstub/gdbstub.h b/src/core/gdbstub/gdbstub.h
deleted file mode 100644
index 8fe3c320b..000000000
--- a/src/core/gdbstub/gdbstub.h
+++ /dev/null
@@ -1,114 +0,0 @@
1// Copyright 2013 Dolphin Emulator Project
2// Licensed under GPLv2+
3// Refer to the license.txt file included.
4
5// Originally written by Sven Peter <sven@fail0verflow.com> for anergistic.
6
7#pragma once
8
9#include <string>
10#include "common/common_types.h"
11#include "core/hle/kernel/thread.h"
12
13namespace GDBStub {
14
15/// Breakpoint Method
16enum class BreakpointType {
17 None, ///< None
18 Execute, ///< Execution Breakpoint
19 Read, ///< Read Breakpoint
20 Write, ///< Write Breakpoint
21 Access ///< Access (R/W) Breakpoint
22};
23
24struct BreakpointAddress {
25 VAddr address;
26 BreakpointType type;
27};
28
29/**
30 * Set the port the gdbstub should use to listen for connections.
31 *
32 * @param port Port to listen for connection
33 */
34void SetServerPort(u16 port);
35
36/**
37 * Starts or stops the server if possible.
38 *
39 * @param status Set the server to enabled or disabled.
40 */
41void ToggleServer(bool status);
42
43/// Start the gdbstub server.
44void Init();
45
46/**
47 * Defer initialization of the gdbstub to the first packet processing functions.
48 * This avoids a case where the gdbstub thread is frozen after initialization
49 * and fails to respond in time to packets.
50 */
51void DeferStart();
52
53/// Stop gdbstub server.
54void Shutdown();
55
56/// Checks if the gdbstub server is enabled.
57bool IsServerEnabled();
58
59/// Returns true if there is an active socket connection.
60bool IsConnected();
61
62/// Register module.
63void RegisterModule(std::string name, VAddr beg, VAddr end, bool add_elf_ext = true);
64
65/**
66 * Signal to the gdbstub server that it should halt CPU execution.
67 *
68 * @param is_memory_break If true, the break resulted from a memory breakpoint.
69 */
70void Break(bool is_memory_break = false);
71
72/// Determine if there was a memory breakpoint.
73bool IsMemoryBreak();
74
75/// Read and handle packet from gdb client.
76void HandlePacket();
77
78/**
79 * Get the nearest breakpoint of the specified type at the given address.
80 *
81 * @param addr Address to search from.
82 * @param type Type of breakpoint.
83 */
84BreakpointAddress GetNextBreakpointFromAddress(VAddr addr, GDBStub::BreakpointType type);
85
86/**
87 * Check if a breakpoint of the specified type exists at the given address.
88 *
89 * @param addr Address of breakpoint.
90 * @param type Type of breakpoint.
91 */
92bool CheckBreakpoint(VAddr addr, GDBStub::BreakpointType type);
93
94/// If set to true, the CPU will halt at the beginning of the next CPU loop.
95bool GetCpuHaltFlag();
96
97/// If set to true and the CPU is halted, the CPU will step one instruction.
98bool GetCpuStepFlag();
99
100/**
101 * When set to true, the CPU will step one instruction when the CPU is halted next.
102 *
103 * @param is_step
104 */
105void SetCpuStepFlag(bool is_step);
106
107/**
108 * Send trap signal from thread back to the gdbstub server.
109 *
110 * @param thread Sending thread.
111 * @param trap Trap no.
112 */
113void SendTrap(Kernel::Thread* thread, int trap);
114} // namespace GDBStub
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp
index c2c11dbcb..6981f8ee7 100644
--- a/src/core/hle/service/acc/acc.cpp
+++ b/src/core/hle/service/acc/acc.cpp
@@ -47,8 +47,8 @@ static constexpr u32 SanitizeJPEGSize(std::size_t size) {
47 47
48class IManagerForSystemService final : public ServiceFramework<IManagerForSystemService> { 48class IManagerForSystemService final : public ServiceFramework<IManagerForSystemService> {
49public: 49public:
50 explicit IManagerForSystemService(Common::UUID user_id) 50 explicit IManagerForSystemService(Core::System& system_, Common::UUID)
51 : ServiceFramework("IManagerForSystemService") { 51 : ServiceFramework{system_, "IManagerForSystemService"} {
52 // clang-format off 52 // clang-format off
53 static const FunctionInfo functions[] = { 53 static const FunctionInfo functions[] = {
54 {0, nullptr, "CheckAvailability"}, 54 {0, nullptr, "CheckAvailability"},
@@ -83,8 +83,8 @@ public:
83// 3.0.0+ 83// 3.0.0+
84class IFloatingRegistrationRequest final : public ServiceFramework<IFloatingRegistrationRequest> { 84class IFloatingRegistrationRequest final : public ServiceFramework<IFloatingRegistrationRequest> {
85public: 85public:
86 explicit IFloatingRegistrationRequest(Common::UUID user_id) 86 explicit IFloatingRegistrationRequest(Core::System& system_, Common::UUID)
87 : ServiceFramework("IFloatingRegistrationRequest") { 87 : ServiceFramework{system_, "IFloatingRegistrationRequest"} {
88 // clang-format off 88 // clang-format off
89 static const FunctionInfo functions[] = { 89 static const FunctionInfo functions[] = {
90 {0, nullptr, "GetSessionId"}, 90 {0, nullptr, "GetSessionId"},
@@ -108,7 +108,8 @@ public:
108 108
109class IAdministrator final : public ServiceFramework<IAdministrator> { 109class IAdministrator final : public ServiceFramework<IAdministrator> {
110public: 110public:
111 explicit IAdministrator(Common::UUID user_id) : ServiceFramework("IAdministrator") { 111 explicit IAdministrator(Core::System& system_, Common::UUID)
112 : ServiceFramework{system_, "IAdministrator"} {
112 // clang-format off 113 // clang-format off
113 static const FunctionInfo functions[] = { 114 static const FunctionInfo functions[] = {
114 {0, nullptr, "CheckAvailability"}, 115 {0, nullptr, "CheckAvailability"},
@@ -165,8 +166,8 @@ public:
165 166
166class IAuthorizationRequest final : public ServiceFramework<IAuthorizationRequest> { 167class IAuthorizationRequest final : public ServiceFramework<IAuthorizationRequest> {
167public: 168public:
168 explicit IAuthorizationRequest(Common::UUID user_id) 169 explicit IAuthorizationRequest(Core::System& system_, Common::UUID)
169 : ServiceFramework("IAuthorizationRequest") { 170 : ServiceFramework{system_, "IAuthorizationRequest"} {
170 // clang-format off 171 // clang-format off
171 static const FunctionInfo functions[] = { 172 static const FunctionInfo functions[] = {
172 {0, nullptr, "GetSessionId"}, 173 {0, nullptr, "GetSessionId"},
@@ -184,7 +185,8 @@ public:
184 185
185class IOAuthProcedure final : public ServiceFramework<IOAuthProcedure> { 186class IOAuthProcedure final : public ServiceFramework<IOAuthProcedure> {
186public: 187public:
187 explicit IOAuthProcedure(Common::UUID user_id) : ServiceFramework("IOAuthProcedure") { 188 explicit IOAuthProcedure(Core::System& system_, Common::UUID)
189 : ServiceFramework{system_, "IOAuthProcedure"} {
188 // clang-format off 190 // clang-format off
189 static const FunctionInfo functions[] = { 191 static const FunctionInfo functions[] = {
190 {0, nullptr, "PrepareAsync"}, 192 {0, nullptr, "PrepareAsync"},
@@ -202,8 +204,8 @@ public:
202// 3.0.0+ 204// 3.0.0+
203class IOAuthProcedureForExternalNsa final : public ServiceFramework<IOAuthProcedureForExternalNsa> { 205class IOAuthProcedureForExternalNsa final : public ServiceFramework<IOAuthProcedureForExternalNsa> {
204public: 206public:
205 explicit IOAuthProcedureForExternalNsa(Common::UUID user_id) 207 explicit IOAuthProcedureForExternalNsa(Core::System& system_, Common::UUID)
206 : ServiceFramework("IOAuthProcedureForExternalNsa") { 208 : ServiceFramework{system_, "IOAuthProcedureForExternalNsa"} {
207 // clang-format off 209 // clang-format off
208 static const FunctionInfo functions[] = { 210 static const FunctionInfo functions[] = {
209 {0, nullptr, "PrepareAsync"}, 211 {0, nullptr, "PrepareAsync"},
@@ -225,8 +227,8 @@ public:
225class IOAuthProcedureForNintendoAccountLinkage final 227class IOAuthProcedureForNintendoAccountLinkage final
226 : public ServiceFramework<IOAuthProcedureForNintendoAccountLinkage> { 228 : public ServiceFramework<IOAuthProcedureForNintendoAccountLinkage> {
227public: 229public:
228 explicit IOAuthProcedureForNintendoAccountLinkage(Common::UUID user_id) 230 explicit IOAuthProcedureForNintendoAccountLinkage(Core::System& system_, Common::UUID)
229 : ServiceFramework("IOAuthProcedureForNintendoAccountLinkage") { 231 : ServiceFramework{system_, "IOAuthProcedureForNintendoAccountLinkage"} {
230 // clang-format off 232 // clang-format off
231 static const FunctionInfo functions[] = { 233 static const FunctionInfo functions[] = {
232 {0, nullptr, "PrepareAsync"}, 234 {0, nullptr, "PrepareAsync"},
@@ -246,7 +248,8 @@ public:
246 248
247class INotifier final : public ServiceFramework<INotifier> { 249class INotifier final : public ServiceFramework<INotifier> {
248public: 250public:
249 explicit INotifier(Common::UUID user_id) : ServiceFramework("INotifier") { 251 explicit INotifier(Core::System& system_, Common::UUID)
252 : ServiceFramework{system_, "INotifier"} {
250 // clang-format off 253 // clang-format off
251 static const FunctionInfo functions[] = { 254 static const FunctionInfo functions[] = {
252 {0, nullptr, "GetSystemEvent"}, 255 {0, nullptr, "GetSystemEvent"},
@@ -259,9 +262,9 @@ public:
259 262
260class IProfileCommon : public ServiceFramework<IProfileCommon> { 263class IProfileCommon : public ServiceFramework<IProfileCommon> {
261public: 264public:
262 explicit IProfileCommon(const char* name, bool editor_commands, Common::UUID user_id, 265 explicit IProfileCommon(Core::System& system_, const char* name, bool editor_commands,
263 ProfileManager& profile_manager) 266 Common::UUID user_id_, ProfileManager& profile_manager_)
264 : ServiceFramework(name), profile_manager(profile_manager), user_id(user_id) { 267 : ServiceFramework{system_, name}, profile_manager{profile_manager_}, user_id{user_id_} {
265 static const FunctionInfo functions[] = { 268 static const FunctionInfo functions[] = {
266 {0, &IProfileCommon::Get, "Get"}, 269 {0, &IProfileCommon::Get, "Get"},
267 {1, &IProfileCommon::GetBase, "GetBase"}, 270 {1, &IProfileCommon::GetBase, "GetBase"},
@@ -427,19 +430,21 @@ protected:
427 430
428class IProfile final : public IProfileCommon { 431class IProfile final : public IProfileCommon {
429public: 432public:
430 IProfile(Common::UUID user_id, ProfileManager& profile_manager) 433 explicit IProfile(Core::System& system_, Common::UUID user_id_,
431 : IProfileCommon("IProfile", false, user_id, profile_manager) {} 434 ProfileManager& profile_manager_)
435 : IProfileCommon{system_, "IProfile", false, user_id_, profile_manager_} {}
432}; 436};
433 437
434class IProfileEditor final : public IProfileCommon { 438class IProfileEditor final : public IProfileCommon {
435public: 439public:
436 IProfileEditor(Common::UUID user_id, ProfileManager& profile_manager) 440 explicit IProfileEditor(Core::System& system_, Common::UUID user_id_,
437 : IProfileCommon("IProfileEditor", true, user_id, profile_manager) {} 441 ProfileManager& profile_manager_)
442 : IProfileCommon{system_, "IProfileEditor", true, user_id_, profile_manager_} {}
438}; 443};
439 444
440class IAsyncContext final : public ServiceFramework<IAsyncContext> { 445class IAsyncContext final : public ServiceFramework<IAsyncContext> {
441public: 446public:
442 explicit IAsyncContext(Common::UUID user_id) : ServiceFramework("IAsyncContext") { 447 explicit IAsyncContext(Core::System& system_) : ServiceFramework{system_, "IAsyncContext"} {
443 // clang-format off 448 // clang-format off
444 static const FunctionInfo functions[] = { 449 static const FunctionInfo functions[] = {
445 {0, nullptr, "GetSystemEvent"}, 450 {0, nullptr, "GetSystemEvent"},
@@ -455,7 +460,8 @@ public:
455 460
456class ISessionObject final : public ServiceFramework<ISessionObject> { 461class ISessionObject final : public ServiceFramework<ISessionObject> {
457public: 462public:
458 explicit ISessionObject(Common::UUID user_id) : ServiceFramework("ISessionObject") { 463 explicit ISessionObject(Core::System& system_, Common::UUID)
464 : ServiceFramework{system_, "ISessionObject"} {
459 // clang-format off 465 // clang-format off
460 static const FunctionInfo functions[] = { 466 static const FunctionInfo functions[] = {
461 {999, nullptr, "Dummy"}, 467 {999, nullptr, "Dummy"},
@@ -468,7 +474,8 @@ public:
468 474
469class IGuestLoginRequest final : public ServiceFramework<IGuestLoginRequest> { 475class IGuestLoginRequest final : public ServiceFramework<IGuestLoginRequest> {
470public: 476public:
471 explicit IGuestLoginRequest(Common::UUID) : ServiceFramework("IGuestLoginRequest") { 477 explicit IGuestLoginRequest(Core::System& system_, Common::UUID)
478 : ServiceFramework{system_, "IGuestLoginRequest"} {
472 // clang-format off 479 // clang-format off
473 static const FunctionInfo functions[] = { 480 static const FunctionInfo functions[] = {
474 {0, nullptr, "GetSessionId"}, 481 {0, nullptr, "GetSessionId"},
@@ -487,8 +494,8 @@ public:
487 494
488class IManagerForApplication final : public ServiceFramework<IManagerForApplication> { 495class IManagerForApplication final : public ServiceFramework<IManagerForApplication> {
489public: 496public:
490 explicit IManagerForApplication(Common::UUID user_id) 497 explicit IManagerForApplication(Core::System& system_, Common::UUID user_id_)
491 : ServiceFramework("IManagerForApplication"), user_id(user_id) { 498 : ServiceFramework{system_, "IManagerForApplication"}, user_id{user_id_} {
492 // clang-format off 499 // clang-format off
493 static const FunctionInfo functions[] = { 500 static const FunctionInfo functions[] = {
494 {0, &IManagerForApplication::CheckAvailability, "CheckAvailability"}, 501 {0, &IManagerForApplication::CheckAvailability, "CheckAvailability"},
@@ -534,8 +541,8 @@ private:
534class IAsyncNetworkServiceLicenseKindContext final 541class IAsyncNetworkServiceLicenseKindContext final
535 : public ServiceFramework<IAsyncNetworkServiceLicenseKindContext> { 542 : public ServiceFramework<IAsyncNetworkServiceLicenseKindContext> {
536public: 543public:
537 explicit IAsyncNetworkServiceLicenseKindContext(Common::UUID user_id) 544 explicit IAsyncNetworkServiceLicenseKindContext(Core::System& system_, Common::UUID)
538 : ServiceFramework("IAsyncNetworkServiceLicenseKindContext") { 545 : ServiceFramework{system_, "IAsyncNetworkServiceLicenseKindContext"} {
539 // clang-format off 546 // clang-format off
540 static const FunctionInfo functions[] = { 547 static const FunctionInfo functions[] = {
541 {0, nullptr, "GetSystemEvent"}, 548 {0, nullptr, "GetSystemEvent"},
@@ -554,8 +561,8 @@ public:
554class IOAuthProcedureForUserRegistration final 561class IOAuthProcedureForUserRegistration final
555 : public ServiceFramework<IOAuthProcedureForUserRegistration> { 562 : public ServiceFramework<IOAuthProcedureForUserRegistration> {
556public: 563public:
557 explicit IOAuthProcedureForUserRegistration(Common::UUID user_id) 564 explicit IOAuthProcedureForUserRegistration(Core::System& system_, Common::UUID)
558 : ServiceFramework("IOAuthProcedureForUserRegistration") { 565 : ServiceFramework{system_, "IOAuthProcedureForUserRegistration"} {
559 // clang-format off 566 // clang-format off
560 static const FunctionInfo functions[] = { 567 static const FunctionInfo functions[] = {
561 {0, nullptr, "PrepareAsync"}, 568 {0, nullptr, "PrepareAsync"},
@@ -578,7 +585,7 @@ public:
578 585
579class DAUTH_O final : public ServiceFramework<DAUTH_O> { 586class DAUTH_O final : public ServiceFramework<DAUTH_O> {
580public: 587public:
581 explicit DAUTH_O(Common::UUID) : ServiceFramework("dauth:o") { 588 explicit DAUTH_O(Core::System& system_, Common::UUID) : ServiceFramework{system_, "dauth:o"} {
582 // clang-format off 589 // clang-format off
583 static const FunctionInfo functions[] = { 590 static const FunctionInfo functions[] = {
584 {0, nullptr, "EnsureAuthenticationTokenCacheAsync"}, // [5.0.0-5.1.0] GeneratePostData 591 {0, nullptr, "EnsureAuthenticationTokenCacheAsync"}, // [5.0.0-5.1.0] GeneratePostData
@@ -597,7 +604,8 @@ public:
597// 6.0.0+ 604// 6.0.0+
598class IAsyncResult final : public ServiceFramework<IAsyncResult> { 605class IAsyncResult final : public ServiceFramework<IAsyncResult> {
599public: 606public:
600 explicit IAsyncResult(Common::UUID user_id) : ServiceFramework("IAsyncResult") { 607 explicit IAsyncResult(Core::System& system_, Common::UUID)
608 : ServiceFramework{system_, "IAsyncResult"} {
601 // clang-format off 609 // clang-format off
602 static const FunctionInfo functions[] = { 610 static const FunctionInfo functions[] = {
603 {0, nullptr, "GetResult"}, 611 {0, nullptr, "GetResult"},
@@ -656,7 +664,7 @@ void Module::Interface::GetProfile(Kernel::HLERequestContext& ctx) {
656 664
657 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 665 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
658 rb.Push(RESULT_SUCCESS); 666 rb.Push(RESULT_SUCCESS);
659 rb.PushIpcInterface<IProfile>(user_id, *profile_manager); 667 rb.PushIpcInterface<IProfile>(system, user_id, *profile_manager);
660} 668}
661 669
662void Module::Interface::IsUserRegistrationRequestPermitted(Kernel::HLERequestContext& ctx) { 670void Module::Interface::IsUserRegistrationRequestPermitted(Kernel::HLERequestContext& ctx) {
@@ -731,7 +739,7 @@ void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestCo
731 LOG_DEBUG(Service_ACC, "called"); 739 LOG_DEBUG(Service_ACC, "called");
732 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 740 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
733 rb.Push(RESULT_SUCCESS); 741 rb.Push(RESULT_SUCCESS);
734 rb.PushIpcInterface<IManagerForApplication>(profile_manager->GetLastOpenedUser()); 742 rb.PushIpcInterface<IManagerForApplication>(system, profile_manager->GetLastOpenedUser());
735} 743}
736 744
737void Module::Interface::IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx) { 745void Module::Interface::IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx) {
@@ -769,7 +777,7 @@ void Module::Interface::GetProfileEditor(Kernel::HLERequestContext& ctx) {
769 777
770 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 778 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
771 rb.Push(RESULT_SUCCESS); 779 rb.Push(RESULT_SUCCESS);
772 rb.PushIpcInterface<IProfileEditor>(user_id, *profile_manager); 780 rb.PushIpcInterface<IProfileEditor>(system, user_id, *profile_manager);
773} 781}
774 782
775void Module::Interface::ListQualifiedUsers(Kernel::HLERequestContext& ctx) { 783void Module::Interface::ListQualifiedUsers(Kernel::HLERequestContext& ctx) {
@@ -791,7 +799,7 @@ void Module::Interface::LoadOpenContext(Kernel::HLERequestContext& ctx) {
791 // TODO: Find the differences between this and GetBaasAccountManagerForApplication 799 // TODO: Find the differences between this and GetBaasAccountManagerForApplication
792 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 800 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
793 rb.Push(RESULT_SUCCESS); 801 rb.Push(RESULT_SUCCESS);
794 rb.PushIpcInterface<IManagerForApplication>(profile_manager->GetLastOpenedUser()); 802 rb.PushIpcInterface<IManagerForApplication>(system, profile_manager->GetLastOpenedUser());
795} 803}
796 804
797void Module::Interface::ListOpenContextStoredUsers(Kernel::HLERequestContext& ctx) { 805void Module::Interface::ListOpenContextStoredUsers(Kernel::HLERequestContext& ctx) {
@@ -827,11 +835,11 @@ void Module::Interface::TrySelectUserWithoutInteraction(Kernel::HLERequestContex
827 rb.PushRaw<u128>(profile_manager->GetUser(0)->uuid); 835 rb.PushRaw<u128>(profile_manager->GetUser(0)->uuid);
828} 836}
829 837
830Module::Interface::Interface(std::shared_ptr<Module> module, 838Module::Interface::Interface(std::shared_ptr<Module> module_,
831 std::shared_ptr<ProfileManager> profile_manager, Core::System& system, 839 std::shared_ptr<ProfileManager> profile_manager_,
832 const char* name) 840 Core::System& system_, const char* name)
833 : ServiceFramework(name), module(std::move(module)), 841 : ServiceFramework{system_, name}, module{std::move(module_)}, profile_manager{std::move(
834 profile_manager(std::move(profile_manager)), system(system) {} 842 profile_manager_)} {}
835 843
836Module::Interface::~Interface() = default; 844Module::Interface::~Interface() = default;
837 845
diff --git a/src/core/hle/service/acc/acc.h b/src/core/hle/service/acc/acc.h
index c611efd89..ab8edc049 100644
--- a/src/core/hle/service/acc/acc.h
+++ b/src/core/hle/service/acc/acc.h
@@ -15,8 +15,8 @@ class Module final {
15public: 15public:
16 class Interface : public ServiceFramework<Interface> { 16 class Interface : public ServiceFramework<Interface> {
17 public: 17 public:
18 explicit Interface(std::shared_ptr<Module> module, 18 explicit Interface(std::shared_ptr<Module> module_,
19 std::shared_ptr<ProfileManager> profile_manager, Core::System& system, 19 std::shared_ptr<ProfileManager> profile_manager_, Core::System& system_,
20 const char* name); 20 const char* name);
21 ~Interface() override; 21 ~Interface() override;
22 22
@@ -60,7 +60,6 @@ public:
60 protected: 60 protected:
61 std::shared_ptr<Module> module; 61 std::shared_ptr<Module> module;
62 std::shared_ptr<ProfileManager> profile_manager; 62 std::shared_ptr<ProfileManager> profile_manager;
63 Core::System& system;
64 }; 63 };
65}; 64};
66 65
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 703a9b234..38d877f6e 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -64,7 +64,7 @@ struct LaunchParameterAccountPreselectedUser {
64static_assert(sizeof(LaunchParameterAccountPreselectedUser) == 0x88); 64static_assert(sizeof(LaunchParameterAccountPreselectedUser) == 0x88);
65 65
66IWindowController::IWindowController(Core::System& system_) 66IWindowController::IWindowController(Core::System& system_)
67 : ServiceFramework("IWindowController"), system{system_} { 67 : ServiceFramework{system_, "IWindowController"} {
68 // clang-format off 68 // clang-format off
69 static const FunctionInfo functions[] = { 69 static const FunctionInfo functions[] = {
70 {0, nullptr, "CreateWindow"}, 70 {0, nullptr, "CreateWindow"},
@@ -99,7 +99,8 @@ void IWindowController::AcquireForegroundRights(Kernel::HLERequestContext& ctx)
99 rb.Push(RESULT_SUCCESS); 99 rb.Push(RESULT_SUCCESS);
100} 100}
101 101
102IAudioController::IAudioController() : ServiceFramework("IAudioController") { 102IAudioController::IAudioController(Core::System& system_)
103 : ServiceFramework{system_, "IAudioController"} {
103 // clang-format off 104 // clang-format off
104 static const FunctionInfo functions[] = { 105 static const FunctionInfo functions[] = {
105 {0, &IAudioController::SetExpectedMasterVolume, "SetExpectedMasterVolume"}, 106 {0, &IAudioController::SetExpectedMasterVolume, "SetExpectedMasterVolume"},
@@ -180,7 +181,8 @@ void IAudioController::SetTransparentAudioRate(Kernel::HLERequestContext& ctx) {
180 rb.Push(RESULT_SUCCESS); 181 rb.Push(RESULT_SUCCESS);
181} 182}
182 183
183IDisplayController::IDisplayController() : ServiceFramework("IDisplayController") { 184IDisplayController::IDisplayController(Core::System& system_)
185 : ServiceFramework{system_, "IDisplayController"} {
184 // clang-format off 186 // clang-format off
185 static const FunctionInfo functions[] = { 187 static const FunctionInfo functions[] = {
186 {0, nullptr, "GetLastForegroundCaptureImage"}, 188 {0, nullptr, "GetLastForegroundCaptureImage"},
@@ -219,7 +221,8 @@ IDisplayController::IDisplayController() : ServiceFramework("IDisplayController"
219 221
220IDisplayController::~IDisplayController() = default; 222IDisplayController::~IDisplayController() = default;
221 223
222IDebugFunctions::IDebugFunctions() : ServiceFramework{"IDebugFunctions"} { 224IDebugFunctions::IDebugFunctions(Core::System& system_)
225 : ServiceFramework{system_, "IDebugFunctions"} {
223 // clang-format off 226 // clang-format off
224 static const FunctionInfo functions[] = { 227 static const FunctionInfo functions[] = {
225 {0, nullptr, "NotifyMessageToHomeMenuForDebug"}, 228 {0, nullptr, "NotifyMessageToHomeMenuForDebug"},
@@ -246,8 +249,8 @@ IDebugFunctions::IDebugFunctions() : ServiceFramework{"IDebugFunctions"} {
246 249
247IDebugFunctions::~IDebugFunctions() = default; 250IDebugFunctions::~IDebugFunctions() = default;
248 251
249ISelfController::ISelfController(Core::System& system, NVFlinger::NVFlinger& nvflinger) 252ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nvflinger_)
250 : ServiceFramework("ISelfController"), system(system), nvflinger(nvflinger) { 253 : ServiceFramework{system_, "ISelfController"}, nvflinger{nvflinger_} {
251 // clang-format off 254 // clang-format off
252 static const FunctionInfo functions[] = { 255 static const FunctionInfo functions[] = {
253 {0, &ISelfController::Exit, "Exit"}, 256 {0, &ISelfController::Exit, "Exit"},
@@ -605,9 +608,9 @@ void AppletMessageQueue::RequestExit() {
605 PushMessage(AppletMessage::ExitRequested); 608 PushMessage(AppletMessage::ExitRequested);
606} 609}
607 610
608ICommonStateGetter::ICommonStateGetter(Core::System& system, 611ICommonStateGetter::ICommonStateGetter(Core::System& system_,
609 std::shared_ptr<AppletMessageQueue> msg_queue) 612 std::shared_ptr<AppletMessageQueue> msg_queue_)
610 : ServiceFramework("ICommonStateGetter"), system(system), msg_queue(std::move(msg_queue)) { 613 : ServiceFramework{system_, "ICommonStateGetter"}, msg_queue{std::move(msg_queue_)} {
611 // clang-format off 614 // clang-format off
612 static const FunctionInfo functions[] = { 615 static const FunctionInfo functions[] = {
613 {0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"}, 616 {0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"},
@@ -795,8 +798,9 @@ private:
795 std::vector<u8> buffer; 798 std::vector<u8> buffer;
796}; 799};
797 800
798IStorage::IStorage(std::vector<u8>&& buffer) 801IStorage::IStorage(Core::System& system_, std::vector<u8>&& buffer)
799 : ServiceFramework("IStorage"), impl{std::make_shared<StorageDataImpl>(std::move(buffer))} { 802 : ServiceFramework{system_, "IStorage"}, impl{std::make_shared<StorageDataImpl>(
803 std::move(buffer))} {
800 Register(); 804 Register();
801} 805}
802 806
@@ -819,7 +823,7 @@ void IStorage::Open(Kernel::HLERequestContext& ctx) {
819 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 823 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
820 824
821 rb.Push(RESULT_SUCCESS); 825 rb.Push(RESULT_SUCCESS);
822 rb.PushIpcInterface<IStorageAccessor>(*this); 826 rb.PushIpcInterface<IStorageAccessor>(system, *this);
823} 827}
824 828
825void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) { 829void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) {
@@ -841,8 +845,8 @@ void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
841 845
842class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> { 846class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> {
843public: 847public:
844 explicit ILibraryAppletAccessor(std::shared_ptr<Applets::Applet> applet) 848 explicit ILibraryAppletAccessor(Core::System& system_, std::shared_ptr<Applets::Applet> applet_)
845 : ServiceFramework("ILibraryAppletAccessor"), applet(std::move(applet)) { 849 : ServiceFramework{system_, "ILibraryAppletAccessor"}, applet{std::move(applet_)} {
846 // clang-format off 850 // clang-format off
847 static const FunctionInfo functions[] = { 851 static const FunctionInfo functions[] = {
848 {0, &ILibraryAppletAccessor::GetAppletStateChangedEvent, "GetAppletStateChangedEvent"}, 852 {0, &ILibraryAppletAccessor::GetAppletStateChangedEvent, "GetAppletStateChangedEvent"},
@@ -997,8 +1001,8 @@ private:
997 std::shared_ptr<Applets::Applet> applet; 1001 std::shared_ptr<Applets::Applet> applet;
998}; 1002};
999 1003
1000IStorageAccessor::IStorageAccessor(IStorage& storage) 1004IStorageAccessor::IStorageAccessor(Core::System& system_, IStorage& backing_)
1001 : ServiceFramework("IStorageAccessor"), backing(storage) { 1005 : ServiceFramework{system_, "IStorageAccessor"}, backing{backing_} {
1002 // clang-format off 1006 // clang-format off
1003 static const FunctionInfo functions[] = { 1007 static const FunctionInfo functions[] = {
1004 {0, &IStorageAccessor::GetSize, "GetSize"}, 1008 {0, &IStorageAccessor::GetSize, "GetSize"},
@@ -1069,7 +1073,7 @@ void IStorageAccessor::Read(Kernel::HLERequestContext& ctx) {
1069} 1073}
1070 1074
1071ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_) 1075ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_)
1072 : ServiceFramework("ILibraryAppletCreator"), system{system_} { 1076 : ServiceFramework{system_, "ILibraryAppletCreator"} {
1073 static const FunctionInfo functions[] = { 1077 static const FunctionInfo functions[] = {
1074 {0, &ILibraryAppletCreator::CreateLibraryApplet, "CreateLibraryApplet"}, 1078 {0, &ILibraryAppletCreator::CreateLibraryApplet, "CreateLibraryApplet"},
1075 {1, nullptr, "TerminateAllLibraryApplets"}, 1079 {1, nullptr, "TerminateAllLibraryApplets"},
@@ -1105,7 +1109,7 @@ void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx)
1105 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 1109 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
1106 1110
1107 rb.Push(RESULT_SUCCESS); 1111 rb.Push(RESULT_SUCCESS);
1108 rb.PushIpcInterface<AM::ILibraryAppletAccessor>(applet); 1112 rb.PushIpcInterface<ILibraryAppletAccessor>(system, applet);
1109} 1113}
1110 1114
1111void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) { 1115void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) {
@@ -1117,7 +1121,7 @@ void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) {
1117 1121
1118 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 1122 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
1119 rb.Push(RESULT_SUCCESS); 1123 rb.Push(RESULT_SUCCESS);
1120 rb.PushIpcInterface<AM::IStorage>(std::move(buffer)); 1124 rb.PushIpcInterface<IStorage>(system, std::move(buffer));
1121} 1125}
1122 1126
1123void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx) { 1127void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx) {
@@ -1144,11 +1148,11 @@ void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContex
1144 1148
1145 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 1149 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
1146 rb.Push(RESULT_SUCCESS); 1150 rb.Push(RESULT_SUCCESS);
1147 rb.PushIpcInterface<IStorage>(std::move(memory)); 1151 rb.PushIpcInterface<IStorage>(system, std::move(memory));
1148} 1152}
1149 1153
1150IApplicationFunctions::IApplicationFunctions(Core::System& system_) 1154IApplicationFunctions::IApplicationFunctions(Core::System& system_)
1151 : ServiceFramework("IApplicationFunctions"), system{system_} { 1155 : ServiceFramework{system_, "IApplicationFunctions"} {
1152 // clang-format off 1156 // clang-format off
1153 static const FunctionInfo functions[] = { 1157 static const FunctionInfo functions[] = {
1154 {1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"}, 1158 {1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"},
@@ -1300,7 +1304,7 @@ void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) {
1300 if (data.has_value()) { 1304 if (data.has_value()) {
1301 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 1305 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
1302 rb.Push(RESULT_SUCCESS); 1306 rb.Push(RESULT_SUCCESS);
1303 rb.PushIpcInterface<IStorage>(std::move(*data)); 1307 rb.PushIpcInterface<IStorage>(system, std::move(*data));
1304 launch_popped_application_specific = true; 1308 launch_popped_application_specific = true;
1305 return; 1309 return;
1306 } 1310 }
@@ -1323,7 +1327,7 @@ void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) {
1323 std::vector<u8> buffer(sizeof(LaunchParameterAccountPreselectedUser)); 1327 std::vector<u8> buffer(sizeof(LaunchParameterAccountPreselectedUser));
1324 std::memcpy(buffer.data(), &params, buffer.size()); 1328 std::memcpy(buffer.data(), &params, buffer.size());
1325 1329
1326 rb.PushIpcInterface<IStorage>(std::move(buffer)); 1330 rb.PushIpcInterface<IStorage>(system, std::move(buffer));
1327 launch_popped_account_preselect = true; 1331 launch_popped_account_preselect = true;
1328 return; 1332 return;
1329 } 1333 }
@@ -1621,14 +1625,14 @@ void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger
1621 1625
1622 std::make_shared<AppletAE>(nvflinger, message_queue, system)->InstallAsService(service_manager); 1626 std::make_shared<AppletAE>(nvflinger, message_queue, system)->InstallAsService(service_manager);
1623 std::make_shared<AppletOE>(nvflinger, message_queue, system)->InstallAsService(service_manager); 1627 std::make_shared<AppletOE>(nvflinger, message_queue, system)->InstallAsService(service_manager);
1624 std::make_shared<IdleSys>()->InstallAsService(service_manager); 1628 std::make_shared<IdleSys>(system)->InstallAsService(service_manager);
1625 std::make_shared<OMM>()->InstallAsService(service_manager); 1629 std::make_shared<OMM>(system)->InstallAsService(service_manager);
1626 std::make_shared<SPSM>()->InstallAsService(service_manager); 1630 std::make_shared<SPSM>(system)->InstallAsService(service_manager);
1627 std::make_shared<TCAP>()->InstallAsService(service_manager); 1631 std::make_shared<TCAP>(system)->InstallAsService(service_manager);
1628} 1632}
1629 1633
1630IHomeMenuFunctions::IHomeMenuFunctions(Kernel::KernelCore& kernel) 1634IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_)
1631 : ServiceFramework("IHomeMenuFunctions"), kernel(kernel) { 1635 : ServiceFramework{system_, "IHomeMenuFunctions"} {
1632 // clang-format off 1636 // clang-format off
1633 static const FunctionInfo functions[] = { 1637 static const FunctionInfo functions[] = {
1634 {10, &IHomeMenuFunctions::RequestToGetForeground, "RequestToGetForeground"}, 1638 {10, &IHomeMenuFunctions::RequestToGetForeground, "RequestToGetForeground"},
@@ -1647,7 +1651,7 @@ IHomeMenuFunctions::IHomeMenuFunctions(Kernel::KernelCore& kernel)
1647 RegisterHandlers(functions); 1651 RegisterHandlers(functions);
1648 1652
1649 pop_from_general_channel_event = Kernel::WritableEvent::CreateEventPair( 1653 pop_from_general_channel_event = Kernel::WritableEvent::CreateEventPair(
1650 kernel, "IHomeMenuFunctions:PopFromGeneralChannelEvent"); 1654 system.Kernel(), "IHomeMenuFunctions:PopFromGeneralChannelEvent");
1651} 1655}
1652 1656
1653IHomeMenuFunctions::~IHomeMenuFunctions() = default; 1657IHomeMenuFunctions::~IHomeMenuFunctions() = default;
@@ -1667,7 +1671,8 @@ void IHomeMenuFunctions::GetPopFromGeneralChannelEvent(Kernel::HLERequestContext
1667 rb.PushCopyObjects(pop_from_general_channel_event.readable); 1671 rb.PushCopyObjects(pop_from_general_channel_event.readable);
1668} 1672}
1669 1673
1670IGlobalStateController::IGlobalStateController() : ServiceFramework("IGlobalStateController") { 1674IGlobalStateController::IGlobalStateController(Core::System& system_)
1675 : ServiceFramework{system_, "IGlobalStateController"} {
1671 // clang-format off 1676 // clang-format off
1672 static const FunctionInfo functions[] = { 1677 static const FunctionInfo functions[] = {
1673 {0, nullptr, "RequestToEnterSleep"}, 1678 {0, nullptr, "RequestToEnterSleep"},
@@ -1690,7 +1695,8 @@ IGlobalStateController::IGlobalStateController() : ServiceFramework("IGlobalStat
1690 1695
1691IGlobalStateController::~IGlobalStateController() = default; 1696IGlobalStateController::~IGlobalStateController() = default;
1692 1697
1693IApplicationCreator::IApplicationCreator() : ServiceFramework("IApplicationCreator") { 1698IApplicationCreator::IApplicationCreator(Core::System& system_)
1699 : ServiceFramework{system_, "IApplicationCreator"} {
1694 // clang-format off 1700 // clang-format off
1695 static const FunctionInfo functions[] = { 1701 static const FunctionInfo functions[] = {
1696 {0, nullptr, "CreateApplication"}, 1702 {0, nullptr, "CreateApplication"},
@@ -1705,8 +1711,8 @@ IApplicationCreator::IApplicationCreator() : ServiceFramework("IApplicationCreat
1705 1711
1706IApplicationCreator::~IApplicationCreator() = default; 1712IApplicationCreator::~IApplicationCreator() = default;
1707 1713
1708IProcessWindingController::IProcessWindingController() 1714IProcessWindingController::IProcessWindingController(Core::System& system_)
1709 : ServiceFramework("IProcessWindingController") { 1715 : ServiceFramework{system_, "IProcessWindingController"} {
1710 // clang-format off 1716 // clang-format off
1711 static const FunctionInfo functions[] = { 1717 static const FunctionInfo functions[] = {
1712 {0, nullptr, "GetLaunchReason"}, 1718 {0, nullptr, "GetLaunchReason"},
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index af97c303a..b1da0d081 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -77,13 +77,11 @@ public:
77private: 77private:
78 void GetAppletResourceUserId(Kernel::HLERequestContext& ctx); 78 void GetAppletResourceUserId(Kernel::HLERequestContext& ctx);
79 void AcquireForegroundRights(Kernel::HLERequestContext& ctx); 79 void AcquireForegroundRights(Kernel::HLERequestContext& ctx);
80
81 Core::System& system;
82}; 80};
83 81
84class IAudioController final : public ServiceFramework<IAudioController> { 82class IAudioController final : public ServiceFramework<IAudioController> {
85public: 83public:
86 IAudioController(); 84 explicit IAudioController(Core::System& system_);
87 ~IAudioController() override; 85 ~IAudioController() override;
88 86
89private: 87private:
@@ -109,13 +107,13 @@ private:
109 107
110class IDisplayController final : public ServiceFramework<IDisplayController> { 108class IDisplayController final : public ServiceFramework<IDisplayController> {
111public: 109public:
112 IDisplayController(); 110 explicit IDisplayController(Core::System& system_);
113 ~IDisplayController() override; 111 ~IDisplayController() override;
114}; 112};
115 113
116class IDebugFunctions final : public ServiceFramework<IDebugFunctions> { 114class IDebugFunctions final : public ServiceFramework<IDebugFunctions> {
117public: 115public:
118 IDebugFunctions(); 116 explicit IDebugFunctions(Core::System& system_);
119 ~IDebugFunctions() override; 117 ~IDebugFunctions() override;
120}; 118};
121 119
@@ -154,7 +152,6 @@ private:
154 Disable = 2, 152 Disable = 2,
155 }; 153 };
156 154
157 Core::System& system;
158 NVFlinger::NVFlinger& nvflinger; 155 NVFlinger::NVFlinger& nvflinger;
159 Kernel::EventPair launchable_event; 156 Kernel::EventPair launchable_event;
160 Kernel::EventPair accumulated_suspended_tick_changed_event; 157 Kernel::EventPair accumulated_suspended_tick_changed_event;
@@ -167,8 +164,8 @@ private:
167 164
168class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> { 165class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> {
169public: 166public:
170 explicit ICommonStateGetter(Core::System& system, 167 explicit ICommonStateGetter(Core::System& system_,
171 std::shared_ptr<AppletMessageQueue> msg_queue); 168 std::shared_ptr<AppletMessageQueue> msg_queue_);
172 ~ICommonStateGetter() override; 169 ~ICommonStateGetter() override;
173 170
174private: 171private:
@@ -196,7 +193,6 @@ private:
196 void GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx); 193 void GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx);
197 void SetCpuBoostMode(Kernel::HLERequestContext& ctx); 194 void SetCpuBoostMode(Kernel::HLERequestContext& ctx);
198 195
199 Core::System& system;
200 std::shared_ptr<AppletMessageQueue> msg_queue; 196 std::shared_ptr<AppletMessageQueue> msg_queue;
201 bool vr_mode_state{}; 197 bool vr_mode_state{};
202}; 198};
@@ -211,7 +207,7 @@ public:
211 207
212class IStorage final : public ServiceFramework<IStorage> { 208class IStorage final : public ServiceFramework<IStorage> {
213public: 209public:
214 explicit IStorage(std::vector<u8>&& buffer); 210 explicit IStorage(Core::System& system_, std::vector<u8>&& buffer);
215 ~IStorage() override; 211 ~IStorage() override;
216 212
217 std::vector<u8>& GetData() { 213 std::vector<u8>& GetData() {
@@ -235,7 +231,7 @@ private:
235 231
236class IStorageAccessor final : public ServiceFramework<IStorageAccessor> { 232class IStorageAccessor final : public ServiceFramework<IStorageAccessor> {
237public: 233public:
238 explicit IStorageAccessor(IStorage& backing); 234 explicit IStorageAccessor(Core::System& system_, IStorage& backing_);
239 ~IStorageAccessor() override; 235 ~IStorageAccessor() override;
240 236
241private: 237private:
@@ -255,8 +251,6 @@ private:
255 void CreateLibraryApplet(Kernel::HLERequestContext& ctx); 251 void CreateLibraryApplet(Kernel::HLERequestContext& ctx);
256 void CreateStorage(Kernel::HLERequestContext& ctx); 252 void CreateStorage(Kernel::HLERequestContext& ctx);
257 void CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx); 253 void CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx);
258
259 Core::System& system;
260}; 254};
261 255
262class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> { 256class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> {
@@ -299,12 +293,11 @@ private:
299 s32 previous_program_index{-1}; 293 s32 previous_program_index{-1};
300 Kernel::EventPair gpu_error_detected_event; 294 Kernel::EventPair gpu_error_detected_event;
301 Kernel::EventPair friend_invitation_storage_channel_event; 295 Kernel::EventPair friend_invitation_storage_channel_event;
302 Core::System& system;
303}; 296};
304 297
305class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> { 298class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> {
306public: 299public:
307 explicit IHomeMenuFunctions(Kernel::KernelCore& kernel); 300 explicit IHomeMenuFunctions(Core::System& system_);
308 ~IHomeMenuFunctions() override; 301 ~IHomeMenuFunctions() override;
309 302
310private: 303private:
@@ -312,24 +305,23 @@ private:
312 void GetPopFromGeneralChannelEvent(Kernel::HLERequestContext& ctx); 305 void GetPopFromGeneralChannelEvent(Kernel::HLERequestContext& ctx);
313 306
314 Kernel::EventPair pop_from_general_channel_event; 307 Kernel::EventPair pop_from_general_channel_event;
315 Kernel::KernelCore& kernel;
316}; 308};
317 309
318class IGlobalStateController final : public ServiceFramework<IGlobalStateController> { 310class IGlobalStateController final : public ServiceFramework<IGlobalStateController> {
319public: 311public:
320 IGlobalStateController(); 312 explicit IGlobalStateController(Core::System& system_);
321 ~IGlobalStateController() override; 313 ~IGlobalStateController() override;
322}; 314};
323 315
324class IApplicationCreator final : public ServiceFramework<IApplicationCreator> { 316class IApplicationCreator final : public ServiceFramework<IApplicationCreator> {
325public: 317public:
326 IApplicationCreator(); 318 explicit IApplicationCreator(Core::System& system_);
327 ~IApplicationCreator() override; 319 ~IApplicationCreator() override;
328}; 320};
329 321
330class IProcessWindingController final : public ServiceFramework<IProcessWindingController> { 322class IProcessWindingController final : public ServiceFramework<IProcessWindingController> {
331public: 323public:
332 IProcessWindingController(); 324 explicit IProcessWindingController(Core::System& system_);
333 ~IProcessWindingController() override; 325 ~IProcessWindingController() override;
334}; 326};
335 327
diff --git a/src/core/hle/service/am/applet_ae.cpp b/src/core/hle/service/am/applet_ae.cpp
index 7de506b70..5421e0da0 100644
--- a/src/core/hle/service/am/applet_ae.cpp
+++ b/src/core/hle/service/am/applet_ae.cpp
@@ -13,11 +13,11 @@ namespace Service::AM {
13 13
14class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> { 14class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> {
15public: 15public:
16 explicit ILibraryAppletProxy(NVFlinger::NVFlinger& nvflinger, 16 explicit ILibraryAppletProxy(NVFlinger::NVFlinger& nvflinger_,
17 std::shared_ptr<AppletMessageQueue> msg_queue, 17 std::shared_ptr<AppletMessageQueue> msg_queue_,
18 Core::System& system) 18 Core::System& system_)
19 : ServiceFramework("ILibraryAppletProxy"), nvflinger(nvflinger), 19 : ServiceFramework{system_, "ILibraryAppletProxy"}, nvflinger{nvflinger_},
20 msg_queue(std::move(msg_queue)), system(system) { 20 msg_queue{std::move(msg_queue_)} {
21 // clang-format off 21 // clang-format off
22 static const FunctionInfo functions[] = { 22 static const FunctionInfo functions[] = {
23 {0, &ILibraryAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"}, 23 {0, &ILibraryAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"},
@@ -66,7 +66,7 @@ private:
66 66
67 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 67 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
68 rb.Push(RESULT_SUCCESS); 68 rb.Push(RESULT_SUCCESS);
69 rb.PushIpcInterface<IAudioController>(); 69 rb.PushIpcInterface<IAudioController>(system);
70 } 70 }
71 71
72 void GetDisplayController(Kernel::HLERequestContext& ctx) { 72 void GetDisplayController(Kernel::HLERequestContext& ctx) {
@@ -74,7 +74,7 @@ private:
74 74
75 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 75 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
76 rb.Push(RESULT_SUCCESS); 76 rb.Push(RESULT_SUCCESS);
77 rb.PushIpcInterface<IDisplayController>(); 77 rb.PushIpcInterface<IDisplayController>(system);
78 } 78 }
79 79
80 void GetProcessWindingController(Kernel::HLERequestContext& ctx) { 80 void GetProcessWindingController(Kernel::HLERequestContext& ctx) {
@@ -82,7 +82,7 @@ private:
82 82
83 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 83 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
84 rb.Push(RESULT_SUCCESS); 84 rb.Push(RESULT_SUCCESS);
85 rb.PushIpcInterface<IProcessWindingController>(); 85 rb.PushIpcInterface<IProcessWindingController>(system);
86 } 86 }
87 87
88 void GetDebugFunctions(Kernel::HLERequestContext& ctx) { 88 void GetDebugFunctions(Kernel::HLERequestContext& ctx) {
@@ -90,7 +90,7 @@ private:
90 90
91 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 91 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
92 rb.Push(RESULT_SUCCESS); 92 rb.Push(RESULT_SUCCESS);
93 rb.PushIpcInterface<IDebugFunctions>(); 93 rb.PushIpcInterface<IDebugFunctions>(system);
94 } 94 }
95 95
96 void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) { 96 void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) {
@@ -111,15 +111,15 @@ private:
111 111
112 NVFlinger::NVFlinger& nvflinger; 112 NVFlinger::NVFlinger& nvflinger;
113 std::shared_ptr<AppletMessageQueue> msg_queue; 113 std::shared_ptr<AppletMessageQueue> msg_queue;
114 Core::System& system;
115}; 114};
116 115
117class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> { 116class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> {
118public: 117public:
119 explicit ISystemAppletProxy(NVFlinger::NVFlinger& nvflinger, 118 explicit ISystemAppletProxy(NVFlinger::NVFlinger& nvflinger_,
120 std::shared_ptr<AppletMessageQueue> msg_queue, Core::System& system) 119 std::shared_ptr<AppletMessageQueue> msg_queue_,
121 : ServiceFramework("ISystemAppletProxy"), nvflinger(nvflinger), 120 Core::System& system_)
122 msg_queue(std::move(msg_queue)), system(system) { 121 : ServiceFramework{system_, "ISystemAppletProxy"}, nvflinger{nvflinger_},
122 msg_queue{std::move(msg_queue_)} {
123 // clang-format off 123 // clang-format off
124 static const FunctionInfo functions[] = { 124 static const FunctionInfo functions[] = {
125 {0, &ISystemAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"}, 125 {0, &ISystemAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"},
@@ -170,7 +170,7 @@ private:
170 170
171 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 171 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
172 rb.Push(RESULT_SUCCESS); 172 rb.Push(RESULT_SUCCESS);
173 rb.PushIpcInterface<IAudioController>(); 173 rb.PushIpcInterface<IAudioController>(system);
174 } 174 }
175 175
176 void GetDisplayController(Kernel::HLERequestContext& ctx) { 176 void GetDisplayController(Kernel::HLERequestContext& ctx) {
@@ -178,7 +178,7 @@ private:
178 178
179 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 179 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
180 rb.Push(RESULT_SUCCESS); 180 rb.Push(RESULT_SUCCESS);
181 rb.PushIpcInterface<IDisplayController>(); 181 rb.PushIpcInterface<IDisplayController>(system);
182 } 182 }
183 183
184 void GetDebugFunctions(Kernel::HLERequestContext& ctx) { 184 void GetDebugFunctions(Kernel::HLERequestContext& ctx) {
@@ -186,7 +186,7 @@ private:
186 186
187 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 187 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
188 rb.Push(RESULT_SUCCESS); 188 rb.Push(RESULT_SUCCESS);
189 rb.PushIpcInterface<IDebugFunctions>(); 189 rb.PushIpcInterface<IDebugFunctions>(system);
190 } 190 }
191 191
192 void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) { 192 void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) {
@@ -202,7 +202,7 @@ private:
202 202
203 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 203 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
204 rb.Push(RESULT_SUCCESS); 204 rb.Push(RESULT_SUCCESS);
205 rb.PushIpcInterface<IHomeMenuFunctions>(system.Kernel()); 205 rb.PushIpcInterface<IHomeMenuFunctions>(system);
206 } 206 }
207 207
208 void GetGlobalStateController(Kernel::HLERequestContext& ctx) { 208 void GetGlobalStateController(Kernel::HLERequestContext& ctx) {
@@ -210,7 +210,7 @@ private:
210 210
211 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 211 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
212 rb.Push(RESULT_SUCCESS); 212 rb.Push(RESULT_SUCCESS);
213 rb.PushIpcInterface<IGlobalStateController>(); 213 rb.PushIpcInterface<IGlobalStateController>(system);
214 } 214 }
215 215
216 void GetApplicationCreator(Kernel::HLERequestContext& ctx) { 216 void GetApplicationCreator(Kernel::HLERequestContext& ctx) {
@@ -218,12 +218,11 @@ private:
218 218
219 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 219 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
220 rb.Push(RESULT_SUCCESS); 220 rb.Push(RESULT_SUCCESS);
221 rb.PushIpcInterface<IApplicationCreator>(); 221 rb.PushIpcInterface<IApplicationCreator>(system);
222 } 222 }
223 223
224 NVFlinger::NVFlinger& nvflinger; 224 NVFlinger::NVFlinger& nvflinger;
225 std::shared_ptr<AppletMessageQueue> msg_queue; 225 std::shared_ptr<AppletMessageQueue> msg_queue;
226 Core::System& system;
227}; 226};
228 227
229void AppletAE::OpenSystemAppletProxy(Kernel::HLERequestContext& ctx) { 228void AppletAE::OpenSystemAppletProxy(Kernel::HLERequestContext& ctx) {
@@ -250,10 +249,10 @@ void AppletAE::OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx) {
250 rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger, msg_queue, system); 249 rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger, msg_queue, system);
251} 250}
252 251
253AppletAE::AppletAE(NVFlinger::NVFlinger& nvflinger, std::shared_ptr<AppletMessageQueue> msg_queue, 252AppletAE::AppletAE(NVFlinger::NVFlinger& nvflinger_, std::shared_ptr<AppletMessageQueue> msg_queue_,
254 Core::System& system) 253 Core::System& system_)
255 : ServiceFramework("appletAE"), nvflinger(nvflinger), msg_queue(std::move(msg_queue)), 254 : ServiceFramework{system_, "appletAE"}, nvflinger{nvflinger_}, msg_queue{
256 system(system) { 255 std::move(msg_queue_)} {
257 // clang-format off 256 // clang-format off
258 static const FunctionInfo functions[] = { 257 static const FunctionInfo functions[] = {
259 {100, &AppletAE::OpenSystemAppletProxy, "OpenSystemAppletProxy"}, 258 {100, &AppletAE::OpenSystemAppletProxy, "OpenSystemAppletProxy"},
diff --git a/src/core/hle/service/am/applet_ae.h b/src/core/hle/service/am/applet_ae.h
index 761844a1f..adb207349 100644
--- a/src/core/hle/service/am/applet_ae.h
+++ b/src/core/hle/service/am/applet_ae.h
@@ -23,8 +23,8 @@ class AppletMessageQueue;
23 23
24class AppletAE final : public ServiceFramework<AppletAE> { 24class AppletAE final : public ServiceFramework<AppletAE> {
25public: 25public:
26 explicit AppletAE(NVFlinger::NVFlinger& nvflinger, 26 explicit AppletAE(NVFlinger::NVFlinger& nvflinger_,
27 std::shared_ptr<AppletMessageQueue> msg_queue, Core::System& system); 27 std::shared_ptr<AppletMessageQueue> msg_queue_, Core::System& system_);
28 ~AppletAE() override; 28 ~AppletAE() override;
29 29
30 const std::shared_ptr<AppletMessageQueue>& GetMessageQueue() const; 30 const std::shared_ptr<AppletMessageQueue>& GetMessageQueue() const;
@@ -36,7 +36,6 @@ private:
36 36
37 NVFlinger::NVFlinger& nvflinger; 37 NVFlinger::NVFlinger& nvflinger;
38 std::shared_ptr<AppletMessageQueue> msg_queue; 38 std::shared_ptr<AppletMessageQueue> msg_queue;
39 Core::System& system;
40}; 39};
41 40
42} // namespace AM 41} // namespace AM
diff --git a/src/core/hle/service/am/applet_oe.cpp b/src/core/hle/service/am/applet_oe.cpp
index 7bed86ec4..f9eba8f52 100644
--- a/src/core/hle/service/am/applet_oe.cpp
+++ b/src/core/hle/service/am/applet_oe.cpp
@@ -12,10 +12,11 @@ namespace Service::AM {
12 12
13class IApplicationProxy final : public ServiceFramework<IApplicationProxy> { 13class IApplicationProxy final : public ServiceFramework<IApplicationProxy> {
14public: 14public:
15 explicit IApplicationProxy(NVFlinger::NVFlinger& nvflinger, 15 explicit IApplicationProxy(NVFlinger::NVFlinger& nvflinger_,
16 std::shared_ptr<AppletMessageQueue> msg_queue, Core::System& system) 16 std::shared_ptr<AppletMessageQueue> msg_queue_,
17 : ServiceFramework("IApplicationProxy"), nvflinger(nvflinger), 17 Core::System& system_)
18 msg_queue(std::move(msg_queue)), system(system) { 18 : ServiceFramework{system_, "IApplicationProxy"}, nvflinger{nvflinger_},
19 msg_queue{std::move(msg_queue_)} {
19 // clang-format off 20 // clang-format off
20 static const FunctionInfo functions[] = { 21 static const FunctionInfo functions[] = {
21 {0, &IApplicationProxy::GetCommonStateGetter, "GetCommonStateGetter"}, 22 {0, &IApplicationProxy::GetCommonStateGetter, "GetCommonStateGetter"},
@@ -39,7 +40,7 @@ private:
39 40
40 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 41 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
41 rb.Push(RESULT_SUCCESS); 42 rb.Push(RESULT_SUCCESS);
42 rb.PushIpcInterface<IAudioController>(); 43 rb.PushIpcInterface<IAudioController>(system);
43 } 44 }
44 45
45 void GetDisplayController(Kernel::HLERequestContext& ctx) { 46 void GetDisplayController(Kernel::HLERequestContext& ctx) {
@@ -47,7 +48,7 @@ private:
47 48
48 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 49 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
49 rb.Push(RESULT_SUCCESS); 50 rb.Push(RESULT_SUCCESS);
50 rb.PushIpcInterface<IDisplayController>(); 51 rb.PushIpcInterface<IDisplayController>(system);
51 } 52 }
52 53
53 void GetDebugFunctions(Kernel::HLERequestContext& ctx) { 54 void GetDebugFunctions(Kernel::HLERequestContext& ctx) {
@@ -55,7 +56,7 @@ private:
55 56
56 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 57 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
57 rb.Push(RESULT_SUCCESS); 58 rb.Push(RESULT_SUCCESS);
58 rb.PushIpcInterface<IDebugFunctions>(); 59 rb.PushIpcInterface<IDebugFunctions>(system);
59 } 60 }
60 61
61 void GetWindowController(Kernel::HLERequestContext& ctx) { 62 void GetWindowController(Kernel::HLERequestContext& ctx) {
@@ -100,7 +101,6 @@ private:
100 101
101 NVFlinger::NVFlinger& nvflinger; 102 NVFlinger::NVFlinger& nvflinger;
102 std::shared_ptr<AppletMessageQueue> msg_queue; 103 std::shared_ptr<AppletMessageQueue> msg_queue;
103 Core::System& system;
104}; 104};
105 105
106void AppletOE::OpenApplicationProxy(Kernel::HLERequestContext& ctx) { 106void AppletOE::OpenApplicationProxy(Kernel::HLERequestContext& ctx) {
@@ -111,10 +111,10 @@ void AppletOE::OpenApplicationProxy(Kernel::HLERequestContext& ctx) {
111 rb.PushIpcInterface<IApplicationProxy>(nvflinger, msg_queue, system); 111 rb.PushIpcInterface<IApplicationProxy>(nvflinger, msg_queue, system);
112} 112}
113 113
114AppletOE::AppletOE(NVFlinger::NVFlinger& nvflinger, std::shared_ptr<AppletMessageQueue> msg_queue, 114AppletOE::AppletOE(NVFlinger::NVFlinger& nvflinger_, std::shared_ptr<AppletMessageQueue> msg_queue_,
115 Core::System& system) 115 Core::System& system_)
116 : ServiceFramework("appletOE"), nvflinger(nvflinger), msg_queue(std::move(msg_queue)), 116 : ServiceFramework{system_, "appletOE"}, nvflinger{nvflinger_}, msg_queue{
117 system(system) { 117 std::move(msg_queue_)} {
118 static const FunctionInfo functions[] = { 118 static const FunctionInfo functions[] = {
119 {0, &AppletOE::OpenApplicationProxy, "OpenApplicationProxy"}, 119 {0, &AppletOE::OpenApplicationProxy, "OpenApplicationProxy"},
120 }; 120 };
diff --git a/src/core/hle/service/am/applet_oe.h b/src/core/hle/service/am/applet_oe.h
index 88906d354..6c1aa255a 100644
--- a/src/core/hle/service/am/applet_oe.h
+++ b/src/core/hle/service/am/applet_oe.h
@@ -23,8 +23,8 @@ class AppletMessageQueue;
23 23
24class AppletOE final : public ServiceFramework<AppletOE> { 24class AppletOE final : public ServiceFramework<AppletOE> {
25public: 25public:
26 explicit AppletOE(NVFlinger::NVFlinger& nvflinger, 26 explicit AppletOE(NVFlinger::NVFlinger& nvflinger_,
27 std::shared_ptr<AppletMessageQueue> msg_queue, Core::System& system); 27 std::shared_ptr<AppletMessageQueue> msg_queue_, Core::System& system_);
28 ~AppletOE() override; 28 ~AppletOE() override;
29 29
30 const std::shared_ptr<AppletMessageQueue>& GetMessageQueue() const; 30 const std::shared_ptr<AppletMessageQueue>& GetMessageQueue() const;
@@ -34,7 +34,6 @@ private:
34 34
35 NVFlinger::NVFlinger& nvflinger; 35 NVFlinger::NVFlinger& nvflinger;
36 std::shared_ptr<AppletMessageQueue> msg_queue; 36 std::shared_ptr<AppletMessageQueue> msg_queue;
37 Core::System& system;
38}; 37};
39 38
40} // namespace AM 39} // namespace AM
diff --git a/src/core/hle/service/am/applets/controller.cpp b/src/core/hle/service/am/applets/controller.cpp
index 3ca63f020..e8ea4248b 100644
--- a/src/core/hle/service/am/applets/controller.cpp
+++ b/src/core/hle/service/am/applets/controller.cpp
@@ -46,7 +46,7 @@ static Core::Frontend::ControllerParameters ConvertToFrontendParameters(
46} 46}
47 47
48Controller::Controller(Core::System& system_, const Core::Frontend::ControllerApplet& frontend_) 48Controller::Controller(Core::System& system_, const Core::Frontend::ControllerApplet& frontend_)
49 : Applet{system_.Kernel()}, frontend(frontend_) {} 49 : Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
50 50
51Controller::~Controller() = default; 51Controller::~Controller() = default;
52 52
@@ -245,7 +245,7 @@ void Controller::ConfigurationComplete() {
245 complete = true; 245 complete = true;
246 out_data = std::vector<u8>(sizeof(ControllerSupportResultInfo)); 246 out_data = std::vector<u8>(sizeof(ControllerSupportResultInfo));
247 std::memcpy(out_data.data(), &result_info, out_data.size()); 247 std::memcpy(out_data.data(), &result_info, out_data.size());
248 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(std::move(out_data))); 248 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data)));
249 broker.SignalStateChanged(); 249 broker.SignalStateChanged();
250} 250}
251 251
diff --git a/src/core/hle/service/am/applets/controller.h b/src/core/hle/service/am/applets/controller.h
index a7a1f2b65..d4c9da7b1 100644
--- a/src/core/hle/service/am/applets/controller.h
+++ b/src/core/hle/service/am/applets/controller.h
@@ -120,6 +120,7 @@ public:
120 120
121private: 121private:
122 const Core::Frontend::ControllerApplet& frontend; 122 const Core::Frontend::ControllerApplet& frontend;
123 Core::System& system;
123 124
124 ControllerAppletVersion controller_applet_version; 125 ControllerAppletVersion controller_applet_version;
125 ControllerSupportArgPrivate controller_private_arg; 126 ControllerSupportArgPrivate controller_private_arg;
diff --git a/src/core/hle/service/am/applets/error.cpp b/src/core/hle/service/am/applets/error.cpp
index f12fd7f89..dcd4b2a35 100644
--- a/src/core/hle/service/am/applets/error.cpp
+++ b/src/core/hle/service/am/applets/error.cpp
@@ -87,7 +87,7 @@ ResultCode Decode64BitError(u64 error) {
87} // Anonymous namespace 87} // Anonymous namespace
88 88
89Error::Error(Core::System& system_, const Core::Frontend::ErrorApplet& frontend_) 89Error::Error(Core::System& system_, const Core::Frontend::ErrorApplet& frontend_)
90 : Applet{system_.Kernel()}, frontend(frontend_), system{system_} {} 90 : Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
91 91
92Error::~Error() = default; 92Error::~Error() = default;
93 93
@@ -186,7 +186,7 @@ void Error::Execute() {
186 186
187void Error::DisplayCompleted() { 187void Error::DisplayCompleted() {
188 complete = true; 188 complete = true;
189 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(std::vector<u8>{})); 189 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>{}));
190 broker.SignalStateChanged(); 190 broker.SignalStateChanged();
191} 191}
192 192
diff --git a/src/core/hle/service/am/applets/general_backend.cpp b/src/core/hle/service/am/applets/general_backend.cpp
index 104501ac5..bdb6fd464 100644
--- a/src/core/hle/service/am/applets/general_backend.cpp
+++ b/src/core/hle/service/am/applets/general_backend.cpp
@@ -38,7 +38,7 @@ static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix)
38} 38}
39 39
40Auth::Auth(Core::System& system_, Core::Frontend::ParentalControlsApplet& frontend_) 40Auth::Auth(Core::System& system_, Core::Frontend::ParentalControlsApplet& frontend_)
41 : Applet{system_.Kernel()}, frontend(frontend_) {} 41 : Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
42 42
43Auth::~Auth() = default; 43Auth::~Auth() = default;
44 44
@@ -135,8 +135,8 @@ void Auth::Execute() {
135 } 135 }
136} 136}
137 137
138void Auth::AuthFinished(bool successful) { 138void Auth::AuthFinished(bool is_successful) {
139 this->successful = successful; 139 this->successful = is_successful;
140 140
141 struct Return { 141 struct Return {
142 ResultCode result_code; 142 ResultCode result_code;
@@ -148,12 +148,12 @@ void Auth::AuthFinished(bool successful) {
148 std::vector<u8> out(sizeof(Return)); 148 std::vector<u8> out(sizeof(Return));
149 std::memcpy(out.data(), &return_, sizeof(Return)); 149 std::memcpy(out.data(), &return_, sizeof(Return));
150 150
151 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(std::move(out))); 151 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out)));
152 broker.SignalStateChanged(); 152 broker.SignalStateChanged();
153} 153}
154 154
155PhotoViewer::PhotoViewer(Core::System& system_, const Core::Frontend::PhotoViewerApplet& frontend_) 155PhotoViewer::PhotoViewer(Core::System& system_, const Core::Frontend::PhotoViewerApplet& frontend_)
156 : Applet{system_.Kernel()}, frontend(frontend_), system{system_} {} 156 : Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
157 157
158PhotoViewer::~PhotoViewer() = default; 158PhotoViewer::~PhotoViewer() = default;
159 159
@@ -198,12 +198,12 @@ void PhotoViewer::Execute() {
198} 198}
199 199
200void PhotoViewer::ViewFinished() { 200void PhotoViewer::ViewFinished() {
201 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(std::vector<u8>{})); 201 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>{}));
202 broker.SignalStateChanged(); 202 broker.SignalStateChanged();
203} 203}
204 204
205StubApplet::StubApplet(Core::System& system_, AppletId id_) 205StubApplet::StubApplet(Core::System& system_, AppletId id_)
206 : Applet{system_.Kernel()}, id(id_), system{system_} {} 206 : Applet{system_.Kernel()}, id{id_}, system{system_} {}
207 207
208StubApplet::~StubApplet() = default; 208StubApplet::~StubApplet() = default;
209 209
@@ -234,8 +234,9 @@ void StubApplet::ExecuteInteractive() {
234 LOG_WARNING(Service_AM, "called (STUBBED)"); 234 LOG_WARNING(Service_AM, "called (STUBBED)");
235 LogCurrentStorage(broker, "ExecuteInteractive"); 235 LogCurrentStorage(broker, "ExecuteInteractive");
236 236
237 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(std::vector<u8>(0x1000))); 237 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>(0x1000)));
238 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(std::vector<u8>(0x1000))); 238 broker.PushInteractiveDataFromApplet(
239 std::make_shared<IStorage>(system, std::vector<u8>(0x1000)));
239 broker.SignalStateChanged(); 240 broker.SignalStateChanged();
240} 241}
241 242
@@ -243,8 +244,9 @@ void StubApplet::Execute() {
243 LOG_WARNING(Service_AM, "called (STUBBED)"); 244 LOG_WARNING(Service_AM, "called (STUBBED)");
244 LogCurrentStorage(broker, "Execute"); 245 LogCurrentStorage(broker, "Execute");
245 246
246 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(std::vector<u8>(0x1000))); 247 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>(0x1000)));
247 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(std::vector<u8>(0x1000))); 248 broker.PushInteractiveDataFromApplet(
249 std::make_shared<IStorage>(system, std::vector<u8>(0x1000)));
248 broker.SignalStateChanged(); 250 broker.SignalStateChanged();
249} 251}
250 252
diff --git a/src/core/hle/service/am/applets/general_backend.h b/src/core/hle/service/am/applets/general_backend.h
index cfa2df369..ba76ae3d3 100644
--- a/src/core/hle/service/am/applets/general_backend.h
+++ b/src/core/hle/service/am/applets/general_backend.h
@@ -29,10 +29,11 @@ public:
29 void ExecuteInteractive() override; 29 void ExecuteInteractive() override;
30 void Execute() override; 30 void Execute() override;
31 31
32 void AuthFinished(bool successful = true); 32 void AuthFinished(bool is_successful = true);
33 33
34private: 34private:
35 Core::Frontend::ParentalControlsApplet& frontend; 35 Core::Frontend::ParentalControlsApplet& frontend;
36 Core::System& system;
36 bool complete = false; 37 bool complete = false;
37 bool successful = false; 38 bool successful = false;
38 39
diff --git a/src/core/hle/service/am/applets/profile_select.cpp b/src/core/hle/service/am/applets/profile_select.cpp
index 70cc23552..77fba16c7 100644
--- a/src/core/hle/service/am/applets/profile_select.cpp
+++ b/src/core/hle/service/am/applets/profile_select.cpp
@@ -17,7 +17,7 @@ constexpr ResultCode ERR_USER_CANCELLED_SELECTION{ErrorModule::Account, 1};
17 17
18ProfileSelect::ProfileSelect(Core::System& system_, 18ProfileSelect::ProfileSelect(Core::System& system_,
19 const Core::Frontend::ProfileSelectApplet& frontend_) 19 const Core::Frontend::ProfileSelectApplet& frontend_)
20 : Applet{system_.Kernel()}, frontend(frontend_) {} 20 : Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
21 21
22ProfileSelect::~ProfileSelect() = default; 22ProfileSelect::~ProfileSelect() = default;
23 23
@@ -50,7 +50,7 @@ void ProfileSelect::ExecuteInteractive() {
50 50
51void ProfileSelect::Execute() { 51void ProfileSelect::Execute() {
52 if (complete) { 52 if (complete) {
53 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(std::move(final_data))); 53 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(final_data)));
54 return; 54 return;
55 } 55 }
56 56
@@ -71,7 +71,7 @@ void ProfileSelect::SelectionComplete(std::optional<Common::UUID> uuid) {
71 71
72 final_data = std::vector<u8>(sizeof(UserSelectionOutput)); 72 final_data = std::vector<u8>(sizeof(UserSelectionOutput));
73 std::memcpy(final_data.data(), &output, final_data.size()); 73 std::memcpy(final_data.data(), &output, final_data.size());
74 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(std::move(final_data))); 74 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(final_data)));
75 broker.SignalStateChanged(); 75 broker.SignalStateChanged();
76} 76}
77 77
diff --git a/src/core/hle/service/am/applets/profile_select.h b/src/core/hle/service/am/applets/profile_select.h
index 16364ead7..648d33a24 100644
--- a/src/core/hle/service/am/applets/profile_select.h
+++ b/src/core/hle/service/am/applets/profile_select.h
@@ -53,6 +53,7 @@ private:
53 bool complete = false; 53 bool complete = false;
54 ResultCode status = RESULT_SUCCESS; 54 ResultCode status = RESULT_SUCCESS;
55 std::vector<u8> final_data; 55 std::vector<u8> final_data;
56 Core::System& system;
56}; 57};
57 58
58} // namespace Service::AM::Applets 59} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/am/applets/software_keyboard.cpp b/src/core/hle/service/am/applets/software_keyboard.cpp
index bdeb0737a..3022438b1 100644
--- a/src/core/hle/service/am/applets/software_keyboard.cpp
+++ b/src/core/hle/service/am/applets/software_keyboard.cpp
@@ -53,7 +53,7 @@ static Core::Frontend::SoftwareKeyboardParameters ConvertToFrontendParameters(
53 53
54SoftwareKeyboard::SoftwareKeyboard(Core::System& system_, 54SoftwareKeyboard::SoftwareKeyboard(Core::System& system_,
55 const Core::Frontend::SoftwareKeyboardApplet& frontend_) 55 const Core::Frontend::SoftwareKeyboardApplet& frontend_)
56 : Applet{system_.Kernel()}, frontend(frontend_) {} 56 : Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
57 57
58SoftwareKeyboard::~SoftwareKeyboard() = default; 58SoftwareKeyboard::~SoftwareKeyboard() = default;
59 59
@@ -122,7 +122,7 @@ void SoftwareKeyboard::ExecuteInteractive() {
122 122
123 switch (request) { 123 switch (request) {
124 case Request::Calc: { 124 case Request::Calc: {
125 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(std::vector<u8>{1})); 125 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>{1}));
126 broker.SignalStateChanged(); 126 broker.SignalStateChanged();
127 break; 127 break;
128 } 128 }
@@ -135,7 +135,7 @@ void SoftwareKeyboard::ExecuteInteractive() {
135 135
136void SoftwareKeyboard::Execute() { 136void SoftwareKeyboard::Execute() {
137 if (complete) { 137 if (complete) {
138 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(std::move(final_data))); 138 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(final_data)));
139 broker.SignalStateChanged(); 139 broker.SignalStateChanged();
140 return; 140 return;
141 } 141 }
@@ -179,15 +179,17 @@ void SoftwareKeyboard::WriteText(std::optional<std::u16string> text) {
179 final_data = output_main; 179 final_data = output_main;
180 180
181 if (complete) { 181 if (complete) {
182 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(std::move(output_main))); 182 broker.PushNormalDataFromApplet(
183 std::make_shared<IStorage>(system, std::move(output_main)));
183 broker.SignalStateChanged(); 184 broker.SignalStateChanged();
184 } else { 185 } else {
185 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(std::move(output_sub))); 186 broker.PushInteractiveDataFromApplet(
187 std::make_shared<IStorage>(system, std::move(output_sub)));
186 } 188 }
187 } else { 189 } else {
188 output_main[0] = 1; 190 output_main[0] = 1;
189 complete = true; 191 complete = true;
190 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(std::move(output_main))); 192 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(output_main)));
191 broker.SignalStateChanged(); 193 broker.SignalStateChanged();
192 } 194 }
193} 195}
diff --git a/src/core/hle/service/am/applets/software_keyboard.h b/src/core/hle/service/am/applets/software_keyboard.h
index 5a3824b5a..1d260fef8 100644
--- a/src/core/hle/service/am/applets/software_keyboard.h
+++ b/src/core/hle/service/am/applets/software_keyboard.h
@@ -80,6 +80,7 @@ private:
80 bool complete = false; 80 bool complete = false;
81 bool is_inline = false; 81 bool is_inline = false;
82 std::vector<u8> final_data; 82 std::vector<u8> final_data;
83 Core::System& system;
83}; 84};
84 85
85} // namespace Service::AM::Applets 86} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/am/applets/web_browser.cpp b/src/core/hle/service/am/applets/web_browser.cpp
index efe595c4f..c3b6b706a 100644
--- a/src/core/hle/service/am/applets/web_browser.cpp
+++ b/src/core/hle/service/am/applets/web_browser.cpp
@@ -290,7 +290,7 @@ void WebBrowser::Finalize() {
290 std::vector<u8> data(sizeof(WebCommonReturnValue)); 290 std::vector<u8> data(sizeof(WebCommonReturnValue));
291 std::memcpy(data.data(), &out, sizeof(WebCommonReturnValue)); 291 std::memcpy(data.data(), &out, sizeof(WebCommonReturnValue));
292 292
293 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(std::move(data))); 293 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(data)));
294 broker.SignalStateChanged(); 294 broker.SignalStateChanged();
295 295
296 if (!temporary_dir.empty() && Common::FS::IsDirectory(temporary_dir)) { 296 if (!temporary_dir.empty() && Common::FS::IsDirectory(temporary_dir)) {
diff --git a/src/core/hle/service/am/idle.cpp b/src/core/hle/service/am/idle.cpp
index d256d57c8..6196773d5 100644
--- a/src/core/hle/service/am/idle.cpp
+++ b/src/core/hle/service/am/idle.cpp
@@ -6,7 +6,7 @@
6 6
7namespace Service::AM { 7namespace Service::AM {
8 8
9IdleSys::IdleSys() : ServiceFramework{"idle:sys"} { 9IdleSys::IdleSys(Core::System& system_) : ServiceFramework{system_, "idle:sys"} {
10 // clang-format off 10 // clang-format off
11 static const FunctionInfo functions[] = { 11 static const FunctionInfo functions[] = {
12 {0, nullptr, "GetAutoPowerDownEvent"}, 12 {0, nullptr, "GetAutoPowerDownEvent"},
diff --git a/src/core/hle/service/am/idle.h b/src/core/hle/service/am/idle.h
index c44e856b1..e290c30b1 100644
--- a/src/core/hle/service/am/idle.h
+++ b/src/core/hle/service/am/idle.h
@@ -6,11 +6,15 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::AM { 13namespace Service::AM {
10 14
11class IdleSys final : public ServiceFramework<IdleSys> { 15class IdleSys final : public ServiceFramework<IdleSys> {
12public: 16public:
13 explicit IdleSys(); 17 explicit IdleSys(Core::System& system_);
14 ~IdleSys() override; 18 ~IdleSys() override;
15}; 19};
16 20
diff --git a/src/core/hle/service/am/omm.cpp b/src/core/hle/service/am/omm.cpp
index 37389ccda..55de67e1d 100644
--- a/src/core/hle/service/am/omm.cpp
+++ b/src/core/hle/service/am/omm.cpp
@@ -6,7 +6,7 @@
6 6
7namespace Service::AM { 7namespace Service::AM {
8 8
9OMM::OMM() : ServiceFramework{"omm"} { 9OMM::OMM(Core::System& system_) : ServiceFramework{system_, "omm"} {
10 // clang-format off 10 // clang-format off
11 static const FunctionInfo functions[] = { 11 static const FunctionInfo functions[] = {
12 {0, nullptr, "GetOperationMode"}, 12 {0, nullptr, "GetOperationMode"},
diff --git a/src/core/hle/service/am/omm.h b/src/core/hle/service/am/omm.h
index 59dc91b72..3766150fe 100644
--- a/src/core/hle/service/am/omm.h
+++ b/src/core/hle/service/am/omm.h
@@ -6,11 +6,15 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::AM { 13namespace Service::AM {
10 14
11class OMM final : public ServiceFramework<OMM> { 15class OMM final : public ServiceFramework<OMM> {
12public: 16public:
13 explicit OMM(); 17 explicit OMM(Core::System& system_);
14 ~OMM() override; 18 ~OMM() override;
15}; 19};
16 20
diff --git a/src/core/hle/service/am/spsm.cpp b/src/core/hle/service/am/spsm.cpp
index f27729ce7..95218d9ee 100644
--- a/src/core/hle/service/am/spsm.cpp
+++ b/src/core/hle/service/am/spsm.cpp
@@ -6,7 +6,7 @@
6 6
7namespace Service::AM { 7namespace Service::AM {
8 8
9SPSM::SPSM() : ServiceFramework{"spsm"} { 9SPSM::SPSM(Core::System& system_) : ServiceFramework{system_, "spsm"} {
10 // clang-format off 10 // clang-format off
11 static const FunctionInfo functions[] = { 11 static const FunctionInfo functions[] = {
12 {0, nullptr, "GetState"}, 12 {0, nullptr, "GetState"},
diff --git a/src/core/hle/service/am/spsm.h b/src/core/hle/service/am/spsm.h
index 3a0b979fa..04bbf9e68 100644
--- a/src/core/hle/service/am/spsm.h
+++ b/src/core/hle/service/am/spsm.h
@@ -6,11 +6,15 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::AM { 13namespace Service::AM {
10 14
11class SPSM final : public ServiceFramework<SPSM> { 15class SPSM final : public ServiceFramework<SPSM> {
12public: 16public:
13 explicit SPSM(); 17 explicit SPSM(Core::System& system_);
14 ~SPSM() override; 18 ~SPSM() override;
15}; 19};
16 20
diff --git a/src/core/hle/service/am/tcap.cpp b/src/core/hle/service/am/tcap.cpp
index a75cbdda8..4d0971c03 100644
--- a/src/core/hle/service/am/tcap.cpp
+++ b/src/core/hle/service/am/tcap.cpp
@@ -6,7 +6,7 @@
6 6
7namespace Service::AM { 7namespace Service::AM {
8 8
9TCAP::TCAP() : ServiceFramework{"tcap"} { 9TCAP::TCAP(Core::System& system_) : ServiceFramework{system_, "tcap"} {
10 // clang-format off 10 // clang-format off
11 static const FunctionInfo functions[] = { 11 static const FunctionInfo functions[] = {
12 {0, nullptr, "GetContinuousHighSkinTemperatureEvent"}, 12 {0, nullptr, "GetContinuousHighSkinTemperatureEvent"},
diff --git a/src/core/hle/service/am/tcap.h b/src/core/hle/service/am/tcap.h
index 2021b55d1..e9578f16e 100644
--- a/src/core/hle/service/am/tcap.h
+++ b/src/core/hle/service/am/tcap.h
@@ -6,11 +6,15 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::AM { 13namespace Service::AM {
10 14
11class TCAP final : public ServiceFramework<TCAP> { 15class TCAP final : public ServiceFramework<TCAP> {
12public: 16public:
13 explicit TCAP(); 17 explicit TCAP(Core::System& system_);
14 ~TCAP() override; 18 ~TCAP() override;
15}; 19};
16 20
diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp
index 173b36da4..6abac3f78 100644
--- a/src/core/hle/service/aoc/aoc_u.cpp
+++ b/src/core/hle/service/aoc/aoc_u.cpp
@@ -48,8 +48,8 @@ static std::vector<u64> AccumulateAOCTitleIDs(Core::System& system) {
48 return add_on_content; 48 return add_on_content;
49} 49}
50 50
51AOC_U::AOC_U(Core::System& system) 51AOC_U::AOC_U(Core::System& system_)
52 : ServiceFramework("aoc:u"), add_on_content(AccumulateAOCTitleIDs(system)), system(system) { 52 : ServiceFramework{system_, "aoc:u"}, add_on_content{AccumulateAOCTitleIDs(system)} {
53 // clang-format off 53 // clang-format off
54 static const FunctionInfo functions[] = { 54 static const FunctionInfo functions[] = {
55 {0, nullptr, "CountAddOnContentByApplicationId"}, 55 {0, nullptr, "CountAddOnContentByApplicationId"},
diff --git a/src/core/hle/service/aoc/aoc_u.h b/src/core/hle/service/aoc/aoc_u.h
index 848b2f416..7628f4568 100644
--- a/src/core/hle/service/aoc/aoc_u.h
+++ b/src/core/hle/service/aoc/aoc_u.h
@@ -6,6 +6,10 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Kernel { 13namespace Kernel {
10class WritableEvent; 14class WritableEvent;
11} 15}
@@ -26,7 +30,6 @@ private:
26 30
27 std::vector<u64> add_on_content; 31 std::vector<u64> add_on_content;
28 Kernel::EventPair aoc_change_event; 32 Kernel::EventPair aoc_change_event;
29 Core::System& system;
30}; 33};
31 34
32/// Registers all AOC services with the specified service manager. 35/// Registers all AOC services with the specified service manager.
diff --git a/src/core/hle/service/apm/apm.cpp b/src/core/hle/service/apm/apm.cpp
index e2d8f0027..97d6619dd 100644
--- a/src/core/hle/service/apm/apm.cpp
+++ b/src/core/hle/service/apm/apm.cpp
@@ -14,13 +14,14 @@ Module::~Module() = default;
14 14
15void InstallInterfaces(Core::System& system) { 15void InstallInterfaces(Core::System& system) {
16 auto module_ = std::make_shared<Module>(); 16 auto module_ = std::make_shared<Module>();
17 std::make_shared<APM>(module_, system.GetAPMController(), "apm") 17 std::make_shared<APM>(system, module_, system.GetAPMController(), "apm")
18 ->InstallAsService(system.ServiceManager()); 18 ->InstallAsService(system.ServiceManager());
19 std::make_shared<APM>(module_, system.GetAPMController(), "apm:p") 19 std::make_shared<APM>(system, module_, system.GetAPMController(), "apm:p")
20 ->InstallAsService(system.ServiceManager()); 20 ->InstallAsService(system.ServiceManager());
21 std::make_shared<APM>(module_, system.GetAPMController(), "apm:am") 21 std::make_shared<APM>(system, module_, system.GetAPMController(), "apm:am")
22 ->InstallAsService(system.ServiceManager());
23 std::make_shared<APM_Sys>(system, system.GetAPMController())
22 ->InstallAsService(system.ServiceManager()); 24 ->InstallAsService(system.ServiceManager());
23 std::make_shared<APM_Sys>(system.GetAPMController())->InstallAsService(system.ServiceManager());
24} 25}
25 26
26} // namespace Service::APM 27} // namespace Service::APM
diff --git a/src/core/hle/service/apm/apm.h b/src/core/hle/service/apm/apm.h
index cf4c2bb11..691fe6c16 100644
--- a/src/core/hle/service/apm/apm.h
+++ b/src/core/hle/service/apm/apm.h
@@ -4,7 +4,9 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "core/hle/service/service.h" 7namespace Core {
8class System;
9}
8 10
9namespace Service::APM { 11namespace Service::APM {
10 12
diff --git a/src/core/hle/service/apm/interface.cpp b/src/core/hle/service/apm/interface.cpp
index 06f0f8edd..89442e21e 100644
--- a/src/core/hle/service/apm/interface.cpp
+++ b/src/core/hle/service/apm/interface.cpp
@@ -12,7 +12,8 @@ namespace Service::APM {
12 12
13class ISession final : public ServiceFramework<ISession> { 13class ISession final : public ServiceFramework<ISession> {
14public: 14public:
15 ISession(Controller& controller) : ServiceFramework("ISession"), controller(controller) { 15 explicit ISession(Core::System& system_, Controller& controller_)
16 : ServiceFramework{system_, "ISession"}, controller{controller_} {
16 static const FunctionInfo functions[] = { 17 static const FunctionInfo functions[] = {
17 {0, &ISession::SetPerformanceConfiguration, "SetPerformanceConfiguration"}, 18 {0, &ISession::SetPerformanceConfiguration, "SetPerformanceConfiguration"},
18 {1, &ISession::GetPerformanceConfiguration, "GetPerformanceConfiguration"}, 19 {1, &ISession::GetPerformanceConfiguration, "GetPerformanceConfiguration"},
@@ -50,8 +51,9 @@ private:
50 Controller& controller; 51 Controller& controller;
51}; 52};
52 53
53APM::APM(std::shared_ptr<Module> apm, Controller& controller, const char* name) 54APM::APM(Core::System& system_, std::shared_ptr<Module> apm_, Controller& controller_,
54 : ServiceFramework(name), apm(std::move(apm)), controller(controller) { 55 const char* name)
56 : ServiceFramework{system_, name}, apm(std::move(apm_)), controller{controller_} {
55 static const FunctionInfo functions[] = { 57 static const FunctionInfo functions[] = {
56 {0, &APM::OpenSession, "OpenSession"}, 58 {0, &APM::OpenSession, "OpenSession"},
57 {1, &APM::GetPerformanceMode, "GetPerformanceMode"}, 59 {1, &APM::GetPerformanceMode, "GetPerformanceMode"},
@@ -67,7 +69,7 @@ void APM::OpenSession(Kernel::HLERequestContext& ctx) {
67 69
68 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 70 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
69 rb.Push(RESULT_SUCCESS); 71 rb.Push(RESULT_SUCCESS);
70 rb.PushIpcInterface<ISession>(controller); 72 rb.PushIpcInterface<ISession>(system, controller);
71} 73}
72 74
73void APM::GetPerformanceMode(Kernel::HLERequestContext& ctx) { 75void APM::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
@@ -77,7 +79,8 @@ void APM::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
77 rb.PushEnum(controller.GetCurrentPerformanceMode()); 79 rb.PushEnum(controller.GetCurrentPerformanceMode());
78} 80}
79 81
80APM_Sys::APM_Sys(Controller& controller) : ServiceFramework{"apm:sys"}, controller(controller) { 82APM_Sys::APM_Sys(Core::System& system_, Controller& controller_)
83 : ServiceFramework{system_, "apm:sys"}, controller{controller_} {
81 // clang-format off 84 // clang-format off
82 static const FunctionInfo functions[] = { 85 static const FunctionInfo functions[] = {
83 {0, nullptr, "RequestPerformanceMode"}, 86 {0, nullptr, "RequestPerformanceMode"},
@@ -101,7 +104,7 @@ void APM_Sys::GetPerformanceEvent(Kernel::HLERequestContext& ctx) {
101 104
102 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 105 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
103 rb.Push(RESULT_SUCCESS); 106 rb.Push(RESULT_SUCCESS);
104 rb.PushIpcInterface<ISession>(controller); 107 rb.PushIpcInterface<ISession>(system, controller);
105} 108}
106 109
107void APM_Sys::SetCpuBoostMode(Kernel::HLERequestContext& ctx) { 110void APM_Sys::SetCpuBoostMode(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/hle/service/apm/interface.h b/src/core/hle/service/apm/interface.h
index de1b89437..7d57c4978 100644
--- a/src/core/hle/service/apm/interface.h
+++ b/src/core/hle/service/apm/interface.h
@@ -13,7 +13,8 @@ class Module;
13 13
14class APM final : public ServiceFramework<APM> { 14class APM final : public ServiceFramework<APM> {
15public: 15public:
16 explicit APM(std::shared_ptr<Module> apm, Controller& controller, const char* name); 16 explicit APM(Core::System& system_, std::shared_ptr<Module> apm_, Controller& controller_,
17 const char* name);
17 ~APM() override; 18 ~APM() override;
18 19
19private: 20private:
@@ -26,7 +27,7 @@ private:
26 27
27class APM_Sys final : public ServiceFramework<APM_Sys> { 28class APM_Sys final : public ServiceFramework<APM_Sys> {
28public: 29public:
29 explicit APM_Sys(Controller& controller); 30 explicit APM_Sys(Core::System& system_, Controller& controller);
30 ~APM_Sys() override; 31 ~APM_Sys() override;
31 32
32 void SetCpuBoostMode(Kernel::HLERequestContext& ctx); 33 void SetCpuBoostMode(Kernel::HLERequestContext& ctx);
diff --git a/src/core/hle/service/audio/audctl.cpp b/src/core/hle/service/audio/audctl.cpp
index 6ddb547fb..84890be72 100644
--- a/src/core/hle/service/audio/audctl.cpp
+++ b/src/core/hle/service/audio/audctl.cpp
@@ -8,7 +8,7 @@
8 8
9namespace Service::Audio { 9namespace Service::Audio {
10 10
11AudCtl::AudCtl() : ServiceFramework{"audctl"} { 11AudCtl::AudCtl(Core::System& system_) : ServiceFramework{system_, "audctl"} {
12 // clang-format off 12 // clang-format off
13 static const FunctionInfo functions[] = { 13 static const FunctionInfo functions[] = {
14 {0, nullptr, "GetTargetVolume"}, 14 {0, nullptr, "GetTargetVolume"},
diff --git a/src/core/hle/service/audio/audctl.h b/src/core/hle/service/audio/audctl.h
index c7fafc02e..15f6c77a0 100644
--- a/src/core/hle/service/audio/audctl.h
+++ b/src/core/hle/service/audio/audctl.h
@@ -6,11 +6,15 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::Audio { 13namespace Service::Audio {
10 14
11class AudCtl final : public ServiceFramework<AudCtl> { 15class AudCtl final : public ServiceFramework<AudCtl> {
12public: 16public:
13 explicit AudCtl(); 17 explicit AudCtl(Core::System& system_);
14 ~AudCtl() override; 18 ~AudCtl() override;
15 19
16private: 20private:
diff --git a/src/core/hle/service/audio/auddbg.cpp b/src/core/hle/service/audio/auddbg.cpp
index 8fff3e4b4..6264e4bda 100644
--- a/src/core/hle/service/audio/auddbg.cpp
+++ b/src/core/hle/service/audio/auddbg.cpp
@@ -6,7 +6,7 @@
6 6
7namespace Service::Audio { 7namespace Service::Audio {
8 8
9AudDbg::AudDbg(const char* name) : ServiceFramework{name} { 9AudDbg::AudDbg(Core::System& system_, const char* name) : ServiceFramework{system_, name} {
10 // clang-format off 10 // clang-format off
11 static const FunctionInfo functions[] = { 11 static const FunctionInfo functions[] = {
12 {0, nullptr, "RequestSuspendForDebug"}, 12 {0, nullptr, "RequestSuspendForDebug"},
diff --git a/src/core/hle/service/audio/auddbg.h b/src/core/hle/service/audio/auddbg.h
index 6689f4759..d1653eedd 100644
--- a/src/core/hle/service/audio/auddbg.h
+++ b/src/core/hle/service/audio/auddbg.h
@@ -6,11 +6,15 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::Audio { 13namespace Service::Audio {
10 14
11class AudDbg final : public ServiceFramework<AudDbg> { 15class AudDbg final : public ServiceFramework<AudDbg> {
12public: 16public:
13 explicit AudDbg(const char* name); 17 explicit AudDbg(Core::System& system_, const char* name);
14 ~AudDbg() override; 18 ~AudDbg() override;
15}; 19};
16 20
diff --git a/src/core/hle/service/audio/audin_a.cpp b/src/core/hle/service/audio/audin_a.cpp
index ddd12f35e..79c3aa920 100644
--- a/src/core/hle/service/audio/audin_a.cpp
+++ b/src/core/hle/service/audio/audin_a.cpp
@@ -6,7 +6,7 @@
6 6
7namespace Service::Audio { 7namespace Service::Audio {
8 8
9AudInA::AudInA() : ServiceFramework{"audin:a"} { 9AudInA::AudInA(Core::System& system_) : ServiceFramework{system_, "audin:a"} {
10 // clang-format off 10 // clang-format off
11 static const FunctionInfo functions[] = { 11 static const FunctionInfo functions[] = {
12 {0, nullptr, "RequestSuspendAudioIns"}, 12 {0, nullptr, "RequestSuspendAudioIns"},
diff --git a/src/core/hle/service/audio/audin_a.h b/src/core/hle/service/audio/audin_a.h
index e7623bc29..15120a4b6 100644
--- a/src/core/hle/service/audio/audin_a.h
+++ b/src/core/hle/service/audio/audin_a.h
@@ -6,11 +6,15 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::Audio { 13namespace Service::Audio {
10 14
11class AudInA final : public ServiceFramework<AudInA> { 15class AudInA final : public ServiceFramework<AudInA> {
12public: 16public:
13 explicit AudInA(); 17 explicit AudInA(Core::System& system_);
14 ~AudInA() override; 18 ~AudInA() override;
15}; 19};
16 20
diff --git a/src/core/hle/service/audio/audin_u.cpp b/src/core/hle/service/audio/audin_u.cpp
index 3e2299426..26a6deddf 100644
--- a/src/core/hle/service/audio/audin_u.cpp
+++ b/src/core/hle/service/audio/audin_u.cpp
@@ -11,7 +11,7 @@ namespace Service::Audio {
11 11
12class IAudioIn final : public ServiceFramework<IAudioIn> { 12class IAudioIn final : public ServiceFramework<IAudioIn> {
13public: 13public:
14 IAudioIn() : ServiceFramework("IAudioIn") { 14 explicit IAudioIn(Core::System& system_) : ServiceFramework{system_, "IAudioIn"} {
15 // clang-format off 15 // clang-format off
16 static const FunctionInfo functions[] = { 16 static const FunctionInfo functions[] = {
17 {0, nullptr, "GetAudioInState"}, 17 {0, nullptr, "GetAudioInState"},
@@ -36,7 +36,7 @@ public:
36 } 36 }
37}; 37};
38 38
39AudInU::AudInU() : ServiceFramework("audin:u") { 39AudInU::AudInU(Core::System& system_) : ServiceFramework{system_, "audin:u"} {
40 // clang-format off 40 // clang-format off
41 static const FunctionInfo functions[] = { 41 static const FunctionInfo functions[] = {
42 {0, &AudInU::ListAudioIns, "ListAudioIns"}, 42 {0, &AudInU::ListAudioIns, "ListAudioIns"},
@@ -96,7 +96,7 @@ void AudInU::OpenInOutImpl(Kernel::HLERequestContext& ctx) {
96 IPC::ResponseBuilder rb{ctx, 6, 0, 1}; 96 IPC::ResponseBuilder rb{ctx, 6, 0, 1};
97 rb.Push(RESULT_SUCCESS); 97 rb.Push(RESULT_SUCCESS);
98 rb.PushRaw<AudInOutParams>(params); 98 rb.PushRaw<AudInOutParams>(params);
99 rb.PushIpcInterface<IAudioIn>(); 99 rb.PushIpcInterface<IAudioIn>(system);
100} 100}
101 101
102void AudInU::OpenAudioIn(Kernel::HLERequestContext& ctx) { 102void AudInU::OpenAudioIn(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/hle/service/audio/audin_u.h b/src/core/hle/service/audio/audin_u.h
index a599f4a64..0d75ae5ac 100644
--- a/src/core/hle/service/audio/audin_u.h
+++ b/src/core/hle/service/audio/audin_u.h
@@ -6,6 +6,10 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Kernel { 13namespace Kernel {
10class HLERequestContext; 14class HLERequestContext;
11} 15}
@@ -14,7 +18,7 @@ namespace Service::Audio {
14 18
15class AudInU final : public ServiceFramework<AudInU> { 19class AudInU final : public ServiceFramework<AudInU> {
16public: 20public:
17 explicit AudInU(); 21 explicit AudInU(Core::System& system_);
18 ~AudInU() override; 22 ~AudInU() override;
19 23
20private: 24private:
diff --git a/src/core/hle/service/audio/audio.cpp b/src/core/hle/service/audio/audio.cpp
index 1781bec83..b3f24f9bb 100644
--- a/src/core/hle/service/audio/audio.cpp
+++ b/src/core/hle/service/audio/audio.cpp
@@ -20,22 +20,22 @@
20namespace Service::Audio { 20namespace Service::Audio {
21 21
22void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 22void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
23 std::make_shared<AudCtl>()->InstallAsService(service_manager); 23 std::make_shared<AudCtl>(system)->InstallAsService(service_manager);
24 std::make_shared<AudOutA>()->InstallAsService(service_manager); 24 std::make_shared<AudOutA>(system)->InstallAsService(service_manager);
25 std::make_shared<AudOutU>(system)->InstallAsService(service_manager); 25 std::make_shared<AudOutU>(system)->InstallAsService(service_manager);
26 std::make_shared<AudInA>()->InstallAsService(service_manager); 26 std::make_shared<AudInA>(system)->InstallAsService(service_manager);
27 std::make_shared<AudInU>()->InstallAsService(service_manager); 27 std::make_shared<AudInU>(system)->InstallAsService(service_manager);
28 std::make_shared<AudRecA>()->InstallAsService(service_manager); 28 std::make_shared<AudRecA>(system)->InstallAsService(service_manager);
29 std::make_shared<AudRecU>()->InstallAsService(service_manager); 29 std::make_shared<AudRecU>(system)->InstallAsService(service_manager);
30 std::make_shared<AudRenA>()->InstallAsService(service_manager); 30 std::make_shared<AudRenA>(system)->InstallAsService(service_manager);
31 std::make_shared<AudRenU>(system)->InstallAsService(service_manager); 31 std::make_shared<AudRenU>(system)->InstallAsService(service_manager);
32 std::make_shared<CodecCtl>()->InstallAsService(service_manager); 32 std::make_shared<CodecCtl>(system)->InstallAsService(service_manager);
33 std::make_shared<HwOpus>()->InstallAsService(service_manager); 33 std::make_shared<HwOpus>(system)->InstallAsService(service_manager);
34 34
35 std::make_shared<AudDbg>("audin:d")->InstallAsService(service_manager); 35 std::make_shared<AudDbg>(system, "audin:d")->InstallAsService(service_manager);
36 std::make_shared<AudDbg>("audout:d")->InstallAsService(service_manager); 36 std::make_shared<AudDbg>(system, "audout:d")->InstallAsService(service_manager);
37 std::make_shared<AudDbg>("audrec:d")->InstallAsService(service_manager); 37 std::make_shared<AudDbg>(system, "audrec:d")->InstallAsService(service_manager);
38 std::make_shared<AudDbg>("audren:d")->InstallAsService(service_manager); 38 std::make_shared<AudDbg>(system, "audren:d")->InstallAsService(service_manager);
39} 39}
40 40
41} // namespace Service::Audio 41} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audout_a.cpp b/src/core/hle/service/audio/audout_a.cpp
index 85febbca3..19825fd5d 100644
--- a/src/core/hle/service/audio/audout_a.cpp
+++ b/src/core/hle/service/audio/audout_a.cpp
@@ -6,7 +6,7 @@
6 6
7namespace Service::Audio { 7namespace Service::Audio {
8 8
9AudOutA::AudOutA() : ServiceFramework{"audout:a"} { 9AudOutA::AudOutA(Core::System& system_) : ServiceFramework{system_, "audout:a"} {
10 // clang-format off 10 // clang-format off
11 static const FunctionInfo functions[] = { 11 static const FunctionInfo functions[] = {
12 {0, nullptr, "RequestSuspendAudioOuts"}, 12 {0, nullptr, "RequestSuspendAudioOuts"},
diff --git a/src/core/hle/service/audio/audout_a.h b/src/core/hle/service/audio/audout_a.h
index d65b66e8e..2043dfb77 100644
--- a/src/core/hle/service/audio/audout_a.h
+++ b/src/core/hle/service/audio/audout_a.h
@@ -6,11 +6,15 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::Audio { 13namespace Service::Audio {
10 14
11class AudOutA final : public ServiceFramework<AudOutA> { 15class AudOutA final : public ServiceFramework<AudOutA> {
12public: 16public:
13 explicit AudOutA(); 17 explicit AudOutA(Core::System& system_);
14 ~AudOutA() override; 18 ~AudOutA() override;
15}; 19};
16 20
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp
index 9b4910e53..145f47ee2 100644
--- a/src/core/hle/service/audio/audout_u.cpp
+++ b/src/core/hle/service/audio/audout_u.cpp
@@ -40,11 +40,11 @@ enum class AudioState : u32 {
40 40
41class IAudioOut final : public ServiceFramework<IAudioOut> { 41class IAudioOut final : public ServiceFramework<IAudioOut> {
42public: 42public:
43 IAudioOut(Core::System& system, AudoutParams audio_params, AudioCore::AudioOut& audio_core, 43 IAudioOut(Core::System& system_, AudoutParams audio_params_, AudioCore::AudioOut& audio_core_,
44 std::string&& device_name, std::string&& unique_name) 44 std::string&& device_name_, std::string&& unique_name)
45 : ServiceFramework("IAudioOut"), audio_core(audio_core), 45 : ServiceFramework{system_, "IAudioOut"}, audio_core{audio_core_},
46 device_name(std::move(device_name)), 46 device_name{std::move(device_name_)}, audio_params{audio_params_}, main_memory{
47 audio_params(audio_params), main_memory{system.Memory()} { 47 system.Memory()} {
48 // clang-format off 48 // clang-format off
49 static const FunctionInfo functions[] = { 49 static const FunctionInfo functions[] = {
50 {0, &IAudioOut::GetAudioOutState, "GetAudioOutState"}, 50 {0, &IAudioOut::GetAudioOutState, "GetAudioOutState"},
@@ -213,7 +213,7 @@ private:
213 Core::Memory::Memory& main_memory; 213 Core::Memory::Memory& main_memory;
214}; 214};
215 215
216AudOutU::AudOutU(Core::System& system_) : ServiceFramework("audout:u"), system{system_} { 216AudOutU::AudOutU(Core::System& system_) : ServiceFramework{system_, "audout:u"} {
217 // clang-format off 217 // clang-format off
218 static const FunctionInfo functions[] = { 218 static const FunctionInfo functions[] = {
219 {0, &AudOutU::ListAudioOutsImpl, "ListAudioOuts"}, 219 {0, &AudOutU::ListAudioOutsImpl, "ListAudioOuts"},
diff --git a/src/core/hle/service/audio/audout_u.h b/src/core/hle/service/audio/audout_u.h
index c9f532ccd..f7ae2f2bf 100644
--- a/src/core/hle/service/audio/audout_u.h
+++ b/src/core/hle/service/audio/audout_u.h
@@ -34,8 +34,6 @@ private:
34 34
35 std::vector<std::shared_ptr<IAudioOut>> audio_out_interfaces; 35 std::vector<std::shared_ptr<IAudioOut>> audio_out_interfaces;
36 std::unique_ptr<AudioCore::AudioOut> audio_core; 36 std::unique_ptr<AudioCore::AudioOut> audio_core;
37
38 Core::System& system;
39}; 37};
40 38
41} // namespace Service::Audio 39} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audrec_a.cpp b/src/core/hle/service/audio/audrec_a.cpp
index ce1bfb48d..c5ab7cad4 100644
--- a/src/core/hle/service/audio/audrec_a.cpp
+++ b/src/core/hle/service/audio/audrec_a.cpp
@@ -6,7 +6,7 @@
6 6
7namespace Service::Audio { 7namespace Service::Audio {
8 8
9AudRecA::AudRecA() : ServiceFramework{"audrec:a"} { 9AudRecA::AudRecA(Core::System& system_) : ServiceFramework{system_, "audrec:a"} {
10 // clang-format off 10 // clang-format off
11 static const FunctionInfo functions[] = { 11 static const FunctionInfo functions[] = {
12 {0, nullptr, "RequestSuspendFinalOutputRecorders"}, 12 {0, nullptr, "RequestSuspendFinalOutputRecorders"},
diff --git a/src/core/hle/service/audio/audrec_a.h b/src/core/hle/service/audio/audrec_a.h
index 384d24c69..2cce90b1d 100644
--- a/src/core/hle/service/audio/audrec_a.h
+++ b/src/core/hle/service/audio/audrec_a.h
@@ -6,11 +6,15 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::Audio { 13namespace Service::Audio {
10 14
11class AudRecA final : public ServiceFramework<AudRecA> { 15class AudRecA final : public ServiceFramework<AudRecA> {
12public: 16public:
13 explicit AudRecA(); 17 explicit AudRecA(Core::System& system_);
14 ~AudRecA() override; 18 ~AudRecA() override;
15}; 19};
16 20
diff --git a/src/core/hle/service/audio/audrec_u.cpp b/src/core/hle/service/audio/audrec_u.cpp
index 1a5aed9ed..eb5c63c62 100644
--- a/src/core/hle/service/audio/audrec_u.cpp
+++ b/src/core/hle/service/audio/audrec_u.cpp
@@ -8,7 +8,8 @@ namespace Service::Audio {
8 8
9class IFinalOutputRecorder final : public ServiceFramework<IFinalOutputRecorder> { 9class IFinalOutputRecorder final : public ServiceFramework<IFinalOutputRecorder> {
10public: 10public:
11 IFinalOutputRecorder() : ServiceFramework("IFinalOutputRecorder") { 11 explicit IFinalOutputRecorder(Core::System& system_)
12 : ServiceFramework{system_, "IFinalOutputRecorder"} {
12 // clang-format off 13 // clang-format off
13 static const FunctionInfo functions[] = { 14 static const FunctionInfo functions[] = {
14 {0, nullptr, "GetFinalOutputRecorderState"}, 15 {0, nullptr, "GetFinalOutputRecorderState"},
@@ -29,7 +30,7 @@ public:
29 } 30 }
30}; 31};
31 32
32AudRecU::AudRecU() : ServiceFramework("audrec:u") { 33AudRecU::AudRecU(Core::System& system_) : ServiceFramework{system_, "audrec:u"} {
33 static const FunctionInfo functions[] = { 34 static const FunctionInfo functions[] = {
34 {0, nullptr, "OpenFinalOutputRecorder"}, 35 {0, nullptr, "OpenFinalOutputRecorder"},
35 }; 36 };
diff --git a/src/core/hle/service/audio/audrec_u.h b/src/core/hle/service/audio/audrec_u.h
index ca3d638e8..f79d49e5c 100644
--- a/src/core/hle/service/audio/audrec_u.h
+++ b/src/core/hle/service/audio/audrec_u.h
@@ -6,15 +6,15 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Kernel { 9namespace Core {
10class HLERequestContext; 10class System;
11} 11}
12 12
13namespace Service::Audio { 13namespace Service::Audio {
14 14
15class AudRecU final : public ServiceFramework<AudRecU> { 15class AudRecU final : public ServiceFramework<AudRecU> {
16public: 16public:
17 explicit AudRecU(); 17 explicit AudRecU(Core::System& system_);
18 ~AudRecU() override; 18 ~AudRecU() override;
19}; 19};
20 20
diff --git a/src/core/hle/service/audio/audren_a.cpp b/src/core/hle/service/audio/audren_a.cpp
index edb66d985..5e9f866f0 100644
--- a/src/core/hle/service/audio/audren_a.cpp
+++ b/src/core/hle/service/audio/audren_a.cpp
@@ -6,7 +6,7 @@
6 6
7namespace Service::Audio { 7namespace Service::Audio {
8 8
9AudRenA::AudRenA() : ServiceFramework{"audren:a"} { 9AudRenA::AudRenA(Core::System& system_) : ServiceFramework{system_, "audren:a"} {
10 // clang-format off 10 // clang-format off
11 static const FunctionInfo functions[] = { 11 static const FunctionInfo functions[] = {
12 {0, nullptr, "RequestSuspendAudioRenderers"}, 12 {0, nullptr, "RequestSuspendAudioRenderers"},
diff --git a/src/core/hle/service/audio/audren_a.h b/src/core/hle/service/audio/audren_a.h
index 81fef0ffe..5d0a626ad 100644
--- a/src/core/hle/service/audio/audren_a.h
+++ b/src/core/hle/service/audio/audren_a.h
@@ -6,11 +6,15 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::Audio { 13namespace Service::Audio {
10 14
11class AudRenA final : public ServiceFramework<AudRenA> { 15class AudRenA final : public ServiceFramework<AudRenA> {
12public: 16public:
13 explicit AudRenA(); 17 explicit AudRenA(Core::System& system_);
14 ~AudRenA() override; 18 ~AudRenA() override;
15}; 19};
16 20
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index a2d3ded7b..6e7b7316c 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -28,7 +28,7 @@ class IAudioRenderer final : public ServiceFramework<IAudioRenderer> {
28public: 28public:
29 explicit IAudioRenderer(Core::System& system, AudioCommon::AudioRendererParameter audren_params, 29 explicit IAudioRenderer(Core::System& system, AudioCommon::AudioRendererParameter audren_params,
30 const std::size_t instance_number) 30 const std::size_t instance_number)
31 : ServiceFramework("IAudioRenderer") { 31 : ServiceFramework{system, "IAudioRenderer"} {
32 // clang-format off 32 // clang-format off
33 static const FunctionInfo functions[] = { 33 static const FunctionInfo functions[] = {
34 {0, &IAudioRenderer::GetSampleRate, "GetSampleRate"}, 34 {0, &IAudioRenderer::GetSampleRate, "GetSampleRate"},
@@ -167,8 +167,8 @@ private:
167 167
168class IAudioDevice final : public ServiceFramework<IAudioDevice> { 168class IAudioDevice final : public ServiceFramework<IAudioDevice> {
169public: 169public:
170 explicit IAudioDevice(Core::System& system, u32_le revision_num) 170 explicit IAudioDevice(Core::System& system_, u32_le revision_num)
171 : ServiceFramework("IAudioDevice"), revision{revision_num} { 171 : ServiceFramework{system_, "IAudioDevice"}, revision{revision_num} {
172 static const FunctionInfo functions[] = { 172 static const FunctionInfo functions[] = {
173 {0, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceName"}, 173 {0, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceName"},
174 {1, &IAudioDevice::SetAudioDeviceOutputVolume, "SetAudioDeviceOutputVolume"}, 174 {1, &IAudioDevice::SetAudioDeviceOutputVolume, "SetAudioDeviceOutputVolume"},
@@ -325,7 +325,7 @@ private:
325 325
326}; // namespace Audio 326}; // namespace Audio
327 327
328AudRenU::AudRenU(Core::System& system_) : ServiceFramework("audren:u"), system{system_} { 328AudRenU::AudRenU(Core::System& system_) : ServiceFramework{system_, "audren:u"} {
329 // clang-format off 329 // clang-format off
330 static const FunctionInfo functions[] = { 330 static const FunctionInfo functions[] = {
331 {0, &AudRenU::OpenAudioRenderer, "OpenAudioRenderer"}, 331 {0, &AudRenU::OpenAudioRenderer, "OpenAudioRenderer"},
diff --git a/src/core/hle/service/audio/audren_u.h b/src/core/hle/service/audio/audren_u.h
index 4e0ccc792..d693dc406 100644
--- a/src/core/hle/service/audio/audren_u.h
+++ b/src/core/hle/service/audio/audren_u.h
@@ -31,7 +31,6 @@ private:
31 void OpenAudioRendererImpl(Kernel::HLERequestContext& ctx); 31 void OpenAudioRendererImpl(Kernel::HLERequestContext& ctx);
32 32
33 std::size_t audren_instance_count = 0; 33 std::size_t audren_instance_count = 0;
34 Core::System& system;
35}; 34};
36 35
37// Describes a particular audio feature that may be supported in a particular revision. 36// Describes a particular audio feature that may be supported in a particular revision.
diff --git a/src/core/hle/service/audio/codecctl.cpp b/src/core/hle/service/audio/codecctl.cpp
index c6864146d..94afec1b6 100644
--- a/src/core/hle/service/audio/codecctl.cpp
+++ b/src/core/hle/service/audio/codecctl.cpp
@@ -2,14 +2,11 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/logging/log.h"
6#include "core/hle/ipc_helpers.h"
7#include "core/hle/kernel/hle_ipc.h"
8#include "core/hle/service/audio/codecctl.h" 5#include "core/hle/service/audio/codecctl.h"
9 6
10namespace Service::Audio { 7namespace Service::Audio {
11 8
12CodecCtl::CodecCtl() : ServiceFramework("codecctl") { 9CodecCtl::CodecCtl(Core::System& system_) : ServiceFramework{system_, "codecctl"} {
13 static const FunctionInfo functions[] = { 10 static const FunctionInfo functions[] = {
14 {0, nullptr, "InitializeCodecController"}, 11 {0, nullptr, "InitializeCodecController"},
15 {1, nullptr, "FinalizeCodecController"}, 12 {1, nullptr, "FinalizeCodecController"},
diff --git a/src/core/hle/service/audio/codecctl.h b/src/core/hle/service/audio/codecctl.h
index 2fe75b6e2..58e53259e 100644
--- a/src/core/hle/service/audio/codecctl.h
+++ b/src/core/hle/service/audio/codecctl.h
@@ -6,15 +6,15 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Kernel { 9namespace Core {
10class HLERequestContext; 10class System;
11} 11}
12 12
13namespace Service::Audio { 13namespace Service::Audio {
14 14
15class CodecCtl final : public ServiceFramework<CodecCtl> { 15class CodecCtl final : public ServiceFramework<CodecCtl> {
16public: 16public:
17 explicit CodecCtl(); 17 explicit CodecCtl(Core::System& system_);
18 ~CodecCtl() override; 18 ~CodecCtl() override;
19}; 19};
20 20
diff --git a/src/core/hle/service/audio/hwopus.cpp b/src/core/hle/service/audio/hwopus.cpp
index f1d81602c..ea3414fd2 100644
--- a/src/core/hle/service/audio/hwopus.cpp
+++ b/src/core/hle/service/audio/hwopus.cpp
@@ -160,8 +160,9 @@ private:
160 160
161class IHardwareOpusDecoderManager final : public ServiceFramework<IHardwareOpusDecoderManager> { 161class IHardwareOpusDecoderManager final : public ServiceFramework<IHardwareOpusDecoderManager> {
162public: 162public:
163 explicit IHardwareOpusDecoderManager(OpusDecoderState decoder_state) 163 explicit IHardwareOpusDecoderManager(Core::System& system_, OpusDecoderState decoder_state)
164 : ServiceFramework("IHardwareOpusDecoderManager"), decoder_state{std::move(decoder_state)} { 164 : ServiceFramework{system_, "IHardwareOpusDecoderManager"}, decoder_state{
165 std::move(decoder_state)} {
165 // clang-format off 166 // clang-format off
166 static const FunctionInfo functions[] = { 167 static const FunctionInfo functions[] = {
167 {0, &IHardwareOpusDecoderManager::DecodeInterleavedOld, "DecodeInterleavedOld"}, 168 {0, &IHardwareOpusDecoderManager::DecodeInterleavedOld, "DecodeInterleavedOld"},
@@ -287,10 +288,10 @@ void HwOpus::OpenOpusDecoder(Kernel::HLERequestContext& ctx) {
287 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 288 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
288 rb.Push(RESULT_SUCCESS); 289 rb.Push(RESULT_SUCCESS);
289 rb.PushIpcInterface<IHardwareOpusDecoderManager>( 290 rb.PushIpcInterface<IHardwareOpusDecoderManager>(
290 OpusDecoderState{std::move(decoder), sample_rate, channel_count}); 291 system, OpusDecoderState{std::move(decoder), sample_rate, channel_count});
291} 292}
292 293
293HwOpus::HwOpus() : ServiceFramework("hwopus") { 294HwOpus::HwOpus(Core::System& system_) : ServiceFramework{system_, "hwopus"} {
294 static const FunctionInfo functions[] = { 295 static const FunctionInfo functions[] = {
295 {0, &HwOpus::OpenOpusDecoder, "OpenOpusDecoder"}, 296 {0, &HwOpus::OpenOpusDecoder, "OpenOpusDecoder"},
296 {1, &HwOpus::GetWorkBufferSize, "GetWorkBufferSize"}, 297 {1, &HwOpus::GetWorkBufferSize, "GetWorkBufferSize"},
diff --git a/src/core/hle/service/audio/hwopus.h b/src/core/hle/service/audio/hwopus.h
index 602ede8ba..4f921f18e 100644
--- a/src/core/hle/service/audio/hwopus.h
+++ b/src/core/hle/service/audio/hwopus.h
@@ -6,11 +6,15 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::Audio { 13namespace Service::Audio {
10 14
11class HwOpus final : public ServiceFramework<HwOpus> { 15class HwOpus final : public ServiceFramework<HwOpus> {
12public: 16public:
13 explicit HwOpus(); 17 explicit HwOpus(Core::System& system_);
14 ~HwOpus() override; 18 ~HwOpus() override;
15 19
16private: 20private:
diff --git a/src/core/hle/service/bcat/module.cpp b/src/core/hle/service/bcat/module.cpp
index 68deb0600..b8696a395 100644
--- a/src/core/hle/service/bcat/module.cpp
+++ b/src/core/hle/service/bcat/module.cpp
@@ -88,9 +88,11 @@ struct DeliveryCacheDirectoryEntry {
88 88
89class IDeliveryCacheProgressService final : public ServiceFramework<IDeliveryCacheProgressService> { 89class IDeliveryCacheProgressService final : public ServiceFramework<IDeliveryCacheProgressService> {
90public: 90public:
91 IDeliveryCacheProgressService(std::shared_ptr<Kernel::ReadableEvent> event, 91 explicit IDeliveryCacheProgressService(Core::System& system_,
92 const DeliveryCacheProgressImpl& impl) 92 std::shared_ptr<Kernel::ReadableEvent> event_,
93 : ServiceFramework{"IDeliveryCacheProgressService"}, event(std::move(event)), impl(impl) { 93 const DeliveryCacheProgressImpl& impl_)
94 : ServiceFramework{system_, "IDeliveryCacheProgressService"}, event{std::move(event_)},
95 impl{impl_} {
94 // clang-format off 96 // clang-format off
95 static const FunctionInfo functions[] = { 97 static const FunctionInfo functions[] = {
96 {0, &IDeliveryCacheProgressService::GetEvent, "GetEvent"}, 98 {0, &IDeliveryCacheProgressService::GetEvent, "GetEvent"},
@@ -126,7 +128,7 @@ private:
126class IBcatService final : public ServiceFramework<IBcatService> { 128class IBcatService final : public ServiceFramework<IBcatService> {
127public: 129public:
128 explicit IBcatService(Core::System& system_, Backend& backend_) 130 explicit IBcatService(Core::System& system_, Backend& backend_)
129 : ServiceFramework("IBcatService"), system{system_}, backend{backend_}, 131 : ServiceFramework{system_, "IBcatService"}, backend{backend_},
130 progress{{ 132 progress{{
131 ProgressServiceBackend{system_.Kernel(), "Normal"}, 133 ProgressServiceBackend{system_.Kernel(), "Normal"},
132 ProgressServiceBackend{system_.Kernel(), "Directory"}, 134 ProgressServiceBackend{system_.Kernel(), "Directory"},
@@ -171,7 +173,7 @@ private:
171 173
172 std::shared_ptr<IDeliveryCacheProgressService> CreateProgressService(SyncType type) { 174 std::shared_ptr<IDeliveryCacheProgressService> CreateProgressService(SyncType type) {
173 auto& backend{progress.at(static_cast<std::size_t>(type))}; 175 auto& backend{progress.at(static_cast<std::size_t>(type))};
174 return std::make_shared<IDeliveryCacheProgressService>(backend.GetEvent(), 176 return std::make_shared<IDeliveryCacheProgressService>(system, backend.GetEvent(),
175 backend.GetImpl()); 177 backend.GetImpl());
176 } 178 }
177 179
@@ -261,7 +263,6 @@ private:
261 rb.Push(RESULT_SUCCESS); 263 rb.Push(RESULT_SUCCESS);
262 } 264 }
263 265
264 Core::System& system;
265 Backend& backend; 266 Backend& backend;
266 267
267 std::array<ProgressServiceBackend, static_cast<std::size_t>(SyncType::Count)> progress; 268 std::array<ProgressServiceBackend, static_cast<std::size_t>(SyncType::Count)> progress;
@@ -277,8 +278,8 @@ void Module::Interface::CreateBcatService(Kernel::HLERequestContext& ctx) {
277 278
278class IDeliveryCacheFileService final : public ServiceFramework<IDeliveryCacheFileService> { 279class IDeliveryCacheFileService final : public ServiceFramework<IDeliveryCacheFileService> {
279public: 280public:
280 IDeliveryCacheFileService(FileSys::VirtualDir root_) 281 explicit IDeliveryCacheFileService(Core::System& system_, FileSys::VirtualDir root_)
281 : ServiceFramework{"IDeliveryCacheFileService"}, root(std::move(root_)) { 282 : ServiceFramework{system_, "IDeliveryCacheFileService"}, root(std::move(root_)) {
282 // clang-format off 283 // clang-format off
283 static const FunctionInfo functions[] = { 284 static const FunctionInfo functions[] = {
284 {0, &IDeliveryCacheFileService::Open, "Open"}, 285 {0, &IDeliveryCacheFileService::Open, "Open"},
@@ -394,8 +395,8 @@ private:
394class IDeliveryCacheDirectoryService final 395class IDeliveryCacheDirectoryService final
395 : public ServiceFramework<IDeliveryCacheDirectoryService> { 396 : public ServiceFramework<IDeliveryCacheDirectoryService> {
396public: 397public:
397 IDeliveryCacheDirectoryService(FileSys::VirtualDir root_) 398 explicit IDeliveryCacheDirectoryService(Core::System& system_, FileSys::VirtualDir root_)
398 : ServiceFramework{"IDeliveryCacheDirectoryService"}, root(std::move(root_)) { 399 : ServiceFramework{system_, "IDeliveryCacheDirectoryService"}, root(std::move(root_)) {
399 // clang-format off 400 // clang-format off
400 static const FunctionInfo functions[] = { 401 static const FunctionInfo functions[] = {
401 {0, &IDeliveryCacheDirectoryService::Open, "Open"}, 402 {0, &IDeliveryCacheDirectoryService::Open, "Open"},
@@ -492,8 +493,8 @@ private:
492 493
493class IDeliveryCacheStorageService final : public ServiceFramework<IDeliveryCacheStorageService> { 494class IDeliveryCacheStorageService final : public ServiceFramework<IDeliveryCacheStorageService> {
494public: 495public:
495 IDeliveryCacheStorageService(FileSys::VirtualDir root_) 496 explicit IDeliveryCacheStorageService(Core::System& system_, FileSys::VirtualDir root_)
496 : ServiceFramework{"IDeliveryCacheStorageService"}, root(std::move(root_)) { 497 : ServiceFramework{system_, "IDeliveryCacheStorageService"}, root(std::move(root_)) {
497 // clang-format off 498 // clang-format off
498 static const FunctionInfo functions[] = { 499 static const FunctionInfo functions[] = {
499 {0, &IDeliveryCacheStorageService::CreateFileService, "CreateFileService"}, 500 {0, &IDeliveryCacheStorageService::CreateFileService, "CreateFileService"},
@@ -518,7 +519,7 @@ private:
518 519
519 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 520 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
520 rb.Push(RESULT_SUCCESS); 521 rb.Push(RESULT_SUCCESS);
521 rb.PushIpcInterface<IDeliveryCacheFileService>(root); 522 rb.PushIpcInterface<IDeliveryCacheFileService>(system, root);
522 } 523 }
523 524
524 void CreateDirectoryService(Kernel::HLERequestContext& ctx) { 525 void CreateDirectoryService(Kernel::HLERequestContext& ctx) {
@@ -526,7 +527,7 @@ private:
526 527
527 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 528 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
528 rb.Push(RESULT_SUCCESS); 529 rb.Push(RESULT_SUCCESS);
529 rb.PushIpcInterface<IDeliveryCacheDirectoryService>(root); 530 rb.PushIpcInterface<IDeliveryCacheDirectoryService>(system, root);
530 } 531 }
531 532
532 void EnumerateDeliveryCacheDirectory(Kernel::HLERequestContext& ctx) { 533 void EnumerateDeliveryCacheDirectory(Kernel::HLERequestContext& ctx) {
@@ -551,10 +552,10 @@ private:
551void Module::Interface::CreateDeliveryCacheStorageService(Kernel::HLERequestContext& ctx) { 552void Module::Interface::CreateDeliveryCacheStorageService(Kernel::HLERequestContext& ctx) {
552 LOG_DEBUG(Service_BCAT, "called"); 553 LOG_DEBUG(Service_BCAT, "called");
553 554
555 const auto title_id = system.CurrentProcess()->GetTitleID();
554 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 556 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
555 rb.Push(RESULT_SUCCESS); 557 rb.Push(RESULT_SUCCESS);
556 rb.PushIpcInterface<IDeliveryCacheStorageService>( 558 rb.PushIpcInterface<IDeliveryCacheStorageService>(system, fsc.GetBCATDirectory(title_id));
557 fsc.GetBCATDirectory(system.CurrentProcess()->GetTitleID()));
558} 559}
559 560
560void Module::Interface::CreateDeliveryCacheStorageServiceWithApplicationId( 561void Module::Interface::CreateDeliveryCacheStorageServiceWithApplicationId(
@@ -566,7 +567,7 @@ void Module::Interface::CreateDeliveryCacheStorageServiceWithApplicationId(
566 567
567 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 568 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
568 rb.Push(RESULT_SUCCESS); 569 rb.Push(RESULT_SUCCESS);
569 rb.PushIpcInterface<IDeliveryCacheStorageService>(fsc.GetBCATDirectory(title_id)); 570 rb.PushIpcInterface<IDeliveryCacheStorageService>(system, fsc.GetBCATDirectory(title_id));
570} 571}
571 572
572std::unique_ptr<Backend> CreateBackendFromSettings([[maybe_unused]] Core::System& system, 573std::unique_ptr<Backend> CreateBackendFromSettings([[maybe_unused]] Core::System& system,
@@ -582,10 +583,9 @@ std::unique_ptr<Backend> CreateBackendFromSettings([[maybe_unused]] Core::System
582 583
583Module::Interface::Interface(Core::System& system_, std::shared_ptr<Module> module_, 584Module::Interface::Interface(Core::System& system_, std::shared_ptr<Module> module_,
584 FileSystem::FileSystemController& fsc_, const char* name) 585 FileSystem::FileSystemController& fsc_, const char* name)
585 : ServiceFramework(name), fsc{fsc_}, module{std::move(module_)}, 586 : ServiceFramework{system_, name}, fsc{fsc_}, module{std::move(module_)},
586 backend{CreateBackendFromSettings(system_, 587 backend{CreateBackendFromSettings(system_,
587 [&fsc_](u64 tid) { return fsc_.GetBCATDirectory(tid); })}, 588 [&fsc_](u64 tid) { return fsc_.GetBCATDirectory(tid); })} {}
588 system{system_} {}
589 589
590Module::Interface::~Interface() = default; 590Module::Interface::~Interface() = default;
591 591
diff --git a/src/core/hle/service/bcat/module.h b/src/core/hle/service/bcat/module.h
index e4ba23ba0..738731c06 100644
--- a/src/core/hle/service/bcat/module.h
+++ b/src/core/hle/service/bcat/module.h
@@ -37,9 +37,6 @@ public:
37 37
38 std::shared_ptr<Module> module; 38 std::shared_ptr<Module> module;
39 std::unique_ptr<Backend> backend; 39 std::unique_ptr<Backend> backend;
40
41 private:
42 Core::System& system;
43 }; 40 };
44}; 41};
45 42
diff --git a/src/core/hle/service/bpc/bpc.cpp b/src/core/hle/service/bpc/bpc.cpp
index fac6b2f9c..e4630320e 100644
--- a/src/core/hle/service/bpc/bpc.cpp
+++ b/src/core/hle/service/bpc/bpc.cpp
@@ -12,7 +12,7 @@ namespace Service::BPC {
12 12
13class BPC final : public ServiceFramework<BPC> { 13class BPC final : public ServiceFramework<BPC> {
14public: 14public:
15 explicit BPC() : ServiceFramework{"bpc"} { 15 explicit BPC(Core::System& system_) : ServiceFramework{system_, "bpc"} {
16 // clang-format off 16 // clang-format off
17 static const FunctionInfo functions[] = { 17 static const FunctionInfo functions[] = {
18 {0, nullptr, "ShutdownSystem"}, 18 {0, nullptr, "ShutdownSystem"},
@@ -40,7 +40,7 @@ public:
40 40
41class BPC_R final : public ServiceFramework<BPC_R> { 41class BPC_R final : public ServiceFramework<BPC_R> {
42public: 42public:
43 explicit BPC_R() : ServiceFramework{"bpc:r"} { 43 explicit BPC_R(Core::System& system_) : ServiceFramework{system_, "bpc:r"} {
44 // clang-format off 44 // clang-format off
45 static const FunctionInfo functions[] = { 45 static const FunctionInfo functions[] = {
46 {0, nullptr, "GetRtcTime"}, 46 {0, nullptr, "GetRtcTime"},
@@ -55,9 +55,9 @@ public:
55 } 55 }
56}; 56};
57 57
58void InstallInterfaces(SM::ServiceManager& sm) { 58void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
59 std::make_shared<BPC>()->InstallAsService(sm); 59 std::make_shared<BPC>(system)->InstallAsService(sm);
60 std::make_shared<BPC_R>()->InstallAsService(sm); 60 std::make_shared<BPC_R>(system)->InstallAsService(sm);
61} 61}
62 62
63} // namespace Service::BPC 63} // namespace Service::BPC
diff --git a/src/core/hle/service/bpc/bpc.h b/src/core/hle/service/bpc/bpc.h
index eaa37be8d..6ec25aa9b 100644
--- a/src/core/hle/service/bpc/bpc.h
+++ b/src/core/hle/service/bpc/bpc.h
@@ -4,12 +4,16 @@
4 4
5#pragma once 5#pragma once
6 6
7namespace Core {
8class System;
9}
10
7namespace Service::SM { 11namespace Service::SM {
8class ServiceManager; 12class ServiceManager;
9} 13}
10 14
11namespace Service::BPC { 15namespace Service::BPC {
12 16
13void InstallInterfaces(SM::ServiceManager& sm); 17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
14 18
15} // namespace Service::BPC 19} // namespace Service::BPC
diff --git a/src/core/hle/service/btdrv/btdrv.cpp b/src/core/hle/service/btdrv/btdrv.cpp
index d4f0dd1ab..2de86f1f1 100644
--- a/src/core/hle/service/btdrv/btdrv.cpp
+++ b/src/core/hle/service/btdrv/btdrv.cpp
@@ -17,7 +17,7 @@ namespace Service::BtDrv {
17 17
18class Bt final : public ServiceFramework<Bt> { 18class Bt final : public ServiceFramework<Bt> {
19public: 19public:
20 explicit Bt(Core::System& system) : ServiceFramework{"bt"} { 20 explicit Bt(Core::System& system_) : ServiceFramework{system_, "bt"} {
21 // clang-format off 21 // clang-format off
22 static const FunctionInfo functions[] = { 22 static const FunctionInfo functions[] = {
23 {0, nullptr, "LeClientReadCharacteristic"}, 23 {0, nullptr, "LeClientReadCharacteristic"},
@@ -52,7 +52,7 @@ private:
52 52
53class BtDrv final : public ServiceFramework<BtDrv> { 53class BtDrv final : public ServiceFramework<BtDrv> {
54public: 54public:
55 explicit BtDrv() : ServiceFramework{"btdrv"} { 55 explicit BtDrv(Core::System& system_) : ServiceFramework{system_, "btdrv"} {
56 // clang-format off 56 // clang-format off
57 static const FunctionInfo functions[] = { 57 static const FunctionInfo functions[] = {
58 {0, nullptr, "InitializeBluetoothDriver"}, 58 {0, nullptr, "InitializeBluetoothDriver"},
@@ -166,7 +166,7 @@ public:
166}; 166};
167 167
168void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 168void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
169 std::make_shared<BtDrv>()->InstallAsService(sm); 169 std::make_shared<BtDrv>(system)->InstallAsService(sm);
170 std::make_shared<Bt>(system)->InstallAsService(sm); 170 std::make_shared<Bt>(system)->InstallAsService(sm);
171} 171}
172 172
diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp
index c8f8ddbd5..38b55300e 100644
--- a/src/core/hle/service/btm/btm.cpp
+++ b/src/core/hle/service/btm/btm.cpp
@@ -18,7 +18,7 @@ namespace Service::BTM {
18 18
19class IBtmUserCore final : public ServiceFramework<IBtmUserCore> { 19class IBtmUserCore final : public ServiceFramework<IBtmUserCore> {
20public: 20public:
21 explicit IBtmUserCore(Core::System& system) : ServiceFramework{"IBtmUserCore"} { 21 explicit IBtmUserCore(Core::System& system_) : ServiceFramework{system_, "IBtmUserCore"} {
22 // clang-format off 22 // clang-format off
23 static const FunctionInfo functions[] = { 23 static const FunctionInfo functions[] = {
24 {0, &IBtmUserCore::AcquireBleScanEvent, "AcquireBleScanEvent"}, 24 {0, &IBtmUserCore::AcquireBleScanEvent, "AcquireBleScanEvent"},
@@ -107,7 +107,7 @@ private:
107 107
108class BTM_USR final : public ServiceFramework<BTM_USR> { 108class BTM_USR final : public ServiceFramework<BTM_USR> {
109public: 109public:
110 explicit BTM_USR(Core::System& system) : ServiceFramework{"btm:u"}, system(system) { 110 explicit BTM_USR(Core::System& system_) : ServiceFramework{system_, "btm:u"} {
111 // clang-format off 111 // clang-format off
112 static const FunctionInfo functions[] = { 112 static const FunctionInfo functions[] = {
113 {0, &BTM_USR::GetCore, "GetCore"}, 113 {0, &BTM_USR::GetCore, "GetCore"},
@@ -124,13 +124,11 @@ private:
124 rb.Push(RESULT_SUCCESS); 124 rb.Push(RESULT_SUCCESS);
125 rb.PushIpcInterface<IBtmUserCore>(system); 125 rb.PushIpcInterface<IBtmUserCore>(system);
126 } 126 }
127
128 Core::System& system;
129}; 127};
130 128
131class BTM final : public ServiceFramework<BTM> { 129class BTM final : public ServiceFramework<BTM> {
132public: 130public:
133 explicit BTM() : ServiceFramework{"btm"} { 131 explicit BTM(Core::System& system_) : ServiceFramework{system_, "btm"} {
134 // clang-format off 132 // clang-format off
135 static const FunctionInfo functions[] = { 133 static const FunctionInfo functions[] = {
136 {0, nullptr, "GetState"}, 134 {0, nullptr, "GetState"},
@@ -207,7 +205,7 @@ public:
207 205
208class BTM_DBG final : public ServiceFramework<BTM_DBG> { 206class BTM_DBG final : public ServiceFramework<BTM_DBG> {
209public: 207public:
210 explicit BTM_DBG() : ServiceFramework{"btm:dbg"} { 208 explicit BTM_DBG(Core::System& system_) : ServiceFramework{system_, "btm:dbg"} {
211 // clang-format off 209 // clang-format off
212 static const FunctionInfo functions[] = { 210 static const FunctionInfo functions[] = {
213 {0, nullptr, "AcquireDiscoveryEvent"}, 211 {0, nullptr, "AcquireDiscoveryEvent"},
@@ -232,7 +230,7 @@ public:
232 230
233class IBtmSystemCore final : public ServiceFramework<IBtmSystemCore> { 231class IBtmSystemCore final : public ServiceFramework<IBtmSystemCore> {
234public: 232public:
235 explicit IBtmSystemCore() : ServiceFramework{"IBtmSystemCore"} { 233 explicit IBtmSystemCore(Core::System& system_) : ServiceFramework{system_, "IBtmSystemCore"} {
236 // clang-format off 234 // clang-format off
237 static const FunctionInfo functions[] = { 235 static const FunctionInfo functions[] = {
238 {0, nullptr, "StartGamepadPairing"}, 236 {0, nullptr, "StartGamepadPairing"},
@@ -254,7 +252,7 @@ public:
254 252
255class BTM_SYS final : public ServiceFramework<BTM_SYS> { 253class BTM_SYS final : public ServiceFramework<BTM_SYS> {
256public: 254public:
257 explicit BTM_SYS() : ServiceFramework{"btm:sys"} { 255 explicit BTM_SYS(Core::System& system_) : ServiceFramework{system_, "btm:sys"} {
258 // clang-format off 256 // clang-format off
259 static const FunctionInfo functions[] = { 257 static const FunctionInfo functions[] = {
260 {0, &BTM_SYS::GetCore, "GetCore"}, 258 {0, &BTM_SYS::GetCore, "GetCore"},
@@ -270,14 +268,14 @@ private:
270 268
271 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 269 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
272 rb.Push(RESULT_SUCCESS); 270 rb.Push(RESULT_SUCCESS);
273 rb.PushIpcInterface<IBtmSystemCore>(); 271 rb.PushIpcInterface<IBtmSystemCore>(system);
274 } 272 }
275}; 273};
276 274
277void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 275void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
278 std::make_shared<BTM>()->InstallAsService(sm); 276 std::make_shared<BTM>(system)->InstallAsService(sm);
279 std::make_shared<BTM_DBG>()->InstallAsService(sm); 277 std::make_shared<BTM_DBG>(system)->InstallAsService(sm);
280 std::make_shared<BTM_SYS>()->InstallAsService(sm); 278 std::make_shared<BTM_SYS>(system)->InstallAsService(sm);
281 std::make_shared<BTM_USR>(system)->InstallAsService(sm); 279 std::make_shared<BTM_USR>(system)->InstallAsService(sm);
282} 280}
283 281
diff --git a/src/core/hle/service/caps/caps.cpp b/src/core/hle/service/caps/caps.cpp
index ba5749b84..5b7fe8e9b 100644
--- a/src/core/hle/service/caps/caps.cpp
+++ b/src/core/hle/service/caps/caps.cpp
@@ -13,13 +13,13 @@
13 13
14namespace Service::Capture { 14namespace Service::Capture {
15 15
16void InstallInterfaces(SM::ServiceManager& sm) { 16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
17 std::make_shared<CAPS_A>()->InstallAsService(sm); 17 std::make_shared<CAPS_A>(system)->InstallAsService(sm);
18 std::make_shared<CAPS_C>()->InstallAsService(sm); 18 std::make_shared<CAPS_C>(system)->InstallAsService(sm);
19 std::make_shared<CAPS_U>()->InstallAsService(sm); 19 std::make_shared<CAPS_U>(system)->InstallAsService(sm);
20 std::make_shared<CAPS_SC>()->InstallAsService(sm); 20 std::make_shared<CAPS_SC>(system)->InstallAsService(sm);
21 std::make_shared<CAPS_SS>()->InstallAsService(sm); 21 std::make_shared<CAPS_SS>(system)->InstallAsService(sm);
22 std::make_shared<CAPS_SU>()->InstallAsService(sm); 22 std::make_shared<CAPS_SU>(system)->InstallAsService(sm);
23} 23}
24 24
25} // namespace Service::Capture 25} // namespace Service::Capture
diff --git a/src/core/hle/service/caps/caps.h b/src/core/hle/service/caps/caps.h
index b8c67b6e2..3c4290c88 100644
--- a/src/core/hle/service/caps/caps.h
+++ b/src/core/hle/service/caps/caps.h
@@ -6,6 +6,10 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::SM { 13namespace Service::SM {
10class ServiceManager; 14class ServiceManager;
11} 15}
@@ -87,6 +91,6 @@ static_assert(sizeof(ApplicationAlbumFileEntry) == 0x30,
87 "ApplicationAlbumFileEntry has incorrect size."); 91 "ApplicationAlbumFileEntry has incorrect size.");
88 92
89/// Registers all Capture services with the specified service manager. 93/// Registers all Capture services with the specified service manager.
90void InstallInterfaces(SM::ServiceManager& sm); 94void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
91 95
92} // namespace Service::Capture 96} // namespace Service::Capture
diff --git a/src/core/hle/service/caps/caps_a.cpp b/src/core/hle/service/caps/caps_a.cpp
index a0a3b2ae3..1fe4f0e14 100644
--- a/src/core/hle/service/caps/caps_a.cpp
+++ b/src/core/hle/service/caps/caps_a.cpp
@@ -8,7 +8,8 @@ namespace Service::Capture {
8 8
9class IAlbumAccessorSession final : public ServiceFramework<IAlbumAccessorSession> { 9class IAlbumAccessorSession final : public ServiceFramework<IAlbumAccessorSession> {
10public: 10public:
11 explicit IAlbumAccessorSession() : ServiceFramework{"IAlbumAccessorSession"} { 11 explicit IAlbumAccessorSession(Core::System& system_)
12 : ServiceFramework{system_, "IAlbumAccessorSession"} {
12 // clang-format off 13 // clang-format off
13 static const FunctionInfo functions[] = { 14 static const FunctionInfo functions[] = {
14 {2001, nullptr, "OpenAlbumMovieReadStream"}, 15 {2001, nullptr, "OpenAlbumMovieReadStream"},
@@ -26,7 +27,7 @@ public:
26 } 27 }
27}; 28};
28 29
29CAPS_A::CAPS_A() : ServiceFramework("caps:a") { 30CAPS_A::CAPS_A(Core::System& system_) : ServiceFramework{system_, "caps:a"} {
30 // clang-format off 31 // clang-format off
31 static const FunctionInfo functions[] = { 32 static const FunctionInfo functions[] = {
32 {0, nullptr, "GetAlbumFileCount"}, 33 {0, nullptr, "GetAlbumFileCount"},
diff --git a/src/core/hle/service/caps/caps_a.h b/src/core/hle/service/caps/caps_a.h
index cb93aad5b..389cc6dbe 100644
--- a/src/core/hle/service/caps/caps_a.h
+++ b/src/core/hle/service/caps/caps_a.h
@@ -6,6 +6,10 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Kernel { 13namespace Kernel {
10class HLERequestContext; 14class HLERequestContext;
11} 15}
@@ -14,7 +18,7 @@ namespace Service::Capture {
14 18
15class CAPS_A final : public ServiceFramework<CAPS_A> { 19class CAPS_A final : public ServiceFramework<CAPS_A> {
16public: 20public:
17 explicit CAPS_A(); 21 explicit CAPS_A(Core::System& system_);
18 ~CAPS_A() override; 22 ~CAPS_A() override;
19}; 23};
20 24
diff --git a/src/core/hle/service/caps/caps_c.cpp b/src/core/hle/service/caps/caps_c.cpp
index a0ee116fa..45c1c9d30 100644
--- a/src/core/hle/service/caps/caps_c.cpp
+++ b/src/core/hle/service/caps/caps_c.cpp
@@ -10,7 +10,8 @@ namespace Service::Capture {
10 10
11class IAlbumControlSession final : public ServiceFramework<IAlbumControlSession> { 11class IAlbumControlSession final : public ServiceFramework<IAlbumControlSession> {
12public: 12public:
13 explicit IAlbumControlSession() : ServiceFramework{"IAlbumControlSession"} { 13 explicit IAlbumControlSession(Core::System& system_)
14 : ServiceFramework{system_, "IAlbumControlSession"} {
14 // clang-format off 15 // clang-format off
15 static const FunctionInfo functions[] = { 16 static const FunctionInfo functions[] = {
16 {2001, nullptr, "OpenAlbumMovieReadStream"}, 17 {2001, nullptr, "OpenAlbumMovieReadStream"},
@@ -44,7 +45,7 @@ public:
44 } 45 }
45}; 46};
46 47
47CAPS_C::CAPS_C() : ServiceFramework("caps:c") { 48CAPS_C::CAPS_C(Core::System& system_) : ServiceFramework{system_, "caps:c"} {
48 // clang-format off 49 // clang-format off
49 static const FunctionInfo functions[] = { 50 static const FunctionInfo functions[] = {
50 {1, nullptr, "CaptureRawImage"}, 51 {1, nullptr, "CaptureRawImage"},
diff --git a/src/core/hle/service/caps/caps_c.h b/src/core/hle/service/caps/caps_c.h
index b110301d4..c6d1dfdce 100644
--- a/src/core/hle/service/caps/caps_c.h
+++ b/src/core/hle/service/caps/caps_c.h
@@ -6,6 +6,10 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Kernel { 13namespace Kernel {
10class HLERequestContext; 14class HLERequestContext;
11} 15}
@@ -14,7 +18,7 @@ namespace Service::Capture {
14 18
15class CAPS_C final : public ServiceFramework<CAPS_C> { 19class CAPS_C final : public ServiceFramework<CAPS_C> {
16public: 20public:
17 explicit CAPS_C(); 21 explicit CAPS_C(Core::System& system_);
18 ~CAPS_C() override; 22 ~CAPS_C() override;
19 23
20private: 24private:
diff --git a/src/core/hle/service/caps/caps_sc.cpp b/src/core/hle/service/caps/caps_sc.cpp
index 822ee96c8..d91e18e80 100644
--- a/src/core/hle/service/caps/caps_sc.cpp
+++ b/src/core/hle/service/caps/caps_sc.cpp
@@ -6,7 +6,7 @@
6 6
7namespace Service::Capture { 7namespace Service::Capture {
8 8
9CAPS_SC::CAPS_SC() : ServiceFramework("caps:sc") { 9CAPS_SC::CAPS_SC(Core::System& system_) : ServiceFramework{system_, "caps:sc"} {
10 // clang-format off 10 // clang-format off
11 static const FunctionInfo functions[] = { 11 static const FunctionInfo functions[] = {
12 {1, nullptr, "CaptureRawImage"}, 12 {1, nullptr, "CaptureRawImage"},
diff --git a/src/core/hle/service/caps/caps_sc.h b/src/core/hle/service/caps/caps_sc.h
index ac3e929ca..e79a33ee5 100644
--- a/src/core/hle/service/caps/caps_sc.h
+++ b/src/core/hle/service/caps/caps_sc.h
@@ -6,15 +6,15 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Kernel { 9namespace Core {
10class HLERequestContext; 10class System;
11} 11}
12 12
13namespace Service::Capture { 13namespace Service::Capture {
14 14
15class CAPS_SC final : public ServiceFramework<CAPS_SC> { 15class CAPS_SC final : public ServiceFramework<CAPS_SC> {
16public: 16public:
17 explicit CAPS_SC(); 17 explicit CAPS_SC(Core::System& system_);
18 ~CAPS_SC() override; 18 ~CAPS_SC() override;
19}; 19};
20 20
diff --git a/src/core/hle/service/caps/caps_ss.cpp b/src/core/hle/service/caps/caps_ss.cpp
index 24dc716e7..2b5314691 100644
--- a/src/core/hle/service/caps/caps_ss.cpp
+++ b/src/core/hle/service/caps/caps_ss.cpp
@@ -6,7 +6,7 @@
6 6
7namespace Service::Capture { 7namespace Service::Capture {
8 8
9CAPS_SS::CAPS_SS() : ServiceFramework("caps:ss") { 9CAPS_SS::CAPS_SS(Core::System& system_) : ServiceFramework{system_, "caps:ss"} {
10 // clang-format off 10 // clang-format off
11 static const FunctionInfo functions[] = { 11 static const FunctionInfo functions[] = {
12 {201, nullptr, "SaveScreenShot"}, 12 {201, nullptr, "SaveScreenShot"},
diff --git a/src/core/hle/service/caps/caps_ss.h b/src/core/hle/service/caps/caps_ss.h
index 450686e4f..1816f7885 100644
--- a/src/core/hle/service/caps/caps_ss.h
+++ b/src/core/hle/service/caps/caps_ss.h
@@ -6,15 +6,15 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Kernel { 9namespace Core {
10class HLERequestContext; 10class System;
11} 11}
12 12
13namespace Service::Capture { 13namespace Service::Capture {
14 14
15class CAPS_SS final : public ServiceFramework<CAPS_SS> { 15class CAPS_SS final : public ServiceFramework<CAPS_SS> {
16public: 16public:
17 explicit CAPS_SS(); 17 explicit CAPS_SS(Core::System& system_);
18 ~CAPS_SS() override; 18 ~CAPS_SS() override;
19}; 19};
20 20
diff --git a/src/core/hle/service/caps/caps_su.cpp b/src/core/hle/service/caps/caps_su.cpp
index e386470f7..eae39eb7b 100644
--- a/src/core/hle/service/caps/caps_su.cpp
+++ b/src/core/hle/service/caps/caps_su.cpp
@@ -8,7 +8,7 @@
8 8
9namespace Service::Capture { 9namespace Service::Capture {
10 10
11CAPS_SU::CAPS_SU() : ServiceFramework("caps:su") { 11CAPS_SU::CAPS_SU(Core::System& system_) : ServiceFramework{system_, "caps:su"} {
12 // clang-format off 12 // clang-format off
13 static const FunctionInfo functions[] = { 13 static const FunctionInfo functions[] = {
14 {32, &CAPS_SU::SetShimLibraryVersion, "SetShimLibraryVersion"}, 14 {32, &CAPS_SU::SetShimLibraryVersion, "SetShimLibraryVersion"},
diff --git a/src/core/hle/service/caps/caps_su.h b/src/core/hle/service/caps/caps_su.h
index 62c9603a9..b366fdb13 100644
--- a/src/core/hle/service/caps/caps_su.h
+++ b/src/core/hle/service/caps/caps_su.h
@@ -6,6 +6,10 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Kernel { 13namespace Kernel {
10class HLERequestContext; 14class HLERequestContext;
11} 15}
@@ -14,7 +18,7 @@ namespace Service::Capture {
14 18
15class CAPS_SU final : public ServiceFramework<CAPS_SU> { 19class CAPS_SU final : public ServiceFramework<CAPS_SU> {
16public: 20public:
17 explicit CAPS_SU(); 21 explicit CAPS_SU(Core::System& system_);
18 ~CAPS_SU() override; 22 ~CAPS_SU() override;
19 23
20private: 24private:
diff --git a/src/core/hle/service/caps/caps_u.cpp b/src/core/hle/service/caps/caps_u.cpp
index f9479bdb3..842316a2e 100644
--- a/src/core/hle/service/caps/caps_u.cpp
+++ b/src/core/hle/service/caps/caps_u.cpp
@@ -12,8 +12,8 @@ namespace Service::Capture {
12class IAlbumAccessorApplicationSession final 12class IAlbumAccessorApplicationSession final
13 : public ServiceFramework<IAlbumAccessorApplicationSession> { 13 : public ServiceFramework<IAlbumAccessorApplicationSession> {
14public: 14public:
15 explicit IAlbumAccessorApplicationSession() 15 explicit IAlbumAccessorApplicationSession(Core::System& system_)
16 : ServiceFramework{"IAlbumAccessorApplicationSession"} { 16 : ServiceFramework{system_, "IAlbumAccessorApplicationSession"} {
17 // clang-format off 17 // clang-format off
18 static const FunctionInfo functions[] = { 18 static const FunctionInfo functions[] = {
19 {2001, nullptr, "OpenAlbumMovieReadStream"}, 19 {2001, nullptr, "OpenAlbumMovieReadStream"},
@@ -28,7 +28,7 @@ public:
28 } 28 }
29}; 29};
30 30
31CAPS_U::CAPS_U() : ServiceFramework("caps:u") { 31CAPS_U::CAPS_U(Core::System& system_) : ServiceFramework{system_, "caps:u"} {
32 // clang-format off 32 // clang-format off
33 static const FunctionInfo functions[] = { 33 static const FunctionInfo functions[] = {
34 {32, &CAPS_U::SetShimLibraryVersion, "SetShimLibraryVersion"}, 34 {32, &CAPS_U::SetShimLibraryVersion, "SetShimLibraryVersion"},
diff --git a/src/core/hle/service/caps/caps_u.h b/src/core/hle/service/caps/caps_u.h
index 4b80f3156..e7e0d8775 100644
--- a/src/core/hle/service/caps/caps_u.h
+++ b/src/core/hle/service/caps/caps_u.h
@@ -6,6 +6,10 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Kernel { 13namespace Kernel {
10class HLERequestContext; 14class HLERequestContext;
11} 15}
@@ -14,7 +18,7 @@ namespace Service::Capture {
14 18
15class CAPS_U final : public ServiceFramework<CAPS_U> { 19class CAPS_U final : public ServiceFramework<CAPS_U> {
16public: 20public:
17 explicit CAPS_U(); 21 explicit CAPS_U(Core::System& system_);
18 ~CAPS_U() override; 22 ~CAPS_U() override;
19 23
20private: 24private:
diff --git a/src/core/hle/service/erpt/erpt.cpp b/src/core/hle/service/erpt/erpt.cpp
index 4ec8c3093..4924c61c3 100644
--- a/src/core/hle/service/erpt/erpt.cpp
+++ b/src/core/hle/service/erpt/erpt.cpp
@@ -12,7 +12,7 @@ namespace Service::ERPT {
12 12
13class ErrorReportContext final : public ServiceFramework<ErrorReportContext> { 13class ErrorReportContext final : public ServiceFramework<ErrorReportContext> {
14public: 14public:
15 explicit ErrorReportContext() : ServiceFramework{"erpt:c"} { 15 explicit ErrorReportContext(Core::System& system_) : ServiceFramework{system_, "erpt:c"} {
16 // clang-format off 16 // clang-format off
17 static const FunctionInfo functions[] = { 17 static const FunctionInfo functions[] = {
18 {0, nullptr, "SubmitContext"}, 18 {0, nullptr, "SubmitContext"},
@@ -35,7 +35,7 @@ public:
35 35
36class ErrorReportSession final : public ServiceFramework<ErrorReportSession> { 36class ErrorReportSession final : public ServiceFramework<ErrorReportSession> {
37public: 37public:
38 explicit ErrorReportSession() : ServiceFramework{"erpt:r"} { 38 explicit ErrorReportSession(Core::System& system_) : ServiceFramework{system_, "erpt:r"} {
39 // clang-format off 39 // clang-format off
40 static const FunctionInfo functions[] = { 40 static const FunctionInfo functions[] = {
41 {0, nullptr, "OpenReport"}, 41 {0, nullptr, "OpenReport"},
@@ -48,9 +48,9 @@ public:
48 } 48 }
49}; 49};
50 50
51void InstallInterfaces(SM::ServiceManager& sm) { 51void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
52 std::make_shared<ErrorReportContext>()->InstallAsService(sm); 52 std::make_shared<ErrorReportContext>(system)->InstallAsService(sm);
53 std::make_shared<ErrorReportSession>()->InstallAsService(sm); 53 std::make_shared<ErrorReportSession>(system)->InstallAsService(sm);
54} 54}
55 55
56} // namespace Service::ERPT 56} // namespace Service::ERPT
diff --git a/src/core/hle/service/erpt/erpt.h b/src/core/hle/service/erpt/erpt.h
index de439ab6d..8cd5c081f 100644
--- a/src/core/hle/service/erpt/erpt.h
+++ b/src/core/hle/service/erpt/erpt.h
@@ -4,6 +4,10 @@
4 4
5#pragma once 5#pragma once
6 6
7namespace Core {
8class System;
9}
10
7namespace Service::SM { 11namespace Service::SM {
8class ServiceManager; 12class ServiceManager;
9} 13}
@@ -11,6 +15,6 @@ class ServiceManager;
11namespace Service::ERPT { 15namespace Service::ERPT {
12 16
13/// Registers all ERPT services with the specified service manager. 17/// Registers all ERPT services with the specified service manager.
14void InstallInterfaces(SM::ServiceManager& sm); 18void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
15 19
16} // namespace Service::ERPT 20} // namespace Service::ERPT
diff --git a/src/core/hle/service/es/es.cpp b/src/core/hle/service/es/es.cpp
index c2737a365..26d1e3306 100644
--- a/src/core/hle/service/es/es.cpp
+++ b/src/core/hle/service/es/es.cpp
@@ -14,7 +14,7 @@ constexpr ResultCode ERROR_INVALID_RIGHTS_ID{ErrorModule::ETicket, 3};
14 14
15class ETicket final : public ServiceFramework<ETicket> { 15class ETicket final : public ServiceFramework<ETicket> {
16public: 16public:
17 explicit ETicket() : ServiceFramework{"es"} { 17 explicit ETicket(Core::System& system_) : ServiceFramework{system_, "es"} {
18 // clang-format off 18 // clang-format off
19 static const FunctionInfo functions[] = { 19 static const FunctionInfo functions[] = {
20 {1, &ETicket::ImportTicket, "ImportTicket"}, 20 {1, &ETicket::ImportTicket, "ImportTicket"},
@@ -305,8 +305,8 @@ private:
305 Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::Instance(); 305 Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::Instance();
306}; 306};
307 307
308void InstallInterfaces(SM::ServiceManager& service_manager) { 308void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
309 std::make_shared<ETicket>()->InstallAsService(service_manager); 309 std::make_shared<ETicket>(system)->InstallAsService(service_manager);
310} 310}
311 311
312} // namespace Service::ES 312} // namespace Service::ES
diff --git a/src/core/hle/service/es/es.h b/src/core/hle/service/es/es.h
index afe70465b..2a7b27d12 100644
--- a/src/core/hle/service/es/es.h
+++ b/src/core/hle/service/es/es.h
@@ -4,6 +4,10 @@
4 4
5#pragma once 5#pragma once
6 6
7namespace Core {
8class System;
9}
10
7namespace Service::SM { 11namespace Service::SM {
8class ServiceManager; 12class ServiceManager;
9} 13}
@@ -11,6 +15,6 @@ class ServiceManager;
11namespace Service::ES { 15namespace Service::ES {
12 16
13/// Registers all ES services with the specified service manager. 17/// Registers all ES services with the specified service manager.
14void InstallInterfaces(SM::ServiceManager& service_manager); 18void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
15 19
16} // namespace Service::ES 20} // namespace Service::ES
diff --git a/src/core/hle/service/eupld/eupld.cpp b/src/core/hle/service/eupld/eupld.cpp
index 0d6d244f4..2d650b1b7 100644
--- a/src/core/hle/service/eupld/eupld.cpp
+++ b/src/core/hle/service/eupld/eupld.cpp
@@ -12,7 +12,7 @@ namespace Service::EUPLD {
12 12
13class ErrorUploadContext final : public ServiceFramework<ErrorUploadContext> { 13class ErrorUploadContext final : public ServiceFramework<ErrorUploadContext> {
14public: 14public:
15 explicit ErrorUploadContext() : ServiceFramework{"eupld:c"} { 15 explicit ErrorUploadContext(Core::System& system_) : ServiceFramework{system_, "eupld:c"} {
16 // clang-format off 16 // clang-format off
17 static const FunctionInfo functions[] = { 17 static const FunctionInfo functions[] = {
18 {0, nullptr, "SetUrl"}, 18 {0, nullptr, "SetUrl"},
@@ -29,7 +29,7 @@ public:
29 29
30class ErrorUploadRequest final : public ServiceFramework<ErrorUploadRequest> { 30class ErrorUploadRequest final : public ServiceFramework<ErrorUploadRequest> {
31public: 31public:
32 explicit ErrorUploadRequest() : ServiceFramework{"eupld:r"} { 32 explicit ErrorUploadRequest(Core::System& system_) : ServiceFramework{system_, "eupld:r"} {
33 // clang-format off 33 // clang-format off
34 static const FunctionInfo functions[] = { 34 static const FunctionInfo functions[] = {
35 {0, nullptr, "Initialize"}, 35 {0, nullptr, "Initialize"},
@@ -45,9 +45,9 @@ public:
45 } 45 }
46}; 46};
47 47
48void InstallInterfaces(SM::ServiceManager& sm) { 48void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
49 std::make_shared<ErrorUploadContext>()->InstallAsService(sm); 49 std::make_shared<ErrorUploadContext>(system)->InstallAsService(sm);
50 std::make_shared<ErrorUploadRequest>()->InstallAsService(sm); 50 std::make_shared<ErrorUploadRequest>(system)->InstallAsService(sm);
51} 51}
52 52
53} // namespace Service::EUPLD 53} // namespace Service::EUPLD
diff --git a/src/core/hle/service/eupld/eupld.h b/src/core/hle/service/eupld/eupld.h
index 6eef2c15f..539993a9d 100644
--- a/src/core/hle/service/eupld/eupld.h
+++ b/src/core/hle/service/eupld/eupld.h
@@ -4,6 +4,10 @@
4 4
5#pragma once 5#pragma once
6 6
7namespace Core {
8class System;
9}
10
7namespace Service::SM { 11namespace Service::SM {
8class ServiceManager; 12class ServiceManager;
9} 13}
@@ -11,6 +15,6 @@ class ServiceManager;
11namespace Service::EUPLD { 15namespace Service::EUPLD {
12 16
13/// Registers all EUPLD services with the specified service manager. 17/// Registers all EUPLD services with the specified service manager.
14void InstallInterfaces(SM::ServiceManager& sm); 18void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
15 19
16} // namespace Service::EUPLD 20} // namespace Service::EUPLD
diff --git a/src/core/hle/service/fatal/fatal.cpp b/src/core/hle/service/fatal/fatal.cpp
index 2546d7595..9b7672a91 100644
--- a/src/core/hle/service/fatal/fatal.cpp
+++ b/src/core/hle/service/fatal/fatal.cpp
@@ -20,8 +20,9 @@
20 20
21namespace Service::Fatal { 21namespace Service::Fatal {
22 22
23Module::Interface::Interface(std::shared_ptr<Module> module, Core::System& system, const char* name) 23Module::Interface::Interface(std::shared_ptr<Module> module_, Core::System& system_,
24 : ServiceFramework(name), module(std::move(module)), system(system) {} 24 const char* name)
25 : ServiceFramework{system_, name}, module{std::move(module_)} {}
25 26
26Module::Interface::~Interface() = default; 27Module::Interface::~Interface() = default;
27 28
diff --git a/src/core/hle/service/fatal/fatal.h b/src/core/hle/service/fatal/fatal.h
index bd9339dfc..2095bf89f 100644
--- a/src/core/hle/service/fatal/fatal.h
+++ b/src/core/hle/service/fatal/fatal.h
@@ -16,7 +16,8 @@ class Module final {
16public: 16public:
17 class Interface : public ServiceFramework<Interface> { 17 class Interface : public ServiceFramework<Interface> {
18 public: 18 public:
19 explicit Interface(std::shared_ptr<Module> module, Core::System& system, const char* name); 19 explicit Interface(std::shared_ptr<Module> module_, Core::System& system_,
20 const char* name);
20 ~Interface() override; 21 ~Interface() override;
21 22
22 void ThrowFatal(Kernel::HLERequestContext& ctx); 23 void ThrowFatal(Kernel::HLERequestContext& ctx);
@@ -25,7 +26,6 @@ public:
25 26
26 protected: 27 protected:
27 std::shared_ptr<Module> module; 28 std::shared_ptr<Module> module;
28 Core::System& system;
29 }; 29 };
30}; 30};
31 31
diff --git a/src/core/hle/service/fatal/fatal_p.cpp b/src/core/hle/service/fatal/fatal_p.cpp
index 066ccf6b0..8672b85dc 100644
--- a/src/core/hle/service/fatal/fatal_p.cpp
+++ b/src/core/hle/service/fatal/fatal_p.cpp
@@ -6,8 +6,8 @@
6 6
7namespace Service::Fatal { 7namespace Service::Fatal {
8 8
9Fatal_P::Fatal_P(std::shared_ptr<Module> module, Core::System& system) 9Fatal_P::Fatal_P(std::shared_ptr<Module> module_, Core::System& system_)
10 : Module::Interface(std::move(module), system, "fatal:p") {} 10 : Interface(std::move(module_), system_, "fatal:p") {}
11 11
12Fatal_P::~Fatal_P() = default; 12Fatal_P::~Fatal_P() = default;
13 13
diff --git a/src/core/hle/service/fatal/fatal_p.h b/src/core/hle/service/fatal/fatal_p.h
index c6d953cb5..ffa5b7b98 100644
--- a/src/core/hle/service/fatal/fatal_p.h
+++ b/src/core/hle/service/fatal/fatal_p.h
@@ -10,7 +10,7 @@ namespace Service::Fatal {
10 10
11class Fatal_P final : public Module::Interface { 11class Fatal_P final : public Module::Interface {
12public: 12public:
13 explicit Fatal_P(std::shared_ptr<Module> module, Core::System& system); 13 explicit Fatal_P(std::shared_ptr<Module> module_, Core::System& system_);
14 ~Fatal_P() override; 14 ~Fatal_P() override;
15}; 15};
16 16
diff --git a/src/core/hle/service/fatal/fatal_u.cpp b/src/core/hle/service/fatal/fatal_u.cpp
index 8d72ed485..82993938a 100644
--- a/src/core/hle/service/fatal/fatal_u.cpp
+++ b/src/core/hle/service/fatal/fatal_u.cpp
@@ -6,8 +6,8 @@
6 6
7namespace Service::Fatal { 7namespace Service::Fatal {
8 8
9Fatal_U::Fatal_U(std::shared_ptr<Module> module, Core::System& system) 9Fatal_U::Fatal_U(std::shared_ptr<Module> module_, Core::System& system_)
10 : Module::Interface(std::move(module), system, "fatal:u") { 10 : Interface(std::move(module_), system_, "fatal:u") {
11 static const FunctionInfo functions[] = { 11 static const FunctionInfo functions[] = {
12 {0, &Fatal_U::ThrowFatal, "ThrowFatal"}, 12 {0, &Fatal_U::ThrowFatal, "ThrowFatal"},
13 {1, &Fatal_U::ThrowFatalWithPolicy, "ThrowFatalWithPolicy"}, 13 {1, &Fatal_U::ThrowFatalWithPolicy, "ThrowFatalWithPolicy"},
diff --git a/src/core/hle/service/fatal/fatal_u.h b/src/core/hle/service/fatal/fatal_u.h
index 34c5c7f95..0b58c9112 100644
--- a/src/core/hle/service/fatal/fatal_u.h
+++ b/src/core/hle/service/fatal/fatal_u.h
@@ -10,7 +10,7 @@ namespace Service::Fatal {
10 10
11class Fatal_U final : public Module::Interface { 11class Fatal_U final : public Module::Interface {
12public: 12public:
13 explicit Fatal_U(std::shared_ptr<Module> module, Core::System& system); 13 explicit Fatal_U(std::shared_ptr<Module> module_, Core::System& system_);
14 ~Fatal_U() override; 14 ~Fatal_U() override;
15}; 15};
16 16
diff --git a/src/core/hle/service/fgm/fgm.cpp b/src/core/hle/service/fgm/fgm.cpp
index e461274c1..9dc1bc52e 100644
--- a/src/core/hle/service/fgm/fgm.cpp
+++ b/src/core/hle/service/fgm/fgm.cpp
@@ -14,7 +14,7 @@ namespace Service::FGM {
14 14
15class IRequest final : public ServiceFramework<IRequest> { 15class IRequest final : public ServiceFramework<IRequest> {
16public: 16public:
17 explicit IRequest() : ServiceFramework{"IRequest"} { 17 explicit IRequest(Core::System& system_) : ServiceFramework{system_, "IRequest"} {
18 // clang-format off 18 // clang-format off
19 static const FunctionInfo functions[] = { 19 static const FunctionInfo functions[] = {
20 {0, nullptr, "Initialize"}, 20 {0, nullptr, "Initialize"},
@@ -30,7 +30,7 @@ public:
30 30
31class FGM final : public ServiceFramework<FGM> { 31class FGM final : public ServiceFramework<FGM> {
32public: 32public:
33 explicit FGM(const char* name) : ServiceFramework{name} { 33 explicit FGM(Core::System& system_, const char* name) : ServiceFramework{system_, name} {
34 // clang-format off 34 // clang-format off
35 static const FunctionInfo functions[] = { 35 static const FunctionInfo functions[] = {
36 {0, &FGM::Initialize, "Initialize"}, 36 {0, &FGM::Initialize, "Initialize"},
@@ -46,13 +46,13 @@ private:
46 46
47 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 47 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
48 rb.Push(RESULT_SUCCESS); 48 rb.Push(RESULT_SUCCESS);
49 rb.PushIpcInterface<IRequest>(); 49 rb.PushIpcInterface<IRequest>(system);
50 } 50 }
51}; 51};
52 52
53class FGM_DBG final : public ServiceFramework<FGM_DBG> { 53class FGM_DBG final : public ServiceFramework<FGM_DBG> {
54public: 54public:
55 explicit FGM_DBG() : ServiceFramework{"fgm:dbg"} { 55 explicit FGM_DBG(Core::System& system_) : ServiceFramework{system_, "fgm:dbg"} {
56 // clang-format off 56 // clang-format off
57 static const FunctionInfo functions[] = { 57 static const FunctionInfo functions[] = {
58 {0, nullptr, "Initialize"}, 58 {0, nullptr, "Initialize"},
@@ -65,11 +65,11 @@ public:
65 } 65 }
66}; 66};
67 67
68void InstallInterfaces(SM::ServiceManager& sm) { 68void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
69 std::make_shared<FGM>("fgm")->InstallAsService(sm); 69 std::make_shared<FGM>(system, "fgm")->InstallAsService(sm);
70 std::make_shared<FGM>("fgm:0")->InstallAsService(sm); 70 std::make_shared<FGM>(system, "fgm:0")->InstallAsService(sm);
71 std::make_shared<FGM>("fgm:9")->InstallAsService(sm); 71 std::make_shared<FGM>(system, "fgm:9")->InstallAsService(sm);
72 std::make_shared<FGM_DBG>()->InstallAsService(sm); 72 std::make_shared<FGM_DBG>(system)->InstallAsService(sm);
73} 73}
74 74
75} // namespace Service::FGM 75} // namespace Service::FGM
diff --git a/src/core/hle/service/fgm/fgm.h b/src/core/hle/service/fgm/fgm.h
index e59691264..75978f2ed 100644
--- a/src/core/hle/service/fgm/fgm.h
+++ b/src/core/hle/service/fgm/fgm.h
@@ -4,12 +4,16 @@
4 4
5#pragma once 5#pragma once
6 6
7namespace Core {
8class System;
9}
10
7namespace Service::SM { 11namespace Service::SM {
8class ServiceManager; 12class ServiceManager;
9} 13}
10 14
11namespace Service::FGM { 15namespace Service::FGM {
12 16
13void InstallInterfaces(SM::ServiceManager& sm); 17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
14 18
15} // namespace Service::FGM 19} // namespace Service::FGM
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp
index 2e53cae5b..ca93062cf 100644
--- a/src/core/hle/service/filesystem/filesystem.cpp
+++ b/src/core/hle/service/filesystem/filesystem.cpp
@@ -717,7 +717,8 @@ void FileSystemController::CreateFactories(FileSys::VfsFilesystem& vfs, bool ove
717 } 717 }
718 718
719 if (save_data_factory == nullptr) { 719 if (save_data_factory == nullptr) {
720 save_data_factory = std::make_unique<FileSys::SaveDataFactory>(std::move(nand_directory)); 720 save_data_factory =
721 std::make_unique<FileSys::SaveDataFactory>(system, std::move(nand_directory));
721 } 722 }
722 723
723 if (sdmc_factory == nullptr) { 724 if (sdmc_factory == nullptr) {
@@ -728,11 +729,9 @@ void FileSystemController::CreateFactories(FileSys::VfsFilesystem& vfs, bool ove
728} 729}
729 730
730void InstallInterfaces(Core::System& system) { 731void InstallInterfaces(Core::System& system) {
731 std::make_shared<FSP_LDR>()->InstallAsService(system.ServiceManager()); 732 std::make_shared<FSP_LDR>(system)->InstallAsService(system.ServiceManager());
732 std::make_shared<FSP_PR>()->InstallAsService(system.ServiceManager()); 733 std::make_shared<FSP_PR>(system)->InstallAsService(system.ServiceManager());
733 std::make_shared<FSP_SRV>(system.GetFileSystemController(), system.GetContentProvider(), 734 std::make_shared<FSP_SRV>(system)->InstallAsService(system.ServiceManager());
734 system.GetReporter())
735 ->InstallAsService(system.ServiceManager());
736} 735}
737 736
738} // namespace Service::FileSystem 737} // namespace Service::FileSystem
diff --git a/src/core/hle/service/filesystem/fsp_ldr.cpp b/src/core/hle/service/filesystem/fsp_ldr.cpp
index fb487d5bc..1f6c17ba5 100644
--- a/src/core/hle/service/filesystem/fsp_ldr.cpp
+++ b/src/core/hle/service/filesystem/fsp_ldr.cpp
@@ -7,7 +7,7 @@
7 7
8namespace Service::FileSystem { 8namespace Service::FileSystem {
9 9
10FSP_LDR::FSP_LDR() : ServiceFramework{"fsp:ldr"} { 10FSP_LDR::FSP_LDR(Core::System& system_) : ServiceFramework{system_, "fsp:ldr"} {
11 // clang-format off 11 // clang-format off
12 static const FunctionInfo functions[] = { 12 static const FunctionInfo functions[] = {
13 {0, nullptr, "OpenCodeFileSystem"}, 13 {0, nullptr, "OpenCodeFileSystem"},
diff --git a/src/core/hle/service/filesystem/fsp_ldr.h b/src/core/hle/service/filesystem/fsp_ldr.h
index 8210b7729..d6432a0e1 100644
--- a/src/core/hle/service/filesystem/fsp_ldr.h
+++ b/src/core/hle/service/filesystem/fsp_ldr.h
@@ -6,11 +6,15 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::FileSystem { 13namespace Service::FileSystem {
10 14
11class FSP_LDR final : public ServiceFramework<FSP_LDR> { 15class FSP_LDR final : public ServiceFramework<FSP_LDR> {
12public: 16public:
13 explicit FSP_LDR(); 17 explicit FSP_LDR(Core::System& system_);
14 ~FSP_LDR() override; 18 ~FSP_LDR() override;
15}; 19};
16 20
diff --git a/src/core/hle/service/filesystem/fsp_pr.cpp b/src/core/hle/service/filesystem/fsp_pr.cpp
index 378201610..00e4d1662 100644
--- a/src/core/hle/service/filesystem/fsp_pr.cpp
+++ b/src/core/hle/service/filesystem/fsp_pr.cpp
@@ -7,7 +7,7 @@
7 7
8namespace Service::FileSystem { 8namespace Service::FileSystem {
9 9
10FSP_PR::FSP_PR() : ServiceFramework{"fsp:pr"} { 10FSP_PR::FSP_PR(Core::System& system_) : ServiceFramework{system_, "fsp:pr"} {
11 // clang-format off 11 // clang-format off
12 static const FunctionInfo functions[] = { 12 static const FunctionInfo functions[] = {
13 {0, nullptr, "RegisterProgram"}, 13 {0, nullptr, "RegisterProgram"},
diff --git a/src/core/hle/service/filesystem/fsp_pr.h b/src/core/hle/service/filesystem/fsp_pr.h
index 556ae5ce9..9e622518c 100644
--- a/src/core/hle/service/filesystem/fsp_pr.h
+++ b/src/core/hle/service/filesystem/fsp_pr.h
@@ -6,11 +6,15 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::FileSystem { 13namespace Service::FileSystem {
10 14
11class FSP_PR final : public ServiceFramework<FSP_PR> { 15class FSP_PR final : public ServiceFramework<FSP_PR> {
12public: 16public:
13 explicit FSP_PR(); 17 explicit FSP_PR(Core::System& system_);
14 ~FSP_PR() override; 18 ~FSP_PR() override;
15}; 19};
16 20
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp
index 031c6dbf6..b3480494c 100644
--- a/src/core/hle/service/filesystem/fsp_srv.cpp
+++ b/src/core/hle/service/filesystem/fsp_srv.cpp
@@ -14,6 +14,7 @@
14#include "common/hex_util.h" 14#include "common/hex_util.h"
15#include "common/logging/log.h" 15#include "common/logging/log.h"
16#include "common/string_util.h" 16#include "common/string_util.h"
17#include "core/core.h"
17#include "core/file_sys/directory.h" 18#include "core/file_sys/directory.h"
18#include "core/file_sys/errors.h" 19#include "core/file_sys/errors.h"
19#include "core/file_sys/mode.h" 20#include "core/file_sys/mode.h"
@@ -56,8 +57,8 @@ enum class FileSystemType : u8 {
56 57
57class IStorage final : public ServiceFramework<IStorage> { 58class IStorage final : public ServiceFramework<IStorage> {
58public: 59public:
59 explicit IStorage(FileSys::VirtualFile backend_) 60 explicit IStorage(Core::System& system_, FileSys::VirtualFile backend_)
60 : ServiceFramework("IStorage"), backend(std::move(backend_)) { 61 : ServiceFramework{system_, "IStorage"}, backend(std::move(backend_)) {
61 static const FunctionInfo functions[] = { 62 static const FunctionInfo functions[] = {
62 {0, &IStorage::Read, "Read"}, 63 {0, &IStorage::Read, "Read"},
63 {1, nullptr, "Write"}, 64 {1, nullptr, "Write"},
@@ -114,8 +115,8 @@ private:
114 115
115class IFile final : public ServiceFramework<IFile> { 116class IFile final : public ServiceFramework<IFile> {
116public: 117public:
117 explicit IFile(FileSys::VirtualFile backend_) 118 explicit IFile(Core::System& system_, FileSys::VirtualFile backend_)
118 : ServiceFramework("IFile"), backend(std::move(backend_)) { 119 : ServiceFramework{system_, "IFile"}, backend(std::move(backend_)) {
119 static const FunctionInfo functions[] = { 120 static const FunctionInfo functions[] = {
120 {0, &IFile::Read, "Read"}, {1, &IFile::Write, "Write"}, 121 {0, &IFile::Read, "Read"}, {1, &IFile::Write, "Write"},
121 {2, &IFile::Flush, "Flush"}, {3, &IFile::SetSize, "SetSize"}, 122 {2, &IFile::Flush, "Flush"}, {3, &IFile::SetSize, "SetSize"},
@@ -246,8 +247,8 @@ static void BuildEntryIndex(std::vector<FileSys::Entry>& entries, const std::vec
246 247
247class IDirectory final : public ServiceFramework<IDirectory> { 248class IDirectory final : public ServiceFramework<IDirectory> {
248public: 249public:
249 explicit IDirectory(FileSys::VirtualDir backend_) 250 explicit IDirectory(Core::System& system_, FileSys::VirtualDir backend_)
250 : ServiceFramework("IDirectory"), backend(std::move(backend_)) { 251 : ServiceFramework{system_, "IDirectory"}, backend(std::move(backend_)) {
251 static const FunctionInfo functions[] = { 252 static const FunctionInfo functions[] = {
252 {0, &IDirectory::Read, "Read"}, 253 {0, &IDirectory::Read, "Read"},
253 {1, &IDirectory::GetEntryCount, "GetEntryCount"}, 254 {1, &IDirectory::GetEntryCount, "GetEntryCount"},
@@ -302,8 +303,9 @@ private:
302 303
303class IFileSystem final : public ServiceFramework<IFileSystem> { 304class IFileSystem final : public ServiceFramework<IFileSystem> {
304public: 305public:
305 explicit IFileSystem(FileSys::VirtualDir backend, SizeGetter size) 306 explicit IFileSystem(Core::System& system_, FileSys::VirtualDir backend_, SizeGetter size_)
306 : ServiceFramework("IFileSystem"), backend(std::move(backend)), size(std::move(size)) { 307 : ServiceFramework{system_, "IFileSystem"}, backend{std::move(backend_)}, size{std::move(
308 size_)} {
307 static const FunctionInfo functions[] = { 309 static const FunctionInfo functions[] = {
308 {0, &IFileSystem::CreateFile, "CreateFile"}, 310 {0, &IFileSystem::CreateFile, "CreateFile"},
309 {1, &IFileSystem::DeleteFile, "DeleteFile"}, 311 {1, &IFileSystem::DeleteFile, "DeleteFile"},
@@ -420,7 +422,7 @@ public:
420 return; 422 return;
421 } 423 }
422 424
423 auto file = std::make_shared<IFile>(result.Unwrap()); 425 auto file = std::make_shared<IFile>(system, result.Unwrap());
424 426
425 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 427 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
426 rb.Push(RESULT_SUCCESS); 428 rb.Push(RESULT_SUCCESS);
@@ -445,7 +447,7 @@ public:
445 return; 447 return;
446 } 448 }
447 449
448 auto directory = std::make_shared<IDirectory>(result.Unwrap()); 450 auto directory = std::make_shared<IDirectory>(system, result.Unwrap());
449 451
450 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 452 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
451 rb.Push(RESULT_SUCCESS); 453 rb.Push(RESULT_SUCCESS);
@@ -500,8 +502,9 @@ private:
500 502
501class ISaveDataInfoReader final : public ServiceFramework<ISaveDataInfoReader> { 503class ISaveDataInfoReader final : public ServiceFramework<ISaveDataInfoReader> {
502public: 504public:
503 explicit ISaveDataInfoReader(FileSys::SaveDataSpaceId space, FileSystemController& fsc) 505 explicit ISaveDataInfoReader(Core::System& system_, FileSys::SaveDataSpaceId space,
504 : ServiceFramework("ISaveDataInfoReader"), fsc(fsc) { 506 FileSystemController& fsc_)
507 : ServiceFramework{system_, "ISaveDataInfoReader"}, fsc{fsc_} {
505 static const FunctionInfo functions[] = { 508 static const FunctionInfo functions[] = {
506 {0, &ISaveDataInfoReader::ReadSaveDataInfo, "ReadSaveDataInfo"}, 509 {0, &ISaveDataInfoReader::ReadSaveDataInfo, "ReadSaveDataInfo"},
507 }; 510 };
@@ -650,10 +653,9 @@ private:
650 u64 next_entry_index = 0; 653 u64 next_entry_index = 0;
651}; 654};
652 655
653FSP_SRV::FSP_SRV(FileSystemController& fsc_, const FileSys::ContentProvider& content_provider_, 656FSP_SRV::FSP_SRV(Core::System& system_)
654 const Core::Reporter& reporter_) 657 : ServiceFramework{system_, "fsp-srv"}, fsc{system.GetFileSystemController()},
655 : ServiceFramework("fsp-srv"), fsc(fsc_), content_provider{content_provider_}, 658 content_provider{system.GetContentProvider()}, reporter{system.GetReporter()} {
656 reporter(reporter_) {
657 // clang-format off 659 // clang-format off
658 static const FunctionInfo functions[] = { 660 static const FunctionInfo functions[] = {
659 {0, nullptr, "OpenFileSystem"}, 661 {0, nullptr, "OpenFileSystem"},
@@ -803,8 +805,9 @@ void FSP_SRV::OpenFileSystemWithPatch(Kernel::HLERequestContext& ctx) {
803void FSP_SRV::OpenSdCardFileSystem(Kernel::HLERequestContext& ctx) { 805void FSP_SRV::OpenSdCardFileSystem(Kernel::HLERequestContext& ctx) {
804 LOG_DEBUG(Service_FS, "called"); 806 LOG_DEBUG(Service_FS, "called");
805 807
806 auto filesystem = std::make_shared<IFileSystem>( 808 auto filesystem =
807 fsc.OpenSDMC().Unwrap(), SizeGetter::FromStorageId(fsc, FileSys::StorageId::SdCard)); 809 std::make_shared<IFileSystem>(system, fsc.OpenSDMC().Unwrap(),
810 SizeGetter::FromStorageId(fsc, FileSys::StorageId::SdCard));
808 811
809 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 812 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
810 rb.Push(RESULT_SUCCESS); 813 rb.Push(RESULT_SUCCESS);
@@ -864,8 +867,8 @@ void FSP_SRV::OpenSaveDataFileSystem(Kernel::HLERequestContext& ctx) {
864 UNREACHABLE(); 867 UNREACHABLE();
865 } 868 }
866 869
867 auto filesystem = 870 auto filesystem = std::make_shared<IFileSystem>(system, std::move(dir.Unwrap()),
868 std::make_shared<IFileSystem>(std::move(dir.Unwrap()), SizeGetter::FromStorageId(fsc, id)); 871 SizeGetter::FromStorageId(fsc, id));
869 872
870 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 873 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
871 rb.Push(RESULT_SUCCESS); 874 rb.Push(RESULT_SUCCESS);
@@ -884,7 +887,8 @@ void FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext&
884 887
885 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 888 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
886 rb.Push(RESULT_SUCCESS); 889 rb.Push(RESULT_SUCCESS);
887 rb.PushIpcInterface<ISaveDataInfoReader>(std::make_shared<ISaveDataInfoReader>(space, fsc)); 890 rb.PushIpcInterface<ISaveDataInfoReader>(
891 std::make_shared<ISaveDataInfoReader>(system, space, fsc));
888} 892}
889 893
890void FSP_SRV::WriteSaveDataFileSystemExtraDataBySaveDataAttribute(Kernel::HLERequestContext& ctx) { 894void FSP_SRV::WriteSaveDataFileSystemExtraDataBySaveDataAttribute(Kernel::HLERequestContext& ctx) {
@@ -933,7 +937,7 @@ void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) {
933 return; 937 return;
934 } 938 }
935 939
936 auto storage = std::make_shared<IStorage>(std::move(romfs.Unwrap())); 940 auto storage = std::make_shared<IStorage>(system, std::move(romfs.Unwrap()));
937 941
938 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 942 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
939 rb.Push(RESULT_SUCCESS); 943 rb.Push(RESULT_SUCCESS);
@@ -957,7 +961,7 @@ void FSP_SRV::OpenDataStorageByDataId(Kernel::HLERequestContext& ctx) {
957 if (archive != nullptr) { 961 if (archive != nullptr) {
958 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 962 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
959 rb.Push(RESULT_SUCCESS); 963 rb.Push(RESULT_SUCCESS);
960 rb.PushIpcInterface(std::make_shared<IStorage>(archive)); 964 rb.PushIpcInterface(std::make_shared<IStorage>(system, archive));
961 return; 965 return;
962 } 966 }
963 967
@@ -973,7 +977,7 @@ void FSP_SRV::OpenDataStorageByDataId(Kernel::HLERequestContext& ctx) {
973 const FileSys::PatchManager pm{title_id, fsc, content_provider}; 977 const FileSys::PatchManager pm{title_id, fsc, content_provider};
974 978
975 auto storage = std::make_shared<IStorage>( 979 auto storage = std::make_shared<IStorage>(
976 pm.PatchRomFS(std::move(data.Unwrap()), 0, FileSys::ContentRecordType::Data)); 980 system, pm.PatchRomFS(std::move(data.Unwrap()), 0, FileSys::ContentRecordType::Data));
977 981
978 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 982 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
979 rb.Push(RESULT_SUCCESS); 983 rb.Push(RESULT_SUCCESS);
@@ -1035,7 +1039,8 @@ void FSP_SRV::GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx) {
1035 1039
1036class IMultiCommitManager final : public ServiceFramework<IMultiCommitManager> { 1040class IMultiCommitManager final : public ServiceFramework<IMultiCommitManager> {
1037public: 1041public:
1038 explicit IMultiCommitManager() : ServiceFramework("IMultiCommitManager") { 1042 explicit IMultiCommitManager(Core::System& system_)
1043 : ServiceFramework{system_, "IMultiCommitManager"} {
1039 static const FunctionInfo functions[] = { 1044 static const FunctionInfo functions[] = {
1040 {1, &IMultiCommitManager::Add, "Add"}, 1045 {1, &IMultiCommitManager::Add, "Add"},
1041 {2, &IMultiCommitManager::Commit, "Commit"}, 1046 {2, &IMultiCommitManager::Commit, "Commit"},
@@ -1066,7 +1071,7 @@ void FSP_SRV::OpenMultiCommitManager(Kernel::HLERequestContext& ctx) {
1066 1071
1067 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 1072 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
1068 rb.Push(RESULT_SUCCESS); 1073 rb.Push(RESULT_SUCCESS);
1069 rb.PushIpcInterface<IMultiCommitManager>(std::make_shared<IMultiCommitManager>()); 1074 rb.PushIpcInterface<IMultiCommitManager>(std::make_shared<IMultiCommitManager>(system));
1070} 1075}
1071 1076
1072} // namespace Service::FileSystem 1077} // namespace Service::FileSystem
diff --git a/src/core/hle/service/filesystem/fsp_srv.h b/src/core/hle/service/filesystem/fsp_srv.h
index 6c7239e6a..472286d6e 100644
--- a/src/core/hle/service/filesystem/fsp_srv.h
+++ b/src/core/hle/service/filesystem/fsp_srv.h
@@ -33,8 +33,7 @@ enum class LogMode : u32 {
33 33
34class FSP_SRV final : public ServiceFramework<FSP_SRV> { 34class FSP_SRV final : public ServiceFramework<FSP_SRV> {
35public: 35public:
36 explicit FSP_SRV(FileSystemController& fsc_, const FileSys::ContentProvider& content_provider_, 36 explicit FSP_SRV(Core::System& system_);
37 const Core::Reporter& reporter_);
38 ~FSP_SRV() override; 37 ~FSP_SRV() override;
39 38
40private: 39private:
diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp
index ebb323da2..40a289594 100644
--- a/src/core/hle/service/friend/friend.cpp
+++ b/src/core/hle/service/friend/friend.cpp
@@ -17,7 +17,7 @@ namespace Service::Friend {
17 17
18class IFriendService final : public ServiceFramework<IFriendService> { 18class IFriendService final : public ServiceFramework<IFriendService> {
19public: 19public:
20 IFriendService() : ServiceFramework("IFriendService") { 20 explicit IFriendService(Core::System& system_) : ServiceFramework{system_, "IFriendService"} {
21 // clang-format off 21 // clang-format off
22 static const FunctionInfo functions[] = { 22 static const FunctionInfo functions[] = {
23 {0, nullptr, "GetCompletionEvent"}, 23 {0, nullptr, "GetCompletionEvent"},
@@ -171,8 +171,8 @@ private:
171 171
172class INotificationService final : public ServiceFramework<INotificationService> { 172class INotificationService final : public ServiceFramework<INotificationService> {
173public: 173public:
174 INotificationService(Common::UUID uuid, Core::System& system) 174 explicit INotificationService(Common::UUID uuid_, Core::System& system_)
175 : ServiceFramework("INotificationService"), uuid(uuid) { 175 : ServiceFramework{system_, "INotificationService"}, uuid{uuid_} {
176 // clang-format off 176 // clang-format off
177 static const FunctionInfo functions[] = { 177 static const FunctionInfo functions[] = {
178 {0, &INotificationService::GetEvent, "GetEvent"}, 178 {0, &INotificationService::GetEvent, "GetEvent"},
@@ -267,7 +267,7 @@ private:
267void Module::Interface::CreateFriendService(Kernel::HLERequestContext& ctx) { 267void Module::Interface::CreateFriendService(Kernel::HLERequestContext& ctx) {
268 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 268 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
269 rb.Push(RESULT_SUCCESS); 269 rb.Push(RESULT_SUCCESS);
270 rb.PushIpcInterface<IFriendService>(); 270 rb.PushIpcInterface<IFriendService>(system);
271 LOG_DEBUG(Service_ACC, "called"); 271 LOG_DEBUG(Service_ACC, "called");
272} 272}
273 273
@@ -282,8 +282,9 @@ void Module::Interface::CreateNotificationService(Kernel::HLERequestContext& ctx
282 rb.PushIpcInterface<INotificationService>(uuid, system); 282 rb.PushIpcInterface<INotificationService>(uuid, system);
283} 283}
284 284
285Module::Interface::Interface(std::shared_ptr<Module> module, Core::System& system, const char* name) 285Module::Interface::Interface(std::shared_ptr<Module> module_, Core::System& system_,
286 : ServiceFramework(name), module(std::move(module)), system(system) {} 286 const char* name)
287 : ServiceFramework{system_, name}, module{std::move(module_)} {}
287 288
288Module::Interface::~Interface() = default; 289Module::Interface::~Interface() = default;
289 290
diff --git a/src/core/hle/service/friend/friend.h b/src/core/hle/service/friend/friend.h
index 24f3fc969..8be3321db 100644
--- a/src/core/hle/service/friend/friend.h
+++ b/src/core/hle/service/friend/friend.h
@@ -16,7 +16,8 @@ class Module final {
16public: 16public:
17 class Interface : public ServiceFramework<Interface> { 17 class Interface : public ServiceFramework<Interface> {
18 public: 18 public:
19 explicit Interface(std::shared_ptr<Module> module, Core::System& system, const char* name); 19 explicit Interface(std::shared_ptr<Module> module_, Core::System& system_,
20 const char* name);
20 ~Interface() override; 21 ~Interface() override;
21 22
22 void CreateFriendService(Kernel::HLERequestContext& ctx); 23 void CreateFriendService(Kernel::HLERequestContext& ctx);
@@ -24,7 +25,6 @@ public:
24 25
25 protected: 26 protected:
26 std::shared_ptr<Module> module; 27 std::shared_ptr<Module> module;
27 Core::System& system;
28 }; 28 };
29}; 29};
30 30
diff --git a/src/core/hle/service/friend/interface.cpp b/src/core/hle/service/friend/interface.cpp
index 58155f652..7368ccec2 100644
--- a/src/core/hle/service/friend/interface.cpp
+++ b/src/core/hle/service/friend/interface.cpp
@@ -6,8 +6,8 @@
6 6
7namespace Service::Friend { 7namespace Service::Friend {
8 8
9Friend::Friend(std::shared_ptr<Module> module, Core::System& system, const char* name) 9Friend::Friend(std::shared_ptr<Module> module_, Core::System& system_, const char* name)
10 : Interface(std::move(module), system, name) { 10 : Interface(std::move(module_), system_, name) {
11 static const FunctionInfo functions[] = { 11 static const FunctionInfo functions[] = {
12 {0, &Friend::CreateFriendService, "CreateFriendService"}, 12 {0, &Friend::CreateFriendService, "CreateFriendService"},
13 {1, &Friend::CreateNotificationService, "CreateNotificationService"}, 13 {1, &Friend::CreateNotificationService, "CreateNotificationService"},
diff --git a/src/core/hle/service/friend/interface.h b/src/core/hle/service/friend/interface.h
index 465a35770..43d914b32 100644
--- a/src/core/hle/service/friend/interface.h
+++ b/src/core/hle/service/friend/interface.h
@@ -10,7 +10,7 @@ namespace Service::Friend {
10 10
11class Friend final : public Module::Interface { 11class Friend final : public Module::Interface {
12public: 12public:
13 explicit Friend(std::shared_ptr<Module> module, Core::System& system, const char* name); 13 explicit Friend(std::shared_ptr<Module> module_, Core::System& system_, const char* name);
14 ~Friend() override; 14 ~Friend() override;
15}; 15};
16 16
diff --git a/src/core/hle/service/glue/arp.cpp b/src/core/hle/service/glue/arp.cpp
index c6252ff89..fc77e7286 100644
--- a/src/core/hle/service/glue/arp.cpp
+++ b/src/core/hle/service/glue/arp.cpp
@@ -33,8 +33,8 @@ std::optional<u64> GetTitleIDForProcessID(const Core::System& system, u64 proces
33} 33}
34} // Anonymous namespace 34} // Anonymous namespace
35 35
36ARP_R::ARP_R(const Core::System& system, const ARPManager& manager) 36ARP_R::ARP_R(Core::System& system_, const ARPManager& manager_)
37 : ServiceFramework{"arp:r"}, system(system), manager(manager) { 37 : ServiceFramework{system_, "arp:r"}, manager{manager_} {
38 // clang-format off 38 // clang-format off
39 static const FunctionInfo functions[] = { 39 static const FunctionInfo functions[] = {
40 {0, &ARP_R::GetApplicationLaunchProperty, "GetApplicationLaunchProperty"}, 40 {0, &ARP_R::GetApplicationLaunchProperty, "GetApplicationLaunchProperty"},
@@ -152,8 +152,9 @@ class IRegistrar final : public ServiceFramework<IRegistrar> {
152 152
153public: 153public:
154 explicit IRegistrar( 154 explicit IRegistrar(
155 Core::System& system_,
155 std::function<ResultCode(u64, ApplicationLaunchProperty, std::vector<u8>)> issuer) 156 std::function<ResultCode(u64, ApplicationLaunchProperty, std::vector<u8>)> issuer)
156 : ServiceFramework{"IRegistrar"}, issue_process_id(std::move(issuer)) { 157 : ServiceFramework{system_, "IRegistrar"}, issue_process_id{std::move(issuer)} {
157 // clang-format off 158 // clang-format off
158 static const FunctionInfo functions[] = { 159 static const FunctionInfo functions[] = {
159 {0, &IRegistrar::Issue, "Issue"}, 160 {0, &IRegistrar::Issue, "Issue"},
@@ -237,8 +238,8 @@ private:
237 std::vector<u8> control; 238 std::vector<u8> control;
238}; 239};
239 240
240ARP_W::ARP_W(const Core::System& system, ARPManager& manager) 241ARP_W::ARP_W(Core::System& system_, ARPManager& manager_)
241 : ServiceFramework{"arp:w"}, system(system), manager(manager) { 242 : ServiceFramework{system_, "arp:w"}, manager{manager_} {
242 // clang-format off 243 // clang-format off
243 static const FunctionInfo functions[] = { 244 static const FunctionInfo functions[] = {
244 {0, &ARP_W::AcquireRegistrar, "AcquireRegistrar"}, 245 {0, &ARP_W::AcquireRegistrar, "AcquireRegistrar"},
@@ -255,7 +256,7 @@ void ARP_W::AcquireRegistrar(Kernel::HLERequestContext& ctx) {
255 LOG_DEBUG(Service_ARP, "called"); 256 LOG_DEBUG(Service_ARP, "called");
256 257
257 registrar = std::make_shared<IRegistrar>( 258 registrar = std::make_shared<IRegistrar>(
258 [this](u64 process_id, ApplicationLaunchProperty launch, std::vector<u8> control) { 259 system, [this](u64 process_id, ApplicationLaunchProperty launch, std::vector<u8> control) {
259 const auto res = GetTitleIDForProcessID(system, process_id); 260 const auto res = GetTitleIDForProcessID(system, process_id);
260 if (!res.has_value()) { 261 if (!res.has_value()) {
261 return ERR_NOT_REGISTERED; 262 return ERR_NOT_REGISTERED;
diff --git a/src/core/hle/service/glue/arp.h b/src/core/hle/service/glue/arp.h
index d5f8a7e7a..34b412e26 100644
--- a/src/core/hle/service/glue/arp.h
+++ b/src/core/hle/service/glue/arp.h
@@ -13,7 +13,7 @@ class IRegistrar;
13 13
14class ARP_R final : public ServiceFramework<ARP_R> { 14class ARP_R final : public ServiceFramework<ARP_R> {
15public: 15public:
16 explicit ARP_R(const Core::System& system, const ARPManager& manager); 16 explicit ARP_R(Core::System& system_, const ARPManager& manager_);
17 ~ARP_R() override; 17 ~ARP_R() override;
18 18
19private: 19private:
@@ -22,20 +22,18 @@ private:
22 void GetApplicationControlProperty(Kernel::HLERequestContext& ctx); 22 void GetApplicationControlProperty(Kernel::HLERequestContext& ctx);
23 void GetApplicationControlPropertyWithApplicationId(Kernel::HLERequestContext& ctx); 23 void GetApplicationControlPropertyWithApplicationId(Kernel::HLERequestContext& ctx);
24 24
25 const Core::System& system;
26 const ARPManager& manager; 25 const ARPManager& manager;
27}; 26};
28 27
29class ARP_W final : public ServiceFramework<ARP_W> { 28class ARP_W final : public ServiceFramework<ARP_W> {
30public: 29public:
31 explicit ARP_W(const Core::System& system, ARPManager& manager); 30 explicit ARP_W(Core::System& system_, ARPManager& manager_);
32 ~ARP_W() override; 31 ~ARP_W() override;
33 32
34private: 33private:
35 void AcquireRegistrar(Kernel::HLERequestContext& ctx); 34 void AcquireRegistrar(Kernel::HLERequestContext& ctx);
36 void DeleteProperties(Kernel::HLERequestContext& ctx); 35 void DeleteProperties(Kernel::HLERequestContext& ctx);
37 36
38 const Core::System& system;
39 ARPManager& manager; 37 ARPManager& manager;
40 std::shared_ptr<IRegistrar> registrar; 38 std::shared_ptr<IRegistrar> registrar;
41}; 39};
diff --git a/src/core/hle/service/glue/bgtc.cpp b/src/core/hle/service/glue/bgtc.cpp
index cd89d088f..a478b68e1 100644
--- a/src/core/hle/service/glue/bgtc.cpp
+++ b/src/core/hle/service/glue/bgtc.cpp
@@ -6,7 +6,7 @@
6 6
7namespace Service::Glue { 7namespace Service::Glue {
8 8
9BGTC_T::BGTC_T() : ServiceFramework{"bgtc:t"} { 9BGTC_T::BGTC_T(Core::System& system_) : ServiceFramework{system_, "bgtc:t"} {
10 // clang-format off 10 // clang-format off
11 static const FunctionInfo functions[] = { 11 static const FunctionInfo functions[] = {
12 {1, nullptr, "NotifyTaskStarting"}, 12 {1, nullptr, "NotifyTaskStarting"},
@@ -31,7 +31,7 @@ BGTC_T::BGTC_T() : ServiceFramework{"bgtc:t"} {
31 31
32BGTC_T::~BGTC_T() = default; 32BGTC_T::~BGTC_T() = default;
33 33
34BGTC_SC::BGTC_SC() : ServiceFramework{"bgtc:sc"} { 34BGTC_SC::BGTC_SC(Core::System& system_) : ServiceFramework{system_, "bgtc:sc"} {
35 // clang-format off 35 // clang-format off
36 static const FunctionInfo functions[] = { 36 static const FunctionInfo functions[] = {
37 {1, nullptr, "GetState"}, 37 {1, nullptr, "GetState"},
diff --git a/src/core/hle/service/glue/bgtc.h b/src/core/hle/service/glue/bgtc.h
index 81844f03e..906116ba6 100644
--- a/src/core/hle/service/glue/bgtc.h
+++ b/src/core/hle/service/glue/bgtc.h
@@ -6,17 +6,21 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::Glue { 13namespace Service::Glue {
10 14
11class BGTC_T final : public ServiceFramework<BGTC_T> { 15class BGTC_T final : public ServiceFramework<BGTC_T> {
12public: 16public:
13 BGTC_T(); 17 explicit BGTC_T(Core::System& system_);
14 ~BGTC_T() override; 18 ~BGTC_T() override;
15}; 19};
16 20
17class BGTC_SC final : public ServiceFramework<BGTC_SC> { 21class BGTC_SC final : public ServiceFramework<BGTC_SC> {
18public: 22public:
19 BGTC_SC(); 23 explicit BGTC_SC(Core::System& system_);
20 ~BGTC_SC() override; 24 ~BGTC_SC() override;
21}; 25};
22 26
diff --git a/src/core/hle/service/glue/glue.cpp b/src/core/hle/service/glue/glue.cpp
index c728e815c..4eafbe5fa 100644
--- a/src/core/hle/service/glue/glue.cpp
+++ b/src/core/hle/service/glue/glue.cpp
@@ -18,8 +18,8 @@ void InstallInterfaces(Core::System& system) {
18 ->InstallAsService(system.ServiceManager()); 18 ->InstallAsService(system.ServiceManager());
19 19
20 // BackGround Task Controller 20 // BackGround Task Controller
21 std::make_shared<BGTC_T>()->InstallAsService(system.ServiceManager()); 21 std::make_shared<BGTC_T>(system)->InstallAsService(system.ServiceManager());
22 std::make_shared<BGTC_SC>()->InstallAsService(system.ServiceManager()); 22 std::make_shared<BGTC_SC>(system)->InstallAsService(system.ServiceManager());
23} 23}
24 24
25} // namespace Service::Glue 25} // namespace Service::Glue
diff --git a/src/core/hle/service/grc/grc.cpp b/src/core/hle/service/grc/grc.cpp
index 401e0b208..a502ab47f 100644
--- a/src/core/hle/service/grc/grc.cpp
+++ b/src/core/hle/service/grc/grc.cpp
@@ -12,7 +12,7 @@ namespace Service::GRC {
12 12
13class GRC final : public ServiceFramework<GRC> { 13class GRC final : public ServiceFramework<GRC> {
14public: 14public:
15 explicit GRC() : ServiceFramework{"grc:c"} { 15 explicit GRC(Core::System& system) : ServiceFramework{system, "grc:c"} {
16 // clang-format off 16 // clang-format off
17 static const FunctionInfo functions[] = { 17 static const FunctionInfo functions[] = {
18 {1, nullptr, "OpenContinuousRecorder"}, 18 {1, nullptr, "OpenContinuousRecorder"},
@@ -27,8 +27,8 @@ public:
27 } 27 }
28}; 28};
29 29
30void InstallInterfaces(SM::ServiceManager& sm) { 30void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
31 std::make_shared<GRC>()->InstallAsService(sm); 31 std::make_shared<GRC>(system)->InstallAsService(sm);
32} 32}
33 33
34} // namespace Service::GRC 34} // namespace Service::GRC
diff --git a/src/core/hle/service/grc/grc.h b/src/core/hle/service/grc/grc.h
index e0d29e70d..9069fe756 100644
--- a/src/core/hle/service/grc/grc.h
+++ b/src/core/hle/service/grc/grc.h
@@ -4,12 +4,16 @@
4 4
5#pragma once 5#pragma once
6 6
7namespace Core {
8class System;
9}
10
7namespace Service::SM { 11namespace Service::SM {
8class ServiceManager; 12class ServiceManager;
9} 13}
10 14
11namespace Service::GRC { 15namespace Service::GRC {
12 16
13void InstallInterfaces(SM::ServiceManager& sm); 17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
14 18
15} // namespace Service::GRC 19} // namespace Service::GRC
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index e2539ded8..66c4fe60a 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -677,6 +677,14 @@ Controller_NPad::NpadHandheldActivationMode Controller_NPad::GetNpadHandheldActi
677 return handheld_activation_mode; 677 return handheld_activation_mode;
678} 678}
679 679
680void Controller_NPad::SetNpadCommunicationMode(NpadCommunicationMode communication_mode_) {
681 communication_mode = communication_mode_;
682}
683
684Controller_NPad::NpadCommunicationMode Controller_NPad::GetNpadCommunicationMode() const {
685 return communication_mode;
686}
687
680void Controller_NPad::SetNpadMode(u32 npad_id, NpadAssignments assignment_mode) { 688void Controller_NPad::SetNpadMode(u32 npad_id, NpadAssignments assignment_mode) {
681 const std::size_t npad_index = NPadIdToIndex(npad_id); 689 const std::size_t npad_index = NPadIdToIndex(npad_id);
682 ASSERT(npad_index < shared_memory_entries.size()); 690 ASSERT(npad_index < shared_memory_entries.size());
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index 160dcbbe3..96f319294 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -86,6 +86,13 @@ public:
86 None = 2, 86 None = 2,
87 }; 87 };
88 88
89 enum class NpadCommunicationMode : u64 {
90 Unknown0 = 0,
91 Unknown1 = 1,
92 Unknown2 = 2,
93 Unknown3 = 3,
94 };
95
89 struct DeviceHandle { 96 struct DeviceHandle {
90 NpadType npad_type{}; 97 NpadType npad_type{};
91 u8 npad_id{}; 98 u8 npad_id{};
@@ -146,6 +153,9 @@ public:
146 void SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_mode); 153 void SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_mode);
147 NpadHandheldActivationMode GetNpadHandheldActivationMode() const; 154 NpadHandheldActivationMode GetNpadHandheldActivationMode() const;
148 155
156 void SetNpadCommunicationMode(NpadCommunicationMode communication_mode_);
157 NpadCommunicationMode GetNpadCommunicationMode() const;
158
149 void SetNpadMode(u32 npad_id, NpadAssignments assignment_mode); 159 void SetNpadMode(u32 npad_id, NpadAssignments assignment_mode);
150 160
151 bool VibrateControllerAtIndex(std::size_t npad_index, std::size_t device_index, 161 bool VibrateControllerAtIndex(std::size_t npad_index, std::size_t device_index,
@@ -424,6 +434,8 @@ private:
424 std::vector<u32> supported_npad_id_types{}; 434 std::vector<u32> supported_npad_id_types{};
425 NpadHoldType hold_type{NpadHoldType::Vertical}; 435 NpadHoldType hold_type{NpadHoldType::Vertical};
426 NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual}; 436 NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual};
437 // NpadCommunicationMode is unknown, default value is 1
438 NpadCommunicationMode communication_mode{NpadCommunicationMode::Unknown1};
427 // Each controller should have their own styleset changed event 439 // Each controller should have their own styleset changed event
428 std::array<Kernel::EventPair, 10> styleset_changed_events; 440 std::array<Kernel::EventPair, 10> styleset_changed_events;
429 std::array<std::array<std::chrono::steady_clock::time_point, 2>, 10> last_vibration_timepoints; 441 std::array<std::array<std::chrono::steady_clock::time_point, 2>, 10> last_vibration_timepoints;
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 902516b29..b3c7234e1 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -44,8 +44,8 @@ constexpr auto pad_update_ns = std::chrono::nanoseconds{1000 * 1000}; //
44constexpr auto motion_update_ns = std::chrono::nanoseconds{15 * 1000 * 1000}; // (15ms, 66.666Hz) 44constexpr auto motion_update_ns = std::chrono::nanoseconds{15 * 1000 * 1000}; // (15ms, 66.666Hz)
45constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; 45constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000;
46 46
47IAppletResource::IAppletResource(Core::System& system) 47IAppletResource::IAppletResource(Core::System& system_)
48 : ServiceFramework("IAppletResource"), system(system) { 48 : ServiceFramework{system_, "IAppletResource"} {
49 static const FunctionInfo functions[] = { 49 static const FunctionInfo functions[] = {
50 {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"}, 50 {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"},
51 }; 51 };
@@ -139,8 +139,10 @@ void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanose
139 139
140class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> { 140class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> {
141public: 141public:
142 explicit IActiveVibrationDeviceList(std::shared_ptr<IAppletResource> applet_resource_) 142 explicit IActiveVibrationDeviceList(Core::System& system_,
143 : ServiceFramework("IActiveVibrationDeviceList"), applet_resource(applet_resource_) { 143 std::shared_ptr<IAppletResource> applet_resource_)
144 : ServiceFramework{system_, "IActiveVibrationDeviceList"},
145 applet_resource(applet_resource_) {
144 // clang-format off 146 // clang-format off
145 static const FunctionInfo functions[] = { 147 static const FunctionInfo functions[] = {
146 {0, &IActiveVibrationDeviceList::InitializeVibrationDevice, "InitializeVibrationDevice"}, 148 {0, &IActiveVibrationDeviceList::InitializeVibrationDevice, "InitializeVibrationDevice"},
@@ -155,8 +157,10 @@ private:
155 IPC::RequestParser rp{ctx}; 157 IPC::RequestParser rp{ctx};
156 const auto vibration_device_handle{rp.PopRaw<Controller_NPad::DeviceHandle>()}; 158 const auto vibration_device_handle{rp.PopRaw<Controller_NPad::DeviceHandle>()};
157 159
158 applet_resource->GetController<Controller_NPad>(HidController::NPad) 160 if (applet_resource != nullptr) {
159 .InitializeVibrationDevice(vibration_device_handle); 161 applet_resource->GetController<Controller_NPad>(HidController::NPad)
162 .InitializeVibrationDevice(vibration_device_handle);
163 }
160 164
161 LOG_DEBUG(Service_HID, "called, npad_type={}, npad_id={}, device_index={}", 165 LOG_DEBUG(Service_HID, "called, npad_type={}, npad_id={}, device_index={}",
162 vibration_device_handle.npad_type, vibration_device_handle.npad_id, 166 vibration_device_handle.npad_type, vibration_device_handle.npad_id,
@@ -177,7 +181,7 @@ std::shared_ptr<IAppletResource> Hid::GetAppletResource() {
177 return applet_resource; 181 return applet_resource;
178} 182}
179 183
180Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) { 184Hid::Hid(Core::System& system_) : ServiceFramework{system_, "hid"} {
181 // clang-format off 185 // clang-format off
182 static const FunctionInfo functions[] = { 186 static const FunctionInfo functions[] = {
183 {0, &Hid::CreateAppletResource, "CreateAppletResource"}, 187 {0, &Hid::CreateAppletResource, "CreateAppletResource"},
@@ -306,8 +310,8 @@ Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) {
306 {527, nullptr, "EnablePalmaBoostMode"}, 310 {527, nullptr, "EnablePalmaBoostMode"},
307 {528, nullptr, "GetPalmaBluetoothAddress"}, 311 {528, nullptr, "GetPalmaBluetoothAddress"},
308 {529, nullptr, "SetDisallowedPalmaConnection"}, 312 {529, nullptr, "SetDisallowedPalmaConnection"},
309 {1000, nullptr, "SetNpadCommunicationMode"}, 313 {1000, &Hid::SetNpadCommunicationMode, "SetNpadCommunicationMode"},
310 {1001, nullptr, "GetNpadCommunicationMode"}, 314 {1001, &Hid::GetNpadCommunicationMode, "GetNpadCommunicationMode"},
311 {1002, nullptr, "SetTouchScreenConfiguration"}, 315 {1002, nullptr, "SetTouchScreenConfiguration"},
312 {1003, nullptr, "IsFirmwareUpdateNeededForNotification"}, 316 {1003, nullptr, "IsFirmwareUpdateNeededForNotification"},
313 {2000, nullptr, "ActivateDigitizer"}, 317 {2000, nullptr, "ActivateDigitizer"},
@@ -1068,7 +1072,7 @@ void Hid::CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) {
1068 1072
1069 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 1073 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
1070 rb.Push(RESULT_SUCCESS); 1074 rb.Push(RESULT_SUCCESS);
1071 rb.PushIpcInterface<IActiveVibrationDeviceList>(applet_resource); 1075 rb.PushIpcInterface<IActiveVibrationDeviceList>(system, applet_resource);
1072} 1076}
1073 1077
1074void Hid::PermitVibration(Kernel::HLERequestContext& ctx) { 1078void Hid::PermitVibration(Kernel::HLERequestContext& ctx) {
@@ -1296,9 +1300,37 @@ void Hid::SetPalmaBoostMode(Kernel::HLERequestContext& ctx) {
1296 rb.Push(RESULT_SUCCESS); 1300 rb.Push(RESULT_SUCCESS);
1297} 1301}
1298 1302
1303void Hid::SetNpadCommunicationMode(Kernel::HLERequestContext& ctx) {
1304 IPC::RequestParser rp{ctx};
1305 const auto applet_resource_user_id{rp.Pop<u64>()};
1306 const auto communication_mode{rp.PopEnum<Controller_NPad::NpadCommunicationMode>()};
1307
1308 applet_resource->GetController<Controller_NPad>(HidController::NPad)
1309 .SetNpadCommunicationMode(communication_mode);
1310
1311 LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, communication_mode={}",
1312 applet_resource_user_id, communication_mode);
1313
1314 IPC::ResponseBuilder rb{ctx, 2};
1315 rb.Push(RESULT_SUCCESS);
1316}
1317
1318void Hid::GetNpadCommunicationMode(Kernel::HLERequestContext& ctx) {
1319 IPC::RequestParser rp{ctx};
1320 const auto applet_resource_user_id{rp.Pop<u64>()};
1321
1322 LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
1323 applet_resource_user_id);
1324
1325 IPC::ResponseBuilder rb{ctx, 4};
1326 rb.Push(RESULT_SUCCESS);
1327 rb.PushEnum(applet_resource->GetController<Controller_NPad>(HidController::NPad)
1328 .GetNpadCommunicationMode());
1329}
1330
1299class HidDbg final : public ServiceFramework<HidDbg> { 1331class HidDbg final : public ServiceFramework<HidDbg> {
1300public: 1332public:
1301 explicit HidDbg() : ServiceFramework{"hid:dbg"} { 1333 explicit HidDbg(Core::System& system_) : ServiceFramework{system_, "hid:dbg"} {
1302 // clang-format off 1334 // clang-format off
1303 static const FunctionInfo functions[] = { 1335 static const FunctionInfo functions[] = {
1304 {0, nullptr, "DeactivateDebugPad"}, 1336 {0, nullptr, "DeactivateDebugPad"},
@@ -1425,7 +1457,7 @@ public:
1425 1457
1426class HidSys final : public ServiceFramework<HidSys> { 1458class HidSys final : public ServiceFramework<HidSys> {
1427public: 1459public:
1428 explicit HidSys() : ServiceFramework{"hid:sys"} { 1460 explicit HidSys(Core::System& system_) : ServiceFramework{system_, "hid:sys"} {
1429 // clang-format off 1461 // clang-format off
1430 static const FunctionInfo functions[] = { 1462 static const FunctionInfo functions[] = {
1431 {31, nullptr, "SendKeyboardLockKeyEvent"}, 1463 {31, nullptr, "SendKeyboardLockKeyEvent"},
@@ -1559,7 +1591,7 @@ public:
1559 1591
1560class HidTmp final : public ServiceFramework<HidTmp> { 1592class HidTmp final : public ServiceFramework<HidTmp> {
1561public: 1593public:
1562 explicit HidTmp() : ServiceFramework{"hid:tmp"} { 1594 explicit HidTmp(Core::System& system_) : ServiceFramework{system_, "hid:tmp"} {
1563 // clang-format off 1595 // clang-format off
1564 static const FunctionInfo functions[] = { 1596 static const FunctionInfo functions[] = {
1565 {0, nullptr, "GetConsoleSixAxisSensorCalibrationValues"}, 1597 {0, nullptr, "GetConsoleSixAxisSensorCalibrationValues"},
@@ -1572,7 +1604,7 @@ public:
1572 1604
1573class HidBus final : public ServiceFramework<HidBus> { 1605class HidBus final : public ServiceFramework<HidBus> {
1574public: 1606public:
1575 explicit HidBus() : ServiceFramework{"hidbus"} { 1607 explicit HidBus(Core::System& system_) : ServiceFramework{system_, "hidbus"} {
1576 // clang-format off 1608 // clang-format off
1577 static const FunctionInfo functions[] = { 1609 static const FunctionInfo functions[] = {
1578 {1, nullptr, "GetBusHandle"}, 1610 {1, nullptr, "GetBusHandle"},
@@ -1602,15 +1634,15 @@ void ReloadInputDevices() {
1602 1634
1603void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 1635void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
1604 std::make_shared<Hid>(system)->InstallAsService(service_manager); 1636 std::make_shared<Hid>(system)->InstallAsService(service_manager);
1605 std::make_shared<HidBus>()->InstallAsService(service_manager); 1637 std::make_shared<HidBus>(system)->InstallAsService(service_manager);
1606 std::make_shared<HidDbg>()->InstallAsService(service_manager); 1638 std::make_shared<HidDbg>(system)->InstallAsService(service_manager);
1607 std::make_shared<HidSys>()->InstallAsService(service_manager); 1639 std::make_shared<HidSys>(system)->InstallAsService(service_manager);
1608 std::make_shared<HidTmp>()->InstallAsService(service_manager); 1640 std::make_shared<HidTmp>(system)->InstallAsService(service_manager);
1609 1641
1610 std::make_shared<IRS>(system)->InstallAsService(service_manager); 1642 std::make_shared<IRS>(system)->InstallAsService(service_manager);
1611 std::make_shared<IRS_SYS>()->InstallAsService(service_manager); 1643 std::make_shared<IRS_SYS>(system)->InstallAsService(service_manager);
1612 1644
1613 std::make_shared<XCD_SYS>()->InstallAsService(service_manager); 1645 std::make_shared<XCD_SYS>(system)->InstallAsService(service_manager);
1614} 1646}
1615 1647
1616} // namespace Service::HID 1648} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index c8e4a4b55..b87bfdde1 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -41,7 +41,7 @@ enum class HidController : std::size_t {
41 41
42class IAppletResource final : public ServiceFramework<IAppletResource> { 42class IAppletResource final : public ServiceFramework<IAppletResource> {
43public: 43public:
44 explicit IAppletResource(Core::System& system); 44 explicit IAppletResource(Core::System& system_);
45 ~IAppletResource() override; 45 ~IAppletResource() override;
46 46
47 void ActivateController(HidController controller); 47 void ActivateController(HidController controller);
@@ -71,7 +71,6 @@ private:
71 71
72 std::shared_ptr<Core::Timing::EventType> pad_update_event; 72 std::shared_ptr<Core::Timing::EventType> pad_update_event;
73 std::shared_ptr<Core::Timing::EventType> motion_update_event; 73 std::shared_ptr<Core::Timing::EventType> motion_update_event;
74 Core::System& system;
75 74
76 std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)> 75 std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)>
77 controllers{}; 76 controllers{};
@@ -79,7 +78,7 @@ private:
79 78
80class Hid final : public ServiceFramework<Hid> { 79class Hid final : public ServiceFramework<Hid> {
81public: 80public:
82 explicit Hid(Core::System& system); 81 explicit Hid(Core::System& system_);
83 ~Hid() override; 82 ~Hid() override;
84 83
85 std::shared_ptr<IAppletResource> GetAppletResource(); 84 std::shared_ptr<IAppletResource> GetAppletResource();
@@ -146,6 +145,8 @@ private:
146 void ResetSevenSixAxisSensorTimestamp(Kernel::HLERequestContext& ctx); 145 void ResetSevenSixAxisSensorTimestamp(Kernel::HLERequestContext& ctx);
147 void SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx); 146 void SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx);
148 void SetPalmaBoostMode(Kernel::HLERequestContext& ctx); 147 void SetPalmaBoostMode(Kernel::HLERequestContext& ctx);
148 void SetNpadCommunicationMode(Kernel::HLERequestContext& ctx);
149 void GetNpadCommunicationMode(Kernel::HLERequestContext& ctx);
149 150
150 enum class VibrationDeviceType : u32 { 151 enum class VibrationDeviceType : u32 {
151 LinearResonantActuator = 1, 152 LinearResonantActuator = 1,
@@ -164,7 +165,6 @@ private:
164 static_assert(sizeof(VibrationDeviceInfo) == 0x8, "VibrationDeviceInfo has incorrect size."); 165 static_assert(sizeof(VibrationDeviceInfo) == 0x8, "VibrationDeviceInfo has incorrect size.");
165 166
166 std::shared_ptr<IAppletResource> applet_resource; 167 std::shared_ptr<IAppletResource> applet_resource;
167 Core::System& system;
168}; 168};
169 169
170/// Reload input devices. Used when input configuration changed 170/// Reload input devices. Used when input configuration changed
diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp
index e82fd031b..c8413099f 100644
--- a/src/core/hle/service/hid/irs.cpp
+++ b/src/core/hle/service/hid/irs.cpp
@@ -12,7 +12,7 @@
12 12
13namespace Service::HID { 13namespace Service::HID {
14 14
15IRS::IRS(Core::System& system) : ServiceFramework{"irs"}, system(system) { 15IRS::IRS(Core::System& system_) : ServiceFramework{system_, "irs"} {
16 // clang-format off 16 // clang-format off
17 static const FunctionInfo functions[] = { 17 static const FunctionInfo functions[] = {
18 {302, &IRS::ActivateIrsensor, "ActivateIrsensor"}, 18 {302, &IRS::ActivateIrsensor, "ActivateIrsensor"},
@@ -175,7 +175,7 @@ void IRS::ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx) {
175 175
176IRS::~IRS() = default; 176IRS::~IRS() = default;
177 177
178IRS_SYS::IRS_SYS() : ServiceFramework{"irs:sys"} { 178IRS_SYS::IRS_SYS(Core::System& system_) : ServiceFramework{system_, "irs:sys"} {
179 // clang-format off 179 // clang-format off
180 static const FunctionInfo functions[] = { 180 static const FunctionInfo functions[] = {
181 {500, nullptr, "SetAppletResourceUserId"}, 181 {500, nullptr, "SetAppletResourceUserId"},
diff --git a/src/core/hle/service/hid/irs.h b/src/core/hle/service/hid/irs.h
index 8918ad6ca..be0c486ba 100644
--- a/src/core/hle/service/hid/irs.h
+++ b/src/core/hle/service/hid/irs.h
@@ -7,6 +7,10 @@
7#include "core/hle/kernel/object.h" 7#include "core/hle/kernel/object.h"
8#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
9 9
10namespace Core {
11class System;
12}
13
10namespace Kernel { 14namespace Kernel {
11class SharedMemory; 15class SharedMemory;
12} 16}
@@ -15,7 +19,7 @@ namespace Service::HID {
15 19
16class IRS final : public ServiceFramework<IRS> { 20class IRS final : public ServiceFramework<IRS> {
17public: 21public:
18 explicit IRS(Core::System& system); 22 explicit IRS(Core::System& system_);
19 ~IRS() override; 23 ~IRS() override;
20 24
21private: 25private:
@@ -37,14 +41,14 @@ private:
37 void RunIrLedProcessor(Kernel::HLERequestContext& ctx); 41 void RunIrLedProcessor(Kernel::HLERequestContext& ctx);
38 void StopImageProcessorAsync(Kernel::HLERequestContext& ctx); 42 void StopImageProcessorAsync(Kernel::HLERequestContext& ctx);
39 void ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx); 43 void ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx);
44
40 std::shared_ptr<Kernel::SharedMemory> shared_mem; 45 std::shared_ptr<Kernel::SharedMemory> shared_mem;
41 const u32 device_handle{0xABCD}; 46 const u32 device_handle{0xABCD};
42 Core::System& system;
43}; 47};
44 48
45class IRS_SYS final : public ServiceFramework<IRS_SYS> { 49class IRS_SYS final : public ServiceFramework<IRS_SYS> {
46public: 50public:
47 explicit IRS_SYS(); 51 explicit IRS_SYS(Core::System& system);
48 ~IRS_SYS() override; 52 ~IRS_SYS() override;
49}; 53};
50 54
diff --git a/src/core/hle/service/hid/xcd.cpp b/src/core/hle/service/hid/xcd.cpp
index c8e9125f6..43a8840d0 100644
--- a/src/core/hle/service/hid/xcd.cpp
+++ b/src/core/hle/service/hid/xcd.cpp
@@ -6,7 +6,7 @@
6 6
7namespace Service::HID { 7namespace Service::HID {
8 8
9XCD_SYS::XCD_SYS() : ServiceFramework{"xcd:sys"} { 9XCD_SYS::XCD_SYS(Core::System& system_) : ServiceFramework{system_, "xcd:sys"} {
10 // clang-format off 10 // clang-format off
11 static const FunctionInfo functions[] = { 11 static const FunctionInfo functions[] = {
12 {0, nullptr, "GetDataFormat"}, 12 {0, nullptr, "GetDataFormat"},
diff --git a/src/core/hle/service/hid/xcd.h b/src/core/hle/service/hid/xcd.h
index fd506d303..54932c228 100644
--- a/src/core/hle/service/hid/xcd.h
+++ b/src/core/hle/service/hid/xcd.h
@@ -6,11 +6,15 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::HID { 13namespace Service::HID {
10 14
11class XCD_SYS final : public ServiceFramework<XCD_SYS> { 15class XCD_SYS final : public ServiceFramework<XCD_SYS> {
12public: 16public:
13 explicit XCD_SYS(); 17 explicit XCD_SYS(Core::System& system_);
14 ~XCD_SYS() override; 18 ~XCD_SYS() override;
15}; 19};
16 20
diff --git a/src/core/hle/service/lbl/lbl.cpp b/src/core/hle/service/lbl/lbl.cpp
index 17350b403..6ad3a2877 100644
--- a/src/core/hle/service/lbl/lbl.cpp
+++ b/src/core/hle/service/lbl/lbl.cpp
@@ -15,7 +15,7 @@ namespace Service::LBL {
15 15
16class LBL final : public ServiceFramework<LBL> { 16class LBL final : public ServiceFramework<LBL> {
17public: 17public:
18 explicit LBL() : ServiceFramework{"lbl"} { 18 explicit LBL(Core::System& system_) : ServiceFramework{system_, "lbl"} {
19 // clang-format off 19 // clang-format off
20 static const FunctionInfo functions[] = { 20 static const FunctionInfo functions[] = {
21 {0, nullptr, "SaveCurrentSetting"}, 21 {0, nullptr, "SaveCurrentSetting"},
@@ -84,8 +84,8 @@ private:
84 bool vr_mode_enabled = false; 84 bool vr_mode_enabled = false;
85}; 85};
86 86
87void InstallInterfaces(SM::ServiceManager& sm) { 87void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
88 std::make_shared<LBL>()->InstallAsService(sm); 88 std::make_shared<LBL>(system)->InstallAsService(sm);
89} 89}
90 90
91} // namespace Service::LBL 91} // namespace Service::LBL
diff --git a/src/core/hle/service/lbl/lbl.h b/src/core/hle/service/lbl/lbl.h
index bf6f400f8..9c2021026 100644
--- a/src/core/hle/service/lbl/lbl.h
+++ b/src/core/hle/service/lbl/lbl.h
@@ -4,12 +4,16 @@
4 4
5#pragma once 5#pragma once
6 6
7namespace Core {
8class System;
9}
10
7namespace Service::SM { 11namespace Service::SM {
8class ServiceManager; 12class ServiceManager;
9} 13}
10 14
11namespace Service::LBL { 15namespace Service::LBL {
12 16
13void InstallInterfaces(SM::ServiceManager& sm); 17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
14 18
15} // namespace Service::LBL 19} // namespace Service::LBL
diff --git a/src/core/hle/service/ldn/ldn.cpp b/src/core/hle/service/ldn/ldn.cpp
index 49972cd69..ee908f399 100644
--- a/src/core/hle/service/ldn/ldn.cpp
+++ b/src/core/hle/service/ldn/ldn.cpp
@@ -13,7 +13,7 @@ namespace Service::LDN {
13 13
14class IMonitorService final : public ServiceFramework<IMonitorService> { 14class IMonitorService final : public ServiceFramework<IMonitorService> {
15public: 15public:
16 explicit IMonitorService() : ServiceFramework{"IMonitorService"} { 16 explicit IMonitorService(Core::System& system_) : ServiceFramework{system_, "IMonitorService"} {
17 // clang-format off 17 // clang-format off
18 static const FunctionInfo functions[] = { 18 static const FunctionInfo functions[] = {
19 {0, nullptr, "GetStateForMonitor"}, 19 {0, nullptr, "GetStateForMonitor"},
@@ -33,7 +33,7 @@ public:
33 33
34class LDNM final : public ServiceFramework<LDNM> { 34class LDNM final : public ServiceFramework<LDNM> {
35public: 35public:
36 explicit LDNM() : ServiceFramework{"ldn:m"} { 36 explicit LDNM(Core::System& system_) : ServiceFramework{system_, "ldn:m"} {
37 // clang-format off 37 // clang-format off
38 static const FunctionInfo functions[] = { 38 static const FunctionInfo functions[] = {
39 {0, &LDNM::CreateMonitorService, "CreateMonitorService"} 39 {0, &LDNM::CreateMonitorService, "CreateMonitorService"}
@@ -48,15 +48,15 @@ public:
48 48
49 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 49 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
50 rb.Push(RESULT_SUCCESS); 50 rb.Push(RESULT_SUCCESS);
51 rb.PushIpcInterface<IMonitorService>(); 51 rb.PushIpcInterface<IMonitorService>(system);
52 } 52 }
53}; 53};
54 54
55class ISystemLocalCommunicationService final 55class ISystemLocalCommunicationService final
56 : public ServiceFramework<ISystemLocalCommunicationService> { 56 : public ServiceFramework<ISystemLocalCommunicationService> {
57public: 57public:
58 explicit ISystemLocalCommunicationService() 58 explicit ISystemLocalCommunicationService(Core::System& system_)
59 : ServiceFramework{"ISystemLocalCommunicationService"} { 59 : ServiceFramework{system_, "ISystemLocalCommunicationService"} {
60 // clang-format off 60 // clang-format off
61 static const FunctionInfo functions[] = { 61 static const FunctionInfo functions[] = {
62 {0, nullptr, "GetState"}, 62 {0, nullptr, "GetState"},
@@ -99,7 +99,8 @@ public:
99class IUserLocalCommunicationService final 99class IUserLocalCommunicationService final
100 : public ServiceFramework<IUserLocalCommunicationService> { 100 : public ServiceFramework<IUserLocalCommunicationService> {
101public: 101public:
102 explicit IUserLocalCommunicationService() : ServiceFramework{"IUserLocalCommunicationService"} { 102 explicit IUserLocalCommunicationService(Core::System& system_)
103 : ServiceFramework{system_, "IUserLocalCommunicationService"} {
103 // clang-format off 104 // clang-format off
104 static const FunctionInfo functions[] = { 105 static const FunctionInfo functions[] = {
105 {0, nullptr, "GetState"}, 106 {0, nullptr, "GetState"},
@@ -148,7 +149,7 @@ public:
148 149
149class LDNS final : public ServiceFramework<LDNS> { 150class LDNS final : public ServiceFramework<LDNS> {
150public: 151public:
151 explicit LDNS() : ServiceFramework{"ldn:s"} { 152 explicit LDNS(Core::System& system_) : ServiceFramework{system_, "ldn:s"} {
152 // clang-format off 153 // clang-format off
153 static const FunctionInfo functions[] = { 154 static const FunctionInfo functions[] = {
154 {0, &LDNS::CreateSystemLocalCommunicationService, "CreateSystemLocalCommunicationService"}, 155 {0, &LDNS::CreateSystemLocalCommunicationService, "CreateSystemLocalCommunicationService"},
@@ -163,13 +164,13 @@ public:
163 164
164 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 165 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
165 rb.Push(RESULT_SUCCESS); 166 rb.Push(RESULT_SUCCESS);
166 rb.PushIpcInterface<ISystemLocalCommunicationService>(); 167 rb.PushIpcInterface<ISystemLocalCommunicationService>(system);
167 } 168 }
168}; 169};
169 170
170class LDNU final : public ServiceFramework<LDNU> { 171class LDNU final : public ServiceFramework<LDNU> {
171public: 172public:
172 explicit LDNU() : ServiceFramework{"ldn:u"} { 173 explicit LDNU(Core::System& system_) : ServiceFramework{system_, "ldn:u"} {
173 // clang-format off 174 // clang-format off
174 static const FunctionInfo functions[] = { 175 static const FunctionInfo functions[] = {
175 {0, &LDNU::CreateUserLocalCommunicationService, "CreateUserLocalCommunicationService"}, 176 {0, &LDNU::CreateUserLocalCommunicationService, "CreateUserLocalCommunicationService"},
@@ -184,14 +185,14 @@ public:
184 185
185 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 186 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
186 rb.Push(RESULT_SUCCESS); 187 rb.Push(RESULT_SUCCESS);
187 rb.PushIpcInterface<IUserLocalCommunicationService>(); 188 rb.PushIpcInterface<IUserLocalCommunicationService>(system);
188 } 189 }
189}; 190};
190 191
191void InstallInterfaces(SM::ServiceManager& sm) { 192void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
192 std::make_shared<LDNM>()->InstallAsService(sm); 193 std::make_shared<LDNM>(system)->InstallAsService(sm);
193 std::make_shared<LDNS>()->InstallAsService(sm); 194 std::make_shared<LDNS>(system)->InstallAsService(sm);
194 std::make_shared<LDNU>()->InstallAsService(sm); 195 std::make_shared<LDNU>(system)->InstallAsService(sm);
195} 196}
196 197
197} // namespace Service::LDN 198} // namespace Service::LDN
diff --git a/src/core/hle/service/ldn/ldn.h b/src/core/hle/service/ldn/ldn.h
index 6b2a3c2b2..3ccd9738b 100644
--- a/src/core/hle/service/ldn/ldn.h
+++ b/src/core/hle/service/ldn/ldn.h
@@ -4,6 +4,10 @@
4 4
5#pragma once 5#pragma once
6 6
7namespace Core {
8class System;
9}
10
7namespace Service::SM { 11namespace Service::SM {
8class ServiceManager; 12class ServiceManager;
9} 13}
@@ -11,6 +15,6 @@ class ServiceManager;
11namespace Service::LDN { 15namespace Service::LDN {
12 16
13/// Registers all LDN services with the specified service manager. 17/// Registers all LDN services with the specified service manager.
14void InstallInterfaces(SM::ServiceManager& sm); 18void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
15 19
16} // namespace Service::LDN 20} // namespace Service::LDN
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp
index 65c209725..fff68326b 100644
--- a/src/core/hle/service/ldr/ldr.cpp
+++ b/src/core/hle/service/ldr/ldr.cpp
@@ -115,7 +115,7 @@ static_assert(sizeof(NROInfo) == 0x60, "NROInfo has invalid size.");
115 115
116class DebugMonitor final : public ServiceFramework<DebugMonitor> { 116class DebugMonitor final : public ServiceFramework<DebugMonitor> {
117public: 117public:
118 explicit DebugMonitor() : ServiceFramework{"ldr:dmnt"} { 118 explicit DebugMonitor(Core::System& system_) : ServiceFramework{system_, "ldr:dmnt"} {
119 // clang-format off 119 // clang-format off
120 static const FunctionInfo functions[] = { 120 static const FunctionInfo functions[] = {
121 {0, nullptr, "AddProcessToDebugLaunchQueue"}, 121 {0, nullptr, "AddProcessToDebugLaunchQueue"},
@@ -130,7 +130,7 @@ public:
130 130
131class ProcessManager final : public ServiceFramework<ProcessManager> { 131class ProcessManager final : public ServiceFramework<ProcessManager> {
132public: 132public:
133 explicit ProcessManager() : ServiceFramework{"ldr:pm"} { 133 explicit ProcessManager(Core::System& system_) : ServiceFramework{system_, "ldr:pm"} {
134 // clang-format off 134 // clang-format off
135 static const FunctionInfo functions[] = { 135 static const FunctionInfo functions[] = {
136 {0, nullptr, "CreateProcess"}, 136 {0, nullptr, "CreateProcess"},
@@ -147,7 +147,7 @@ public:
147 147
148class Shell final : public ServiceFramework<Shell> { 148class Shell final : public ServiceFramework<Shell> {
149public: 149public:
150 explicit Shell() : ServiceFramework{"ldr:shel"} { 150 explicit Shell(Core::System& system_) : ServiceFramework{system_, "ldr:shel"} {
151 // clang-format off 151 // clang-format off
152 static const FunctionInfo functions[] = { 152 static const FunctionInfo functions[] = {
153 {0, nullptr, "AddProcessToLaunchQueue"}, 153 {0, nullptr, "AddProcessToLaunchQueue"},
@@ -161,7 +161,7 @@ public:
161 161
162class RelocatableObject final : public ServiceFramework<RelocatableObject> { 162class RelocatableObject final : public ServiceFramework<RelocatableObject> {
163public: 163public:
164 explicit RelocatableObject(Core::System& system) : ServiceFramework{"ldr:ro"}, system(system) { 164 explicit RelocatableObject(Core::System& system_) : ServiceFramework{system_, "ldr:ro"} {
165 // clang-format off 165 // clang-format off
166 static const FunctionInfo functions[] = { 166 static const FunctionInfo functions[] = {
167 {0, &RelocatableObject::LoadNro, "LoadNro"}, 167 {0, &RelocatableObject::LoadNro, "LoadNro"},
@@ -639,13 +639,12 @@ private:
639 Common::Is4KBAligned(header.segment_headers[RO_INDEX].memory_size) && 639 Common::Is4KBAligned(header.segment_headers[RO_INDEX].memory_size) &&
640 Common::Is4KBAligned(header.segment_headers[DATA_INDEX].memory_size); 640 Common::Is4KBAligned(header.segment_headers[DATA_INDEX].memory_size);
641 } 641 }
642 Core::System& system;
643}; 642};
644 643
645void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 644void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
646 std::make_shared<DebugMonitor>()->InstallAsService(sm); 645 std::make_shared<DebugMonitor>(system)->InstallAsService(sm);
647 std::make_shared<ProcessManager>()->InstallAsService(sm); 646 std::make_shared<ProcessManager>(system)->InstallAsService(sm);
648 std::make_shared<Shell>()->InstallAsService(sm); 647 std::make_shared<Shell>(system)->InstallAsService(sm);
649 std::make_shared<RelocatableObject>(system)->InstallAsService(sm); 648 std::make_shared<RelocatableObject>(system)->InstallAsService(sm);
650} 649}
651 650
diff --git a/src/core/hle/service/ldr/ldr.h b/src/core/hle/service/ldr/ldr.h
index 7ac8c0b65..104fc15c5 100644
--- a/src/core/hle/service/ldr/ldr.h
+++ b/src/core/hle/service/ldr/ldr.h
@@ -4,6 +4,10 @@
4 4
5#pragma once 5#pragma once
6 6
7namespace Core {
8class System;
9}
10
7namespace Service::SM { 11namespace Service::SM {
8class ServiceManager; 12class ServiceManager;
9} 13}
diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp
index 49a42a9c9..f884b2735 100644
--- a/src/core/hle/service/lm/lm.cpp
+++ b/src/core/hle/service/lm/lm.cpp
@@ -18,8 +18,9 @@ namespace Service::LM {
18 18
19class ILogger final : public ServiceFramework<ILogger> { 19class ILogger final : public ServiceFramework<ILogger> {
20public: 20public:
21 explicit ILogger(Manager& manager_, Core::Memory::Memory& memory_) 21 explicit ILogger(Core::System& system_)
22 : ServiceFramework("ILogger"), manager{manager_}, memory{memory_} { 22 : ServiceFramework{system_, "ILogger"}, manager{system_.GetLogManager()},
23 memory{system_.Memory()} {
23 static const FunctionInfo functions[] = { 24 static const FunctionInfo functions[] = {
24 {0, &ILogger::Log, "Log"}, 25 {0, &ILogger::Log, "Log"},
25 {1, &ILogger::SetDestination, "SetDestination"}, 26 {1, &ILogger::SetDestination, "SetDestination"},
@@ -81,8 +82,7 @@ private:
81 82
82class LM final : public ServiceFramework<LM> { 83class LM final : public ServiceFramework<LM> {
83public: 84public:
84 explicit LM(Manager& manager_, Core::Memory::Memory& memory_) 85 explicit LM(Core::System& system_) : ServiceFramework{system_, "lm"} {
85 : ServiceFramework{"lm"}, manager{manager_}, memory{memory_} {
86 // clang-format off 86 // clang-format off
87 static const FunctionInfo functions[] = { 87 static const FunctionInfo functions[] = {
88 {0, &LM::OpenLogger, "OpenLogger"}, 88 {0, &LM::OpenLogger, "OpenLogger"},
@@ -98,16 +98,12 @@ private:
98 98
99 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 99 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
100 rb.Push(RESULT_SUCCESS); 100 rb.Push(RESULT_SUCCESS);
101 rb.PushIpcInterface<ILogger>(manager, memory); 101 rb.PushIpcInterface<ILogger>(system);
102 } 102 }
103
104 Manager& manager;
105 Core::Memory::Memory& memory;
106}; 103};
107 104
108void InstallInterfaces(Core::System& system) { 105void InstallInterfaces(Core::System& system) {
109 std::make_shared<LM>(system.GetLogManager(), system.Memory()) 106 std::make_shared<LM>(system)->InstallAsService(system.ServiceManager());
110 ->InstallAsService(system.ServiceManager());
111} 107}
112 108
113} // namespace Service::LM 109} // namespace Service::LM
diff --git a/src/core/hle/service/mig/mig.cpp b/src/core/hle/service/mig/mig.cpp
index 113a4665c..1599d941b 100644
--- a/src/core/hle/service/mig/mig.cpp
+++ b/src/core/hle/service/mig/mig.cpp
@@ -12,7 +12,7 @@ namespace Service::Migration {
12 12
13class MIG_USR final : public ServiceFramework<MIG_USR> { 13class MIG_USR final : public ServiceFramework<MIG_USR> {
14public: 14public:
15 explicit MIG_USR() : ServiceFramework{"mig:usr"} { 15 explicit MIG_USR(Core::System& system_) : ServiceFramework{system_, "mig:usr"} {
16 // clang-format off 16 // clang-format off
17 static const FunctionInfo functions[] = { 17 static const FunctionInfo functions[] = {
18 {10, nullptr, "TryGetLastMigrationInfo"}, 18 {10, nullptr, "TryGetLastMigrationInfo"},
@@ -33,8 +33,8 @@ public:
33 } 33 }
34}; 34};
35 35
36void InstallInterfaces(SM::ServiceManager& sm) { 36void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
37 std::make_shared<MIG_USR>()->InstallAsService(sm); 37 std::make_shared<MIG_USR>(system)->InstallAsService(sm);
38} 38}
39 39
40} // namespace Service::Migration 40} // namespace Service::Migration
diff --git a/src/core/hle/service/mig/mig.h b/src/core/hle/service/mig/mig.h
index 288c1c1b3..2b24cdf2c 100644
--- a/src/core/hle/service/mig/mig.h
+++ b/src/core/hle/service/mig/mig.h
@@ -4,12 +4,16 @@
4 4
5#pragma once 5#pragma once
6 6
7namespace Core {
8class System;
9}
10
7namespace Service::SM { 11namespace Service::SM {
8class ServiceManager; 12class ServiceManager;
9} 13}
10 14
11namespace Service::Migration { 15namespace Service::Migration {
12 16
13void InstallInterfaces(SM::ServiceManager& sm); 17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
14 18
15} // namespace Service::Migration 19} // namespace Service::Migration
diff --git a/src/core/hle/service/mii/mii.cpp b/src/core/hle/service/mii/mii.cpp
index d7080b715..26be9e45b 100644
--- a/src/core/hle/service/mii/mii.cpp
+++ b/src/core/hle/service/mii/mii.cpp
@@ -18,7 +18,8 @@ constexpr ResultCode ERROR_INVALID_ARGUMENT{ErrorModule::Mii, 1};
18 18
19class IDatabaseService final : public ServiceFramework<IDatabaseService> { 19class IDatabaseService final : public ServiceFramework<IDatabaseService> {
20public: 20public:
21 explicit IDatabaseService() : ServiceFramework{"IDatabaseService"} { 21 explicit IDatabaseService(Core::System& system_)
22 : ServiceFramework{system_, "IDatabaseService"} {
22 // clang-format off 23 // clang-format off
23 static const FunctionInfo functions[] = { 24 static const FunctionInfo functions[] = {
24 {0, &IDatabaseService::IsUpdated, "IsUpdated"}, 25 {0, &IDatabaseService::IsUpdated, "IsUpdated"},
@@ -252,7 +253,8 @@ private:
252 253
253class MiiDBModule final : public ServiceFramework<MiiDBModule> { 254class MiiDBModule final : public ServiceFramework<MiiDBModule> {
254public: 255public:
255 explicit MiiDBModule(const char* name) : ServiceFramework{name} { 256 explicit MiiDBModule(Core::System& system_, const char* name)
257 : ServiceFramework{system_, name} {
256 // clang-format off 258 // clang-format off
257 static const FunctionInfo functions[] = { 259 static const FunctionInfo functions[] = {
258 {0, &MiiDBModule::GetDatabaseService, "GetDatabaseService"}, 260 {0, &MiiDBModule::GetDatabaseService, "GetDatabaseService"},
@@ -266,7 +268,7 @@ private:
266 void GetDatabaseService(Kernel::HLERequestContext& ctx) { 268 void GetDatabaseService(Kernel::HLERequestContext& ctx) {
267 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 269 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
268 rb.Push(RESULT_SUCCESS); 270 rb.Push(RESULT_SUCCESS);
269 rb.PushIpcInterface<IDatabaseService>(); 271 rb.PushIpcInterface<IDatabaseService>(system);
270 272
271 LOG_DEBUG(Service_Mii, "called"); 273 LOG_DEBUG(Service_Mii, "called");
272 } 274 }
@@ -274,7 +276,7 @@ private:
274 276
275class MiiImg final : public ServiceFramework<MiiImg> { 277class MiiImg final : public ServiceFramework<MiiImg> {
276public: 278public:
277 explicit MiiImg() : ServiceFramework{"miiimg"} { 279 explicit MiiImg(Core::System& system_) : ServiceFramework{system_, "miiimg"} {
278 // clang-format off 280 // clang-format off
279 static const FunctionInfo functions[] = { 281 static const FunctionInfo functions[] = {
280 {0, nullptr, "Initialize"}, 282 {0, nullptr, "Initialize"},
@@ -298,11 +300,11 @@ public:
298 } 300 }
299}; 301};
300 302
301void InstallInterfaces(SM::ServiceManager& sm) { 303void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
302 std::make_shared<MiiDBModule>("mii:e")->InstallAsService(sm); 304 std::make_shared<MiiDBModule>(system, "mii:e")->InstallAsService(sm);
303 std::make_shared<MiiDBModule>("mii:u")->InstallAsService(sm); 305 std::make_shared<MiiDBModule>(system, "mii:u")->InstallAsService(sm);
304 306
305 std::make_shared<MiiImg>()->InstallAsService(sm); 307 std::make_shared<MiiImg>(system)->InstallAsService(sm);
306} 308}
307 309
308} // namespace Service::Mii 310} // namespace Service::Mii
diff --git a/src/core/hle/service/mii/mii.h b/src/core/hle/service/mii/mii.h
index 7ce9be50e..9d3238e72 100644
--- a/src/core/hle/service/mii/mii.h
+++ b/src/core/hle/service/mii/mii.h
@@ -4,12 +4,16 @@
4 4
5#pragma once 5#pragma once
6 6
7namespace Core {
8class System;
9}
10
7namespace Service::SM { 11namespace Service::SM {
8class ServiceManager; 12class ServiceManager;
9} 13}
10 14
11namespace Service::Mii { 15namespace Service::Mii {
12 16
13void InstallInterfaces(SM::ServiceManager& sm); 17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
14 18
15} // namespace Service::Mii 19} // namespace Service::Mii
diff --git a/src/core/hle/service/mm/mm_u.cpp b/src/core/hle/service/mm/mm_u.cpp
index 25c24e537..b0cb07d24 100644
--- a/src/core/hle/service/mm/mm_u.cpp
+++ b/src/core/hle/service/mm/mm_u.cpp
@@ -6,12 +6,13 @@
6#include "core/hle/ipc_helpers.h" 6#include "core/hle/ipc_helpers.h"
7#include "core/hle/kernel/client_session.h" 7#include "core/hle/kernel/client_session.h"
8#include "core/hle/service/mm/mm_u.h" 8#include "core/hle/service/mm/mm_u.h"
9#include "core/hle/service/sm/sm.h"
9 10
10namespace Service::MM { 11namespace Service::MM {
11 12
12class MM_U final : public ServiceFramework<MM_U> { 13class MM_U final : public ServiceFramework<MM_U> {
13public: 14public:
14 explicit MM_U() : ServiceFramework{"mm:u"} { 15 explicit MM_U(Core::System& system_) : ServiceFramework{system_, "mm:u"} {
15 // clang-format off 16 // clang-format off
16 static const FunctionInfo functions[] = { 17 static const FunctionInfo functions[] = {
17 {0, &MM_U::InitializeOld, "InitializeOld"}, 18 {0, &MM_U::InitializeOld, "InitializeOld"},
@@ -104,8 +105,8 @@ private:
104 u32 id{1}; 105 u32 id{1};
105}; 106};
106 107
107void InstallInterfaces(SM::ServiceManager& service_manager) { 108void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
108 std::make_shared<MM_U>()->InstallAsService(service_manager); 109 std::make_shared<MM_U>(system)->InstallAsService(service_manager);
109} 110}
110 111
111} // namespace Service::MM 112} // namespace Service::MM
diff --git a/src/core/hle/service/mm/mm_u.h b/src/core/hle/service/mm/mm_u.h
index 5439fa653..49b6a3355 100644
--- a/src/core/hle/service/mm/mm_u.h
+++ b/src/core/hle/service/mm/mm_u.h
@@ -4,11 +4,17 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "core/hle/service/service.h" 7namespace Core {
8class System;
9}
10
11namespace Service::SM {
12class ServiceManager;
13}
8 14
9namespace Service::MM { 15namespace Service::MM {
10 16
11/// Registers all MM services with the specified service manager. 17/// Registers all MM services with the specified service manager.
12void InstallInterfaces(SM::ServiceManager& service_manager); 18void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
13 19
14} // namespace Service::MM 20} // namespace Service::MM
diff --git a/src/core/hle/service/ncm/ncm.cpp b/src/core/hle/service/ncm/ncm.cpp
index e38dea1f4..b8d627ca8 100644
--- a/src/core/hle/service/ncm/ncm.cpp
+++ b/src/core/hle/service/ncm/ncm.cpp
@@ -14,8 +14,8 @@ namespace Service::NCM {
14 14
15class ILocationResolver final : public ServiceFramework<ILocationResolver> { 15class ILocationResolver final : public ServiceFramework<ILocationResolver> {
16public: 16public:
17 explicit ILocationResolver(FileSys::StorageId id) 17 explicit ILocationResolver(Core::System& system_, FileSys::StorageId id)
18 : ServiceFramework{"ILocationResolver"}, storage(id) { 18 : ServiceFramework{system_, "ILocationResolver"}, storage{id} {
19 // clang-format off 19 // clang-format off
20 static const FunctionInfo functions[] = { 20 static const FunctionInfo functions[] = {
21 {0, nullptr, "ResolveProgramPath"}, 21 {0, nullptr, "ResolveProgramPath"},
@@ -50,7 +50,8 @@ private:
50 50
51class IRegisteredLocationResolver final : public ServiceFramework<IRegisteredLocationResolver> { 51class IRegisteredLocationResolver final : public ServiceFramework<IRegisteredLocationResolver> {
52public: 52public:
53 explicit IRegisteredLocationResolver() : ServiceFramework{"IRegisteredLocationResolver"} { 53 explicit IRegisteredLocationResolver(Core::System& system_)
54 : ServiceFramework{system_, "IRegisteredLocationResolver"} {
54 // clang-format off 55 // clang-format off
55 static const FunctionInfo functions[] = { 56 static const FunctionInfo functions[] = {
56 {0, nullptr, "ResolveProgramPath"}, 57 {0, nullptr, "ResolveProgramPath"},
@@ -72,7 +73,8 @@ public:
72 73
73class IAddOnContentLocationResolver final : public ServiceFramework<IAddOnContentLocationResolver> { 74class IAddOnContentLocationResolver final : public ServiceFramework<IAddOnContentLocationResolver> {
74public: 75public:
75 explicit IAddOnContentLocationResolver() : ServiceFramework{"IAddOnContentLocationResolver"} { 76 explicit IAddOnContentLocationResolver(Core::System& system_)
77 : ServiceFramework{system_, "IAddOnContentLocationResolver"} {
76 // clang-format off 78 // clang-format off
77 static const FunctionInfo functions[] = { 79 static const FunctionInfo functions[] = {
78 {0, nullptr, "ResolveAddOnContentPath"}, 80 {0, nullptr, "ResolveAddOnContentPath"},
@@ -89,7 +91,7 @@ public:
89 91
90class LR final : public ServiceFramework<LR> { 92class LR final : public ServiceFramework<LR> {
91public: 93public:
92 explicit LR() : ServiceFramework{"lr"} { 94 explicit LR(Core::System& system_) : ServiceFramework{system_, "lr"} {
93 // clang-format off 95 // clang-format off
94 static const FunctionInfo functions[] = { 96 static const FunctionInfo functions[] = {
95 {0, nullptr, "OpenLocationResolver"}, 97 {0, nullptr, "OpenLocationResolver"},
@@ -105,7 +107,7 @@ public:
105 107
106class NCM final : public ServiceFramework<NCM> { 108class NCM final : public ServiceFramework<NCM> {
107public: 109public:
108 explicit NCM() : ServiceFramework{"ncm"} { 110 explicit NCM(Core::System& system_) : ServiceFramework{system_, "ncm"} {
109 // clang-format off 111 // clang-format off
110 static const FunctionInfo functions[] = { 112 static const FunctionInfo functions[] = {
111 {0, nullptr, "CreateContentStorage"}, 113 {0, nullptr, "CreateContentStorage"},
@@ -130,9 +132,9 @@ public:
130 } 132 }
131}; 133};
132 134
133void InstallInterfaces(SM::ServiceManager& sm) { 135void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
134 std::make_shared<LR>()->InstallAsService(sm); 136 std::make_shared<LR>(system)->InstallAsService(sm);
135 std::make_shared<NCM>()->InstallAsService(sm); 137 std::make_shared<NCM>(system)->InstallAsService(sm);
136} 138}
137 139
138} // namespace Service::NCM 140} // namespace Service::NCM
diff --git a/src/core/hle/service/ncm/ncm.h b/src/core/hle/service/ncm/ncm.h
index 7bc8518a6..ee01eddc0 100644
--- a/src/core/hle/service/ncm/ncm.h
+++ b/src/core/hle/service/ncm/ncm.h
@@ -4,12 +4,16 @@
4 4
5#pragma once 5#pragma once
6 6
7namespace Core {
8class System;
9}
10
7namespace Service::SM { 11namespace Service::SM {
8class ServiceManager; 12class ServiceManager;
9} 13}
10 14
11namespace Service::NCM { 15namespace Service::NCM {
12 16
13void InstallInterfaces(SM::ServiceManager& sm); 17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
14 18
15} // namespace Service::NCM 19} // namespace Service::NCM
diff --git a/src/core/hle/service/nfc/nfc.cpp b/src/core/hle/service/nfc/nfc.cpp
index 780ea30fe..6ab35de47 100644
--- a/src/core/hle/service/nfc/nfc.cpp
+++ b/src/core/hle/service/nfc/nfc.cpp
@@ -16,7 +16,7 @@ namespace Service::NFC {
16 16
17class IAm final : public ServiceFramework<IAm> { 17class IAm final : public ServiceFramework<IAm> {
18public: 18public:
19 explicit IAm() : ServiceFramework{"NFC::IAm"} { 19 explicit IAm(Core::System& system_) : ServiceFramework{system_, "NFC::IAm"} {
20 // clang-format off 20 // clang-format off
21 static const FunctionInfo functions[] = { 21 static const FunctionInfo functions[] = {
22 {0, nullptr, "Initialize"}, 22 {0, nullptr, "Initialize"},
@@ -31,7 +31,7 @@ public:
31 31
32class NFC_AM final : public ServiceFramework<NFC_AM> { 32class NFC_AM final : public ServiceFramework<NFC_AM> {
33public: 33public:
34 explicit NFC_AM() : ServiceFramework{"nfc:am"} { 34 explicit NFC_AM(Core::System& system_) : ServiceFramework{system_, "nfc:am"} {
35 // clang-format off 35 // clang-format off
36 static const FunctionInfo functions[] = { 36 static const FunctionInfo functions[] = {
37 {0, &NFC_AM::CreateAmInterface, "CreateAmInterface"}, 37 {0, &NFC_AM::CreateAmInterface, "CreateAmInterface"},
@@ -47,13 +47,13 @@ private:
47 47
48 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 48 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
49 rb.Push(RESULT_SUCCESS); 49 rb.Push(RESULT_SUCCESS);
50 rb.PushIpcInterface<IAm>(); 50 rb.PushIpcInterface<IAm>(system);
51 } 51 }
52}; 52};
53 53
54class MFIUser final : public ServiceFramework<MFIUser> { 54class MFIUser final : public ServiceFramework<MFIUser> {
55public: 55public:
56 explicit MFIUser() : ServiceFramework{"NFC::MFIUser"} { 56 explicit MFIUser(Core::System& system_) : ServiceFramework{system_, "NFC::MFIUser"} {
57 // clang-format off 57 // clang-format off
58 static const FunctionInfo functions[] = { 58 static const FunctionInfo functions[] = {
59 {0, nullptr, "Initialize"}, 59 {0, nullptr, "Initialize"},
@@ -79,7 +79,7 @@ public:
79 79
80class NFC_MF_U final : public ServiceFramework<NFC_MF_U> { 80class NFC_MF_U final : public ServiceFramework<NFC_MF_U> {
81public: 81public:
82 explicit NFC_MF_U() : ServiceFramework{"nfc:mf:u"} { 82 explicit NFC_MF_U(Core::System& system_) : ServiceFramework{system_, "nfc:mf:u"} {
83 // clang-format off 83 // clang-format off
84 static const FunctionInfo functions[] = { 84 static const FunctionInfo functions[] = {
85 {0, &NFC_MF_U::CreateUserInterface, "CreateUserInterface"}, 85 {0, &NFC_MF_U::CreateUserInterface, "CreateUserInterface"},
@@ -95,13 +95,13 @@ private:
95 95
96 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 96 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
97 rb.Push(RESULT_SUCCESS); 97 rb.Push(RESULT_SUCCESS);
98 rb.PushIpcInterface<MFIUser>(); 98 rb.PushIpcInterface<MFIUser>(system);
99 } 99 }
100}; 100};
101 101
102class IUser final : public ServiceFramework<IUser> { 102class IUser final : public ServiceFramework<IUser> {
103public: 103public:
104 explicit IUser() : ServiceFramework{"NFC::IUser"} { 104 explicit IUser(Core::System& system_) : ServiceFramework{system_, "NFC::IUser"} {
105 // clang-format off 105 // clang-format off
106 static const FunctionInfo functions[] = { 106 static const FunctionInfo functions[] = {
107 {0, &IUser::InitializeOld, "InitializeOld"}, 107 {0, &IUser::InitializeOld, "InitializeOld"},
@@ -171,7 +171,7 @@ private:
171 171
172class NFC_U final : public ServiceFramework<NFC_U> { 172class NFC_U final : public ServiceFramework<NFC_U> {
173public: 173public:
174 explicit NFC_U() : ServiceFramework{"nfc:user"} { 174 explicit NFC_U(Core::System& system_) : ServiceFramework{system_, "nfc:user"} {
175 // clang-format off 175 // clang-format off
176 static const FunctionInfo functions[] = { 176 static const FunctionInfo functions[] = {
177 {0, &NFC_U::CreateUserInterface, "CreateUserInterface"}, 177 {0, &NFC_U::CreateUserInterface, "CreateUserInterface"},
@@ -187,13 +187,13 @@ private:
187 187
188 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 188 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
189 rb.Push(RESULT_SUCCESS); 189 rb.Push(RESULT_SUCCESS);
190 rb.PushIpcInterface<IUser>(); 190 rb.PushIpcInterface<IUser>(system);
191 } 191 }
192}; 192};
193 193
194class ISystem final : public ServiceFramework<ISystem> { 194class ISystem final : public ServiceFramework<ISystem> {
195public: 195public:
196 explicit ISystem() : ServiceFramework{"ISystem"} { 196 explicit ISystem(Core::System& system_) : ServiceFramework{system_, "ISystem"} {
197 // clang-format off 197 // clang-format off
198 static const FunctionInfo functions[] = { 198 static const FunctionInfo functions[] = {
199 {0, nullptr, "Initialize"}, 199 {0, nullptr, "Initialize"},
@@ -230,7 +230,7 @@ public:
230 230
231class NFC_SYS final : public ServiceFramework<NFC_SYS> { 231class NFC_SYS final : public ServiceFramework<NFC_SYS> {
232public: 232public:
233 explicit NFC_SYS() : ServiceFramework{"nfc:sys"} { 233 explicit NFC_SYS(Core::System& system_) : ServiceFramework{system_, "nfc:sys"} {
234 // clang-format off 234 // clang-format off
235 static const FunctionInfo functions[] = { 235 static const FunctionInfo functions[] = {
236 {0, &NFC_SYS::CreateSystemInterface, "CreateSystemInterface"}, 236 {0, &NFC_SYS::CreateSystemInterface, "CreateSystemInterface"},
@@ -246,15 +246,15 @@ private:
246 246
247 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 247 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
248 rb.Push(RESULT_SUCCESS); 248 rb.Push(RESULT_SUCCESS);
249 rb.PushIpcInterface<ISystem>(); 249 rb.PushIpcInterface<ISystem>(system);
250 } 250 }
251}; 251};
252 252
253void InstallInterfaces(SM::ServiceManager& sm) { 253void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
254 std::make_shared<NFC_AM>()->InstallAsService(sm); 254 std::make_shared<NFC_AM>(system)->InstallAsService(sm);
255 std::make_shared<NFC_MF_U>()->InstallAsService(sm); 255 std::make_shared<NFC_MF_U>(system)->InstallAsService(sm);
256 std::make_shared<NFC_U>()->InstallAsService(sm); 256 std::make_shared<NFC_U>(system)->InstallAsService(sm);
257 std::make_shared<NFC_SYS>()->InstallAsService(sm); 257 std::make_shared<NFC_SYS>(system)->InstallAsService(sm);
258} 258}
259 259
260} // namespace Service::NFC 260} // namespace Service::NFC
diff --git a/src/core/hle/service/nfc/nfc.h b/src/core/hle/service/nfc/nfc.h
index 4d2d815f9..5a94b076d 100644
--- a/src/core/hle/service/nfc/nfc.h
+++ b/src/core/hle/service/nfc/nfc.h
@@ -4,12 +4,16 @@
4 4
5#pragma once 5#pragma once
6 6
7namespace Core {
8class System;
9}
10
7namespace Service::SM { 11namespace Service::SM {
8class ServiceManager; 12class ServiceManager;
9} 13}
10 14
11namespace Service::NFC { 15namespace Service::NFC {
12 16
13void InstallInterfaces(SM::ServiceManager& sm); 17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
14 18
15} // namespace Service::NFC 19} // namespace Service::NFC
diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp
index a0469ffbd..5557da72e 100644
--- a/src/core/hle/service/nfp/nfp.cpp
+++ b/src/core/hle/service/nfp/nfp.cpp
@@ -21,8 +21,9 @@ namespace ErrCodes {
21constexpr ResultCode ERR_NO_APPLICATION_AREA(ErrorModule::NFP, 152); 21constexpr ResultCode ERR_NO_APPLICATION_AREA(ErrorModule::NFP, 152);
22} // namespace ErrCodes 22} // namespace ErrCodes
23 23
24Module::Interface::Interface(std::shared_ptr<Module> module, Core::System& system, const char* name) 24Module::Interface::Interface(std::shared_ptr<Module> module_, Core::System& system_,
25 : ServiceFramework(name), module(std::move(module)), system(system) { 25 const char* name)
26 : ServiceFramework{system_, name}, module{std::move(module_)} {
26 auto& kernel = system.Kernel(); 27 auto& kernel = system.Kernel();
27 nfc_tag_load = Kernel::WritableEvent::CreateEventPair(kernel, "IUser:NFCTagDetected"); 28 nfc_tag_load = Kernel::WritableEvent::CreateEventPair(kernel, "IUser:NFCTagDetected");
28} 29}
@@ -31,8 +32,8 @@ Module::Interface::~Interface() = default;
31 32
32class IUser final : public ServiceFramework<IUser> { 33class IUser final : public ServiceFramework<IUser> {
33public: 34public:
34 IUser(Module::Interface& nfp_interface, Core::System& system) 35 explicit IUser(Module::Interface& nfp_interface_, Core::System& system_)
35 : ServiceFramework("NFP::IUser"), nfp_interface(nfp_interface) { 36 : ServiceFramework{system_, "NFP::IUser"}, nfp_interface{nfp_interface_} {
36 static const FunctionInfo functions[] = { 37 static const FunctionInfo functions[] = {
37 {0, &IUser::Initialize, "Initialize"}, 38 {0, &IUser::Initialize, "Initialize"},
38 {1, &IUser::Finalize, "Finalize"}, 39 {1, &IUser::Finalize, "Finalize"},
diff --git a/src/core/hle/service/nfp/nfp.h b/src/core/hle/service/nfp/nfp.h
index 200013795..295de535b 100644
--- a/src/core/hle/service/nfp/nfp.h
+++ b/src/core/hle/service/nfp/nfp.h
@@ -16,7 +16,8 @@ class Module final {
16public: 16public:
17 class Interface : public ServiceFramework<Interface> { 17 class Interface : public ServiceFramework<Interface> {
18 public: 18 public:
19 explicit Interface(std::shared_ptr<Module> module, Core::System& system, const char* name); 19 explicit Interface(std::shared_ptr<Module> module_, Core::System& system_,
20 const char* name);
20 ~Interface() override; 21 ~Interface() override;
21 22
22 struct ModelInfo { 23 struct ModelInfo {
@@ -43,7 +44,6 @@ public:
43 44
44 protected: 45 protected:
45 std::shared_ptr<Module> module; 46 std::shared_ptr<Module> module;
46 Core::System& system;
47 }; 47 };
48}; 48};
49 49
diff --git a/src/core/hle/service/nfp/nfp_user.cpp b/src/core/hle/service/nfp/nfp_user.cpp
index 298184f17..10b0ef944 100644
--- a/src/core/hle/service/nfp/nfp_user.cpp
+++ b/src/core/hle/service/nfp/nfp_user.cpp
@@ -6,8 +6,8 @@
6 6
7namespace Service::NFP { 7namespace Service::NFP {
8 8
9NFP_User::NFP_User(std::shared_ptr<Module> module, Core::System& system) 9NFP_User::NFP_User(std::shared_ptr<Module> module_, Core::System& system_)
10 : Module::Interface(std::move(module), system, "nfp:user") { 10 : Interface(std::move(module_), system_, "nfp:user") {
11 static const FunctionInfo functions[] = { 11 static const FunctionInfo functions[] = {
12 {0, &NFP_User::CreateUserInterface, "CreateUserInterface"}, 12 {0, &NFP_User::CreateUserInterface, "CreateUserInterface"},
13 }; 13 };
diff --git a/src/core/hle/service/nfp/nfp_user.h b/src/core/hle/service/nfp/nfp_user.h
index 1686ebf20..7f3c124f6 100644
--- a/src/core/hle/service/nfp/nfp_user.h
+++ b/src/core/hle/service/nfp/nfp_user.h
@@ -10,7 +10,7 @@ namespace Service::NFP {
10 10
11class NFP_User final : public Module::Interface { 11class NFP_User final : public Module::Interface {
12public: 12public:
13 explicit NFP_User(std::shared_ptr<Module> module, Core::System& system); 13 explicit NFP_User(std::shared_ptr<Module> module_, Core::System& system_);
14 ~NFP_User() override; 14 ~NFP_User() override;
15}; 15};
16 16
diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp
index db7ec6d0e..ef5176bea 100644
--- a/src/core/hle/service/nifm/nifm.cpp
+++ b/src/core/hle/service/nifm/nifm.cpp
@@ -23,7 +23,7 @@ enum class RequestState : u32 {
23 23
24class IScanRequest final : public ServiceFramework<IScanRequest> { 24class IScanRequest final : public ServiceFramework<IScanRequest> {
25public: 25public:
26 explicit IScanRequest() : ServiceFramework("IScanRequest") { 26 explicit IScanRequest(Core::System& system_) : ServiceFramework{system_, "IScanRequest"} {
27 // clang-format off 27 // clang-format off
28 static const FunctionInfo functions[] = { 28 static const FunctionInfo functions[] = {
29 {0, nullptr, "Submit"}, 29 {0, nullptr, "Submit"},
@@ -40,7 +40,7 @@ public:
40 40
41class IRequest final : public ServiceFramework<IRequest> { 41class IRequest final : public ServiceFramework<IRequest> {
42public: 42public:
43 explicit IRequest(Core::System& system) : ServiceFramework("IRequest") { 43 explicit IRequest(Core::System& system_) : ServiceFramework{system_, "IRequest"} {
44 static const FunctionInfo functions[] = { 44 static const FunctionInfo functions[] = {
45 {0, &IRequest::GetRequestState, "GetRequestState"}, 45 {0, &IRequest::GetRequestState, "GetRequestState"},
46 {1, &IRequest::GetResult, "GetResult"}, 46 {1, &IRequest::GetResult, "GetResult"},
@@ -140,7 +140,7 @@ private:
140 140
141class INetworkProfile final : public ServiceFramework<INetworkProfile> { 141class INetworkProfile final : public ServiceFramework<INetworkProfile> {
142public: 142public:
143 explicit INetworkProfile() : ServiceFramework("INetworkProfile") { 143 explicit INetworkProfile(Core::System& system_) : ServiceFramework{system_, "INetworkProfile"} {
144 static const FunctionInfo functions[] = { 144 static const FunctionInfo functions[] = {
145 {0, nullptr, "Update"}, 145 {0, nullptr, "Update"},
146 {1, nullptr, "PersistOld"}, 146 {1, nullptr, "PersistOld"},
@@ -152,7 +152,7 @@ public:
152 152
153class IGeneralService final : public ServiceFramework<IGeneralService> { 153class IGeneralService final : public ServiceFramework<IGeneralService> {
154public: 154public:
155 IGeneralService(Core::System& system); 155 explicit IGeneralService(Core::System& system_);
156 156
157private: 157private:
158 void GetClientId(Kernel::HLERequestContext& ctx) { 158 void GetClientId(Kernel::HLERequestContext& ctx) {
@@ -169,7 +169,7 @@ private:
169 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 169 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
170 170
171 rb.Push(RESULT_SUCCESS); 171 rb.Push(RESULT_SUCCESS);
172 rb.PushIpcInterface<IScanRequest>(); 172 rb.PushIpcInterface<IScanRequest>(system);
173 } 173 }
174 void CreateRequest(Kernel::HLERequestContext& ctx) { 174 void CreateRequest(Kernel::HLERequestContext& ctx) {
175 LOG_DEBUG(Service_NIFM, "called"); 175 LOG_DEBUG(Service_NIFM, "called");
@@ -207,7 +207,7 @@ private:
207 IPC::ResponseBuilder rb{ctx, 6, 0, 1}; 207 IPC::ResponseBuilder rb{ctx, 6, 0, 1};
208 208
209 rb.Push(RESULT_SUCCESS); 209 rb.Push(RESULT_SUCCESS);
210 rb.PushIpcInterface<INetworkProfile>(); 210 rb.PushIpcInterface<INetworkProfile>(system);
211 rb.PushRaw<u128>(uuid); 211 rb.PushRaw<u128>(uuid);
212 } 212 }
213 void IsWirelessCommunicationEnabled(Kernel::HLERequestContext& ctx) { 213 void IsWirelessCommunicationEnabled(Kernel::HLERequestContext& ctx) {
@@ -239,11 +239,10 @@ private:
239 rb.Push<u8>(1); 239 rb.Push<u8>(1);
240 } 240 }
241 } 241 }
242 Core::System& system;
243}; 242};
244 243
245IGeneralService::IGeneralService(Core::System& system) 244IGeneralService::IGeneralService(Core::System& system_)
246 : ServiceFramework("IGeneralService"), system(system) { 245 : ServiceFramework{system_, "IGeneralService"} {
247 // clang-format off 246 // clang-format off
248 static const FunctionInfo functions[] = { 247 static const FunctionInfo functions[] = {
249 {1, &IGeneralService::GetClientId, "GetClientId"}, 248 {1, &IGeneralService::GetClientId, "GetClientId"},
@@ -296,8 +295,8 @@ IGeneralService::IGeneralService(Core::System& system)
296 295
297class NetworkInterface final : public ServiceFramework<NetworkInterface> { 296class NetworkInterface final : public ServiceFramework<NetworkInterface> {
298public: 297public:
299 explicit NetworkInterface(const char* name, Core::System& system) 298 explicit NetworkInterface(const char* name, Core::System& system_)
300 : ServiceFramework{name}, system(system) { 299 : ServiceFramework{system_, name} {
301 static const FunctionInfo functions[] = { 300 static const FunctionInfo functions[] = {
302 {4, &NetworkInterface::CreateGeneralServiceOld, "CreateGeneralServiceOld"}, 301 {4, &NetworkInterface::CreateGeneralServiceOld, "CreateGeneralServiceOld"},
303 {5, &NetworkInterface::CreateGeneralService, "CreateGeneralService"}, 302 {5, &NetworkInterface::CreateGeneralService, "CreateGeneralService"},
@@ -305,6 +304,7 @@ public:
305 RegisterHandlers(functions); 304 RegisterHandlers(functions);
306 } 305 }
307 306
307private:
308 void CreateGeneralServiceOld(Kernel::HLERequestContext& ctx) { 308 void CreateGeneralServiceOld(Kernel::HLERequestContext& ctx) {
309 LOG_DEBUG(Service_NIFM, "called"); 309 LOG_DEBUG(Service_NIFM, "called");
310 310
@@ -320,9 +320,6 @@ public:
320 rb.Push(RESULT_SUCCESS); 320 rb.Push(RESULT_SUCCESS);
321 rb.PushIpcInterface<IGeneralService>(system); 321 rb.PushIpcInterface<IGeneralService>(system);
322 } 322 }
323
324private:
325 Core::System& system;
326}; 323};
327 324
328void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 325void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
diff --git a/src/core/hle/service/nifm/nifm.h b/src/core/hle/service/nifm/nifm.h
index 6857e18f9..c3dd4f386 100644
--- a/src/core/hle/service/nifm/nifm.h
+++ b/src/core/hle/service/nifm/nifm.h
@@ -4,14 +4,14 @@
4 4
5#pragma once 5#pragma once
6 6
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Core { 7namespace Core {
12class System; 8class System;
13} 9}
14 10
11namespace Service::SM {
12class ServiceManager;
13}
14
15namespace Service::NIFM { 15namespace Service::NIFM {
16 16
17/// Registers all NIFM services with the specified service manager. 17/// Registers all NIFM services with the specified service manager.
diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp
index 11aa74828..d33b26129 100644
--- a/src/core/hle/service/nim/nim.cpp
+++ b/src/core/hle/service/nim/nim.cpp
@@ -17,7 +17,8 @@ namespace Service::NIM {
17 17
18class IShopServiceAsync final : public ServiceFramework<IShopServiceAsync> { 18class IShopServiceAsync final : public ServiceFramework<IShopServiceAsync> {
19public: 19public:
20 IShopServiceAsync() : ServiceFramework("IShopServiceAsync") { 20 explicit IShopServiceAsync(Core::System& system_)
21 : ServiceFramework{system_, "IShopServiceAsync"} {
21 // clang-format off 22 // clang-format off
22 static const FunctionInfo functions[] = { 23 static const FunctionInfo functions[] = {
23 {0, nullptr, "Cancel"}, 24 {0, nullptr, "Cancel"},
@@ -35,7 +36,8 @@ public:
35 36
36class IShopServiceAccessor final : public ServiceFramework<IShopServiceAccessor> { 37class IShopServiceAccessor final : public ServiceFramework<IShopServiceAccessor> {
37public: 38public:
38 IShopServiceAccessor() : ServiceFramework("IShopServiceAccessor") { 39 explicit IShopServiceAccessor(Core::System& system_)
40 : ServiceFramework{system_, "IShopServiceAccessor"} {
39 // clang-format off 41 // clang-format off
40 static const FunctionInfo functions[] = { 42 static const FunctionInfo functions[] = {
41 {0, &IShopServiceAccessor::CreateAsyncInterface, "CreateAsyncInterface"}, 43 {0, &IShopServiceAccessor::CreateAsyncInterface, "CreateAsyncInterface"},
@@ -50,13 +52,14 @@ private:
50 LOG_WARNING(Service_NIM, "(STUBBED) called"); 52 LOG_WARNING(Service_NIM, "(STUBBED) called");
51 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 53 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
52 rb.Push(RESULT_SUCCESS); 54 rb.Push(RESULT_SUCCESS);
53 rb.PushIpcInterface<IShopServiceAsync>(); 55 rb.PushIpcInterface<IShopServiceAsync>(system);
54 } 56 }
55}; 57};
56 58
57class IShopServiceAccessServer final : public ServiceFramework<IShopServiceAccessServer> { 59class IShopServiceAccessServer final : public ServiceFramework<IShopServiceAccessServer> {
58public: 60public:
59 IShopServiceAccessServer() : ServiceFramework("IShopServiceAccessServer") { 61 explicit IShopServiceAccessServer(Core::System& system_)
62 : ServiceFramework{system_, "IShopServiceAccessServer"} {
60 // clang-format off 63 // clang-format off
61 static const FunctionInfo functions[] = { 64 static const FunctionInfo functions[] = {
62 {0, &IShopServiceAccessServer::CreateAccessorInterface, "CreateAccessorInterface"}, 65 {0, &IShopServiceAccessServer::CreateAccessorInterface, "CreateAccessorInterface"},
@@ -71,13 +74,13 @@ private:
71 LOG_WARNING(Service_NIM, "(STUBBED) called"); 74 LOG_WARNING(Service_NIM, "(STUBBED) called");
72 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 75 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
73 rb.Push(RESULT_SUCCESS); 76 rb.Push(RESULT_SUCCESS);
74 rb.PushIpcInterface<IShopServiceAccessor>(); 77 rb.PushIpcInterface<IShopServiceAccessor>(system);
75 } 78 }
76}; 79};
77 80
78class NIM final : public ServiceFramework<NIM> { 81class NIM final : public ServiceFramework<NIM> {
79public: 82public:
80 explicit NIM() : ServiceFramework{"nim"} { 83 explicit NIM(Core::System& system_) : ServiceFramework{system_, "nim"} {
81 // clang-format off 84 // clang-format off
82 static const FunctionInfo functions[] = { 85 static const FunctionInfo functions[] = {
83 {0, nullptr, "CreateSystemUpdateTask"}, 86 {0, nullptr, "CreateSystemUpdateTask"},
@@ -207,7 +210,7 @@ public:
207 210
208class NIM_ECA final : public ServiceFramework<NIM_ECA> { 211class NIM_ECA final : public ServiceFramework<NIM_ECA> {
209public: 212public:
210 explicit NIM_ECA() : ServiceFramework{"nim:eca"} { 213 explicit NIM_ECA(Core::System& system_) : ServiceFramework{system_, "nim:eca"} {
211 // clang-format off 214 // clang-format off
212 static const FunctionInfo functions[] = { 215 static const FunctionInfo functions[] = {
213 {0, &NIM_ECA::CreateServerInterface, "CreateServerInterface"}, 216 {0, &NIM_ECA::CreateServerInterface, "CreateServerInterface"},
@@ -226,13 +229,13 @@ private:
226 LOG_WARNING(Service_NIM, "(STUBBED) called"); 229 LOG_WARNING(Service_NIM, "(STUBBED) called");
227 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 230 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
228 rb.Push(RESULT_SUCCESS); 231 rb.Push(RESULT_SUCCESS);
229 rb.PushIpcInterface<IShopServiceAccessServer>(); 232 rb.PushIpcInterface<IShopServiceAccessServer>(system);
230 } 233 }
231}; 234};
232 235
233class NIM_SHP final : public ServiceFramework<NIM_SHP> { 236class NIM_SHP final : public ServiceFramework<NIM_SHP> {
234public: 237public:
235 explicit NIM_SHP() : ServiceFramework{"nim:shp"} { 238 explicit NIM_SHP(Core::System& system_) : ServiceFramework{system_, "nim:shp"} {
236 // clang-format off 239 // clang-format off
237 static const FunctionInfo functions[] = { 240 static const FunctionInfo functions[] = {
238 {0, nullptr, "RequestDeviceAuthenticationToken"}, 241 {0, nullptr, "RequestDeviceAuthenticationToken"},
@@ -272,8 +275,8 @@ public:
272class IEnsureNetworkClockAvailabilityService final 275class IEnsureNetworkClockAvailabilityService final
273 : public ServiceFramework<IEnsureNetworkClockAvailabilityService> { 276 : public ServiceFramework<IEnsureNetworkClockAvailabilityService> {
274public: 277public:
275 explicit IEnsureNetworkClockAvailabilityService(Core::System& system) 278 explicit IEnsureNetworkClockAvailabilityService(Core::System& system_)
276 : ServiceFramework("IEnsureNetworkClockAvailabilityService") { 279 : ServiceFramework{system_, "IEnsureNetworkClockAvailabilityService"} {
277 static const FunctionInfo functions[] = { 280 static const FunctionInfo functions[] = {
278 {0, &IEnsureNetworkClockAvailabilityService::StartTask, "StartTask"}, 281 {0, &IEnsureNetworkClockAvailabilityService::StartTask, "StartTask"},
279 {1, &IEnsureNetworkClockAvailabilityService::GetFinishNotificationEvent, 282 {1, &IEnsureNetworkClockAvailabilityService::GetFinishNotificationEvent,
@@ -345,7 +348,7 @@ private:
345 348
346class NTC final : public ServiceFramework<NTC> { 349class NTC final : public ServiceFramework<NTC> {
347public: 350public:
348 explicit NTC(Core::System& system) : ServiceFramework{"ntc"}, system(system) { 351 explicit NTC(Core::System& system_) : ServiceFramework{system_, "ntc"} {
349 // clang-format off 352 // clang-format off
350 static const FunctionInfo functions[] = { 353 static const FunctionInfo functions[] = {
351 {0, &NTC::OpenEnsureNetworkClockAvailabilityService, "OpenEnsureNetworkClockAvailabilityService"}, 354 {0, &NTC::OpenEnsureNetworkClockAvailabilityService, "OpenEnsureNetworkClockAvailabilityService"},
@@ -380,13 +383,12 @@ private:
380 IPC::ResponseBuilder rb{ctx, 2}; 383 IPC::ResponseBuilder rb{ctx, 2};
381 rb.Push(RESULT_SUCCESS); 384 rb.Push(RESULT_SUCCESS);
382 } 385 }
383 Core::System& system;
384}; 386};
385 387
386void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 388void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
387 std::make_shared<NIM>()->InstallAsService(sm); 389 std::make_shared<NIM>(system)->InstallAsService(sm);
388 std::make_shared<NIM_ECA>()->InstallAsService(sm); 390 std::make_shared<NIM_ECA>(system)->InstallAsService(sm);
389 std::make_shared<NIM_SHP>()->InstallAsService(sm); 391 std::make_shared<NIM_SHP>(system)->InstallAsService(sm);
390 std::make_shared<NTC>(system)->InstallAsService(sm); 392 std::make_shared<NTC>(system)->InstallAsService(sm);
391} 393}
392 394
diff --git a/src/core/hle/service/nim/nim.h b/src/core/hle/service/nim/nim.h
index dbe25dc01..571153fe6 100644
--- a/src/core/hle/service/nim/nim.h
+++ b/src/core/hle/service/nim/nim.h
@@ -4,14 +4,14 @@
4 4
5#pragma once 5#pragma once
6 6
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Core { 7namespace Core {
12class System; 8class System;
13} 9}
14 10
11namespace Service::SM {
12class ServiceManager;
13}
14
15namespace Service::NIM { 15namespace Service::NIM {
16 16
17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
diff --git a/src/core/hle/service/npns/npns.cpp b/src/core/hle/service/npns/npns.cpp
index 8fa16fb08..f7a58f659 100644
--- a/src/core/hle/service/npns/npns.cpp
+++ b/src/core/hle/service/npns/npns.cpp
@@ -12,7 +12,7 @@ namespace Service::NPNS {
12 12
13class NPNS_S final : public ServiceFramework<NPNS_S> { 13class NPNS_S final : public ServiceFramework<NPNS_S> {
14public: 14public:
15 explicit NPNS_S() : ServiceFramework{"npns:s"} { 15 explicit NPNS_S(Core::System& system_) : ServiceFramework{system_, "npns:s"} {
16 // clang-format off 16 // clang-format off
17 static const FunctionInfo functions[] = { 17 static const FunctionInfo functions[] = {
18 {1, nullptr, "ListenAll"}, 18 {1, nullptr, "ListenAll"},
@@ -62,7 +62,7 @@ public:
62 62
63class NPNS_U final : public ServiceFramework<NPNS_U> { 63class NPNS_U final : public ServiceFramework<NPNS_U> {
64public: 64public:
65 explicit NPNS_U() : ServiceFramework{"npns:u"} { 65 explicit NPNS_U(Core::System& system_) : ServiceFramework{system_, "npns:u"} {
66 // clang-format off 66 // clang-format off
67 static const FunctionInfo functions[] = { 67 static const FunctionInfo functions[] = {
68 {1, nullptr, "ListenAll"}, 68 {1, nullptr, "ListenAll"},
@@ -91,9 +91,9 @@ public:
91 } 91 }
92}; 92};
93 93
94void InstallInterfaces(SM::ServiceManager& sm) { 94void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
95 std::make_shared<NPNS_S>()->InstallAsService(sm); 95 std::make_shared<NPNS_S>(system)->InstallAsService(sm);
96 std::make_shared<NPNS_U>()->InstallAsService(sm); 96 std::make_shared<NPNS_U>(system)->InstallAsService(sm);
97} 97}
98 98
99} // namespace Service::NPNS 99} // namespace Service::NPNS
diff --git a/src/core/hle/service/npns/npns.h b/src/core/hle/service/npns/npns.h
index 861cd3e48..3b7596b6b 100644
--- a/src/core/hle/service/npns/npns.h
+++ b/src/core/hle/service/npns/npns.h
@@ -4,12 +4,16 @@
4 4
5#pragma once 5#pragma once
6 6
7namespace Core {
8class System;
9}
10
7namespace Service::SM { 11namespace Service::SM {
8class ServiceManager; 12class ServiceManager;
9} 13}
10 14
11namespace Service::NPNS { 15namespace Service::NPNS {
12 16
13void InstallInterfaces(SM::ServiceManager& sm); 17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
14 18
15} // namespace Service::NPNS 19} // namespace Service::NPNS
diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp
index 2594e6839..ef7584641 100644
--- a/src/core/hle/service/ns/ns.cpp
+++ b/src/core/hle/service/ns/ns.cpp
@@ -18,7 +18,8 @@
18 18
19namespace Service::NS { 19namespace Service::NS {
20 20
21IAccountProxyInterface::IAccountProxyInterface() : ServiceFramework{"IAccountProxyInterface"} { 21IAccountProxyInterface::IAccountProxyInterface(Core::System& system_)
22 : ServiceFramework{system_, "IAccountProxyInterface"} {
22 // clang-format off 23 // clang-format off
23 static const FunctionInfo functions[] = { 24 static const FunctionInfo functions[] = {
24 {0, nullptr, "CreateUserAccount"}, 25 {0, nullptr, "CreateUserAccount"},
@@ -31,7 +32,7 @@ IAccountProxyInterface::IAccountProxyInterface() : ServiceFramework{"IAccountPro
31IAccountProxyInterface::~IAccountProxyInterface() = default; 32IAccountProxyInterface::~IAccountProxyInterface() = default;
32 33
33IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_) 34IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_)
34 : ServiceFramework{"IApplicationManagerInterface"}, system{system_} { 35 : ServiceFramework{system_, "IApplicationManagerInterface"} {
35 // clang-format off 36 // clang-format off
36 static const FunctionInfo functions[] = { 37 static const FunctionInfo functions[] = {
37 {0, nullptr, "ListApplicationRecord"}, 38 {0, nullptr, "ListApplicationRecord"},
@@ -428,8 +429,8 @@ ResultVal<u64> IApplicationManagerInterface::ConvertApplicationLanguageToLanguag
428 return MakeResult(static_cast<u64>(*language_code)); 429 return MakeResult(static_cast<u64>(*language_code));
429} 430}
430 431
431IApplicationVersionInterface::IApplicationVersionInterface() 432IApplicationVersionInterface::IApplicationVersionInterface(Core::System& system_)
432 : ServiceFramework{"IApplicationVersionInterface"} { 433 : ServiceFramework{system_, "IApplicationVersionInterface"} {
433 // clang-format off 434 // clang-format off
434 static const FunctionInfo functions[] = { 435 static const FunctionInfo functions[] = {
435 {0, nullptr, "GetLaunchRequiredVersion"}, 436 {0, nullptr, "GetLaunchRequiredVersion"},
@@ -449,8 +450,8 @@ IApplicationVersionInterface::IApplicationVersionInterface()
449 450
450IApplicationVersionInterface::~IApplicationVersionInterface() = default; 451IApplicationVersionInterface::~IApplicationVersionInterface() = default;
451 452
452IContentManagementInterface::IContentManagementInterface() 453IContentManagementInterface::IContentManagementInterface(Core::System& system_)
453 : ServiceFramework{"IContentManagementInterface"} { 454 : ServiceFramework{system_, "IContentManagementInterface"} {
454 // clang-format off 455 // clang-format off
455 static const FunctionInfo functions[] = { 456 static const FunctionInfo functions[] = {
456 {11, nullptr, "CalculateApplicationOccupiedSize"}, 457 {11, nullptr, "CalculateApplicationOccupiedSize"},
@@ -469,7 +470,8 @@ IContentManagementInterface::IContentManagementInterface()
469 470
470IContentManagementInterface::~IContentManagementInterface() = default; 471IContentManagementInterface::~IContentManagementInterface() = default;
471 472
472IDocumentInterface::IDocumentInterface() : ServiceFramework{"IDocumentInterface"} { 473IDocumentInterface::IDocumentInterface(Core::System& system_)
474 : ServiceFramework{system_, "IDocumentInterface"} {
473 // clang-format off 475 // clang-format off
474 static const FunctionInfo functions[] = { 476 static const FunctionInfo functions[] = {
475 {21, nullptr, "GetApplicationContentPath"}, 477 {21, nullptr, "GetApplicationContentPath"},
@@ -483,7 +485,8 @@ IDocumentInterface::IDocumentInterface() : ServiceFramework{"IDocumentInterface"
483 485
484IDocumentInterface::~IDocumentInterface() = default; 486IDocumentInterface::~IDocumentInterface() = default;
485 487
486IDownloadTaskInterface::IDownloadTaskInterface() : ServiceFramework{"IDownloadTaskInterface"} { 488IDownloadTaskInterface::IDownloadTaskInterface(Core::System& system_)
489 : ServiceFramework{system_, "IDownloadTaskInterface"} {
487 // clang-format off 490 // clang-format off
488 static const FunctionInfo functions[] = { 491 static const FunctionInfo functions[] = {
489 {701, nullptr, "ClearTaskStatusList"}, 492 {701, nullptr, "ClearTaskStatusList"},
@@ -503,7 +506,8 @@ IDownloadTaskInterface::IDownloadTaskInterface() : ServiceFramework{"IDownloadTa
503 506
504IDownloadTaskInterface::~IDownloadTaskInterface() = default; 507IDownloadTaskInterface::~IDownloadTaskInterface() = default;
505 508
506IECommerceInterface::IECommerceInterface() : ServiceFramework{"IECommerceInterface"} { 509IECommerceInterface::IECommerceInterface(Core::System& system_)
510 : ServiceFramework{system_, "IECommerceInterface"} {
507 // clang-format off 511 // clang-format off
508 static const FunctionInfo functions[] = { 512 static const FunctionInfo functions[] = {
509 {0, nullptr, "RequestLinkDevice"}, 513 {0, nullptr, "RequestLinkDevice"},
@@ -521,8 +525,8 @@ IECommerceInterface::IECommerceInterface() : ServiceFramework{"IECommerceInterfa
521 525
522IECommerceInterface::~IECommerceInterface() = default; 526IECommerceInterface::~IECommerceInterface() = default;
523 527
524IFactoryResetInterface::IFactoryResetInterface::IFactoryResetInterface() 528IFactoryResetInterface::IFactoryResetInterface(Core::System& system_)
525 : ServiceFramework{"IFactoryResetInterface"} { 529 : ServiceFramework{system_, "IFactoryResetInterface"} {
526 // clang-format off 530 // clang-format off
527 static const FunctionInfo functions[] = { 531 static const FunctionInfo functions[] = {
528 {100, nullptr, "ResetToFactorySettings"}, 532 {100, nullptr, "ResetToFactorySettings"},
@@ -540,7 +544,7 @@ IFactoryResetInterface::IFactoryResetInterface::IFactoryResetInterface()
540 544
541IFactoryResetInterface::~IFactoryResetInterface() = default; 545IFactoryResetInterface::~IFactoryResetInterface() = default;
542 546
543NS::NS(const char* name, Core::System& system_) : ServiceFramework{name}, system{system_} { 547NS::NS(const char* name, Core::System& system_) : ServiceFramework{system_, name} {
544 // clang-format off 548 // clang-format off
545 static const FunctionInfo functions[] = { 549 static const FunctionInfo functions[] = {
546 {7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"}, 550 {7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"},
@@ -565,7 +569,7 @@ std::shared_ptr<IApplicationManagerInterface> NS::GetApplicationManagerInterface
565 569
566class NS_DEV final : public ServiceFramework<NS_DEV> { 570class NS_DEV final : public ServiceFramework<NS_DEV> {
567public: 571public:
568 explicit NS_DEV() : ServiceFramework{"ns:dev"} { 572 explicit NS_DEV(Core::System& system_) : ServiceFramework{system_, "ns:dev"} {
569 // clang-format off 573 // clang-format off
570 static const FunctionInfo functions[] = { 574 static const FunctionInfo functions[] = {
571 {0, nullptr, "LaunchProgram"}, 575 {0, nullptr, "LaunchProgram"},
@@ -592,7 +596,8 @@ public:
592 596
593class ISystemUpdateControl final : public ServiceFramework<ISystemUpdateControl> { 597class ISystemUpdateControl final : public ServiceFramework<ISystemUpdateControl> {
594public: 598public:
595 explicit ISystemUpdateControl() : ServiceFramework{"ISystemUpdateControl"} { 599 explicit ISystemUpdateControl(Core::System& system_)
600 : ServiceFramework{system_, "ISystemUpdateControl"} {
596 // clang-format off 601 // clang-format off
597 static const FunctionInfo functions[] = { 602 static const FunctionInfo functions[] = {
598 {0, nullptr, "HasDownloaded"}, 603 {0, nullptr, "HasDownloaded"},
@@ -627,7 +632,7 @@ public:
627 632
628class NS_SU final : public ServiceFramework<NS_SU> { 633class NS_SU final : public ServiceFramework<NS_SU> {
629public: 634public:
630 explicit NS_SU() : ServiceFramework{"ns:su"} { 635 explicit NS_SU(Core::System& system_) : ServiceFramework{system_, "ns:su"} {
631 // clang-format off 636 // clang-format off
632 static const FunctionInfo functions[] = { 637 static const FunctionInfo functions[] = {
633 {0, nullptr, "GetBackgroundNetworkUpdateState"}, 638 {0, nullptr, "GetBackgroundNetworkUpdateState"},
@@ -659,13 +664,13 @@ private:
659 664
660 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 665 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
661 rb.Push(RESULT_SUCCESS); 666 rb.Push(RESULT_SUCCESS);
662 rb.PushIpcInterface<ISystemUpdateControl>(); 667 rb.PushIpcInterface<ISystemUpdateControl>(system);
663 } 668 }
664}; 669};
665 670
666class NS_VM final : public ServiceFramework<NS_VM> { 671class NS_VM final : public ServiceFramework<NS_VM> {
667public: 672public:
668 explicit NS_VM() : ServiceFramework{"ns:vm"} { 673 explicit NS_VM(Core::System& system_) : ServiceFramework{system_, "ns:vm"} {
669 // clang-format off 674 // clang-format off
670 static const FunctionInfo functions[] = { 675 static const FunctionInfo functions[] = {
671 {1200, nullptr, "NeedsUpdateVulnerability"}, 676 {1200, nullptr, "NeedsUpdateVulnerability"},
@@ -686,9 +691,9 @@ void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system
686 std::make_shared<NS>("ns:rt", system)->InstallAsService(service_manager); 691 std::make_shared<NS>("ns:rt", system)->InstallAsService(service_manager);
687 std::make_shared<NS>("ns:web", system)->InstallAsService(service_manager); 692 std::make_shared<NS>("ns:web", system)->InstallAsService(service_manager);
688 693
689 std::make_shared<NS_DEV>()->InstallAsService(service_manager); 694 std::make_shared<NS_DEV>(system)->InstallAsService(service_manager);
690 std::make_shared<NS_SU>()->InstallAsService(service_manager); 695 std::make_shared<NS_SU>(system)->InstallAsService(service_manager);
691 std::make_shared<NS_VM>()->InstallAsService(service_manager); 696 std::make_shared<NS_VM>(system)->InstallAsService(service_manager);
692 697
693 std::make_shared<PL_U>(system)->InstallAsService(service_manager); 698 std::make_shared<PL_U>(system)->InstallAsService(service_manager);
694} 699}
diff --git a/src/core/hle/service/ns/ns.h b/src/core/hle/service/ns/ns.h
index c90ccd755..991271f3e 100644
--- a/src/core/hle/service/ns/ns.h
+++ b/src/core/hle/service/ns/ns.h
@@ -20,7 +20,7 @@ namespace NS {
20 20
21class IAccountProxyInterface final : public ServiceFramework<IAccountProxyInterface> { 21class IAccountProxyInterface final : public ServiceFramework<IAccountProxyInterface> {
22public: 22public:
23 explicit IAccountProxyInterface(); 23 explicit IAccountProxyInterface(Core::System& system_);
24 ~IAccountProxyInterface() override; 24 ~IAccountProxyInterface() override;
25}; 25};
26 26
@@ -36,43 +36,41 @@ private:
36 void GetApplicationControlData(Kernel::HLERequestContext& ctx); 36 void GetApplicationControlData(Kernel::HLERequestContext& ctx);
37 void GetApplicationDesiredLanguage(Kernel::HLERequestContext& ctx); 37 void GetApplicationDesiredLanguage(Kernel::HLERequestContext& ctx);
38 void ConvertApplicationLanguageToLanguageCode(Kernel::HLERequestContext& ctx); 38 void ConvertApplicationLanguageToLanguageCode(Kernel::HLERequestContext& ctx);
39
40 Core::System& system;
41}; 39};
42 40
43class IApplicationVersionInterface final : public ServiceFramework<IApplicationVersionInterface> { 41class IApplicationVersionInterface final : public ServiceFramework<IApplicationVersionInterface> {
44public: 42public:
45 explicit IApplicationVersionInterface(); 43 explicit IApplicationVersionInterface(Core::System& system_);
46 ~IApplicationVersionInterface() override; 44 ~IApplicationVersionInterface() override;
47}; 45};
48 46
49class IContentManagementInterface final : public ServiceFramework<IContentManagementInterface> { 47class IContentManagementInterface final : public ServiceFramework<IContentManagementInterface> {
50public: 48public:
51 explicit IContentManagementInterface(); 49 explicit IContentManagementInterface(Core::System& system_);
52 ~IContentManagementInterface() override; 50 ~IContentManagementInterface() override;
53}; 51};
54 52
55class IDocumentInterface final : public ServiceFramework<IDocumentInterface> { 53class IDocumentInterface final : public ServiceFramework<IDocumentInterface> {
56public: 54public:
57 explicit IDocumentInterface(); 55 explicit IDocumentInterface(Core::System& system_);
58 ~IDocumentInterface() override; 56 ~IDocumentInterface() override;
59}; 57};
60 58
61class IDownloadTaskInterface final : public ServiceFramework<IDownloadTaskInterface> { 59class IDownloadTaskInterface final : public ServiceFramework<IDownloadTaskInterface> {
62public: 60public:
63 explicit IDownloadTaskInterface(); 61 explicit IDownloadTaskInterface(Core::System& system_);
64 ~IDownloadTaskInterface() override; 62 ~IDownloadTaskInterface() override;
65}; 63};
66 64
67class IECommerceInterface final : public ServiceFramework<IECommerceInterface> { 65class IECommerceInterface final : public ServiceFramework<IECommerceInterface> {
68public: 66public:
69 explicit IECommerceInterface(); 67 explicit IECommerceInterface(Core::System& system_);
70 ~IECommerceInterface() override; 68 ~IECommerceInterface() override;
71}; 69};
72 70
73class IFactoryResetInterface final : public ServiceFramework<IFactoryResetInterface> { 71class IFactoryResetInterface final : public ServiceFramework<IFactoryResetInterface> {
74public: 72public:
75 explicit IFactoryResetInterface(); 73 explicit IFactoryResetInterface(Core::System& system_);
76 ~IFactoryResetInterface() override; 74 ~IFactoryResetInterface() override;
77}; 75};
78 76
@@ -90,7 +88,7 @@ private:
90 88
91 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 89 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
92 rb.Push(RESULT_SUCCESS); 90 rb.Push(RESULT_SUCCESS);
93 rb.PushIpcInterface<T>(); 91 rb.PushIpcInterface<T>(system);
94 } 92 }
95 93
96 void PushIApplicationManagerInterface(Kernel::HLERequestContext& ctx) { 94 void PushIApplicationManagerInterface(Kernel::HLERequestContext& ctx) {
@@ -108,8 +106,6 @@ private:
108 106
109 return std::make_shared<T>(std::forward<Args>(args)...); 107 return std::make_shared<T>(std::forward<Args>(args)...);
110 } 108 }
111
112 Core::System& system;
113}; 109};
114 110
115/// Registers all NS services with the specified service manager. 111/// Registers all NS services with the specified service manager.
diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp
index 5ccec2637..ccc137e40 100644
--- a/src/core/hle/service/ns/pl_u.cpp
+++ b/src/core/hle/service/ns/pl_u.cpp
@@ -141,8 +141,8 @@ struct PL_U::Impl {
141 std::vector<FontRegion> shared_font_regions; 141 std::vector<FontRegion> shared_font_regions;
142}; 142};
143 143
144PL_U::PL_U(Core::System& system) 144PL_U::PL_U(Core::System& system_)
145 : ServiceFramework("pl:u"), impl{std::make_unique<Impl>()}, system(system) { 145 : ServiceFramework{system_, "pl:u"}, impl{std::make_unique<Impl>()} {
146 // clang-format off 146 // clang-format off
147 static const FunctionInfo functions[] = { 147 static const FunctionInfo functions[] = {
148 {0, &PL_U::RequestLoad, "RequestLoad"}, 148 {0, &PL_U::RequestLoad, "RequestLoad"},
diff --git a/src/core/hle/service/ns/pl_u.h b/src/core/hle/service/ns/pl_u.h
index 27161bd7a..224dcb997 100644
--- a/src/core/hle/service/ns/pl_u.h
+++ b/src/core/hle/service/ns/pl_u.h
@@ -20,7 +20,7 @@ void EncryptSharedFont(const std::vector<u32>& input, std::vector<u8>& output, s
20 20
21class PL_U final : public ServiceFramework<PL_U> { 21class PL_U final : public ServiceFramework<PL_U> {
22public: 22public:
23 explicit PL_U(Core::System& system); 23 explicit PL_U(Core::System& system_);
24 ~PL_U() override; 24 ~PL_U() override;
25 25
26private: 26private:
@@ -33,7 +33,6 @@ private:
33 33
34 struct Impl; 34 struct Impl;
35 std::unique_ptr<Impl> impl; 35 std::unique_ptr<Impl> impl;
36 Core::System& system;
37}; 36};
38 37
39} // namespace NS 38} // namespace NS
diff --git a/src/core/hle/service/nvdrv/devices/nvdevice.h b/src/core/hle/service/nvdrv/devices/nvdevice.h
index 5681599ba..44a8bc060 100644
--- a/src/core/hle/service/nvdrv/devices/nvdevice.h
+++ b/src/core/hle/service/nvdrv/devices/nvdevice.h
@@ -31,8 +31,8 @@ public:
31 * @param output A buffer where the output data will be written to. 31 * @param output A buffer where the output data will be written to.
32 * @returns The result code of the ioctl. 32 * @returns The result code of the ioctl.
33 */ 33 */
34 virtual NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, 34 virtual NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
35 std::vector<u8>& output) = 0; 35 IoctlCtrl& ctrl) = 0;
36 36
37 /** 37 /**
38 * Handles an ioctl2 request. 38 * Handles an ioctl2 request.
@@ -43,7 +43,8 @@ public:
43 * @returns The result code of the ioctl. 43 * @returns The result code of the ioctl.
44 */ 44 */
45 virtual NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, 45 virtual NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
46 const std::vector<u8>& inline_input, std::vector<u8>& output) = 0; 46 const std::vector<u8>& inline_input, std::vector<u8>& output,
47 IoctlCtrl& ctrl) = 0;
47 48
48 /** 49 /**
49 * Handles an ioctl3 request. 50 * Handles an ioctl3 request.
@@ -54,7 +55,7 @@ public:
54 * @returns The result code of the ioctl. 55 * @returns The result code of the ioctl.
55 */ 56 */
56 virtual NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 57 virtual NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
57 std::vector<u8>& inline_output) = 0; 58 std::vector<u8>& inline_output, IoctlCtrl& ctrl) = 0;
58 59
59protected: 60protected:
60 Core::System& system; 61 Core::System& system;
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
index ce615c758..170a7c9a0 100644
--- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
@@ -18,20 +18,21 @@ nvdisp_disp0::nvdisp_disp0(Core::System& system, std::shared_ptr<nvmap> nvmap_de
18 : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {} 18 : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {}
19nvdisp_disp0 ::~nvdisp_disp0() = default; 19nvdisp_disp0 ::~nvdisp_disp0() = default;
20 20
21NvResult nvdisp_disp0::Ioctl1(Ioctl command, const std::vector<u8>& input, 21NvResult nvdisp_disp0::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
22 std::vector<u8>& output) { 22 IoctlCtrl& ctrl) {
23 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 23 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
24 return NvResult::NotImplemented; 24 return NvResult::NotImplemented;
25} 25}
26 26
27NvResult nvdisp_disp0::Ioctl2(Ioctl command, const std::vector<u8>& input, 27NvResult nvdisp_disp0::Ioctl2(Ioctl command, const std::vector<u8>& input,
28 const std::vector<u8>& inline_input, std::vector<u8>& output) { 28 const std::vector<u8>& inline_input, std::vector<u8>& output,
29 IoctlCtrl& ctrl) {
29 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 30 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
30 return NvResult::NotImplemented; 31 return NvResult::NotImplemented;
31} 32}
32 33
33NvResult nvdisp_disp0::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 34NvResult nvdisp_disp0::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
34 std::vector<u8>& inline_output) { 35 std::vector<u8>& inline_output, IoctlCtrl& ctrl) {
35 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 36 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
36 return NvResult::NotImplemented; 37 return NvResult::NotImplemented;
37} 38}
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h
index 55a33b7e4..eb7575e40 100644
--- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h
+++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h
@@ -20,11 +20,13 @@ public:
20 explicit nvdisp_disp0(Core::System& system, std::shared_ptr<nvmap> nvmap_dev); 20 explicit nvdisp_disp0(Core::System& system, std::shared_ptr<nvmap> nvmap_dev);
21 ~nvdisp_disp0() override; 21 ~nvdisp_disp0() override;
22 22
23 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; 23 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
24 IoctlCtrl& ctrl) override;
24 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, 25 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
25 const std::vector<u8>& inline_input, std::vector<u8>& output) override; 26 const std::vector<u8>& inline_input, std::vector<u8>& output,
27 IoctlCtrl& ctrl) override;
26 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 28 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
27 std::vector<u8>& inline_output) override; 29 std::vector<u8>& inline_output, IoctlCtrl& ctrl) override;
28 30
29 /// Performs a screen flip, drawing the buffer pointed to by the handle. 31 /// Performs a screen flip, drawing the buffer pointed to by the handle.
30 void flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, u32 stride, 32 void flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, u32 stride,
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
index 6b062e10e..4e0652c39 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
@@ -21,8 +21,8 @@ nvhost_as_gpu::nvhost_as_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_
21 : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {} 21 : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {}
22nvhost_as_gpu::~nvhost_as_gpu() = default; 22nvhost_as_gpu::~nvhost_as_gpu() = default;
23 23
24NvResult nvhost_as_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input, 24NvResult nvhost_as_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
25 std::vector<u8>& output) { 25 IoctlCtrl& ctrl) {
26 switch (command.group) { 26 switch (command.group) {
27 case 'A': 27 case 'A':
28 switch (command.cmd) { 28 switch (command.cmd) {
@@ -55,13 +55,14 @@ NvResult nvhost_as_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input,
55} 55}
56 56
57NvResult nvhost_as_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input, 57NvResult nvhost_as_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input,
58 const std::vector<u8>& inline_input, std::vector<u8>& output) { 58 const std::vector<u8>& inline_input, std::vector<u8>& output,
59 IoctlCtrl& ctrl) {
59 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 60 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
60 return NvResult::NotImplemented; 61 return NvResult::NotImplemented;
61} 62}
62 63
63NvResult nvhost_as_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 64NvResult nvhost_as_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
64 std::vector<u8>& inline_output) { 65 std::vector<u8>& inline_output, IoctlCtrl& ctrl) {
65 switch (command.group) { 66 switch (command.group) {
66 case 'A': 67 case 'A':
67 switch (command.cmd) { 68 switch (command.cmd) {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h
index 08035fa0e..2bd355af9 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h
@@ -30,11 +30,13 @@ public:
30 explicit nvhost_as_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev); 30 explicit nvhost_as_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev);
31 ~nvhost_as_gpu() override; 31 ~nvhost_as_gpu() override;
32 32
33 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; 33 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
34 IoctlCtrl& ctrl) override;
34 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, 35 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
35 const std::vector<u8>& inline_input, std::vector<u8>& output) override; 36 const std::vector<u8>& inline_input, std::vector<u8>& output,
37 IoctlCtrl& ctrl) override;
36 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 38 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
37 std::vector<u8>& inline_output) override; 39 std::vector<u8>& inline_output, IoctlCtrl& ctrl) override;
38 40
39private: 41private:
40 class BufferMap final { 42 class BufferMap final {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index d90cf90a8..92d31b620 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -20,7 +20,8 @@ nvhost_ctrl::nvhost_ctrl(Core::System& system, EventInterface& events_interface,
20 : nvdevice(system), events_interface{events_interface}, syncpoint_manager{syncpoint_manager} {} 20 : nvdevice(system), events_interface{events_interface}, syncpoint_manager{syncpoint_manager} {}
21nvhost_ctrl::~nvhost_ctrl() = default; 21nvhost_ctrl::~nvhost_ctrl() = default;
22 22
23NvResult nvhost_ctrl::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { 23NvResult nvhost_ctrl::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
24 IoctlCtrl& ctrl) {
24 switch (command.group) { 25 switch (command.group) {
25 case 0x0: 26 case 0x0:
26 switch (command.cmd) { 27 switch (command.cmd) {
@@ -29,9 +30,9 @@ NvResult nvhost_ctrl::Ioctl1(Ioctl command, const std::vector<u8>& input, std::v
29 case 0x1c: 30 case 0x1c:
30 return IocCtrlClearEventWait(input, output); 31 return IocCtrlClearEventWait(input, output);
31 case 0x1d: 32 case 0x1d:
32 return IocCtrlEventWait(input, output, false); 33 return IocCtrlEventWait(input, output, false, ctrl);
33 case 0x1e: 34 case 0x1e:
34 return IocCtrlEventWait(input, output, true); 35 return IocCtrlEventWait(input, output, true, ctrl);
35 case 0x1f: 36 case 0x1f:
36 return IocCtrlEventRegister(input, output); 37 return IocCtrlEventRegister(input, output);
37 case 0x20: 38 case 0x20:
@@ -47,13 +48,14 @@ NvResult nvhost_ctrl::Ioctl1(Ioctl command, const std::vector<u8>& input, std::v
47} 48}
48 49
49NvResult nvhost_ctrl::Ioctl2(Ioctl command, const std::vector<u8>& input, 50NvResult nvhost_ctrl::Ioctl2(Ioctl command, const std::vector<u8>& input,
50 const std::vector<u8>& inline_input, std::vector<u8>& output) { 51 const std::vector<u8>& inline_input, std::vector<u8>& output,
52 IoctlCtrl& ctrl) {
51 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 53 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
52 return NvResult::NotImplemented; 54 return NvResult::NotImplemented;
53} 55}
54 56
55NvResult nvhost_ctrl::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 57NvResult nvhost_ctrl::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
56 std::vector<u8>& inline_output) { 58 std::vector<u8>& inline_output, IoctlCtrl& ctrl) {
57 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 59 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
58 return NvResult::NotImplemented; 60 return NvResult::NotImplemented;
59} 61}
@@ -67,7 +69,7 @@ NvResult nvhost_ctrl::NvOsGetConfigU32(const std::vector<u8>& input, std::vector
67} 69}
68 70
69NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output, 71NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output,
70 bool is_async) { 72 bool is_async, IoctlCtrl& ctrl) {
71 IocCtrlEventWaitParams params{}; 73 IocCtrlEventWaitParams params{};
72 std::memcpy(&params, input.data(), sizeof(params)); 74 std::memcpy(&params, input.data(), sizeof(params));
73 LOG_DEBUG(Service_NVDRV, "syncpt_id={}, threshold={}, timeout={}, is_async={}", 75 LOG_DEBUG(Service_NVDRV, "syncpt_id={}, threshold={}, timeout={}, is_async={}",
@@ -139,7 +141,10 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
139 params.value |= event_id; 141 params.value |= event_id;
140 event.event.writable->Clear(); 142 event.event.writable->Clear();
141 gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value); 143 gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value);
142 if (!is_async) { 144 if (!is_async && ctrl.fresh_call) {
145 ctrl.must_delay = true;
146 ctrl.timeout = params.timeout;
147 ctrl.event_id = event_id;
143 return NvResult::Timeout; 148 return NvResult::Timeout;
144 } 149 }
145 std::memcpy(output.data(), &params, sizeof(params)); 150 std::memcpy(output.data(), &params, sizeof(params));
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
index c5aa1362a..107168e21 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
@@ -18,11 +18,13 @@ public:
18 SyncpointManager& syncpoint_manager); 18 SyncpointManager& syncpoint_manager);
19 ~nvhost_ctrl() override; 19 ~nvhost_ctrl() override;
20 20
21 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; 21 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
22 IoctlCtrl& ctrl) override;
22 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, 23 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
23 const std::vector<u8>& inline_input, std::vector<u8>& output) override; 24 const std::vector<u8>& inline_input, std::vector<u8>& output,
25 IoctlCtrl& ctrl) override;
24 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 26 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
25 std::vector<u8>& inline_output) override; 27 std::vector<u8>& inline_output, IoctlCtrl& ctrl) override;
26 28
27private: 29private:
28 struct IocSyncptReadParams { 30 struct IocSyncptReadParams {
@@ -121,7 +123,8 @@ private:
121 static_assert(sizeof(IocCtrlEventKill) == 8, "IocCtrlEventKill is incorrect size"); 123 static_assert(sizeof(IocCtrlEventKill) == 8, "IocCtrlEventKill is incorrect size");
122 124
123 NvResult NvOsGetConfigU32(const std::vector<u8>& input, std::vector<u8>& output); 125 NvResult NvOsGetConfigU32(const std::vector<u8>& input, std::vector<u8>& output);
124 NvResult IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output, bool is_async); 126 NvResult IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output, bool is_async,
127 IoctlCtrl& ctrl);
125 NvResult IocCtrlEventRegister(const std::vector<u8>& input, std::vector<u8>& output); 128 NvResult IocCtrlEventRegister(const std::vector<u8>& input, std::vector<u8>& output);
126 NvResult IocCtrlEventUnregister(const std::vector<u8>& input, std::vector<u8>& output); 129 NvResult IocCtrlEventUnregister(const std::vector<u8>& input, std::vector<u8>& output);
127 NvResult IocCtrlClearEventWait(const std::vector<u8>& input, std::vector<u8>& output); 130 NvResult IocCtrlClearEventWait(const std::vector<u8>& input, std::vector<u8>& output);
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
index 2d7ea433c..647f5907e 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
@@ -16,7 +16,7 @@ nvhost_ctrl_gpu::nvhost_ctrl_gpu(Core::System& system) : nvdevice(system) {}
16nvhost_ctrl_gpu::~nvhost_ctrl_gpu() = default; 16nvhost_ctrl_gpu::~nvhost_ctrl_gpu() = default;
17 17
18NvResult nvhost_ctrl_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input, 18NvResult nvhost_ctrl_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input,
19 std::vector<u8>& output) { 19 std::vector<u8>& output, IoctlCtrl& ctrl) {
20 switch (command.group) { 20 switch (command.group) {
21 case 'G': 21 case 'G':
22 switch (command.cmd) { 22 switch (command.cmd) {
@@ -48,13 +48,15 @@ NvResult nvhost_ctrl_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input,
48} 48}
49 49
50NvResult nvhost_ctrl_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input, 50NvResult nvhost_ctrl_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input,
51 const std::vector<u8>& inline_input, std::vector<u8>& output) { 51 const std::vector<u8>& inline_input, std::vector<u8>& output,
52 IoctlCtrl& ctrl) {
52 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 53 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
53 return NvResult::NotImplemented; 54 return NvResult::NotImplemented;
54} 55}
55 56
56NvResult nvhost_ctrl_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input, 57NvResult nvhost_ctrl_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input,
57 std::vector<u8>& output, std::vector<u8>& inline_output) { 58 std::vector<u8>& output, std::vector<u8>& inline_output,
59 IoctlCtrl& ctrl) {
58 switch (command.group) { 60 switch (command.group) {
59 case 'G': 61 case 'G':
60 switch (command.cmd) { 62 switch (command.cmd) {
@@ -162,7 +164,7 @@ NvResult nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, std::
162 params.gpu_characteristics_buf_size = 0xA0; 164 params.gpu_characteristics_buf_size = 0xA0;
163 params.gpu_characteristics_buf_addr = 0xdeadbeef; // Cannot be 0 (UNUSED) 165 params.gpu_characteristics_buf_addr = 0xdeadbeef; // Cannot be 0 (UNUSED)
164 166
165 std::memcpy(output.data(), input.data(), output.size()); 167 std::memcpy(output.data(), &params, output.size());
166 std::memcpy(inline_output.data(), &params.gc, inline_output.size()); 168 std::memcpy(inline_output.data(), &params.gc, inline_output.size());
167 return NvResult::Success; 169 return NvResult::Success;
168} 170}
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h
index 137b88238..c2fffe734 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h
@@ -16,11 +16,13 @@ public:
16 explicit nvhost_ctrl_gpu(Core::System& system); 16 explicit nvhost_ctrl_gpu(Core::System& system);
17 ~nvhost_ctrl_gpu() override; 17 ~nvhost_ctrl_gpu() override;
18 18
19 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; 19 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
20 IoctlCtrl& ctrl) override;
20 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, 21 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
21 const std::vector<u8>& inline_input, std::vector<u8>& output) override; 22 const std::vector<u8>& inline_input, std::vector<u8>& output,
23 IoctlCtrl& ctrl) override;
22 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 24 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
23 std::vector<u8>& inline_output) override; 25 std::vector<u8>& inline_output, IoctlCtrl& ctrl) override;
24 26
25private: 27private:
26 struct IoctlGpuCharacteristics { 28 struct IoctlGpuCharacteristics {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
index af8b3d9f1..b0c2caba5 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
@@ -23,7 +23,8 @@ nvhost_gpu::nvhost_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev,
23 23
24nvhost_gpu::~nvhost_gpu() = default; 24nvhost_gpu::~nvhost_gpu() = default;
25 25
26NvResult nvhost_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { 26NvResult nvhost_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
27 IoctlCtrl& ctrl) {
27 switch (command.group) { 28 switch (command.group) {
28 case 0x0: 29 case 0x0:
29 switch (command.cmd) { 30 switch (command.cmd) {
@@ -75,7 +76,8 @@ NvResult nvhost_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input, std::ve
75}; 76};
76 77
77NvResult nvhost_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input, 78NvResult nvhost_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input,
78 const std::vector<u8>& inline_input, std::vector<u8>& output) { 79 const std::vector<u8>& inline_input, std::vector<u8>& output,
80 IoctlCtrl& ctrl) {
79 switch (command.group) { 81 switch (command.group) {
80 case 'H': 82 case 'H':
81 switch (command.cmd) { 83 switch (command.cmd) {
@@ -89,7 +91,7 @@ NvResult nvhost_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input,
89} 91}
90 92
91NvResult nvhost_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 93NvResult nvhost_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
92 std::vector<u8>& inline_output) { 94 std::vector<u8>& inline_output, IoctlCtrl& ctrl) {
93 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 95 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
94 return NvResult::NotImplemented; 96 return NvResult::NotImplemented;
95} 97}
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
index e0298b4fe..aa0048a9d 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
@@ -26,11 +26,13 @@ public:
26 SyncpointManager& syncpoint_manager); 26 SyncpointManager& syncpoint_manager);
27 ~nvhost_gpu() override; 27 ~nvhost_gpu() override;
28 28
29 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; 29 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
30 IoctlCtrl& ctrl) override;
30 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, 31 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
31 const std::vector<u8>& inline_input, std::vector<u8>& output) override; 32 const std::vector<u8>& inline_input, std::vector<u8>& output,
33 IoctlCtrl& ctrl) override;
32 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 34 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
33 std::vector<u8>& inline_output) override; 35 std::vector<u8>& inline_output, IoctlCtrl& ctrl) override;
34 36
35private: 37private:
36 enum class CtxObjects : u32_le { 38 enum class CtxObjects : u32_le {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
index d8735491c..b8328c314 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
@@ -15,8 +15,8 @@ nvhost_nvdec::nvhost_nvdec(Core::System& system, std::shared_ptr<nvmap> nvmap_de
15 : nvhost_nvdec_common(system, std::move(nvmap_dev)) {} 15 : nvhost_nvdec_common(system, std::move(nvmap_dev)) {}
16nvhost_nvdec::~nvhost_nvdec() = default; 16nvhost_nvdec::~nvhost_nvdec() = default;
17 17
18NvResult nvhost_nvdec::Ioctl1(Ioctl command, const std::vector<u8>& input, 18NvResult nvhost_nvdec::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
19 std::vector<u8>& output) { 19 IoctlCtrl& ctrl) {
20 switch (command.group) { 20 switch (command.group) {
21 case 0x0: 21 case 0x0:
22 switch (command.cmd) { 22 switch (command.cmd) {
@@ -58,13 +58,14 @@ NvResult nvhost_nvdec::Ioctl1(Ioctl command, const std::vector<u8>& input,
58} 58}
59 59
60NvResult nvhost_nvdec::Ioctl2(Ioctl command, const std::vector<u8>& input, 60NvResult nvhost_nvdec::Ioctl2(Ioctl command, const std::vector<u8>& input,
61 const std::vector<u8>& inline_input, std::vector<u8>& output) { 61 const std::vector<u8>& inline_input, std::vector<u8>& output,
62 IoctlCtrl& ctrl) {
62 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 63 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
63 return NvResult::NotImplemented; 64 return NvResult::NotImplemented;
64} 65}
65 66
66NvResult nvhost_nvdec::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 67NvResult nvhost_nvdec::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
67 std::vector<u8>& inline_output) { 68 std::vector<u8>& inline_output, IoctlCtrl& ctrl) {
68 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 69 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
69 return NvResult::NotImplemented; 70 return NvResult::NotImplemented;
70} 71}
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
index 79b8b6de1..884ed6c5b 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
@@ -14,11 +14,13 @@ public:
14 explicit nvhost_nvdec(Core::System& system, std::shared_ptr<nvmap> nvmap_dev); 14 explicit nvhost_nvdec(Core::System& system, std::shared_ptr<nvmap> nvmap_dev);
15 ~nvhost_nvdec() override; 15 ~nvhost_nvdec() override;
16 16
17 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; 17 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
18 IoctlCtrl& ctrl) override;
18 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, 19 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
19 const std::vector<u8>& inline_input, std::vector<u8>& output) override; 20 const std::vector<u8>& inline_input, std::vector<u8>& output,
21 IoctlCtrl& ctrl) override;
20 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 22 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
21 std::vector<u8>& inline_output) override; 23 std::vector<u8>& inline_output, IoctlCtrl& ctrl) override;
22}; 24};
23 25
24} // namespace Service::Nvidia::Devices 26} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
index 86ba3a4d1..ab152bf0e 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
@@ -25,8 +25,8 @@ public:
25 * @param output A buffer where the output data will be written to. 25 * @param output A buffer where the output data will be written to.
26 * @returns The result code of the ioctl. 26 * @returns The result code of the ioctl.
27 */ 27 */
28 virtual NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, 28 virtual NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
29 std::vector<u8>& output) = 0; 29 IoctlCtrl& ctrl) = 0;
30 30
31 /** 31 /**
32 * Handles an ioctl2 request. 32 * Handles an ioctl2 request.
@@ -37,7 +37,8 @@ public:
37 * @returns The result code of the ioctl. 37 * @returns The result code of the ioctl.
38 */ 38 */
39 virtual NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, 39 virtual NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
40 const std::vector<u8>& inline_input, std::vector<u8>& output) = 0; 40 const std::vector<u8>& inline_input, std::vector<u8>& output,
41 IoctlCtrl& ctrl) = 0;
41 42
42 /** 43 /**
43 * Handles an ioctl3 request. 44 * Handles an ioctl3 request.
@@ -48,7 +49,7 @@ public:
48 * @returns The result code of the ioctl. 49 * @returns The result code of the ioctl.
49 */ 50 */
50 virtual NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 51 virtual NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
51 std::vector<u8>& inline_output) = 0; 52 std::vector<u8>& inline_output, IoctlCtrl& ctrl) = 0;
52 53
53protected: 54protected:
54 class BufferMap final { 55 class BufferMap final {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp
index 2d06955c0..6f4ab0ab3 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp
@@ -13,8 +13,8 @@ namespace Service::Nvidia::Devices {
13nvhost_nvjpg::nvhost_nvjpg(Core::System& system) : nvdevice(system) {} 13nvhost_nvjpg::nvhost_nvjpg(Core::System& system) : nvdevice(system) {}
14nvhost_nvjpg::~nvhost_nvjpg() = default; 14nvhost_nvjpg::~nvhost_nvjpg() = default;
15 15
16NvResult nvhost_nvjpg::Ioctl1(Ioctl command, const std::vector<u8>& input, 16NvResult nvhost_nvjpg::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
17 std::vector<u8>& output) { 17 IoctlCtrl& ctrl) {
18 switch (command.group) { 18 switch (command.group) {
19 case 'H': 19 case 'H':
20 switch (command.cmd) { 20 switch (command.cmd) {
@@ -33,13 +33,14 @@ NvResult nvhost_nvjpg::Ioctl1(Ioctl command, const std::vector<u8>& input,
33} 33}
34 34
35NvResult nvhost_nvjpg::Ioctl2(Ioctl command, const std::vector<u8>& input, 35NvResult nvhost_nvjpg::Ioctl2(Ioctl command, const std::vector<u8>& input,
36 const std::vector<u8>& inline_input, std::vector<u8>& output) { 36 const std::vector<u8>& inline_input, std::vector<u8>& output,
37 IoctlCtrl& ctrl) {
37 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 38 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
38 return NvResult::NotImplemented; 39 return NvResult::NotImplemented;
39} 40}
40 41
41NvResult nvhost_nvjpg::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 42NvResult nvhost_nvjpg::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
42 std::vector<u8>& inline_output) { 43 std::vector<u8>& inline_output, IoctlCtrl& ctrl) {
43 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 44 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
44 return NvResult::NotImplemented; 45 return NvResult::NotImplemented;
45} 46}
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h
index 43948d18d..6fb99d959 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h
@@ -16,11 +16,13 @@ public:
16 explicit nvhost_nvjpg(Core::System& system); 16 explicit nvhost_nvjpg(Core::System& system);
17 ~nvhost_nvjpg() override; 17 ~nvhost_nvjpg() override;
18 18
19 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; 19 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
20 IoctlCtrl& ctrl) override;
20 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, 21 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
21 const std::vector<u8>& inline_input, std::vector<u8>& output) override; 22 const std::vector<u8>& inline_input, std::vector<u8>& output,
23 IoctlCtrl& ctrl) override;
22 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 24 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
23 std::vector<u8>& inline_output) override; 25 std::vector<u8>& inline_output, IoctlCtrl& ctrl) override;
24 26
25private: 27private:
26 struct IoctlSetNvmapFD { 28 struct IoctlSetNvmapFD {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
index 805fe86ae..55a17f423 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
@@ -15,7 +15,8 @@ nvhost_vic::nvhost_vic(Core::System& system, std::shared_ptr<nvmap> nvmap_dev)
15 15
16nvhost_vic::~nvhost_vic() = default; 16nvhost_vic::~nvhost_vic() = default;
17 17
18NvResult nvhost_vic::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { 18NvResult nvhost_vic::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
19 IoctlCtrl& ctrl) {
19 switch (command.group) { 20 switch (command.group) {
20 case 0x0: 21 case 0x0:
21 switch (command.cmd) { 22 switch (command.cmd) {
@@ -50,13 +51,14 @@ NvResult nvhost_vic::Ioctl1(Ioctl command, const std::vector<u8>& input, std::ve
50} 51}
51 52
52NvResult nvhost_vic::Ioctl2(Ioctl command, const std::vector<u8>& input, 53NvResult nvhost_vic::Ioctl2(Ioctl command, const std::vector<u8>& input,
53 const std::vector<u8>& inline_input, std::vector<u8>& output) { 54 const std::vector<u8>& inline_input, std::vector<u8>& output,
55 IoctlCtrl& ctrl) {
54 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 56 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
55 return NvResult::NotImplemented; 57 return NvResult::NotImplemented;
56} 58}
57 59
58NvResult nvhost_vic::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 60NvResult nvhost_vic::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
59 std::vector<u8>& inline_output) { 61 std::vector<u8>& inline_output, IoctlCtrl& ctrl) {
60 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 62 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
61 return NvResult::NotImplemented; 63 return NvResult::NotImplemented;
62} 64}
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.h b/src/core/hle/service/nvdrv/devices/nvhost_vic.h
index b2e11f4d4..7f4858cd4 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.h
@@ -14,10 +14,12 @@ public:
14 explicit nvhost_vic(Core::System& system, std::shared_ptr<nvmap> nvmap_dev); 14 explicit nvhost_vic(Core::System& system, std::shared_ptr<nvmap> nvmap_dev);
15 ~nvhost_vic(); 15 ~nvhost_vic();
16 16
17 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; 17 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
18 IoctlCtrl& ctrl) override;
18 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, 19 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
19 const std::vector<u8>& inline_input, std::vector<u8>& output) override; 20 const std::vector<u8>& inline_input, std::vector<u8>& output,
21 IoctlCtrl& ctrl) override;
20 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 22 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
21 std::vector<u8>& inline_output) override; 23 std::vector<u8>& inline_output, IoctlCtrl& ctrl) override;
22}; 24};
23} // namespace Service::Nvidia::Devices 25} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp
index 4015a2740..910cfee51 100644
--- a/src/core/hle/service/nvdrv/devices/nvmap.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp
@@ -19,7 +19,8 @@ nvmap::nvmap(Core::System& system) : nvdevice(system) {
19 19
20nvmap::~nvmap() = default; 20nvmap::~nvmap() = default;
21 21
22NvResult nvmap::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { 22NvResult nvmap::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
23 IoctlCtrl& ctrl) {
23 switch (command.group) { 24 switch (command.group) {
24 case 0x1: 25 case 0x1:
25 switch (command.cmd) { 26 switch (command.cmd) {
@@ -48,13 +49,14 @@ NvResult nvmap::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<
48} 49}
49 50
50NvResult nvmap::Ioctl2(Ioctl command, const std::vector<u8>& input, 51NvResult nvmap::Ioctl2(Ioctl command, const std::vector<u8>& input,
51 const std::vector<u8>& inline_input, std::vector<u8>& output) { 52 const std::vector<u8>& inline_input, std::vector<u8>& output,
53 IoctlCtrl& ctrl) {
52 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 54 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
53 return NvResult::NotImplemented; 55 return NvResult::NotImplemented;
54} 56}
55 57
56NvResult nvmap::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 58NvResult nvmap::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
57 std::vector<u8>& inline_output) { 59 std::vector<u8>& inline_output, IoctlCtrl& ctrl) {
58 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 60 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
59 return NvResult::NotImplemented; 61 return NvResult::NotImplemented;
60} 62}
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.h b/src/core/hle/service/nvdrv/devices/nvmap.h
index 4484bd79f..c0c2fa5eb 100644
--- a/src/core/hle/service/nvdrv/devices/nvmap.h
+++ b/src/core/hle/service/nvdrv/devices/nvmap.h
@@ -19,11 +19,13 @@ public:
19 explicit nvmap(Core::System& system); 19 explicit nvmap(Core::System& system);
20 ~nvmap() override; 20 ~nvmap() override;
21 21
22 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; 22 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
23 IoctlCtrl& ctrl) override;
23 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, 24 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
24 const std::vector<u8>& inline_input, std::vector<u8>& output) override; 25 const std::vector<u8>& inline_input, std::vector<u8>& output,
26 IoctlCtrl& ctrl) override;
25 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 27 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
26 std::vector<u8>& inline_output) override; 28 std::vector<u8>& inline_output, IoctlCtrl& ctrl) override;
27 29
28 /// Returns the allocated address of an nvmap object given its handle. 30 /// Returns the allocated address of an nvmap object given its handle.
29 VAddr GetObjectAddress(u32 handle) const; 31 VAddr GetObjectAddress(u32 handle) const;
diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp
index f6c38e853..d72c531f6 100644
--- a/src/core/hle/service/nvdrv/interface.cpp
+++ b/src/core/hle/service/nvdrv/interface.cpp
@@ -61,10 +61,32 @@ void NVDRV::Ioctl1(Kernel::HLERequestContext& ctx) {
61 std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0)); 61 std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0));
62 const auto input_buffer = ctx.ReadBuffer(0); 62 const auto input_buffer = ctx.ReadBuffer(0);
63 63
64 const auto nv_result = nvdrv->Ioctl1(fd, command, input_buffer, output_buffer); 64 IoctlCtrl ctrl{};
65 65
66 if (command.is_out != 0) { 66 const auto nv_result = nvdrv->Ioctl1(fd, command, input_buffer, output_buffer, ctrl);
67 ctx.WriteBuffer(output_buffer); 67 if (ctrl.must_delay) {
68 ctrl.fresh_call = false;
69 ctx.SleepClientThread(
70 "NVServices::DelayedResponse", ctrl.timeout,
71 [=, this](std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx_,
72 Kernel::ThreadWakeupReason reason) {
73 IoctlCtrl ctrl2{ctrl};
74 std::vector<u8> tmp_output = output_buffer;
75 const auto nv_result2 = nvdrv->Ioctl1(fd, command, input_buffer, tmp_output, ctrl2);
76
77 if (command.is_out != 0) {
78 ctx.WriteBuffer(tmp_output);
79 }
80
81 IPC::ResponseBuilder rb{ctx_, 3};
82 rb.Push(RESULT_SUCCESS);
83 rb.PushEnum(nv_result2);
84 },
85 nvdrv->GetEventWriteable(ctrl.event_id));
86 } else {
87 if (command.is_out != 0) {
88 ctx.WriteBuffer(output_buffer);
89 }
68 } 90 }
69 91
70 IPC::ResponseBuilder rb{ctx, 3}; 92 IPC::ResponseBuilder rb{ctx, 3};
@@ -88,8 +110,35 @@ void NVDRV::Ioctl2(Kernel::HLERequestContext& ctx) {
88 const auto input_inlined_buffer = ctx.ReadBuffer(1); 110 const auto input_inlined_buffer = ctx.ReadBuffer(1);
89 std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0)); 111 std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0));
90 112
113 IoctlCtrl ctrl{};
114
91 const auto nv_result = 115 const auto nv_result =
92 nvdrv->Ioctl2(fd, command, input_buffer, input_inlined_buffer, output_buffer); 116 nvdrv->Ioctl2(fd, command, input_buffer, input_inlined_buffer, output_buffer, ctrl);
117 if (ctrl.must_delay) {
118 ctrl.fresh_call = false;
119 ctx.SleepClientThread(
120 "NVServices::DelayedResponse", ctrl.timeout,
121 [=, this](std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx_,
122 Kernel::ThreadWakeupReason reason) {
123 IoctlCtrl ctrl2{ctrl};
124 std::vector<u8> tmp_output = output_buffer;
125 const auto nv_result2 = nvdrv->Ioctl2(fd, command, input_buffer,
126 input_inlined_buffer, tmp_output, ctrl2);
127
128 if (command.is_out != 0) {
129 ctx.WriteBuffer(tmp_output);
130 }
131
132 IPC::ResponseBuilder rb{ctx_, 3};
133 rb.Push(RESULT_SUCCESS);
134 rb.PushEnum(nv_result2);
135 },
136 nvdrv->GetEventWriteable(ctrl.event_id));
137 } else {
138 if (command.is_out != 0) {
139 ctx.WriteBuffer(output_buffer);
140 }
141 }
93 142
94 if (command.is_out != 0) { 143 if (command.is_out != 0) {
95 ctx.WriteBuffer(output_buffer); 144 ctx.WriteBuffer(output_buffer);
@@ -116,12 +165,36 @@ void NVDRV::Ioctl3(Kernel::HLERequestContext& ctx) {
116 std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0)); 165 std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0));
117 std::vector<u8> output_buffer_inline(ctx.GetWriteBufferSize(1)); 166 std::vector<u8> output_buffer_inline(ctx.GetWriteBufferSize(1));
118 167
168 IoctlCtrl ctrl{};
119 const auto nv_result = 169 const auto nv_result =
120 nvdrv->Ioctl3(fd, command, input_buffer, output_buffer, output_buffer_inline); 170 nvdrv->Ioctl3(fd, command, input_buffer, output_buffer, output_buffer_inline, ctrl);
121 171 if (ctrl.must_delay) {
122 if (command.is_out != 0) { 172 ctrl.fresh_call = false;
123 ctx.WriteBuffer(output_buffer, 0); 173 ctx.SleepClientThread(
124 ctx.WriteBuffer(output_buffer_inline, 1); 174 "NVServices::DelayedResponse", ctrl.timeout,
175 [=, this](std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx_,
176 Kernel::ThreadWakeupReason reason) {
177 IoctlCtrl ctrl2{ctrl};
178 std::vector<u8> tmp_output = output_buffer;
179 std::vector<u8> tmp_output2 = output_buffer;
180 const auto nv_result2 =
181 nvdrv->Ioctl3(fd, command, input_buffer, tmp_output, tmp_output2, ctrl2);
182
183 if (command.is_out != 0) {
184 ctx.WriteBuffer(tmp_output, 0);
185 ctx.WriteBuffer(tmp_output2, 1);
186 }
187
188 IPC::ResponseBuilder rb{ctx_, 3};
189 rb.Push(RESULT_SUCCESS);
190 rb.PushEnum(nv_result2);
191 },
192 nvdrv->GetEventWriteable(ctrl.event_id));
193 } else {
194 if (command.is_out != 0) {
195 ctx.WriteBuffer(output_buffer, 0);
196 ctx.WriteBuffer(output_buffer_inline, 1);
197 }
125 } 198 }
126 199
127 IPC::ResponseBuilder rb{ctx, 3}; 200 IPC::ResponseBuilder rb{ctx, 3};
@@ -224,8 +297,8 @@ void NVDRV::DumpGraphicsMemoryInfo(Kernel::HLERequestContext& ctx) {
224 rb.Push(RESULT_SUCCESS); 297 rb.Push(RESULT_SUCCESS);
225} 298}
226 299
227NVDRV::NVDRV(std::shared_ptr<Module> nvdrv, const char* name) 300NVDRV::NVDRV(Core::System& system_, std::shared_ptr<Module> nvdrv_, const char* name)
228 : ServiceFramework(name), nvdrv(std::move(nvdrv)) { 301 : ServiceFramework{system_, name}, nvdrv{std::move(nvdrv_)} {
229 static const FunctionInfo functions[] = { 302 static const FunctionInfo functions[] = {
230 {0, &NVDRV::Open, "Open"}, 303 {0, &NVDRV::Open, "Open"},
231 {1, &NVDRV::Ioctl1, "Ioctl"}, 304 {1, &NVDRV::Ioctl1, "Ioctl"},
diff --git a/src/core/hle/service/nvdrv/interface.h b/src/core/hle/service/nvdrv/interface.h
index e05f905ae..5c777c59b 100644
--- a/src/core/hle/service/nvdrv/interface.h
+++ b/src/core/hle/service/nvdrv/interface.h
@@ -16,10 +16,10 @@ namespace Service::Nvidia {
16 16
17class NVDRV final : public ServiceFramework<NVDRV> { 17class NVDRV final : public ServiceFramework<NVDRV> {
18public: 18public:
19 NVDRV(std::shared_ptr<Module> nvdrv, const char* name); 19 explicit NVDRV(Core::System& system_, std::shared_ptr<Module> nvdrv_, const char* name);
20 ~NVDRV() override; 20 ~NVDRV() override;
21 21
22 void SignalGPUInterruptSyncpt(const u32 syncpoint_id, const u32 value); 22 void SignalGPUInterruptSyncpt(u32 syncpoint_id, u32 value);
23 23
24private: 24private:
25 void Open(Kernel::HLERequestContext& ctx); 25 void Open(Kernel::HLERequestContext& ctx);
diff --git a/src/core/hle/service/nvdrv/nvdata.h b/src/core/hle/service/nvdrv/nvdata.h
index 3294bc0e7..a3c4ecd85 100644
--- a/src/core/hle/service/nvdrv/nvdata.h
+++ b/src/core/hle/service/nvdrv/nvdata.h
@@ -97,4 +97,15 @@ union Ioctl {
97 BitField<31, 1, u32> is_out; 97 BitField<31, 1, u32> is_out;
98}; 98};
99 99
100struct IoctlCtrl {
101 // First call done to the servioce for services that call itself again after a call.
102 bool fresh_call{true};
103 // Tells the Ioctl Wrapper that it must delay the IPC response and send the thread to sleep
104 bool must_delay{};
105 // Timeout for the delay
106 s64 timeout{};
107 // NV Event Id
108 s32 event_id{-1};
109};
110
100} // namespace Service::Nvidia 111} // namespace Service::Nvidia
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp
index bdbbedd0d..8e0c9f093 100644
--- a/src/core/hle/service/nvdrv/nvdrv.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv.cpp
@@ -30,11 +30,11 @@ namespace Service::Nvidia {
30void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger, 30void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger,
31 Core::System& system) { 31 Core::System& system) {
32 auto module_ = std::make_shared<Module>(system); 32 auto module_ = std::make_shared<Module>(system);
33 std::make_shared<NVDRV>(module_, "nvdrv")->InstallAsService(service_manager); 33 std::make_shared<NVDRV>(system, module_, "nvdrv")->InstallAsService(service_manager);
34 std::make_shared<NVDRV>(module_, "nvdrv:a")->InstallAsService(service_manager); 34 std::make_shared<NVDRV>(system, module_, "nvdrv:a")->InstallAsService(service_manager);
35 std::make_shared<NVDRV>(module_, "nvdrv:s")->InstallAsService(service_manager); 35 std::make_shared<NVDRV>(system, module_, "nvdrv:s")->InstallAsService(service_manager);
36 std::make_shared<NVDRV>(module_, "nvdrv:t")->InstallAsService(service_manager); 36 std::make_shared<NVDRV>(system, module_, "nvdrv:t")->InstallAsService(service_manager);
37 std::make_shared<NVMEMP>()->InstallAsService(service_manager); 37 std::make_shared<NVMEMP>(system)->InstallAsService(service_manager);
38 nvflinger.SetNVDrvInstance(module_); 38 nvflinger.SetNVDrvInstance(module_);
39} 39}
40 40
@@ -91,7 +91,7 @@ DeviceFD Module::Open(const std::string& device_name) {
91} 91}
92 92
93NvResult Module::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, 93NvResult Module::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
94 std::vector<u8>& output) { 94 std::vector<u8>& output, IoctlCtrl& ctrl) {
95 if (fd < 0) { 95 if (fd < 0) {
96 LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd); 96 LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd);
97 return NvResult::InvalidState; 97 return NvResult::InvalidState;
@@ -104,11 +104,12 @@ NvResult Module::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input
104 return NvResult::NotImplemented; 104 return NvResult::NotImplemented;
105 } 105 }
106 106
107 return itr->second->Ioctl1(command, input, output); 107 return itr->second->Ioctl1(command, input, output, ctrl);
108} 108}
109 109
110NvResult Module::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, 110NvResult Module::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
111 const std::vector<u8>& inline_input, std::vector<u8>& output) { 111 const std::vector<u8>& inline_input, std::vector<u8>& output,
112 IoctlCtrl& ctrl) {
112 if (fd < 0) { 113 if (fd < 0) {
113 LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd); 114 LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd);
114 return NvResult::InvalidState; 115 return NvResult::InvalidState;
@@ -121,11 +122,11 @@ NvResult Module::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input
121 return NvResult::NotImplemented; 122 return NvResult::NotImplemented;
122 } 123 }
123 124
124 return itr->second->Ioctl2(command, input, inline_input, output); 125 return itr->second->Ioctl2(command, input, inline_input, output, ctrl);
125} 126}
126 127
127NvResult Module::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, 128NvResult Module::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
128 std::vector<u8>& output, std::vector<u8>& inline_output) { 129 std::vector<u8>& output, std::vector<u8>& inline_output, IoctlCtrl& ctrl) {
129 if (fd < 0) { 130 if (fd < 0) {
130 LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd); 131 LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd);
131 return NvResult::InvalidState; 132 return NvResult::InvalidState;
@@ -138,7 +139,7 @@ NvResult Module::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input
138 return NvResult::NotImplemented; 139 return NvResult::NotImplemented;
139 } 140 }
140 141
141 return itr->second->Ioctl3(command, input, output, inline_output); 142 return itr->second->Ioctl3(command, input, output, inline_output, ctrl);
142} 143}
143 144
144NvResult Module::Close(DeviceFD fd) { 145NvResult Module::Close(DeviceFD fd) {
diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h
index 7654bb026..5985d2179 100644
--- a/src/core/hle/service/nvdrv/nvdrv.h
+++ b/src/core/hle/service/nvdrv/nvdrv.h
@@ -100,7 +100,7 @@ struct EventInterface {
100 100
101class Module final { 101class Module final {
102public: 102public:
103 Module(Core::System& system); 103 explicit Module(Core::System& system_);
104 ~Module(); 104 ~Module();
105 105
106 /// Returns a pointer to one of the available devices, identified by its name. 106 /// Returns a pointer to one of the available devices, identified by its name.
@@ -119,13 +119,13 @@ public:
119 119
120 /// Sends an ioctl command to the specified file descriptor. 120 /// Sends an ioctl command to the specified file descriptor.
121 NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, 121 NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
122 std::vector<u8>& output); 122 std::vector<u8>& output, IoctlCtrl& ctrl);
123 123
124 NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, 124 NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
125 const std::vector<u8>& inline_input, std::vector<u8>& output); 125 const std::vector<u8>& inline_input, std::vector<u8>& output, IoctlCtrl& ctrl);
126 126
127 NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, 127 NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
128 std::vector<u8>& output, std::vector<u8>& inline_output); 128 std::vector<u8>& output, std::vector<u8>& inline_output, IoctlCtrl& ctrl);
129 129
130 /// Closes a device file descriptor and returns operation success. 130 /// Closes a device file descriptor and returns operation success.
131 NvResult Close(DeviceFD fd); 131 NvResult Close(DeviceFD fd);
diff --git a/src/core/hle/service/nvdrv/nvmemp.cpp b/src/core/hle/service/nvdrv/nvmemp.cpp
index 73b37e805..331c02243 100644
--- a/src/core/hle/service/nvdrv/nvmemp.cpp
+++ b/src/core/hle/service/nvdrv/nvmemp.cpp
@@ -8,7 +8,7 @@
8 8
9namespace Service::Nvidia { 9namespace Service::Nvidia {
10 10
11NVMEMP::NVMEMP() : ServiceFramework("nvmemp") { 11NVMEMP::NVMEMP(Core::System& system_) : ServiceFramework{system_, "nvmemp"} {
12 static const FunctionInfo functions[] = { 12 static const FunctionInfo functions[] = {
13 {0, &NVMEMP::Open, "Open"}, 13 {0, &NVMEMP::Open, "Open"},
14 {1, &NVMEMP::GetAruid, "GetAruid"}, 14 {1, &NVMEMP::GetAruid, "GetAruid"},
diff --git a/src/core/hle/service/nvdrv/nvmemp.h b/src/core/hle/service/nvdrv/nvmemp.h
index c453ee4db..724c27ef9 100644
--- a/src/core/hle/service/nvdrv/nvmemp.h
+++ b/src/core/hle/service/nvdrv/nvmemp.h
@@ -6,11 +6,15 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::Nvidia { 13namespace Service::Nvidia {
10 14
11class NVMEMP final : public ServiceFramework<NVMEMP> { 15class NVMEMP final : public ServiceFramework<NVMEMP> {
12public: 16public:
13 NVMEMP(); 17 explicit NVMEMP(Core::System& system_);
14 ~NVMEMP() override; 18 ~NVMEMP() override;
15 19
16private: 20private:
diff --git a/src/core/hle/service/nvdrv/syncpoint_manager.h b/src/core/hle/service/nvdrv/syncpoint_manager.h
index 4168b6c7e..d395c5d0b 100644
--- a/src/core/hle/service/nvdrv/syncpoint_manager.h
+++ b/src/core/hle/service/nvdrv/syncpoint_manager.h
@@ -37,7 +37,7 @@ public:
37 * @returns The lower bound for the specified syncpoint. 37 * @returns The lower bound for the specified syncpoint.
38 */ 38 */
39 u32 GetSyncpointMin(u32 syncpoint_id) const { 39 u32 GetSyncpointMin(u32 syncpoint_id) const {
40 return syncpoints[syncpoint_id].min.load(std::memory_order_relaxed); 40 return syncpoints.at(syncpoint_id).min.load(std::memory_order_relaxed);
41 } 41 }
42 42
43 /** 43 /**
@@ -46,7 +46,7 @@ public:
46 * @returns The upper bound for the specified syncpoint. 46 * @returns The upper bound for the specified syncpoint.
47 */ 47 */
48 u32 GetSyncpointMax(u32 syncpoint_id) const { 48 u32 GetSyncpointMax(u32 syncpoint_id) const {
49 return syncpoints[syncpoint_id].max.load(std::memory_order_relaxed); 49 return syncpoints.at(syncpoint_id).max.load(std::memory_order_relaxed);
50 } 50 }
51 51
52 /** 52 /**
diff --git a/src/core/hle/service/olsc/olsc.cpp b/src/core/hle/service/olsc/olsc.cpp
index aad4ca706..4440135ed 100644
--- a/src/core/hle/service/olsc/olsc.cpp
+++ b/src/core/hle/service/olsc/olsc.cpp
@@ -12,7 +12,7 @@ namespace Service::OLSC {
12 12
13class OLSC final : public ServiceFramework<OLSC> { 13class OLSC final : public ServiceFramework<OLSC> {
14public: 14public:
15 explicit OLSC() : ServiceFramework{"olsc:u"} { 15 explicit OLSC(Core::System& system_) : ServiceFramework{system_, "olsc:u"} {
16 // clang-format off 16 // clang-format off
17 static const FunctionInfo functions[] = { 17 static const FunctionInfo functions[] = {
18 {0, &OLSC::Initialize, "Initialize"}, 18 {0, &OLSC::Initialize, "Initialize"},
@@ -62,8 +62,8 @@ private:
62 bool initialized{}; 62 bool initialized{};
63}; 63};
64 64
65void InstallInterfaces(SM::ServiceManager& service_manager) { 65void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
66 std::make_shared<OLSC>()->InstallAsService(service_manager); 66 std::make_shared<OLSC>(system)->InstallAsService(service_manager);
67} 67}
68 68
69} // namespace Service::OLSC 69} // namespace Service::OLSC
diff --git a/src/core/hle/service/olsc/olsc.h b/src/core/hle/service/olsc/olsc.h
index edee4376b..24f24ca6b 100644
--- a/src/core/hle/service/olsc/olsc.h
+++ b/src/core/hle/service/olsc/olsc.h
@@ -4,6 +4,10 @@
4 4
5#pragma once 5#pragma once
6 6
7namespace Core {
8class System;
9}
10
7namespace Service::SM { 11namespace Service::SM {
8class ServiceManager; 12class ServiceManager;
9} 13}
@@ -11,6 +15,6 @@ class ServiceManager;
11namespace Service::OLSC { 15namespace Service::OLSC {
12 16
13/// Registers all SSL services with the specified service manager. 17/// Registers all SSL services with the specified service manager.
14void InstallInterfaces(SM::ServiceManager& service_manager); 18void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
15 19
16} // namespace Service::OLSC 20} // namespace Service::OLSC
diff --git a/src/core/hle/service/pcie/pcie.cpp b/src/core/hle/service/pcie/pcie.cpp
index c568a0adc..80c0fc7ac 100644
--- a/src/core/hle/service/pcie/pcie.cpp
+++ b/src/core/hle/service/pcie/pcie.cpp
@@ -12,7 +12,7 @@ namespace Service::PCIe {
12 12
13class ISession final : public ServiceFramework<ISession> { 13class ISession final : public ServiceFramework<ISession> {
14public: 14public:
15 explicit ISession() : ServiceFramework{"ISession"} { 15 explicit ISession(Core::System& system_) : ServiceFramework{system_, "ISession"} {
16 // clang-format off 16 // clang-format off
17 static const FunctionInfo functions[] = { 17 static const FunctionInfo functions[] = {
18 {0, nullptr, "QueryFunctions"}, 18 {0, nullptr, "QueryFunctions"},
@@ -48,7 +48,7 @@ public:
48 48
49class PCIe final : public ServiceFramework<PCIe> { 49class PCIe final : public ServiceFramework<PCIe> {
50public: 50public:
51 explicit PCIe() : ServiceFramework{"pcie"} { 51 explicit PCIe(Core::System& system_) : ServiceFramework{system, "pcie"} {
52 // clang-format off 52 // clang-format off
53 static const FunctionInfo functions[] = { 53 static const FunctionInfo functions[] = {
54 {0, nullptr, "RegisterClassDriver"}, 54 {0, nullptr, "RegisterClassDriver"},
@@ -60,8 +60,8 @@ public:
60 } 60 }
61}; 61};
62 62
63void InstallInterfaces(SM::ServiceManager& sm) { 63void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
64 std::make_shared<PCIe>()->InstallAsService(sm); 64 std::make_shared<PCIe>(system)->InstallAsService(sm);
65} 65}
66 66
67} // namespace Service::PCIe 67} // namespace Service::PCIe
diff --git a/src/core/hle/service/pcie/pcie.h b/src/core/hle/service/pcie/pcie.h
index 59c22ca45..e5709a72f 100644
--- a/src/core/hle/service/pcie/pcie.h
+++ b/src/core/hle/service/pcie/pcie.h
@@ -4,12 +4,16 @@
4 4
5#pragma once 5#pragma once
6 6
7namespace Core {
8class System;
9}
10
7namespace Service::SM { 11namespace Service::SM {
8class ServiceManager; 12class ServiceManager;
9} 13}
10 14
11namespace Service::PCIe { 15namespace Service::PCIe {
12 16
13void InstallInterfaces(SM::ServiceManager& sm); 17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
14 18
15} // namespace Service::PCIe 19} // namespace Service::PCIe
diff --git a/src/core/hle/service/pctl/module.cpp b/src/core/hle/service/pctl/module.cpp
index caf14ed61..6ab1e4124 100644
--- a/src/core/hle/service/pctl/module.cpp
+++ b/src/core/hle/service/pctl/module.cpp
@@ -11,7 +11,8 @@ namespace Service::PCTL {
11 11
12class IParentalControlService final : public ServiceFramework<IParentalControlService> { 12class IParentalControlService final : public ServiceFramework<IParentalControlService> {
13public: 13public:
14 IParentalControlService() : ServiceFramework("IParentalControlService") { 14 explicit IParentalControlService(Core::System& system_)
15 : ServiceFramework{system_, "IParentalControlService"} {
15 // clang-format off 16 // clang-format off
16 static const FunctionInfo functions[] = { 17 static const FunctionInfo functions[] = {
17 {1, &IParentalControlService::Initialize, "Initialize"}, 18 {1, &IParentalControlService::Initialize, "Initialize"},
@@ -137,7 +138,7 @@ void Module::Interface::CreateService(Kernel::HLERequestContext& ctx) {
137 138
138 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 139 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
139 rb.Push(RESULT_SUCCESS); 140 rb.Push(RESULT_SUCCESS);
140 rb.PushIpcInterface<IParentalControlService>(); 141 rb.PushIpcInterface<IParentalControlService>(system);
141} 142}
142 143
143void Module::Interface::CreateServiceWithoutInitialize(Kernel::HLERequestContext& ctx) { 144void Module::Interface::CreateServiceWithoutInitialize(Kernel::HLERequestContext& ctx) {
@@ -145,20 +146,20 @@ void Module::Interface::CreateServiceWithoutInitialize(Kernel::HLERequestContext
145 146
146 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 147 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
147 rb.Push(RESULT_SUCCESS); 148 rb.Push(RESULT_SUCCESS);
148 rb.PushIpcInterface<IParentalControlService>(); 149 rb.PushIpcInterface<IParentalControlService>(system);
149} 150}
150 151
151Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) 152Module::Interface::Interface(Core::System& system_, std::shared_ptr<Module> module_, const char* name)
152 : ServiceFramework(name), module(std::move(module)) {} 153 : ServiceFramework{system_, name}, module{std::move(module_)} {}
153 154
154Module::Interface::~Interface() = default; 155Module::Interface::~Interface() = default;
155 156
156void InstallInterfaces(SM::ServiceManager& service_manager) { 157void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
157 auto module = std::make_shared<Module>(); 158 auto module = std::make_shared<Module>();
158 std::make_shared<PCTL>(module, "pctl")->InstallAsService(service_manager); 159 std::make_shared<PCTL>(system, module, "pctl")->InstallAsService(service_manager);
159 std::make_shared<PCTL>(module, "pctl:a")->InstallAsService(service_manager); 160 std::make_shared<PCTL>(system, module, "pctl:a")->InstallAsService(service_manager);
160 std::make_shared<PCTL>(module, "pctl:r")->InstallAsService(service_manager); 161 std::make_shared<PCTL>(system, module, "pctl:r")->InstallAsService(service_manager);
161 std::make_shared<PCTL>(module, "pctl:s")->InstallAsService(service_manager); 162 std::make_shared<PCTL>(system, module, "pctl:s")->InstallAsService(service_manager);
162} 163}
163 164
164} // namespace Service::PCTL 165} // namespace Service::PCTL
diff --git a/src/core/hle/service/pctl/module.h b/src/core/hle/service/pctl/module.h
index 3e449110d..4c7e09a3b 100644
--- a/src/core/hle/service/pctl/module.h
+++ b/src/core/hle/service/pctl/module.h
@@ -6,13 +6,18 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::PCTL { 13namespace Service::PCTL {
10 14
11class Module final { 15class Module final {
12public: 16public:
13 class Interface : public ServiceFramework<Interface> { 17 class Interface : public ServiceFramework<Interface> {
14 public: 18 public:
15 explicit Interface(std::shared_ptr<Module> module, const char* name); 19 explicit Interface(Core::System& system_, std::shared_ptr<Module> module_,
20 const char* name);
16 ~Interface() override; 21 ~Interface() override;
17 22
18 void CreateService(Kernel::HLERequestContext& ctx); 23 void CreateService(Kernel::HLERequestContext& ctx);
@@ -24,6 +29,6 @@ public:
24}; 29};
25 30
26/// Registers all PCTL services with the specified service manager. 31/// Registers all PCTL services with the specified service manager.
27void InstallInterfaces(SM::ServiceManager& service_manager); 32void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
28 33
29} // namespace Service::PCTL 34} // namespace Service::PCTL
diff --git a/src/core/hle/service/pctl/pctl.cpp b/src/core/hle/service/pctl/pctl.cpp
index af9d1433a..16dd34f90 100644
--- a/src/core/hle/service/pctl/pctl.cpp
+++ b/src/core/hle/service/pctl/pctl.cpp
@@ -6,8 +6,8 @@
6 6
7namespace Service::PCTL { 7namespace Service::PCTL {
8 8
9PCTL::PCTL(std::shared_ptr<Module> module, const char* name) 9PCTL::PCTL(Core::System& system_, std::shared_ptr<Module> module_, const char* name)
10 : Module::Interface(std::move(module), name) { 10 : Interface{system_, std::move(module_), name} {
11 static const FunctionInfo functions[] = { 11 static const FunctionInfo functions[] = {
12 {0, &PCTL::CreateService, "CreateService"}, 12 {0, &PCTL::CreateService, "CreateService"},
13 {1, &PCTL::CreateServiceWithoutInitialize, "CreateServiceWithoutInitialize"}, 13 {1, &PCTL::CreateServiceWithoutInitialize, "CreateServiceWithoutInitialize"},
diff --git a/src/core/hle/service/pctl/pctl.h b/src/core/hle/service/pctl/pctl.h
index c33ea80b6..275d23007 100644
--- a/src/core/hle/service/pctl/pctl.h
+++ b/src/core/hle/service/pctl/pctl.h
@@ -6,11 +6,15 @@
6 6
7#include "core/hle/service/pctl/module.h" 7#include "core/hle/service/pctl/module.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::PCTL { 13namespace Service::PCTL {
10 14
11class PCTL final : public Module::Interface { 15class PCTL final : public Module::Interface {
12public: 16public:
13 explicit PCTL(std::shared_ptr<Module> module, const char* name); 17 explicit PCTL(Core::System& system_, std::shared_ptr<Module> module_, const char* name);
14 ~PCTL() override; 18 ~PCTL() override;
15}; 19};
16 20
diff --git a/src/core/hle/service/pcv/pcv.cpp b/src/core/hle/service/pcv/pcv.cpp
index 8bfc0276e..68b2c4178 100644
--- a/src/core/hle/service/pcv/pcv.cpp
+++ b/src/core/hle/service/pcv/pcv.cpp
@@ -12,7 +12,7 @@ namespace Service::PCV {
12 12
13class PCV final : public ServiceFramework<PCV> { 13class PCV final : public ServiceFramework<PCV> {
14public: 14public:
15 explicit PCV() : ServiceFramework{"pcv"} { 15 explicit PCV(Core::System& system_) : ServiceFramework{system_, "pcv"} {
16 // clang-format off 16 // clang-format off
17 static const FunctionInfo functions[] = { 17 static const FunctionInfo functions[] = {
18 {0, nullptr, "SetPowerEnabled"}, 18 {0, nullptr, "SetPowerEnabled"},
@@ -54,7 +54,7 @@ public:
54 54
55class PCV_ARB final : public ServiceFramework<PCV_ARB> { 55class PCV_ARB final : public ServiceFramework<PCV_ARB> {
56public: 56public:
57 explicit PCV_ARB() : ServiceFramework{"pcv:arb"} { 57 explicit PCV_ARB(Core::System& system_) : ServiceFramework{system_, "pcv:arb"} {
58 // clang-format off 58 // clang-format off
59 static const FunctionInfo functions[] = { 59 static const FunctionInfo functions[] = {
60 {0, nullptr, "ReleaseControl"}, 60 {0, nullptr, "ReleaseControl"},
@@ -67,7 +67,7 @@ public:
67 67
68class PCV_IMM final : public ServiceFramework<PCV_IMM> { 68class PCV_IMM final : public ServiceFramework<PCV_IMM> {
69public: 69public:
70 explicit PCV_IMM() : ServiceFramework{"pcv:imm"} { 70 explicit PCV_IMM(Core::System& system_) : ServiceFramework{system_, "pcv:imm"} {
71 // clang-format off 71 // clang-format off
72 static const FunctionInfo functions[] = { 72 static const FunctionInfo functions[] = {
73 {0, nullptr, "SetClockRate"}, 73 {0, nullptr, "SetClockRate"},
@@ -78,10 +78,10 @@ public:
78 } 78 }
79}; 79};
80 80
81void InstallInterfaces(SM::ServiceManager& sm) { 81void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
82 std::make_shared<PCV>()->InstallAsService(sm); 82 std::make_shared<PCV>(system)->InstallAsService(sm);
83 std::make_shared<PCV_ARB>()->InstallAsService(sm); 83 std::make_shared<PCV_ARB>(system)->InstallAsService(sm);
84 std::make_shared<PCV_IMM>()->InstallAsService(sm); 84 std::make_shared<PCV_IMM>(system)->InstallAsService(sm);
85} 85}
86 86
87} // namespace Service::PCV 87} // namespace Service::PCV
diff --git a/src/core/hle/service/pcv/pcv.h b/src/core/hle/service/pcv/pcv.h
index 219a893c3..c61a0b591 100644
--- a/src/core/hle/service/pcv/pcv.h
+++ b/src/core/hle/service/pcv/pcv.h
@@ -4,12 +4,16 @@
4 4
5#pragma once 5#pragma once
6 6
7namespace Core {
8class System;
9}
10
7namespace Service::SM { 11namespace Service::SM {
8class ServiceManager; 12class ServiceManager;
9} 13}
10 14
11namespace Service::PCV { 15namespace Service::PCV {
12 16
13void InstallInterfaces(SM::ServiceManager& sm); 17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
14 18
15} // namespace Service::PCV 19} // namespace Service::PCV
diff --git a/src/core/hle/service/pm/pm.cpp b/src/core/hle/service/pm/pm.cpp
index a771a51b4..68736c40c 100644
--- a/src/core/hle/service/pm/pm.cpp
+++ b/src/core/hle/service/pm/pm.cpp
@@ -44,7 +44,7 @@ void GetApplicationPidGeneric(Kernel::HLERequestContext& ctx,
44 44
45class BootMode final : public ServiceFramework<BootMode> { 45class BootMode final : public ServiceFramework<BootMode> {
46public: 46public:
47 explicit BootMode() : ServiceFramework{"pm:bm"} { 47 explicit BootMode(Core::System& system_) : ServiceFramework{system_, "pm:bm"} {
48 static const FunctionInfo functions[] = { 48 static const FunctionInfo functions[] = {
49 {0, &BootMode::GetBootMode, "GetBootMode"}, 49 {0, &BootMode::GetBootMode, "GetBootMode"},
50 {1, &BootMode::SetMaintenanceBoot, "SetMaintenanceBoot"}, 50 {1, &BootMode::SetMaintenanceBoot, "SetMaintenanceBoot"},
@@ -75,8 +75,8 @@ private:
75 75
76class DebugMonitor final : public ServiceFramework<DebugMonitor> { 76class DebugMonitor final : public ServiceFramework<DebugMonitor> {
77public: 77public:
78 explicit DebugMonitor(const Kernel::KernelCore& kernel) 78 explicit DebugMonitor(Core::System& system_)
79 : ServiceFramework{"pm:dmnt"}, kernel(kernel) { 79 : ServiceFramework{system_, "pm:dmnt"}, kernel{system_.Kernel()} {
80 // clang-format off 80 // clang-format off
81 static const FunctionInfo functions[] = { 81 static const FunctionInfo functions[] = {
82 {0, nullptr, "GetJitDebugProcessIdList"}, 82 {0, nullptr, "GetJitDebugProcessIdList"},
@@ -125,8 +125,9 @@ private:
125 125
126class Info final : public ServiceFramework<Info> { 126class Info final : public ServiceFramework<Info> {
127public: 127public:
128 explicit Info(const std::vector<std::shared_ptr<Kernel::Process>>& process_list) 128 explicit Info(Core::System& system_,
129 : ServiceFramework{"pm:info"}, process_list(process_list) { 129 const std::vector<std::shared_ptr<Kernel::Process>>& process_list_)
130 : ServiceFramework{system_, "pm:info"}, process_list{process_list_} {
130 static const FunctionInfo functions[] = { 131 static const FunctionInfo functions[] = {
131 {0, &Info::GetTitleId, "GetTitleId"}, 132 {0, &Info::GetTitleId, "GetTitleId"},
132 }; 133 };
@@ -160,8 +161,8 @@ private:
160 161
161class Shell final : public ServiceFramework<Shell> { 162class Shell final : public ServiceFramework<Shell> {
162public: 163public:
163 explicit Shell(const Kernel::KernelCore& kernel) 164 explicit Shell(Core::System& system_)
164 : ServiceFramework{"pm:shell"}, kernel(kernel) { 165 : ServiceFramework{system_, "pm:shell"}, kernel{system_.Kernel()} {
165 // clang-format off 166 // clang-format off
166 static const FunctionInfo functions[] = { 167 static const FunctionInfo functions[] = {
167 {0, nullptr, "LaunchProgram"}, 168 {0, nullptr, "LaunchProgram"},
@@ -190,11 +191,11 @@ private:
190}; 191};
191 192
192void InstallInterfaces(Core::System& system) { 193void InstallInterfaces(Core::System& system) {
193 std::make_shared<BootMode>()->InstallAsService(system.ServiceManager()); 194 std::make_shared<BootMode>(system)->InstallAsService(system.ServiceManager());
194 std::make_shared<DebugMonitor>(system.Kernel())->InstallAsService(system.ServiceManager()); 195 std::make_shared<DebugMonitor>(system)->InstallAsService(system.ServiceManager());
195 std::make_shared<Info>(system.Kernel().GetProcessList()) 196 std::make_shared<Info>(system, system.Kernel().GetProcessList())
196 ->InstallAsService(system.ServiceManager()); 197 ->InstallAsService(system.ServiceManager());
197 std::make_shared<Shell>(system.Kernel())->InstallAsService(system.ServiceManager()); 198 std::make_shared<Shell>(system)->InstallAsService(system.ServiceManager());
198} 199}
199 200
200} // namespace Service::PM 201} // namespace Service::PM
diff --git a/src/core/hle/service/prepo/prepo.cpp b/src/core/hle/service/prepo/prepo.cpp
index b9ef86b72..392fda73e 100644
--- a/src/core/hle/service/prepo/prepo.cpp
+++ b/src/core/hle/service/prepo/prepo.cpp
@@ -16,8 +16,7 @@ namespace Service::PlayReport {
16 16
17class PlayReport final : public ServiceFramework<PlayReport> { 17class PlayReport final : public ServiceFramework<PlayReport> {
18public: 18public:
19 explicit PlayReport(const char* name, Core::System& system) 19 explicit PlayReport(const char* name, Core::System& system_) : ServiceFramework{system_, name} {
20 : ServiceFramework{name}, system(system) {
21 // clang-format off 20 // clang-format off
22 static const FunctionInfo functions[] = { 21 static const FunctionInfo functions[] = {
23 {10100, &PlayReport::SaveReport<Core::Reporter::PlayReportType::Old>, "SaveReportOld"}, 22 {10100, &PlayReport::SaveReport<Core::Reporter::PlayReportType::Old>, "SaveReportOld"},
@@ -140,8 +139,6 @@ private:
140 IPC::ResponseBuilder rb{ctx, 2}; 139 IPC::ResponseBuilder rb{ctx, 2};
141 rb.Push(RESULT_SUCCESS); 140 rb.Push(RESULT_SUCCESS);
142 } 141 }
143
144 Core::System& system;
145}; 142};
146 143
147void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 144void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
diff --git a/src/core/hle/service/prepo/prepo.h b/src/core/hle/service/prepo/prepo.h
index a5682ee26..395b57ead 100644
--- a/src/core/hle/service/prepo/prepo.h
+++ b/src/core/hle/service/prepo/prepo.h
@@ -4,14 +4,14 @@
4 4
5#pragma once 5#pragma once
6 6
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Core { 7namespace Core {
12class System; 8class System;
13} 9}
14 10
11namespace Service::SM {
12class ServiceManager;
13}
14
15namespace Service::PlayReport { 15namespace Service::PlayReport {
16 16
17void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); 17void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
diff --git a/src/core/hle/service/psc/psc.cpp b/src/core/hle/service/psc/psc.cpp
index 99e1c9042..5a52b2b05 100644
--- a/src/core/hle/service/psc/psc.cpp
+++ b/src/core/hle/service/psc/psc.cpp
@@ -14,7 +14,7 @@ namespace Service::PSC {
14 14
15class PSC_C final : public ServiceFramework<PSC_C> { 15class PSC_C final : public ServiceFramework<PSC_C> {
16public: 16public:
17 explicit PSC_C() : ServiceFramework{"psc:c"} { 17 explicit PSC_C(Core::System& system_) : ServiceFramework{system_, "psc:c"} {
18 // clang-format off 18 // clang-format off
19 static const FunctionInfo functions[] = { 19 static const FunctionInfo functions[] = {
20 {0, nullptr, "Initialize"}, 20 {0, nullptr, "Initialize"},
@@ -35,7 +35,7 @@ public:
35 35
36class IPmModule final : public ServiceFramework<IPmModule> { 36class IPmModule final : public ServiceFramework<IPmModule> {
37public: 37public:
38 explicit IPmModule() : ServiceFramework{"IPmModule"} { 38 explicit IPmModule(Core::System& system_) : ServiceFramework{system_, "IPmModule"} {
39 // clang-format off 39 // clang-format off
40 static const FunctionInfo functions[] = { 40 static const FunctionInfo functions[] = {
41 {0, nullptr, "Initialize"}, 41 {0, nullptr, "Initialize"},
@@ -52,7 +52,7 @@ public:
52 52
53class PSC_M final : public ServiceFramework<PSC_M> { 53class PSC_M final : public ServiceFramework<PSC_M> {
54public: 54public:
55 explicit PSC_M() : ServiceFramework{"psc:m"} { 55 explicit PSC_M(Core::System& system_) : ServiceFramework{system_, "psc:m"} {
56 // clang-format off 56 // clang-format off
57 static const FunctionInfo functions[] = { 57 static const FunctionInfo functions[] = {
58 {0, &PSC_M::GetPmModule, "GetPmModule"}, 58 {0, &PSC_M::GetPmModule, "GetPmModule"},
@@ -68,13 +68,13 @@ private:
68 68
69 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 69 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
70 rb.Push(RESULT_SUCCESS); 70 rb.Push(RESULT_SUCCESS);
71 rb.PushIpcInterface<IPmModule>(); 71 rb.PushIpcInterface<IPmModule>(system);
72 } 72 }
73}; 73};
74 74
75void InstallInterfaces(SM::ServiceManager& sm) { 75void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
76 std::make_shared<PSC_C>()->InstallAsService(sm); 76 std::make_shared<PSC_C>(system)->InstallAsService(sm);
77 std::make_shared<PSC_M>()->InstallAsService(sm); 77 std::make_shared<PSC_M>(system)->InstallAsService(sm);
78} 78}
79 79
80} // namespace Service::PSC 80} // namespace Service::PSC
diff --git a/src/core/hle/service/psc/psc.h b/src/core/hle/service/psc/psc.h
index 5052eb02c..89344f32d 100644
--- a/src/core/hle/service/psc/psc.h
+++ b/src/core/hle/service/psc/psc.h
@@ -4,12 +4,16 @@
4 4
5#pragma once 5#pragma once
6 6
7namespace Core {
8class System;
9}
10
7namespace Service::SM { 11namespace Service::SM {
8class ServiceManager; 12class ServiceManager;
9} 13}
10 14
11namespace Service::PSC { 15namespace Service::PSC {
12 16
13void InstallInterfaces(SM::ServiceManager& sm); 17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
14 18
15} // namespace Service::PSC 19} // namespace Service::PSC
diff --git a/src/core/hle/service/ptm/psm.cpp b/src/core/hle/service/ptm/psm.cpp
index 6d9e6bd09..b4b0dd241 100644
--- a/src/core/hle/service/ptm/psm.cpp
+++ b/src/core/hle/service/ptm/psm.cpp
@@ -14,7 +14,7 @@ namespace Service::PSM {
14 14
15class PSM final : public ServiceFramework<PSM> { 15class PSM final : public ServiceFramework<PSM> {
16public: 16public:
17 explicit PSM() : ServiceFramework{"psm"} { 17 explicit PSM(Core::System& system_) : ServiceFramework{system_, "psm"} {
18 // clang-format off 18 // clang-format off
19 static const FunctionInfo functions[] = { 19 static const FunctionInfo functions[] = {
20 {0, &PSM::GetBatteryChargePercentage, "GetBatteryChargePercentage"}, 20 {0, &PSM::GetBatteryChargePercentage, "GetBatteryChargePercentage"},
@@ -72,8 +72,8 @@ private:
72 ChargerType charger_type{ChargerType::RegularCharger}; 72 ChargerType charger_type{ChargerType::RegularCharger};
73}; 73};
74 74
75void InstallInterfaces(SM::ServiceManager& sm) { 75void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
76 std::make_shared<PSM>()->InstallAsService(sm); 76 std::make_shared<PSM>(system)->InstallAsService(sm);
77} 77}
78 78
79} // namespace Service::PSM 79} // namespace Service::PSM
diff --git a/src/core/hle/service/ptm/psm.h b/src/core/hle/service/ptm/psm.h
index a286793ae..2930ce26a 100644
--- a/src/core/hle/service/ptm/psm.h
+++ b/src/core/hle/service/ptm/psm.h
@@ -4,12 +4,16 @@
4 4
5#pragma once 5#pragma once
6 6
7namespace Core {
8class System;
9}
10
7namespace Service::SM { 11namespace Service::SM {
8class ServiceManager; 12class ServiceManager;
9} 13}
10 14
11namespace Service::PSM { 15namespace Service::PSM {
12 16
13void InstallInterfaces(SM::ServiceManager& sm); 17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
14 18
15} // namespace Service::PSM 19} // namespace Service::PSM
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index fb4979af2..360e0bf37 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -90,9 +90,10 @@ namespace Service {
90 return function_string; 90 return function_string;
91} 91}
92 92
93ServiceFrameworkBase::ServiceFrameworkBase(const char* service_name, u32 max_sessions, 93ServiceFrameworkBase::ServiceFrameworkBase(Core::System& system_, const char* service_name_,
94 InvokerFn* handler_invoker) 94 u32 max_sessions_, InvokerFn* handler_invoker_)
95 : service_name(service_name), max_sessions(max_sessions), handler_invoker(handler_invoker) {} 95 : system{system_}, service_name{service_name_}, max_sessions{max_sessions_},
96 handler_invoker{handler_invoker_} {}
96 97
97ServiceFrameworkBase::~ServiceFrameworkBase() = default; 98ServiceFrameworkBase::~ServiceFrameworkBase() = default;
98 99
@@ -146,8 +147,8 @@ void ServiceFrameworkBase::ReportUnimplementedFunction(Kernel::HLERequestContext
146 } 147 }
147 buf.push_back('}'); 148 buf.push_back('}');
148 149
149 Core::System::GetInstance().GetReporter().SaveUnimplementedFunctionReport( 150 system.GetReporter().SaveUnimplementedFunctionReport(ctx, ctx.GetCommand(), function_name,
150 ctx, ctx.GetCommand(), function_name, service_name); 151 service_name);
151 UNIMPLEMENTED_MSG("Unknown / unimplemented {}", fmt::to_string(buf)); 152 UNIMPLEMENTED_MSG("Unknown / unimplemented {}", fmt::to_string(buf));
152} 153}
153 154
@@ -171,7 +172,7 @@ ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::HLERequestContext& co
171 } 172 }
172 case IPC::CommandType::ControlWithContext: 173 case IPC::CommandType::ControlWithContext:
173 case IPC::CommandType::Control: { 174 case IPC::CommandType::Control: {
174 Core::System::GetInstance().ServiceManager().InvokeControlRequest(context); 175 system.ServiceManager().InvokeControlRequest(context);
175 break; 176 break;
176 } 177 }
177 case IPC::CommandType::RequestWithContext: 178 case IPC::CommandType::RequestWithContext:
@@ -197,7 +198,7 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system
197 198
198 system.GetFileSystemController().CreateFactories(*system.GetFilesystem(), false); 199 system.GetFileSystemController().CreateFactories(*system.GetFilesystem(), false);
199 200
200 SM::ServiceManager::InstallInterfaces(sm, system.Kernel()); 201 SM::ServiceManager::InstallInterfaces(sm, system);
201 202
202 Account::InstallInterfaces(system); 203 Account::InstallInterfaces(system);
203 AM::InstallInterfaces(*sm, *nv_flinger, system); 204 AM::InstallInterfaces(*sm, *nv_flinger, system);
@@ -205,51 +206,51 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system
205 APM::InstallInterfaces(system); 206 APM::InstallInterfaces(system);
206 Audio::InstallInterfaces(*sm, system); 207 Audio::InstallInterfaces(*sm, system);
207 BCAT::InstallInterfaces(system); 208 BCAT::InstallInterfaces(system);
208 BPC::InstallInterfaces(*sm); 209 BPC::InstallInterfaces(*sm, system);
209 BtDrv::InstallInterfaces(*sm, system); 210 BtDrv::InstallInterfaces(*sm, system);
210 BTM::InstallInterfaces(*sm, system); 211 BTM::InstallInterfaces(*sm, system);
211 Capture::InstallInterfaces(*sm); 212 Capture::InstallInterfaces(*sm, system);
212 ERPT::InstallInterfaces(*sm); 213 ERPT::InstallInterfaces(*sm, system);
213 ES::InstallInterfaces(*sm); 214 ES::InstallInterfaces(*sm, system);
214 EUPLD::InstallInterfaces(*sm); 215 EUPLD::InstallInterfaces(*sm, system);
215 Fatal::InstallInterfaces(*sm, system); 216 Fatal::InstallInterfaces(*sm, system);
216 FGM::InstallInterfaces(*sm); 217 FGM::InstallInterfaces(*sm, system);
217 FileSystem::InstallInterfaces(system); 218 FileSystem::InstallInterfaces(system);
218 Friend::InstallInterfaces(*sm, system); 219 Friend::InstallInterfaces(*sm, system);
219 Glue::InstallInterfaces(system); 220 Glue::InstallInterfaces(system);
220 GRC::InstallInterfaces(*sm); 221 GRC::InstallInterfaces(*sm, system);
221 HID::InstallInterfaces(*sm, system); 222 HID::InstallInterfaces(*sm, system);
222 LBL::InstallInterfaces(*sm); 223 LBL::InstallInterfaces(*sm, system);
223 LDN::InstallInterfaces(*sm); 224 LDN::InstallInterfaces(*sm, system);
224 LDR::InstallInterfaces(*sm, system); 225 LDR::InstallInterfaces(*sm, system);
225 LM::InstallInterfaces(system); 226 LM::InstallInterfaces(system);
226 Migration::InstallInterfaces(*sm); 227 Migration::InstallInterfaces(*sm, system);
227 Mii::InstallInterfaces(*sm); 228 Mii::InstallInterfaces(*sm, system);
228 MM::InstallInterfaces(*sm); 229 MM::InstallInterfaces(*sm, system);
229 NCM::InstallInterfaces(*sm); 230 NCM::InstallInterfaces(*sm, system);
230 NFC::InstallInterfaces(*sm); 231 NFC::InstallInterfaces(*sm, system);
231 NFP::InstallInterfaces(*sm, system); 232 NFP::InstallInterfaces(*sm, system);
232 NIFM::InstallInterfaces(*sm, system); 233 NIFM::InstallInterfaces(*sm, system);
233 NIM::InstallInterfaces(*sm, system); 234 NIM::InstallInterfaces(*sm, system);
234 NPNS::InstallInterfaces(*sm); 235 NPNS::InstallInterfaces(*sm, system);
235 NS::InstallInterfaces(*sm, system); 236 NS::InstallInterfaces(*sm, system);
236 Nvidia::InstallInterfaces(*sm, *nv_flinger, system); 237 Nvidia::InstallInterfaces(*sm, *nv_flinger, system);
237 OLSC::InstallInterfaces(*sm); 238 OLSC::InstallInterfaces(*sm, system);
238 PCIe::InstallInterfaces(*sm); 239 PCIe::InstallInterfaces(*sm, system);
239 PCTL::InstallInterfaces(*sm); 240 PCTL::InstallInterfaces(*sm, system);
240 PCV::InstallInterfaces(*sm); 241 PCV::InstallInterfaces(*sm, system);
241 PlayReport::InstallInterfaces(*sm, system); 242 PlayReport::InstallInterfaces(*sm, system);
242 PM::InstallInterfaces(system); 243 PM::InstallInterfaces(system);
243 PSC::InstallInterfaces(*sm); 244 PSC::InstallInterfaces(*sm, system);
244 PSM::InstallInterfaces(*sm); 245 PSM::InstallInterfaces(*sm, system);
245 Set::InstallInterfaces(*sm); 246 Set::InstallInterfaces(*sm, system);
246 Sockets::InstallInterfaces(*sm, system); 247 Sockets::InstallInterfaces(*sm, system);
247 SPL::InstallInterfaces(*sm); 248 SPL::InstallInterfaces(*sm, system);
248 SSL::InstallInterfaces(*sm); 249 SSL::InstallInterfaces(*sm, system);
249 Time::InstallInterfaces(system); 250 Time::InstallInterfaces(system);
250 USB::InstallInterfaces(*sm); 251 USB::InstallInterfaces(*sm, system);
251 VI::InstallInterfaces(*sm, *nv_flinger); 252 VI::InstallInterfaces(*sm, system, *nv_flinger);
252 WLAN::InstallInterfaces(*sm); 253 WLAN::InstallInterfaces(*sm, system);
253} 254}
254 255
255Services::~Services() = default; 256Services::~Services() = default;
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index ed4792289..62a182310 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -80,6 +80,9 @@ protected:
80 template <typename Self> 80 template <typename Self>
81 using HandlerFnP = void (Self::*)(Kernel::HLERequestContext&); 81 using HandlerFnP = void (Self::*)(Kernel::HLERequestContext&);
82 82
83 /// System context that the service operates under.
84 Core::System& system;
85
83private: 86private:
84 template <typename T> 87 template <typename T>
85 friend class ServiceFramework; 88 friend class ServiceFramework;
@@ -93,7 +96,8 @@ private:
93 using InvokerFn = void(ServiceFrameworkBase* object, HandlerFnP<ServiceFrameworkBase> member, 96 using InvokerFn = void(ServiceFrameworkBase* object, HandlerFnP<ServiceFrameworkBase> member,
94 Kernel::HLERequestContext& ctx); 97 Kernel::HLERequestContext& ctx);
95 98
96 ServiceFrameworkBase(const char* service_name, u32 max_sessions, InvokerFn* handler_invoker); 99 explicit ServiceFrameworkBase(Core::System& system_, const char* service_name_,
100 u32 max_sessions_, InvokerFn* handler_invoker_);
97 ~ServiceFrameworkBase() override; 101 ~ServiceFrameworkBase() override;
98 102
99 void RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n); 103 void RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n);
@@ -151,11 +155,15 @@ protected:
151 155
152 /** 156 /**
153 * Initializes the handler with no functions installed. 157 * Initializes the handler with no functions installed.
154 * @param max_sessions Maximum number of sessions that can be 158 *
155 * connected to this service at the same time. 159 * @param system_ The system context to construct this service under.
160 * @param service_name_ Name of the service.
161 * @param max_sessions_ Maximum number of sessions that can be
162 * connected to this service at the same time.
156 */ 163 */
157 explicit ServiceFramework(const char* service_name, u32 max_sessions = DefaultMaxSessions) 164 explicit ServiceFramework(Core::System& system_, const char* service_name_,
158 : ServiceFrameworkBase(service_name, max_sessions, Invoker) {} 165 u32 max_sessions_ = DefaultMaxSessions)
166 : ServiceFrameworkBase(system_, service_name_, max_sessions_, Invoker) {}
159 167
160 /// Registers handlers in the service. 168 /// Registers handlers in the service.
161 template <std::size_t N> 169 template <std::size_t N>
diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp
index ffbf90b00..d953b4303 100644
--- a/src/core/hle/service/set/set.cpp
+++ b/src/core/hle/service/set/set.cpp
@@ -188,7 +188,7 @@ void SET::GetKeyCodeMap2(Kernel::HLERequestContext& ctx) {
188 GetKeyCodeMapImpl(ctx); 188 GetKeyCodeMapImpl(ctx);
189} 189}
190 190
191SET::SET() : ServiceFramework("set") { 191SET::SET(Core::System& system_) : ServiceFramework{system_, "set"} {
192 // clang-format off 192 // clang-format off
193 static const FunctionInfo functions[] = { 193 static const FunctionInfo functions[] = {
194 {0, &SET::GetLanguageCode, "GetLanguageCode"}, 194 {0, &SET::GetLanguageCode, "GetLanguageCode"},
diff --git a/src/core/hle/service/set/set.h b/src/core/hle/service/set/set.h
index 8ac9c169d..d5bd7828d 100644
--- a/src/core/hle/service/set/set.h
+++ b/src/core/hle/service/set/set.h
@@ -6,6 +6,10 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::Set { 13namespace Service::Set {
10 14
11/// This is "nn::settings::LanguageCode", which is a NUL-terminated string stored in a u64. 15/// This is "nn::settings::LanguageCode", which is a NUL-terminated string stored in a u64.
@@ -32,7 +36,7 @@ LanguageCode GetLanguageCodeFromIndex(std::size_t idx);
32 36
33class SET final : public ServiceFramework<SET> { 37class SET final : public ServiceFramework<SET> {
34public: 38public:
35 explicit SET(); 39 explicit SET(Core::System& system_);
36 ~SET() override; 40 ~SET() override;
37 41
38private: 42private:
diff --git a/src/core/hle/service/set/set_cal.cpp b/src/core/hle/service/set/set_cal.cpp
index 3fbfecc9e..b2aa7bc0c 100644
--- a/src/core/hle/service/set/set_cal.cpp
+++ b/src/core/hle/service/set/set_cal.cpp
@@ -6,7 +6,7 @@
6 6
7namespace Service::Set { 7namespace Service::Set {
8 8
9SET_CAL::SET_CAL() : ServiceFramework("set:cal") { 9SET_CAL::SET_CAL(Core::System& system_) : ServiceFramework{system_, "set:cal"} {
10 // clang-format off 10 // clang-format off
11 static const FunctionInfo functions[] = { 11 static const FunctionInfo functions[] = {
12 {0, nullptr, "GetBluetoothBdAddress"}, 12 {0, nullptr, "GetBluetoothBdAddress"},
diff --git a/src/core/hle/service/set/set_cal.h b/src/core/hle/service/set/set_cal.h
index a0677e815..a29fc3ddd 100644
--- a/src/core/hle/service/set/set_cal.h
+++ b/src/core/hle/service/set/set_cal.h
@@ -6,11 +6,15 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::Set { 13namespace Service::Set {
10 14
11class SET_CAL final : public ServiceFramework<SET_CAL> { 15class SET_CAL final : public ServiceFramework<SET_CAL> {
12public: 16public:
13 explicit SET_CAL(); 17 explicit SET_CAL(Core::System& system_);
14 ~SET_CAL() override; 18 ~SET_CAL() override;
15}; 19};
16 20
diff --git a/src/core/hle/service/set/set_fd.cpp b/src/core/hle/service/set/set_fd.cpp
index 565882a31..f04dc5047 100644
--- a/src/core/hle/service/set/set_fd.cpp
+++ b/src/core/hle/service/set/set_fd.cpp
@@ -6,7 +6,7 @@
6 6
7namespace Service::Set { 7namespace Service::Set {
8 8
9SET_FD::SET_FD() : ServiceFramework("set:fd") { 9SET_FD::SET_FD(Core::System& system_) : ServiceFramework{system_, "set:fd"} {
10 // clang-format off 10 // clang-format off
11 static const FunctionInfo functions[] = { 11 static const FunctionInfo functions[] = {
12 {2, nullptr, "SetSettingsItemValue"}, 12 {2, nullptr, "SetSettingsItemValue"},
diff --git a/src/core/hle/service/set/set_fd.h b/src/core/hle/service/set/set_fd.h
index 216e65f1f..c28cb301e 100644
--- a/src/core/hle/service/set/set_fd.h
+++ b/src/core/hle/service/set/set_fd.h
@@ -6,11 +6,15 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::Set { 13namespace Service::Set {
10 14
11class SET_FD final : public ServiceFramework<SET_FD> { 15class SET_FD final : public ServiceFramework<SET_FD> {
12public: 16public:
13 explicit SET_FD(); 17 explicit SET_FD(Core::System& system_);
14 ~SET_FD() override; 18 ~SET_FD() override;
15}; 19};
16 20
diff --git a/src/core/hle/service/set/set_sys.cpp b/src/core/hle/service/set/set_sys.cpp
index 080b5743e..19b8f113d 100644
--- a/src/core/hle/service/set/set_sys.cpp
+++ b/src/core/hle/service/set/set_sys.cpp
@@ -103,7 +103,7 @@ void SET_SYS::SetColorSetId(Kernel::HLERequestContext& ctx) {
103 rb.Push(RESULT_SUCCESS); 103 rb.Push(RESULT_SUCCESS);
104} 104}
105 105
106SET_SYS::SET_SYS() : ServiceFramework("set:sys") { 106SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
107 // clang-format off 107 // clang-format off
108 static const FunctionInfo functions[] = { 108 static const FunctionInfo functions[] = {
109 {0, nullptr, "SetLanguageCode"}, 109 {0, nullptr, "SetLanguageCode"},
diff --git a/src/core/hle/service/set/set_sys.h b/src/core/hle/service/set/set_sys.h
index 13ee2cf46..edb185a68 100644
--- a/src/core/hle/service/set/set_sys.h
+++ b/src/core/hle/service/set/set_sys.h
@@ -6,11 +6,15 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::Set { 13namespace Service::Set {
10 14
11class SET_SYS final : public ServiceFramework<SET_SYS> { 15class SET_SYS final : public ServiceFramework<SET_SYS> {
12public: 16public:
13 explicit SET_SYS(); 17 explicit SET_SYS(Core::System& system_);
14 ~SET_SYS() override; 18 ~SET_SYS() override;
15 19
16private: 20private:
diff --git a/src/core/hle/service/set/settings.cpp b/src/core/hle/service/set/settings.cpp
index cf5541ca8..212ebc427 100644
--- a/src/core/hle/service/set/settings.cpp
+++ b/src/core/hle/service/set/settings.cpp
@@ -7,14 +7,15 @@
7#include "core/hle/service/set/set_fd.h" 7#include "core/hle/service/set/set_fd.h"
8#include "core/hle/service/set/set_sys.h" 8#include "core/hle/service/set/set_sys.h"
9#include "core/hle/service/set/settings.h" 9#include "core/hle/service/set/settings.h"
10#include "core/hle/service/sm/sm.h"
10 11
11namespace Service::Set { 12namespace Service::Set {
12 13
13void InstallInterfaces(SM::ServiceManager& service_manager) { 14void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
14 std::make_shared<SET>()->InstallAsService(service_manager); 15 std::make_shared<SET>(system)->InstallAsService(service_manager);
15 std::make_shared<SET_CAL>()->InstallAsService(service_manager); 16 std::make_shared<SET_CAL>(system)->InstallAsService(service_manager);
16 std::make_shared<SET_FD>()->InstallAsService(service_manager); 17 std::make_shared<SET_FD>(system)->InstallAsService(service_manager);
17 std::make_shared<SET_SYS>()->InstallAsService(service_manager); 18 std::make_shared<SET_SYS>(system)->InstallAsService(service_manager);
18} 19}
19 20
20} // namespace Service::Set 21} // namespace Service::Set
diff --git a/src/core/hle/service/set/settings.h b/src/core/hle/service/set/settings.h
index 6606ce776..7a6950dd0 100644
--- a/src/core/hle/service/set/settings.h
+++ b/src/core/hle/service/set/settings.h
@@ -4,11 +4,17 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "core/hle/service/service.h" 7namespace Core {
8class System;
9}
10
11namespace Service::SM {
12class ServiceManager;
13}
8 14
9namespace Service::Set { 15namespace Service::Set {
10 16
11/// Registers all Settings services with the specified service manager. 17/// Registers all Settings services with the specified service manager.
12void InstallInterfaces(SM::ServiceManager& service_manager); 18void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
13 19
14} // namespace Service::Set 20} // namespace Service::Set
diff --git a/src/core/hle/service/sm/controller.cpp b/src/core/hle/service/sm/controller.cpp
index 972aaa6d9..916177efd 100644
--- a/src/core/hle/service/sm/controller.cpp
+++ b/src/core/hle/service/sm/controller.cpp
@@ -48,7 +48,7 @@ void Controller::QueryPointerBufferSize(Kernel::HLERequestContext& ctx) {
48} 48}
49 49
50// https://switchbrew.org/wiki/IPC_Marshalling 50// https://switchbrew.org/wiki/IPC_Marshalling
51Controller::Controller() : ServiceFramework("IpcController") { 51Controller::Controller(Core::System& system_) : ServiceFramework{system_, "IpcController"} {
52 static const FunctionInfo functions[] = { 52 static const FunctionInfo functions[] = {
53 {0, &Controller::ConvertCurrentObjectToDomain, "ConvertCurrentObjectToDomain"}, 53 {0, &Controller::ConvertCurrentObjectToDomain, "ConvertCurrentObjectToDomain"},
54 {1, nullptr, "CopyFromCurrentDomain"}, 54 {1, nullptr, "CopyFromCurrentDomain"},
diff --git a/src/core/hle/service/sm/controller.h b/src/core/hle/service/sm/controller.h
index 180c6da50..7494f898d 100644
--- a/src/core/hle/service/sm/controller.h
+++ b/src/core/hle/service/sm/controller.h
@@ -6,11 +6,15 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::SM { 13namespace Service::SM {
10 14
11class Controller final : public ServiceFramework<Controller> { 15class Controller final : public ServiceFramework<Controller> {
12public: 16public:
13 Controller(); 17 explicit Controller(Core::System& system_);
14 ~Controller() override; 18 ~Controller() override;
15 19
16private: 20private:
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp
index 9c1da361b..4da69f503 100644
--- a/src/core/hle/service/sm/sm.cpp
+++ b/src/core/hle/service/sm/sm.cpp
@@ -38,14 +38,13 @@ static ResultCode ValidateServiceName(const std::string& name) {
38 return RESULT_SUCCESS; 38 return RESULT_SUCCESS;
39} 39}
40 40
41void ServiceManager::InstallInterfaces(std::shared_ptr<ServiceManager> self, 41void ServiceManager::InstallInterfaces(std::shared_ptr<ServiceManager> self, Core::System& system) {
42 Kernel::KernelCore& kernel) {
43 ASSERT(self->sm_interface.expired()); 42 ASSERT(self->sm_interface.expired());
44 43
45 auto sm = std::make_shared<SM>(self, kernel); 44 auto sm = std::make_shared<SM>(self, system);
46 sm->InstallAsNamedPort(kernel); 45 sm->InstallAsNamedPort(system.Kernel());
47 self->sm_interface = sm; 46 self->sm_interface = sm;
48 self->controller_interface = std::make_unique<Controller>(); 47 self->controller_interface = std::make_unique<Controller>(system);
49} 48}
50 49
51ResultVal<std::shared_ptr<Kernel::ServerPort>> ServiceManager::RegisterService(std::string name, 50ResultVal<std::shared_ptr<Kernel::ServerPort>> ServiceManager::RegisterService(std::string name,
@@ -190,8 +189,9 @@ void SM::UnregisterService(Kernel::HLERequestContext& ctx) {
190 rb.Push(service_manager->UnregisterService(name)); 189 rb.Push(service_manager->UnregisterService(name));
191} 190}
192 191
193SM::SM(std::shared_ptr<ServiceManager> service_manager, Kernel::KernelCore& kernel) 192SM::SM(std::shared_ptr<ServiceManager> service_manager_, Core::System& system_)
194 : ServiceFramework{"sm:", 4}, service_manager{std::move(service_manager)}, kernel{kernel} { 193 : ServiceFramework{system_, "sm:", 4},
194 service_manager{std::move(service_manager_)}, kernel{system_.Kernel()} {
195 static const FunctionInfo functions[] = { 195 static const FunctionInfo functions[] = {
196 {0x00000000, &SM::Initialize, "Initialize"}, 196 {0x00000000, &SM::Initialize, "Initialize"},
197 {0x00000001, &SM::GetService, "GetService"}, 197 {0x00000001, &SM::GetService, "GetService"},
diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h
index 6790c86f0..3f46ae44f 100644
--- a/src/core/hle/service/sm/sm.h
+++ b/src/core/hle/service/sm/sm.h
@@ -16,6 +16,10 @@
16#include "core/hle/result.h" 16#include "core/hle/result.h"
17#include "core/hle/service/service.h" 17#include "core/hle/service/service.h"
18 18
19namespace Core {
20class System;
21}
22
19namespace Kernel { 23namespace Kernel {
20class ClientPort; 24class ClientPort;
21class ClientSession; 25class ClientSession;
@@ -31,7 +35,7 @@ class Controller;
31/// Interface to "sm:" service 35/// Interface to "sm:" service
32class SM final : public ServiceFramework<SM> { 36class SM final : public ServiceFramework<SM> {
33public: 37public:
34 explicit SM(std::shared_ptr<ServiceManager> service_manager, Kernel::KernelCore& kernel); 38 explicit SM(std::shared_ptr<ServiceManager> service_manager_, Core::System& system_);
35 ~SM() override; 39 ~SM() override;
36 40
37private: 41private:
@@ -46,7 +50,7 @@ private:
46 50
47class ServiceManager { 51class ServiceManager {
48public: 52public:
49 static void InstallInterfaces(std::shared_ptr<ServiceManager> self, Kernel::KernelCore& kernel); 53 static void InstallInterfaces(std::shared_ptr<ServiceManager> self, Core::System& system);
50 54
51 explicit ServiceManager(Kernel::KernelCore& kernel_); 55 explicit ServiceManager(Kernel::KernelCore& kernel_);
52 ~ServiceManager(); 56 ~ServiceManager();
diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp
index a74be9370..a9875b9a6 100644
--- a/src/core/hle/service/sockets/bsd.cpp
+++ b/src/core/hle/service/sockets/bsd.cpp
@@ -827,8 +827,8 @@ void BSD::BuildErrnoResponse(Kernel::HLERequestContext& ctx, Errno bsd_errno) co
827 rb.PushEnum(bsd_errno); 827 rb.PushEnum(bsd_errno);
828} 828}
829 829
830BSD::BSD(Core::System& system, const char* name) 830BSD::BSD(Core::System& system_, const char* name)
831 : ServiceFramework(name), worker_pool{system, this} { 831 : ServiceFramework{system_, name}, worker_pool{system_, this} {
832 // clang-format off 832 // clang-format off
833 static const FunctionInfo functions[] = { 833 static const FunctionInfo functions[] = {
834 {0, &BSD::RegisterClient, "RegisterClient"}, 834 {0, &BSD::RegisterClient, "RegisterClient"},
@@ -873,7 +873,7 @@ BSD::BSD(Core::System& system, const char* name)
873 873
874BSD::~BSD() = default; 874BSD::~BSD() = default;
875 875
876BSDCFG::BSDCFG() : ServiceFramework{"bsdcfg"} { 876BSDCFG::BSDCFG(Core::System& system_) : ServiceFramework{system_, "bsdcfg"} {
877 // clang-format off 877 // clang-format off
878 static const FunctionInfo functions[] = { 878 static const FunctionInfo functions[] = {
879 {0, nullptr, "SetIfUp"}, 879 {0, nullptr, "SetIfUp"},
diff --git a/src/core/hle/service/sockets/bsd.h b/src/core/hle/service/sockets/bsd.h
index 357531951..f14713fc4 100644
--- a/src/core/hle/service/sockets/bsd.h
+++ b/src/core/hle/service/sockets/bsd.h
@@ -26,7 +26,7 @@ namespace Service::Sockets {
26 26
27class BSD final : public ServiceFramework<BSD> { 27class BSD final : public ServiceFramework<BSD> {
28public: 28public:
29 explicit BSD(Core::System& system, const char* name); 29 explicit BSD(Core::System& system_, const char* name);
30 ~BSD() override; 30 ~BSD() override;
31 31
32private: 32private:
@@ -176,7 +176,7 @@ private:
176 176
177class BSDCFG final : public ServiceFramework<BSDCFG> { 177class BSDCFG final : public ServiceFramework<BSDCFG> {
178public: 178public:
179 explicit BSDCFG(); 179 explicit BSDCFG(Core::System& system_);
180 ~BSDCFG() override; 180 ~BSDCFG() override;
181}; 181};
182 182
diff --git a/src/core/hle/service/sockets/ethc.cpp b/src/core/hle/service/sockets/ethc.cpp
index abbeb4c50..05681ca2d 100644
--- a/src/core/hle/service/sockets/ethc.cpp
+++ b/src/core/hle/service/sockets/ethc.cpp
@@ -6,7 +6,7 @@
6 6
7namespace Service::Sockets { 7namespace Service::Sockets {
8 8
9ETHC_C::ETHC_C() : ServiceFramework{"ethc:c"} { 9ETHC_C::ETHC_C(Core::System& system_) : ServiceFramework{system_, "ethc:c"} {
10 // clang-format off 10 // clang-format off
11 static const FunctionInfo functions[] = { 11 static const FunctionInfo functions[] = {
12 {0, nullptr, "Initialize"}, 12 {0, nullptr, "Initialize"},
@@ -23,7 +23,7 @@ ETHC_C::ETHC_C() : ServiceFramework{"ethc:c"} {
23 23
24ETHC_C::~ETHC_C() = default; 24ETHC_C::~ETHC_C() = default;
25 25
26ETHC_I::ETHC_I() : ServiceFramework{"ethc:i"} { 26ETHC_I::ETHC_I(Core::System& system_) : ServiceFramework{system_, "ethc:i"} {
27 // clang-format off 27 // clang-format off
28 static const FunctionInfo functions[] = { 28 static const FunctionInfo functions[] = {
29 {0, nullptr, "GetReadableHandle"}, 29 {0, nullptr, "GetReadableHandle"},
diff --git a/src/core/hle/service/sockets/ethc.h b/src/core/hle/service/sockets/ethc.h
index da2c7f741..71884182e 100644
--- a/src/core/hle/service/sockets/ethc.h
+++ b/src/core/hle/service/sockets/ethc.h
@@ -6,17 +6,21 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::Sockets { 13namespace Service::Sockets {
10 14
11class ETHC_C final : public ServiceFramework<ETHC_C> { 15class ETHC_C final : public ServiceFramework<ETHC_C> {
12public: 16public:
13 explicit ETHC_C(); 17 explicit ETHC_C(Core::System& system_);
14 ~ETHC_C() override; 18 ~ETHC_C() override;
15}; 19};
16 20
17class ETHC_I final : public ServiceFramework<ETHC_I> { 21class ETHC_I final : public ServiceFramework<ETHC_I> {
18public: 22public:
19 explicit ETHC_I(); 23 explicit ETHC_I(Core::System& system_);
20 ~ETHC_I() override; 24 ~ETHC_I() override;
21}; 25};
22 26
diff --git a/src/core/hle/service/sockets/nsd.cpp b/src/core/hle/service/sockets/nsd.cpp
index 40d781124..51c3739bb 100644
--- a/src/core/hle/service/sockets/nsd.cpp
+++ b/src/core/hle/service/sockets/nsd.cpp
@@ -6,7 +6,7 @@
6 6
7namespace Service::Sockets { 7namespace Service::Sockets {
8 8
9NSD::NSD(const char* name) : ServiceFramework(name) { 9NSD::NSD(Core::System& system_, const char* name) : ServiceFramework{system_, name} {
10 // clang-format off 10 // clang-format off
11 static const FunctionInfo functions[] = { 11 static const FunctionInfo functions[] = {
12 {10, nullptr, "GetSettingName"}, 12 {10, nullptr, "GetSettingName"},
diff --git a/src/core/hle/service/sockets/nsd.h b/src/core/hle/service/sockets/nsd.h
index d842e3232..becf93125 100644
--- a/src/core/hle/service/sockets/nsd.h
+++ b/src/core/hle/service/sockets/nsd.h
@@ -4,14 +4,17 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "core/hle/kernel/hle_ipc.h"
8#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
9 8
9namespace Core {
10class System;
11}
12
10namespace Service::Sockets { 13namespace Service::Sockets {
11 14
12class NSD final : public ServiceFramework<NSD> { 15class NSD final : public ServiceFramework<NSD> {
13public: 16public:
14 explicit NSD(const char* name); 17 explicit NSD(Core::System& system_, const char* name);
15 ~NSD() override; 18 ~NSD() override;
16}; 19};
17 20
diff --git a/src/core/hle/service/sockets/sfdnsres.cpp b/src/core/hle/service/sockets/sfdnsres.cpp
index e3017451f..3a6329f56 100644
--- a/src/core/hle/service/sockets/sfdnsres.cpp
+++ b/src/core/hle/service/sockets/sfdnsres.cpp
@@ -7,25 +7,7 @@
7 7
8namespace Service::Sockets { 8namespace Service::Sockets {
9 9
10void SFDNSRES::GetAddrInfoRequest(Kernel::HLERequestContext& ctx) { 10SFDNSRES::SFDNSRES(Core::System& system_) : ServiceFramework{system_, "sfdnsres"} {
11 struct Parameters {
12 u8 use_nsd_resolve;
13 u32 unknown;
14 u64 process_id;
15 };
16
17 IPC::RequestParser rp{ctx};
18 const auto parameters = rp.PopRaw<Parameters>();
19
20 LOG_WARNING(Service,
21 "(STUBBED) called. use_nsd_resolve={}, unknown=0x{:08X}, process_id=0x{:016X}",
22 parameters.use_nsd_resolve, parameters.unknown, parameters.process_id);
23
24 IPC::ResponseBuilder rb{ctx, 2};
25 rb.Push(RESULT_SUCCESS);
26}
27
28SFDNSRES::SFDNSRES() : ServiceFramework("sfdnsres") {
29 static const FunctionInfo functions[] = { 11 static const FunctionInfo functions[] = {
30 {0, nullptr, "SetDnsAddressesPrivate"}, 12 {0, nullptr, "SetDnsAddressesPrivate"},
31 {1, nullptr, "GetDnsAddressPrivate"}, 13 {1, nullptr, "GetDnsAddressPrivate"},
@@ -49,4 +31,22 @@ SFDNSRES::SFDNSRES() : ServiceFramework("sfdnsres") {
49 31
50SFDNSRES::~SFDNSRES() = default; 32SFDNSRES::~SFDNSRES() = default;
51 33
34void SFDNSRES::GetAddrInfoRequest(Kernel::HLERequestContext& ctx) {
35 struct Parameters {
36 u8 use_nsd_resolve;
37 u32 unknown;
38 u64 process_id;
39 };
40
41 IPC::RequestParser rp{ctx};
42 const auto parameters = rp.PopRaw<Parameters>();
43
44 LOG_WARNING(Service,
45 "(STUBBED) called. use_nsd_resolve={}, unknown=0x{:08X}, process_id=0x{:016X}",
46 parameters.use_nsd_resolve, parameters.unknown, parameters.process_id);
47
48 IPC::ResponseBuilder rb{ctx, 2};
49 rb.Push(RESULT_SUCCESS);
50}
51
52} // namespace Service::Sockets 52} // namespace Service::Sockets
diff --git a/src/core/hle/service/sockets/sfdnsres.h b/src/core/hle/service/sockets/sfdnsres.h
index acd3647bb..faa6b7d0d 100644
--- a/src/core/hle/service/sockets/sfdnsres.h
+++ b/src/core/hle/service/sockets/sfdnsres.h
@@ -7,11 +7,15 @@
7#include "core/hle/kernel/hle_ipc.h" 7#include "core/hle/kernel/hle_ipc.h"
8#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
9 9
10namespace Core {
11class System;
12}
13
10namespace Service::Sockets { 14namespace Service::Sockets {
11 15
12class SFDNSRES final : public ServiceFramework<SFDNSRES> { 16class SFDNSRES final : public ServiceFramework<SFDNSRES> {
13public: 17public:
14 explicit SFDNSRES(); 18 explicit SFDNSRES(Core::System& system_);
15 ~SFDNSRES() override; 19 ~SFDNSRES() override;
16 20
17private: 21private:
diff --git a/src/core/hle/service/sockets/sockets.cpp b/src/core/hle/service/sockets/sockets.cpp
index 1d27f7906..96f73bce3 100644
--- a/src/core/hle/service/sockets/sockets.cpp
+++ b/src/core/hle/service/sockets/sockets.cpp
@@ -13,15 +13,15 @@ namespace Service::Sockets {
13void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 13void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
14 std::make_shared<BSD>(system, "bsd:s")->InstallAsService(service_manager); 14 std::make_shared<BSD>(system, "bsd:s")->InstallAsService(service_manager);
15 std::make_shared<BSD>(system, "bsd:u")->InstallAsService(service_manager); 15 std::make_shared<BSD>(system, "bsd:u")->InstallAsService(service_manager);
16 std::make_shared<BSDCFG>()->InstallAsService(service_manager); 16 std::make_shared<BSDCFG>(system)->InstallAsService(service_manager);
17 17
18 std::make_shared<ETHC_C>()->InstallAsService(service_manager); 18 std::make_shared<ETHC_C>(system)->InstallAsService(service_manager);
19 std::make_shared<ETHC_I>()->InstallAsService(service_manager); 19 std::make_shared<ETHC_I>(system)->InstallAsService(service_manager);
20 20
21 std::make_shared<NSD>("nsd:a")->InstallAsService(service_manager); 21 std::make_shared<NSD>(system, "nsd:a")->InstallAsService(service_manager);
22 std::make_shared<NSD>("nsd:u")->InstallAsService(service_manager); 22 std::make_shared<NSD>(system, "nsd:u")->InstallAsService(service_manager);
23 23
24 std::make_shared<SFDNSRES>()->InstallAsService(service_manager); 24 std::make_shared<SFDNSRES>(system)->InstallAsService(service_manager);
25} 25}
26 26
27} // namespace Service::Sockets 27} // namespace Service::Sockets
diff --git a/src/core/hle/service/spl/csrng.cpp b/src/core/hle/service/spl/csrng.cpp
index 674928798..1beca417c 100644
--- a/src/core/hle/service/spl/csrng.cpp
+++ b/src/core/hle/service/spl/csrng.cpp
@@ -6,7 +6,8 @@
6 6
7namespace Service::SPL { 7namespace Service::SPL {
8 8
9CSRNG::CSRNG(std::shared_ptr<Module> module) : Module::Interface(std::move(module), "csrng") { 9CSRNG::CSRNG(Core::System& system_, std::shared_ptr<Module> module_)
10 : Interface(system_, std::move(module_), "csrng") {
10 static const FunctionInfo functions[] = { 11 static const FunctionInfo functions[] = {
11 {0, &CSRNG::GetRandomBytes, "GetRandomBytes"}, 12 {0, &CSRNG::GetRandomBytes, "GetRandomBytes"},
12 }; 13 };
diff --git a/src/core/hle/service/spl/csrng.h b/src/core/hle/service/spl/csrng.h
index 764d5ceb0..5c0bd2199 100644
--- a/src/core/hle/service/spl/csrng.h
+++ b/src/core/hle/service/spl/csrng.h
@@ -6,11 +6,15 @@
6 6
7#include "core/hle/service/spl/module.h" 7#include "core/hle/service/spl/module.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::SPL { 13namespace Service::SPL {
10 14
11class CSRNG final : public Module::Interface { 15class CSRNG final : public Module::Interface {
12public: 16public:
13 explicit CSRNG(std::shared_ptr<Module> module); 17 explicit CSRNG(Core::System& system_, std::shared_ptr<Module> module_);
14 ~CSRNG() override; 18 ~CSRNG() override;
15}; 19};
16 20
diff --git a/src/core/hle/service/spl/module.cpp b/src/core/hle/service/spl/module.cpp
index 865ed3b91..dea6b0fe0 100644
--- a/src/core/hle/service/spl/module.cpp
+++ b/src/core/hle/service/spl/module.cpp
@@ -17,8 +17,9 @@
17 17
18namespace Service::SPL { 18namespace Service::SPL {
19 19
20Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) 20Module::Interface::Interface(Core::System& system_, std::shared_ptr<Module> module_,
21 : ServiceFramework(name), module(std::move(module)), 21 const char* name)
22 : ServiceFramework{system_, name}, module{std::move(module_)},
22 rng(Settings::values.rng_seed.GetValue().value_or(std::time(nullptr))) {} 23 rng(Settings::values.rng_seed.GetValue().value_or(std::time(nullptr))) {}
23 24
24Module::Interface::~Interface() = default; 25Module::Interface::~Interface() = default;
@@ -38,10 +39,10 @@ void Module::Interface::GetRandomBytes(Kernel::HLERequestContext& ctx) {
38 rb.Push(RESULT_SUCCESS); 39 rb.Push(RESULT_SUCCESS);
39} 40}
40 41
41void InstallInterfaces(SM::ServiceManager& service_manager) { 42void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
42 auto module = std::make_shared<Module>(); 43 auto module = std::make_shared<Module>();
43 std::make_shared<CSRNG>(module)->InstallAsService(service_manager); 44 std::make_shared<CSRNG>(system, module)->InstallAsService(service_manager);
44 std::make_shared<SPL>(module)->InstallAsService(service_manager); 45 std::make_shared<SPL>(system, module)->InstallAsService(service_manager);
45} 46}
46 47
47} // namespace Service::SPL 48} // namespace Service::SPL
diff --git a/src/core/hle/service/spl/module.h b/src/core/hle/service/spl/module.h
index afa1f0295..71855c1bf 100644
--- a/src/core/hle/service/spl/module.h
+++ b/src/core/hle/service/spl/module.h
@@ -7,13 +7,18 @@
7#include <random> 7#include <random>
8#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
9 9
10namespace Core {
11class System;
12}
13
10namespace Service::SPL { 14namespace Service::SPL {
11 15
12class Module final { 16class Module final {
13public: 17public:
14 class Interface : public ServiceFramework<Interface> { 18 class Interface : public ServiceFramework<Interface> {
15 public: 19 public:
16 explicit Interface(std::shared_ptr<Module> module, const char* name); 20 explicit Interface(Core::System& system_, std::shared_ptr<Module> module_,
21 const char* name);
17 ~Interface() override; 22 ~Interface() override;
18 23
19 void GetRandomBytes(Kernel::HLERequestContext& ctx); 24 void GetRandomBytes(Kernel::HLERequestContext& ctx);
@@ -27,6 +32,6 @@ public:
27}; 32};
28 33
29/// Registers all SPL services with the specified service manager. 34/// Registers all SPL services with the specified service manager.
30void InstallInterfaces(SM::ServiceManager& service_manager); 35void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
31 36
32} // namespace Service::SPL 37} // namespace Service::SPL
diff --git a/src/core/hle/service/spl/spl.cpp b/src/core/hle/service/spl/spl.cpp
index 773551464..3fabc2c79 100644
--- a/src/core/hle/service/spl/spl.cpp
+++ b/src/core/hle/service/spl/spl.cpp
@@ -6,7 +6,8 @@
6 6
7namespace Service::SPL { 7namespace Service::SPL {
8 8
9SPL::SPL(std::shared_ptr<Module> module) : Module::Interface(std::move(module), "spl:") { 9SPL::SPL(Core::System& system_, std::shared_ptr<Module> module_)
10 : Interface(system_, std::move(module_), "spl:") {
10 static const FunctionInfo functions[] = { 11 static const FunctionInfo functions[] = {
11 {0, nullptr, "GetConfig"}, 12 {0, nullptr, "GetConfig"},
12 {1, nullptr, "ModularExponentiate"}, 13 {1, nullptr, "ModularExponentiate"},
diff --git a/src/core/hle/service/spl/spl.h b/src/core/hle/service/spl/spl.h
index 3637d1623..d27d16b86 100644
--- a/src/core/hle/service/spl/spl.h
+++ b/src/core/hle/service/spl/spl.h
@@ -6,11 +6,15 @@
6 6
7#include "core/hle/service/spl/module.h" 7#include "core/hle/service/spl/module.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::SPL { 13namespace Service::SPL {
10 14
11class SPL final : public Module::Interface { 15class SPL final : public Module::Interface {
12public: 16public:
13 explicit SPL(std::shared_ptr<Module> module); 17 explicit SPL(Core::System& system_, std::shared_ptr<Module> module_);
14 ~SPL() override; 18 ~SPL() override;
15}; 19};
16 20
diff --git a/src/core/hle/service/ssl/ssl.cpp b/src/core/hle/service/ssl/ssl.cpp
index 1ba8c19a0..dc2baca4a 100644
--- a/src/core/hle/service/ssl/ssl.cpp
+++ b/src/core/hle/service/ssl/ssl.cpp
@@ -12,7 +12,7 @@ namespace Service::SSL {
12 12
13class ISslConnection final : public ServiceFramework<ISslConnection> { 13class ISslConnection final : public ServiceFramework<ISslConnection> {
14public: 14public:
15 ISslConnection() : ServiceFramework("ISslConnection") { 15 explicit ISslConnection(Core::System& system_) : ServiceFramework{system_, "ISslConnection"} {
16 // clang-format off 16 // clang-format off
17 static const FunctionInfo functions[] = { 17 static const FunctionInfo functions[] = {
18 {0, nullptr, "SetSocketDescriptor"}, 18 {0, nullptr, "SetSocketDescriptor"},
@@ -52,7 +52,7 @@ public:
52 52
53class ISslContext final : public ServiceFramework<ISslContext> { 53class ISslContext final : public ServiceFramework<ISslContext> {
54public: 54public:
55 ISslContext() : ServiceFramework("ISslContext") { 55 explicit ISslContext(Core::System& system_) : ServiceFramework{system_, "ISslContext"} {
56 static const FunctionInfo functions[] = { 56 static const FunctionInfo functions[] = {
57 {0, &ISslContext::SetOption, "SetOption"}, 57 {0, &ISslContext::SetOption, "SetOption"},
58 {1, nullptr, "GetOption"}, 58 {1, nullptr, "GetOption"},
@@ -92,13 +92,13 @@ private:
92 92
93 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 93 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
94 rb.Push(RESULT_SUCCESS); 94 rb.Push(RESULT_SUCCESS);
95 rb.PushIpcInterface<ISslConnection>(); 95 rb.PushIpcInterface<ISslConnection>(system);
96 } 96 }
97}; 97};
98 98
99class SSL final : public ServiceFramework<SSL> { 99class SSL final : public ServiceFramework<SSL> {
100public: 100public:
101 explicit SSL() : ServiceFramework{"ssl"} { 101 explicit SSL(Core::System& system_) : ServiceFramework{system_, "ssl"} {
102 // clang-format off 102 // clang-format off
103 static const FunctionInfo functions[] = { 103 static const FunctionInfo functions[] = {
104 {0, &SSL::CreateContext, "CreateContext"}, 104 {0, &SSL::CreateContext, "CreateContext"},
@@ -123,7 +123,7 @@ private:
123 123
124 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 124 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
125 rb.Push(RESULT_SUCCESS); 125 rb.Push(RESULT_SUCCESS);
126 rb.PushIpcInterface<ISslContext>(); 126 rb.PushIpcInterface<ISslContext>(system);
127 } 127 }
128 128
129 void SetInterfaceVersion(Kernel::HLERequestContext& ctx) { 129 void SetInterfaceVersion(Kernel::HLERequestContext& ctx) {
@@ -137,8 +137,8 @@ private:
137 } 137 }
138}; 138};
139 139
140void InstallInterfaces(SM::ServiceManager& service_manager) { 140void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
141 std::make_shared<SSL>()->InstallAsService(service_manager); 141 std::make_shared<SSL>(system)->InstallAsService(service_manager);
142} 142}
143 143
144} // namespace Service::SSL 144} // namespace Service::SSL
diff --git a/src/core/hle/service/ssl/ssl.h b/src/core/hle/service/ssl/ssl.h
index 5cb04c3b9..a3aa4b4b5 100644
--- a/src/core/hle/service/ssl/ssl.h
+++ b/src/core/hle/service/ssl/ssl.h
@@ -4,6 +4,10 @@
4 4
5#pragma once 5#pragma once
6 6
7namespace Core {
8class System;
9}
10
7namespace Service::SM { 11namespace Service::SM {
8class ServiceManager; 12class ServiceManager;
9} 13}
@@ -11,6 +15,6 @@ class ServiceManager;
11namespace Service::SSL { 15namespace Service::SSL {
12 16
13/// Registers all SSL services with the specified service manager. 17/// Registers all SSL services with the specified service manager.
14void InstallInterfaces(SM::ServiceManager& service_manager); 18void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
15 19
16} // namespace Service::SSL 20} // namespace Service::SSL
diff --git a/src/core/hle/service/time/interface.cpp b/src/core/hle/service/time/interface.cpp
index ba8fd6152..a01d9e0ff 100644
--- a/src/core/hle/service/time/interface.cpp
+++ b/src/core/hle/service/time/interface.cpp
@@ -7,7 +7,7 @@
7namespace Service::Time { 7namespace Service::Time {
8 8
9Time::Time(std::shared_ptr<Module> module, Core::System& system, const char* name) 9Time::Time(std::shared_ptr<Module> module, Core::System& system, const char* name)
10 : Module::Interface(std::move(module), system, name) { 10 : Interface(std::move(module), system, name) {
11 // clang-format off 11 // clang-format off
12 static const FunctionInfo functions[] = { 12 static const FunctionInfo functions[] = {
13 {0, &Time::GetStandardUserSystemClock, "GetStandardUserSystemClock"}, 13 {0, &Time::GetStandardUserSystemClock, "GetStandardUserSystemClock"},
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp
index 7d0474e0b..7b7ac282d 100644
--- a/src/core/hle/service/time/time.cpp
+++ b/src/core/hle/service/time/time.cpp
@@ -21,8 +21,8 @@ namespace Service::Time {
21 21
22class ISystemClock final : public ServiceFramework<ISystemClock> { 22class ISystemClock final : public ServiceFramework<ISystemClock> {
23public: 23public:
24 explicit ISystemClock(Clock::SystemClockCore& clock_core, Core::System& system) 24 explicit ISystemClock(Clock::SystemClockCore& clock_core_, Core::System& system_)
25 : ServiceFramework("ISystemClock"), clock_core{clock_core}, system{system} { 25 : ServiceFramework{system_, "ISystemClock"}, clock_core{clock_core_} {
26 // clang-format off 26 // clang-format off
27 static const FunctionInfo functions[] = { 27 static const FunctionInfo functions[] = {
28 {0, &ISystemClock::GetCurrentTime, "GetCurrentTime"}, 28 {0, &ISystemClock::GetCurrentTime, "GetCurrentTime"},
@@ -82,13 +82,12 @@ private:
82 } 82 }
83 83
84 Clock::SystemClockCore& clock_core; 84 Clock::SystemClockCore& clock_core;
85 Core::System& system;
86}; 85};
87 86
88class ISteadyClock final : public ServiceFramework<ISteadyClock> { 87class ISteadyClock final : public ServiceFramework<ISteadyClock> {
89public: 88public:
90 explicit ISteadyClock(Clock::SteadyClockCore& clock_core, Core::System& system) 89 explicit ISteadyClock(Clock::SteadyClockCore& clock_core_, Core::System& system_)
91 : ServiceFramework("ISteadyClock"), clock_core{clock_core}, system{system} { 90 : ServiceFramework{system_, "ISteadyClock"}, clock_core{clock_core_} {
92 static const FunctionInfo functions[] = { 91 static const FunctionInfo functions[] = {
93 {0, &ISteadyClock::GetCurrentTimePoint, "GetCurrentTimePoint"}, 92 {0, &ISteadyClock::GetCurrentTimePoint, "GetCurrentTimePoint"},
94 {2, nullptr, "GetTestOffset"}, 93 {2, nullptr, "GetTestOffset"},
@@ -119,7 +118,6 @@ private:
119 } 118 }
120 119
121 Clock::SteadyClockCore& clock_core; 120 Clock::SteadyClockCore& clock_core;
122 Core::System& system;
123}; 121};
124 122
125ResultCode Module::Interface::GetClockSnapshotFromSystemClockContextInternal( 123ResultCode Module::Interface::GetClockSnapshotFromSystemClockContextInternal(
@@ -206,7 +204,8 @@ void Module::Interface::GetTimeZoneService(Kernel::HLERequestContext& ctx) {
206 LOG_DEBUG(Service_Time, "called"); 204 LOG_DEBUG(Service_Time, "called");
207 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 205 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
208 rb.Push(RESULT_SUCCESS); 206 rb.Push(RESULT_SUCCESS);
209 rb.PushIpcInterface<ITimeZoneService>(system.GetTimeManager().GetTimeZoneContentManager()); 207 rb.PushIpcInterface<ITimeZoneService>(system,
208 system.GetTimeManager().GetTimeZoneContentManager());
210} 209}
211 210
212void Module::Interface::GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx) { 211void Module::Interface::GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx) {
@@ -375,8 +374,9 @@ void Module::Interface::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& c
375 rb.PushCopyObjects(SharedFrom(&system.Kernel().GetTimeSharedMem())); 374 rb.PushCopyObjects(SharedFrom(&system.Kernel().GetTimeSharedMem()));
376} 375}
377 376
378Module::Interface::Interface(std::shared_ptr<Module> module, Core::System& system, const char* name) 377Module::Interface::Interface(std::shared_ptr<Module> module_, Core::System& system_,
379 : ServiceFramework(name), module{std::move(module)}, system{system} {} 378 const char* name)
379 : ServiceFramework{system_, name}, module{std::move(module_)} {}
380 380
381Module::Interface::~Interface() = default; 381Module::Interface::~Interface() = default;
382 382
diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h
index 49f4aac0a..975a8ae5b 100644
--- a/src/core/hle/service/time/time.h
+++ b/src/core/hle/service/time/time.h
@@ -20,7 +20,8 @@ public:
20 20
21 class Interface : public ServiceFramework<Interface> { 21 class Interface : public ServiceFramework<Interface> {
22 public: 22 public:
23 explicit Interface(std::shared_ptr<Module> module, Core::System& system, const char* name); 23 explicit Interface(std::shared_ptr<Module> module_, Core::System& system_,
24 const char* name);
24 ~Interface() override; 25 ~Interface() override;
25 26
26 void GetStandardUserSystemClock(Kernel::HLERequestContext& ctx); 27 void GetStandardUserSystemClock(Kernel::HLERequestContext& ctx);
@@ -44,7 +45,6 @@ public:
44 45
45 protected: 46 protected:
46 std::shared_ptr<Module> module; 47 std::shared_ptr<Module> module;
47 Core::System& system;
48 }; 48 };
49}; 49};
50 50
diff --git a/src/core/hle/service/time/time_zone_service.cpp b/src/core/hle/service/time/time_zone_service.cpp
index ff3a10b3e..25cecbc83 100644
--- a/src/core/hle/service/time/time_zone_service.cpp
+++ b/src/core/hle/service/time/time_zone_service.cpp
@@ -10,8 +10,9 @@
10 10
11namespace Service::Time { 11namespace Service::Time {
12 12
13ITimeZoneService ::ITimeZoneService(TimeZone::TimeZoneContentManager& time_zone_content_manager) 13ITimeZoneService ::ITimeZoneService(Core::System& system_,
14 : ServiceFramework("ITimeZoneService"), time_zone_content_manager{time_zone_content_manager} { 14 TimeZone::TimeZoneContentManager& time_zone_manager_)
15 : ServiceFramework{system_, "ITimeZoneService"}, time_zone_content_manager{time_zone_manager_} {
15 static const FunctionInfo functions[] = { 16 static const FunctionInfo functions[] = {
16 {0, &ITimeZoneService::GetDeviceLocationName, "GetDeviceLocationName"}, 17 {0, &ITimeZoneService::GetDeviceLocationName, "GetDeviceLocationName"},
17 {1, nullptr, "SetDeviceLocationName"}, 18 {1, nullptr, "SetDeviceLocationName"},
diff --git a/src/core/hle/service/time/time_zone_service.h b/src/core/hle/service/time/time_zone_service.h
index cb495748b..2c9b97603 100644
--- a/src/core/hle/service/time/time_zone_service.h
+++ b/src/core/hle/service/time/time_zone_service.h
@@ -6,6 +6,10 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Service::Time { 13namespace Service::Time {
10 14
11namespace TimeZone { 15namespace TimeZone {
@@ -14,7 +18,8 @@ class TimeZoneContentManager;
14 18
15class ITimeZoneService final : public ServiceFramework<ITimeZoneService> { 19class ITimeZoneService final : public ServiceFramework<ITimeZoneService> {
16public: 20public:
17 explicit ITimeZoneService(TimeZone::TimeZoneContentManager& time_zone_manager); 21 explicit ITimeZoneService(Core::System& system_,
22 TimeZone::TimeZoneContentManager& time_zone_manager_);
18 23
19private: 24private:
20 void GetDeviceLocationName(Kernel::HLERequestContext& ctx); 25 void GetDeviceLocationName(Kernel::HLERequestContext& ctx);
diff --git a/src/core/hle/service/usb/usb.cpp b/src/core/hle/service/usb/usb.cpp
index d033f8603..579de83e4 100644
--- a/src/core/hle/service/usb/usb.cpp
+++ b/src/core/hle/service/usb/usb.cpp
@@ -15,7 +15,7 @@ namespace Service::USB {
15 15
16class IDsInterface final : public ServiceFramework<IDsInterface> { 16class IDsInterface final : public ServiceFramework<IDsInterface> {
17public: 17public:
18 explicit IDsInterface() : ServiceFramework{"IDsInterface"} { 18 explicit IDsInterface(Core::System& system_) : ServiceFramework{system_, "IDsInterface"} {
19 // clang-format off 19 // clang-format off
20 static const FunctionInfo functions[] = { 20 static const FunctionInfo functions[] = {
21 {0, nullptr, "GetDsEndpoint"}, 21 {0, nullptr, "GetDsEndpoint"},
@@ -40,7 +40,7 @@ public:
40 40
41class USB_DS final : public ServiceFramework<USB_DS> { 41class USB_DS final : public ServiceFramework<USB_DS> {
42public: 42public:
43 explicit USB_DS() : ServiceFramework{"usb:ds"} { 43 explicit USB_DS(Core::System& system_) : ServiceFramework{system_, "usb:ds"} {
44 // clang-format off 44 // clang-format off
45 static const FunctionInfo functions[] = { 45 static const FunctionInfo functions[] = {
46 {0, nullptr, "BindDevice"}, 46 {0, nullptr, "BindDevice"},
@@ -65,7 +65,8 @@ public:
65 65
66class IClientEpSession final : public ServiceFramework<IClientEpSession> { 66class IClientEpSession final : public ServiceFramework<IClientEpSession> {
67public: 67public:
68 explicit IClientEpSession() : ServiceFramework{"IClientEpSession"} { 68 explicit IClientEpSession(Core::System& system_)
69 : ServiceFramework{system_, "IClientEpSession"} {
69 // clang-format off 70 // clang-format off
70 static const FunctionInfo functions[] = { 71 static const FunctionInfo functions[] = {
71 {0, nullptr, "Open"}, 72 {0, nullptr, "Open"},
@@ -86,7 +87,8 @@ public:
86 87
87class IClientIfSession final : public ServiceFramework<IClientIfSession> { 88class IClientIfSession final : public ServiceFramework<IClientIfSession> {
88public: 89public:
89 explicit IClientIfSession() : ServiceFramework{"IClientIfSession"} { 90 explicit IClientIfSession(Core::System& system_)
91 : ServiceFramework{system_, "IClientIfSession"} {
90 // clang-format off 92 // clang-format off
91 static const FunctionInfo functions[] = { 93 static const FunctionInfo functions[] = {
92 {0, nullptr, "Unknown0"}, 94 {0, nullptr, "Unknown0"},
@@ -108,7 +110,7 @@ public:
108 110
109class USB_HS final : public ServiceFramework<USB_HS> { 111class USB_HS final : public ServiceFramework<USB_HS> {
110public: 112public:
111 explicit USB_HS() : ServiceFramework{"usb:hs"} { 113 explicit USB_HS(Core::System& system_) : ServiceFramework{system_, "usb:hs"} {
112 // clang-format off 114 // clang-format off
113 static const FunctionInfo functions[] = { 115 static const FunctionInfo functions[] = {
114 {0, nullptr, "BindClientProcess"}, 116 {0, nullptr, "BindClientProcess"},
@@ -129,7 +131,7 @@ public:
129 131
130class IPdSession final : public ServiceFramework<IPdSession> { 132class IPdSession final : public ServiceFramework<IPdSession> {
131public: 133public:
132 explicit IPdSession() : ServiceFramework{"IPdSession"} { 134 explicit IPdSession(Core::System& system_) : ServiceFramework{system_, "IPdSession"} {
133 // clang-format off 135 // clang-format off
134 static const FunctionInfo functions[] = { 136 static const FunctionInfo functions[] = {
135 {0, nullptr, "BindNoticeEvent"}, 137 {0, nullptr, "BindNoticeEvent"},
@@ -148,7 +150,7 @@ public:
148 150
149class USB_PD final : public ServiceFramework<USB_PD> { 151class USB_PD final : public ServiceFramework<USB_PD> {
150public: 152public:
151 explicit USB_PD() : ServiceFramework{"usb:pd"} { 153 explicit USB_PD(Core::System& system_) : ServiceFramework{system_, "usb:pd"} {
152 // clang-format off 154 // clang-format off
153 static const FunctionInfo functions[] = { 155 static const FunctionInfo functions[] = {
154 {0, &USB_PD::GetPdSession, "GetPdSession"}, 156 {0, &USB_PD::GetPdSession, "GetPdSession"},
@@ -164,13 +166,14 @@ private:
164 166
165 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 167 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
166 rb.Push(RESULT_SUCCESS); 168 rb.Push(RESULT_SUCCESS);
167 rb.PushIpcInterface<IPdSession>(); 169 rb.PushIpcInterface<IPdSession>(system);
168 } 170 }
169}; 171};
170 172
171class IPdCradleSession final : public ServiceFramework<IPdCradleSession> { 173class IPdCradleSession final : public ServiceFramework<IPdCradleSession> {
172public: 174public:
173 explicit IPdCradleSession() : ServiceFramework{"IPdCradleSession"} { 175 explicit IPdCradleSession(Core::System& system_)
176 : ServiceFramework{system_, "IPdCradleSession"} {
174 // clang-format off 177 // clang-format off
175 static const FunctionInfo functions[] = { 178 static const FunctionInfo functions[] = {
176 {0, nullptr, "VdmUserWrite"}, 179 {0, nullptr, "VdmUserWrite"},
@@ -191,7 +194,7 @@ public:
191 194
192class USB_PD_C final : public ServiceFramework<USB_PD_C> { 195class USB_PD_C final : public ServiceFramework<USB_PD_C> {
193public: 196public:
194 explicit USB_PD_C() : ServiceFramework{"usb:pd:c"} { 197 explicit USB_PD_C(Core::System& system_) : ServiceFramework{system_, "usb:pd:c"} {
195 // clang-format off 198 // clang-format off
196 static const FunctionInfo functions[] = { 199 static const FunctionInfo functions[] = {
197 {0, &USB_PD_C::GetPdCradleSession, "GetPdCradleSession"}, 200 {0, &USB_PD_C::GetPdCradleSession, "GetPdCradleSession"},
@@ -205,7 +208,7 @@ private:
205 void GetPdCradleSession(Kernel::HLERequestContext& ctx) { 208 void GetPdCradleSession(Kernel::HLERequestContext& ctx) {
206 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 209 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
207 rb.Push(RESULT_SUCCESS); 210 rb.Push(RESULT_SUCCESS);
208 rb.PushIpcInterface<IPdCradleSession>(); 211 rb.PushIpcInterface<IPdCradleSession>(system);
209 212
210 LOG_DEBUG(Service_USB, "called"); 213 LOG_DEBUG(Service_USB, "called");
211 } 214 }
@@ -213,7 +216,7 @@ private:
213 216
214class USB_PM final : public ServiceFramework<USB_PM> { 217class USB_PM final : public ServiceFramework<USB_PM> {
215public: 218public:
216 explicit USB_PM() : ServiceFramework{"usb:pm"} { 219 explicit USB_PM(Core::System& system_) : ServiceFramework{system_, "usb:pm"} {
217 // clang-format off 220 // clang-format off
218 static const FunctionInfo functions[] = { 221 static const FunctionInfo functions[] = {
219 {0, nullptr, "Unknown0"}, 222 {0, nullptr, "Unknown0"},
@@ -229,12 +232,12 @@ public:
229 } 232 }
230}; 233};
231 234
232void InstallInterfaces(SM::ServiceManager& sm) { 235void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
233 std::make_shared<USB_DS>()->InstallAsService(sm); 236 std::make_shared<USB_DS>(system)->InstallAsService(sm);
234 std::make_shared<USB_HS>()->InstallAsService(sm); 237 std::make_shared<USB_HS>(system)->InstallAsService(sm);
235 std::make_shared<USB_PD>()->InstallAsService(sm); 238 std::make_shared<USB_PD>(system)->InstallAsService(sm);
236 std::make_shared<USB_PD_C>()->InstallAsService(sm); 239 std::make_shared<USB_PD_C>(system)->InstallAsService(sm);
237 std::make_shared<USB_PM>()->InstallAsService(sm); 240 std::make_shared<USB_PM>(system)->InstallAsService(sm);
238} 241}
239 242
240} // namespace Service::USB 243} // namespace Service::USB
diff --git a/src/core/hle/service/usb/usb.h b/src/core/hle/service/usb/usb.h
index 970a11fe8..fc366df34 100644
--- a/src/core/hle/service/usb/usb.h
+++ b/src/core/hle/service/usb/usb.h
@@ -4,12 +4,16 @@
4 4
5#pragma once 5#pragma once
6 6
7namespace Core {
8class System;
9}
10
7namespace Service::SM { 11namespace Service::SM {
8class ServiceManager; 12class ServiceManager;
9} 13}
10 14
11namespace Service::USB { 15namespace Service::USB {
12 16
13void InstallInterfaces(SM::ServiceManager& sm); 17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
14 18
15} // namespace Service::USB 19} // namespace Service::USB
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 86bd604f4..af5b8b0b9 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -492,8 +492,8 @@ private:
492 492
493class IHOSBinderDriver final : public ServiceFramework<IHOSBinderDriver> { 493class IHOSBinderDriver final : public ServiceFramework<IHOSBinderDriver> {
494public: 494public:
495 explicit IHOSBinderDriver(NVFlinger::NVFlinger& nv_flinger) 495 explicit IHOSBinderDriver(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_)
496 : ServiceFramework("IHOSBinderDriver"), nv_flinger(nv_flinger) { 496 : ServiceFramework{system_, "IHOSBinderDriver"}, nv_flinger(nv_flinger_) {
497 static const FunctionInfo functions[] = { 497 static const FunctionInfo functions[] = {
498 {0, &IHOSBinderDriver::TransactParcel, "TransactParcel"}, 498 {0, &IHOSBinderDriver::TransactParcel, "TransactParcel"},
499 {1, &IHOSBinderDriver::AdjustRefcount, "AdjustRefcount"}, 499 {1, &IHOSBinderDriver::AdjustRefcount, "AdjustRefcount"},
@@ -689,7 +689,8 @@ private:
689 689
690class ISystemDisplayService final : public ServiceFramework<ISystemDisplayService> { 690class ISystemDisplayService final : public ServiceFramework<ISystemDisplayService> {
691public: 691public:
692 explicit ISystemDisplayService() : ServiceFramework("ISystemDisplayService") { 692 explicit ISystemDisplayService(Core::System& system_)
693 : ServiceFramework{system_, "ISystemDisplayService"} {
693 static const FunctionInfo functions[] = { 694 static const FunctionInfo functions[] = {
694 {1200, nullptr, "GetZOrderCountMin"}, 695 {1200, nullptr, "GetZOrderCountMin"},
695 {1202, nullptr, "GetZOrderCountMax"}, 696 {1202, nullptr, "GetZOrderCountMax"},
@@ -790,8 +791,8 @@ private:
790 791
791class IManagerDisplayService final : public ServiceFramework<IManagerDisplayService> { 792class IManagerDisplayService final : public ServiceFramework<IManagerDisplayService> {
792public: 793public:
793 explicit IManagerDisplayService(NVFlinger::NVFlinger& nv_flinger) 794 explicit IManagerDisplayService(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_)
794 : ServiceFramework("IManagerDisplayService"), nv_flinger(nv_flinger) { 795 : ServiceFramework{system_, "IManagerDisplayService"}, nv_flinger{nv_flinger_} {
795 // clang-format off 796 // clang-format off
796 static const FunctionInfo functions[] = { 797 static const FunctionInfo functions[] = {
797 {200, nullptr, "AllocateProcessHeapBlock"}, 798 {200, nullptr, "AllocateProcessHeapBlock"},
@@ -935,7 +936,7 @@ private:
935 936
936class IApplicationDisplayService final : public ServiceFramework<IApplicationDisplayService> { 937class IApplicationDisplayService final : public ServiceFramework<IApplicationDisplayService> {
937public: 938public:
938 explicit IApplicationDisplayService(NVFlinger::NVFlinger& nv_flinger); 939 explicit IApplicationDisplayService(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_);
939 940
940private: 941private:
941 enum class ConvertedScaleMode : u64 { 942 enum class ConvertedScaleMode : u64 {
@@ -959,7 +960,7 @@ private:
959 960
960 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 961 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
961 rb.Push(RESULT_SUCCESS); 962 rb.Push(RESULT_SUCCESS);
962 rb.PushIpcInterface<IHOSBinderDriver>(nv_flinger); 963 rb.PushIpcInterface<IHOSBinderDriver>(system, nv_flinger);
963 } 964 }
964 965
965 void GetSystemDisplayService(Kernel::HLERequestContext& ctx) { 966 void GetSystemDisplayService(Kernel::HLERequestContext& ctx) {
@@ -967,7 +968,7 @@ private:
967 968
968 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 969 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
969 rb.Push(RESULT_SUCCESS); 970 rb.Push(RESULT_SUCCESS);
970 rb.PushIpcInterface<ISystemDisplayService>(); 971 rb.PushIpcInterface<ISystemDisplayService>(system);
971 } 972 }
972 973
973 void GetManagerDisplayService(Kernel::HLERequestContext& ctx) { 974 void GetManagerDisplayService(Kernel::HLERequestContext& ctx) {
@@ -975,7 +976,7 @@ private:
975 976
976 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 977 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
977 rb.Push(RESULT_SUCCESS); 978 rb.Push(RESULT_SUCCESS);
978 rb.PushIpcInterface<IManagerDisplayService>(nv_flinger); 979 rb.PushIpcInterface<IManagerDisplayService>(system, nv_flinger);
979 } 980 }
980 981
981 void GetIndirectDisplayTransactionService(Kernel::HLERequestContext& ctx) { 982 void GetIndirectDisplayTransactionService(Kernel::HLERequestContext& ctx) {
@@ -983,7 +984,7 @@ private:
983 984
984 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 985 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
985 rb.Push(RESULT_SUCCESS); 986 rb.Push(RESULT_SUCCESS);
986 rb.PushIpcInterface<IHOSBinderDriver>(nv_flinger); 987 rb.PushIpcInterface<IHOSBinderDriver>(system, nv_flinger);
987 } 988 }
988 989
989 void OpenDisplay(Kernel::HLERequestContext& ctx) { 990 void OpenDisplay(Kernel::HLERequestContext& ctx) {
@@ -1261,8 +1262,9 @@ private:
1261 NVFlinger::NVFlinger& nv_flinger; 1262 NVFlinger::NVFlinger& nv_flinger;
1262}; 1263};
1263 1264
1264IApplicationDisplayService::IApplicationDisplayService(NVFlinger::NVFlinger& nv_flinger) 1265IApplicationDisplayService::IApplicationDisplayService(Core::System& system_,
1265 : ServiceFramework("IApplicationDisplayService"), nv_flinger(nv_flinger) { 1266 NVFlinger::NVFlinger& nv_flinger_)
1267 : ServiceFramework{system_, "IApplicationDisplayService"}, nv_flinger{nv_flinger_} {
1266 static const FunctionInfo functions[] = { 1268 static const FunctionInfo functions[] = {
1267 {100, &IApplicationDisplayService::GetRelayService, "GetRelayService"}, 1269 {100, &IApplicationDisplayService::GetRelayService, "GetRelayService"},
1268 {101, &IApplicationDisplayService::GetSystemDisplayService, "GetSystemDisplayService"}, 1270 {101, &IApplicationDisplayService::GetSystemDisplayService, "GetSystemDisplayService"},
@@ -1303,8 +1305,8 @@ static bool IsValidServiceAccess(Permission permission, Policy policy) {
1303 return false; 1305 return false;
1304} 1306}
1305 1307
1306void detail::GetDisplayServiceImpl(Kernel::HLERequestContext& ctx, NVFlinger::NVFlinger& nv_flinger, 1308void detail::GetDisplayServiceImpl(Kernel::HLERequestContext& ctx, Core::System& system,
1307 Permission permission) { 1309 NVFlinger::NVFlinger& nv_flinger, Permission permission) {
1308 IPC::RequestParser rp{ctx}; 1310 IPC::RequestParser rp{ctx};
1309 const auto policy = rp.PopEnum<Policy>(); 1311 const auto policy = rp.PopEnum<Policy>();
1310 1312
@@ -1317,13 +1319,14 @@ void detail::GetDisplayServiceImpl(Kernel::HLERequestContext& ctx, NVFlinger::NV
1317 1319
1318 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 1320 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
1319 rb.Push(RESULT_SUCCESS); 1321 rb.Push(RESULT_SUCCESS);
1320 rb.PushIpcInterface<IApplicationDisplayService>(nv_flinger); 1322 rb.PushIpcInterface<IApplicationDisplayService>(system, nv_flinger);
1321} 1323}
1322 1324
1323void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nv_flinger) { 1325void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system,
1324 std::make_shared<VI_M>(nv_flinger)->InstallAsService(service_manager); 1326 NVFlinger::NVFlinger& nv_flinger) {
1325 std::make_shared<VI_S>(nv_flinger)->InstallAsService(service_manager); 1327 std::make_shared<VI_M>(system, nv_flinger)->InstallAsService(service_manager);
1326 std::make_shared<VI_U>(nv_flinger)->InstallAsService(service_manager); 1328 std::make_shared<VI_S>(system, nv_flinger)->InstallAsService(service_manager);
1329 std::make_shared<VI_U>(system, nv_flinger)->InstallAsService(service_manager);
1327} 1330}
1328 1331
1329} // namespace Service::VI 1332} // namespace Service::VI
diff --git a/src/core/hle/service/vi/vi.h b/src/core/hle/service/vi/vi.h
index 5229fa753..eec531d54 100644
--- a/src/core/hle/service/vi/vi.h
+++ b/src/core/hle/service/vi/vi.h
@@ -7,6 +7,10 @@
7#include <memory> 7#include <memory>
8#include "common/common_types.h" 8#include "common/common_types.h"
9 9
10namespace Core {
11class System;
12}
13
10namespace Kernel { 14namespace Kernel {
11class HLERequestContext; 15class HLERequestContext;
12} 16}
@@ -43,11 +47,12 @@ enum class Policy {
43}; 47};
44 48
45namespace detail { 49namespace detail {
46void GetDisplayServiceImpl(Kernel::HLERequestContext& ctx, NVFlinger::NVFlinger& nv_flinger, 50void GetDisplayServiceImpl(Kernel::HLERequestContext& ctx, Core::System& system,
47 Permission permission); 51 NVFlinger::NVFlinger& nv_flinger, Permission permission);
48} // namespace detail 52} // namespace detail
49 53
50/// Registers all VI services with the specified service manager. 54/// Registers all VI services with the specified service manager.
51void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nv_flinger); 55void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system,
56 NVFlinger::NVFlinger& nv_flinger);
52 57
53} // namespace Service::VI 58} // namespace Service::VI
diff --git a/src/core/hle/service/vi/vi_m.cpp b/src/core/hle/service/vi/vi_m.cpp
index 41da3ee93..87db1c416 100644
--- a/src/core/hle/service/vi/vi_m.cpp
+++ b/src/core/hle/service/vi/vi_m.cpp
@@ -8,7 +8,8 @@
8 8
9namespace Service::VI { 9namespace Service::VI {
10 10
11VI_M::VI_M(NVFlinger::NVFlinger& nv_flinger) : ServiceFramework{"vi:m"}, nv_flinger{nv_flinger} { 11VI_M::VI_M(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_)
12 : ServiceFramework{system_, "vi:m"}, nv_flinger{nv_flinger_} {
12 static const FunctionInfo functions[] = { 13 static const FunctionInfo functions[] = {
13 {2, &VI_M::GetDisplayService, "GetDisplayService"}, 14 {2, &VI_M::GetDisplayService, "GetDisplayService"},
14 {3, nullptr, "GetDisplayServiceWithProxyNameExchange"}, 15 {3, nullptr, "GetDisplayServiceWithProxyNameExchange"},
@@ -21,7 +22,7 @@ VI_M::~VI_M() = default;
21void VI_M::GetDisplayService(Kernel::HLERequestContext& ctx) { 22void VI_M::GetDisplayService(Kernel::HLERequestContext& ctx) {
22 LOG_DEBUG(Service_VI, "called"); 23 LOG_DEBUG(Service_VI, "called");
23 24
24 detail::GetDisplayServiceImpl(ctx, nv_flinger, Permission::Manager); 25 detail::GetDisplayServiceImpl(ctx, system, nv_flinger, Permission::Manager);
25} 26}
26 27
27} // namespace Service::VI 28} // namespace Service::VI
diff --git a/src/core/hle/service/vi/vi_m.h b/src/core/hle/service/vi/vi_m.h
index ee2489874..d79c41beb 100644
--- a/src/core/hle/service/vi/vi_m.h
+++ b/src/core/hle/service/vi/vi_m.h
@@ -6,6 +6,10 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Kernel { 13namespace Kernel {
10class HLERequestContext; 14class HLERequestContext;
11} 15}
@@ -18,7 +22,7 @@ namespace Service::VI {
18 22
19class VI_M final : public ServiceFramework<VI_M> { 23class VI_M final : public ServiceFramework<VI_M> {
20public: 24public:
21 explicit VI_M(NVFlinger::NVFlinger& nv_flinger); 25 explicit VI_M(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_);
22 ~VI_M() override; 26 ~VI_M() override;
23 27
24private: 28private:
diff --git a/src/core/hle/service/vi/vi_s.cpp b/src/core/hle/service/vi/vi_s.cpp
index 6acb51e2a..5cd22f7df 100644
--- a/src/core/hle/service/vi/vi_s.cpp
+++ b/src/core/hle/service/vi/vi_s.cpp
@@ -8,7 +8,8 @@
8 8
9namespace Service::VI { 9namespace Service::VI {
10 10
11VI_S::VI_S(NVFlinger::NVFlinger& nv_flinger) : ServiceFramework{"vi:s"}, nv_flinger{nv_flinger} { 11VI_S::VI_S(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_)
12 : ServiceFramework{system_, "vi:s"}, nv_flinger{nv_flinger_} {
12 static const FunctionInfo functions[] = { 13 static const FunctionInfo functions[] = {
13 {1, &VI_S::GetDisplayService, "GetDisplayService"}, 14 {1, &VI_S::GetDisplayService, "GetDisplayService"},
14 {3, nullptr, "GetDisplayServiceWithProxyNameExchange"}, 15 {3, nullptr, "GetDisplayServiceWithProxyNameExchange"},
@@ -21,7 +22,7 @@ VI_S::~VI_S() = default;
21void VI_S::GetDisplayService(Kernel::HLERequestContext& ctx) { 22void VI_S::GetDisplayService(Kernel::HLERequestContext& ctx) {
22 LOG_DEBUG(Service_VI, "called"); 23 LOG_DEBUG(Service_VI, "called");
23 24
24 detail::GetDisplayServiceImpl(ctx, nv_flinger, Permission::System); 25 detail::GetDisplayServiceImpl(ctx, system, nv_flinger, Permission::System);
25} 26}
26 27
27} // namespace Service::VI 28} // namespace Service::VI
diff --git a/src/core/hle/service/vi/vi_s.h b/src/core/hle/service/vi/vi_s.h
index 6790673ab..5f1f8f290 100644
--- a/src/core/hle/service/vi/vi_s.h
+++ b/src/core/hle/service/vi/vi_s.h
@@ -6,6 +6,10 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Kernel { 13namespace Kernel {
10class HLERequestContext; 14class HLERequestContext;
11} 15}
@@ -18,7 +22,7 @@ namespace Service::VI {
18 22
19class VI_S final : public ServiceFramework<VI_S> { 23class VI_S final : public ServiceFramework<VI_S> {
20public: 24public:
21 explicit VI_S(NVFlinger::NVFlinger& nv_flinger); 25 explicit VI_S(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_);
22 ~VI_S() override; 26 ~VI_S() override;
23 27
24private: 28private:
diff --git a/src/core/hle/service/vi/vi_u.cpp b/src/core/hle/service/vi/vi_u.cpp
index 44e00a4f6..0079d51f0 100644
--- a/src/core/hle/service/vi/vi_u.cpp
+++ b/src/core/hle/service/vi/vi_u.cpp
@@ -8,7 +8,8 @@
8 8
9namespace Service::VI { 9namespace Service::VI {
10 10
11VI_U::VI_U(NVFlinger::NVFlinger& nv_flinger) : ServiceFramework{"vi:u"}, nv_flinger{nv_flinger} { 11VI_U::VI_U(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_)
12 : ServiceFramework{system_, "vi:u"}, nv_flinger{nv_flinger_} {
12 static const FunctionInfo functions[] = { 13 static const FunctionInfo functions[] = {
13 {0, &VI_U::GetDisplayService, "GetDisplayService"}, 14 {0, &VI_U::GetDisplayService, "GetDisplayService"},
14 {1, nullptr, "GetDisplayServiceWithProxyNameExchange"}, 15 {1, nullptr, "GetDisplayServiceWithProxyNameExchange"},
@@ -21,7 +22,7 @@ VI_U::~VI_U() = default;
21void VI_U::GetDisplayService(Kernel::HLERequestContext& ctx) { 22void VI_U::GetDisplayService(Kernel::HLERequestContext& ctx) {
22 LOG_DEBUG(Service_VI, "called"); 23 LOG_DEBUG(Service_VI, "called");
23 24
24 detail::GetDisplayServiceImpl(ctx, nv_flinger, Permission::User); 25 detail::GetDisplayServiceImpl(ctx, system, nv_flinger, Permission::User);
25} 26}
26 27
27} // namespace Service::VI 28} // namespace Service::VI
diff --git a/src/core/hle/service/vi/vi_u.h b/src/core/hle/service/vi/vi_u.h
index b59f986f0..8e3885c73 100644
--- a/src/core/hle/service/vi/vi_u.h
+++ b/src/core/hle/service/vi/vi_u.h
@@ -6,6 +6,10 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Kernel { 13namespace Kernel {
10class HLERequestContext; 14class HLERequestContext;
11} 15}
@@ -18,7 +22,7 @@ namespace Service::VI {
18 22
19class VI_U final : public ServiceFramework<VI_U> { 23class VI_U final : public ServiceFramework<VI_U> {
20public: 24public:
21 explicit VI_U(NVFlinger::NVFlinger& nv_flinger); 25 explicit VI_U(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_);
22 ~VI_U() override; 26 ~VI_U() override;
23 27
24private: 28private:
diff --git a/src/core/hle/service/wlan/wlan.cpp b/src/core/hle/service/wlan/wlan.cpp
index 0260d7dcf..ddbf04069 100644
--- a/src/core/hle/service/wlan/wlan.cpp
+++ b/src/core/hle/service/wlan/wlan.cpp
@@ -12,7 +12,7 @@ namespace Service::WLAN {
12 12
13class WLANInfra final : public ServiceFramework<WLANInfra> { 13class WLANInfra final : public ServiceFramework<WLANInfra> {
14public: 14public:
15 explicit WLANInfra() : ServiceFramework{"wlan:inf"} { 15 explicit WLANInfra(Core::System& system_) : ServiceFramework{system_, "wlan:inf"} {
16 // clang-format off 16 // clang-format off
17 static const FunctionInfo functions[] = { 17 static const FunctionInfo functions[] = {
18 {0, nullptr, "OpenMode"}, 18 {0, nullptr, "OpenMode"},
@@ -55,7 +55,7 @@ public:
55 55
56class WLANLocal final : public ServiceFramework<WLANLocal> { 56class WLANLocal final : public ServiceFramework<WLANLocal> {
57public: 57public:
58 explicit WLANLocal() : ServiceFramework{"wlan:lcl"} { 58 explicit WLANLocal(Core::System& system_) : ServiceFramework{system_, "wlan:lcl"} {
59 // clang-format off 59 // clang-format off
60 static const FunctionInfo functions[] = { 60 static const FunctionInfo functions[] = {
61 {0, nullptr, "Unknown0"}, 61 {0, nullptr, "Unknown0"},
@@ -120,7 +120,7 @@ public:
120 120
121class WLANLocalGetFrame final : public ServiceFramework<WLANLocalGetFrame> { 121class WLANLocalGetFrame final : public ServiceFramework<WLANLocalGetFrame> {
122public: 122public:
123 explicit WLANLocalGetFrame() : ServiceFramework{"wlan:lg"} { 123 explicit WLANLocalGetFrame(Core::System& system_) : ServiceFramework{system_, "wlan:lg"} {
124 // clang-format off 124 // clang-format off
125 static const FunctionInfo functions[] = { 125 static const FunctionInfo functions[] = {
126 {0, nullptr, "Unknown"}, 126 {0, nullptr, "Unknown"},
@@ -133,7 +133,7 @@ public:
133 133
134class WLANSocketGetFrame final : public ServiceFramework<WLANSocketGetFrame> { 134class WLANSocketGetFrame final : public ServiceFramework<WLANSocketGetFrame> {
135public: 135public:
136 explicit WLANSocketGetFrame() : ServiceFramework{"wlan:sg"} { 136 explicit WLANSocketGetFrame(Core::System& system_) : ServiceFramework{system_, "wlan:sg"} {
137 // clang-format off 137 // clang-format off
138 static const FunctionInfo functions[] = { 138 static const FunctionInfo functions[] = {
139 {0, nullptr, "Unknown"}, 139 {0, nullptr, "Unknown"},
@@ -146,7 +146,7 @@ public:
146 146
147class WLANSocketManager final : public ServiceFramework<WLANSocketManager> { 147class WLANSocketManager final : public ServiceFramework<WLANSocketManager> {
148public: 148public:
149 explicit WLANSocketManager() : ServiceFramework{"wlan:soc"} { 149 explicit WLANSocketManager(Core::System& system_) : ServiceFramework{system_, "wlan:soc"} {
150 // clang-format off 150 // clang-format off
151 static const FunctionInfo functions[] = { 151 static const FunctionInfo functions[] = {
152 {0, nullptr, "Unknown0"}, 152 {0, nullptr, "Unknown0"},
@@ -169,12 +169,12 @@ public:
169 } 169 }
170}; 170};
171 171
172void InstallInterfaces(SM::ServiceManager& sm) { 172void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
173 std::make_shared<WLANInfra>()->InstallAsService(sm); 173 std::make_shared<WLANInfra>(system)->InstallAsService(sm);
174 std::make_shared<WLANLocal>()->InstallAsService(sm); 174 std::make_shared<WLANLocal>(system)->InstallAsService(sm);
175 std::make_shared<WLANLocalGetFrame>()->InstallAsService(sm); 175 std::make_shared<WLANLocalGetFrame>(system)->InstallAsService(sm);
176 std::make_shared<WLANSocketGetFrame>()->InstallAsService(sm); 176 std::make_shared<WLANSocketGetFrame>(system)->InstallAsService(sm);
177 std::make_shared<WLANSocketManager>()->InstallAsService(sm); 177 std::make_shared<WLANSocketManager>(system)->InstallAsService(sm);
178} 178}
179 179
180} // namespace Service::WLAN 180} // namespace Service::WLAN
diff --git a/src/core/hle/service/wlan/wlan.h b/src/core/hle/service/wlan/wlan.h
index 054ea928a..3899eedbb 100644
--- a/src/core/hle/service/wlan/wlan.h
+++ b/src/core/hle/service/wlan/wlan.h
@@ -4,12 +4,16 @@
4 4
5#pragma once 5#pragma once
6 6
7namespace Core {
8class System;
9}
10
7namespace Service::SM { 11namespace Service::SM {
8class ServiceManager; 12class ServiceManager;
9} 13}
10 14
11namespace Service::WLAN { 15namespace Service::WLAN {
12 16
13void InstallInterfaces(SM::ServiceManager& sm); 17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
14 18
15} // namespace Service::WLAN 19} // namespace Service::WLAN
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp
index 2002dc4f2..79ebf11de 100644
--- a/src/core/loader/deconstructed_rom_directory.cpp
+++ b/src/core/loader/deconstructed_rom_directory.cpp
@@ -12,7 +12,6 @@
12#include "core/file_sys/control_metadata.h" 12#include "core/file_sys/control_metadata.h"
13#include "core/file_sys/patch_manager.h" 13#include "core/file_sys/patch_manager.h"
14#include "core/file_sys/romfs_factory.h" 14#include "core/file_sys/romfs_factory.h"
15#include "core/gdbstub/gdbstub.h"
16#include "core/hle/kernel/kernel.h" 15#include "core/hle/kernel/kernel.h"
17#include "core/hle/kernel/memory/page_table.h" 16#include "core/hle/kernel/memory/page_table.h"
18#include "core/hle/kernel/process.h" 17#include "core/hle/kernel/process.h"
@@ -180,8 +179,6 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect
180 next_load_addr = *tentative_next_load_addr; 179 next_load_addr = *tentative_next_load_addr;
181 modules.insert_or_assign(load_addr, module); 180 modules.insert_or_assign(load_addr, module);
182 LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr); 181 LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr);
183 // Register module with GDBStub
184 GDBStub::RegisterModule(module, load_addr, next_load_addr - 1, false);
185 } 182 }
186 183
187 // Find the RomFS by searching for a ".romfs" file in this directory 184 // Find the RomFS by searching for a ".romfs" file in this directory
diff --git a/src/core/loader/kip.cpp b/src/core/loader/kip.cpp
index 2a905d3e4..e162c4ff0 100644
--- a/src/core/loader/kip.cpp
+++ b/src/core/loader/kip.cpp
@@ -5,7 +5,6 @@
5#include <cstring> 5#include <cstring>
6#include "core/file_sys/kernel_executable.h" 6#include "core/file_sys/kernel_executable.h"
7#include "core/file_sys/program_metadata.h" 7#include "core/file_sys/program_metadata.h"
8#include "core/gdbstub/gdbstub.h"
9#include "core/hle/kernel/code_set.h" 8#include "core/hle/kernel/code_set.h"
10#include "core/hle/kernel/memory/page_table.h" 9#include "core/hle/kernel/memory/page_table.h"
11#include "core/hle/kernel/process.h" 10#include "core/hle/kernel/process.h"
@@ -91,8 +90,6 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::Process& process,
91 program_image.resize(PageAlignSize(kip->GetBSSOffset()) + kip->GetBSSSize()); 90 program_image.resize(PageAlignSize(kip->GetBSSOffset()) + kip->GetBSSSize());
92 codeset.DataSegment().size += kip->GetBSSSize(); 91 codeset.DataSegment().size += kip->GetBSSSize();
93 92
94 GDBStub::RegisterModule(kip->GetName(), base_address, base_address + program_image.size());
95
96 codeset.memory = std::move(program_image); 93 codeset.memory = std::move(program_image);
97 process.LoadModule(std::move(codeset), base_address); 94 process.LoadModule(std::move(codeset), base_address);
98 95
diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp
index 5f4b3104b..ccf8cc153 100644
--- a/src/core/loader/nro.cpp
+++ b/src/core/loader/nro.cpp
@@ -14,10 +14,10 @@
14#include "core/file_sys/control_metadata.h" 14#include "core/file_sys/control_metadata.h"
15#include "core/file_sys/romfs_factory.h" 15#include "core/file_sys/romfs_factory.h"
16#include "core/file_sys/vfs_offset.h" 16#include "core/file_sys/vfs_offset.h"
17#include "core/gdbstub/gdbstub.h"
18#include "core/hle/kernel/code_set.h" 17#include "core/hle/kernel/code_set.h"
19#include "core/hle/kernel/memory/page_table.h" 18#include "core/hle/kernel/memory/page_table.h"
20#include "core/hle/kernel/process.h" 19#include "core/hle/kernel/process.h"
20#include "core/hle/kernel/thread.h"
21#include "core/hle/service/filesystem/filesystem.h" 21#include "core/hle/service/filesystem/filesystem.h"
22#include "core/loader/nro.h" 22#include "core/loader/nro.h"
23#include "core/loader/nso.h" 23#include "core/loader/nso.h"
@@ -197,10 +197,6 @@ static bool LoadNroImpl(Kernel::Process& process, const std::vector<u8>& data,
197 codeset.memory = std::move(program_image); 197 codeset.memory = std::move(program_image);
198 process.LoadModule(std::move(codeset), process.PageTable().GetCodeRegionStart()); 198 process.LoadModule(std::move(codeset), process.PageTable().GetCodeRegionStart());
199 199
200 // Register module with GDBStub
201 GDBStub::RegisterModule(name, process.PageTable().GetCodeRegionStart(),
202 process.PageTable().GetCodeRegionEnd());
203
204 return true; 200 return true;
205} 201}
206 202
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp
index aa85c1a29..95b6f339a 100644
--- a/src/core/loader/nso.cpp
+++ b/src/core/loader/nso.cpp
@@ -14,10 +14,10 @@
14#include "common/swap.h" 14#include "common/swap.h"
15#include "core/core.h" 15#include "core/core.h"
16#include "core/file_sys/patch_manager.h" 16#include "core/file_sys/patch_manager.h"
17#include "core/gdbstub/gdbstub.h"
18#include "core/hle/kernel/code_set.h" 17#include "core/hle/kernel/code_set.h"
19#include "core/hle/kernel/memory/page_table.h" 18#include "core/hle/kernel/memory/page_table.h"
20#include "core/hle/kernel/process.h" 19#include "core/hle/kernel/process.h"
20#include "core/hle/kernel/thread.h"
21#include "core/loader/nso.h" 21#include "core/loader/nso.h"
22#include "core/memory.h" 22#include "core/memory.h"
23#include "core/settings.h" 23#include "core/settings.h"
@@ -159,9 +159,6 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process, Core::S
159 codeset.memory = std::move(program_image); 159 codeset.memory = std::move(program_image);
160 process.LoadModule(std::move(codeset), load_base); 160 process.LoadModule(std::move(codeset), load_base);
161 161
162 // Register module with GDBStub
163 GDBStub::RegisterModule(file.GetName(), load_base, load_base);
164
165 return load_base + image_size; 162 return load_base + image_size;
166} 163}
167 164
diff --git a/src/core/settings.cpp b/src/core/settings.cpp
index aadbc3932..e9997a263 100644
--- a/src/core/settings.cpp
+++ b/src/core/settings.cpp
@@ -4,9 +4,10 @@
4 4
5#include <string_view> 5#include <string_view>
6 6
7#include "common/assert.h"
7#include "common/file_util.h" 8#include "common/file_util.h"
9#include "common/logging/log.h"
8#include "core/core.h" 10#include "core/core.h"
9#include "core/gdbstub/gdbstub.h"
10#include "core/hle/service/hid/hid.h" 11#include "core/hle/service/hid/hid.h"
11#include "core/settings.h" 12#include "core/settings.h"
12#include "video_core/renderer_base.h" 13#include "video_core/renderer_base.h"
@@ -31,13 +32,9 @@ std::string GetTimeZoneString() {
31 return timezones[time_zone_index]; 32 return timezones[time_zone_index];
32} 33}
33 34
34void Apply() { 35void Apply(Core::System& system) {
35 GDBStub::SetServerPort(values.gdbstub_port); 36 if (system.IsPoweredOn()) {
36 GDBStub::ToggleServer(values.use_gdbstub); 37 system.Renderer().RefreshBaseSettings();
37
38 auto& system_instance = Core::System::GetInstance();
39 if (system_instance.IsPoweredOn()) {
40 system_instance.Renderer().RefreshBaseSettings();
41 } 38 }
42 39
43 Service::HID::ReloadInputDevices(); 40 Service::HID::ReloadInputDevices();
@@ -106,9 +103,9 @@ float Volume() {
106 return values.volume.GetValue(); 103 return values.volume.GetValue();
107} 104}
108 105
109void RestoreGlobalState() { 106void RestoreGlobalState(bool is_powered_on) {
110 // If a game is running, DO NOT restore the global settings state 107 // If a game is running, DO NOT restore the global settings state
111 if (Core::System::GetInstance().IsPoweredOn()) { 108 if (is_powered_on) {
112 return; 109 return;
113 } 110 }
114 111
diff --git a/src/core/settings.h b/src/core/settings.h
index 1143aba5d..8e076f7ef 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -14,6 +14,10 @@
14#include "common/common_types.h" 14#include "common/common_types.h"
15#include "input_common/settings.h" 15#include "input_common/settings.h"
16 16
17namespace Core {
18class System;
19}
20
17namespace Settings { 21namespace Settings {
18 22
19enum class RendererBackend { 23enum class RendererBackend {
@@ -174,9 +178,7 @@ struct Values {
174 178
175 Setting<bool> motion_enabled; 179 Setting<bool> motion_enabled;
176 std::string motion_device; 180 std::string motion_device;
177 std::string udp_input_address; 181 std::string udp_input_servers;
178 u16 udp_input_port;
179 u8 udp_pad_index;
180 182
181 bool mouse_enabled; 183 bool mouse_enabled;
182 std::string mouse_device; 184 std::string mouse_device;
@@ -247,11 +249,11 @@ float Volume();
247 249
248std::string GetTimeZoneString(); 250std::string GetTimeZoneString();
249 251
250void Apply(); 252void Apply(Core::System& system);
251void LogSettings(); 253void LogSettings();
252 254
253// Restore the global state of all applicable settings in the Values struct 255// Restore the global state of all applicable settings in the Values struct
254void RestoreGlobalState(); 256void RestoreGlobalState(bool is_powered_on);
255 257
256// Fixes settings that are known to cause issues with the emulator 258// Fixes settings that are known to cause issues with the emulator
257void Sanitize(); 259void Sanitize();
diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt
index 1d1b2e08a..38ab31898 100644
--- a/src/input_common/CMakeLists.txt
+++ b/src/input_common/CMakeLists.txt
@@ -5,8 +5,6 @@ add_library(input_common STATIC
5 keyboard.h 5 keyboard.h
6 main.cpp 6 main.cpp
7 main.h 7 main.h
8 motion_emu.cpp
9 motion_emu.h
10 motion_from_button.cpp 8 motion_from_button.cpp
11 motion_from_button.h 9 motion_from_button.h
12 motion_input.cpp 10 motion_input.cpp
@@ -19,6 +17,10 @@ add_library(input_common STATIC
19 gcadapter/gc_adapter.h 17 gcadapter/gc_adapter.h
20 gcadapter/gc_poller.cpp 18 gcadapter/gc_poller.cpp
21 gcadapter/gc_poller.h 19 gcadapter/gc_poller.h
20 mouse/mouse_input.cpp
21 mouse/mouse_input.h
22 mouse/mouse_poller.cpp
23 mouse/mouse_poller.h
22 sdl/sdl.cpp 24 sdl/sdl.cpp
23 sdl/sdl.h 25 sdl/sdl.h
24 udp/client.cpp 26 udp/client.cpp
@@ -56,8 +58,8 @@ else()
56 -Werror=reorder 58 -Werror=reorder
57 -Werror=shadow 59 -Werror=shadow
58 -Werror=sign-compare 60 -Werror=sign-compare
59 -Werror=unused-but-set-parameter 61 $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter>
60 -Werror=unused-but-set-variable 62 $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable>
61 -Werror=unused-variable 63 -Werror=unused-variable
62 ) 64 )
63endif() 65endif()
diff --git a/src/input_common/main.cpp b/src/input_common/main.cpp
index e59ad4ff5..7c4e7dd3b 100644
--- a/src/input_common/main.cpp
+++ b/src/input_common/main.cpp
@@ -10,8 +10,9 @@
10#include "input_common/gcadapter/gc_poller.h" 10#include "input_common/gcadapter/gc_poller.h"
11#include "input_common/keyboard.h" 11#include "input_common/keyboard.h"
12#include "input_common/main.h" 12#include "input_common/main.h"
13#include "input_common/motion_emu.h"
14#include "input_common/motion_from_button.h" 13#include "input_common/motion_from_button.h"
14#include "input_common/mouse/mouse_input.h"
15#include "input_common/mouse/mouse_poller.h"
15#include "input_common/touch_from_button.h" 16#include "input_common/touch_from_button.h"
16#include "input_common/udp/client.h" 17#include "input_common/udp/client.h"
17#include "input_common/udp/udp.h" 18#include "input_common/udp/udp.h"
@@ -37,8 +38,6 @@ struct InputSubsystem::Impl {
37 std::make_shared<AnalogFromButton>()); 38 std::make_shared<AnalogFromButton>());
38 Input::RegisterFactory<Input::MotionDevice>("keyboard", 39 Input::RegisterFactory<Input::MotionDevice>("keyboard",
39 std::make_shared<MotionFromButton>()); 40 std::make_shared<MotionFromButton>());
40 motion_emu = std::make_shared<MotionEmu>();
41 Input::RegisterFactory<Input::MotionDevice>("motion_emu", motion_emu);
42 Input::RegisterFactory<Input::TouchDevice>("touch_from_button", 41 Input::RegisterFactory<Input::TouchDevice>("touch_from_button",
43 std::make_shared<TouchFromButtonFactory>()); 42 std::make_shared<TouchFromButtonFactory>());
44 43
@@ -51,6 +50,16 @@ struct InputSubsystem::Impl {
51 Input::RegisterFactory<Input::MotionDevice>("cemuhookudp", udpmotion); 50 Input::RegisterFactory<Input::MotionDevice>("cemuhookudp", udpmotion);
52 udptouch = std::make_shared<UDPTouchFactory>(udp); 51 udptouch = std::make_shared<UDPTouchFactory>(udp);
53 Input::RegisterFactory<Input::TouchDevice>("cemuhookudp", udptouch); 52 Input::RegisterFactory<Input::TouchDevice>("cemuhookudp", udptouch);
53
54 mouse = std::make_shared<MouseInput::Mouse>();
55 mousebuttons = std::make_shared<MouseButtonFactory>(mouse);
56 Input::RegisterFactory<Input::ButtonDevice>("mouse", mousebuttons);
57 mouseanalog = std::make_shared<MouseAnalogFactory>(mouse);
58 Input::RegisterFactory<Input::AnalogDevice>("mouse", mouseanalog);
59 mousemotion = std::make_shared<MouseMotionFactory>(mouse);
60 Input::RegisterFactory<Input::MotionDevice>("mouse", mousemotion);
61 mousetouch = std::make_shared<MouseTouchFactory>(mouse);
62 Input::RegisterFactory<Input::TouchDevice>("mouse", mousetouch);
54 } 63 }
55 64
56 void Shutdown() { 65 void Shutdown() {
@@ -58,8 +67,6 @@ struct InputSubsystem::Impl {
58 Input::UnregisterFactory<Input::MotionDevice>("keyboard"); 67 Input::UnregisterFactory<Input::MotionDevice>("keyboard");
59 keyboard.reset(); 68 keyboard.reset();
60 Input::UnregisterFactory<Input::AnalogDevice>("analog_from_button"); 69 Input::UnregisterFactory<Input::AnalogDevice>("analog_from_button");
61 Input::UnregisterFactory<Input::MotionDevice>("motion_emu");
62 motion_emu.reset();
63 Input::UnregisterFactory<Input::TouchDevice>("touch_from_button"); 70 Input::UnregisterFactory<Input::TouchDevice>("touch_from_button");
64#ifdef HAVE_SDL2 71#ifdef HAVE_SDL2
65 sdl.reset(); 72 sdl.reset();
@@ -77,6 +84,16 @@ struct InputSubsystem::Impl {
77 84
78 udpmotion.reset(); 85 udpmotion.reset();
79 udptouch.reset(); 86 udptouch.reset();
87
88 Input::UnregisterFactory<Input::ButtonDevice>("mouse");
89 Input::UnregisterFactory<Input::AnalogDevice>("mouse");
90 Input::UnregisterFactory<Input::MotionDevice>("mouse");
91 Input::UnregisterFactory<Input::TouchDevice>("mouse");
92
93 mousebuttons.reset();
94 mouseanalog.reset();
95 mousemotion.reset();
96 mousetouch.reset();
80 } 97 }
81 98
82 [[nodiscard]] std::vector<Common::ParamPackage> GetInputDevices() const { 99 [[nodiscard]] std::vector<Common::ParamPackage> GetInputDevices() const {
@@ -140,7 +157,6 @@ struct InputSubsystem::Impl {
140 } 157 }
141 158
142 std::shared_ptr<Keyboard> keyboard; 159 std::shared_ptr<Keyboard> keyboard;
143 std::shared_ptr<MotionEmu> motion_emu;
144#ifdef HAVE_SDL2 160#ifdef HAVE_SDL2
145 std::unique_ptr<SDL::State> sdl; 161 std::unique_ptr<SDL::State> sdl;
146#endif 162#endif
@@ -149,8 +165,13 @@ struct InputSubsystem::Impl {
149 std::shared_ptr<GCVibrationFactory> gcvibration; 165 std::shared_ptr<GCVibrationFactory> gcvibration;
150 std::shared_ptr<UDPMotionFactory> udpmotion; 166 std::shared_ptr<UDPMotionFactory> udpmotion;
151 std::shared_ptr<UDPTouchFactory> udptouch; 167 std::shared_ptr<UDPTouchFactory> udptouch;
168 std::shared_ptr<MouseButtonFactory> mousebuttons;
169 std::shared_ptr<MouseAnalogFactory> mouseanalog;
170 std::shared_ptr<MouseMotionFactory> mousemotion;
171 std::shared_ptr<MouseTouchFactory> mousetouch;
152 std::shared_ptr<CemuhookUDP::Client> udp; 172 std::shared_ptr<CemuhookUDP::Client> udp;
153 std::shared_ptr<GCAdapter::Adapter> gcadapter; 173 std::shared_ptr<GCAdapter::Adapter> gcadapter;
174 std::shared_ptr<MouseInput::Mouse> mouse;
154}; 175};
155 176
156InputSubsystem::InputSubsystem() : impl{std::make_unique<Impl>()} {} 177InputSubsystem::InputSubsystem() : impl{std::make_unique<Impl>()} {}
@@ -173,12 +194,12 @@ const Keyboard* InputSubsystem::GetKeyboard() const {
173 return impl->keyboard.get(); 194 return impl->keyboard.get();
174} 195}
175 196
176MotionEmu* InputSubsystem::GetMotionEmu() { 197MouseInput::Mouse* InputSubsystem::GetMouse() {
177 return impl->motion_emu.get(); 198 return impl->mouse.get();
178} 199}
179 200
180const MotionEmu* InputSubsystem::GetMotionEmu() const { 201const MouseInput::Mouse* InputSubsystem::GetMouse() const {
181 return impl->motion_emu.get(); 202 return impl->mouse.get();
182} 203}
183 204
184std::vector<Common::ParamPackage> InputSubsystem::GetInputDevices() const { 205std::vector<Common::ParamPackage> InputSubsystem::GetInputDevices() const {
@@ -229,11 +250,43 @@ const UDPTouchFactory* InputSubsystem::GetUDPTouch() const {
229 return impl->udptouch.get(); 250 return impl->udptouch.get();
230} 251}
231 252
253MouseButtonFactory* InputSubsystem::GetMouseButtons() {
254 return impl->mousebuttons.get();
255}
256
257const MouseButtonFactory* InputSubsystem::GetMouseButtons() const {
258 return impl->mousebuttons.get();
259}
260
261MouseAnalogFactory* InputSubsystem::GetMouseAnalogs() {
262 return impl->mouseanalog.get();
263}
264
265const MouseAnalogFactory* InputSubsystem::GetMouseAnalogs() const {
266 return impl->mouseanalog.get();
267}
268
269MouseMotionFactory* InputSubsystem::GetMouseMotions() {
270 return impl->mousemotion.get();
271}
272
273const MouseMotionFactory* InputSubsystem::GetMouseMotions() const {
274 return impl->mousemotion.get();
275}
276
277MouseTouchFactory* InputSubsystem::GetMouseTouch() {
278 return impl->mousetouch.get();
279}
280
281const MouseTouchFactory* InputSubsystem::GetMouseTouch() const {
282 return impl->mousetouch.get();
283}
284
232void InputSubsystem::ReloadInputDevices() { 285void InputSubsystem::ReloadInputDevices() {
233 if (!impl->udp) { 286 if (!impl->udp) {
234 return; 287 return;
235 } 288 }
236 impl->udp->ReloadUDPClient(); 289 impl->udp->ReloadSockets();
237} 290}
238 291
239std::vector<std::unique_ptr<Polling::DevicePoller>> InputSubsystem::GetPollers( 292std::vector<std::unique_ptr<Polling::DevicePoller>> InputSubsystem::GetPollers(
diff --git a/src/input_common/main.h b/src/input_common/main.h
index dded3f1ef..5d6f26385 100644
--- a/src/input_common/main.h
+++ b/src/input_common/main.h
@@ -25,6 +25,10 @@ namespace Settings::NativeMotion {
25enum Values : int; 25enum Values : int;
26} 26}
27 27
28namespace MouseInput {
29class Mouse;
30}
31
28namespace InputCommon { 32namespace InputCommon {
29namespace Polling { 33namespace Polling {
30 34
@@ -56,8 +60,11 @@ class GCAnalogFactory;
56class GCButtonFactory; 60class GCButtonFactory;
57class UDPMotionFactory; 61class UDPMotionFactory;
58class UDPTouchFactory; 62class UDPTouchFactory;
63class MouseButtonFactory;
64class MouseAnalogFactory;
65class MouseMotionFactory;
66class MouseTouchFactory;
59class Keyboard; 67class Keyboard;
60class MotionEmu;
61 68
62/** 69/**
63 * Given a ParamPackage for a Device returned from `GetInputDevices`, attempt to get the default 70 * Given a ParamPackage for a Device returned from `GetInputDevices`, attempt to get the default
@@ -90,11 +97,11 @@ public:
90 /// Retrieves the underlying keyboard device. 97 /// Retrieves the underlying keyboard device.
91 [[nodiscard]] const Keyboard* GetKeyboard() const; 98 [[nodiscard]] const Keyboard* GetKeyboard() const;
92 99
93 /// Retrieves the underlying motion emulation factory. 100 /// Retrieves the underlying mouse device.
94 [[nodiscard]] MotionEmu* GetMotionEmu(); 101 [[nodiscard]] MouseInput::Mouse* GetMouse();
95 102
96 /// Retrieves the underlying motion emulation factory. 103 /// Retrieves the underlying mouse device.
97 [[nodiscard]] const MotionEmu* GetMotionEmu() const; 104 [[nodiscard]] const MouseInput::Mouse* GetMouse() const;
98 105
99 /** 106 /**
100 * Returns all available input devices that this Factory can create a new device with. 107 * Returns all available input devices that this Factory can create a new device with.
@@ -137,6 +144,30 @@ public:
137 /// Retrieves the underlying udp touch handler. 144 /// Retrieves the underlying udp touch handler.
138 [[nodiscard]] const UDPTouchFactory* GetUDPTouch() const; 145 [[nodiscard]] const UDPTouchFactory* GetUDPTouch() const;
139 146
147 /// Retrieves the underlying GameCube button handler.
148 [[nodiscard]] MouseButtonFactory* GetMouseButtons();
149
150 /// Retrieves the underlying GameCube button handler.
151 [[nodiscard]] const MouseButtonFactory* GetMouseButtons() const;
152
153 /// Retrieves the underlying udp touch handler.
154 [[nodiscard]] MouseAnalogFactory* GetMouseAnalogs();
155
156 /// Retrieves the underlying udp touch handler.
157 [[nodiscard]] const MouseAnalogFactory* GetMouseAnalogs() const;
158
159 /// Retrieves the underlying udp motion handler.
160 [[nodiscard]] MouseMotionFactory* GetMouseMotions();
161
162 /// Retrieves the underlying udp motion handler.
163 [[nodiscard]] const MouseMotionFactory* GetMouseMotions() const;
164
165 /// Retrieves the underlying udp touch handler.
166 [[nodiscard]] MouseTouchFactory* GetMouseTouch();
167
168 /// Retrieves the underlying udp touch handler.
169 [[nodiscard]] const MouseTouchFactory* GetMouseTouch() const;
170
140 /// Reloads the input devices 171 /// Reloads the input devices
141 void ReloadInputDevices(); 172 void ReloadInputDevices();
142 173
diff --git a/src/input_common/motion_emu.cpp b/src/input_common/motion_emu.cpp
deleted file mode 100644
index d4da5596b..000000000
--- a/src/input_common/motion_emu.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
1// Copyright 2017 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <algorithm>
6#include <chrono>
7#include <mutex>
8#include <thread>
9#include <tuple>
10#include "common/math_util.h"
11#include "common/quaternion.h"
12#include "common/thread.h"
13#include "common/vector_math.h"
14#include "input_common/motion_emu.h"
15
16namespace InputCommon {
17
18// Implementation class of the motion emulation device
19class MotionEmuDevice {
20public:
21 explicit MotionEmuDevice(int update_millisecond_, float sensitivity_)
22 : update_millisecond(update_millisecond_),
23 update_duration(std::chrono::duration_cast<std::chrono::steady_clock::duration>(
24 std::chrono::milliseconds(update_millisecond))),
25 sensitivity(sensitivity_), motion_emu_thread(&MotionEmuDevice::MotionEmuThread, this) {}
26
27 ~MotionEmuDevice() {
28 if (motion_emu_thread.joinable()) {
29 shutdown_event.Set();
30 motion_emu_thread.join();
31 }
32 }
33
34 void BeginTilt(int x, int y) {
35 mouse_origin = Common::MakeVec(x, y);
36 is_tilting = true;
37 }
38
39 void Tilt(int x, int y) {
40 if (!is_tilting) {
41 return;
42 }
43
44 std::lock_guard guard{tilt_mutex};
45 const auto mouse_move = Common::MakeVec(x, y) - mouse_origin;
46 if (mouse_move.x == 0 && mouse_move.y == 0) {
47 tilt_angle = 0;
48 } else {
49 tilt_direction = mouse_move.Cast<float>();
50 tilt_angle =
51 std::clamp(tilt_direction.Normalize() * sensitivity, 0.0f, Common::PI * 0.5f);
52 }
53 }
54
55 void EndTilt() {
56 std::lock_guard guard{tilt_mutex};
57 tilt_angle = 0;
58 is_tilting = false;
59 }
60
61 Input::MotionStatus GetStatus() {
62 std::lock_guard guard{status_mutex};
63 return status;
64 }
65
66private:
67 const int update_millisecond;
68 const std::chrono::steady_clock::duration update_duration;
69 const float sensitivity;
70
71 Common::Vec2<int> mouse_origin;
72
73 std::mutex tilt_mutex;
74 Common::Vec2<float> tilt_direction;
75 float tilt_angle = 0;
76
77 bool is_tilting = false;
78
79 Common::Event shutdown_event;
80
81 Input::MotionStatus status;
82 std::mutex status_mutex;
83
84 // Note: always keep the thread declaration at the end so that other objects are initialized
85 // before this!
86 std::thread motion_emu_thread;
87
88 void MotionEmuThread() {
89 auto update_time = std::chrono::steady_clock::now();
90 Common::Quaternion<float> q = Common::MakeQuaternion(Common::Vec3<float>(), 0);
91
92 while (!shutdown_event.WaitUntil(update_time)) {
93 update_time += update_duration;
94 const Common::Quaternion<float> old_q = q;
95
96 {
97 std::lock_guard guard{tilt_mutex};
98
99 // Find the quaternion describing current 3DS tilting
100 q = Common::MakeQuaternion(
101 Common::MakeVec(-tilt_direction.y, 0.0f, tilt_direction.x), tilt_angle);
102 }
103
104 const auto inv_q = q.Inverse();
105
106 // Set the gravity vector in world space
107 auto gravity = Common::MakeVec(0.0f, -1.0f, 0.0f);
108
109 // Find the angular rate vector in world space
110 auto angular_rate = ((q - old_q) * inv_q).xyz * 2;
111 angular_rate *= static_cast<float>(1000 / update_millisecond) / Common::PI * 180.0f;
112
113 // Transform the two vectors from world space to 3DS space
114 gravity = QuaternionRotate(inv_q, gravity);
115 angular_rate = QuaternionRotate(inv_q, angular_rate);
116
117 // TODO: Calculate the correct rotation vector and orientation matrix
118 const auto matrix4x4 = q.ToMatrix();
119 const auto rotation = Common::MakeVec(0.0f, 0.0f, 0.0f);
120 const std::array orientation{
121 Common::Vec3f(matrix4x4[0], matrix4x4[1], -matrix4x4[2]),
122 Common::Vec3f(matrix4x4[4], matrix4x4[5], -matrix4x4[6]),
123 Common::Vec3f(-matrix4x4[8], -matrix4x4[9], matrix4x4[10]),
124 };
125
126 // Update the sensor state
127 {
128 std::lock_guard guard{status_mutex};
129 status = std::make_tuple(gravity, angular_rate, rotation, orientation);
130 }
131 }
132 }
133};
134
135// Interface wrapper held by input receiver as a unique_ptr. It holds the implementation class as
136// a shared_ptr, which is also observed by the factory class as a weak_ptr. In this way the factory
137// can forward all the inputs to the implementation only when it is valid.
138class MotionEmuDeviceWrapper : public Input::MotionDevice {
139public:
140 explicit MotionEmuDeviceWrapper(int update_millisecond, float sensitivity) {
141 device = std::make_shared<MotionEmuDevice>(update_millisecond, sensitivity);
142 }
143
144 Input::MotionStatus GetStatus() const override {
145 return device->GetStatus();
146 }
147
148 std::shared_ptr<MotionEmuDevice> device;
149};
150
151std::unique_ptr<Input::MotionDevice> MotionEmu::Create(const Common::ParamPackage& params) {
152 const int update_period = params.Get("update_period", 100);
153 const float sensitivity = params.Get("sensitivity", 0.01f);
154 auto device_wrapper = std::make_unique<MotionEmuDeviceWrapper>(update_period, sensitivity);
155 // Previously created device is disconnected here. Having two motion devices for 3DS is not
156 // expected.
157 current_device = device_wrapper->device;
158 return device_wrapper;
159}
160
161void MotionEmu::BeginTilt(int x, int y) {
162 if (auto ptr = current_device.lock()) {
163 ptr->BeginTilt(x, y);
164 }
165}
166
167void MotionEmu::Tilt(int x, int y) {
168 if (auto ptr = current_device.lock()) {
169 ptr->Tilt(x, y);
170 }
171}
172
173void MotionEmu::EndTilt() {
174 if (auto ptr = current_device.lock()) {
175 ptr->EndTilt();
176 }
177}
178
179} // namespace InputCommon
diff --git a/src/input_common/motion_emu.h b/src/input_common/motion_emu.h
deleted file mode 100644
index 7a7e22467..000000000
--- a/src/input_common/motion_emu.h
+++ /dev/null
@@ -1,46 +0,0 @@
1// Copyright 2017 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/frontend/input.h"
8
9namespace InputCommon {
10
11class MotionEmuDevice;
12
13class MotionEmu : public Input::Factory<Input::MotionDevice> {
14public:
15 /**
16 * Creates a motion device emulated from mouse input
17 * @param params contains parameters for creating the device:
18 * - "update_period": update period in milliseconds
19 * - "sensitivity": the coefficient converting mouse movement to tilting angle
20 */
21 std::unique_ptr<Input::MotionDevice> Create(const Common::ParamPackage& params) override;
22
23 /**
24 * Signals that a motion sensor tilt has begun.
25 * @param x the x-coordinate of the cursor
26 * @param y the y-coordinate of the cursor
27 */
28 void BeginTilt(int x, int y);
29
30 /**
31 * Signals that a motion sensor tilt is occurring.
32 * @param x the x-coordinate of the cursor
33 * @param y the y-coordinate of the cursor
34 */
35 void Tilt(int x, int y);
36
37 /**
38 * Signals that a motion sensor tilt has ended.
39 */
40 void EndTilt();
41
42private:
43 std::weak_ptr<MotionEmuDevice> current_device;
44};
45
46} // namespace InputCommon
diff --git a/src/input_common/mouse/mouse_input.cpp b/src/input_common/mouse/mouse_input.cpp
new file mode 100644
index 000000000..d0ee64ad7
--- /dev/null
+++ b/src/input_common/mouse/mouse_input.cpp
@@ -0,0 +1,127 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2+
3// Refer to the license.txt file included.
4
5#include "common/logging/log.h"
6#include "common/math_util.h"
7#include "common/param_package.h"
8#include "input_common/mouse/mouse_input.h"
9
10namespace MouseInput {
11
12Mouse::Mouse() {
13 update_thread = std::thread(&Mouse::UpdateThread, this);
14}
15
16Mouse::~Mouse() {
17 update_thread_running = false;
18 if (update_thread.joinable()) {
19 update_thread.join();
20 }
21}
22
23void Mouse::UpdateThread() {
24 constexpr int update_time = 10;
25 while (update_thread_running) {
26 for (MouseInfo& info : mouse_info) {
27 Common::Vec3f angular_direction = {-info.tilt_direction.y, 0.0f,
28 -info.tilt_direction.x};
29
30 info.motion.SetGyroscope(angular_direction * info.tilt_speed);
31 info.motion.UpdateRotation(update_time * 1000);
32 info.motion.UpdateOrientation(update_time * 1000);
33 info.tilt_speed = 0;
34 info.data.motion = info.motion.GetMotion();
35 }
36 if (configuring) {
37 UpdateYuzuSettings();
38 }
39 std::this_thread::sleep_for(std::chrono::milliseconds(update_time));
40 }
41}
42
43void Mouse::UpdateYuzuSettings() {
44 MouseStatus pad_status{};
45 if (buttons != 0) {
46 pad_status.button = last_button;
47 mouse_queue.Push(pad_status);
48 }
49}
50
51void Mouse::PressButton(int x, int y, int button_) {
52 if (button_ >= static_cast<int>(mouse_info.size())) {
53 return;
54 }
55
56 int button = 1 << button_;
57 const auto button_index = static_cast<std::size_t>(button_);
58 buttons |= static_cast<u16>(button);
59 last_button = static_cast<MouseButton>(button_);
60
61 mouse_info[button_index].mouse_origin = Common::MakeVec(x, y);
62 mouse_info[button_index].last_mouse_position = Common::MakeVec(x, y);
63 mouse_info[button_index].data.pressed = true;
64}
65
66void Mouse::MouseMove(int x, int y) {
67 for (MouseInfo& info : mouse_info) {
68 if (info.data.pressed) {
69 auto mouse_move = Common::MakeVec(x, y) - info.mouse_origin;
70 auto mouse_change = Common::MakeVec(x, y) - info.last_mouse_position;
71 info.last_mouse_position = Common::MakeVec(x, y);
72 info.data.axis = {mouse_move.x, -mouse_move.y};
73
74 if (mouse_change.x == 0 && mouse_change.y == 0) {
75 info.tilt_speed = 0;
76 } else {
77 info.tilt_direction = mouse_change.Cast<float>();
78 info.tilt_speed = info.tilt_direction.Normalize() * info.sensitivity;
79 }
80 }
81 }
82}
83
84void Mouse::ReleaseButton(int button_) {
85 if (button_ >= static_cast<int>(mouse_info.size())) {
86 return;
87 }
88
89 int button = 1 << button_;
90 const auto button_index = static_cast<std::size_t>(button_);
91 buttons &= static_cast<u16>(0xFF - button);
92
93 mouse_info[button_index].tilt_speed = 0;
94 mouse_info[button_index].data.pressed = false;
95 mouse_info[button_index].data.axis = {0, 0};
96}
97
98void Mouse::BeginConfiguration() {
99 buttons = 0;
100 last_button = MouseButton::Undefined;
101 mouse_queue.Clear();
102 configuring = true;
103}
104
105void Mouse::EndConfiguration() {
106 buttons = 0;
107 last_button = MouseButton::Undefined;
108 mouse_queue.Clear();
109 configuring = false;
110}
111
112Common::SPSCQueue<MouseStatus>& Mouse::GetMouseQueue() {
113 return mouse_queue;
114}
115
116const Common::SPSCQueue<MouseStatus>& Mouse::GetMouseQueue() const {
117 return mouse_queue;
118}
119
120MouseData& Mouse::GetMouseState(std::size_t button) {
121 return mouse_info[button].data;
122}
123
124const MouseData& Mouse::GetMouseState(std::size_t button) const {
125 return mouse_info[button].data;
126}
127} // namespace MouseInput
diff --git a/src/input_common/mouse/mouse_input.h b/src/input_common/mouse/mouse_input.h
new file mode 100644
index 000000000..761663334
--- /dev/null
+++ b/src/input_common/mouse/mouse_input.h
@@ -0,0 +1,99 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <algorithm>
8#include <functional>
9#include <mutex>
10#include <thread>
11#include <unordered_map>
12#include "common/common_types.h"
13#include "common/threadsafe_queue.h"
14#include "core/frontend/input.h"
15#include "input_common/main.h"
16#include "input_common/motion_input.h"
17
18namespace MouseInput {
19
20enum class MouseButton {
21 Left,
22 Wheel,
23 Right,
24 Foward,
25 Backward,
26 Undefined,
27};
28
29struct MouseStatus {
30 MouseButton button{MouseButton::Undefined};
31};
32
33struct MouseData {
34 bool pressed{};
35 std::array<int, 2> axis{};
36 Input::MotionStatus motion{};
37 Input::TouchStatus touch{};
38};
39
40class Mouse {
41public:
42 Mouse();
43 ~Mouse();
44
45 /// Used for polling
46 void BeginConfiguration();
47 void EndConfiguration();
48
49 /**
50 * Signals that a button is pressed.
51 * @param x the x-coordinate of the cursor
52 * @param y the y-coordinate of the cursor
53 * @param button the button pressed
54 */
55 void PressButton(int x, int y, int button_);
56
57 /**
58 * Signals that mouse has moved.
59 * @param x the x-coordinate of the cursor
60 * @param y the y-coordinate of the cursor
61 */
62 void MouseMove(int x, int y);
63
64 /**
65 * Signals that a motion sensor tilt has ended.
66 */
67 void ReleaseButton(int button_);
68
69 [[nodiscard]] Common::SPSCQueue<MouseStatus>& GetMouseQueue();
70 [[nodiscard]] const Common::SPSCQueue<MouseStatus>& GetMouseQueue() const;
71
72 [[nodiscard]] MouseData& GetMouseState(std::size_t button);
73 [[nodiscard]] const MouseData& GetMouseState(std::size_t button) const;
74
75private:
76 void UpdateThread();
77 void UpdateYuzuSettings();
78
79 struct MouseInfo {
80 InputCommon::MotionInput motion{0.0f, 0.0f, 0.0f};
81 Common::Vec2<int> mouse_origin;
82 Common::Vec2<int> last_mouse_position;
83 bool is_tilting = false;
84 float sensitivity{0.120f};
85
86 float tilt_speed = 0;
87 Common::Vec2<float> tilt_direction;
88 MouseData data;
89 };
90
91 u16 buttons{};
92 std::thread update_thread;
93 MouseButton last_button{MouseButton::Undefined};
94 std::array<MouseInfo, 5> mouse_info;
95 Common::SPSCQueue<MouseStatus> mouse_queue;
96 bool configuring{false};
97 bool update_thread_running{true};
98};
99} // namespace MouseInput
diff --git a/src/input_common/mouse/mouse_poller.cpp b/src/input_common/mouse/mouse_poller.cpp
new file mode 100644
index 000000000..6213f3dbd
--- /dev/null
+++ b/src/input_common/mouse/mouse_poller.cpp
@@ -0,0 +1,261 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <atomic>
6#include <list>
7#include <mutex>
8#include <utility>
9#include "common/assert.h"
10#include "common/threadsafe_queue.h"
11#include "input_common/mouse/mouse_input.h"
12#include "input_common/mouse/mouse_poller.h"
13
14namespace InputCommon {
15
16class MouseButton final : public Input::ButtonDevice {
17public:
18 explicit MouseButton(u32 button_, const MouseInput::Mouse* mouse_input_)
19 : button(button_), mouse_input(mouse_input_) {}
20
21 bool GetStatus() const override {
22 return mouse_input->GetMouseState(button).pressed;
23 }
24
25private:
26 const u32 button;
27 const MouseInput::Mouse* mouse_input;
28};
29
30MouseButtonFactory::MouseButtonFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_)
31 : mouse_input(std::move(mouse_input_)) {}
32
33std::unique_ptr<Input::ButtonDevice> MouseButtonFactory::Create(
34 const Common::ParamPackage& params) {
35 const auto button_id = params.Get("button", 0);
36
37 return std::make_unique<MouseButton>(button_id, mouse_input.get());
38}
39
40Common::ParamPackage MouseButtonFactory::GetNextInput() const {
41 MouseInput::MouseStatus pad;
42 Common::ParamPackage params;
43 auto& queue = mouse_input->GetMouseQueue();
44 while (queue.Pop(pad)) {
45 // This while loop will break on the earliest detected button
46 if (pad.button != MouseInput::MouseButton::Undefined) {
47 params.Set("engine", "mouse");
48 params.Set("button", static_cast<u16>(pad.button));
49 return params;
50 }
51 }
52 return params;
53}
54
55void MouseButtonFactory::BeginConfiguration() {
56 polling = true;
57 mouse_input->BeginConfiguration();
58}
59
60void MouseButtonFactory::EndConfiguration() {
61 polling = false;
62 mouse_input->EndConfiguration();
63}
64
65class MouseAnalog final : public Input::AnalogDevice {
66public:
67 explicit MouseAnalog(u32 port_, u32 axis_x_, u32 axis_y_, float deadzone_, float range_,
68 const MouseInput::Mouse* mouse_input_)
69 : button(port_), axis_x(axis_x_), axis_y(axis_y_), deadzone(deadzone_), range(range_),
70 mouse_input(mouse_input_) {}
71
72 float GetAxis(u32 axis) const {
73 std::lock_guard lock{mutex};
74 const auto axis_value =
75 static_cast<float>(mouse_input->GetMouseState(button).axis.at(axis));
76 return axis_value / (100.0f * range);
77 }
78
79 std::pair<float, float> GetAnalog(u32 analog_axis_x, u32 analog_axis_y) const {
80 float x = GetAxis(analog_axis_x);
81 float y = GetAxis(analog_axis_y);
82
83 // Make sure the coordinates are in the unit circle,
84 // otherwise normalize it.
85 float r = x * x + y * y;
86 if (r > 1.0f) {
87 r = std::sqrt(r);
88 x /= r;
89 y /= r;
90 }
91
92 return {x, y};
93 }
94
95 std::tuple<float, float> GetStatus() const override {
96 const auto [x, y] = GetAnalog(axis_x, axis_y);
97 const float r = std::sqrt((x * x) + (y * y));
98 if (r > deadzone) {
99 return {x / r * (r - deadzone) / (1 - deadzone),
100 y / r * (r - deadzone) / (1 - deadzone)};
101 }
102 return {0.0f, 0.0f};
103 }
104
105private:
106 const u32 button;
107 const u32 axis_x;
108 const u32 axis_y;
109 const float deadzone;
110 const float range;
111 const MouseInput::Mouse* mouse_input;
112 mutable std::mutex mutex;
113};
114
115/// An analog device factory that creates analog devices from GC Adapter
116MouseAnalogFactory::MouseAnalogFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_)
117 : mouse_input(std::move(mouse_input_)) {}
118
119/**
120 * Creates analog device from joystick axes
121 * @param params contains parameters for creating the device:
122 * - "port": the nth gcpad on the adapter
123 * - "axis_x": the index of the axis to be bind as x-axis
124 * - "axis_y": the index of the axis to be bind as y-axis
125 */
126std::unique_ptr<Input::AnalogDevice> MouseAnalogFactory::Create(
127 const Common::ParamPackage& params) {
128 const auto port = static_cast<u32>(params.Get("port", 0));
129 const auto axis_x = static_cast<u32>(params.Get("axis_x", 0));
130 const auto axis_y = static_cast<u32>(params.Get("axis_y", 1));
131 const auto deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f);
132 const auto range = std::clamp(params.Get("range", 1.0f), 0.50f, 1.50f);
133
134 return std::make_unique<MouseAnalog>(port, axis_x, axis_y, deadzone, range, mouse_input.get());
135}
136
137void MouseAnalogFactory::BeginConfiguration() {
138 polling = true;
139 mouse_input->BeginConfiguration();
140}
141
142void MouseAnalogFactory::EndConfiguration() {
143 polling = false;
144 mouse_input->EndConfiguration();
145}
146
147Common::ParamPackage MouseAnalogFactory::GetNextInput() const {
148 MouseInput::MouseStatus pad;
149 Common::ParamPackage params;
150 auto& queue = mouse_input->GetMouseQueue();
151 while (queue.Pop(pad)) {
152 // This while loop will break on the earliest detected button
153 if (pad.button != MouseInput::MouseButton::Undefined) {
154 params.Set("engine", "mouse");
155 params.Set("port", static_cast<u16>(pad.button));
156 params.Set("axis_x", 0);
157 params.Set("axis_y", 1);
158 return params;
159 }
160 }
161 return params;
162}
163
164class MouseMotion final : public Input::MotionDevice {
165public:
166 explicit MouseMotion(u32 button_, const MouseInput::Mouse* mouse_input_)
167 : button(button_), mouse_input(mouse_input_) {}
168
169 Input::MotionStatus GetStatus() const override {
170 return mouse_input->GetMouseState(button).motion;
171 }
172
173private:
174 const u32 button;
175 const MouseInput::Mouse* mouse_input;
176};
177
178MouseMotionFactory::MouseMotionFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_)
179 : mouse_input(std::move(mouse_input_)) {}
180
181std::unique_ptr<Input::MotionDevice> MouseMotionFactory::Create(
182 const Common::ParamPackage& params) {
183 const auto button_id = params.Get("button", 0);
184
185 return std::make_unique<MouseMotion>(button_id, mouse_input.get());
186}
187
188Common::ParamPackage MouseMotionFactory::GetNextInput() const {
189 MouseInput::MouseStatus pad;
190 Common::ParamPackage params;
191 auto& queue = mouse_input->GetMouseQueue();
192 while (queue.Pop(pad)) {
193 // This while loop will break on the earliest detected button
194 if (pad.button != MouseInput::MouseButton::Undefined) {
195 params.Set("engine", "mouse");
196 params.Set("button", static_cast<u16>(pad.button));
197 return params;
198 }
199 }
200 return params;
201}
202
203void MouseMotionFactory::BeginConfiguration() {
204 polling = true;
205 mouse_input->BeginConfiguration();
206}
207
208void MouseMotionFactory::EndConfiguration() {
209 polling = false;
210 mouse_input->EndConfiguration();
211}
212
213class MouseTouch final : public Input::TouchDevice {
214public:
215 explicit MouseTouch(u32 button_, const MouseInput::Mouse* mouse_input_)
216 : button(button_), mouse_input(mouse_input_) {}
217
218 Input::TouchStatus GetStatus() const override {
219 return mouse_input->GetMouseState(button).touch;
220 }
221
222private:
223 const u32 button;
224 const MouseInput::Mouse* mouse_input;
225};
226
227MouseTouchFactory::MouseTouchFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_)
228 : mouse_input(std::move(mouse_input_)) {}
229
230std::unique_ptr<Input::TouchDevice> MouseTouchFactory::Create(const Common::ParamPackage& params) {
231 const auto button_id = params.Get("button", 0);
232
233 return std::make_unique<MouseTouch>(button_id, mouse_input.get());
234}
235
236Common::ParamPackage MouseTouchFactory::GetNextInput() const {
237 MouseInput::MouseStatus pad;
238 Common::ParamPackage params;
239 auto& queue = mouse_input->GetMouseQueue();
240 while (queue.Pop(pad)) {
241 // This while loop will break on the earliest detected button
242 if (pad.button != MouseInput::MouseButton::Undefined) {
243 params.Set("engine", "mouse");
244 params.Set("button", static_cast<u16>(pad.button));
245 return params;
246 }
247 }
248 return params;
249}
250
251void MouseTouchFactory::BeginConfiguration() {
252 polling = true;
253 mouse_input->BeginConfiguration();
254}
255
256void MouseTouchFactory::EndConfiguration() {
257 polling = false;
258 mouse_input->EndConfiguration();
259}
260
261} // namespace InputCommon
diff --git a/src/input_common/mouse/mouse_poller.h b/src/input_common/mouse/mouse_poller.h
new file mode 100644
index 000000000..cf331293b
--- /dev/null
+++ b/src/input_common/mouse/mouse_poller.h
@@ -0,0 +1,109 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8#include "core/frontend/input.h"
9#include "input_common/mouse/mouse_input.h"
10
11namespace InputCommon {
12
13/**
14 * A button device factory representing a mouse. It receives mouse events and forward them
15 * to all button devices it created.
16 */
17class MouseButtonFactory final : public Input::Factory<Input::ButtonDevice> {
18public:
19 explicit MouseButtonFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_);
20
21 /**
22 * Creates a button device from a button press
23 * @param params contains parameters for creating the device:
24 * - "code": the code of the key to bind with the button
25 */
26 std::unique_ptr<Input::ButtonDevice> Create(const Common::ParamPackage& params) override;
27
28 Common::ParamPackage GetNextInput() const;
29
30 /// For device input configuration/polling
31 void BeginConfiguration();
32 void EndConfiguration();
33
34 bool IsPolling() const {
35 return polling;
36 }
37
38private:
39 std::shared_ptr<MouseInput::Mouse> mouse_input;
40 bool polling = false;
41};
42
43/// An analog device factory that creates analog devices from mouse
44class MouseAnalogFactory final : public Input::Factory<Input::AnalogDevice> {
45public:
46 explicit MouseAnalogFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_);
47
48 std::unique_ptr<Input::AnalogDevice> Create(const Common::ParamPackage& params) override;
49
50 Common::ParamPackage GetNextInput() const;
51
52 /// For device input configuration/polling
53 void BeginConfiguration();
54 void EndConfiguration();
55
56 bool IsPolling() const {
57 return polling;
58 }
59
60private:
61 std::shared_ptr<MouseInput::Mouse> mouse_input;
62 bool polling = false;
63};
64
65/// A motion device factory that creates motion devices from mouse
66class MouseMotionFactory final : public Input::Factory<Input::MotionDevice> {
67public:
68 explicit MouseMotionFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_);
69
70 std::unique_ptr<Input::MotionDevice> Create(const Common::ParamPackage& params) override;
71
72 Common::ParamPackage GetNextInput() const;
73
74 /// For device input configuration/polling
75 void BeginConfiguration();
76 void EndConfiguration();
77
78 bool IsPolling() const {
79 return polling;
80 }
81
82private:
83 std::shared_ptr<MouseInput::Mouse> mouse_input;
84 bool polling = false;
85};
86
87/// An touch device factory that creates touch devices from mouse
88class MouseTouchFactory final : public Input::Factory<Input::TouchDevice> {
89public:
90 explicit MouseTouchFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_);
91
92 std::unique_ptr<Input::TouchDevice> Create(const Common::ParamPackage& params) override;
93
94 Common::ParamPackage GetNextInput() const;
95
96 /// For device input configuration/polling
97 void BeginConfiguration();
98 void EndConfiguration();
99
100 bool IsPolling() const {
101 return polling;
102 }
103
104private:
105 std::shared_ptr<MouseInput::Mouse> mouse_input;
106 bool polling = false;
107};
108
109} // namespace InputCommon
diff --git a/src/input_common/udp/client.cpp b/src/input_common/udp/client.cpp
index c0bb90048..17a9225d7 100644
--- a/src/input_common/udp/client.cpp
+++ b/src/input_common/udp/client.cpp
@@ -136,15 +136,7 @@ static void SocketLoop(Socket* socket) {
136 136
137Client::Client() { 137Client::Client() {
138 LOG_INFO(Input, "Udp Initialization started"); 138 LOG_INFO(Input, "Udp Initialization started");
139 for (std::size_t client = 0; client < clients.size(); client++) { 139 ReloadSockets();
140 const auto pad = client % 4;
141 StartCommunication(client, Settings::values.udp_input_address,
142 Settings::values.udp_input_port, pad, 24872);
143 // Set motion parameters
144 // SetGyroThreshold value should be dependent on GyroscopeZeroDriftMode
145 // Real HW values are unknown, 0.0001 is an approximate to Standard
146 clients[client].motion.SetGyroThreshold(0.0001f);
147 }
148} 140}
149 141
150Client::~Client() { 142Client::~Client() {
@@ -167,26 +159,61 @@ std::vector<Common::ParamPackage> Client::GetInputDevices() const {
167 return devices; 159 return devices;
168} 160}
169 161
170bool Client::DeviceConnected(std::size_t pad) const { 162bool Client::DeviceConnected(std::size_t client) const {
171 // Use last timestamp to detect if the socket has stopped sending data 163 // Use last timestamp to detect if the socket has stopped sending data
172 const auto now = std::chrono::system_clock::now(); 164 const auto now = std::chrono::steady_clock::now();
173 const auto time_difference = static_cast<u64>( 165 const auto time_difference =
174 std::chrono::duration_cast<std::chrono::milliseconds>(now - clients[pad].last_motion_update) 166 static_cast<u64>(std::chrono::duration_cast<std::chrono::milliseconds>(
175 .count()); 167 now - clients[client].last_motion_update)
176 return time_difference < 1000 && clients[pad].active == 1; 168 .count());
169 return time_difference < 1000 && clients[client].active == 1;
177} 170}
178 171
179void Client::ReloadUDPClient() { 172void Client::ReloadSockets() {
180 for (std::size_t client = 0; client < clients.size(); client++) { 173 Reset();
181 ReloadSocket(Settings::values.udp_input_address, Settings::values.udp_input_port, client); 174
175 std::stringstream servers_ss(Settings::values.udp_input_servers);
176 std::string server_token;
177 std::size_t client = 0;
178 while (std::getline(servers_ss, server_token, ',')) {
179 if (client == max_udp_clients) {
180 break;
181 }
182 std::stringstream server_ss(server_token);
183 std::string token;
184 std::getline(server_ss, token, ':');
185 std::string udp_input_address = token;
186 std::getline(server_ss, token, ':');
187 char* temp;
188 const u16 udp_input_port = static_cast<u16>(std::strtol(token.c_str(), &temp, 0));
189 if (*temp != '\0') {
190 LOG_ERROR(Input, "Port number is not valid {}", token);
191 continue;
192 }
193
194 for (std::size_t pad = 0; pad < 4; ++pad) {
195 const std::size_t client_number =
196 GetClientNumber(udp_input_address, udp_input_port, pad);
197 if (client_number != max_udp_clients) {
198 LOG_ERROR(Input, "Duplicated UDP servers found");
199 continue;
200 }
201 StartCommunication(client++, udp_input_address, udp_input_port, pad, 24872);
202 }
182 } 203 }
183} 204}
184void Client::ReloadSocket(const std::string& host, u16 port, std::size_t pad_index, u32 client_id) { 205
185 // client number must be determined from host / port and pad index 206std::size_t Client::GetClientNumber(std::string_view host, u16 port, std::size_t pad) const {
186 const std::size_t client = pad_index; 207 for (std::size_t client = 0; client < clients.size(); client++) {
187 clients[client].socket->Stop(); 208 if (clients[client].active == -1) {
188 clients[client].thread.join(); 209 continue;
189 StartCommunication(client, host, port, pad_index, client_id); 210 }
211 if (clients[client].host == host && clients[client].port == port &&
212 clients[client].pad_index == pad) {
213 return client;
214 }
215 }
216 return max_udp_clients;
190} 217}
191 218
192void Client::OnVersion([[maybe_unused]] Response::Version data) { 219void Client::OnVersion([[maybe_unused]] Response::Version data) {
@@ -197,9 +224,7 @@ void Client::OnPortInfo([[maybe_unused]] Response::PortInfo data) {
197 LOG_TRACE(Input, "PortInfo packet received: {}", data.model); 224 LOG_TRACE(Input, "PortInfo packet received: {}", data.model);
198} 225}
199 226
200void Client::OnPadData(Response::PadData data) { 227void Client::OnPadData(Response::PadData data, std::size_t client) {
201 // Client number must be determined from host / port and pad index
202 const std::size_t client = data.info.id;
203 LOG_TRACE(Input, "PadData packet received"); 228 LOG_TRACE(Input, "PadData packet received");
204 if (data.packet_counter == clients[client].packet_sequence) { 229 if (data.packet_counter == clients[client].packet_sequence) {
205 LOG_WARNING( 230 LOG_WARNING(
@@ -208,9 +233,9 @@ void Client::OnPadData(Response::PadData data) {
208 clients[client].packet_sequence, data.packet_counter); 233 clients[client].packet_sequence, data.packet_counter);
209 return; 234 return;
210 } 235 }
211 clients[client].active = data.info.is_pad_active; 236 clients[client].active = static_cast<s8>(data.info.is_pad_active);
212 clients[client].packet_sequence = data.packet_counter; 237 clients[client].packet_sequence = data.packet_counter;
213 const auto now = std::chrono::system_clock::now(); 238 const auto now = std::chrono::steady_clock::now();
214 const auto time_difference = 239 const auto time_difference =
215 static_cast<u64>(std::chrono::duration_cast<std::chrono::microseconds>( 240 static_cast<u64>(std::chrono::duration_cast<std::chrono::microseconds>(
216 now - clients[client].last_motion_update) 241 now - clients[client].last_motion_update)
@@ -264,16 +289,28 @@ void Client::StartCommunication(std::size_t client, const std::string& host, u16
264 std::size_t pad_index, u32 client_id) { 289 std::size_t pad_index, u32 client_id) {
265 SocketCallback callback{[this](Response::Version version) { OnVersion(version); }, 290 SocketCallback callback{[this](Response::Version version) { OnVersion(version); },
266 [this](Response::PortInfo info) { OnPortInfo(info); }, 291 [this](Response::PortInfo info) { OnPortInfo(info); },
267 [this](Response::PadData data) { OnPadData(data); }}; 292 [this, client](Response::PadData data) { OnPadData(data, client); }};
268 LOG_INFO(Input, "Starting communication with UDP input server on {}:{}", host, port); 293 LOG_INFO(Input, "Starting communication with UDP input server on {}:{}:{}", host, port,
294 pad_index);
295 clients[client].host = host;
296 clients[client].port = port;
297 clients[client].pad_index = pad_index;
298 clients[client].active = 0;
269 clients[client].socket = std::make_unique<Socket>(host, port, pad_index, client_id, callback); 299 clients[client].socket = std::make_unique<Socket>(host, port, pad_index, client_id, callback);
270 clients[client].thread = std::thread{SocketLoop, clients[client].socket.get()}; 300 clients[client].thread = std::thread{SocketLoop, clients[client].socket.get()};
301 // Set motion parameters
302 // SetGyroThreshold value should be dependent on GyroscopeZeroDriftMode
303 // Real HW values are unknown, 0.0001 is an approximate to Standard
304 clients[client].motion.SetGyroThreshold(0.0001f);
271} 305}
272 306
273void Client::Reset() { 307void Client::Reset() {
274 for (auto& client : clients) { 308 for (auto& client : clients) {
275 client.socket->Stop(); 309 if (client.thread.joinable()) {
276 client.thread.join(); 310 client.active = -1;
311 client.socket->Stop();
312 client.thread.join();
313 }
277 } 314 }
278} 315}
279 316
@@ -283,52 +320,60 @@ void Client::UpdateYuzuSettings(std::size_t client, const Common::Vec3<float>& a
283 LOG_DEBUG(Input, "UDP Controller {}: gyro=({}, {}, {}), accel=({}, {}, {}), touch={}", 320 LOG_DEBUG(Input, "UDP Controller {}: gyro=({}, {}, {}), accel=({}, {}, {}), touch={}",
284 client, gyro[0], gyro[1], gyro[2], acc[0], acc[1], acc[2], touch); 321 client, gyro[0], gyro[1], gyro[2], acc[0], acc[1], acc[2], touch);
285 } 322 }
286 UDPPadStatus pad; 323 UDPPadStatus pad{
324 .host = clients[client].host,
325 .port = clients[client].port,
326 .pad_index = clients[client].pad_index,
327 };
287 if (touch) { 328 if (touch) {
288 pad.touch = PadTouch::Click; 329 pad.touch = PadTouch::Click;
289 pad_queue[client].Push(pad); 330 pad_queue.Push(pad);
290 } 331 }
291 for (size_t i = 0; i < 3; ++i) { 332 for (size_t i = 0; i < 3; ++i) {
292 if (gyro[i] > 5.0f || gyro[i] < -5.0f) { 333 if (gyro[i] > 5.0f || gyro[i] < -5.0f) {
293 pad.motion = static_cast<PadMotion>(i); 334 pad.motion = static_cast<PadMotion>(i);
294 pad.motion_value = gyro[i]; 335 pad.motion_value = gyro[i];
295 pad_queue[client].Push(pad); 336 pad_queue.Push(pad);
296 } 337 }
297 if (acc[i] > 1.75f || acc[i] < -1.75f) { 338 if (acc[i] > 1.75f || acc[i] < -1.75f) {
298 pad.motion = static_cast<PadMotion>(i + 3); 339 pad.motion = static_cast<PadMotion>(i + 3);
299 pad.motion_value = acc[i]; 340 pad.motion_value = acc[i];
300 pad_queue[client].Push(pad); 341 pad_queue.Push(pad);
301 } 342 }
302 } 343 }
303} 344}
304 345
305void Client::BeginConfiguration() { 346void Client::BeginConfiguration() {
306 for (auto& pq : pad_queue) { 347 pad_queue.Clear();
307 pq.Clear();
308 }
309 configuring = true; 348 configuring = true;
310} 349}
311 350
312void Client::EndConfiguration() { 351void Client::EndConfiguration() {
313 for (auto& pq : pad_queue) { 352 pad_queue.Clear();
314 pq.Clear();
315 }
316 configuring = false; 353 configuring = false;
317} 354}
318 355
319DeviceStatus& Client::GetPadState(std::size_t pad) { 356DeviceStatus& Client::GetPadState(const std::string& host, u16 port, std::size_t pad) {
320 return clients[pad].status; 357 const std::size_t client_number = GetClientNumber(host, port, pad);
358 if (client_number == max_udp_clients) {
359 return clients[0].status;
360 }
361 return clients[client_number].status;
321} 362}
322 363
323const DeviceStatus& Client::GetPadState(std::size_t pad) const { 364const DeviceStatus& Client::GetPadState(const std::string& host, u16 port, std::size_t pad) const {
324 return clients[pad].status; 365 const std::size_t client_number = GetClientNumber(host, port, pad);
366 if (client_number == max_udp_clients) {
367 return clients[0].status;
368 }
369 return clients[client_number].status;
325} 370}
326 371
327std::array<Common::SPSCQueue<UDPPadStatus>, 4>& Client::GetPadQueue() { 372Common::SPSCQueue<UDPPadStatus>& Client::GetPadQueue() {
328 return pad_queue; 373 return pad_queue;
329} 374}
330 375
331const std::array<Common::SPSCQueue<UDPPadStatus>, 4>& Client::GetPadQueue() const { 376const Common::SPSCQueue<UDPPadStatus>& Client::GetPadQueue() const {
332 return pad_queue; 377 return pad_queue;
333} 378}
334 379
diff --git a/src/input_common/udp/client.h b/src/input_common/udp/client.h
index 747e0c0a2..00c8b09f5 100644
--- a/src/input_common/udp/client.h
+++ b/src/input_common/udp/client.h
@@ -21,8 +21,7 @@
21 21
22namespace InputCommon::CemuhookUDP { 22namespace InputCommon::CemuhookUDP {
23 23
24constexpr u16 DEFAULT_PORT = 26760; 24constexpr char DEFAULT_SRV[] = "127.0.0.1:26760";
25constexpr char DEFAULT_ADDR[] = "127.0.0.1";
26 25
27class Socket; 26class Socket;
28 27
@@ -48,6 +47,9 @@ enum class PadTouch {
48}; 47};
49 48
50struct UDPPadStatus { 49struct UDPPadStatus {
50 std::string host{"127.0.0.1"};
51 u16 port{26760};
52 std::size_t pad_index{};
51 PadTouch touch{PadTouch::Undefined}; 53 PadTouch touch{PadTouch::Undefined};
52 PadMotion motion{PadMotion::Undefined}; 54 PadMotion motion{PadMotion::Undefined};
53 f32 motion_value{0.0f}; 55 f32 motion_value{0.0f};
@@ -82,37 +84,41 @@ public:
82 84
83 std::vector<Common::ParamPackage> GetInputDevices() const; 85 std::vector<Common::ParamPackage> GetInputDevices() const;
84 86
85 bool DeviceConnected(std::size_t pad) const; 87 bool DeviceConnected(std::size_t client) const;
86 void ReloadUDPClient(); 88 void ReloadSockets();
87 void ReloadSocket(const std::string& host = "127.0.0.1", u16 port = 26760,
88 std::size_t pad_index = 0, u32 client_id = 24872);
89 89
90 std::array<Common::SPSCQueue<UDPPadStatus>, 4>& GetPadQueue(); 90 Common::SPSCQueue<UDPPadStatus>& GetPadQueue();
91 const std::array<Common::SPSCQueue<UDPPadStatus>, 4>& GetPadQueue() const; 91 const Common::SPSCQueue<UDPPadStatus>& GetPadQueue() const;
92 92
93 DeviceStatus& GetPadState(std::size_t pad); 93 DeviceStatus& GetPadState(const std::string& host, u16 port, std::size_t pad);
94 const DeviceStatus& GetPadState(std::size_t pad) const; 94 const DeviceStatus& GetPadState(const std::string& host, u16 port, std::size_t pad) const;
95 95
96private: 96private:
97 struct ClientData { 97 struct ClientData {
98 std::string host{"127.0.0.1"};
99 u16 port{26760};
100 std::size_t pad_index{};
98 std::unique_ptr<Socket> socket; 101 std::unique_ptr<Socket> socket;
99 DeviceStatus status; 102 DeviceStatus status;
100 std::thread thread; 103 std::thread thread;
101 u64 packet_sequence = 0; 104 u64 packet_sequence{};
102 u8 active = 0; 105 s8 active{-1};
103 106
104 // Realtime values 107 // Realtime values
105 // motion is initalized with PID values for drift correction on joycons 108 // motion is initalized with PID values for drift correction on joycons
106 InputCommon::MotionInput motion{0.3f, 0.005f, 0.0f}; 109 InputCommon::MotionInput motion{0.3f, 0.005f, 0.0f};
107 std::chrono::time_point<std::chrono::system_clock> last_motion_update; 110 std::chrono::time_point<std::chrono::steady_clock> last_motion_update;
108 }; 111 };
109 112
110 // For shutting down, clear all data, join all threads, release usb 113 // For shutting down, clear all data, join all threads, release usb
111 void Reset(); 114 void Reset();
112 115
116 // Translates configuration to client number
117 std::size_t GetClientNumber(std::string_view host, u16 port, std::size_t pad) const;
118
113 void OnVersion(Response::Version); 119 void OnVersion(Response::Version);
114 void OnPortInfo(Response::PortInfo); 120 void OnPortInfo(Response::PortInfo);
115 void OnPadData(Response::PadData); 121 void OnPadData(Response::PadData, std::size_t client);
116 void StartCommunication(std::size_t client, const std::string& host, u16 port, 122 void StartCommunication(std::size_t client, const std::string& host, u16 port,
117 std::size_t pad_index, u32 client_id); 123 std::size_t pad_index, u32 client_id);
118 void UpdateYuzuSettings(std::size_t client, const Common::Vec3<float>& acc, 124 void UpdateYuzuSettings(std::size_t client, const Common::Vec3<float>& acc,
@@ -120,8 +126,10 @@ private:
120 126
121 bool configuring = false; 127 bool configuring = false;
122 128
123 std::array<ClientData, 4> clients; 129 // Allocate clients for 8 udp servers
124 std::array<Common::SPSCQueue<UDPPadStatus>, 4> pad_queue; 130 const std::size_t max_udp_clients = 32;
131 std::array<ClientData, 4 * 8> clients;
132 Common::SPSCQueue<UDPPadStatus> pad_queue;
125}; 133};
126 134
127/// An async job allowing configuration of the touchpad calibration. 135/// An async job allowing configuration of the touchpad calibration.
diff --git a/src/input_common/udp/udp.cpp b/src/input_common/udp/udp.cpp
index 71a76a7aa..8686a059c 100644
--- a/src/input_common/udp/udp.cpp
+++ b/src/input_common/udp/udp.cpp
@@ -13,17 +13,17 @@ namespace InputCommon {
13 13
14class UDPMotion final : public Input::MotionDevice { 14class UDPMotion final : public Input::MotionDevice {
15public: 15public:
16 explicit UDPMotion(std::string ip_, int port_, u32 pad_, CemuhookUDP::Client* client_) 16 explicit UDPMotion(std::string ip_, u16 port_, u16 pad_, CemuhookUDP::Client* client_)
17 : ip(std::move(ip_)), port(port_), pad(pad_), client(client_) {} 17 : ip(std::move(ip_)), port(port_), pad(pad_), client(client_) {}
18 18
19 Input::MotionStatus GetStatus() const override { 19 Input::MotionStatus GetStatus() const override {
20 return client->GetPadState(pad).motion_status; 20 return client->GetPadState(ip, port, pad).motion_status;
21 } 21 }
22 22
23private: 23private:
24 const std::string ip; 24 const std::string ip;
25 const int port; 25 const u16 port;
26 const u32 pad; 26 const u16 pad;
27 CemuhookUDP::Client* client; 27 CemuhookUDP::Client* client;
28 mutable std::mutex mutex; 28 mutable std::mutex mutex;
29}; 29};
@@ -39,8 +39,8 @@ UDPMotionFactory::UDPMotionFactory(std::shared_ptr<CemuhookUDP::Client> client_)
39 */ 39 */
40std::unique_ptr<Input::MotionDevice> UDPMotionFactory::Create(const Common::ParamPackage& params) { 40std::unique_ptr<Input::MotionDevice> UDPMotionFactory::Create(const Common::ParamPackage& params) {
41 auto ip = params.Get("ip", "127.0.0.1"); 41 auto ip = params.Get("ip", "127.0.0.1");
42 const auto port = params.Get("port", 26760); 42 const auto port = static_cast<u16>(params.Get("port", 26760));
43 const auto pad = static_cast<u32>(params.Get("pad_index", 0)); 43 const auto pad = static_cast<u16>(params.Get("pad_index", 0));
44 44
45 return std::make_unique<UDPMotion>(std::move(ip), port, pad, client.get()); 45 return std::make_unique<UDPMotion>(std::move(ip), port, pad, client.get());
46} 46}
@@ -59,35 +59,33 @@ Common::ParamPackage UDPMotionFactory::GetNextInput() {
59 Common::ParamPackage params; 59 Common::ParamPackage params;
60 CemuhookUDP::UDPPadStatus pad; 60 CemuhookUDP::UDPPadStatus pad;
61 auto& queue = client->GetPadQueue(); 61 auto& queue = client->GetPadQueue();
62 for (std::size_t pad_number = 0; pad_number < queue.size(); ++pad_number) { 62 while (queue.Pop(pad)) {
63 while (queue[pad_number].Pop(pad)) { 63 if (pad.motion == CemuhookUDP::PadMotion::Undefined || std::abs(pad.motion_value) < 1) {
64 if (pad.motion == CemuhookUDP::PadMotion::Undefined || std::abs(pad.motion_value) < 1) { 64 continue;
65 continue;
66 }
67 params.Set("engine", "cemuhookudp");
68 params.Set("ip", "127.0.0.1");
69 params.Set("port", 26760);
70 params.Set("pad_index", static_cast<int>(pad_number));
71 params.Set("motion", static_cast<u16>(pad.motion));
72 return params;
73 } 65 }
66 params.Set("engine", "cemuhookudp");
67 params.Set("ip", pad.host);
68 params.Set("port", static_cast<u16>(pad.port));
69 params.Set("pad_index", static_cast<u16>(pad.pad_index));
70 params.Set("motion", static_cast<u16>(pad.motion));
71 return params;
74 } 72 }
75 return params; 73 return params;
76} 74}
77 75
78class UDPTouch final : public Input::TouchDevice { 76class UDPTouch final : public Input::TouchDevice {
79public: 77public:
80 explicit UDPTouch(std::string ip_, int port_, u32 pad_, CemuhookUDP::Client* client_) 78 explicit UDPTouch(std::string ip_, u16 port_, u16 pad_, CemuhookUDP::Client* client_)
81 : ip(std::move(ip_)), port(port_), pad(pad_), client(client_) {} 79 : ip(std::move(ip_)), port(port_), pad(pad_), client(client_) {}
82 80
83 std::tuple<float, float, bool> GetStatus() const override { 81 std::tuple<float, float, bool> GetStatus() const override {
84 return client->GetPadState(pad).touch_status; 82 return client->GetPadState(ip, port, pad).touch_status;
85 } 83 }
86 84
87private: 85private:
88 const std::string ip; 86 const std::string ip;
89 const int port; 87 const u16 port;
90 const u32 pad; 88 const u16 pad;
91 CemuhookUDP::Client* client; 89 CemuhookUDP::Client* client;
92 mutable std::mutex mutex; 90 mutable std::mutex mutex;
93}; 91};
@@ -103,8 +101,8 @@ UDPTouchFactory::UDPTouchFactory(std::shared_ptr<CemuhookUDP::Client> client_)
103 */ 101 */
104std::unique_ptr<Input::TouchDevice> UDPTouchFactory::Create(const Common::ParamPackage& params) { 102std::unique_ptr<Input::TouchDevice> UDPTouchFactory::Create(const Common::ParamPackage& params) {
105 auto ip = params.Get("ip", "127.0.0.1"); 103 auto ip = params.Get("ip", "127.0.0.1");
106 const auto port = params.Get("port", 26760); 104 const auto port = static_cast<u16>(params.Get("port", 26760));
107 const auto pad = static_cast<u32>(params.Get("pad_index", 0)); 105 const auto pad = static_cast<u16>(params.Get("pad_index", 0));
108 106
109 return std::make_unique<UDPTouch>(std::move(ip), port, pad, client.get()); 107 return std::make_unique<UDPTouch>(std::move(ip), port, pad, client.get());
110} 108}
@@ -123,18 +121,16 @@ Common::ParamPackage UDPTouchFactory::GetNextInput() {
123 Common::ParamPackage params; 121 Common::ParamPackage params;
124 CemuhookUDP::UDPPadStatus pad; 122 CemuhookUDP::UDPPadStatus pad;
125 auto& queue = client->GetPadQueue(); 123 auto& queue = client->GetPadQueue();
126 for (std::size_t pad_number = 0; pad_number < queue.size(); ++pad_number) { 124 while (queue.Pop(pad)) {
127 while (queue[pad_number].Pop(pad)) { 125 if (pad.touch == CemuhookUDP::PadTouch::Undefined) {
128 if (pad.touch == CemuhookUDP::PadTouch::Undefined) { 126 continue;
129 continue;
130 }
131 params.Set("engine", "cemuhookudp");
132 params.Set("ip", "127.0.0.1");
133 params.Set("port", 26760);
134 params.Set("pad_index", static_cast<int>(pad_number));
135 params.Set("touch", static_cast<u16>(pad.touch));
136 return params;
137 } 127 }
128 params.Set("engine", "cemuhookudp");
129 params.Set("ip", pad.host);
130 params.Set("port", static_cast<u16>(pad.port));
131 params.Set("pad_index", static_cast<u16>(pad.pad_index));
132 params.Set("touch", static_cast<u16>(pad.touch));
133 return params;
138 } 134 }
139 return params; 135 return params;
140} 136}
diff --git a/src/tests/common/bit_field.cpp b/src/tests/common/bit_field.cpp
index 8ca1889f9..182638000 100644
--- a/src/tests/common/bit_field.cpp
+++ b/src/tests/common/bit_field.cpp
@@ -68,7 +68,7 @@ TEST_CASE("BitField", "[common]") {
68 }}); 68 }});
69 69
70 // bit fields: 01101100111101'10101110'1011'101100 70 // bit fields: 01101100111101'10101110'1011'101100
71 REQUIRE(be_bitfield.raw == 0b01101100'11110110'10111010'11101100); 71 REQUIRE(be_bitfield.raw == 0b01101100'11110110'10111010'11101100U);
72 REQUIRE(be_bitfield.a == 0b101100); 72 REQUIRE(be_bitfield.a == 0b101100);
73 REQUIRE(be_bitfield.b == -5); // 1011 as two's complement 73 REQUIRE(be_bitfield.b == -5); // 1011 as two's complement
74 REQUIRE(be_bitfield.c == TestEnum::B); 74 REQUIRE(be_bitfield.c == TestEnum::B);
@@ -80,7 +80,7 @@ TEST_CASE("BitField", "[common]") {
80 be_bitfield.d.Assign(0b01010101010101); 80 be_bitfield.d.Assign(0b01010101010101);
81 std::memcpy(&raw, &be_bitfield, sizeof(raw)); 81 std::memcpy(&raw, &be_bitfield, sizeof(raw));
82 // bit fields: 01010101010101'00001111'1111'000111 82 // bit fields: 01010101010101'00001111'1111'000111
83 REQUIRE(be_bitfield.raw == 0b01010101'01010100'00111111'11000111); 83 REQUIRE(be_bitfield.raw == 0b01010101'01010100'00111111'11000111U);
84 REQUIRE(raw == std::array<u8, 4>{{ 84 REQUIRE(raw == std::array<u8, 4>{{
85 0b01010101, 85 0b01010101,
86 0b01010100, 86 0b01010100,
diff --git a/src/video_core/command_classes/codecs/codec.cpp b/src/video_core/command_classes/codecs/codec.cpp
index 1adf3cd13..9a88f64e4 100644
--- a/src/video_core/command_classes/codecs/codec.cpp
+++ b/src/video_core/command_classes/codecs/codec.cpp
@@ -18,6 +18,11 @@ extern "C" {
18 18
19namespace Tegra { 19namespace Tegra {
20 20
21void AVFrameDeleter(AVFrame* ptr) {
22 av_frame_unref(ptr);
23 av_free(ptr);
24}
25
21Codec::Codec(GPU& gpu_) 26Codec::Codec(GPU& gpu_)
22 : gpu(gpu_), h264_decoder(std::make_unique<Decoder::H264>(gpu)), 27 : gpu(gpu_), h264_decoder(std::make_unique<Decoder::H264>(gpu)),
23 vp9_decoder(std::make_unique<Decoder::VP9>(gpu)) {} 28 vp9_decoder(std::make_unique<Decoder::VP9>(gpu)) {}
@@ -27,7 +32,9 @@ Codec::~Codec() {
27 return; 32 return;
28 } 33 }
29 // Free libav memory 34 // Free libav memory
35 AVFrame* av_frame{nullptr};
30 avcodec_send_packet(av_codec_ctx, nullptr); 36 avcodec_send_packet(av_codec_ctx, nullptr);
37 av_frame = av_frame_alloc();
31 avcodec_receive_frame(av_codec_ctx, av_frame); 38 avcodec_receive_frame(av_codec_ctx, av_frame);
32 avcodec_flush_buffers(av_codec_ctx); 39 avcodec_flush_buffers(av_codec_ctx);
33 40
@@ -60,7 +67,7 @@ void Codec::Decode() {
60 } 67 }
61 68
62 av_codec_ctx = avcodec_alloc_context3(av_codec); 69 av_codec_ctx = avcodec_alloc_context3(av_codec);
63 av_frame = av_frame_alloc(); 70 av_codec_ctx->refcounted_frames = 1;
64 av_opt_set(av_codec_ctx->priv_data, "tune", "zerolatency", 0); 71 av_opt_set(av_codec_ctx->priv_data, "tune", "zerolatency", 0);
65 72
66 // TODO(ameerj): libavcodec gpu hw acceleration 73 // TODO(ameerj): libavcodec gpu hw acceleration
@@ -68,8 +75,6 @@ void Codec::Decode() {
68 const auto av_error = avcodec_open2(av_codec_ctx, av_codec, nullptr); 75 const auto av_error = avcodec_open2(av_codec_ctx, av_codec, nullptr);
69 if (av_error < 0) { 76 if (av_error < 0) {
70 LOG_ERROR(Service_NVDRV, "avcodec_open2() Failed."); 77 LOG_ERROR(Service_NVDRV, "avcodec_open2() Failed.");
71 av_frame_unref(av_frame);
72 av_free(av_frame);
73 avcodec_close(av_codec_ctx); 78 avcodec_close(av_codec_ctx);
74 return; 79 return;
75 } 80 }
@@ -96,16 +101,26 @@ void Codec::Decode() {
96 101
97 if (!vp9_hidden_frame) { 102 if (!vp9_hidden_frame) {
98 // Only receive/store visible frames 103 // Only receive/store visible frames
99 avcodec_receive_frame(av_codec_ctx, av_frame); 104 AVFramePtr frame = AVFramePtr{av_frame_alloc(), AVFrameDeleter};
105 avcodec_receive_frame(av_codec_ctx, frame.get());
106 av_frames.push(std::move(frame));
107 // Limit queue to 10 frames. Workaround for ZLA decode and queue spam
108 if (av_frames.size() > 10) {
109 av_frames.pop();
110 }
100 } 111 }
101} 112}
102 113
103AVFrame* Codec::GetCurrentFrame() { 114AVFramePtr Codec::GetCurrentFrame() {
104 return av_frame; 115 // Sometimes VIC will request more frames than have been decoded.
105} 116 // in this case, return a nullptr and don't overwrite previous frame data
117 if (av_frames.empty()) {
118 return AVFramePtr{nullptr, AVFrameDeleter};
119 }
106 120
107const AVFrame* Codec::GetCurrentFrame() const { 121 AVFramePtr frame = std::move(av_frames.front());
108 return av_frame; 122 av_frames.pop();
123 return frame;
109} 124}
110 125
111NvdecCommon::VideoCodec Codec::GetCurrentCodec() const { 126NvdecCommon::VideoCodec Codec::GetCurrentCodec() const {
diff --git a/src/video_core/command_classes/codecs/codec.h b/src/video_core/command_classes/codecs/codec.h
index 5bbe6a332..8a2a6c360 100644
--- a/src/video_core/command_classes/codecs/codec.h
+++ b/src/video_core/command_classes/codecs/codec.h
@@ -5,11 +5,13 @@
5#pragma once 5#pragma once
6 6
7#include <memory> 7#include <memory>
8#include <queue>
8#include "common/common_types.h" 9#include "common/common_types.h"
9#include "video_core/command_classes/nvdec_common.h" 10#include "video_core/command_classes/nvdec_common.h"
10 11
11extern "C" { 12extern "C" {
12#if defined(__GNUC__) || defined(__clang__) 13#if defined(__GNUC__) || defined(__clang__)
14#pragma GCC diagnostic push
13#pragma GCC diagnostic ignored "-Wconversion" 15#pragma GCC diagnostic ignored "-Wconversion"
14#endif 16#endif
15#include <libavcodec/avcodec.h> 17#include <libavcodec/avcodec.h>
@@ -22,6 +24,9 @@ namespace Tegra {
22class GPU; 24class GPU;
23struct VicRegisters; 25struct VicRegisters;
24 26
27void AVFrameDeleter(AVFrame* ptr);
28using AVFramePtr = std::unique_ptr<AVFrame, decltype(&AVFrameDeleter)>;
29
25namespace Decoder { 30namespace Decoder {
26class H264; 31class H264;
27class VP9; 32class VP9;
@@ -41,9 +46,8 @@ public:
41 /// Call decoders to construct headers, decode AVFrame with ffmpeg 46 /// Call decoders to construct headers, decode AVFrame with ffmpeg
42 void Decode(); 47 void Decode();
43 48
44 /// Returns most recently decoded frame 49 /// Returns next decoded frame
45 [[nodiscard]] AVFrame* GetCurrentFrame(); 50 [[nodiscard]] AVFramePtr GetCurrentFrame();
46 [[nodiscard]] const AVFrame* GetCurrentFrame() const;
47 51
48 /// Returns the value of current_codec 52 /// Returns the value of current_codec
49 [[nodiscard]] NvdecCommon::VideoCodec GetCurrentCodec() const; 53 [[nodiscard]] NvdecCommon::VideoCodec GetCurrentCodec() const;
@@ -54,13 +58,13 @@ private:
54 58
55 AVCodec* av_codec{nullptr}; 59 AVCodec* av_codec{nullptr};
56 AVCodecContext* av_codec_ctx{nullptr}; 60 AVCodecContext* av_codec_ctx{nullptr};
57 AVFrame* av_frame{nullptr};
58 61
59 GPU& gpu; 62 GPU& gpu;
60 std::unique_ptr<Decoder::H264> h264_decoder; 63 std::unique_ptr<Decoder::H264> h264_decoder;
61 std::unique_ptr<Decoder::VP9> vp9_decoder; 64 std::unique_ptr<Decoder::VP9> vp9_decoder;
62 65
63 NvdecCommon::NvdecRegisters state{}; 66 NvdecCommon::NvdecRegisters state{};
67 std::queue<AVFramePtr> av_frames{};
64}; 68};
65 69
66} // namespace Tegra 70} // namespace Tegra
diff --git a/src/video_core/command_classes/codecs/h264.cpp b/src/video_core/command_classes/codecs/h264.cpp
index 33e063e20..65bbeac78 100644
--- a/src/video_core/command_classes/codecs/h264.cpp
+++ b/src/video_core/command_classes/codecs/h264.cpp
@@ -43,7 +43,7 @@ H264::H264(GPU& gpu_) : gpu(gpu_) {}
43 43
44H264::~H264() = default; 44H264::~H264() = default;
45 45
46const std::vector<u8>& H264::ComposeFrameHeader(NvdecCommon::NvdecRegisters& state, 46const std::vector<u8>& H264::ComposeFrameHeader(const NvdecCommon::NvdecRegisters& state,
47 bool is_first_frame) { 47 bool is_first_frame) {
48 H264DecoderContext context{}; 48 H264DecoderContext context{};
49 gpu.MemoryManager().ReadBlock(state.picture_info_offset, &context, sizeof(H264DecoderContext)); 49 gpu.MemoryManager().ReadBlock(state.picture_info_offset, &context, sizeof(H264DecoderContext));
diff --git a/src/video_core/command_classes/codecs/h264.h b/src/video_core/command_classes/codecs/h264.h
index 273449495..0f3a1d9f3 100644
--- a/src/video_core/command_classes/codecs/h264.h
+++ b/src/video_core/command_classes/codecs/h264.h
@@ -74,8 +74,8 @@ public:
74 ~H264(); 74 ~H264();
75 75
76 /// Compose the H264 header of the frame for FFmpeg decoding 76 /// Compose the H264 header of the frame for FFmpeg decoding
77 [[nodiscard]] const std::vector<u8>& ComposeFrameHeader(NvdecCommon::NvdecRegisters& state, 77 [[nodiscard]] const std::vector<u8>& ComposeFrameHeader(
78 bool is_first_frame = false); 78 const NvdecCommon::NvdecRegisters& state, bool is_first_frame = false);
79 79
80private: 80private:
81 struct H264ParameterSet { 81 struct H264ParameterSet {
diff --git a/src/video_core/command_classes/codecs/vp9.cpp b/src/video_core/command_classes/codecs/vp9.cpp
index ab44fdc9e..b1d675cdb 100644
--- a/src/video_core/command_classes/codecs/vp9.cpp
+++ b/src/video_core/command_classes/codecs/vp9.cpp
@@ -23,122 +23,102 @@ constexpr Vp9EntropyProbs default_probs{
23 222, 34, 30, 0, 72, 16, 44, 0, 58, 32, 12, 0, 10, 7, 6, 0, 23 222, 34, 30, 0, 72, 16, 44, 0, 58, 32, 12, 0, 10, 7, 6, 0,
24 }, 24 },
25 .coef_probs{ 25 .coef_probs{
26 195, 29, 183, 0, 84, 49, 136, 0, 8, 42, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26 195, 29, 183, 84, 49, 136, 8, 42, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0,
27 0, 0, 0, 0, 31, 107, 169, 0, 35, 99, 159, 0, 17, 82, 140, 0, 8, 66, 114, 0, 27 31, 107, 169, 35, 99, 159, 17, 82, 140, 8, 66, 114, 2, 44, 76, 1, 19, 32,
28 2, 44, 76, 0, 1, 19, 32, 0, 40, 132, 201, 0, 29, 114, 187, 0, 13, 91, 157, 0, 28 40, 132, 201, 29, 114, 187, 13, 91, 157, 7, 75, 127, 3, 58, 95, 1, 28, 47,
29 7, 75, 127, 0, 3, 58, 95, 0, 1, 28, 47, 0, 69, 142, 221, 0, 42, 122, 201, 0, 29 69, 142, 221, 42, 122, 201, 15, 91, 159, 6, 67, 121, 1, 42, 77, 1, 17, 31,
30 15, 91, 159, 0, 6, 67, 121, 0, 1, 42, 77, 0, 1, 17, 31, 0, 102, 148, 228, 0, 30 102, 148, 228, 67, 117, 204, 17, 82, 154, 6, 59, 114, 2, 39, 75, 1, 15, 29,
31 67, 117, 204, 0, 17, 82, 154, 0, 6, 59, 114, 0, 2, 39, 75, 0, 1, 15, 29, 0, 31 156, 57, 233, 119, 57, 212, 58, 48, 163, 29, 40, 124, 12, 30, 81, 3, 12, 31,
32 156, 57, 233, 0, 119, 57, 212, 0, 58, 48, 163, 0, 29, 40, 124, 0, 12, 30, 81, 0, 32 191, 107, 226, 124, 117, 204, 25, 99, 155, 0, 0, 0, 0, 0, 0, 0, 0, 0,
33 3, 12, 31, 0, 191, 107, 226, 0, 124, 117, 204, 0, 25, 99, 155, 0, 0, 0, 0, 0, 33 29, 148, 210, 37, 126, 194, 8, 93, 157, 2, 68, 118, 1, 39, 69, 1, 17, 33,
34 0, 0, 0, 0, 0, 0, 0, 0, 29, 148, 210, 0, 37, 126, 194, 0, 8, 93, 157, 0, 34 41, 151, 213, 27, 123, 193, 3, 82, 144, 1, 58, 105, 1, 32, 60, 1, 13, 26,
35 2, 68, 118, 0, 1, 39, 69, 0, 1, 17, 33, 0, 41, 151, 213, 0, 27, 123, 193, 0, 35 59, 159, 220, 23, 126, 198, 4, 88, 151, 1, 66, 114, 1, 38, 71, 1, 18, 34,
36 3, 82, 144, 0, 1, 58, 105, 0, 1, 32, 60, 0, 1, 13, 26, 0, 59, 159, 220, 0, 36 114, 136, 232, 51, 114, 207, 11, 83, 155, 3, 56, 105, 1, 33, 65, 1, 17, 34,
37 23, 126, 198, 0, 4, 88, 151, 0, 1, 66, 114, 0, 1, 38, 71, 0, 1, 18, 34, 0, 37 149, 65, 234, 121, 57, 215, 61, 49, 166, 28, 36, 114, 12, 25, 76, 3, 16, 42,
38 114, 136, 232, 0, 51, 114, 207, 0, 11, 83, 155, 0, 3, 56, 105, 0, 1, 33, 65, 0, 38 214, 49, 220, 132, 63, 188, 42, 65, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0,
39 1, 17, 34, 0, 149, 65, 234, 0, 121, 57, 215, 0, 61, 49, 166, 0, 28, 36, 114, 0, 39 85, 137, 221, 104, 131, 216, 49, 111, 192, 21, 87, 155, 2, 49, 87, 1, 16, 28,
40 12, 25, 76, 0, 3, 16, 42, 0, 214, 49, 220, 0, 132, 63, 188, 0, 42, 65, 137, 0, 40 89, 163, 230, 90, 137, 220, 29, 100, 183, 10, 70, 135, 2, 42, 81, 1, 17, 33,
41 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 137, 221, 0, 104, 131, 216, 0, 41 108, 167, 237, 55, 133, 222, 15, 97, 179, 4, 72, 135, 1, 45, 85, 1, 19, 38,
42 49, 111, 192, 0, 21, 87, 155, 0, 2, 49, 87, 0, 1, 16, 28, 0, 89, 163, 230, 0, 42 124, 146, 240, 66, 124, 224, 17, 88, 175, 4, 58, 122, 1, 36, 75, 1, 18, 37,
43 90, 137, 220, 0, 29, 100, 183, 0, 10, 70, 135, 0, 2, 42, 81, 0, 1, 17, 33, 0, 43 141, 79, 241, 126, 70, 227, 66, 58, 182, 30, 44, 136, 12, 34, 96, 2, 20, 47,
44 108, 167, 237, 0, 55, 133, 222, 0, 15, 97, 179, 0, 4, 72, 135, 0, 1, 45, 85, 0, 44 229, 99, 249, 143, 111, 235, 46, 109, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0,
45 1, 19, 38, 0, 124, 146, 240, 0, 66, 124, 224, 0, 17, 88, 175, 0, 4, 58, 122, 0, 45 82, 158, 236, 94, 146, 224, 25, 117, 191, 9, 87, 149, 3, 56, 99, 1, 33, 57,
46 1, 36, 75, 0, 1, 18, 37, 0, 141, 79, 241, 0, 126, 70, 227, 0, 66, 58, 182, 0, 46 83, 167, 237, 68, 145, 222, 10, 103, 177, 2, 72, 131, 1, 41, 79, 1, 20, 39,
47 30, 44, 136, 0, 12, 34, 96, 0, 2, 20, 47, 0, 229, 99, 249, 0, 143, 111, 235, 0, 47 99, 167, 239, 47, 141, 224, 10, 104, 178, 2, 73, 133, 1, 44, 85, 1, 22, 47,
48 46, 109, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 158, 236, 0, 48 127, 145, 243, 71, 129, 228, 17, 93, 177, 3, 61, 124, 1, 41, 84, 1, 21, 52,
49 94, 146, 224, 0, 25, 117, 191, 0, 9, 87, 149, 0, 3, 56, 99, 0, 1, 33, 57, 0, 49 157, 78, 244, 140, 72, 231, 69, 58, 184, 31, 44, 137, 14, 38, 105, 8, 23, 61,
50 83, 167, 237, 0, 68, 145, 222, 0, 10, 103, 177, 0, 2, 72, 131, 0, 1, 41, 79, 0, 50 125, 34, 187, 52, 41, 133, 6, 31, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0,
51 1, 20, 39, 0, 99, 167, 239, 0, 47, 141, 224, 0, 10, 104, 178, 0, 2, 73, 133, 0, 51 37, 109, 153, 51, 102, 147, 23, 87, 128, 8, 67, 101, 1, 41, 63, 1, 19, 29,
52 1, 44, 85, 0, 1, 22, 47, 0, 127, 145, 243, 0, 71, 129, 228, 0, 17, 93, 177, 0, 52 31, 154, 185, 17, 127, 175, 6, 96, 145, 2, 73, 114, 1, 51, 82, 1, 28, 45,
53 3, 61, 124, 0, 1, 41, 84, 0, 1, 21, 52, 0, 157, 78, 244, 0, 140, 72, 231, 0, 53 23, 163, 200, 10, 131, 185, 2, 93, 148, 1, 67, 111, 1, 41, 69, 1, 14, 24,
54 69, 58, 184, 0, 31, 44, 137, 0, 14, 38, 105, 0, 8, 23, 61, 0, 125, 34, 187, 0, 54 29, 176, 217, 12, 145, 201, 3, 101, 156, 1, 69, 111, 1, 39, 63, 1, 14, 23,
55 52, 41, 133, 0, 6, 31, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55 57, 192, 233, 25, 154, 215, 6, 109, 167, 3, 78, 118, 1, 48, 69, 1, 21, 29,
56 37, 109, 153, 0, 51, 102, 147, 0, 23, 87, 128, 0, 8, 67, 101, 0, 1, 41, 63, 0, 56 202, 105, 245, 108, 106, 216, 18, 90, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0,
57 1, 19, 29, 0, 31, 154, 185, 0, 17, 127, 175, 0, 6, 96, 145, 0, 2, 73, 114, 0, 57 33, 172, 219, 64, 149, 206, 14, 117, 177, 5, 90, 141, 2, 61, 95, 1, 37, 57,
58 1, 51, 82, 0, 1, 28, 45, 0, 23, 163, 200, 0, 10, 131, 185, 0, 2, 93, 148, 0, 58 33, 179, 220, 11, 140, 198, 1, 89, 148, 1, 60, 104, 1, 33, 57, 1, 12, 21,
59 1, 67, 111, 0, 1, 41, 69, 0, 1, 14, 24, 0, 29, 176, 217, 0, 12, 145, 201, 0, 59 30, 181, 221, 8, 141, 198, 1, 87, 145, 1, 58, 100, 1, 31, 55, 1, 12, 20,
60 3, 101, 156, 0, 1, 69, 111, 0, 1, 39, 63, 0, 1, 14, 23, 0, 57, 192, 233, 0, 60 32, 186, 224, 7, 142, 198, 1, 86, 143, 1, 58, 100, 1, 31, 55, 1, 12, 22,
61 25, 154, 215, 0, 6, 109, 167, 0, 3, 78, 118, 0, 1, 48, 69, 0, 1, 21, 29, 0, 61 57, 192, 227, 20, 143, 204, 3, 96, 154, 1, 68, 112, 1, 42, 69, 1, 19, 32,
62 202, 105, 245, 0, 108, 106, 216, 0, 18, 90, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62 212, 35, 215, 113, 47, 169, 29, 48, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0,
63 0, 0, 0, 0, 33, 172, 219, 0, 64, 149, 206, 0, 14, 117, 177, 0, 5, 90, 141, 0, 63 74, 129, 203, 106, 120, 203, 49, 107, 178, 19, 84, 144, 4, 50, 84, 1, 15, 25,
64 2, 61, 95, 0, 1, 37, 57, 0, 33, 179, 220, 0, 11, 140, 198, 0, 1, 89, 148, 0, 64 71, 172, 217, 44, 141, 209, 15, 102, 173, 6, 76, 133, 2, 51, 89, 1, 24, 42,
65 1, 60, 104, 0, 1, 33, 57, 0, 1, 12, 21, 0, 30, 181, 221, 0, 8, 141, 198, 0, 65 64, 185, 231, 31, 148, 216, 8, 103, 175, 3, 74, 131, 1, 46, 81, 1, 18, 30,
66 1, 87, 145, 0, 1, 58, 100, 0, 1, 31, 55, 0, 1, 12, 20, 0, 32, 186, 224, 0, 66 65, 196, 235, 25, 157, 221, 5, 105, 174, 1, 67, 120, 1, 38, 69, 1, 15, 30,
67 7, 142, 198, 0, 1, 86, 143, 0, 1, 58, 100, 0, 1, 31, 55, 0, 1, 12, 22, 0, 67 65, 204, 238, 30, 156, 224, 7, 107, 177, 2, 70, 124, 1, 42, 73, 1, 18, 34,
68 57, 192, 227, 0, 20, 143, 204, 0, 3, 96, 154, 0, 1, 68, 112, 0, 1, 42, 69, 0, 68 225, 86, 251, 144, 104, 235, 42, 99, 181, 0, 0, 0, 0, 0, 0, 0, 0, 0,
69 1, 19, 32, 0, 212, 35, 215, 0, 113, 47, 169, 0, 29, 48, 105, 0, 0, 0, 0, 0, 69 85, 175, 239, 112, 165, 229, 29, 136, 200, 12, 103, 162, 6, 77, 123, 2, 53, 84,
70 0, 0, 0, 0, 0, 0, 0, 0, 74, 129, 203, 0, 106, 120, 203, 0, 49, 107, 178, 0, 70 75, 183, 239, 30, 155, 221, 3, 106, 171, 1, 74, 128, 1, 44, 76, 1, 17, 28,
71 19, 84, 144, 0, 4, 50, 84, 0, 1, 15, 25, 0, 71, 172, 217, 0, 44, 141, 209, 0, 71 73, 185, 240, 27, 159, 222, 2, 107, 172, 1, 75, 127, 1, 42, 73, 1, 17, 29,
72 15, 102, 173, 0, 6, 76, 133, 0, 2, 51, 89, 0, 1, 24, 42, 0, 64, 185, 231, 0, 72 62, 190, 238, 21, 159, 222, 2, 107, 172, 1, 72, 122, 1, 40, 71, 1, 18, 32,
73 31, 148, 216, 0, 8, 103, 175, 0, 3, 74, 131, 0, 1, 46, 81, 0, 1, 18, 30, 0, 73 61, 199, 240, 27, 161, 226, 4, 113, 180, 1, 76, 129, 1, 46, 80, 1, 23, 41,
74 65, 196, 235, 0, 25, 157, 221, 0, 5, 105, 174, 0, 1, 67, 120, 0, 1, 38, 69, 0, 74 7, 27, 153, 5, 30, 95, 1, 16, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0,
75 1, 15, 30, 0, 65, 204, 238, 0, 30, 156, 224, 0, 7, 107, 177, 0, 2, 70, 124, 0, 75 50, 75, 127, 57, 75, 124, 27, 67, 108, 10, 54, 86, 1, 33, 52, 1, 12, 18,
76 1, 42, 73, 0, 1, 18, 34, 0, 225, 86, 251, 0, 144, 104, 235, 0, 42, 99, 181, 0, 76 43, 125, 151, 26, 108, 148, 7, 83, 122, 2, 59, 89, 1, 38, 60, 1, 17, 27,
77 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 175, 239, 0, 112, 165, 229, 0, 77 23, 144, 163, 13, 112, 154, 2, 75, 117, 1, 50, 81, 1, 31, 51, 1, 14, 23,
78 29, 136, 200, 0, 12, 103, 162, 0, 6, 77, 123, 0, 2, 53, 84, 0, 75, 183, 239, 0, 78 18, 162, 185, 6, 123, 171, 1, 78, 125, 1, 51, 86, 1, 31, 54, 1, 14, 23,
79 30, 155, 221, 0, 3, 106, 171, 0, 1, 74, 128, 0, 1, 44, 76, 0, 1, 17, 28, 0, 79 15, 199, 227, 3, 150, 204, 1, 91, 146, 1, 55, 95, 1, 30, 53, 1, 11, 20,
80 73, 185, 240, 0, 27, 159, 222, 0, 2, 107, 172, 0, 1, 75, 127, 0, 1, 42, 73, 0, 80 19, 55, 240, 19, 59, 196, 3, 52, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0,
81 1, 17, 29, 0, 62, 190, 238, 0, 21, 159, 222, 0, 2, 107, 172, 0, 1, 72, 122, 0, 81 41, 166, 207, 104, 153, 199, 31, 123, 181, 14, 101, 152, 5, 72, 106, 1, 36, 52,
82 1, 40, 71, 0, 1, 18, 32, 0, 61, 199, 240, 0, 27, 161, 226, 0, 4, 113, 180, 0, 82 35, 176, 211, 12, 131, 190, 2, 88, 144, 1, 60, 101, 1, 36, 60, 1, 16, 28,
83 1, 76, 129, 0, 1, 46, 80, 0, 1, 23, 41, 0, 7, 27, 153, 0, 5, 30, 95, 0, 83 28, 183, 213, 8, 134, 191, 1, 86, 142, 1, 56, 96, 1, 30, 53, 1, 12, 20,
84 1, 16, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 75, 127, 0, 84 20, 190, 215, 4, 135, 192, 1, 84, 139, 1, 53, 91, 1, 28, 49, 1, 11, 20,
85 57, 75, 124, 0, 27, 67, 108, 0, 10, 54, 86, 0, 1, 33, 52, 0, 1, 12, 18, 0, 85 13, 196, 216, 2, 137, 192, 1, 86, 143, 1, 57, 99, 1, 32, 56, 1, 13, 24,
86 43, 125, 151, 0, 26, 108, 148, 0, 7, 83, 122, 0, 2, 59, 89, 0, 1, 38, 60, 0, 86 211, 29, 217, 96, 47, 156, 22, 43, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0,
87 1, 17, 27, 0, 23, 144, 163, 0, 13, 112, 154, 0, 2, 75, 117, 0, 1, 50, 81, 0, 87 78, 120, 193, 111, 116, 186, 46, 102, 164, 15, 80, 128, 2, 49, 76, 1, 18, 28,
88 1, 31, 51, 0, 1, 14, 23, 0, 18, 162, 185, 0, 6, 123, 171, 0, 1, 78, 125, 0, 88 71, 161, 203, 42, 132, 192, 10, 98, 150, 3, 69, 109, 1, 44, 70, 1, 18, 29,
89 1, 51, 86, 0, 1, 31, 54, 0, 1, 14, 23, 0, 15, 199, 227, 0, 3, 150, 204, 0, 89 57, 186, 211, 30, 140, 196, 4, 93, 146, 1, 62, 102, 1, 38, 65, 1, 16, 27,
90 1, 91, 146, 0, 1, 55, 95, 0, 1, 30, 53, 0, 1, 11, 20, 0, 19, 55, 240, 0, 90 47, 199, 217, 14, 145, 196, 1, 88, 142, 1, 57, 98, 1, 36, 62, 1, 15, 26,
91 19, 59, 196, 0, 3, 52, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91 26, 219, 229, 5, 155, 207, 1, 94, 151, 1, 60, 104, 1, 36, 62, 1, 16, 28,
92 41, 166, 207, 0, 104, 153, 199, 0, 31, 123, 181, 0, 14, 101, 152, 0, 5, 72, 106, 0, 92 233, 29, 248, 146, 47, 220, 43, 52, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0,
93 1, 36, 52, 0, 35, 176, 211, 0, 12, 131, 190, 0, 2, 88, 144, 0, 1, 60, 101, 0, 93 100, 163, 232, 179, 161, 222, 63, 142, 204, 37, 113, 174, 26, 89, 137, 18, 68, 97,
94 1, 36, 60, 0, 1, 16, 28, 0, 28, 183, 213, 0, 8, 134, 191, 0, 1, 86, 142, 0, 94 85, 181, 230, 32, 146, 209, 7, 100, 164, 3, 71, 121, 1, 45, 77, 1, 18, 30,
95 1, 56, 96, 0, 1, 30, 53, 0, 1, 12, 20, 0, 20, 190, 215, 0, 4, 135, 192, 0, 95 65, 187, 230, 20, 148, 207, 2, 97, 159, 1, 68, 116, 1, 40, 70, 1, 14, 29,
96 1, 84, 139, 0, 1, 53, 91, 0, 1, 28, 49, 0, 1, 11, 20, 0, 13, 196, 216, 0, 96 40, 194, 227, 8, 147, 204, 1, 94, 155, 1, 65, 112, 1, 39, 66, 1, 14, 26,
97 2, 137, 192, 0, 1, 86, 143, 0, 1, 57, 99, 0, 1, 32, 56, 0, 1, 13, 24, 0, 97 16, 208, 228, 3, 151, 207, 1, 98, 160, 1, 67, 117, 1, 41, 74, 1, 17, 31,
98 211, 29, 217, 0, 96, 47, 156, 0, 22, 43, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98 17, 38, 140, 7, 34, 80, 1, 17, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0,
99 0, 0, 0, 0, 78, 120, 193, 0, 111, 116, 186, 0, 46, 102, 164, 0, 15, 80, 128, 0, 99 37, 75, 128, 41, 76, 128, 26, 66, 116, 12, 52, 94, 2, 32, 55, 1, 10, 16,
100 2, 49, 76, 0, 1, 18, 28, 0, 71, 161, 203, 0, 42, 132, 192, 0, 10, 98, 150, 0, 100 50, 127, 154, 37, 109, 152, 16, 82, 121, 5, 59, 85, 1, 35, 54, 1, 13, 20,
101 3, 69, 109, 0, 1, 44, 70, 0, 1, 18, 29, 0, 57, 186, 211, 0, 30, 140, 196, 0, 101 40, 142, 167, 17, 110, 157, 2, 71, 112, 1, 44, 72, 1, 27, 45, 1, 11, 17,
102 4, 93, 146, 0, 1, 62, 102, 0, 1, 38, 65, 0, 1, 16, 27, 0, 47, 199, 217, 0, 102 30, 175, 188, 9, 124, 169, 1, 74, 116, 1, 48, 78, 1, 30, 49, 1, 11, 18,
103 14, 145, 196, 0, 1, 88, 142, 0, 1, 57, 98, 0, 1, 36, 62, 0, 1, 15, 26, 0, 103 10, 222, 223, 2, 150, 194, 1, 83, 128, 1, 48, 79, 1, 27, 45, 1, 11, 17,
104 26, 219, 229, 0, 5, 155, 207, 0, 1, 94, 151, 0, 1, 60, 104, 0, 1, 36, 62, 0, 104 36, 41, 235, 29, 36, 193, 10, 27, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0,
105 1, 16, 28, 0, 233, 29, 248, 0, 146, 47, 220, 0, 43, 52, 140, 0, 0, 0, 0, 0, 105 85, 165, 222, 177, 162, 215, 110, 135, 195, 57, 113, 168, 23, 83, 120, 10, 49, 61,
106 0, 0, 0, 0, 0, 0, 0, 0, 100, 163, 232, 0, 179, 161, 222, 0, 63, 142, 204, 0, 106 85, 190, 223, 36, 139, 200, 5, 90, 146, 1, 60, 103, 1, 38, 65, 1, 18, 30,
107 37, 113, 174, 0, 26, 89, 137, 0, 18, 68, 97, 0, 85, 181, 230, 0, 32, 146, 209, 0, 107 72, 202, 223, 23, 141, 199, 2, 86, 140, 1, 56, 97, 1, 36, 61, 1, 16, 27,
108 7, 100, 164, 0, 3, 71, 121, 0, 1, 45, 77, 0, 1, 18, 30, 0, 65, 187, 230, 0, 108 55, 218, 225, 13, 145, 200, 1, 86, 141, 1, 57, 99, 1, 35, 61, 1, 13, 22,
109 20, 148, 207, 0, 2, 97, 159, 0, 1, 68, 116, 0, 1, 40, 70, 0, 1, 14, 29, 0, 109 15, 235, 212, 1, 132, 184, 1, 84, 139, 1, 57, 97, 1, 34, 56, 1, 14, 23,
110 40, 194, 227, 0, 8, 147, 204, 0, 1, 94, 155, 0, 1, 65, 112, 0, 1, 39, 66, 0, 110 181, 21, 201, 61, 37, 123, 10, 38, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0,
111 1, 14, 26, 0, 16, 208, 228, 0, 3, 151, 207, 0, 1, 98, 160, 0, 1, 67, 117, 0, 111 47, 106, 172, 95, 104, 173, 42, 93, 159, 18, 77, 131, 4, 50, 81, 1, 17, 23,
112 1, 41, 74, 0, 1, 17, 31, 0, 17, 38, 140, 0, 7, 34, 80, 0, 1, 17, 29, 0, 112 62, 147, 199, 44, 130, 189, 28, 102, 154, 18, 75, 115, 2, 44, 65, 1, 12, 19,
113 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 75, 128, 0, 41, 76, 128, 0, 113 55, 153, 210, 24, 130, 194, 3, 93, 146, 1, 61, 97, 1, 31, 50, 1, 10, 16,
114 26, 66, 116, 0, 12, 52, 94, 0, 2, 32, 55, 0, 1, 10, 16, 0, 50, 127, 154, 0, 114 49, 186, 223, 17, 148, 204, 1, 96, 142, 1, 53, 83, 1, 26, 44, 1, 11, 17,
115 37, 109, 152, 0, 16, 82, 121, 0, 5, 59, 85, 0, 1, 35, 54, 0, 1, 13, 20, 0, 115 13, 217, 212, 2, 136, 180, 1, 78, 124, 1, 50, 83, 1, 29, 49, 1, 14, 23,
116 40, 142, 167, 0, 17, 110, 157, 0, 2, 71, 112, 0, 1, 44, 72, 0, 1, 27, 45, 0, 116 197, 13, 247, 82, 17, 222, 25, 17, 162, 0, 0, 0, 0, 0, 0, 0, 0, 0,
117 1, 11, 17, 0, 30, 175, 188, 0, 9, 124, 169, 0, 1, 74, 116, 0, 1, 48, 78, 0, 117 126, 186, 247, 234, 191, 243, 176, 177, 234, 104, 158, 220, 66, 128, 186, 55, 90, 137,
118 1, 30, 49, 0, 1, 11, 18, 0, 10, 222, 223, 0, 2, 150, 194, 0, 1, 83, 128, 0, 118 111, 197, 242, 46, 158, 219, 9, 104, 171, 2, 65, 125, 1, 44, 80, 1, 17, 91,
119 1, 48, 79, 0, 1, 27, 45, 0, 1, 11, 17, 0, 36, 41, 235, 0, 29, 36, 193, 0, 119 104, 208, 245, 39, 168, 224, 3, 109, 162, 1, 79, 124, 1, 50, 102, 1, 43, 102,
120 10, 27, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 165, 222, 0, 120 84, 220, 246, 31, 177, 231, 2, 115, 180, 1, 79, 134, 1, 55, 77, 1, 60, 79,
121 177, 162, 215, 0, 110, 135, 195, 0, 57, 113, 168, 0, 23, 83, 120, 0, 10, 49, 61, 0, 121 43, 243, 240, 8, 180, 217, 1, 115, 166, 1, 84, 121, 1, 51, 67, 1, 16, 6,
122 85, 190, 223, 0, 36, 139, 200, 0, 5, 90, 146, 0, 1, 60, 103, 0, 1, 38, 65, 0,
123 1, 18, 30, 0, 72, 202, 223, 0, 23, 141, 199, 0, 2, 86, 140, 0, 1, 56, 97, 0,
124 1, 36, 61, 0, 1, 16, 27, 0, 55, 218, 225, 0, 13, 145, 200, 0, 1, 86, 141, 0,
125 1, 57, 99, 0, 1, 35, 61, 0, 1, 13, 22, 0, 15, 235, 212, 0, 1, 132, 184, 0,
126 1, 84, 139, 0, 1, 57, 97, 0, 1, 34, 56, 0, 1, 14, 23, 0, 181, 21, 201, 0,
127 61, 37, 123, 0, 10, 38, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
128 47, 106, 172, 0, 95, 104, 173, 0, 42, 93, 159, 0, 18, 77, 131, 0, 4, 50, 81, 0,
129 1, 17, 23, 0, 62, 147, 199, 0, 44, 130, 189, 0, 28, 102, 154, 0, 18, 75, 115, 0,
130 2, 44, 65, 0, 1, 12, 19, 0, 55, 153, 210, 0, 24, 130, 194, 0, 3, 93, 146, 0,
131 1, 61, 97, 0, 1, 31, 50, 0, 1, 10, 16, 0, 49, 186, 223, 0, 17, 148, 204, 0,
132 1, 96, 142, 0, 1, 53, 83, 0, 1, 26, 44, 0, 1, 11, 17, 0, 13, 217, 212, 0,
133 2, 136, 180, 0, 1, 78, 124, 0, 1, 50, 83, 0, 1, 29, 49, 0, 1, 14, 23, 0,
134 197, 13, 247, 0, 82, 17, 222, 0, 25, 17, 162, 0, 0, 0, 0, 0, 0, 0, 0, 0,
135 0, 0, 0, 0, 126, 186, 247, 0, 234, 191, 243, 0, 176, 177, 234, 0, 104, 158, 220, 0,
136 66, 128, 186, 0, 55, 90, 137, 0, 111, 197, 242, 0, 46, 158, 219, 0, 9, 104, 171, 0,
137 2, 65, 125, 0, 1, 44, 80, 0, 1, 17, 91, 0, 104, 208, 245, 0, 39, 168, 224, 0,
138 3, 109, 162, 0, 1, 79, 124, 0, 1, 50, 102, 0, 1, 43, 102, 0, 84, 220, 246, 0,
139 31, 177, 231, 0, 2, 115, 180, 0, 1, 79, 134, 0, 1, 55, 77, 0, 1, 60, 79, 0,
140 43, 243, 240, 0, 8, 180, 217, 0, 1, 115, 166, 0, 1, 84, 121, 0, 1, 51, 67, 0,
141 1, 16, 6, 0,
142 }, 122 },
143 .switchable_interp_prob{235, 162, 36, 255, 34, 3, 149, 144}, 123 .switchable_interp_prob{235, 162, 36, 255, 34, 3, 149, 144},
144 .inter_mode_prob{ 124 .inter_mode_prob{
@@ -322,39 +302,23 @@ bool VP9::WriteLessThan(VpxRangeEncoder& writer, s32 value, s32 test) {
322} 302}
323 303
324void VP9::WriteCoefProbabilityUpdate(VpxRangeEncoder& writer, s32 tx_mode, 304void VP9::WriteCoefProbabilityUpdate(VpxRangeEncoder& writer, s32 tx_mode,
325 const std::array<u8, 2304>& new_prob, 305 const std::array<u8, 1728>& new_prob,
326 const std::array<u8, 2304>& old_prob) { 306 const std::array<u8, 1728>& old_prob) {
327 // Note: There's 1 byte added on each packet for alignment, 307 constexpr u32 block_bytes = 2 * 2 * 6 * 6 * 3;
328 // this byte is ignored when doing updates. 308
329 constexpr s32 block_bytes = 2 * 2 * 6 * 6 * 4; 309 const auto needs_update = [&](u32 base_index) {
330 310 return !std::equal(new_prob.begin() + base_index,
331 const auto needs_update = [&](s32 base_index) -> bool { 311 new_prob.begin() + base_index + block_bytes,
332 s32 index = base_index; 312 old_prob.begin() + base_index);
333 for (s32 i = 0; i < 2; i++) {
334 for (s32 j = 0; j < 2; j++) {
335 for (s32 k = 0; k < 6; k++) {
336 for (s32 l = 0; l < 6; l++) {
337 if (new_prob[index + 0] != old_prob[index + 0] ||
338 new_prob[index + 1] != old_prob[index + 1] ||
339 new_prob[index + 2] != old_prob[index + 2]) {
340 return true;
341 }
342
343 index += 4;
344 }
345 }
346 }
347 }
348 return false;
349 }; 313 };
350 314
351 for (s32 block_index = 0; block_index < 4; block_index++) { 315 for (u32 block_index = 0; block_index < 4; block_index++) {
352 const s32 base_index = block_index * block_bytes; 316 const u32 base_index = block_index * block_bytes;
353 const bool update = needs_update(base_index); 317 const bool update = needs_update(base_index);
354 writer.Write(update); 318 writer.Write(update);
355 319
356 if (update) { 320 if (update) {
357 s32 index = base_index; 321 u32 index = base_index;
358 for (s32 i = 0; i < 2; i++) { 322 for (s32 i = 0; i < 2; i++) {
359 for (s32 j = 0; j < 2; j++) { 323 for (s32 j = 0; j < 2; j++) {
360 for (s32 k = 0; k < 6; k++) { 324 for (s32 k = 0; k < 6; k++) {
@@ -367,14 +331,13 @@ void VP9::WriteCoefProbabilityUpdate(VpxRangeEncoder& writer, s32 tx_mode,
367 WriteProbabilityUpdate(writer, new_prob[index + 2], 331 WriteProbabilityUpdate(writer, new_prob[index + 2],
368 old_prob[index + 2]); 332 old_prob[index + 2]);
369 } 333 }
370 index += 4; 334 index += 3;
371 } 335 }
372 } 336 }
373 } 337 }
374 } 338 }
375 } 339 }
376 340 if (block_index == static_cast<u32>(tx_mode)) {
377 if (block_index == tx_mode) {
378 break; 341 break;
379 } 342 }
380 } 343 }
@@ -392,7 +355,7 @@ void VP9::WriteMvProbabilityUpdate(VpxRangeEncoder& writer, u8 new_prob, u8 old_
392Vp9PictureInfo VP9::GetVp9PictureInfo(const NvdecCommon::NvdecRegisters& state) { 355Vp9PictureInfo VP9::GetVp9PictureInfo(const NvdecCommon::NvdecRegisters& state) {
393 PictureInfo picture_info{}; 356 PictureInfo picture_info{};
394 gpu.MemoryManager().ReadBlock(state.picture_info_offset, &picture_info, sizeof(PictureInfo)); 357 gpu.MemoryManager().ReadBlock(state.picture_info_offset, &picture_info, sizeof(PictureInfo));
395 Vp9PictureInfo vp9_info = picture_info.Convert(); 358 Vp9PictureInfo vp9_info = std::move(picture_info.Convert());
396 359
397 InsertEntropy(state.vp9_entropy_probs_offset, vp9_info.entropy); 360 InsertEntropy(state.vp9_entropy_probs_offset, vp9_info.entropy);
398 361
@@ -414,8 +377,7 @@ Vp9FrameContainer VP9::GetCurrentFrame(const NvdecCommon::NvdecRegisters& state)
414 Vp9FrameContainer frame{}; 377 Vp9FrameContainer frame{};
415 { 378 {
416 gpu.SyncGuestHost(); 379 gpu.SyncGuestHost();
417 frame.info = GetVp9PictureInfo(state); 380 frame.info = std::move(GetVp9PictureInfo(state));
418
419 frame.bit_stream.resize(frame.info.bitstream_size); 381 frame.bit_stream.resize(frame.info.bitstream_size);
420 gpu.MemoryManager().ReadBlock(state.frame_bitstream_offset, frame.bit_stream.data(), 382 gpu.MemoryManager().ReadBlock(state.frame_bitstream_offset, frame.bit_stream.data(),
421 frame.info.bitstream_size); 383 frame.info.bitstream_size);
@@ -423,37 +385,37 @@ Vp9FrameContainer VP9::GetCurrentFrame(const NvdecCommon::NvdecRegisters& state)
423 // Buffer two frames, saving the last show frame info 385 // Buffer two frames, saving the last show frame info
424 if (!next_next_frame.bit_stream.empty()) { 386 if (!next_next_frame.bit_stream.empty()) {
425 Vp9FrameContainer temp{ 387 Vp9FrameContainer temp{
426 .info = frame.info, 388 .info = std::move(frame.info),
427 .bit_stream = frame.bit_stream, 389 .bit_stream = std::move(frame.bit_stream),
428 }; 390 };
429 next_next_frame.info.show_frame = frame.info.last_frame_shown; 391 next_next_frame.info.show_frame = frame.info.last_frame_shown;
430 frame.info = next_next_frame.info; 392 frame.info = std::move(next_next_frame.info);
431 frame.bit_stream = next_next_frame.bit_stream; 393 frame.bit_stream = std::move(next_next_frame.bit_stream);
432 next_next_frame = std::move(temp); 394 next_next_frame = std::move(temp);
433 395
434 if (!next_frame.bit_stream.empty()) { 396 if (!next_frame.bit_stream.empty()) {
435 Vp9FrameContainer temp2{ 397 Vp9FrameContainer temp2{
436 .info = frame.info, 398 .info = std::move(frame.info),
437 .bit_stream = frame.bit_stream, 399 .bit_stream = std::move(frame.bit_stream),
438 }; 400 };
439 next_frame.info.show_frame = frame.info.last_frame_shown; 401 next_frame.info.show_frame = frame.info.last_frame_shown;
440 frame.info = next_frame.info; 402 frame.info = std::move(next_frame.info);
441 frame.bit_stream = next_frame.bit_stream; 403 frame.bit_stream = std::move(next_frame.bit_stream);
442 next_frame = std::move(temp2); 404 next_frame = std::move(temp2);
443 } else { 405 } else {
444 next_frame.info = frame.info; 406 next_frame.info = std::move(frame.info);
445 next_frame.bit_stream = frame.bit_stream; 407 next_frame.bit_stream = std::move(frame.bit_stream);
446 } 408 }
447 } else { 409 } else {
448 next_next_frame.info = frame.info; 410 next_next_frame.info = std::move(frame.info);
449 next_next_frame.bit_stream = frame.bit_stream; 411 next_next_frame.bit_stream = std::move(frame.bit_stream);
450 } 412 }
451 return frame; 413 return frame;
452} 414}
453 415
454std::vector<u8> VP9::ComposeCompressedHeader() { 416std::vector<u8> VP9::ComposeCompressedHeader() {
455 VpxRangeEncoder writer{}; 417 VpxRangeEncoder writer{};
456 418 const bool update_probs = current_frame_info.show_frame && !current_frame_info.is_key_frame;
457 if (!current_frame_info.lossless) { 419 if (!current_frame_info.lossless) {
458 if (static_cast<u32>(current_frame_info.transform_mode) >= 3) { 420 if (static_cast<u32>(current_frame_info.transform_mode) >= 3) {
459 writer.Write(3, 2); 421 writer.Write(3, 2);
@@ -471,7 +433,7 @@ std::vector<u8> VP9::ComposeCompressedHeader() {
471 prev_frame_probs.tx_16x16_prob); 433 prev_frame_probs.tx_16x16_prob);
472 WriteProbabilityUpdate(writer, current_frame_info.entropy.tx_32x32_prob, 434 WriteProbabilityUpdate(writer, current_frame_info.entropy.tx_32x32_prob,
473 prev_frame_probs.tx_32x32_prob); 435 prev_frame_probs.tx_32x32_prob);
474 if (current_frame_info.show_frame && !current_frame_info.is_key_frame) { 436 if (update_probs) {
475 prev_frame_probs.tx_8x8_prob = current_frame_info.entropy.tx_8x8_prob; 437 prev_frame_probs.tx_8x8_prob = current_frame_info.entropy.tx_8x8_prob;
476 prev_frame_probs.tx_16x16_prob = current_frame_info.entropy.tx_16x16_prob; 438 prev_frame_probs.tx_16x16_prob = current_frame_info.entropy.tx_16x16_prob;
477 prev_frame_probs.tx_32x32_prob = current_frame_info.entropy.tx_32x32_prob; 439 prev_frame_probs.tx_32x32_prob = current_frame_info.entropy.tx_32x32_prob;
@@ -484,7 +446,7 @@ std::vector<u8> VP9::ComposeCompressedHeader() {
484 WriteProbabilityUpdate(writer, current_frame_info.entropy.skip_probs, 446 WriteProbabilityUpdate(writer, current_frame_info.entropy.skip_probs,
485 prev_frame_probs.skip_probs); 447 prev_frame_probs.skip_probs);
486 448
487 if (current_frame_info.show_frame && !current_frame_info.is_key_frame) { 449 if (update_probs) {
488 prev_frame_probs.coef_probs = current_frame_info.entropy.coef_probs; 450 prev_frame_probs.coef_probs = current_frame_info.entropy.coef_probs;
489 prev_frame_probs.skip_probs = current_frame_info.entropy.skip_probs; 451 prev_frame_probs.skip_probs = current_frame_info.entropy.skip_probs;
490 } 452 }
@@ -493,15 +455,12 @@ std::vector<u8> VP9::ComposeCompressedHeader() {
493 // read_inter_probs() in the spec 455 // read_inter_probs() in the spec
494 WriteProbabilityUpdateAligned4(writer, current_frame_info.entropy.inter_mode_prob, 456 WriteProbabilityUpdateAligned4(writer, current_frame_info.entropy.inter_mode_prob,
495 prev_frame_probs.inter_mode_prob); 457 prev_frame_probs.inter_mode_prob);
496 if (current_frame_info.show_frame && !current_frame_info.is_key_frame) {
497 prev_frame_probs.inter_mode_prob = current_frame_info.entropy.inter_mode_prob;
498 }
499 458
500 if (current_frame_info.interp_filter == 4) { 459 if (current_frame_info.interp_filter == 4) {
501 // read_interp_filter_probs() in the spec 460 // read_interp_filter_probs() in the spec
502 WriteProbabilityUpdate(writer, current_frame_info.entropy.switchable_interp_prob, 461 WriteProbabilityUpdate(writer, current_frame_info.entropy.switchable_interp_prob,
503 prev_frame_probs.switchable_interp_prob); 462 prev_frame_probs.switchable_interp_prob);
504 if (current_frame_info.show_frame && !current_frame_info.is_key_frame) { 463 if (update_probs) {
505 prev_frame_probs.switchable_interp_prob = 464 prev_frame_probs.switchable_interp_prob =
506 current_frame_info.entropy.switchable_interp_prob; 465 current_frame_info.entropy.switchable_interp_prob;
507 } 466 }
@@ -510,9 +469,7 @@ std::vector<u8> VP9::ComposeCompressedHeader() {
510 // read_is_inter_probs() in the spec 469 // read_is_inter_probs() in the spec
511 WriteProbabilityUpdate(writer, current_frame_info.entropy.intra_inter_prob, 470 WriteProbabilityUpdate(writer, current_frame_info.entropy.intra_inter_prob,
512 prev_frame_probs.intra_inter_prob); 471 prev_frame_probs.intra_inter_prob);
513 if (current_frame_info.show_frame && !current_frame_info.is_key_frame) { 472
514 prev_frame_probs.intra_inter_prob = current_frame_info.entropy.intra_inter_prob;
515 }
516 // frame_reference_mode() in the spec 473 // frame_reference_mode() in the spec
517 if ((current_frame_info.ref_frame_sign_bias[1] & 1) != 474 if ((current_frame_info.ref_frame_sign_bias[1] & 1) !=
518 (current_frame_info.ref_frame_sign_bias[2] & 1) || 475 (current_frame_info.ref_frame_sign_bias[2] & 1) ||
@@ -530,7 +487,7 @@ std::vector<u8> VP9::ComposeCompressedHeader() {
530 if (current_frame_info.reference_mode == 2) { 487 if (current_frame_info.reference_mode == 2) {
531 WriteProbabilityUpdate(writer, current_frame_info.entropy.comp_inter_prob, 488 WriteProbabilityUpdate(writer, current_frame_info.entropy.comp_inter_prob,
532 prev_frame_probs.comp_inter_prob); 489 prev_frame_probs.comp_inter_prob);
533 if (current_frame_info.show_frame && !current_frame_info.is_key_frame) { 490 if (update_probs) {
534 prev_frame_probs.comp_inter_prob = current_frame_info.entropy.comp_inter_prob; 491 prev_frame_probs.comp_inter_prob = current_frame_info.entropy.comp_inter_prob;
535 } 492 }
536 } 493 }
@@ -538,7 +495,7 @@ std::vector<u8> VP9::ComposeCompressedHeader() {
538 if (current_frame_info.reference_mode != 1) { 495 if (current_frame_info.reference_mode != 1) {
539 WriteProbabilityUpdate(writer, current_frame_info.entropy.single_ref_prob, 496 WriteProbabilityUpdate(writer, current_frame_info.entropy.single_ref_prob,
540 prev_frame_probs.single_ref_prob); 497 prev_frame_probs.single_ref_prob);
541 if (current_frame_info.show_frame && !current_frame_info.is_key_frame) { 498 if (update_probs) {
542 prev_frame_probs.single_ref_prob = current_frame_info.entropy.single_ref_prob; 499 prev_frame_probs.single_ref_prob = current_frame_info.entropy.single_ref_prob;
543 } 500 }
544 } 501 }
@@ -546,7 +503,7 @@ std::vector<u8> VP9::ComposeCompressedHeader() {
546 if (current_frame_info.reference_mode != 0) { 503 if (current_frame_info.reference_mode != 0) {
547 WriteProbabilityUpdate(writer, current_frame_info.entropy.comp_ref_prob, 504 WriteProbabilityUpdate(writer, current_frame_info.entropy.comp_ref_prob,
548 prev_frame_probs.comp_ref_prob); 505 prev_frame_probs.comp_ref_prob);
549 if (current_frame_info.show_frame && !current_frame_info.is_key_frame) { 506 if (update_probs) {
550 prev_frame_probs.comp_ref_prob = current_frame_info.entropy.comp_ref_prob; 507 prev_frame_probs.comp_ref_prob = current_frame_info.entropy.comp_ref_prob;
551 } 508 }
552 } 509 }
@@ -557,42 +514,37 @@ std::vector<u8> VP9::ComposeCompressedHeader() {
557 WriteProbabilityUpdate(writer, current_frame_info.entropy.y_mode_prob[index], 514 WriteProbabilityUpdate(writer, current_frame_info.entropy.y_mode_prob[index],
558 prev_frame_probs.y_mode_prob[index]); 515 prev_frame_probs.y_mode_prob[index]);
559 } 516 }
560 if (current_frame_info.show_frame && !current_frame_info.is_key_frame) { 517
561 prev_frame_probs.y_mode_prob = current_frame_info.entropy.y_mode_prob;
562 }
563 // read_partition_probs 518 // read_partition_probs
564 WriteProbabilityUpdateAligned4(writer, current_frame_info.entropy.partition_prob, 519 WriteProbabilityUpdateAligned4(writer, current_frame_info.entropy.partition_prob,
565 prev_frame_probs.partition_prob); 520 prev_frame_probs.partition_prob);
566 if (current_frame_info.show_frame && !current_frame_info.is_key_frame) {
567 prev_frame_probs.partition_prob = current_frame_info.entropy.partition_prob;
568 }
569 521
570 // mv_probs 522 // mv_probs
571 for (s32 i = 0; i < 3; i++) { 523 for (s32 i = 0; i < 3; i++) {
572 WriteMvProbabilityUpdate(writer, current_frame_info.entropy.joints[i], 524 WriteMvProbabilityUpdate(writer, current_frame_info.entropy.joints[i],
573 prev_frame_probs.joints[i]); 525 prev_frame_probs.joints[i]);
574 } 526 }
575 if (current_frame_info.show_frame && !current_frame_info.is_key_frame) { 527 if (update_probs) {
528 prev_frame_probs.inter_mode_prob = current_frame_info.entropy.inter_mode_prob;
529 prev_frame_probs.intra_inter_prob = current_frame_info.entropy.intra_inter_prob;
530 prev_frame_probs.y_mode_prob = current_frame_info.entropy.y_mode_prob;
531 prev_frame_probs.partition_prob = current_frame_info.entropy.partition_prob;
576 prev_frame_probs.joints = current_frame_info.entropy.joints; 532 prev_frame_probs.joints = current_frame_info.entropy.joints;
577 } 533 }
578 534
579 for (s32 i = 0; i < 2; i++) { 535 for (s32 i = 0; i < 2; i++) {
580 WriteMvProbabilityUpdate(writer, current_frame_info.entropy.sign[i], 536 WriteMvProbabilityUpdate(writer, current_frame_info.entropy.sign[i],
581 prev_frame_probs.sign[i]); 537 prev_frame_probs.sign[i]);
582
583 for (s32 j = 0; j < 10; j++) { 538 for (s32 j = 0; j < 10; j++) {
584 const int index = i * 10 + j; 539 const int index = i * 10 + j;
585
586 WriteMvProbabilityUpdate(writer, current_frame_info.entropy.classes[index], 540 WriteMvProbabilityUpdate(writer, current_frame_info.entropy.classes[index],
587 prev_frame_probs.classes[index]); 541 prev_frame_probs.classes[index]);
588 } 542 }
589
590 WriteMvProbabilityUpdate(writer, current_frame_info.entropy.class_0[i], 543 WriteMvProbabilityUpdate(writer, current_frame_info.entropy.class_0[i],
591 prev_frame_probs.class_0[i]); 544 prev_frame_probs.class_0[i]);
592 545
593 for (s32 j = 0; j < 10; j++) { 546 for (s32 j = 0; j < 10; j++) {
594 const int index = i * 10 + j; 547 const int index = i * 10 + j;
595
596 WriteMvProbabilityUpdate(writer, current_frame_info.entropy.prob_bits[index], 548 WriteMvProbabilityUpdate(writer, current_frame_info.entropy.prob_bits[index],
597 prev_frame_probs.prob_bits[index]); 549 prev_frame_probs.prob_bits[index]);
598 } 550 }
@@ -602,7 +554,6 @@ std::vector<u8> VP9::ComposeCompressedHeader() {
602 for (s32 j = 0; j < 2; j++) { 554 for (s32 j = 0; j < 2; j++) {
603 for (s32 k = 0; k < 3; k++) { 555 for (s32 k = 0; k < 3; k++) {
604 const int index = i * 2 * 3 + j * 3 + k; 556 const int index = i * 2 * 3 + j * 3 + k;
605
606 WriteMvProbabilityUpdate(writer, current_frame_info.entropy.class_0_fr[index], 557 WriteMvProbabilityUpdate(writer, current_frame_info.entropy.class_0_fr[index],
607 prev_frame_probs.class_0_fr[index]); 558 prev_frame_probs.class_0_fr[index]);
608 } 559 }
@@ -610,7 +561,6 @@ std::vector<u8> VP9::ComposeCompressedHeader() {
610 561
611 for (s32 j = 0; j < 3; j++) { 562 for (s32 j = 0; j < 3; j++) {
612 const int index = i * 3 + j; 563 const int index = i * 3 + j;
613
614 WriteMvProbabilityUpdate(writer, current_frame_info.entropy.fr[index], 564 WriteMvProbabilityUpdate(writer, current_frame_info.entropy.fr[index],
615 prev_frame_probs.fr[index]); 565 prev_frame_probs.fr[index]);
616 } 566 }
@@ -626,7 +576,7 @@ std::vector<u8> VP9::ComposeCompressedHeader() {
626 } 576 }
627 577
628 // save previous probs 578 // save previous probs
629 if (current_frame_info.show_frame && !current_frame_info.is_key_frame) { 579 if (update_probs) {
630 prev_frame_probs.sign = current_frame_info.entropy.sign; 580 prev_frame_probs.sign = current_frame_info.entropy.sign;
631 prev_frame_probs.classes = current_frame_info.entropy.classes; 581 prev_frame_probs.classes = current_frame_info.entropy.classes;
632 prev_frame_probs.class_0 = current_frame_info.entropy.class_0; 582 prev_frame_probs.class_0 = current_frame_info.entropy.class_0;
@@ -637,7 +587,6 @@ std::vector<u8> VP9::ComposeCompressedHeader() {
637 prev_frame_probs.high_precision = current_frame_info.entropy.high_precision; 587 prev_frame_probs.high_precision = current_frame_info.entropy.high_precision;
638 } 588 }
639 } 589 }
640
641 writer.End(); 590 writer.End();
642 return writer.GetBuffer(); 591 return writer.GetBuffer();
643} 592}
@@ -854,11 +803,11 @@ VpxBitStreamWriter VP9::ComposeUncompressedHeader() {
854 return uncomp_writer; 803 return uncomp_writer;
855} 804}
856 805
857const std::vector<u8>& VP9::ComposeFrameHeader(NvdecCommon::NvdecRegisters& state) { 806const std::vector<u8>& VP9::ComposeFrameHeader(const NvdecCommon::NvdecRegisters& state) {
858 std::vector<u8> bitstream; 807 std::vector<u8> bitstream;
859 { 808 {
860 Vp9FrameContainer curr_frame = GetCurrentFrame(state); 809 Vp9FrameContainer curr_frame = std::move(GetCurrentFrame(state));
861 current_frame_info = curr_frame.info; 810 current_frame_info = std::move(curr_frame.info);
862 bitstream = std::move(curr_frame.bit_stream); 811 bitstream = std::move(curr_frame.bit_stream);
863 } 812 }
864 813
diff --git a/src/video_core/command_classes/codecs/vp9.h b/src/video_core/command_classes/codecs/vp9.h
index e2504512c..9ebbbf59e 100644
--- a/src/video_core/command_classes/codecs/vp9.h
+++ b/src/video_core/command_classes/codecs/vp9.h
@@ -119,7 +119,8 @@ public:
119 119
120 /// Composes the VP9 frame from the GPU state information. Based on the official VP9 spec 120 /// Composes the VP9 frame from the GPU state information. Based on the official VP9 spec
121 /// documentation 121 /// documentation
122 [[nodiscard]] const std::vector<u8>& ComposeFrameHeader(NvdecCommon::NvdecRegisters& state); 122 [[nodiscard]] const std::vector<u8>& ComposeFrameHeader(
123 const NvdecCommon::NvdecRegisters& state);
123 124
124 /// Returns true if the most recent frame was a hidden frame. 125 /// Returns true if the most recent frame was a hidden frame.
125 [[nodiscard]] bool WasFrameHidden() const { 126 [[nodiscard]] bool WasFrameHidden() const {
@@ -147,8 +148,8 @@ private:
147 148
148 /// Writes probability updates for the Coef probabilities 149 /// Writes probability updates for the Coef probabilities
149 void WriteCoefProbabilityUpdate(VpxRangeEncoder& writer, s32 tx_mode, 150 void WriteCoefProbabilityUpdate(VpxRangeEncoder& writer, s32 tx_mode,
150 const std::array<u8, 2304>& new_prob, 151 const std::array<u8, 1728>& new_prob,
151 const std::array<u8, 2304>& old_prob); 152 const std::array<u8, 1728>& old_prob);
152 153
153 /// Write probabilities for 4-byte aligned structures 154 /// Write probabilities for 4-byte aligned structures
154 template <typename T, std::size_t N> 155 template <typename T, std::size_t N>
diff --git a/src/video_core/command_classes/codecs/vp9_types.h b/src/video_core/command_classes/codecs/vp9_types.h
index 4f0b05d22..139501a1c 100644
--- a/src/video_core/command_classes/codecs/vp9_types.h
+++ b/src/video_core/command_classes/codecs/vp9_types.h
@@ -31,62 +31,6 @@ enum FrameFlags : u32 {
31 IntraOnly = 1 << 5, 31 IntraOnly = 1 << 5,
32}; 32};
33 33
34enum class MvJointType {
35 MvJointZero = 0, /* Zero vector */
36 MvJointHnzvz = 1, /* Vert zero, hor nonzero */
37 MvJointHzvnz = 2, /* Hor zero, vert nonzero */
38 MvJointHnzvnz = 3, /* Both components nonzero */
39};
40enum class MvClassType {
41 MvClass0 = 0, /* (0, 2] integer pel */
42 MvClass1 = 1, /* (2, 4] integer pel */
43 MvClass2 = 2, /* (4, 8] integer pel */
44 MvClass3 = 3, /* (8, 16] integer pel */
45 MvClass4 = 4, /* (16, 32] integer pel */
46 MvClass5 = 5, /* (32, 64] integer pel */
47 MvClass6 = 6, /* (64, 128] integer pel */
48 MvClass7 = 7, /* (128, 256] integer pel */
49 MvClass8 = 8, /* (256, 512] integer pel */
50 MvClass9 = 9, /* (512, 1024] integer pel */
51 MvClass10 = 10, /* (1024,2048] integer pel */
52};
53
54enum class BlockSize {
55 Block4x4 = 0,
56 Block4x8 = 1,
57 Block8x4 = 2,
58 Block8x8 = 3,
59 Block8x16 = 4,
60 Block16x8 = 5,
61 Block16x16 = 6,
62 Block16x32 = 7,
63 Block32x16 = 8,
64 Block32x32 = 9,
65 Block32x64 = 10,
66 Block64x32 = 11,
67 Block64x64 = 12,
68 BlockSizes = 13,
69 BlockInvalid = BlockSizes
70};
71
72enum class PredictionMode {
73 DcPred = 0, // Average of above and left pixels
74 VPred = 1, // Vertical
75 HPred = 2, // Horizontal
76 D45Pred = 3, // Directional 45 deg = round(arctan(1 / 1) * 180 / pi)
77 D135Pred = 4, // Directional 135 deg = 180 - 45
78 D117Pred = 5, // Directional 117 deg = 180 - 63
79 D153Pred = 6, // Directional 153 deg = 180 - 27
80 D207Pred = 7, // Directional 207 deg = 180 + 27
81 D63Pred = 8, // Directional 63 deg = round(arctan(2 / 1) * 180 / pi)
82 TmPred = 9, // True-motion
83 NearestMv = 10,
84 NearMv = 11,
85 ZeroMv = 12,
86 NewMv = 13,
87 MbModeCount = 14
88};
89
90enum class TxSize { 34enum class TxSize {
91 Tx4x4 = 0, // 4x4 transform 35 Tx4x4 = 0, // 4x4 transform
92 Tx8x8 = 1, // 8x8 transform 36 Tx8x8 = 1, // 8x8 transform
@@ -104,13 +48,6 @@ enum class TxMode {
104 TxModes = 5 48 TxModes = 5
105}; 49};
106 50
107enum class reference_mode {
108 SingleReference = 0,
109 CompoundReference = 1,
110 ReferenceModeSelect = 2,
111 ReferenceModes = 3
112};
113
114struct Segmentation { 51struct Segmentation {
115 u8 enabled{}; 52 u8 enabled{};
116 u8 update_map{}; 53 u8 update_map{};
@@ -131,7 +68,7 @@ static_assert(sizeof(LoopFilter) == 0x7, "LoopFilter is an invalid size");
131struct Vp9EntropyProbs { 68struct Vp9EntropyProbs {
132 std::array<u8, 36> y_mode_prob{}; 69 std::array<u8, 36> y_mode_prob{};
133 std::array<u8, 64> partition_prob{}; 70 std::array<u8, 64> partition_prob{};
134 std::array<u8, 2304> coef_probs{}; 71 std::array<u8, 1728> coef_probs{};
135 std::array<u8, 8> switchable_interp_prob{}; 72 std::array<u8, 8> switchable_interp_prob{};
136 std::array<u8, 28> inter_mode_prob{}; 73 std::array<u8, 28> inter_mode_prob{};
137 std::array<u8, 4> intra_inter_prob{}; 74 std::array<u8, 4> intra_inter_prob{};
@@ -152,7 +89,7 @@ struct Vp9EntropyProbs {
152 std::array<u8, 2> class_0_hp{}; 89 std::array<u8, 2> class_0_hp{};
153 std::array<u8, 2> high_precision{}; 90 std::array<u8, 2> high_precision{};
154}; 91};
155static_assert(sizeof(Vp9EntropyProbs) == 0x9F4, "Vp9EntropyProbs is an invalid size"); 92static_assert(sizeof(Vp9EntropyProbs) == 0x7B4, "Vp9EntropyProbs is an invalid size");
156 93
157struct Vp9PictureInfo { 94struct Vp9PictureInfo {
158 bool is_key_frame{}; 95 bool is_key_frame{};
@@ -278,72 +215,71 @@ static_assert(sizeof(PictureInfo) == 0x100, "PictureInfo is an invalid size");
278 215
279struct EntropyProbs { 216struct EntropyProbs {
280 INSERT_PADDING_BYTES(1024); 217 INSERT_PADDING_BYTES(1024);
281 std::array<std::array<u8, 4>, 7> inter_mode_prob{}; 218 std::array<u8, 28> inter_mode_prob{};
282 std::array<u8, 4> intra_inter_prob{}; 219 std::array<u8, 4> intra_inter_prob{};
283 INSERT_PADDING_BYTES(80); 220 INSERT_PADDING_BYTES(80);
284 std::array<std::array<u8, 1>, 2> tx_8x8_prob{}; 221 std::array<u8, 2> tx_8x8_prob{};
285 std::array<std::array<u8, 2>, 2> tx_16x16_prob{}; 222 std::array<u8, 4> tx_16x16_prob{};
286 std::array<std::array<u8, 3>, 2> tx_32x32_prob{}; 223 std::array<u8, 6> tx_32x32_prob{};
287 std::array<u8, 4> y_mode_prob_e8{}; 224 std::array<u8, 4> y_mode_prob_e8{};
288 std::array<std::array<u8, 8>, 4> y_mode_prob_e0e7{}; 225 std::array<std::array<u8, 8>, 4> y_mode_prob_e0e7{};
289 INSERT_PADDING_BYTES(64); 226 INSERT_PADDING_BYTES(64);
290 std::array<std::array<u8, 4>, 16> partition_prob{}; 227 std::array<u8, 64> partition_prob{};
291 INSERT_PADDING_BYTES(10); 228 INSERT_PADDING_BYTES(10);
292 std::array<std::array<u8, 2>, 4> switchable_interp_prob{}; 229 std::array<u8, 8> switchable_interp_prob{};
293 std::array<u8, 5> comp_inter_prob{}; 230 std::array<u8, 5> comp_inter_prob{};
294 std::array<u8, 4> skip_probs{}; 231 std::array<u8, 3> skip_probs{};
232 INSERT_PADDING_BYTES(1);
295 std::array<u8, 3> joints{}; 233 std::array<u8, 3> joints{};
296 std::array<u8, 2> sign{}; 234 std::array<u8, 2> sign{};
297 std::array<std::array<u8, 1>, 2> class_0{}; 235 std::array<u8, 2> class_0{};
298 std::array<std::array<u8, 3>, 2> fr{}; 236 std::array<u8, 6> fr{};
299 std::array<u8, 2> class_0_hp{}; 237 std::array<u8, 2> class_0_hp{};
300 std::array<u8, 2> high_precision{}; 238 std::array<u8, 2> high_precision{};
301 std::array<std::array<u8, 10>, 2> classes{}; 239 std::array<u8, 20> classes{};
302 std::array<std::array<std::array<u8, 3>, 2>, 2> class_0_fr{}; 240 std::array<u8, 12> class_0_fr{};
303 std::array<std::array<u8, 10>, 2> pred_bits{}; 241 std::array<u8, 20> pred_bits{};
304 std::array<std::array<u8, 2>, 5> single_ref_prob{}; 242 std::array<u8, 10> single_ref_prob{};
305 std::array<u8, 5> comp_ref_prob{}; 243 std::array<u8, 5> comp_ref_prob{};
306 INSERT_PADDING_BYTES(17); 244 INSERT_PADDING_BYTES(17);
307 std::array<std::array<std::array<std::array<std::array<std::array<u8, 4>, 6>, 6>, 2>, 2>, 4> 245 std::array<u8, 2304> coef_probs{};
308 coef_probs{};
309 246
310 void Convert(Vp9EntropyProbs& fc) { 247 void Convert(Vp9EntropyProbs& fc) {
311 std::memcpy(fc.inter_mode_prob.data(), inter_mode_prob.data(), fc.inter_mode_prob.size()); 248 fc.inter_mode_prob = inter_mode_prob;
312 249 fc.intra_inter_prob = intra_inter_prob;
313 std::memcpy(fc.intra_inter_prob.data(), intra_inter_prob.data(), 250 fc.tx_8x8_prob = tx_8x8_prob;
314 fc.intra_inter_prob.size()); 251 fc.tx_16x16_prob = tx_16x16_prob;
315 252 fc.tx_32x32_prob = tx_32x32_prob;
316 std::memcpy(fc.tx_8x8_prob.data(), tx_8x8_prob.data(), fc.tx_8x8_prob.size()); 253
317 std::memcpy(fc.tx_16x16_prob.data(), tx_16x16_prob.data(), fc.tx_16x16_prob.size()); 254 for (std::size_t i = 0; i < 4; i++) {
318 std::memcpy(fc.tx_32x32_prob.data(), tx_32x32_prob.data(), fc.tx_32x32_prob.size()); 255 for (std::size_t j = 0; j < 9; j++) {
319
320 for (s32 i = 0; i < 4; i++) {
321 for (s32 j = 0; j < 9; j++) {
322 fc.y_mode_prob[j + 9 * i] = j < 8 ? y_mode_prob_e0e7[i][j] : y_mode_prob_e8[i]; 256 fc.y_mode_prob[j + 9 * i] = j < 8 ? y_mode_prob_e0e7[i][j] : y_mode_prob_e8[i];
323 } 257 }
324 } 258 }
325 259
326 std::memcpy(fc.partition_prob.data(), partition_prob.data(), fc.partition_prob.size()); 260 fc.partition_prob = partition_prob;
327 261 fc.switchable_interp_prob = switchable_interp_prob;
328 std::memcpy(fc.switchable_interp_prob.data(), switchable_interp_prob.data(), 262 fc.comp_inter_prob = comp_inter_prob;
329 fc.switchable_interp_prob.size()); 263 fc.skip_probs = skip_probs;
330 std::memcpy(fc.comp_inter_prob.data(), comp_inter_prob.data(), fc.comp_inter_prob.size()); 264 fc.joints = joints;
331 std::memcpy(fc.skip_probs.data(), skip_probs.data(), fc.skip_probs.size()); 265 fc.sign = sign;
332 266 fc.class_0 = class_0;
333 std::memcpy(fc.joints.data(), joints.data(), fc.joints.size()); 267 fc.fr = fr;
334 268 fc.class_0_hp = class_0_hp;
335 std::memcpy(fc.sign.data(), sign.data(), fc.sign.size()); 269 fc.high_precision = high_precision;
336 std::memcpy(fc.class_0.data(), class_0.data(), fc.class_0.size()); 270 fc.classes = classes;
337 std::memcpy(fc.fr.data(), fr.data(), fc.fr.size()); 271 fc.class_0_fr = class_0_fr;
338 std::memcpy(fc.class_0_hp.data(), class_0_hp.data(), fc.class_0_hp.size()); 272 fc.prob_bits = pred_bits;
339 std::memcpy(fc.high_precision.data(), high_precision.data(), fc.high_precision.size()); 273 fc.single_ref_prob = single_ref_prob;
340 std::memcpy(fc.classes.data(), classes.data(), fc.classes.size()); 274 fc.comp_ref_prob = comp_ref_prob;
341 std::memcpy(fc.class_0_fr.data(), class_0_fr.data(), fc.class_0_fr.size()); 275
342 std::memcpy(fc.prob_bits.data(), pred_bits.data(), fc.prob_bits.size()); 276 // Skip the 4th element as it goes unused
343 std::memcpy(fc.single_ref_prob.data(), single_ref_prob.data(), fc.single_ref_prob.size()); 277 for (std::size_t i = 0; i < coef_probs.size(); i += 4) {
344 std::memcpy(fc.comp_ref_prob.data(), comp_ref_prob.data(), fc.comp_ref_prob.size()); 278 const std::size_t j = i - i / 4;
345 279 fc.coef_probs[j] = coef_probs[i];
346 std::memcpy(fc.coef_probs.data(), coef_probs.data(), fc.coef_probs.size()); 280 fc.coef_probs[j + 1] = coef_probs[i + 1];
281 fc.coef_probs[j + 2] = coef_probs[i + 2];
282 }
347 } 283 }
348}; 284};
349static_assert(sizeof(EntropyProbs) == 0xEA0, "EntropyProbs is an invalid size"); 285static_assert(sizeof(EntropyProbs) == 0xEA0, "EntropyProbs is an invalid size");
diff --git a/src/video_core/command_classes/nvdec.cpp b/src/video_core/command_classes/nvdec.cpp
index 8ca7a7b06..79e1f4e13 100644
--- a/src/video_core/command_classes/nvdec.cpp
+++ b/src/video_core/command_classes/nvdec.cpp
@@ -29,11 +29,7 @@ void Nvdec::ProcessMethod(Method method, const std::vector<u32>& arguments) {
29 } 29 }
30} 30}
31 31
32AVFrame* Nvdec::GetFrame() { 32AVFramePtr Nvdec::GetFrame() {
33 return codec->GetCurrentFrame();
34}
35
36const AVFrame* Nvdec::GetFrame() const {
37 return codec->GetCurrentFrame(); 33 return codec->GetCurrentFrame();
38} 34}
39 35
diff --git a/src/video_core/command_classes/nvdec.h b/src/video_core/command_classes/nvdec.h
index eec4443f9..e4877c533 100644
--- a/src/video_core/command_classes/nvdec.h
+++ b/src/video_core/command_classes/nvdec.h
@@ -26,8 +26,7 @@ public:
26 void ProcessMethod(Method method, const std::vector<u32>& arguments); 26 void ProcessMethod(Method method, const std::vector<u32>& arguments);
27 27
28 /// Return most recently decoded frame 28 /// Return most recently decoded frame
29 [[nodiscard]] AVFrame* GetFrame(); 29 [[nodiscard]] AVFramePtr GetFrame();
30 [[nodiscard]] const AVFrame* GetFrame() const;
31 30
32private: 31private:
33 /// Invoke codec to decode a frame 32 /// Invoke codec to decode a frame
diff --git a/src/video_core/command_classes/vic.cpp b/src/video_core/command_classes/vic.cpp
index 5b52da277..248443027 100644
--- a/src/video_core/command_classes/vic.cpp
+++ b/src/video_core/command_classes/vic.cpp
@@ -58,17 +58,18 @@ void Vic::Execute() {
58 return; 58 return;
59 } 59 }
60 const VicConfig config{gpu.MemoryManager().Read<u64>(config_struct_address + 0x20)}; 60 const VicConfig config{gpu.MemoryManager().Read<u64>(config_struct_address + 0x20)};
61 const AVFramePtr frame_ptr = std::move(nvdec_processor->GetFrame());
62 const auto* frame = frame_ptr.get();
63 if (!frame || frame->width == 0 || frame->height == 0) {
64 return;
65 }
61 const VideoPixelFormat pixel_format = 66 const VideoPixelFormat pixel_format =
62 static_cast<VideoPixelFormat>(config.pixel_format.Value()); 67 static_cast<VideoPixelFormat>(config.pixel_format.Value());
63 switch (pixel_format) { 68 switch (pixel_format) {
64 case VideoPixelFormat::BGRA8: 69 case VideoPixelFormat::BGRA8:
65 case VideoPixelFormat::RGBA8: { 70 case VideoPixelFormat::RGBA8: {
66 LOG_TRACE(Service_NVDRV, "Writing RGB Frame"); 71 LOG_TRACE(Service_NVDRV, "Writing RGB Frame");
67 const auto* frame = nvdec_processor->GetFrame();
68 72
69 if (!frame || frame->width == 0 || frame->height == 0) {
70 return;
71 }
72 if (scaler_ctx == nullptr || frame->width != scaler_width || 73 if (scaler_ctx == nullptr || frame->width != scaler_width ||
73 frame->height != scaler_height) { 74 frame->height != scaler_height) {
74 const AVPixelFormat target_format = 75 const AVPixelFormat target_format =
@@ -121,12 +122,6 @@ void Vic::Execute() {
121 case VideoPixelFormat::Yuv420: { 122 case VideoPixelFormat::Yuv420: {
122 LOG_TRACE(Service_NVDRV, "Writing YUV420 Frame"); 123 LOG_TRACE(Service_NVDRV, "Writing YUV420 Frame");
123 124
124 const auto* frame = nvdec_processor->GetFrame();
125
126 if (!frame || frame->width == 0 || frame->height == 0) {
127 return;
128 }
129
130 const std::size_t surface_width = config.surface_width_minus1 + 1; 125 const std::size_t surface_width = config.surface_width_minus1 + 1;
131 const std::size_t surface_height = config.surface_height_minus1 + 1; 126 const std::size_t surface_height = config.surface_height_minus1 + 1;
132 const std::size_t half_width = surface_width / 2; 127 const std::size_t half_width = surface_width / 2;
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 1cbe8fe67..b0d9559d0 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -755,7 +755,11 @@ public:
755 755
756 u32 data_upload; 756 u32 data_upload;
757 757
758 INSERT_UNION_PADDING_WORDS(0x44); 758 INSERT_UNION_PADDING_WORDS(0x16);
759
760 u32 force_early_fragment_tests;
761
762 INSERT_UNION_PADDING_WORDS(0x2D);
759 763
760 struct { 764 struct {
761 union { 765 union {
@@ -1572,6 +1576,7 @@ ASSERT_REG_POSITION(shadow_ram_control, 0x49);
1572ASSERT_REG_POSITION(upload, 0x60); 1576ASSERT_REG_POSITION(upload, 0x60);
1573ASSERT_REG_POSITION(exec_upload, 0x6C); 1577ASSERT_REG_POSITION(exec_upload, 0x6C);
1574ASSERT_REG_POSITION(data_upload, 0x6D); 1578ASSERT_REG_POSITION(data_upload, 0x6D);
1579ASSERT_REG_POSITION(force_early_fragment_tests, 0x84);
1575ASSERT_REG_POSITION(sync_info, 0xB2); 1580ASSERT_REG_POSITION(sync_info, 0xB2);
1576ASSERT_REG_POSITION(tess_mode, 0xC8); 1581ASSERT_REG_POSITION(tess_mode, 0xC8);
1577ASSERT_REG_POSITION(tess_level_outer, 0xC9); 1582ASSERT_REG_POSITION(tess_level_outer, 0xC9);
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index ebd149c3a..e91f52938 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -95,22 +95,29 @@ void GPU::WaitFence(u32 syncpoint_id, u32 value) {
95 if (!is_async) { 95 if (!is_async) {
96 return; 96 return;
97 } 97 }
98 if (syncpoint_id == UINT32_MAX) {
99 // TODO: Research what this does.
100 LOG_ERROR(HW_GPU, "Waiting for syncpoint -1 not implemented");
101 return;
102 }
98 MICROPROFILE_SCOPE(GPU_wait); 103 MICROPROFILE_SCOPE(GPU_wait);
99 std::unique_lock lock{sync_mutex}; 104 std::unique_lock lock{sync_mutex};
100 sync_cv.wait(lock, [=, this] { return syncpoints[syncpoint_id].load() >= value; }); 105 sync_cv.wait(lock, [=, this] { return syncpoints.at(syncpoint_id).load() >= value; });
101} 106}
102 107
103void GPU::IncrementSyncPoint(const u32 syncpoint_id) { 108void GPU::IncrementSyncPoint(const u32 syncpoint_id) {
104 syncpoints[syncpoint_id]++; 109 auto& syncpoint = syncpoints.at(syncpoint_id);
110 syncpoint++;
105 std::lock_guard lock{sync_mutex}; 111 std::lock_guard lock{sync_mutex};
106 sync_cv.notify_all(); 112 sync_cv.notify_all();
107 if (!syncpt_interrupts[syncpoint_id].empty()) { 113 auto& interrupt = syncpt_interrupts.at(syncpoint_id);
108 u32 value = syncpoints[syncpoint_id].load(); 114 if (!interrupt.empty()) {
109 auto it = syncpt_interrupts[syncpoint_id].begin(); 115 u32 value = syncpoint.load();
110 while (it != syncpt_interrupts[syncpoint_id].end()) { 116 auto it = interrupt.begin();
117 while (it != interrupt.end()) {
111 if (value >= *it) { 118 if (value >= *it) {
112 TriggerCpuInterrupt(syncpoint_id, *it); 119 TriggerCpuInterrupt(syncpoint_id, *it);
113 it = syncpt_interrupts[syncpoint_id].erase(it); 120 it = interrupt.erase(it);
114 continue; 121 continue;
115 } 122 }
116 it++; 123 it++;
@@ -119,22 +126,22 @@ void GPU::IncrementSyncPoint(const u32 syncpoint_id) {
119} 126}
120 127
121u32 GPU::GetSyncpointValue(const u32 syncpoint_id) const { 128u32 GPU::GetSyncpointValue(const u32 syncpoint_id) const {
122 return syncpoints[syncpoint_id].load(); 129 return syncpoints.at(syncpoint_id).load();
123} 130}
124 131
125void GPU::RegisterSyncptInterrupt(const u32 syncpoint_id, const u32 value) { 132void GPU::RegisterSyncptInterrupt(const u32 syncpoint_id, const u32 value) {
126 auto& interrupt = syncpt_interrupts[syncpoint_id]; 133 auto& interrupt = syncpt_interrupts.at(syncpoint_id);
127 bool contains = std::any_of(interrupt.begin(), interrupt.end(), 134 bool contains = std::any_of(interrupt.begin(), interrupt.end(),
128 [value](u32 in_value) { return in_value == value; }); 135 [value](u32 in_value) { return in_value == value; });
129 if (contains) { 136 if (contains) {
130 return; 137 return;
131 } 138 }
132 syncpt_interrupts[syncpoint_id].emplace_back(value); 139 interrupt.emplace_back(value);
133} 140}
134 141
135bool GPU::CancelSyncptInterrupt(const u32 syncpoint_id, const u32 value) { 142bool GPU::CancelSyncptInterrupt(const u32 syncpoint_id, const u32 value) {
136 std::lock_guard lock{sync_mutex}; 143 std::lock_guard lock{sync_mutex};
137 auto& interrupt = syncpt_interrupts[syncpoint_id]; 144 auto& interrupt = syncpt_interrupts.at(syncpoint_id);
138 const auto iter = 145 const auto iter =
139 std::find_if(interrupt.begin(), interrupt.end(), 146 std::find_if(interrupt.begin(), interrupt.end(),
140 [value](u32 interrupt_value) { return value == interrupt_value; }); 147 [value](u32 interrupt_value) { return value == interrupt_value; });
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 2ccca1993..c869bb0e2 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -151,8 +151,8 @@ void RendererOpenGL::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
151 151
152 rasterizer->TickFrame(); 152 rasterizer->TickFrame();
153 153
154 render_window.PollEvents();
155 context->SwapBuffers(); 154 context->SwapBuffers();
155 render_window.OnFrameDisplayed();
156} 156}
157 157
158void RendererOpenGL::PrepareRendertarget(const Tegra::FramebufferConfig* framebuffer) { 158void RendererOpenGL::PrepareRendertarget(const Tegra::FramebufferConfig* framebuffer) {
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
index da5c550ea..5ec43db11 100644
--- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
+++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
@@ -8,6 +8,7 @@
8 8
9#include <boost/functional/hash.hpp> 9#include <boost/functional/hash.hpp>
10 10
11#include "common/bit_cast.h"
11#include "common/cityhash.h" 12#include "common/cityhash.h"
12#include "common/common_types.h" 13#include "common/common_types.h"
13#include "video_core/renderer_vulkan/fixed_pipeline_state.h" 14#include "video_core/renderer_vulkan/fixed_pipeline_state.h"
@@ -45,7 +46,7 @@ void FixedPipelineState::Fill(const Maxwell& regs, bool has_extended_dynamic_sta
45 regs.polygon_offset_fill_enable}; 46 regs.polygon_offset_fill_enable};
46 const u32 topology_index = static_cast<u32>(regs.draw.topology.Value()); 47 const u32 topology_index = static_cast<u32>(regs.draw.topology.Value());
47 48
48 raw = 0; 49 raw1 = 0;
49 primitive_restart_enable.Assign(regs.primitive_restart.enabled != 0 ? 1 : 0); 50 primitive_restart_enable.Assign(regs.primitive_restart.enabled != 0 ? 1 : 0);
50 depth_bias_enable.Assign(enabled_lut[POLYGON_OFFSET_ENABLE_LUT[topology_index]] != 0 ? 1 : 0); 51 depth_bias_enable.Assign(enabled_lut[POLYGON_OFFSET_ENABLE_LUT[topology_index]] != 0 ? 1 : 0);
51 depth_clamp_disabled.Assign(regs.view_volume_clip_control.depth_clamp_disabled.Value()); 52 depth_clamp_disabled.Assign(regs.view_volume_clip_control.depth_clamp_disabled.Value());
@@ -60,7 +61,14 @@ void FixedPipelineState::Fill(const Maxwell& regs, bool has_extended_dynamic_sta
60 rasterize_enable.Assign(regs.rasterize_enable != 0 ? 1 : 0); 61 rasterize_enable.Assign(regs.rasterize_enable != 0 ? 1 : 0);
61 topology.Assign(regs.draw.topology); 62 topology.Assign(regs.draw.topology);
62 63
63 std::memcpy(&point_size, &regs.point_size, sizeof(point_size)); // TODO: C++20 std::bit_cast 64 raw2 = 0;
65 const auto test_func =
66 regs.alpha_test_enabled == 1 ? regs.alpha_test_func : Maxwell::ComparisonOp::Always;
67 alpha_test_func.Assign(PackComparisonOp(test_func));
68 early_z.Assign(regs.force_early_fragment_tests != 0 ? 1 : 0);
69
70 alpha_test_ref = Common::BitCast<u32>(regs.alpha_test_ref);
71 point_size = Common::BitCast<u32>(regs.point_size);
64 72
65 for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) { 73 for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) {
66 binding_divisors[index] = 74 binding_divisors[index] =
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.h b/src/video_core/renderer_vulkan/fixed_pipeline_state.h
index 2c18eeaae..c26b77790 100644
--- a/src/video_core/renderer_vulkan/fixed_pipeline_state.h
+++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.h
@@ -171,7 +171,7 @@ struct FixedPipelineState {
171 }; 171 };
172 172
173 union { 173 union {
174 u32 raw; 174 u32 raw1;
175 BitField<0, 1, u32> no_extended_dynamic_state; 175 BitField<0, 1, u32> no_extended_dynamic_state;
176 BitField<2, 1, u32> primitive_restart_enable; 176 BitField<2, 1, u32> primitive_restart_enable;
177 BitField<3, 1, u32> depth_bias_enable; 177 BitField<3, 1, u32> depth_bias_enable;
@@ -187,6 +187,13 @@ struct FixedPipelineState {
187 BitField<23, 1, u32> rasterize_enable; 187 BitField<23, 1, u32> rasterize_enable;
188 BitField<24, 4, Maxwell::PrimitiveTopology> topology; 188 BitField<24, 4, Maxwell::PrimitiveTopology> topology;
189 }; 189 };
190 union {
191 u32 raw2;
192 BitField<0, 3, u32> alpha_test_func;
193 BitField<3, 1, u32> early_z;
194 };
195
196 u32 alpha_test_ref;
190 u32 point_size; 197 u32 point_size;
191 std::array<u32, Maxwell::NumVertexArrays> binding_divisors; 198 std::array<u32, Maxwell::NumVertexArrays> binding_divisors;
192 std::array<VertexAttribute, Maxwell::NumVertexAttributes> attributes; 199 std::array<VertexAttribute, Maxwell::NumVertexAttributes> attributes;
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
index f2610868e..a2173edd2 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
@@ -252,8 +252,6 @@ RendererVulkan::~RendererVulkan() {
252} 252}
253 253
254void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { 254void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
255 render_window.PollEvents();
256
257 if (!framebuffer) { 255 if (!framebuffer) {
258 return; 256 return;
259 } 257 }
@@ -283,7 +281,7 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
283 rasterizer->TickFrame(); 281 rasterizer->TickFrame();
284 } 282 }
285 283
286 render_window.PollEvents(); 284 render_window.OnFrameDisplayed();
287} 285}
288 286
289bool RendererVulkan::Init() { 287bool RendererVulkan::Init() {
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index dedc9c466..df7e8c864 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -7,6 +7,7 @@
7#include <memory> 7#include <memory>
8#include <vector> 8#include <vector>
9 9
10#include "common/bit_cast.h"
10#include "common/microprofile.h" 11#include "common/microprofile.h"
11#include "core/core.h" 12#include "core/core.h"
12#include "core/memory.h" 13#include "core/memory.h"
@@ -343,6 +344,12 @@ VKPipelineCache::DecompileShaders(const FixedPipelineState& fixed_state) {
343 specialization.attribute_types[i] = attribute.Type(); 344 specialization.attribute_types[i] = attribute.Type();
344 } 345 }
345 specialization.ndc_minus_one_to_one = fixed_state.ndc_minus_one_to_one; 346 specialization.ndc_minus_one_to_one = fixed_state.ndc_minus_one_to_one;
347 specialization.early_fragment_tests = fixed_state.early_z;
348
349 // Alpha test
350 specialization.alpha_test_func =
351 FixedPipelineState::UnpackComparisonOp(fixed_state.alpha_test_func.Value());
352 specialization.alpha_test_ref = Common::BitCast<float>(fixed_state.alpha_test_ref);
346 353
347 SPIRVProgram program; 354 SPIRVProgram program;
348 std::vector<VkDescriptorSetLayoutBinding> bindings; 355 std::vector<VkDescriptorSetLayoutBinding> bindings;
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
index a20452b87..fed9ebecd 100644
--- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
+++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
@@ -315,7 +315,6 @@ public:
315 "supported on this device"); 315 "supported on this device");
316 } 316 }
317 } 317 }
318
319 if (ir.UsesLayer() || ir.UsesViewportIndex()) { 318 if (ir.UsesLayer() || ir.UsesViewportIndex()) {
320 if (ir.UsesViewportIndex()) { 319 if (ir.UsesViewportIndex()) {
321 AddCapability(spv::Capability::MultiViewport); 320 AddCapability(spv::Capability::MultiViewport);
@@ -325,11 +324,9 @@ public:
325 AddCapability(spv::Capability::ShaderViewportIndexLayerEXT); 324 AddCapability(spv::Capability::ShaderViewportIndexLayerEXT);
326 } 325 }
327 } 326 }
328
329 if (device.IsFormatlessImageLoadSupported()) { 327 if (device.IsFormatlessImageLoadSupported()) {
330 AddCapability(spv::Capability::StorageImageReadWithoutFormat); 328 AddCapability(spv::Capability::StorageImageReadWithoutFormat);
331 } 329 }
332
333 if (device.IsFloat16Supported()) { 330 if (device.IsFloat16Supported()) {
334 AddCapability(spv::Capability::Float16); 331 AddCapability(spv::Capability::Float16);
335 } 332 }
@@ -377,6 +374,9 @@ public:
377 if (header.ps.omap.depth) { 374 if (header.ps.omap.depth) {
378 AddExecutionMode(main, spv::ExecutionMode::DepthReplacing); 375 AddExecutionMode(main, spv::ExecutionMode::DepthReplacing);
379 } 376 }
377 if (specialization.early_fragment_tests) {
378 AddExecutionMode(main, spv::ExecutionMode::EarlyFragmentTests);
379 }
380 break; 380 break;
381 case ShaderType::Compute: 381 case ShaderType::Compute:
382 const auto workgroup_size = specialization.workgroup_size; 382 const auto workgroup_size = specialization.workgroup_size;
@@ -2075,6 +2075,45 @@ private:
2075 return {}; 2075 return {};
2076 } 2076 }
2077 2077
2078 Id MaxwellToSpirvComparison(Maxwell::ComparisonOp compare_op, Id operand_1, Id operand_2) {
2079 using Compare = Maxwell::ComparisonOp;
2080 switch (compare_op) {
2081 case Compare::NeverOld:
2082 return v_false; // Never let the test pass
2083 case Compare::LessOld:
2084 return OpFOrdLessThan(t_bool, operand_1, operand_2);
2085 case Compare::EqualOld:
2086 return OpFOrdEqual(t_bool, operand_1, operand_2);
2087 case Compare::LessEqualOld:
2088 return OpFOrdLessThanEqual(t_bool, operand_1, operand_2);
2089 case Compare::GreaterOld:
2090 return OpFOrdGreaterThan(t_bool, operand_1, operand_2);
2091 case Compare::NotEqualOld:
2092 return OpFOrdNotEqual(t_bool, operand_1, operand_2);
2093 case Compare::GreaterEqualOld:
2094 return OpFOrdGreaterThanEqual(t_bool, operand_1, operand_2);
2095 default:
2096 UNREACHABLE();
2097 }
2098 }
2099
2100 void AlphaTest(Id pointer) {
2101 if (specialization.alpha_test_func == Maxwell::ComparisonOp::AlwaysOld) {
2102 return;
2103 }
2104 const Id true_label = OpLabel();
2105 const Id discard_label = OpLabel();
2106 const Id alpha_reference = Constant(t_float, specialization.alpha_test_ref);
2107 const Id alpha_value = OpLoad(t_float, pointer);
2108 const Id condition =
2109 MaxwellToSpirvComparison(specialization.alpha_test_func, alpha_value, alpha_reference);
2110
2111 OpBranchConditional(condition, true_label, discard_label);
2112 AddLabel(discard_label);
2113 OpKill();
2114 AddLabel(true_label);
2115 }
2116
2078 void PreExit() { 2117 void PreExit() {
2079 if (stage == ShaderType::Vertex && specialization.ndc_minus_one_to_one) { 2118 if (stage == ShaderType::Vertex && specialization.ndc_minus_one_to_one) {
2080 const u32 position_index = out_indices.position.value(); 2119 const u32 position_index = out_indices.position.value();
@@ -2097,8 +2136,6 @@ private:
2097 UNIMPLEMENTED_IF_MSG(header.ps.omap.sample_mask != 0, 2136 UNIMPLEMENTED_IF_MSG(header.ps.omap.sample_mask != 0,
2098 "Sample mask write is unimplemented"); 2137 "Sample mask write is unimplemented");
2099 2138
2100 // TODO(Rodrigo): Alpha testing
2101
2102 // Write the color outputs using the data in the shader registers, disabled 2139 // Write the color outputs using the data in the shader registers, disabled
2103 // rendertargets/components are skipped in the register assignment. 2140 // rendertargets/components are skipped in the register assignment.
2104 u32 current_reg = 0; 2141 u32 current_reg = 0;
@@ -2110,6 +2147,9 @@ private:
2110 } 2147 }
2111 const Id pointer = AccessElement(t_out_float, frag_colors[rt], component); 2148 const Id pointer = AccessElement(t_out_float, frag_colors[rt], component);
2112 OpStore(pointer, SafeGetRegister(current_reg)); 2149 OpStore(pointer, SafeGetRegister(current_reg));
2150 if (rt == 0 && component == 3) {
2151 AlphaTest(pointer);
2152 }
2113 ++current_reg; 2153 ++current_reg;
2114 } 2154 }
2115 } 2155 }
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.h b/src/video_core/renderer_vulkan/vk_shader_decompiler.h
index 2b0e90396..110848922 100644
--- a/src/video_core/renderer_vulkan/vk_shader_decompiler.h
+++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.h
@@ -95,6 +95,9 @@ struct Specialization final {
95 std::bitset<Maxwell::NumVertexAttributes> enabled_attributes; 95 std::bitset<Maxwell::NumVertexAttributes> enabled_attributes;
96 std::array<Maxwell::VertexAttribute::Type, Maxwell::NumVertexAttributes> attribute_types{}; 96 std::array<Maxwell::VertexAttribute::Type, Maxwell::NumVertexAttributes> attribute_types{};
97 bool ndc_minus_one_to_one{}; 97 bool ndc_minus_one_to_one{};
98 bool early_fragment_tests{};
99 float alpha_test_ref{};
100 Maxwell::ComparisonOp alpha_test_func{};
98}; 101};
99// Old gcc versions don't consider this trivially copyable. 102// Old gcc versions don't consider this trivially copyable.
100// static_assert(std::is_trivially_copyable_v<Specialization>); 103// static_assert(std::is_trivially_copyable_v<Specialization>);
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index f0338cf7a..489104d5f 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -35,7 +35,7 @@
35#include "core/settings.h" 35#include "core/settings.h"
36#include "input_common/keyboard.h" 36#include "input_common/keyboard.h"
37#include "input_common/main.h" 37#include "input_common/main.h"
38#include "input_common/motion_emu.h" 38#include "input_common/mouse/mouse_input.h"
39#include "video_core/renderer_base.h" 39#include "video_core/renderer_base.h"
40#include "video_core/video_core.h" 40#include "video_core/video_core.h"
41#include "yuzu/bootmanager.h" 41#include "yuzu/bootmanager.h"
@@ -314,7 +314,7 @@ GRenderWindow::~GRenderWindow() {
314 input_subsystem->Shutdown(); 314 input_subsystem->Shutdown();
315} 315}
316 316
317void GRenderWindow::PollEvents() { 317void GRenderWindow::OnFrameDisplayed() {
318 if (!first_frame) { 318 if (!first_frame) {
319 first_frame = true; 319 first_frame = true;
320 emit FirstFrameDisplayed(); 320 emit FirstFrameDisplayed();
@@ -388,23 +388,19 @@ void GRenderWindow::keyReleaseEvent(QKeyEvent* event) {
388} 388}
389 389
390void GRenderWindow::mousePressEvent(QMouseEvent* event) { 390void GRenderWindow::mousePressEvent(QMouseEvent* event) {
391 if (!Settings::values.touchscreen.enabled) {
392 input_subsystem->GetKeyboard()->PressKey(event->button());
393 return;
394 }
395
396 // Touch input is handled in TouchBeginEvent 391 // Touch input is handled in TouchBeginEvent
397 if (event->source() == Qt::MouseEventSynthesizedBySystem) { 392 if (event->source() == Qt::MouseEventSynthesizedBySystem) {
398 return; 393 return;
399 } 394 }
400 395
401 auto pos = event->pos(); 396 auto pos = event->pos();
397 const auto [x, y] = ScaleTouch(pos);
398 input_subsystem->GetMouse()->PressButton(x, y, event->button());
399
402 if (event->button() == Qt::LeftButton) { 400 if (event->button() == Qt::LeftButton) {
403 const auto [x, y] = ScaleTouch(pos);
404 this->TouchPressed(x, y); 401 this->TouchPressed(x, y);
405 } else if (event->button() == Qt::RightButton) {
406 input_subsystem->GetMotionEmu()->BeginTilt(pos.x(), pos.y());
407 } 402 }
403
408 QWidget::mousePressEvent(event); 404 QWidget::mousePressEvent(event);
409} 405}
410 406
@@ -416,26 +412,22 @@ void GRenderWindow::mouseMoveEvent(QMouseEvent* event) {
416 412
417 auto pos = event->pos(); 413 auto pos = event->pos();
418 const auto [x, y] = ScaleTouch(pos); 414 const auto [x, y] = ScaleTouch(pos);
415 input_subsystem->GetMouse()->MouseMove(x, y);
419 this->TouchMoved(x, y); 416 this->TouchMoved(x, y);
420 input_subsystem->GetMotionEmu()->Tilt(pos.x(), pos.y()); 417
421 QWidget::mouseMoveEvent(event); 418 QWidget::mouseMoveEvent(event);
422} 419}
423 420
424void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) { 421void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) {
425 if (!Settings::values.touchscreen.enabled) {
426 input_subsystem->GetKeyboard()->ReleaseKey(event->button());
427 return;
428 }
429
430 // Touch input is handled in TouchEndEvent 422 // Touch input is handled in TouchEndEvent
431 if (event->source() == Qt::MouseEventSynthesizedBySystem) { 423 if (event->source() == Qt::MouseEventSynthesizedBySystem) {
432 return; 424 return;
433 } 425 }
434 426
427 input_subsystem->GetMouse()->ReleaseButton(event->button());
428
435 if (event->button() == Qt::LeftButton) { 429 if (event->button() == Qt::LeftButton) {
436 this->TouchReleased(); 430 this->TouchReleased();
437 } else if (event->button() == Qt::RightButton) {
438 input_subsystem->GetMotionEmu()->EndTilt();
439 } 431 }
440} 432}
441 433
diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h
index 503b4f89e..a6d788d40 100644
--- a/src/yuzu/bootmanager.h
+++ b/src/yuzu/bootmanager.h
@@ -131,7 +131,7 @@ public:
131 ~GRenderWindow() override; 131 ~GRenderWindow() override;
132 132
133 // EmuWindow implementation. 133 // EmuWindow implementation.
134 void PollEvents() override; 134 void OnFrameDisplayed() override;
135 bool IsShown() const override; 135 bool IsShown() const override;
136 std::unique_ptr<Core::Frontend::GraphicsContext> CreateSharedContext() const override; 136 std::unique_ptr<Core::Frontend::GraphicsContext> CreateSharedContext() const override;
137 137
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 3c423a271..fcc38b3af 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -7,6 +7,7 @@
7#include <QSettings> 7#include <QSettings>
8#include "common/common_paths.h" 8#include "common/common_paths.h"
9#include "common/file_util.h" 9#include "common/file_util.h"
10#include "core/core.h"
10#include "core/hle/service/acc/profile_manager.h" 11#include "core/hle/service/acc/profile_manager.h"
11#include "core/hle/service/hid/controllers/npad.h" 12#include "core/hle/service/hid/controllers/npad.h"
12#include "input_common/main.h" 13#include "input_common/main.h"
@@ -568,16 +569,11 @@ void Config::ReadMotionTouchValues() {
568 ReadSetting(QStringLiteral("touch_from_button_map"), 0).toInt(); 569 ReadSetting(QStringLiteral("touch_from_button_map"), 0).toInt();
569 Settings::values.touch_from_button_map_index = 570 Settings::values.touch_from_button_map_index =
570 std::clamp(Settings::values.touch_from_button_map_index, 0, num_touch_from_button_maps - 1); 571 std::clamp(Settings::values.touch_from_button_map_index, 0, num_touch_from_button_maps - 1);
571 Settings::values.udp_input_address = 572 Settings::values.udp_input_servers =
572 ReadSetting(QStringLiteral("udp_input_address"), 573 ReadSetting(QStringLiteral("udp_input_servers"),
573 QString::fromUtf8(InputCommon::CemuhookUDP::DEFAULT_ADDR)) 574 QString::fromUtf8(InputCommon::CemuhookUDP::DEFAULT_SRV))
574 .toString() 575 .toString()
575 .toStdString(); 576 .toStdString();
576 Settings::values.udp_input_port = static_cast<u16>(
577 ReadSetting(QStringLiteral("udp_input_port"), InputCommon::CemuhookUDP::DEFAULT_PORT)
578 .toInt());
579 Settings::values.udp_pad_index =
580 static_cast<u8>(ReadSetting(QStringLiteral("udp_pad_index"), 0).toUInt());
581} 577}
582 578
583void Config::ReadCoreValues() { 579void Config::ReadCoreValues() {
@@ -1108,12 +1104,9 @@ void Config::SaveMotionTouchValues() {
1108 false); 1104 false);
1109 WriteSetting(QStringLiteral("touch_from_button_map"), 1105 WriteSetting(QStringLiteral("touch_from_button_map"),
1110 Settings::values.touch_from_button_map_index, 0); 1106 Settings::values.touch_from_button_map_index, 0);
1111 WriteSetting(QStringLiteral("udp_input_address"), 1107 WriteSetting(QStringLiteral("udp_input_servers"),
1112 QString::fromStdString(Settings::values.udp_input_address), 1108 QString::fromStdString(Settings::values.udp_input_servers),
1113 QString::fromUtf8(InputCommon::CemuhookUDP::DEFAULT_ADDR)); 1109 QString::fromUtf8(InputCommon::CemuhookUDP::DEFAULT_SRV));
1114 WriteSetting(QStringLiteral("udp_input_port"), Settings::values.udp_input_port,
1115 InputCommon::CemuhookUDP::DEFAULT_PORT);
1116 WriteSetting(QStringLiteral("udp_pad_index"), Settings::values.udp_pad_index, 0);
1117 1110
1118 qt_config->beginWriteArray(QStringLiteral("touch_from_button_maps")); 1111 qt_config->beginWriteArray(QStringLiteral("touch_from_button_maps"));
1119 for (std::size_t p = 0; p < Settings::values.touch_from_button_maps.size(); ++p) { 1112 for (std::size_t p = 0; p < Settings::values.touch_from_button_maps.size(); ++p) {
@@ -1598,7 +1591,7 @@ void Config::Reload() {
1598 Settings::Sanitize(); 1591 Settings::Sanitize();
1599 // To apply default value changes 1592 // To apply default value changes
1600 SaveValues(); 1593 SaveValues();
1601 Settings::Apply(); 1594 Settings::Apply(Core::System::GetInstance());
1602} 1595}
1603 1596
1604void Config::Save() { 1597void Config::Save() {
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp
index 5041e0bf8..b33f8437a 100644
--- a/src/yuzu/configuration/configure_dialog.cpp
+++ b/src/yuzu/configuration/configure_dialog.cpp
@@ -5,6 +5,7 @@
5#include <QHash> 5#include <QHash>
6#include <QListWidgetItem> 6#include <QListWidgetItem>
7#include <QSignalBlocker> 7#include <QSignalBlocker>
8#include "core/core.h"
8#include "core/settings.h" 9#include "core/settings.h"
9#include "ui_configure.h" 10#include "ui_configure.h"
10#include "yuzu/configuration/config.h" 11#include "yuzu/configuration/config.h"
@@ -54,7 +55,7 @@ void ConfigureDialog::ApplyConfiguration() {
54 ui->debugTab->ApplyConfiguration(); 55 ui->debugTab->ApplyConfiguration();
55 ui->webTab->ApplyConfiguration(); 56 ui->webTab->ApplyConfiguration();
56 ui->serviceTab->ApplyConfiguration(); 57 ui->serviceTab->ApplyConfiguration();
57 Settings::Apply(); 58 Settings::Apply(Core::System::GetInstance());
58 Settings::LogSettings(); 59 Settings::LogSettings();
59} 60}
60 61
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index 918bfb56b..f9915fb7a 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -19,6 +19,7 @@
19#include "core/hle/service/sm/sm.h" 19#include "core/hle/service/sm/sm.h"
20#include "input_common/gcadapter/gc_poller.h" 20#include "input_common/gcadapter/gc_poller.h"
21#include "input_common/main.h" 21#include "input_common/main.h"
22#include "input_common/mouse/mouse_poller.h"
22#include "input_common/udp/udp.h" 23#include "input_common/udp/udp.h"
23#include "ui_configure_input_player.h" 24#include "ui_configure_input_player.h"
24#include "yuzu/configuration/config.h" 25#include "yuzu/configuration/config.h"
@@ -152,6 +153,14 @@ QString ButtonToText(const Common::ParamPackage& param) {
152 return {}; 153 return {};
153 } 154 }
154 155
156 if (param.Get("engine", "") == "mouse") {
157 if (param.Has("button")) {
158 const QString button_str = QString::number(int(param.Get("button", 0)));
159 return QObject::tr("Click %1").arg(button_str);
160 }
161 return GetKeyName(param.Get("code", 0));
162 }
163
155 return QObject::tr("[unknown]"); 164 return QObject::tr("[unknown]");
156} 165}
157 166
@@ -203,6 +212,26 @@ QString AnalogToText(const Common::ParamPackage& param, const std::string& dir)
203 212
204 return {}; 213 return {};
205 } 214 }
215
216 if (param.Get("engine", "") == "mouse") {
217 if (dir == "modifier") {
218 return QObject::tr("[unused]");
219 }
220
221 if (dir == "left" || dir == "right") {
222 const QString axis_x_str = QString::fromStdString(param.Get("axis_x", ""));
223
224 return QObject::tr("Mouse %1").arg(axis_x_str);
225 }
226
227 if (dir == "up" || dir == "down") {
228 const QString axis_y_str = QString::fromStdString(param.Get("axis_y", ""));
229
230 return QObject::tr("Mouse %1").arg(axis_y_str);
231 }
232
233 return {};
234 }
206 return QObject::tr("[unknown]"); 235 return QObject::tr("[unknown]");
207} 236}
208} // namespace 237} // namespace
@@ -484,6 +513,34 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
484 return; 513 return;
485 } 514 }
486 } 515 }
516 if (input_subsystem->GetMouseButtons()->IsPolling()) {
517 params = input_subsystem->GetMouseButtons()->GetNextInput();
518 if (params.Has("engine") && IsInputAcceptable(params)) {
519 SetPollingResult(params, false);
520 return;
521 }
522 }
523 if (input_subsystem->GetMouseAnalogs()->IsPolling()) {
524 params = input_subsystem->GetMouseAnalogs()->GetNextInput();
525 if (params.Has("engine") && IsInputAcceptable(params)) {
526 SetPollingResult(params, false);
527 return;
528 }
529 }
530 if (input_subsystem->GetMouseMotions()->IsPolling()) {
531 params = input_subsystem->GetMouseMotions()->GetNextInput();
532 if (params.Has("engine") && IsInputAcceptable(params)) {
533 SetPollingResult(params, false);
534 return;
535 }
536 }
537 if (input_subsystem->GetMouseTouch()->IsPolling()) {
538 params = input_subsystem->GetMouseTouch()->GetNextInput();
539 if (params.Has("engine") && IsInputAcceptable(params)) {
540 SetPollingResult(params, false);
541 return;
542 }
543 }
487 for (auto& poller : device_pollers) { 544 for (auto& poller : device_pollers) {
488 params = poller->GetNextInput(); 545 params = poller->GetNextInput();
489 if (params.Has("engine") && IsInputAcceptable(params)) { 546 if (params.Has("engine") && IsInputAcceptable(params)) {
@@ -761,8 +818,9 @@ void ConfigureInputPlayer::UpdateUI() {
761 818
762 int slider_value; 819 int slider_value;
763 auto& param = analogs_param[analog_id]; 820 auto& param = analogs_param[analog_id];
764 const bool is_controller = 821 const bool is_controller = param.Get("engine", "") == "sdl" ||
765 param.Get("engine", "") == "sdl" || param.Get("engine", "") == "gcpad"; 822 param.Get("engine", "") == "gcpad" ||
823 param.Get("engine", "") == "mouse";
766 824
767 if (is_controller) { 825 if (is_controller) {
768 if (!param.Has("deadzone")) { 826 if (!param.Has("deadzone")) {
@@ -1078,6 +1136,16 @@ void ConfigureInputPlayer::HandleClick(
1078 input_subsystem->GetUDPMotions()->BeginConfiguration(); 1136 input_subsystem->GetUDPMotions()->BeginConfiguration();
1079 } 1137 }
1080 1138
1139 if (type == InputCommon::Polling::DeviceType::Button) {
1140 input_subsystem->GetMouseButtons()->BeginConfiguration();
1141 } else if (type == InputCommon::Polling::DeviceType::AnalogPreferred) {
1142 input_subsystem->GetMouseAnalogs()->BeginConfiguration();
1143 } else if (type == InputCommon::Polling::DeviceType::Motion) {
1144 input_subsystem->GetMouseMotions()->BeginConfiguration();
1145 } else {
1146 input_subsystem->GetMouseTouch()->BeginConfiguration();
1147 }
1148
1081 timeout_timer->start(2500); // Cancel after 2.5 seconds 1149 timeout_timer->start(2500); // Cancel after 2.5 seconds
1082 poll_timer->start(50); // Check for new inputs every 50ms 1150 poll_timer->start(50); // Check for new inputs every 50ms
1083} 1151}
@@ -1097,6 +1165,11 @@ void ConfigureInputPlayer::SetPollingResult(const Common::ParamPackage& params,
1097 1165
1098 input_subsystem->GetUDPMotions()->EndConfiguration(); 1166 input_subsystem->GetUDPMotions()->EndConfiguration();
1099 1167
1168 input_subsystem->GetMouseButtons()->EndConfiguration();
1169 input_subsystem->GetMouseAnalogs()->EndConfiguration();
1170 input_subsystem->GetMouseMotions()->EndConfiguration();
1171 input_subsystem->GetMouseTouch()->EndConfiguration();
1172
1100 if (!abort) { 1173 if (!abort) {
1101 (*input_setter)(params); 1174 (*input_setter)(params);
1102 } 1175 }
@@ -1128,15 +1201,7 @@ void ConfigureInputPlayer::mousePressEvent(QMouseEvent* event) {
1128 return; 1201 return;
1129 } 1202 }
1130 1203
1131 if (want_keyboard_mouse) { 1204 input_subsystem->GetMouse()->PressButton(0, 0, event->button());
1132 SetPollingResult(Common::ParamPackage{InputCommon::GenerateKeyboardParam(event->button())},
1133 false);
1134 } else {
1135 // We don't want any mouse buttons, so don't stop polling
1136 return;
1137 }
1138
1139 SetPollingResult({}, true);
1140} 1205}
1141 1206
1142void ConfigureInputPlayer::keyPressEvent(QKeyEvent* event) { 1207void ConfigureInputPlayer::keyPressEvent(QKeyEvent* event) {
diff --git a/src/yuzu/configuration/configure_motion_touch.cpp b/src/yuzu/configuration/configure_motion_touch.cpp
index 170574d9b..2afac591a 100644
--- a/src/yuzu/configuration/configure_motion_touch.cpp
+++ b/src/yuzu/configuration/configure_motion_touch.cpp
@@ -3,10 +3,12 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <array> 5#include <array>
6#include <sstream>
6#include <QCloseEvent> 7#include <QCloseEvent>
7#include <QLabel> 8#include <QLabel>
8#include <QMessageBox> 9#include <QMessageBox>
9#include <QPushButton> 10#include <QPushButton>
11#include <QStringListModel>
10#include <QVBoxLayout> 12#include <QVBoxLayout>
11#include "common/logging/log.h" 13#include "common/logging/log.h"
12#include "core/settings.h" 14#include "core/settings.h"
@@ -74,11 +76,6 @@ void CalibrationConfigurationDialog::UpdateButtonText(const QString& text) {
74 cancel_button->setText(text); 76 cancel_button->setText(text);
75} 77}
76 78
77constexpr std::array<std::pair<const char*, const char*>, 2> MotionProviders = {{
78 {"motion_emu", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "Mouse (Right Click)")},
79 {"cemuhookudp", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "CemuhookUDP")},
80}};
81
82constexpr std::array<std::pair<const char*, const char*>, 2> TouchProviders = {{ 79constexpr std::array<std::pair<const char*, const char*>, 2> TouchProviders = {{
83 {"emu_window", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "Emulator Window")}, 80 {"emu_window", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "Emulator Window")},
84 {"cemuhookudp", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "CemuhookUDP")}, 81 {"cemuhookudp", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "CemuhookUDP")},
@@ -89,9 +86,6 @@ ConfigureMotionTouch::ConfigureMotionTouch(QWidget* parent,
89 : QDialog(parent), input_subsystem{input_subsystem_}, 86 : QDialog(parent), input_subsystem{input_subsystem_},
90 ui(std::make_unique<Ui::ConfigureMotionTouch>()) { 87 ui(std::make_unique<Ui::ConfigureMotionTouch>()) {
91 ui->setupUi(this); 88 ui->setupUi(this);
92 for (const auto& [provider, name] : MotionProviders) {
93 ui->motion_provider->addItem(tr(name), QString::fromUtf8(provider));
94 }
95 for (const auto& [provider, name] : TouchProviders) { 89 for (const auto& [provider, name] : TouchProviders) {
96 ui->touch_provider->addItem(tr(name), QString::fromUtf8(provider)); 90 ui->touch_provider->addItem(tr(name), QString::fromUtf8(provider));
97 } 91 }
@@ -116,8 +110,6 @@ void ConfigureMotionTouch::SetConfiguration() {
116 const std::string motion_engine = motion_param.Get("engine", "motion_emu"); 110 const std::string motion_engine = motion_param.Get("engine", "motion_emu");
117 const std::string touch_engine = touch_param.Get("engine", "emu_window"); 111 const std::string touch_engine = touch_param.Get("engine", "emu_window");
118 112
119 ui->motion_provider->setCurrentIndex(
120 ui->motion_provider->findData(QString::fromStdString(motion_engine)));
121 ui->touch_provider->setCurrentIndex( 113 ui->touch_provider->setCurrentIndex(
122 ui->touch_provider->findData(QString::fromStdString(touch_engine))); 114 ui->touch_provider->findData(QString::fromStdString(touch_engine)));
123 ui->touch_from_button_checkbox->setChecked(Settings::values.use_touch_from_button); 115 ui->touch_from_button_checkbox->setChecked(Settings::values.use_touch_from_button);
@@ -133,23 +125,30 @@ void ConfigureMotionTouch::SetConfiguration() {
133 max_x = touch_param.Get("max_x", 1800); 125 max_x = touch_param.Get("max_x", 1800);
134 max_y = touch_param.Get("max_y", 850); 126 max_y = touch_param.Get("max_y", 850);
135 127
136 ui->udp_server->setText(QString::fromStdString(Settings::values.udp_input_address)); 128 ui->udp_server->setText(QString::fromStdString("127.0.0.1"));
137 ui->udp_port->setText(QString::number(Settings::values.udp_input_port)); 129 ui->udp_port->setText(QString::number(26760));
138 ui->udp_pad_index->setCurrentIndex(Settings::values.udp_pad_index); 130
131 udp_server_list_model = new QStringListModel(this);
132 udp_server_list_model->setStringList({});
133 ui->udp_server_list->setModel(udp_server_list_model);
134
135 std::stringstream ss(Settings::values.udp_input_servers);
136 std::string token;
137
138 while (std::getline(ss, token, ',')) {
139 const int row = udp_server_list_model->rowCount();
140 udp_server_list_model->insertRows(row, 1);
141 const QModelIndex index = udp_server_list_model->index(row);
142 udp_server_list_model->setData(index, QString::fromStdString(token));
143 }
139} 144}
140 145
141void ConfigureMotionTouch::UpdateUiDisplay() { 146void ConfigureMotionTouch::UpdateUiDisplay() {
142 const QString motion_engine = ui->motion_provider->currentData().toString();
143 const QString touch_engine = ui->touch_provider->currentData().toString(); 147 const QString touch_engine = ui->touch_provider->currentData().toString();
144 const QString cemuhook_udp = QStringLiteral("cemuhookudp"); 148 const QString cemuhook_udp = QStringLiteral("cemuhookudp");
145 149
146 if (motion_engine == QStringLiteral("motion_emu")) { 150 ui->motion_sensitivity_label->setVisible(true);
147 ui->motion_sensitivity_label->setVisible(true); 151 ui->motion_sensitivity->setVisible(true);
148 ui->motion_sensitivity->setVisible(true);
149 } else {
150 ui->motion_sensitivity_label->setVisible(false);
151 ui->motion_sensitivity->setVisible(false);
152 }
153 152
154 if (touch_engine == cemuhook_udp) { 153 if (touch_engine == cemuhook_udp) {
155 ui->touch_calibration->setVisible(true); 154 ui->touch_calibration->setVisible(true);
@@ -163,19 +162,15 @@ void ConfigureMotionTouch::UpdateUiDisplay() {
163 ui->touch_calibration_label->setVisible(false); 162 ui->touch_calibration_label->setVisible(false);
164 } 163 }
165 164
166 if (motion_engine == cemuhook_udp || touch_engine == cemuhook_udp) { 165 ui->udp_config_group_box->setVisible(true);
167 ui->udp_config_group_box->setVisible(true);
168 } else {
169 ui->udp_config_group_box->setVisible(false);
170 }
171} 166}
172 167
173void ConfigureMotionTouch::ConnectEvents() { 168void ConfigureMotionTouch::ConnectEvents() {
174 connect(ui->motion_provider, qOverload<int>(&QComboBox::currentIndexChanged), this,
175 [this](int index) { UpdateUiDisplay(); });
176 connect(ui->touch_provider, qOverload<int>(&QComboBox::currentIndexChanged), this, 169 connect(ui->touch_provider, qOverload<int>(&QComboBox::currentIndexChanged), this,
177 [this](int index) { UpdateUiDisplay(); }); 170 [this](int index) { UpdateUiDisplay(); });
178 connect(ui->udp_test, &QPushButton::clicked, this, &ConfigureMotionTouch::OnCemuhookUDPTest); 171 connect(ui->udp_test, &QPushButton::clicked, this, &ConfigureMotionTouch::OnCemuhookUDPTest);
172 connect(ui->udp_add, &QPushButton::clicked, this, &ConfigureMotionTouch::OnUDPAddServer);
173 connect(ui->udp_remove, &QPushButton::clicked, this, &ConfigureMotionTouch::OnUDPDeleteServer);
179 connect(ui->touch_calibration_config, &QPushButton::clicked, this, 174 connect(ui->touch_calibration_config, &QPushButton::clicked, this,
180 &ConfigureMotionTouch::OnConfigureTouchCalibration); 175 &ConfigureMotionTouch::OnConfigureTouchCalibration);
181 connect(ui->touch_from_button_config_btn, &QPushButton::clicked, this, 176 connect(ui->touch_from_button_config_btn, &QPushButton::clicked, this,
@@ -187,13 +182,58 @@ void ConfigureMotionTouch::ConnectEvents() {
187 }); 182 });
188} 183}
189 184
185void ConfigureMotionTouch::OnUDPAddServer() {
186 QRegExp re(tr("^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?["
187 "0-9][0-9]?)$")); // a valid ip address
188 bool ok;
189 QString port_text = ui->udp_port->text();
190 QString server_text = ui->udp_server->text();
191 const QString server_string = tr("%1:%2").arg(server_text, port_text);
192 int port_number = port_text.toInt(&ok, 10);
193 int row = udp_server_list_model->rowCount();
194
195 if (!ok) {
196 QMessageBox::warning(this, tr("yuzu"), tr("Port number has invalid characters"));
197 return;
198 }
199 if (port_number < 0 || port_number > 65353) {
200 QMessageBox::warning(this, tr("yuzu"), tr("Port has to be in range 0 and 65353"));
201 return;
202 }
203 if (!re.exactMatch(server_text)) {
204 QMessageBox::warning(this, tr("yuzu"), tr("IP address is not valid"));
205 return;
206 }
207 // Search for duplicates
208 for (const auto& item : udp_server_list_model->stringList()) {
209 if (item == server_string) {
210 QMessageBox::warning(this, tr("yuzu"), tr("This UDP server already exists"));
211 return;
212 }
213 }
214 // Limit server count to 8
215 if (row == 8) {
216 QMessageBox::warning(this, tr("yuzu"), tr("Unable to add more than 8 servers"));
217 return;
218 }
219
220 udp_server_list_model->insertRows(row, 1);
221 QModelIndex index = udp_server_list_model->index(row);
222 udp_server_list_model->setData(index, server_string);
223 ui->udp_server_list->setCurrentIndex(index);
224}
225
226void ConfigureMotionTouch::OnUDPDeleteServer() {
227 udp_server_list_model->removeRows(ui->udp_server_list->currentIndex().row(), 1);
228}
229
190void ConfigureMotionTouch::OnCemuhookUDPTest() { 230void ConfigureMotionTouch::OnCemuhookUDPTest() {
191 ui->udp_test->setEnabled(false); 231 ui->udp_test->setEnabled(false);
192 ui->udp_test->setText(tr("Testing")); 232 ui->udp_test->setText(tr("Testing"));
193 udp_test_in_progress = true; 233 udp_test_in_progress = true;
194 InputCommon::CemuhookUDP::TestCommunication( 234 InputCommon::CemuhookUDP::TestCommunication(
195 ui->udp_server->text().toStdString(), static_cast<u16>(ui->udp_port->text().toInt()), 235 ui->udp_server->text().toStdString(), static_cast<u16>(ui->udp_port->text().toInt()), 0,
196 static_cast<u32>(ui->udp_pad_index->currentIndex()), 24872, 236 24872,
197 [this] { 237 [this] {
198 LOG_INFO(Frontend, "UDP input test success"); 238 LOG_INFO(Frontend, "UDP input test success");
199 QMetaObject::invokeMethod(this, "ShowUDPTestResult", Q_ARG(bool, true)); 239 QMetaObject::invokeMethod(this, "ShowUDPTestResult", Q_ARG(bool, true));
@@ -207,9 +247,9 @@ void ConfigureMotionTouch::OnCemuhookUDPTest() {
207void ConfigureMotionTouch::OnConfigureTouchCalibration() { 247void ConfigureMotionTouch::OnConfigureTouchCalibration() {
208 ui->touch_calibration_config->setEnabled(false); 248 ui->touch_calibration_config->setEnabled(false);
209 ui->touch_calibration_config->setText(tr("Configuring")); 249 ui->touch_calibration_config->setText(tr("Configuring"));
210 CalibrationConfigurationDialog dialog( 250 CalibrationConfigurationDialog dialog(this, ui->udp_server->text().toStdString(),
211 this, ui->udp_server->text().toStdString(), static_cast<u16>(ui->udp_port->text().toUInt()), 251 static_cast<u16>(ui->udp_port->text().toUInt()), 0,
212 static_cast<u8>(ui->udp_pad_index->currentIndex()), 24872); 252 24872);
213 dialog.exec(); 253 dialog.exec();
214 if (dialog.completed) { 254 if (dialog.completed) {
215 min_x = dialog.min_x; 255 min_x = dialog.min_x;
@@ -269,7 +309,7 @@ void ConfigureMotionTouch::OnConfigureTouchFromButton() {
269 309
270bool ConfigureMotionTouch::CanCloseDialog() { 310bool ConfigureMotionTouch::CanCloseDialog() {
271 if (udp_test_in_progress) { 311 if (udp_test_in_progress) {
272 QMessageBox::warning(this, tr("Citra"), 312 QMessageBox::warning(this, tr("yuzu"),
273 tr("UDP Test or calibration configuration is in progress.<br>Please " 313 tr("UDP Test or calibration configuration is in progress.<br>Please "
274 "wait for them to finish.")); 314 "wait for them to finish."));
275 return false; 315 return false;
@@ -282,17 +322,11 @@ void ConfigureMotionTouch::ApplyConfiguration() {
282 return; 322 return;
283 } 323 }
284 324
285 std::string motion_engine = ui->motion_provider->currentData().toString().toStdString();
286 std::string touch_engine = ui->touch_provider->currentData().toString().toStdString(); 325 std::string touch_engine = ui->touch_provider->currentData().toString().toStdString();
287 326
288 Common::ParamPackage motion_param{}, touch_param{}; 327 Common::ParamPackage touch_param{};
289 motion_param.Set("engine", std::move(motion_engine));
290 touch_param.Set("engine", std::move(touch_engine)); 328 touch_param.Set("engine", std::move(touch_engine));
291 329
292 if (motion_engine == "motion_emu") {
293 motion_param.Set("sensitivity", static_cast<float>(ui->motion_sensitivity->value()));
294 }
295
296 if (touch_engine == "cemuhookudp") { 330 if (touch_engine == "cemuhookudp") {
297 touch_param.Set("min_x", min_x); 331 touch_param.Set("min_x", min_x);
298 touch_param.Set("min_y", min_y); 332 touch_param.Set("min_y", min_y);
@@ -300,15 +334,25 @@ void ConfigureMotionTouch::ApplyConfiguration() {
300 touch_param.Set("max_y", max_y); 334 touch_param.Set("max_y", max_y);
301 } 335 }
302 336
303 Settings::values.motion_device = motion_param.Serialize();
304 Settings::values.touch_device = touch_param.Serialize(); 337 Settings::values.touch_device = touch_param.Serialize();
305 Settings::values.use_touch_from_button = ui->touch_from_button_checkbox->isChecked(); 338 Settings::values.use_touch_from_button = ui->touch_from_button_checkbox->isChecked();
306 Settings::values.touch_from_button_map_index = ui->touch_from_button_map->currentIndex(); 339 Settings::values.touch_from_button_map_index = ui->touch_from_button_map->currentIndex();
307 Settings::values.touch_from_button_maps = touch_from_button_maps; 340 Settings::values.touch_from_button_maps = touch_from_button_maps;
308 Settings::values.udp_input_address = ui->udp_server->text().toStdString(); 341 Settings::values.udp_input_servers = GetUDPServerString();
309 Settings::values.udp_input_port = static_cast<u16>(ui->udp_port->text().toInt());
310 Settings::values.udp_pad_index = static_cast<u8>(ui->udp_pad_index->currentIndex());
311 input_subsystem->ReloadInputDevices(); 342 input_subsystem->ReloadInputDevices();
312 343
313 accept(); 344 accept();
314} 345}
346
347std::string ConfigureMotionTouch::GetUDPServerString() const {
348 QString input_servers;
349
350 for (const auto& item : udp_server_list_model->stringList()) {
351 input_servers += item;
352 input_servers += QLatin1Char{','};
353 }
354
355 // Remove last comma
356 input_servers.chop(1);
357 return input_servers.toStdString();
358}
diff --git a/src/yuzu/configuration/configure_motion_touch.h b/src/yuzu/configuration/configure_motion_touch.h
index 3d4b5d659..15d61e8ba 100644
--- a/src/yuzu/configuration/configure_motion_touch.h
+++ b/src/yuzu/configuration/configure_motion_touch.h
@@ -10,6 +10,7 @@
10 10
11class QLabel; 11class QLabel;
12class QPushButton; 12class QPushButton;
13class QStringListModel;
13class QVBoxLayout; 14class QVBoxLayout;
14 15
15namespace InputCommon { 16namespace InputCommon {
@@ -62,6 +63,8 @@ public slots:
62 void ApplyConfiguration(); 63 void ApplyConfiguration();
63 64
64private slots: 65private slots:
66 void OnUDPAddServer();
67 void OnUDPDeleteServer();
65 void OnCemuhookUDPTest(); 68 void OnCemuhookUDPTest();
66 void OnConfigureTouchCalibration(); 69 void OnConfigureTouchCalibration();
67 void OnConfigureTouchFromButton(); 70 void OnConfigureTouchFromButton();
@@ -73,10 +76,12 @@ private:
73 void UpdateUiDisplay(); 76 void UpdateUiDisplay();
74 void ConnectEvents(); 77 void ConnectEvents();
75 bool CanCloseDialog(); 78 bool CanCloseDialog();
79 std::string GetUDPServerString() const;
76 80
77 InputCommon::InputSubsystem* input_subsystem; 81 InputCommon::InputSubsystem* input_subsystem;
78 82
79 std::unique_ptr<Ui::ConfigureMotionTouch> ui; 83 std::unique_ptr<Ui::ConfigureMotionTouch> ui;
84 QStringListModel* udp_server_list_model;
80 85
81 // Coordinate system of the CemuhookUDP touch provider 86 // Coordinate system of the CemuhookUDP touch provider
82 int min_x{}; 87 int min_x{};
diff --git a/src/yuzu/configuration/configure_motion_touch.ui b/src/yuzu/configuration/configure_motion_touch.ui
index 5b78c5a4b..ebca835ac 100644
--- a/src/yuzu/configuration/configure_motion_touch.ui
+++ b/src/yuzu/configuration/configure_motion_touch.ui
@@ -2,41 +2,30 @@
2<ui version="4.0"> 2<ui version="4.0">
3 <class>ConfigureMotionTouch</class> 3 <class>ConfigureMotionTouch</class>
4 <widget class="QDialog" name="ConfigureMotionTouch"> 4 <widget class="QDialog" name="ConfigureMotionTouch">
5 <property name="windowTitle">
6 <string>Configure Motion / Touch</string>
7 </property>
8 <property name="geometry"> 5 <property name="geometry">
9 <rect> 6 <rect>
10 <x>0</x> 7 <x>0</x>
11 <y>0</y> 8 <y>0</y>
12 <width>500</width> 9 <width>500</width>
13 <height>450</height> 10 <height>482</height>
14 </rect> 11 </rect>
15 </property> 12 </property>
13 <property name="windowTitle">
14 <string>Configure Motion / Touch</string>
15 </property>
16 <property name="styleSheet">
17 <string notr="true"/>
18 </property>
16 <layout class="QVBoxLayout"> 19 <layout class="QVBoxLayout">
17 <item> 20 <item>
18 <widget class="QGroupBox" name="motion_group_box"> 21 <widget class="QGroupBox" name="motion_group_box">
19 <property name="title"> 22 <property name="title">
20 <string>Motion</string> 23 <string>Mouse Motion</string>
21 </property> 24 </property>
22 <layout class="QVBoxLayout"> 25 <layout class="QVBoxLayout">
23 <item> 26 <item>
24 <layout class="QHBoxLayout"> 27 <layout class="QHBoxLayout">
25 <item> 28 <item>
26 <widget class="QLabel" name="motion_provider_label">
27 <property name="text">
28 <string>Motion Provider:</string>
29 </property>
30 </widget>
31 </item>
32 <item>
33 <widget class="QComboBox" name="motion_provider"/>
34 </item>
35 </layout>
36 </item>
37 <item>
38 <layout class="QHBoxLayout">
39 <item>
40 <widget class="QLabel" name="motion_sensitivity_label"> 29 <widget class="QLabel" name="motion_sensitivity_label">
41 <property name="text"> 30 <property name="text">
42 <string>Sensitivity:</string> 31 <string>Sensitivity:</string>
@@ -180,103 +169,171 @@
180 </widget> 169 </widget>
181 </item> 170 </item>
182 <item> 171 <item>
183 <layout class="QHBoxLayout"> 172 <layout class="QHBoxLayout" name="horizontalLayout">
184 <item> 173 <item>
185 <widget class="QLabel" name="udp_server_label"> 174 <widget class="QListView" name="udp_server_list"/>
186 <property name="text">
187 <string>Server:</string>
188 </property>
189 </widget>
190 </item> 175 </item>
191 <item> 176 <item>
192 <widget class="QLineEdit" name="udp_server"> 177 <layout class="QVBoxLayout" name="verticalLayout">
193 <property name="sizePolicy"> 178 <property name="leftMargin">
194 <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> 179 <number>0</number>
195 <horstretch>0</horstretch>
196 <verstretch>0</verstretch>
197 </sizepolicy>
198 </property> 180 </property>
199 </widget> 181 <property name="topMargin">
200 </item> 182 <number>0</number>
201 </layout>
202 </item>
203 <item>
204 <layout class="QHBoxLayout">
205 <item>
206 <widget class="QLabel" name="udp_port_label">
207 <property name="text">
208 <string>Port:</string>
209 </property> 183 </property>
210 </widget> 184 <property name="rightMargin">
211 </item> 185 <number>0</number>
212 <item>
213 <widget class="QLineEdit" name="udp_port">
214 <property name="sizePolicy">
215 <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
216 <horstretch>0</horstretch>
217 <verstretch>0</verstretch>
218 </sizepolicy>
219 </property> 186 </property>
220 </widget> 187 <property name="bottomMargin">
221 </item> 188 <number>0</number>
222 </layout>
223 </item>
224 <item>
225 <layout class="QHBoxLayout">
226 <item>
227 <widget class="QLabel" name="udp_pad_index_label">
228 <property name="text">
229 <string>Pad:</string>
230 </property> 189 </property>
231 </widget>
232 </item>
233 <item>
234 <widget class="QComboBox" name="udp_pad_index">
235 <item> 190 <item>
236 <property name="text"> 191 <layout class="QHBoxLayout">
237 <string>Pad 1</string> 192 <property name="leftMargin">
238 </property> 193 <number>3</number>
194 </property>
195 <property name="topMargin">
196 <number>3</number>
197 </property>
198 <property name="rightMargin">
199 <number>0</number>
200 </property>
201 <item>
202 <widget class="QLabel" name="udp_server_label">
203 <property name="text">
204 <string>Server:</string>
205 </property>
206 </widget>
207 </item>
208 <item>
209 <widget class="QLineEdit" name="udp_server">
210 <property name="sizePolicy">
211 <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
212 <horstretch>0</horstretch>
213 <verstretch>0</verstretch>
214 </sizepolicy>
215 </property>
216 </widget>
217 </item>
218 </layout>
239 </item> 219 </item>
240 <item> 220 <item>
241 <property name="text"> 221 <layout class="QHBoxLayout">
242 <string>Pad 2</string> 222 <property name="leftMargin">
243 </property> 223 <number>3</number>
224 </property>
225 <property name="rightMargin">
226 <number>0</number>
227 </property>
228 <item>
229 <widget class="QLabel" name="udp_port_label">
230 <property name="text">
231 <string>Port:</string>
232 </property>
233 </widget>
234 </item>
235 <item>
236 <widget class="QLineEdit" name="udp_port">
237 <property name="sizePolicy">
238 <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
239 <horstretch>0</horstretch>
240 <verstretch>0</verstretch>
241 </sizepolicy>
242 </property>
243 </widget>
244 </item>
245 </layout>
244 </item> 246 </item>
245 <item> 247 <item>
246 <property name="text"> 248 <layout class="QHBoxLayout">
247 <string>Pad 3</string> 249 <property name="leftMargin">
248 </property> 250 <number>3</number>
251 </property>
252 <property name="rightMargin">
253 <number>0</number>
254 </property>
255 <item>
256 <widget class="QLabel" name="udp_learn_more">
257 <property name="text">
258 <string>Learn More</string>
259 </property>
260 </widget>
261 </item>
262 <item>
263 <widget class="QPushButton" name="udp_test">
264 <property name="sizePolicy">
265 <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
266 <horstretch>0</horstretch>
267 <verstretch>0</verstretch>
268 </sizepolicy>
269 </property>
270 <property name="text">
271 <string>Test</string>
272 </property>
273 </widget>
274 </item>
275 <item>
276 <widget class="QPushButton" name="udp_add">
277 <property name="sizePolicy">
278 <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
279 <horstretch>0</horstretch>
280 <verstretch>0</verstretch>
281 </sizepolicy>
282 </property>
283 <property name="text">
284 <string>Add Server</string>
285 </property>
286 </widget>
287 </item>
288 </layout>
249 </item> 289 </item>
250 <item> 290 <item>
251 <property name="text"> 291 <spacer name="verticalSpacer_3">
252 <string>Pad 4</string> 292 <property name="orientation">
253 </property> 293 <enum>Qt::Vertical</enum>
294 </property>
295 <property name="sizeHint" stdset="0">
296 <size>
297 <width>20</width>
298 <height>40</height>
299 </size>
300 </property>
301 </spacer>
254 </item> 302 </item>
255 </widget> 303 <item>
256 </item> 304 <layout class="QHBoxLayout" name="horizontalLayout_2">
257 </layout> 305 <property name="topMargin">
258 </item> 306 <number>0</number>
259 <item> 307 </property>
260 <layout class="QHBoxLayout"> 308 <item>
261 <item> 309 <widget class="QPushButton" name="udp_remove">
262 <widget class="QLabel" name="udp_learn_more"> 310 <property name="sizePolicy">
263 <property name="text"> 311 <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
264 <string>Learn More</string> 312 <horstretch>0</horstretch>
265 </property> 313 <verstretch>0</verstretch>
266 </widget> 314 </sizepolicy>
267 </item> 315 </property>
268 <item> 316 <property name="text">
269 <widget class="QPushButton" name="udp_test"> 317 <string>Remove Server</string>
270 <property name="sizePolicy"> 318 </property>
271 <sizepolicy hsizetype="Maximum" vsizetype="Fixed"> 319 </widget>
272 <horstretch>0</horstretch> 320 </item>
273 <verstretch>0</verstretch> 321 <item>
274 </sizepolicy> 322 <spacer name="horizontalSpacer_2">
275 </property> 323 <property name="orientation">
276 <property name="text"> 324 <enum>Qt::Horizontal</enum>
277 <string>Test</string> 325 </property>
278 </property> 326 <property name="sizeHint" stdset="0">
279 </widget> 327 <size>
328 <width>40</width>
329 <height>20</height>
330 </size>
331 </property>
332 </spacer>
333 </item>
334 </layout>
335 </item>
336 </layout>
280 </item> 337 </item>
281 </layout> 338 </layout>
282 </item> 339 </item>
@@ -312,6 +369,16 @@
312 <signal>accepted()</signal> 369 <signal>accepted()</signal>
313 <receiver>ConfigureMotionTouch</receiver> 370 <receiver>ConfigureMotionTouch</receiver>
314 <slot>ApplyConfiguration()</slot> 371 <slot>ApplyConfiguration()</slot>
372 <hints>
373 <hint type="sourcelabel">
374 <x>20</x>
375 <y>20</y>
376 </hint>
377 <hint type="destinationlabel">
378 <x>20</x>
379 <y>20</y>
380 </hint>
381 </hints>
315 </connection> 382 </connection>
316 </connections> 383 </connections>
317</ui> 384</ui>
diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp
index 8eac3bd9d..f598513df 100644
--- a/src/yuzu/configuration/configure_per_game.cpp
+++ b/src/yuzu/configuration/configure_per_game.cpp
@@ -57,7 +57,7 @@ void ConfigurePerGame::ApplyConfiguration() {
57 ui->graphicsAdvancedTab->ApplyConfiguration(); 57 ui->graphicsAdvancedTab->ApplyConfiguration();
58 ui->audioTab->ApplyConfiguration(); 58 ui->audioTab->ApplyConfiguration();
59 59
60 Settings::Apply(); 60 Settings::Apply(Core::System::GetInstance());
61 Settings::LogSettings(); 61 Settings::LogSettings();
62 62
63 game_config->Save(); 63 game_config->Save();
diff --git a/src/yuzu/configuration/configure_profile_manager.cpp b/src/yuzu/configuration/configure_profile_manager.cpp
index 6334c4c50..13d9a4757 100644
--- a/src/yuzu/configuration/configure_profile_manager.cpp
+++ b/src/yuzu/configuration/configure_profile_manager.cpp
@@ -180,7 +180,7 @@ void ConfigureProfileManager::ApplyConfiguration() {
180 return; 180 return;
181 } 181 }
182 182
183 Settings::Apply(); 183 Settings::Apply(Core::System::GetInstance());
184} 184}
185 185
186void ConfigureProfileManager::SelectUser(const QModelIndex& index) { 186void ConfigureProfileManager::SelectUser(const QModelIndex& index) {
diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp
index 59a58d92c..6cf2032da 100644
--- a/src/yuzu/configuration/configure_system.cpp
+++ b/src/yuzu/configuration/configure_system.cpp
@@ -105,16 +105,18 @@ void ConfigureSystem::SetConfiguration() {
105void ConfigureSystem::ReadSystemSettings() {} 105void ConfigureSystem::ReadSystemSettings() {}
106 106
107void ConfigureSystem::ApplyConfiguration() { 107void ConfigureSystem::ApplyConfiguration() {
108 // Allow setting custom RTC even if system is powered on, to allow in-game time to be fast 108 auto& system = Core::System::GetInstance();
109 // forwared 109
110 // Allow setting custom RTC even if system is powered on,
111 // to allow in-game time to be fast forwarded
110 if (Settings::values.custom_rtc.UsingGlobal()) { 112 if (Settings::values.custom_rtc.UsingGlobal()) {
111 if (ui->custom_rtc_checkbox->isChecked()) { 113 if (ui->custom_rtc_checkbox->isChecked()) {
112 Settings::values.custom_rtc.SetValue( 114 Settings::values.custom_rtc.SetValue(
113 std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch())); 115 std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch()));
114 if (Core::System::GetInstance().IsPoweredOn()) { 116 if (system.IsPoweredOn()) {
115 const s64 posix_time{Settings::values.custom_rtc.GetValue()->count() + 117 const s64 posix_time{Settings::values.custom_rtc.GetValue()->count() +
116 Service::Time::TimeManager::GetExternalTimeZoneOffset()}; 118 Service::Time::TimeManager::GetExternalTimeZoneOffset()};
117 Core::System::GetInstance().GetTimeManager().UpdateLocalSystemClockTime(posix_time); 119 system.GetTimeManager().UpdateLocalSystemClockTime(posix_time);
118 } 120 }
119 } else { 121 } else {
120 Settings::values.custom_rtc.SetValue(std::nullopt); 122 Settings::values.custom_rtc.SetValue(std::nullopt);
@@ -197,7 +199,7 @@ void ConfigureSystem::ApplyConfiguration() {
197 } 199 }
198 } 200 }
199 201
200 Settings::Apply(); 202 Settings::Apply(system);
201} 203}
202 204
203void ConfigureSystem::RefreshConsoleID() { 205void ConfigureSystem::RefreshConsoleID() {
diff --git a/src/yuzu/configuration/configure_ui.cpp b/src/yuzu/configuration/configure_ui.cpp
index dbe3f78c8..aed876008 100644
--- a/src/yuzu/configuration/configure_ui.cpp
+++ b/src/yuzu/configuration/configure_ui.cpp
@@ -9,6 +9,7 @@
9#include <QDirIterator> 9#include <QDirIterator>
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "common/file_util.h" 11#include "common/file_util.h"
12#include "core/core.h"
12#include "core/settings.h" 13#include "core/settings.h"
13#include "ui_configure_ui.h" 14#include "ui_configure_ui.h"
14#include "yuzu/configuration/configure_ui.h" 15#include "yuzu/configuration/configure_ui.h"
@@ -84,7 +85,7 @@ void ConfigureUi::ApplyConfiguration() {
84 UISettings::values.enable_screenshot_save_as = ui->enable_screenshot_save_as->isChecked(); 85 UISettings::values.enable_screenshot_save_as = ui->enable_screenshot_save_as->isChecked();
85 Common::FS::GetUserPath(Common::FS::UserPath::ScreenshotsDir, 86 Common::FS::GetUserPath(Common::FS::UserPath::ScreenshotsDir,
86 ui->screenshot_path_edit->text().toStdString()); 87 ui->screenshot_path_edit->text().toStdString());
87 Settings::Apply(); 88 Settings::Apply(Core::System::GetInstance());
88} 89}
89 90
90void ConfigureUi::RequestGameListUpdate() { 91void ConfigureUi::RequestGameListUpdate() {
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 805619ccf..26f5e42ed 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -172,7 +172,7 @@ void GMainWindow::ShowTelemetryCallout() {
172 "<br/><br/>Would you like to share your usage data with us?"); 172 "<br/><br/>Would you like to share your usage data with us?");
173 if (QMessageBox::question(this, tr("Telemetry"), telemetry_message) != QMessageBox::Yes) { 173 if (QMessageBox::question(this, tr("Telemetry"), telemetry_message) != QMessageBox::Yes) {
174 Settings::values.enable_telemetry = false; 174 Settings::values.enable_telemetry = false;
175 Settings::Apply(); 175 Settings::Apply(Core::System::GetInstance());
176 } 176 }
177} 177}
178 178
@@ -302,7 +302,7 @@ void GMainWindow::ControllerSelectorReconfigureControllers(
302 emit ControllerSelectorReconfigureFinished(); 302 emit ControllerSelectorReconfigureFinished();
303 303
304 // Don't forget to apply settings. 304 // Don't forget to apply settings.
305 Settings::Apply(); 305 Settings::Apply(Core::System::GetInstance());
306 config->Save(); 306 config->Save();
307 307
308 UpdateStatusButtons(); 308 UpdateStatusButtons();
@@ -477,11 +477,13 @@ void GMainWindow::WebBrowserOpenPage(std::string_view filename, std::string_view
477#else 477#else
478 478
479void GMainWindow::WebBrowserOpenPage(std::string_view filename, std::string_view additional_args) { 479void GMainWindow::WebBrowserOpenPage(std::string_view filename, std::string_view additional_args) {
480#ifndef __linux__
480 QMessageBox::warning( 481 QMessageBox::warning(
481 this, tr("Web Applet"), 482 this, tr("Web Applet"),
482 tr("This version of yuzu was built without QtWebEngine support, meaning that yuzu cannot " 483 tr("This version of yuzu was built without QtWebEngine support, meaning that yuzu cannot "
483 "properly display the game manual or web page requested."), 484 "properly display the game manual or web page requested."),
484 QMessageBox::Ok, QMessageBox::Ok); 485 QMessageBox::Ok, QMessageBox::Ok);
486#endif
485 487
486 LOG_INFO(Frontend, 488 LOG_INFO(Frontend,
487 "(STUBBED) called - Missing QtWebEngine dependency needed to open website page at " 489 "(STUBBED) called - Missing QtWebEngine dependency needed to open website page at "
@@ -571,11 +573,11 @@ void GMainWindow::InitializeWidgets() {
571 if (emulation_running) { 573 if (emulation_running) {
572 return; 574 return;
573 } 575 }
574 bool is_async = !Settings::values.use_asynchronous_gpu_emulation.GetValue() || 576 const bool is_async = !Settings::values.use_asynchronous_gpu_emulation.GetValue() ||
575 Settings::values.use_multi_core.GetValue(); 577 Settings::values.use_multi_core.GetValue();
576 Settings::values.use_asynchronous_gpu_emulation.SetValue(is_async); 578 Settings::values.use_asynchronous_gpu_emulation.SetValue(is_async);
577 async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation.GetValue()); 579 async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation.GetValue());
578 Settings::Apply(); 580 Settings::Apply(Core::System::GetInstance());
579 }); 581 });
580 async_status_button->setText(tr("ASYNC")); 582 async_status_button->setText(tr("ASYNC"));
581 async_status_button->setCheckable(true); 583 async_status_button->setCheckable(true);
@@ -590,12 +592,12 @@ void GMainWindow::InitializeWidgets() {
590 return; 592 return;
591 } 593 }
592 Settings::values.use_multi_core.SetValue(!Settings::values.use_multi_core.GetValue()); 594 Settings::values.use_multi_core.SetValue(!Settings::values.use_multi_core.GetValue());
593 bool is_async = Settings::values.use_asynchronous_gpu_emulation.GetValue() || 595 const bool is_async = Settings::values.use_asynchronous_gpu_emulation.GetValue() ||
594 Settings::values.use_multi_core.GetValue(); 596 Settings::values.use_multi_core.GetValue();
595 Settings::values.use_asynchronous_gpu_emulation.SetValue(is_async); 597 Settings::values.use_asynchronous_gpu_emulation.SetValue(is_async);
596 async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation.GetValue()); 598 async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation.GetValue());
597 multicore_status_button->setChecked(Settings::values.use_multi_core.GetValue()); 599 multicore_status_button->setChecked(Settings::values.use_multi_core.GetValue());
598 Settings::Apply(); 600 Settings::Apply(Core::System::GetInstance());
599 }); 601 });
600 multicore_status_button->setText(tr("MULTICORE")); 602 multicore_status_button->setText(tr("MULTICORE"));
601 multicore_status_button->setCheckable(true); 603 multicore_status_button->setCheckable(true);
@@ -630,7 +632,7 @@ void GMainWindow::InitializeWidgets() {
630 Settings::values.renderer_backend.SetValue(Settings::RendererBackend::OpenGL); 632 Settings::values.renderer_backend.SetValue(Settings::RendererBackend::OpenGL);
631 } 633 }
632 634
633 Settings::Apply(); 635 Settings::Apply(Core::System::GetInstance());
634 }); 636 });
635#endif // HAS_VULKAN 637#endif // HAS_VULKAN
636 statusBar()->insertPermanentWidget(0, renderer_status_button); 638 statusBar()->insertPermanentWidget(0, renderer_status_button);
@@ -1342,12 +1344,12 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
1342 const auto user_id = manager.GetUser(static_cast<std::size_t>(index)); 1344 const auto user_id = manager.GetUser(static_cast<std::size_t>(index));
1343 ASSERT(user_id); 1345 ASSERT(user_id);
1344 path = nand_dir + FileSys::SaveDataFactory::GetFullPath( 1346 path = nand_dir + FileSys::SaveDataFactory::GetFullPath(
1345 FileSys::SaveDataSpaceId::NandUser, 1347 system, FileSys::SaveDataSpaceId::NandUser,
1346 FileSys::SaveDataType::SaveData, program_id, user_id->uuid, 0); 1348 FileSys::SaveDataType::SaveData, program_id, user_id->uuid, 0);
1347 } else { 1349 } else {
1348 // Device save data 1350 // Device save data
1349 path = nand_dir + FileSys::SaveDataFactory::GetFullPath( 1351 path = nand_dir + FileSys::SaveDataFactory::GetFullPath(
1350 FileSys::SaveDataSpaceId::NandUser, 1352 system, FileSys::SaveDataSpaceId::NandUser,
1351 FileSys::SaveDataType::SaveData, program_id, {}, 0); 1353 FileSys::SaveDataType::SaveData, program_id, {}, 0);
1352 } 1354 }
1353 1355
@@ -2130,14 +2132,14 @@ void GMainWindow::OnPauseGame() {
2130} 2132}
2131 2133
2132void GMainWindow::OnStopGame() { 2134void GMainWindow::OnStopGame() {
2133 Core::System& system{Core::System::GetInstance()}; 2135 auto& system{Core::System::GetInstance()};
2134 if (system.GetExitLock() && !ConfirmForceLockedExit()) { 2136 if (system.GetExitLock() && !ConfirmForceLockedExit()) {
2135 return; 2137 return;
2136 } 2138 }
2137 2139
2138 ShutdownGame(); 2140 ShutdownGame();
2139 2141
2140 Settings::RestoreGlobalState(); 2142 Settings::RestoreGlobalState(system.IsPoweredOn());
2141 UpdateStatusButtons(); 2143 UpdateStatusButtons();
2142} 2144}
2143 2145
@@ -2312,10 +2314,11 @@ void GMainWindow::OnConfigurePerGame() {
2312 2314
2313void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file_name) { 2315void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file_name) {
2314 const auto v_file = Core::GetGameFileFromPath(vfs, file_name); 2316 const auto v_file = Core::GetGameFileFromPath(vfs, file_name);
2317 const auto& system = Core::System::GetInstance();
2315 2318
2316 ConfigurePerGame dialog(this, title_id); 2319 ConfigurePerGame dialog(this, title_id);
2317 dialog.LoadFromFile(v_file); 2320 dialog.LoadFromFile(v_file);
2318 auto result = dialog.exec(); 2321 const auto result = dialog.exec();
2319 if (result == QDialog::Accepted) { 2322 if (result == QDialog::Accepted) {
2320 dialog.ApplyConfiguration(); 2323 dialog.ApplyConfiguration();
2321 2324
@@ -2325,13 +2328,14 @@ void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file
2325 } 2328 }
2326 2329
2327 // Do not cause the global config to write local settings into the config file 2330 // Do not cause the global config to write local settings into the config file
2328 Settings::RestoreGlobalState(); 2331 const bool is_powered_on = system.IsPoweredOn();
2332 Settings::RestoreGlobalState(is_powered_on);
2329 2333
2330 if (!Core::System::GetInstance().IsPoweredOn()) { 2334 if (!is_powered_on) {
2331 config->Save(); 2335 config->Save();
2332 } 2336 }
2333 } else { 2337 } else {
2334 Settings::RestoreGlobalState(); 2338 Settings::RestoreGlobalState(system.IsPoweredOn());
2335 } 2339 }
2336} 2340}
2337 2341
@@ -2602,7 +2606,7 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det
2602 if (emu_thread) { 2606 if (emu_thread) {
2603 ShutdownGame(); 2607 ShutdownGame();
2604 2608
2605 Settings::RestoreGlobalState(); 2609 Settings::RestoreGlobalState(Core::System::GetInstance().IsPoweredOn());
2606 UpdateStatusButtons(); 2610 UpdateStatusButtons();
2607 } 2611 }
2608 } else { 2612 } else {
@@ -2774,7 +2778,7 @@ void GMainWindow::closeEvent(QCloseEvent* event) {
2774 if (emu_thread != nullptr) { 2778 if (emu_thread != nullptr) {
2775 ShutdownGame(); 2779 ShutdownGame();
2776 2780
2777 Settings::RestoreGlobalState(); 2781 Settings::RestoreGlobalState(Core::System::GetInstance().IsPoweredOn());
2778 UpdateStatusButtons(); 2782 UpdateStatusButtons();
2779 } 2783 }
2780 2784
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index e1adbbf2b..34c9673bc 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -306,10 +306,8 @@ void Config::ReadValues() {
306 sdl2_config->GetInteger("ControlsGeneral", "touch_diameter_x", 15); 306 sdl2_config->GetInteger("ControlsGeneral", "touch_diameter_x", 15);
307 Settings::values.touchscreen.diameter_y = 307 Settings::values.touchscreen.diameter_y =
308 sdl2_config->GetInteger("ControlsGeneral", "touch_diameter_y", 15); 308 sdl2_config->GetInteger("ControlsGeneral", "touch_diameter_y", 15);
309 Settings::values.udp_input_address = 309 Settings::values.udp_input_servers =
310 sdl2_config->Get("Controls", "udp_input_address", InputCommon::CemuhookUDP::DEFAULT_ADDR); 310 sdl2_config->Get("Controls", "udp_input_address", InputCommon::CemuhookUDP::DEFAULT_SRV);
311 Settings::values.udp_input_port = static_cast<u16>(sdl2_config->GetInteger(
312 "Controls", "udp_input_port", InputCommon::CemuhookUDP::DEFAULT_PORT));
313 311
314 std::transform(keyboard_keys.begin(), keyboard_keys.end(), 312 std::transform(keyboard_keys.begin(), keyboard_keys.end(),
315 Settings::values.keyboard_keys.begin(), InputCommon::GenerateKeyboardParam); 313 Settings::values.keyboard_keys.begin(), InputCommon::GenerateKeyboardParam);
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
index 521209622..e32bed5e6 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
@@ -9,7 +9,7 @@
9#include "core/perf_stats.h" 9#include "core/perf_stats.h"
10#include "input_common/keyboard.h" 10#include "input_common/keyboard.h"
11#include "input_common/main.h" 11#include "input_common/main.h"
12#include "input_common/motion_emu.h" 12#include "input_common/mouse/mouse_input.h"
13#include "input_common/sdl/sdl.h" 13#include "input_common/sdl/sdl.h"
14#include "yuzu_cmd/emu_window/emu_window_sdl2.h" 14#include "yuzu_cmd/emu_window/emu_window_sdl2.h"
15 15
@@ -30,7 +30,7 @@ EmuWindow_SDL2::~EmuWindow_SDL2() {
30 30
31void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) { 31void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) {
32 TouchMoved((unsigned)std::max(x, 0), (unsigned)std::max(y, 0)); 32 TouchMoved((unsigned)std::max(x, 0), (unsigned)std::max(y, 0));
33 input_subsystem->GetMotionEmu()->Tilt(x, y); 33 input_subsystem->GetMouse()->MouseMove(x, y);
34} 34}
35 35
36void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) { 36void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) {
@@ -42,9 +42,9 @@ void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) {
42 } 42 }
43 } else if (button == SDL_BUTTON_RIGHT) { 43 } else if (button == SDL_BUTTON_RIGHT) {
44 if (state == SDL_PRESSED) { 44 if (state == SDL_PRESSED) {
45 input_subsystem->GetMotionEmu()->BeginTilt(x, y); 45 input_subsystem->GetMouse()->PressButton(x, y, button);
46 } else { 46 } else {
47 input_subsystem->GetMotionEmu()->EndTilt(); 47 input_subsystem->GetMouse()->ReleaseButton(button);
48 } 48 }
49 } 49 }
50} 50}
@@ -121,62 +121,64 @@ void EmuWindow_SDL2::Fullscreen() {
121 SDL_MaximizeWindow(render_window); 121 SDL_MaximizeWindow(render_window);
122} 122}
123 123
124void EmuWindow_SDL2::PollEvents() { 124void EmuWindow_SDL2::WaitEvent() {
125 // Called on main thread
125 SDL_Event event; 126 SDL_Event event;
126 127
127 // SDL_PollEvent returns 0 when there are no more events in the event queue 128 if (!SDL_WaitEvent(&event)) {
128 while (SDL_PollEvent(&event)) { 129 LOG_CRITICAL(Frontend, "SDL_WaitEvent failed: {}", SDL_GetError());
129 switch (event.type) { 130 exit(1);
130 case SDL_WINDOWEVENT: 131 }
131 switch (event.window.event) { 132
132 case SDL_WINDOWEVENT_SIZE_CHANGED: 133 switch (event.type) {
133 case SDL_WINDOWEVENT_RESIZED: 134 case SDL_WINDOWEVENT:
134 case SDL_WINDOWEVENT_MAXIMIZED: 135 switch (event.window.event) {
135 case SDL_WINDOWEVENT_RESTORED: 136 case SDL_WINDOWEVENT_SIZE_CHANGED:
136 OnResize(); 137 case SDL_WINDOWEVENT_RESIZED:
137 break; 138 case SDL_WINDOWEVENT_MAXIMIZED:
138 case SDL_WINDOWEVENT_MINIMIZED: 139 case SDL_WINDOWEVENT_RESTORED:
139 case SDL_WINDOWEVENT_EXPOSED: 140 OnResize();
140 is_shown = event.window.event == SDL_WINDOWEVENT_EXPOSED;
141 OnResize();
142 break;
143 case SDL_WINDOWEVENT_CLOSE:
144 is_open = false;
145 break;
146 }
147 break;
148 case SDL_KEYDOWN:
149 case SDL_KEYUP:
150 OnKeyEvent(static_cast<int>(event.key.keysym.scancode), event.key.state);
151 break;
152 case SDL_MOUSEMOTION:
153 // ignore if it came from touch
154 if (event.button.which != SDL_TOUCH_MOUSEID)
155 OnMouseMotion(event.motion.x, event.motion.y);
156 break;
157 case SDL_MOUSEBUTTONDOWN:
158 case SDL_MOUSEBUTTONUP:
159 // ignore if it came from touch
160 if (event.button.which != SDL_TOUCH_MOUSEID) {
161 OnMouseButton(event.button.button, event.button.state, event.button.x,
162 event.button.y);
163 }
164 break;
165 case SDL_FINGERDOWN:
166 OnFingerDown(event.tfinger.x, event.tfinger.y);
167 break;
168 case SDL_FINGERMOTION:
169 OnFingerMotion(event.tfinger.x, event.tfinger.y);
170 break; 141 break;
171 case SDL_FINGERUP: 142 case SDL_WINDOWEVENT_MINIMIZED:
172 OnFingerUp(); 143 case SDL_WINDOWEVENT_EXPOSED:
144 is_shown = event.window.event == SDL_WINDOWEVENT_EXPOSED;
145 OnResize();
173 break; 146 break;
174 case SDL_QUIT: 147 case SDL_WINDOWEVENT_CLOSE:
175 is_open = false; 148 is_open = false;
176 break; 149 break;
177 default:
178 break;
179 } 150 }
151 break;
152 case SDL_KEYDOWN:
153 case SDL_KEYUP:
154 OnKeyEvent(static_cast<int>(event.key.keysym.scancode), event.key.state);
155 break;
156 case SDL_MOUSEMOTION:
157 // ignore if it came from touch
158 if (event.button.which != SDL_TOUCH_MOUSEID)
159 OnMouseMotion(event.motion.x, event.motion.y);
160 break;
161 case SDL_MOUSEBUTTONDOWN:
162 case SDL_MOUSEBUTTONUP:
163 // ignore if it came from touch
164 if (event.button.which != SDL_TOUCH_MOUSEID) {
165 OnMouseButton(event.button.button, event.button.state, event.button.x, event.button.y);
166 }
167 break;
168 case SDL_FINGERDOWN:
169 OnFingerDown(event.tfinger.x, event.tfinger.y);
170 break;
171 case SDL_FINGERMOTION:
172 OnFingerMotion(event.tfinger.x, event.tfinger.y);
173 break;
174 case SDL_FINGERUP:
175 OnFingerUp();
176 break;
177 case SDL_QUIT:
178 is_open = false;
179 break;
180 default:
181 break;
180 } 182 }
181 183
182 const u32 current_time = SDL_GetTicks(); 184 const u32 current_time = SDL_GetTicks();
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.h b/src/yuzu_cmd/emu_window/emu_window_sdl2.h
index 53d756c3c..a93141240 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2.h
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.h
@@ -23,38 +23,38 @@ public:
23 explicit EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem); 23 explicit EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem);
24 ~EmuWindow_SDL2(); 24 ~EmuWindow_SDL2();
25 25
26 /// Polls window events
27 void PollEvents() override;
28
29 /// Whether the window is still open, and a close request hasn't yet been sent 26 /// Whether the window is still open, and a close request hasn't yet been sent
30 bool IsOpen() const; 27 bool IsOpen() const;
31 28
32 /// Returns if window is shown (not minimized) 29 /// Returns if window is shown (not minimized)
33 bool IsShown() const override; 30 bool IsShown() const override;
34 31
32 /// Wait for the next event on the main thread.
33 void WaitEvent();
34
35protected: 35protected:
36 /// Called by PollEvents when a key is pressed or released. 36 /// Called by WaitEvent when a key is pressed or released.
37 void OnKeyEvent(int key, u8 state); 37 void OnKeyEvent(int key, u8 state);
38 38
39 /// Called by PollEvents when the mouse moves. 39 /// Called by WaitEvent when the mouse moves.
40 void OnMouseMotion(s32 x, s32 y); 40 void OnMouseMotion(s32 x, s32 y);
41 41
42 /// Called by PollEvents when a mouse button is pressed or released 42 /// Called by WaitEvent when a mouse button is pressed or released
43 void OnMouseButton(u32 button, u8 state, s32 x, s32 y); 43 void OnMouseButton(u32 button, u8 state, s32 x, s32 y);
44 44
45 /// Translates pixel position (0..1) to pixel positions 45 /// Translates pixel position (0..1) to pixel positions
46 std::pair<unsigned, unsigned> TouchToPixelPos(float touch_x, float touch_y) const; 46 std::pair<unsigned, unsigned> TouchToPixelPos(float touch_x, float touch_y) const;
47 47
48 /// Called by PollEvents when a finger starts touching the touchscreen 48 /// Called by WaitEvent when a finger starts touching the touchscreen
49 void OnFingerDown(float x, float y); 49 void OnFingerDown(float x, float y);
50 50
51 /// Called by PollEvents when a finger moves while touching the touchscreen 51 /// Called by WaitEvent when a finger moves while touching the touchscreen
52 void OnFingerMotion(float x, float y); 52 void OnFingerMotion(float x, float y);
53 53
54 /// Called by PollEvents when a finger stops touching the touchscreen 54 /// Called by WaitEvent when a finger stops touching the touchscreen
55 void OnFingerUp(); 55 void OnFingerUp();
56 56
57 /// Called by PollEvents when any event that may cause the window to be resized occurs 57 /// Called by WaitEvent when any event that may cause the window to be resized occurs
58 void OnResize(); 58 void OnResize();
59 59
60 /// Called when user passes the fullscreen parameter flag 60 /// Called when user passes the fullscreen parameter flag
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp
index 5f35233b5..a103b04bd 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp
@@ -17,7 +17,6 @@
17#include "core/settings.h" 17#include "core/settings.h"
18#include "input_common/keyboard.h" 18#include "input_common/keyboard.h"
19#include "input_common/main.h" 19#include "input_common/main.h"
20#include "input_common/motion_emu.h"
21#include "video_core/renderer_base.h" 20#include "video_core/renderer_base.h"
22#include "yuzu_cmd/emu_window/emu_window_sdl2_gl.h" 21#include "yuzu_cmd/emu_window/emu_window_sdl2_gl.h"
23 22
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp
index 14a23c71b..c2efe1ee6 100644
--- a/src/yuzu_cmd/yuzu.cpp
+++ b/src/yuzu_cmd/yuzu.cpp
@@ -25,7 +25,6 @@
25#include "core/crypto/key_manager.h" 25#include "core/crypto/key_manager.h"
26#include "core/file_sys/registered_cache.h" 26#include "core/file_sys/registered_cache.h"
27#include "core/file_sys/vfs_real.h" 27#include "core/file_sys/vfs_real.h"
28#include "core/gdbstub/gdbstub.h"
29#include "core/hle/kernel/process.h" 28#include "core/hle/kernel/process.h"
30#include "core/hle/service/filesystem/filesystem.h" 29#include "core/hle/service/filesystem/filesystem.h"
31#include "core/loader/loader.h" 30#include "core/loader/loader.h"
@@ -174,13 +173,13 @@ int main(int argc, char** argv) {
174 return -1; 173 return -1;
175 } 174 }
176 175
176 auto& system{Core::System::GetInstance()};
177 InputCommon::InputSubsystem input_subsystem;
178
177 // Apply the command line arguments 179 // Apply the command line arguments
178 Settings::values.gdbstub_port = gdb_port; 180 Settings::values.gdbstub_port = gdb_port;
179 Settings::values.use_gdbstub = use_gdbstub; 181 Settings::values.use_gdbstub = use_gdbstub;
180 Settings::Apply(); 182 Settings::Apply(system);
181
182 Core::System& system{Core::System::GetInstance()};
183 InputCommon::InputSubsystem input_subsystem;
184 183
185 std::unique_ptr<EmuWindow_SDL2> emu_window; 184 std::unique_ptr<EmuWindow_SDL2> emu_window;
186 switch (Settings::values.renderer_backend.GetValue()) { 185 switch (Settings::values.renderer_backend.GetValue()) {
@@ -242,7 +241,7 @@ int main(int argc, char** argv) {
242 241
243 void(system.Run()); 242 void(system.Run());
244 while (emu_window->IsOpen()) { 243 while (emu_window->IsOpen()) {
245 std::this_thread::sleep_for(std::chrono::milliseconds(1)); 244 emu_window->WaitEvent();
246 } 245 }
247 void(system.Pause()); 246 void(system.Pause());
248 system.Shutdown(); 247 system.Shutdown();
diff --git a/src/yuzu_tester/emu_window/emu_window_sdl2_hide.cpp b/src/yuzu_tester/emu_window/emu_window_sdl2_hide.cpp
index 78f75fb38..358e03870 100644
--- a/src/yuzu_tester/emu_window/emu_window_sdl2_hide.cpp
+++ b/src/yuzu_tester/emu_window/emu_window_sdl2_hide.cpp
@@ -109,8 +109,6 @@ EmuWindow_SDL2_Hide::~EmuWindow_SDL2_Hide() {
109 SDL_Quit(); 109 SDL_Quit();
110} 110}
111 111
112void EmuWindow_SDL2_Hide::PollEvents() {}
113
114bool EmuWindow_SDL2_Hide::IsShown() const { 112bool EmuWindow_SDL2_Hide::IsShown() const {
115 return false; 113 return false;
116} 114}
diff --git a/src/yuzu_tester/emu_window/emu_window_sdl2_hide.h b/src/yuzu_tester/emu_window/emu_window_sdl2_hide.h
index a553b4b95..adccdf35e 100644
--- a/src/yuzu_tester/emu_window/emu_window_sdl2_hide.h
+++ b/src/yuzu_tester/emu_window/emu_window_sdl2_hide.h
@@ -17,9 +17,6 @@ public:
17 explicit EmuWindow_SDL2_Hide(); 17 explicit EmuWindow_SDL2_Hide();
18 ~EmuWindow_SDL2_Hide(); 18 ~EmuWindow_SDL2_Hide();
19 19
20 /// Polls window events
21 void PollEvents() override;
22
23 /// Whether the screen is being shown or not. 20 /// Whether the screen is being shown or not.
24 bool IsShown() const override; 21 bool IsShown() const override;
25 22
diff --git a/src/yuzu_tester/service/yuzutest.cpp b/src/yuzu_tester/service/yuzutest.cpp
index 2d3f6e3a7..e257fae25 100644
--- a/src/yuzu_tester/service/yuzutest.cpp
+++ b/src/yuzu_tester/service/yuzutest.cpp
@@ -4,6 +4,7 @@
4 4
5#include <memory> 5#include <memory>
6#include "common/string_util.h" 6#include "common/string_util.h"
7#include "core/core.h"
7#include "core/hle/ipc_helpers.h" 8#include "core/hle/ipc_helpers.h"
8#include "core/hle/service/service.h" 9#include "core/hle/service/service.h"
9#include "core/hle/service/sm/sm.h" 10#include "core/hle/service/sm/sm.h"
@@ -15,10 +16,10 @@ constexpr u64 SERVICE_VERSION = 0x00000002;
15 16
16class YuzuTest final : public ServiceFramework<YuzuTest> { 17class YuzuTest final : public ServiceFramework<YuzuTest> {
17public: 18public:
18 explicit YuzuTest(std::string data, 19 explicit YuzuTest(Core::System& system_, std::string data_,
19 std::function<void(std::vector<TestResult>)> finish_callback) 20 std::function<void(std::vector<TestResult>)> finish_callback_)
20 : ServiceFramework{"yuzutest"}, data(std::move(data)), 21 : ServiceFramework{system_, "yuzutest"}, data{std::move(data_)}, finish_callback{std::move(
21 finish_callback(std::move(finish_callback)) { 22 finish_callback_)} {
22 static const FunctionInfo functions[] = { 23 static const FunctionInfo functions[] = {
23 {0, &YuzuTest::Initialize, "Initialize"}, 24 {0, &YuzuTest::Initialize, "Initialize"},
24 {1, &YuzuTest::GetServiceVersion, "GetServiceVersion"}, 25 {1, &YuzuTest::GetServiceVersion, "GetServiceVersion"},
@@ -104,9 +105,11 @@ private:
104 std::function<void(std::vector<TestResult>)> finish_callback; 105 std::function<void(std::vector<TestResult>)> finish_callback;
105}; 106};
106 107
107void InstallInterfaces(SM::ServiceManager& sm, std::string data, 108void InstallInterfaces(Core::System& system, std::string data,
108 std::function<void(std::vector<TestResult>)> finish_callback) { 109 std::function<void(std::vector<TestResult>)> finish_callback) {
109 std::make_shared<YuzuTest>(data, finish_callback)->InstallAsService(sm); 110 auto& sm = system.ServiceManager();
111 std::make_shared<YuzuTest>(system, std::move(data), std::move(finish_callback))
112 ->InstallAsService(sm);
110} 113}
111 114
112} // namespace Service::Yuzu 115} // namespace Service::Yuzu
diff --git a/src/yuzu_tester/service/yuzutest.h b/src/yuzu_tester/service/yuzutest.h
index eca129c8c..7794814fa 100644
--- a/src/yuzu_tester/service/yuzutest.h
+++ b/src/yuzu_tester/service/yuzutest.h
@@ -7,8 +7,8 @@
7#include <functional> 7#include <functional>
8#include <string> 8#include <string>
9 9
10namespace Service::SM { 10namespace Core {
11class ServiceManager; 11class System;
12} 12}
13 13
14namespace Service::Yuzu { 14namespace Service::Yuzu {
@@ -19,7 +19,7 @@ struct TestResult {
19 std::string name; 19 std::string name;
20}; 20};
21 21
22void InstallInterfaces(SM::ServiceManager& sm, std::string data, 22void InstallInterfaces(Core::System& system, std::string data,
23 std::function<void(std::vector<TestResult>)> finish_callback); 23 std::function<void(std::vector<TestResult>)> finish_callback);
24 24
25} // namespace Service::Yuzu 25} // namespace Service::Yuzu
diff --git a/src/yuzu_tester/yuzu.cpp b/src/yuzu_tester/yuzu.cpp
index 88e4bd1f7..50bd7ae41 100644
--- a/src/yuzu_tester/yuzu.cpp
+++ b/src/yuzu_tester/yuzu.cpp
@@ -160,10 +160,12 @@ int main(int argc, char** argv) {
160 return -1; 160 return -1;
161 } 161 }
162 162
163 Core::System& system{Core::System::GetInstance()};
164
163 Settings::values.use_gdbstub = false; 165 Settings::values.use_gdbstub = false;
164 Settings::Apply(); 166 Settings::Apply(system);
165 167
166 std::unique_ptr<EmuWindow_SDL2_Hide> emu_window{std::make_unique<EmuWindow_SDL2_Hide>()}; 168 const auto emu_window{std::make_unique<EmuWindow_SDL2_Hide>()};
167 169
168 bool finished = false; 170 bool finished = false;
169 int return_value = 0; 171 int return_value = 0;
@@ -212,7 +214,6 @@ int main(int argc, char** argv) {
212 return_value = -1; 214 return_value = -1;
213 }; 215 };
214 216
215 Core::System& system{Core::System::GetInstance()};
216 system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>()); 217 system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
217 system.SetFilesystem(std::make_shared<FileSys::RealVfsFilesystem>()); 218 system.SetFilesystem(std::make_shared<FileSys::RealVfsFilesystem>());
218 system.GetFileSystemController().CreateFactories(*system.GetFilesystem()); 219 system.GetFileSystemController().CreateFactories(*system.GetFilesystem());
@@ -247,9 +248,10 @@ int main(int argc, char** argv) {
247 "additional help.\n\nError Code: {:04X}-{:04X}\nError Description: {}", 248 "additional help.\n\nError Code: {:04X}-{:04X}\nError Description: {}",
248 loader_id, error_id, static_cast<Loader::ResultStatus>(error_id)); 249 loader_id, error_id, static_cast<Loader::ResultStatus>(error_id));
249 } 250 }
251 break;
250 } 252 }
251 253
252 Service::Yuzu::InstallInterfaces(system.ServiceManager(), datastring, callback); 254 Service::Yuzu::InstallInterfaces(system, datastring, callback);
253 255
254 system.TelemetrySession().AddField(Common::Telemetry::FieldType::App, "Frontend", 256 system.TelemetrySession().AddField(Common::Telemetry::FieldType::App, "Frontend",
255 "SDLHideTester"); 257 "SDLHideTester");