summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/audio_core/audio_out.cpp2
-rw-r--r--src/audio_core/audio_out.h2
-rw-r--r--src/audio_core/sink_details.h13
-rw-r--r--src/common/logging/backend.cpp5
-rw-r--r--src/common/logging/log.h5
-rw-r--r--src/common/math_util.h10
-rw-r--r--src/core/CMakeLists.txt22
-rw-r--r--src/core/core.cpp12
-rw-r--r--src/core/core.h13
-rw-r--r--src/core/core_cpu.cpp1
-rw-r--r--src/core/file_sys/vfs_vector.cpp9
-rw-r--r--src/core/gdbstub/gdbstub.cpp1
-rw-r--r--src/core/hle/ipc_helpers.h7
-rw-r--r--src/core/hle/kernel/address_arbiter.cpp2
-rw-r--r--src/core/hle/kernel/client_port.cpp2
-rw-r--r--src/core/hle/kernel/client_port.h2
-rw-r--r--src/core/hle/kernel/client_session.h2
-rw-r--r--src/core/hle/kernel/event.cpp2
-rw-r--r--src/core/hle/kernel/event.h2
-rw-r--r--src/core/hle/kernel/handle_table.cpp1
-rw-r--r--src/core/hle/kernel/handle_table.h2
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp6
-rw-r--r--src/core/hle/kernel/hle_ipc.h2
-rw-r--r--src/core/hle/kernel/kernel.cpp6
-rw-r--r--src/core/hle/kernel/kernel.h112
-rw-r--r--src/core/hle/kernel/memory.cpp90
-rw-r--r--src/core/hle/kernel/memory.h34
-rw-r--r--src/core/hle/kernel/mutex.cpp2
-rw-r--r--src/core/hle/kernel/mutex.h2
-rw-r--r--src/core/hle/kernel/object.cpp35
-rw-r--r--src/core/hle/kernel/object.h100
-rw-r--r--src/core/hle/kernel/process.cpp84
-rw-r--r--src/core/hle/kernel/process.h64
-rw-r--r--src/core/hle/kernel/resource_limit.h2
-rw-r--r--src/core/hle/kernel/scheduler.h1
-rw-r--r--src/core/hle/kernel/server_port.cpp2
-rw-r--r--src/core/hle/kernel/server_port.h2
-rw-r--r--src/core/hle/kernel/server_session.h2
-rw-r--r--src/core/hle/kernel/session.h2
-rw-r--r--src/core/hle/kernel/shared_memory.cpp35
-rw-r--r--src/core/hle/kernel/shared_memory.h5
-rw-r--r--src/core/hle/kernel/svc.cpp2
-rw-r--r--src/core/hle/kernel/thread.cpp50
-rw-r--r--src/core/hle/kernel/thread.h10
-rw-r--r--src/core/hle/kernel/timer.cpp2
-rw-r--r--src/core/hle/kernel/timer.h2
-rw-r--r--src/core/hle/kernel/vm_manager.cpp36
-rw-r--r--src/core/hle/kernel/vm_manager.h8
-rw-r--r--src/core/hle/kernel/wait_object.cpp3
-rw-r--r--src/core/hle/kernel/wait_object.h2
-rw-r--r--src/core/hle/service/acc/acc.cpp30
-rw-r--r--src/core/hle/service/am/am.cpp3
-rw-r--r--src/core/hle/service/bpc/bpc.cpp57
-rw-r--r--src/core/hle/service/bpc/bpc.h15
-rw-r--r--src/core/hle/service/caps/caps.cpp152
-rw-r--r--src/core/hle/service/caps/caps.h15
-rw-r--r--src/core/hle/service/filesystem/filesystem.cpp4
-rw-r--r--src/core/hle/service/filesystem/fsp_ldr.cpp24
-rw-r--r--src/core/hle/service/filesystem/fsp_ldr.h16
-rw-r--r--src/core/hle/service/filesystem/fsp_pr.cpp25
-rw-r--r--src/core/hle/service/filesystem/fsp_pr.h16
-rw-r--r--src/core/hle/service/lm/lm.cpp8
-rw-r--r--src/core/hle/service/mig/mig.cpp34
-rw-r--r--src/core/hle/service/mig/mig.h15
-rw-r--r--src/core/hle/service/ns/ns.cpp447
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.cpp5
-rw-r--r--src/core/hle/service/pcv/pcv.cpp84
-rw-r--r--src/core/hle/service/pcv/pcv.h15
-rw-r--r--src/core/hle/service/psc/psc.cpp77
-rw-r--r--src/core/hle/service/psc/psc.h15
-rw-r--r--src/core/hle/service/service.cpp10
-rw-r--r--src/core/hle/service/service.h3
-rw-r--r--src/core/hle/service/set/set.cpp15
-rw-r--r--src/core/hle/service/set/set.h2
-rw-r--r--src/core/hle/service/sm/sm.h8
-rw-r--r--src/core/hw/aes/ccm.cpp28
-rw-r--r--src/core/hw/hw.cpp96
-rw-r--r--src/core/hw/hw.h50
-rw-r--r--src/core/hw/lcd.cpp67
-rw-r--r--src/core/hw/lcd.h86
-rw-r--r--src/core/loader/deconstructed_rom_directory.h2
-rw-r--r--src/core/loader/elf.cpp6
-rw-r--r--src/core/loader/loader.h2
-rw-r--r--src/core/loader/nca.h2
-rw-r--r--src/core/loader/nro.cpp2
-rw-r--r--src/core/loader/nro.h2
-rw-r--r--src/core/loader/nso.cpp2
-rw-r--r--src/core/loader/nso.h2
-rw-r--r--src/core/memory.cpp122
-rw-r--r--src/core/memory.h88
-rw-r--r--src/core/settings.cpp8
-rw-r--r--src/core/settings.h2
-rw-r--r--src/input_common/keyboard.cpp5
-rw-r--r--src/input_common/motion_emu.cpp2
-rw-r--r--src/input_common/sdl/sdl.cpp20
-rw-r--r--src/tests/CMakeLists.txt1
-rw-r--r--src/tests/core/memory/memory.cpp56
-rw-r--r--src/video_core/gpu.cpp1
-rw-r--r--src/video_core/gpu.h1
-rw-r--r--src/video_core/renderer_base.cpp14
-rw-r--r--src/video_core/renderer_base.h15
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp7
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h5
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp9
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h22
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.cpp17
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.h6
-rw-r--r--src/video_core/renderer_opengl/gl_state.h5
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp26
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.h15
-rw-r--r--src/video_core/textures/decoders.cpp4
-rw-r--r--src/video_core/video_core.cpp7
-rw-r--r--src/video_core/video_core.h6
-rw-r--r--src/yuzu/configuration/config.cpp4
-rw-r--r--src/yuzu/configuration/configure_system.cpp8
-rw-r--r--src/yuzu/configuration/configure_system.ui29
-rw-r--r--src/yuzu/debugger/graphics/graphics_breakpoint_observer.cpp6
-rw-r--r--src/yuzu/debugger/graphics/graphics_breakpoint_observer.h8
-rw-r--r--src/yuzu/debugger/graphics/graphics_breakpoints.cpp26
-rw-r--r--src/yuzu/debugger/graphics/graphics_breakpoints.h11
-rw-r--r--src/yuzu/debugger/graphics/graphics_breakpoints_p.h1
-rw-r--r--src/yuzu/debugger/graphics/graphics_surface.cpp34
-rw-r--r--src/yuzu/debugger/graphics/graphics_surface.h9
-rw-r--r--src/yuzu/debugger/wait_tree.h2
-rw-r--r--src/yuzu/main.cpp2
-rw-r--r--src/yuzu_cmd/default_ini.h10
-rw-r--r--src/yuzu_cmd/yuzu.cpp2
128 files changed, 1602 insertions, 1278 deletions
diff --git a/src/audio_core/audio_out.cpp b/src/audio_core/audio_out.cpp
index 0cabaa354..3dfdf61f9 100644
--- a/src/audio_core/audio_out.cpp
+++ b/src/audio_core/audio_out.cpp
@@ -39,7 +39,7 @@ StreamPtr AudioOut::OpenStream(u32 sample_rate, u32 num_channels,
39 sink->AcquireSinkStream(sample_rate, num_channels)); 39 sink->AcquireSinkStream(sample_rate, num_channels));
40} 40}
41 41
42std::vector<u64> AudioOut::GetTagsAndReleaseBuffers(StreamPtr stream, size_t max_count) { 42std::vector<Buffer::Tag> AudioOut::GetTagsAndReleaseBuffers(StreamPtr stream, size_t max_count) {
43 return stream->GetTagsAndReleaseBuffers(max_count); 43 return stream->GetTagsAndReleaseBuffers(max_count);
44} 44}
45 45
diff --git a/src/audio_core/audio_out.h b/src/audio_core/audio_out.h
index 8d9b695d4..95e9b53fe 100644
--- a/src/audio_core/audio_out.h
+++ b/src/audio_core/audio_out.h
@@ -24,7 +24,7 @@ public:
24 Stream::ReleaseCallback&& release_callback); 24 Stream::ReleaseCallback&& release_callback);
25 25
26 /// Returns a vector of recently released buffers specified by tag for the specified stream 26 /// Returns a vector of recently released buffers specified by tag for the specified stream
27 std::vector<u64> GetTagsAndReleaseBuffers(StreamPtr stream, size_t max_count); 27 std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(StreamPtr stream, size_t max_count);
28 28
29 /// Starts an audio stream for playback 29 /// Starts an audio stream for playback
30 void StartStream(StreamPtr stream); 30 void StartStream(StreamPtr stream);
diff --git a/src/audio_core/sink_details.h b/src/audio_core/sink_details.h
index aa8aae1a9..ea666c554 100644
--- a/src/audio_core/sink_details.h
+++ b/src/audio_core/sink_details.h
@@ -6,6 +6,7 @@
6 6
7#include <functional> 7#include <functional>
8#include <memory> 8#include <memory>
9#include <utility>
9#include <vector> 10#include <vector>
10 11
11namespace AudioCore { 12namespace AudioCore {
@@ -13,16 +14,18 @@ namespace AudioCore {
13class Sink; 14class Sink;
14 15
15struct SinkDetails { 16struct SinkDetails {
16 SinkDetails(const char* id_, std::function<std::unique_ptr<Sink>(std::string)> factory_, 17 using FactoryFn = std::function<std::unique_ptr<Sink>(std::string)>;
17 std::function<std::vector<std::string>()> list_devices_) 18 using ListDevicesFn = std::function<std::vector<std::string>()>;
18 : id(id_), factory(factory_), list_devices(list_devices_) {} 19
20 SinkDetails(const char* id_, FactoryFn factory_, ListDevicesFn list_devices_)
21 : id(id_), factory(std::move(factory_)), list_devices(std::move(list_devices_)) {}
19 22
20 /// Name for this sink. 23 /// Name for this sink.
21 const char* id; 24 const char* id;
22 /// A method to call to construct an instance of this type of sink. 25 /// A method to call to construct an instance of this type of sink.
23 std::function<std::unique_ptr<Sink>(std::string device_id)> factory; 26 FactoryFn factory;
24 /// A method to call to list available devices. 27 /// A method to call to list available devices.
25 std::function<std::vector<std::string>()> list_devices; 28 ListDevicesFn list_devices;
26}; 29};
27 30
28extern const std::vector<SinkDetails> g_sink_details; 31extern const std::vector<SinkDetails> g_sink_details;
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index d7d2f9a20..34dec06fe 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -169,7 +169,9 @@ void FileBackend::Write(const Entry& entry) {
169 SUB(Service, AOC) \ 169 SUB(Service, AOC) \
170 SUB(Service, APM) \ 170 SUB(Service, APM) \
171 SUB(Service, BCAT) \ 171 SUB(Service, BCAT) \
172 SUB(Service, BPC) \
172 SUB(Service, BTM) \ 173 SUB(Service, BTM) \
174 SUB(Service, Capture) \
173 SUB(Service, Fatal) \ 175 SUB(Service, Fatal) \
174 SUB(Service, FGM) \ 176 SUB(Service, FGM) \
175 SUB(Service, Friend) \ 177 SUB(Service, Friend) \
@@ -178,6 +180,7 @@ void FileBackend::Write(const Entry& entry) {
178 SUB(Service, LBL) \ 180 SUB(Service, LBL) \
179 SUB(Service, LDN) \ 181 SUB(Service, LDN) \
180 SUB(Service, LM) \ 182 SUB(Service, LM) \
183 SUB(Service, Migration) \
181 SUB(Service, Mii) \ 184 SUB(Service, Mii) \
182 SUB(Service, MM) \ 185 SUB(Service, MM) \
183 SUB(Service, NCM) \ 186 SUB(Service, NCM) \
@@ -188,7 +191,9 @@ void FileBackend::Write(const Entry& entry) {
188 SUB(Service, NVDRV) \ 191 SUB(Service, NVDRV) \
189 SUB(Service, PCIE) \ 192 SUB(Service, PCIE) \
190 SUB(Service, PCTL) \ 193 SUB(Service, PCTL) \
194 SUB(Service, PCV) \
191 SUB(Service, PREPO) \ 195 SUB(Service, PREPO) \
196 SUB(Service, PSC) \
192 SUB(Service, SET) \ 197 SUB(Service, SET) \
193 SUB(Service, SM) \ 198 SUB(Service, SM) \
194 SUB(Service, SPL) \ 199 SUB(Service, SPL) \
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index 5a580b004..dd5c9e6be 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -56,7 +56,9 @@ enum class Class : ClassType {
56 Service_APM, ///< The APM (Performance) service 56 Service_APM, ///< The APM (Performance) service
57 Service_Audio, ///< The Audio (Audio control) service 57 Service_Audio, ///< The Audio (Audio control) service
58 Service_BCAT, ///< The BCAT service 58 Service_BCAT, ///< The BCAT service
59 Service_BPC, ///< The BPC service
59 Service_BTM, ///< The BTM service 60 Service_BTM, ///< The BTM service
61 Service_Capture, ///< The capture service
60 Service_Fatal, ///< The Fatal service 62 Service_Fatal, ///< The Fatal service
61 Service_FGM, ///< The FGM service 63 Service_FGM, ///< The FGM service
62 Service_Friend, ///< The friend service 64 Service_Friend, ///< The friend service
@@ -65,6 +67,7 @@ enum class Class : ClassType {
65 Service_LBL, ///< The LBL (LCD backlight) service 67 Service_LBL, ///< The LBL (LCD backlight) service
66 Service_LDN, ///< The LDN (Local domain network) service 68 Service_LDN, ///< The LDN (Local domain network) service
67 Service_LM, ///< The LM (Logger) service 69 Service_LM, ///< The LM (Logger) service
70 Service_Migration, ///< The migration service
68 Service_Mii, ///< The Mii service 71 Service_Mii, ///< The Mii service
69 Service_MM, ///< The MM (Multimedia) service 72 Service_MM, ///< The MM (Multimedia) service
70 Service_NCM, ///< The NCM service 73 Service_NCM, ///< The NCM service
@@ -75,7 +78,9 @@ enum class Class : ClassType {
75 Service_NVDRV, ///< The NVDRV (Nvidia driver) service 78 Service_NVDRV, ///< The NVDRV (Nvidia driver) service
76 Service_PCIE, ///< The PCIe service 79 Service_PCIE, ///< The PCIe service
77 Service_PCTL, ///< The PCTL (Parental control) service 80 Service_PCTL, ///< The PCTL (Parental control) service
81 Service_PCV, ///< The PCV service
78 Service_PREPO, ///< The PREPO (Play report) service 82 Service_PREPO, ///< The PREPO (Play report) service
83 Service_PSC, ///< The PSC service
79 Service_SET, ///< The SET (Settings) service 84 Service_SET, ///< The SET (Settings) service
80 Service_SM, ///< The SM (Service manager) service 85 Service_SM, ///< The SM (Service manager) service
81 Service_SPL, ///< The SPL service 86 Service_SPL, ///< The SPL service
diff --git a/src/common/math_util.h b/src/common/math_util.h
index c6a83c953..343cdd902 100644
--- a/src/common/math_util.h
+++ b/src/common/math_util.h
@@ -19,12 +19,12 @@ inline bool IntervalsIntersect(unsigned start0, unsigned length0, unsigned start
19 19
20template <class T> 20template <class T>
21struct Rectangle { 21struct Rectangle {
22 T left; 22 T left{};
23 T top; 23 T top{};
24 T right; 24 T right{};
25 T bottom; 25 T bottom{};
26 26
27 Rectangle() {} 27 Rectangle() = default;
28 28
29 Rectangle(T left, T top, T right, T bottom) 29 Rectangle(T left, T top, T right, T bottom)
30 : left(left), top(top), right(right), bottom(bottom) {} 30 : left(left), top(top), right(right), bottom(bottom) {}
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 22fad97a3..28de22398 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -73,10 +73,10 @@ add_library(core STATIC
73 hle/kernel/hle_ipc.h 73 hle/kernel/hle_ipc.h
74 hle/kernel/kernel.cpp 74 hle/kernel/kernel.cpp
75 hle/kernel/kernel.h 75 hle/kernel/kernel.h
76 hle/kernel/memory.cpp
77 hle/kernel/memory.h
78 hle/kernel/mutex.cpp 76 hle/kernel/mutex.cpp
79 hle/kernel/mutex.h 77 hle/kernel/mutex.h
78 hle/kernel/object.cpp
79 hle/kernel/object.h
80 hle/kernel/process.cpp 80 hle/kernel/process.cpp
81 hle/kernel/process.h 81 hle/kernel/process.h
82 hle/kernel/resource_limit.cpp 82 hle/kernel/resource_limit.cpp
@@ -164,10 +164,14 @@ add_library(core STATIC
164 hle/service/bcat/bcat.h 164 hle/service/bcat/bcat.h
165 hle/service/bcat/module.cpp 165 hle/service/bcat/module.cpp
166 hle/service/bcat/module.h 166 hle/service/bcat/module.h
167 hle/service/bpc/bpc.cpp
168 hle/service/bpc/bpc.h
167 hle/service/btdrv/btdrv.cpp 169 hle/service/btdrv/btdrv.cpp
168 hle/service/btdrv/btdrv.h 170 hle/service/btdrv/btdrv.h
169 hle/service/btm/btm.cpp 171 hle/service/btm/btm.cpp
170 hle/service/btm/btm.h 172 hle/service/btm/btm.h
173 hle/service/caps/caps.cpp
174 hle/service/caps/caps.h
171 hle/service/erpt/erpt.cpp 175 hle/service/erpt/erpt.cpp
172 hle/service/erpt/erpt.h 176 hle/service/erpt/erpt.h
173 hle/service/es/es.cpp 177 hle/service/es/es.cpp
@@ -182,6 +186,10 @@ add_library(core STATIC
182 hle/service/fatal/fatal_u.h 186 hle/service/fatal/fatal_u.h
183 hle/service/filesystem/filesystem.cpp 187 hle/service/filesystem/filesystem.cpp
184 hle/service/filesystem/filesystem.h 188 hle/service/filesystem/filesystem.h
189 hle/service/filesystem/fsp_ldr.cpp
190 hle/service/filesystem/fsp_ldr.h
191 hle/service/filesystem/fsp_pr.cpp
192 hle/service/filesystem/fsp_pr.h
185 hle/service/filesystem/fsp_srv.cpp 193 hle/service/filesystem/fsp_srv.cpp
186 hle/service/filesystem/fsp_srv.h 194 hle/service/filesystem/fsp_srv.h
187 hle/service/fgm/fgm.cpp 195 hle/service/fgm/fgm.cpp
@@ -206,6 +214,8 @@ add_library(core STATIC
206 hle/service/ldr/ldr.h 214 hle/service/ldr/ldr.h
207 hle/service/lm/lm.cpp 215 hle/service/lm/lm.cpp
208 hle/service/lm/lm.h 216 hle/service/lm/lm.h
217 hle/service/mig/mig.cpp
218 hle/service/mig/mig.h
209 hle/service/mii/mii.cpp 219 hle/service/mii/mii.cpp
210 hle/service/mii/mii.h 220 hle/service/mii/mii.h
211 hle/service/mm/mm_u.cpp 221 hle/service/mm/mm_u.cpp
@@ -257,10 +267,14 @@ add_library(core STATIC
257 hle/service/pctl/module.h 267 hle/service/pctl/module.h
258 hle/service/pctl/pctl.cpp 268 hle/service/pctl/pctl.cpp
259 hle/service/pctl/pctl.h 269 hle/service/pctl/pctl.h
270 hle/service/pcv/pcv.cpp
271 hle/service/pcv/pcv.h
260 hle/service/pm/pm.cpp 272 hle/service/pm/pm.cpp
261 hle/service/pm/pm.h 273 hle/service/pm/pm.h
262 hle/service/prepo/prepo.cpp 274 hle/service/prepo/prepo.cpp
263 hle/service/prepo/prepo.h 275 hle/service/prepo/prepo.h
276 hle/service/psc/psc.cpp
277 hle/service/psc/psc.h
264 hle/service/service.cpp 278 hle/service/service.cpp
265 hle/service/service.h 279 hle/service/service.h
266 hle/service/set/set.cpp 280 hle/service/set/set.cpp
@@ -309,10 +323,6 @@ add_library(core STATIC
309 hle/service/vi/vi_u.h 323 hle/service/vi/vi_u.h
310 hle/service/wlan/wlan.cpp 324 hle/service/wlan/wlan.cpp
311 hle/service/wlan/wlan.h 325 hle/service/wlan/wlan.h
312 hw/hw.cpp
313 hw/hw.h
314 hw/lcd.cpp
315 hw/lcd.h
316 loader/deconstructed_rom_directory.cpp 326 loader/deconstructed_rom_directory.cpp
317 loader/deconstructed_rom_directory.h 327 loader/deconstructed_rom_directory.h
318 loader/elf.cpp 328 loader/elf.cpp
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 0ef6af3fe..e51e66550 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -15,9 +15,7 @@
15#include "core/hle/service/service.h" 15#include "core/hle/service/service.h"
16#include "core/hle/service/sm/controller.h" 16#include "core/hle/service/sm/controller.h"
17#include "core/hle/service/sm/sm.h" 17#include "core/hle/service/sm/sm.h"
18#include "core/hw/hw.h"
19#include "core/loader/loader.h" 18#include "core/loader/loader.h"
20#include "core/memory_setup.h"
21#include "core/settings.h" 19#include "core/settings.h"
22#include "file_sys/vfs_real.h" 20#include "file_sys/vfs_real.h"
23#include "video_core/video_core.h" 21#include "video_core/video_core.h"
@@ -86,7 +84,7 @@ System::ResultStatus System::SingleStep() {
86 return RunLoop(false); 84 return RunLoop(false);
87} 85}
88 86
89System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& filepath) { 87System::ResultStatus System::Load(EmuWindow& emu_window, const std::string& filepath) {
90 app_loader = Loader::GetLoader(std::make_shared<FileSys::RealVfsFile>(filepath)); 88 app_loader = Loader::GetLoader(std::make_shared<FileSys::RealVfsFile>(filepath));
91 89
92 if (!app_loader) { 90 if (!app_loader) {
@@ -114,7 +112,7 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file
114 } 112 }
115 } 113 }
116 114
117 ResultStatus init_result{Init(emu_window, system_mode.first.get())}; 115 ResultStatus init_result{Init(emu_window)};
118 if (init_result != ResultStatus::Success) { 116 if (init_result != ResultStatus::Success) {
119 LOG_CRITICAL(Core, "Failed to initialize system (Error {})!", 117 LOG_CRITICAL(Core, "Failed to initialize system (Error {})!",
120 static_cast<int>(init_result)); 118 static_cast<int>(init_result));
@@ -167,7 +165,7 @@ Cpu& System::CpuCore(size_t core_index) {
167 return *cpu_cores[core_index]; 165 return *cpu_cores[core_index];
168} 166}
169 167
170System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) { 168System::ResultStatus System::Init(EmuWindow& emu_window) {
171 LOG_DEBUG(HW_Memory, "initialized OK"); 169 LOG_DEBUG(HW_Memory, "initialized OK");
172 170
173 CoreTiming::Init(); 171 CoreTiming::Init();
@@ -184,8 +182,7 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
184 telemetry_session = std::make_unique<Core::TelemetrySession>(); 182 telemetry_session = std::make_unique<Core::TelemetrySession>();
185 service_manager = std::make_shared<Service::SM::ServiceManager>(); 183 service_manager = std::make_shared<Service::SM::ServiceManager>();
186 184
187 HW::Init(); 185 Kernel::Init();
188 Kernel::Init(system_mode);
189 Service::Init(service_manager); 186 Service::Init(service_manager);
190 GDBStub::Init(); 187 GDBStub::Init();
191 188
@@ -228,7 +225,6 @@ void System::Shutdown() {
228 GDBStub::Shutdown(); 225 GDBStub::Shutdown();
229 Service::Shutdown(); 226 Service::Shutdown();
230 Kernel::Shutdown(); 227 Kernel::Shutdown();
231 HW::Shutdown();
232 service_manager.reset(); 228 service_manager.reset();
233 telemetry_session.reset(); 229 telemetry_session.reset();
234 gpu_core.reset(); 230 gpu_core.reset();
diff --git a/src/core/core.h b/src/core/core.h
index a90bff3df..4c9967559 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -11,7 +11,7 @@
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "core/arm/exclusive_monitor.h" 12#include "core/arm/exclusive_monitor.h"
13#include "core/core_cpu.h" 13#include "core/core_cpu.h"
14#include "core/hle/kernel/kernel.h" 14#include "core/hle/kernel/object.h"
15#include "core/hle/kernel/scheduler.h" 15#include "core/hle/kernel/scheduler.h"
16#include "core/loader/loader.h" 16#include "core/loader/loader.h"
17#include "core/memory.h" 17#include "core/memory.h"
@@ -83,11 +83,12 @@ public:
83 83
84 /** 84 /**
85 * Load an executable application. 85 * Load an executable application.
86 * @param emu_window Pointer to the host-system window used for video output and keyboard input. 86 * @param emu_window Reference to the host-system window used for video output and keyboard
87 * input.
87 * @param filepath String path to the executable application to load on the host file system. 88 * @param filepath String path to the executable application to load on the host file system.
88 * @returns ResultStatus code, indicating if the operation succeeded. 89 * @returns ResultStatus code, indicating if the operation succeeded.
89 */ 90 */
90 ResultStatus Load(EmuWindow* emu_window, const std::string& filepath); 91 ResultStatus Load(EmuWindow& emu_window, const std::string& filepath);
91 92
92 /** 93 /**
93 * Indicates if the emulated system is powered on (all subsystems initialized and able to run an 94 * Indicates if the emulated system is powered on (all subsystems initialized and able to run an
@@ -188,11 +189,11 @@ private:
188 189
189 /** 190 /**
190 * Initialize the emulated system. 191 * Initialize the emulated system.
191 * @param emu_window Pointer to the host-system window used for video output and keyboard input. 192 * @param emu_window Reference to the host-system window used for video output and keyboard
192 * @param system_mode The system mode. 193 * input.
193 * @return ResultStatus code, indicating if the operation succeeded. 194 * @return ResultStatus code, indicating if the operation succeeded.
194 */ 195 */
195 ResultStatus Init(EmuWindow* emu_window, u32 system_mode); 196 ResultStatus Init(EmuWindow& emu_window);
196 197
197 /// AppLoader used to load the current executing application 198 /// AppLoader used to load the current executing application
198 std::unique_ptr<Loader::AppLoader> app_loader; 199 std::unique_ptr<Loader::AppLoader> app_loader;
diff --git a/src/core/core_cpu.cpp b/src/core/core_cpu.cpp
index 54e15a701..46a522fcd 100644
--- a/src/core/core_cpu.cpp
+++ b/src/core/core_cpu.cpp
@@ -12,7 +12,6 @@
12#include "core/arm/unicorn/arm_unicorn.h" 12#include "core/arm/unicorn/arm_unicorn.h"
13#include "core/core_cpu.h" 13#include "core/core_cpu.h"
14#include "core/core_timing.h" 14#include "core/core_timing.h"
15#include "core/hle/kernel/kernel.h"
16#include "core/hle/kernel/scheduler.h" 15#include "core/hle/kernel/scheduler.h"
17#include "core/hle/kernel/thread.h" 16#include "core/hle/kernel/thread.h"
18#include "core/settings.h" 17#include "core/settings.h"
diff --git a/src/core/file_sys/vfs_vector.cpp b/src/core/file_sys/vfs_vector.cpp
index 4c6337e3a..fda603960 100644
--- a/src/core/file_sys/vfs_vector.cpp
+++ b/src/core/file_sys/vfs_vector.cpp
@@ -3,6 +3,7 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm> 5#include <algorithm>
6#include <utility>
6#include "core/file_sys/vfs_vector.h" 7#include "core/file_sys/vfs_vector.h"
7 8
8namespace FileSys { 9namespace FileSys {
@@ -31,16 +32,18 @@ bool VectorVfsDirectory::IsReadable() const {
31std::string VectorVfsDirectory::GetName() const { 32std::string VectorVfsDirectory::GetName() const {
32 return name; 33 return name;
33} 34}
35
34std::shared_ptr<VfsDirectory> VectorVfsDirectory::GetParentDirectory() const { 36std::shared_ptr<VfsDirectory> VectorVfsDirectory::GetParentDirectory() const {
35 return parent; 37 return parent;
36} 38}
37 39
38template <typename T> 40template <typename T>
39static bool FindAndRemoveVectorElement(std::vector<T>& vec, std::string_view name) { 41static bool FindAndRemoveVectorElement(std::vector<T>& vec, std::string_view name) {
40 auto iter = std::find_if(vec.begin(), vec.end(), [name](T e) { return e->GetName() == name; }); 42 const auto iter =
43 std::find_if(vec.begin(), vec.end(), [name](const T& e) { return e->GetName() == name; });
41 if (iter == vec.end()) 44 if (iter == vec.end())
42 return false; 45 return false;
43 auto old_size = vec.size(); 46
44 vec.erase(iter); 47 vec.erase(iter);
45 return true; 48 return true;
46} 49}
@@ -77,7 +80,7 @@ void VectorVfsDirectory::AddDirectory(VirtualDir dir) {
77bool VectorVfsDirectory::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) { 80bool VectorVfsDirectory::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) {
78 if (!DeleteFile(file->GetName())) 81 if (!DeleteFile(file->GetName()))
79 return false; 82 return false;
80 dirs.emplace_back(dir); 83 dirs.emplace_back(std::move(dir));
81 return true; 84 return true;
82} 85}
83} // namespace FileSys 86} // namespace FileSys
diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp
index 5ca573652..75f6b8235 100644
--- a/src/core/gdbstub/gdbstub.cpp
+++ b/src/core/gdbstub/gdbstub.cpp
@@ -37,7 +37,6 @@
37#include "core/core.h" 37#include "core/core.h"
38#include "core/core_cpu.h" 38#include "core/core_cpu.h"
39#include "core/gdbstub/gdbstub.h" 39#include "core/gdbstub/gdbstub.h"
40#include "core/hle/kernel/kernel.h"
41#include "core/hle/kernel/scheduler.h" 40#include "core/hle/kernel/scheduler.h"
42#include "core/loader/loader.h" 41#include "core/loader/loader.h"
43#include "core/memory.h" 42#include "core/memory.h"
diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h
index 7fb0da408..d3a734831 100644
--- a/src/core/hle/ipc_helpers.h
+++ b/src/core/hle/ipc_helpers.h
@@ -5,15 +5,18 @@
5#pragma once 5#pragma once
6 6
7#include <array> 7#include <array>
8#include <cstring>
9#include <memory>
8#include <tuple> 10#include <tuple>
9#include <type_traits> 11#include <type_traits>
10#include <utility> 12#include <utility>
13#include "common/assert.h"
14#include "common/common_types.h"
11#include "core/hle/ipc.h" 15#include "core/hle/ipc.h"
12#include "core/hle/kernel/client_port.h" 16#include "core/hle/kernel/client_port.h"
13#include "core/hle/kernel/client_session.h" 17#include "core/hle/kernel/client_session.h"
14#include "core/hle/kernel/handle_table.h"
15#include "core/hle/kernel/hle_ipc.h" 18#include "core/hle/kernel/hle_ipc.h"
16#include "core/hle/kernel/kernel.h" 19#include "core/hle/kernel/object.h"
17#include "core/hle/kernel/server_port.h" 20#include "core/hle/kernel/server_port.h"
18 21
19namespace IPC { 22namespace IPC {
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp
index 6a10efab1..7a17ed162 100644
--- a/src/core/hle/kernel/address_arbiter.cpp
+++ b/src/core/hle/kernel/address_arbiter.cpp
@@ -9,7 +9,7 @@
9#include "common/common_types.h" 9#include "common/common_types.h"
10#include "core/core.h" 10#include "core/core.h"
11#include "core/hle/kernel/errors.h" 11#include "core/hle/kernel/errors.h"
12#include "core/hle/kernel/kernel.h" 12#include "core/hle/kernel/object.h"
13#include "core/hle/kernel/process.h" 13#include "core/hle/kernel/process.h"
14#include "core/hle/kernel/thread.h" 14#include "core/hle/kernel/thread.h"
15#include "core/hle/result.h" 15#include "core/hle/result.h"
diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp
index 2d6051e8b..7933c105c 100644
--- a/src/core/hle/kernel/client_port.cpp
+++ b/src/core/hle/kernel/client_port.cpp
@@ -8,7 +8,7 @@
8#include "core/hle/kernel/client_session.h" 8#include "core/hle/kernel/client_session.h"
9#include "core/hle/kernel/errors.h" 9#include "core/hle/kernel/errors.h"
10#include "core/hle/kernel/hle_ipc.h" 10#include "core/hle/kernel/hle_ipc.h"
11#include "core/hle/kernel/kernel.h" 11#include "core/hle/kernel/object.h"
12#include "core/hle/kernel/server_port.h" 12#include "core/hle/kernel/server_port.h"
13#include "core/hle/kernel/server_session.h" 13#include "core/hle/kernel/server_session.h"
14 14
diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h
index a829aeb6d..b42c94bde 100644
--- a/src/core/hle/kernel/client_port.h
+++ b/src/core/hle/kernel/client_port.h
@@ -6,7 +6,7 @@
6 6
7#include <string> 7#include <string>
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "core/hle/kernel/kernel.h" 9#include "core/hle/kernel/object.h"
10#include "core/hle/result.h" 10#include "core/hle/result.h"
11 11
12namespace Kernel { 12namespace Kernel {
diff --git a/src/core/hle/kernel/client_session.h b/src/core/hle/kernel/client_session.h
index 2258f95bc..dabd93ed7 100644
--- a/src/core/hle/kernel/client_session.h
+++ b/src/core/hle/kernel/client_session.h
@@ -7,7 +7,7 @@
7#include <memory> 7#include <memory>
8#include <string> 8#include <string>
9#include "common/common_types.h" 9#include "common/common_types.h"
10#include "core/hle/kernel/kernel.h" 10#include "core/hle/kernel/object.h"
11#include "core/hle/result.h" 11#include "core/hle/result.h"
12 12
13namespace Kernel { 13namespace Kernel {
diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp
index 37e0766c3..5623c4b6a 100644
--- a/src/core/hle/kernel/event.cpp
+++ b/src/core/hle/kernel/event.cpp
@@ -5,7 +5,7 @@
5#include <algorithm> 5#include <algorithm>
6#include "common/assert.h" 6#include "common/assert.h"
7#include "core/hle/kernel/event.h" 7#include "core/hle/kernel/event.h"
8#include "core/hle/kernel/kernel.h" 8#include "core/hle/kernel/object.h"
9#include "core/hle/kernel/thread.h" 9#include "core/hle/kernel/thread.h"
10 10
11namespace Kernel { 11namespace Kernel {
diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/event.h
index e5c924a75..1c99911b2 100644
--- a/src/core/hle/kernel/event.h
+++ b/src/core/hle/kernel/event.h
@@ -5,7 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "core/hle/kernel/kernel.h" 8#include "core/hle/kernel/object.h"
9#include "core/hle/kernel/wait_object.h" 9#include "core/hle/kernel/wait_object.h"
10 10
11namespace Kernel { 11namespace Kernel {
diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp
index 7dd67f80f..28e21428a 100644
--- a/src/core/hle/kernel/handle_table.cpp
+++ b/src/core/hle/kernel/handle_table.cpp
@@ -8,7 +8,6 @@
8#include "core/core.h" 8#include "core/core.h"
9#include "core/hle/kernel/errors.h" 9#include "core/hle/kernel/errors.h"
10#include "core/hle/kernel/handle_table.h" 10#include "core/hle/kernel/handle_table.h"
11#include "core/hle/kernel/kernel.h"
12#include "core/hle/kernel/process.h" 11#include "core/hle/kernel/process.h"
13#include "core/hle/kernel/thread.h" 12#include "core/hle/kernel/thread.h"
14 13
diff --git a/src/core/hle/kernel/handle_table.h b/src/core/hle/kernel/handle_table.h
index ba968c666..22ddda630 100644
--- a/src/core/hle/kernel/handle_table.h
+++ b/src/core/hle/kernel/handle_table.h
@@ -7,7 +7,7 @@
7#include <array> 7#include <array>
8#include <cstddef> 8#include <cstddef>
9#include "common/common_types.h" 9#include "common/common_types.h"
10#include "core/hle/kernel/kernel.h" 10#include "core/hle/kernel/object.h"
11#include "core/hle/result.h" 11#include "core/hle/result.h"
12 12
13namespace Kernel { 13namespace Kernel {
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index 771d6d476..5dd1b68d7 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -3,17 +3,21 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm> 5#include <algorithm>
6#include <array>
7#include <sstream>
6#include <utility> 8#include <utility>
7 9
8#include <boost/range/algorithm_ext/erase.hpp> 10#include <boost/range/algorithm_ext/erase.hpp>
11
9#include "common/assert.h" 12#include "common/assert.h"
10#include "common/common_funcs.h" 13#include "common/common_funcs.h"
11#include "common/common_types.h" 14#include "common/common_types.h"
15#include "common/logging/log.h"
12#include "core/hle/ipc_helpers.h" 16#include "core/hle/ipc_helpers.h"
13#include "core/hle/kernel/event.h" 17#include "core/hle/kernel/event.h"
14#include "core/hle/kernel/handle_table.h" 18#include "core/hle/kernel/handle_table.h"
15#include "core/hle/kernel/hle_ipc.h" 19#include "core/hle/kernel/hle_ipc.h"
16#include "core/hle/kernel/kernel.h" 20#include "core/hle/kernel/object.h"
17#include "core/hle/kernel/process.h" 21#include "core/hle/kernel/process.h"
18#include "core/hle/kernel/server_session.h" 22#include "core/hle/kernel/server_session.h"
19#include "core/memory.h" 23#include "core/memory.h"
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h
index ee4abebf2..9ce52db24 100644
--- a/src/core/hle/kernel/hle_ipc.h
+++ b/src/core/hle/kernel/hle_ipc.h
@@ -13,7 +13,7 @@
13#include "common/common_types.h" 13#include "common/common_types.h"
14#include "common/swap.h" 14#include "common/swap.h"
15#include "core/hle/ipc.h" 15#include "core/hle/ipc.h"
16#include "core/hle/kernel/kernel.h" 16#include "core/hle/kernel/object.h"
17#include "core/hle/kernel/server_session.h" 17#include "core/hle/kernel/server_session.h"
18#include "core/hle/kernel/thread.h" 18#include "core/hle/kernel/thread.h"
19 19
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 3eb4f465c..1b0cd0abf 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -4,7 +4,6 @@
4 4
5#include "core/hle/kernel/handle_table.h" 5#include "core/hle/kernel/handle_table.h"
6#include "core/hle/kernel/kernel.h" 6#include "core/hle/kernel/kernel.h"
7#include "core/hle/kernel/memory.h"
8#include "core/hle/kernel/process.h" 7#include "core/hle/kernel/process.h"
9#include "core/hle/kernel/resource_limit.h" 8#include "core/hle/kernel/resource_limit.h"
10#include "core/hle/kernel/thread.h" 9#include "core/hle/kernel/thread.h"
@@ -15,9 +14,7 @@ namespace Kernel {
15unsigned int Object::next_object_id; 14unsigned int Object::next_object_id;
16 15
17/// Initialize the kernel 16/// Initialize the kernel
18void Init(u32 system_mode) { 17void Init() {
19 Kernel::MemoryInit(system_mode);
20
21 Kernel::ResourceLimitsInit(); 18 Kernel::ResourceLimitsInit();
22 Kernel::ThreadingInit(); 19 Kernel::ThreadingInit();
23 Kernel::TimersInit(); 20 Kernel::TimersInit();
@@ -37,7 +34,6 @@ void Shutdown() {
37 34
38 Kernel::TimersShutdown(); 35 Kernel::TimersShutdown();
39 Kernel::ResourceLimitsShutdown(); 36 Kernel::ResourceLimitsShutdown();
40 Kernel::MemoryShutdown();
41} 37}
42 38
43} // namespace Kernel 39} // namespace Kernel
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 402ae900f..131311472 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -4,122 +4,12 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <cstddef>
8#include <string>
9#include <utility>
10#include <boost/smart_ptr/intrusive_ptr.hpp>
11#include "common/assert.h"
12#include "common/common_types.h" 7#include "common/common_types.h"
13 8
14namespace Kernel { 9namespace Kernel {
15 10
16using Handle = u32;
17
18enum class HandleType : u32 {
19 Unknown,
20 Event,
21 SharedMemory,
22 Thread,
23 Process,
24 AddressArbiter,
25 Timer,
26 ResourceLimit,
27 CodeSet,
28 ClientPort,
29 ServerPort,
30 ClientSession,
31 ServerSession,
32};
33
34enum class ResetType {
35 OneShot,
36 Sticky,
37 Pulse,
38};
39
40class Object : NonCopyable {
41public:
42 virtual ~Object() {}
43
44 /// Returns a unique identifier for the object. For debugging purposes only.
45 unsigned int GetObjectId() const {
46 return object_id;
47 }
48
49 virtual std::string GetTypeName() const {
50 return "[BAD KERNEL OBJECT TYPE]";
51 }
52 virtual std::string GetName() const {
53 return "[UNKNOWN KERNEL OBJECT]";
54 }
55 virtual Kernel::HandleType GetHandleType() const = 0;
56
57 /**
58 * Check if a thread can wait on the object
59 * @return True if a thread can wait on the object, otherwise false
60 */
61 bool IsWaitable() const {
62 switch (GetHandleType()) {
63 case HandleType::Event:
64 case HandleType::Thread:
65 case HandleType::Timer:
66 case HandleType::ServerPort:
67 case HandleType::ServerSession:
68 return true;
69
70 case HandleType::Unknown:
71 case HandleType::SharedMemory:
72 case HandleType::Process:
73 case HandleType::AddressArbiter:
74 case HandleType::ResourceLimit:
75 case HandleType::CodeSet:
76 case HandleType::ClientPort:
77 case HandleType::ClientSession:
78 return false;
79 }
80
81 UNREACHABLE();
82 }
83
84public:
85 static unsigned int next_object_id;
86
87private:
88 friend void intrusive_ptr_add_ref(Object*);
89 friend void intrusive_ptr_release(Object*);
90
91 unsigned int ref_count = 0;
92 unsigned int object_id = next_object_id++;
93};
94
95// Special functions used by boost::instrusive_ptr to do automatic ref-counting
96inline void intrusive_ptr_add_ref(Object* object) {
97 ++object->ref_count;
98}
99
100inline void intrusive_ptr_release(Object* object) {
101 if (--object->ref_count == 0) {
102 delete object;
103 }
104}
105
106template <typename T>
107using SharedPtr = boost::intrusive_ptr<T>;
108
109/**
110 * Attempts to downcast the given Object pointer to a pointer to T.
111 * @return Derived pointer to the object, or `nullptr` if `object` isn't of type T.
112 */
113template <typename T>
114inline SharedPtr<T> DynamicObjectCast(SharedPtr<Object> object) {
115 if (object != nullptr && object->GetHandleType() == T::HANDLE_TYPE) {
116 return boost::static_pointer_cast<T>(std::move(object));
117 }
118 return nullptr;
119}
120
121/// Initialize the kernel with the specified system mode. 11/// Initialize the kernel with the specified system mode.
122void Init(u32 system_mode); 12void Init();
123 13
124/// Shutdown the kernel 14/// Shutdown the kernel
125void Shutdown(); 15void Shutdown();
diff --git a/src/core/hle/kernel/memory.cpp b/src/core/hle/kernel/memory.cpp
deleted file mode 100644
index a7f3c3c5a..000000000
--- a/src/core/hle/kernel/memory.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
1// Copyright 2014 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 <cinttypes>
7#include <memory>
8#include <utility>
9#include <vector>
10#include "common/assert.h"
11#include "common/common_types.h"
12#include "common/logging/log.h"
13#include "core/hle/kernel/memory.h"
14#include "core/hle/kernel/process.h"
15#include "core/hle/kernel/vm_manager.h"
16#include "core/memory.h"
17
18////////////////////////////////////////////////////////////////////////////////////////////////////
19
20namespace Kernel {
21
22MemoryRegionInfo memory_regions[3];
23
24/// Size of the APPLICATION, SYSTEM and BASE memory regions (respectively) for each system
25/// memory configuration type.
26static const u32 memory_region_sizes[8][3] = {
27 // Old 3DS layouts
28 {0x04000000, 0x02C00000, 0x01400000}, // 0
29 {/* This appears to be unused. */}, // 1
30 {0x06000000, 0x00C00000, 0x01400000}, // 2
31 {0x05000000, 0x01C00000, 0x01400000}, // 3
32 {0x04800000, 0x02400000, 0x01400000}, // 4
33 {0x02000000, 0x04C00000, 0x01400000}, // 5
34
35 // New 3DS layouts
36 {0x07C00000, 0x06400000, 0x02000000}, // 6
37 {0x0B200000, 0x02E00000, 0x02000000}, // 7
38};
39
40void MemoryInit(u32 mem_type) {
41 // TODO(yuriks): On the n3DS, all o3DS configurations (<=5) are forced to 6 instead.
42 ASSERT_MSG(mem_type <= 5, "New 3DS memory configuration aren't supported yet!");
43 ASSERT(mem_type != 1);
44
45 // The kernel allocation regions (APPLICATION, SYSTEM and BASE) are laid out in sequence, with
46 // the sizes specified in the memory_region_sizes table.
47 VAddr base = 0;
48 for (int i = 0; i < 3; ++i) {
49 memory_regions[i].base = base;
50 memory_regions[i].size = memory_region_sizes[mem_type][i];
51 memory_regions[i].used = 0;
52 memory_regions[i].linear_heap_memory = std::make_shared<std::vector<u8>>();
53 // Reserve enough space for this region of FCRAM.
54 // We do not want this block of memory to be relocated when allocating from it.
55 memory_regions[i].linear_heap_memory->reserve(memory_regions[i].size);
56
57 base += memory_regions[i].size;
58 }
59
60 // We must've allocated the entire FCRAM by the end
61 ASSERT(base == Memory::FCRAM_SIZE);
62}
63
64void MemoryShutdown() {
65 for (auto& region : memory_regions) {
66 region.base = 0;
67 region.size = 0;
68 region.used = 0;
69 region.linear_heap_memory = nullptr;
70 }
71}
72
73MemoryRegionInfo* GetMemoryRegion(MemoryRegion region) {
74 switch (region) {
75 case MemoryRegion::APPLICATION:
76 return &memory_regions[0];
77 case MemoryRegion::SYSTEM:
78 return &memory_regions[1];
79 case MemoryRegion::BASE:
80 return &memory_regions[2];
81 default:
82 UNREACHABLE();
83 }
84}
85
86void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping) {}
87
88void MapSharedPages(VMManager& address_space) {}
89
90} // namespace Kernel
diff --git a/src/core/hle/kernel/memory.h b/src/core/hle/kernel/memory.h
deleted file mode 100644
index 1d05b8871..000000000
--- a/src/core/hle/kernel/memory.h
+++ /dev/null
@@ -1,34 +0,0 @@
1// Copyright 2014 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 <memory>
8#include <vector>
9
10#include "common/common_types.h"
11
12namespace Kernel {
13
14class VMManager;
15enum class MemoryRegion : u16;
16struct AddressMapping;
17
18struct MemoryRegionInfo {
19 u64 base; // Not an address, but offset from start of FCRAM
20 u64 size;
21 u64 used;
22
23 std::shared_ptr<std::vector<u8>> linear_heap_memory;
24};
25
26void MemoryInit(u32 mem_type);
27void MemoryShutdown();
28MemoryRegionInfo* GetMemoryRegion(MemoryRegion region);
29
30void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping);
31void MapSharedPages(VMManager& address_space);
32
33extern MemoryRegionInfo memory_regions[3];
34} // namespace Kernel
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp
index 12b974c4b..cb7f58b35 100644
--- a/src/core/hle/kernel/mutex.cpp
+++ b/src/core/hle/kernel/mutex.cpp
@@ -12,8 +12,8 @@
12#include "core/core.h" 12#include "core/core.h"
13#include "core/hle/kernel/errors.h" 13#include "core/hle/kernel/errors.h"
14#include "core/hle/kernel/handle_table.h" 14#include "core/hle/kernel/handle_table.h"
15#include "core/hle/kernel/kernel.h"
16#include "core/hle/kernel/mutex.h" 15#include "core/hle/kernel/mutex.h"
16#include "core/hle/kernel/object.h"
17#include "core/hle/kernel/thread.h" 17#include "core/hle/kernel/thread.h"
18#include "core/hle/result.h" 18#include "core/hle/result.h"
19 19
diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h
index febfde698..45268bbe9 100644
--- a/src/core/hle/kernel/mutex.h
+++ b/src/core/hle/kernel/mutex.h
@@ -5,7 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "core/hle/kernel/kernel.h" 8#include "core/hle/kernel/object.h"
9 9
10union ResultCode; 10union ResultCode;
11 11
diff --git a/src/core/hle/kernel/object.cpp b/src/core/hle/kernel/object.cpp
new file mode 100644
index 000000000..cdba272f5
--- /dev/null
+++ b/src/core/hle/kernel/object.cpp
@@ -0,0 +1,35 @@
1// Copyright 2018 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/assert.h"
6#include "core/hle/kernel/object.h"
7
8namespace Kernel {
9
10Object::~Object() = default;
11
12bool Object::IsWaitable() const {
13 switch (GetHandleType()) {
14 case HandleType::Event:
15 case HandleType::Thread:
16 case HandleType::Timer:
17 case HandleType::ServerPort:
18 case HandleType::ServerSession:
19 return true;
20
21 case HandleType::Unknown:
22 case HandleType::SharedMemory:
23 case HandleType::Process:
24 case HandleType::AddressArbiter:
25 case HandleType::ResourceLimit:
26 case HandleType::CodeSet:
27 case HandleType::ClientPort:
28 case HandleType::ClientSession:
29 return false;
30 }
31
32 UNREACHABLE();
33}
34
35} // namespace Kernel
diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h
new file mode 100644
index 000000000..83df68dfd
--- /dev/null
+++ b/src/core/hle/kernel/object.h
@@ -0,0 +1,100 @@
1// Copyright 2018 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 <string>
8#include <utility>
9
10#include <boost/smart_ptr/intrusive_ptr.hpp>
11
12#include "common/common_types.h"
13
14namespace Kernel {
15
16using Handle = u32;
17
18enum class HandleType : u32 {
19 Unknown,
20 Event,
21 SharedMemory,
22 Thread,
23 Process,
24 AddressArbiter,
25 Timer,
26 ResourceLimit,
27 CodeSet,
28 ClientPort,
29 ServerPort,
30 ClientSession,
31 ServerSession,
32};
33
34enum class ResetType {
35 OneShot,
36 Sticky,
37 Pulse,
38};
39
40class Object : NonCopyable {
41public:
42 virtual ~Object();
43
44 /// Returns a unique identifier for the object. For debugging purposes only.
45 unsigned int GetObjectId() const {
46 return object_id;
47 }
48
49 virtual std::string GetTypeName() const {
50 return "[BAD KERNEL OBJECT TYPE]";
51 }
52 virtual std::string GetName() const {
53 return "[UNKNOWN KERNEL OBJECT]";
54 }
55 virtual HandleType GetHandleType() const = 0;
56
57 /**
58 * Check if a thread can wait on the object
59 * @return True if a thread can wait on the object, otherwise false
60 */
61 bool IsWaitable() const;
62
63public:
64 static unsigned int next_object_id;
65
66private:
67 friend void intrusive_ptr_add_ref(Object*);
68 friend void intrusive_ptr_release(Object*);
69
70 unsigned int ref_count = 0;
71 unsigned int object_id = next_object_id++;
72};
73
74// Special functions used by boost::instrusive_ptr to do automatic ref-counting
75inline void intrusive_ptr_add_ref(Object* object) {
76 ++object->ref_count;
77}
78
79inline void intrusive_ptr_release(Object* object) {
80 if (--object->ref_count == 0) {
81 delete object;
82 }
83}
84
85template <typename T>
86using SharedPtr = boost::intrusive_ptr<T>;
87
88/**
89 * Attempts to downcast the given Object pointer to a pointer to T.
90 * @return Derived pointer to the object, or `nullptr` if `object` isn't of type T.
91 */
92template <typename T>
93inline SharedPtr<T> DynamicObjectCast(SharedPtr<Object> object) {
94 if (object != nullptr && object->GetHandleType() == T::HANDLE_TYPE) {
95 return boost::static_pointer_cast<T>(std::move(object));
96 }
97 return nullptr;
98}
99
100} // namespace Kernel
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 0c0506085..edf34c5a3 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -8,7 +8,6 @@
8#include "common/common_funcs.h" 8#include "common/common_funcs.h"
9#include "common/logging/log.h" 9#include "common/logging/log.h"
10#include "core/hle/kernel/errors.h" 10#include "core/hle/kernel/errors.h"
11#include "core/hle/kernel/memory.h"
12#include "core/hle/kernel/process.h" 11#include "core/hle/kernel/process.h"
13#include "core/hle/kernel/resource_limit.h" 12#include "core/hle/kernel/resource_limit.h"
14#include "core/hle/kernel/thread.h" 13#include "core/hle/kernel/thread.h"
@@ -125,14 +124,6 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {
125 std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size, 124 std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size,
126 MemoryState::Mapped) 125 MemoryState::Mapped)
127 .Unwrap(); 126 .Unwrap();
128 misc_memory_used += stack_size;
129 memory_region->used += stack_size;
130
131 // Map special address mappings
132 MapSharedPages(vm_manager);
133 for (const auto& mapping : address_mappings) {
134 HandleSpecialMapping(vm_manager, mapping);
135 }
136 127
137 vm_manager.LogLayout(); 128 vm_manager.LogLayout();
138 status = ProcessStatus::Running; 129 status = ProcessStatus::Running;
@@ -141,37 +132,19 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {
141} 132}
142 133
143void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) { 134void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) {
144 memory_region = GetMemoryRegion(flags.memory_region); 135 const auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions,
145 136 MemoryState memory_state) {
146 auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions,
147 MemoryState memory_state) {
148 auto vma = vm_manager 137 auto vma = vm_manager
149 .MapMemoryBlock(segment.addr + base_addr, module_->memory, segment.offset, 138 .MapMemoryBlock(segment.addr + base_addr, module_->memory, segment.offset,
150 segment.size, memory_state) 139 segment.size, memory_state)
151 .Unwrap(); 140 .Unwrap();
152 vm_manager.Reprotect(vma, permissions); 141 vm_manager.Reprotect(vma, permissions);
153 misc_memory_used += segment.size;
154 memory_region->used += segment.size;
155 }; 142 };
156 143
157 // Map CodeSet segments 144 // Map CodeSet segments
158 MapSegment(module_->code, VMAPermission::ReadExecute, MemoryState::CodeStatic); 145 MapSegment(module_->CodeSegment(), VMAPermission::ReadExecute, MemoryState::CodeStatic);
159 MapSegment(module_->rodata, VMAPermission::Read, MemoryState::CodeMutable); 146 MapSegment(module_->RODataSegment(), VMAPermission::Read, MemoryState::CodeMutable);
160 MapSegment(module_->data, VMAPermission::ReadWrite, MemoryState::CodeMutable); 147 MapSegment(module_->DataSegment(), VMAPermission::ReadWrite, MemoryState::CodeMutable);
161}
162
163VAddr Process::GetLinearHeapAreaAddress() const {
164 // Starting from system version 8.0.0 a new linear heap layout is supported to allow usage of
165 // the extra RAM in the n3DS.
166 return kernel_version < 0x22C ? Memory::LINEAR_HEAP_VADDR : Memory::NEW_LINEAR_HEAP_VADDR;
167}
168
169VAddr Process::GetLinearHeapBase() const {
170 return GetLinearHeapAreaAddress() + memory_region->base;
171}
172
173VAddr Process::GetLinearHeapLimit() const {
174 return GetLinearHeapBase() + memory_region->size;
175} 148}
176 149
177ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission perms) { 150ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission perms) {
@@ -206,7 +179,6 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission per
206 vm_manager.Reprotect(vma, perms); 179 vm_manager.Reprotect(vma, perms);
207 180
208 heap_used = size; 181 heap_used = size;
209 memory_region->used += size;
210 182
211 return MakeResult<VAddr>(heap_end - size); 183 return MakeResult<VAddr>(heap_end - size);
212} 184}
@@ -226,52 +198,6 @@ ResultCode Process::HeapFree(VAddr target, u32 size) {
226 return result; 198 return result;
227 199
228 heap_used -= size; 200 heap_used -= size;
229 memory_region->used -= size;
230
231 return RESULT_SUCCESS;
232}
233
234ResultVal<VAddr> Process::LinearAllocate(VAddr target, u32 size, VMAPermission perms) {
235 UNIMPLEMENTED();
236 return {};
237}
238
239ResultCode Process::LinearFree(VAddr target, u32 size) {
240 auto& linheap_memory = memory_region->linear_heap_memory;
241
242 if (target < GetLinearHeapBase() || target + size > GetLinearHeapLimit() ||
243 target + size < target) {
244
245 return ERR_INVALID_ADDRESS;
246 }
247
248 if (size == 0) {
249 return RESULT_SUCCESS;
250 }
251
252 VAddr heap_end = GetLinearHeapBase() + (u32)linheap_memory->size();
253 if (target + size > heap_end) {
254 return ERR_INVALID_ADDRESS_STATE;
255 }
256
257 ResultCode result = vm_manager.UnmapRange(target, size);
258 if (result.IsError())
259 return result;
260
261 linear_heap_used -= size;
262 memory_region->used -= size;
263
264 if (target + size == heap_end) {
265 // End of linear heap has been freed, so check what's the last allocated block in it and
266 // reduce the size.
267 auto vma = vm_manager.FindVMA(target);
268 ASSERT(vma != vm_manager.vma_map.end());
269 ASSERT(vma->second.type == VMAType::Free);
270 VAddr new_end = vma->second.base;
271 if (new_end >= GetLinearHeapBase()) {
272 linheap_memory->resize(new_end - GetLinearHeapBase());
273 }
274 }
275 201
276 return RESULT_SUCCESS; 202 return RESULT_SUCCESS;
277} 203}
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index 68e77a4d1..992689186 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -4,6 +4,7 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <array>
7#include <bitset> 8#include <bitset>
8#include <cstddef> 9#include <cstddef>
9#include <memory> 10#include <memory>
@@ -12,7 +13,7 @@
12#include <boost/container/static_vector.hpp> 13#include <boost/container/static_vector.hpp>
13#include "common/bit_field.h" 14#include "common/bit_field.h"
14#include "common/common_types.h" 15#include "common/common_types.h"
15#include "core/hle/kernel/kernel.h" 16#include "core/hle/kernel/object.h"
16#include "core/hle/kernel/thread.h" 17#include "core/hle/kernel/thread.h"
17#include "core/hle/kernel/vm_manager.h" 18#include "core/hle/kernel/vm_manager.h"
18 19
@@ -53,9 +54,14 @@ union ProcessFlags {
53enum class ProcessStatus { Created, Running, Exited }; 54enum class ProcessStatus { Created, Running, Exited };
54 55
55class ResourceLimit; 56class ResourceLimit;
56struct MemoryRegionInfo;
57 57
58struct CodeSet final : public Object { 58struct CodeSet final : public Object {
59 struct Segment {
60 size_t offset = 0;
61 VAddr addr = 0;
62 u32 size = 0;
63 };
64
59 static SharedPtr<CodeSet> Create(std::string name); 65 static SharedPtr<CodeSet> Create(std::string name);
60 66
61 std::string GetTypeName() const override { 67 std::string GetTypeName() const override {
@@ -70,24 +76,38 @@ struct CodeSet final : public Object {
70 return HANDLE_TYPE; 76 return HANDLE_TYPE;
71 } 77 }
72 78
73 /// Name of the process 79 Segment& CodeSegment() {
74 std::string name; 80 return segments[0];
81 }
75 82
76 std::shared_ptr<std::vector<u8>> memory; 83 const Segment& CodeSegment() const {
84 return segments[0];
85 }
77 86
78 struct Segment { 87 Segment& RODataSegment() {
79 size_t offset = 0; 88 return segments[1];
80 VAddr addr = 0; 89 }
81 u32 size = 0; 90
82 }; 91 const Segment& RODataSegment() const {
92 return segments[1];
93 }
94
95 Segment& DataSegment() {
96 return segments[2];
97 }
98
99 const Segment& DataSegment() const {
100 return segments[2];
101 }
83 102
84 Segment segments[3]; 103 std::shared_ptr<std::vector<u8>> memory;
85 Segment& code = segments[0];
86 Segment& rodata = segments[1];
87 Segment& data = segments[2];
88 104
105 std::array<Segment, 3> segments;
89 VAddr entrypoint; 106 VAddr entrypoint;
90 107
108 /// Name of the process
109 std::string name;
110
91private: 111private:
92 CodeSet(); 112 CodeSet();
93 ~CodeSet() override; 113 ~CodeSet() override;
@@ -163,12 +183,11 @@ public:
163 // This makes deallocation and reallocation of holes fast and keeps process memory contiguous 183 // This makes deallocation and reallocation of holes fast and keeps process memory contiguous
164 // in the emulator address space, allowing Memory::GetPointer to be reasonably safe. 184 // in the emulator address space, allowing Memory::GetPointer to be reasonably safe.
165 std::shared_ptr<std::vector<u8>> heap_memory; 185 std::shared_ptr<std::vector<u8>> heap_memory;
166 // The left/right bounds of the address space covered by heap_memory.
167 VAddr heap_start = 0, heap_end = 0;
168 186
169 u64 heap_used = 0, linear_heap_used = 0, misc_memory_used = 0; 187 // The left/right bounds of the address space covered by heap_memory.
170 188 VAddr heap_start = 0;
171 MemoryRegionInfo* memory_region = nullptr; 189 VAddr heap_end = 0;
190 u64 heap_used = 0;
172 191
173 /// The Thread Local Storage area is allocated as processes create threads, 192 /// The Thread Local Storage area is allocated as processes create threads,
174 /// each TLS area is 0x200 bytes, so one page (0x1000) is split up in 8 parts, and each part 193 /// each TLS area is 0x200 bytes, so one page (0x1000) is split up in 8 parts, and each part
@@ -179,16 +198,9 @@ public:
179 198
180 std::string name; 199 std::string name;
181 200
182 VAddr GetLinearHeapAreaAddress() const;
183 VAddr GetLinearHeapBase() const;
184 VAddr GetLinearHeapLimit() const;
185
186 ResultVal<VAddr> HeapAllocate(VAddr target, u64 size, VMAPermission perms); 201 ResultVal<VAddr> HeapAllocate(VAddr target, u64 size, VMAPermission perms);
187 ResultCode HeapFree(VAddr target, u32 size); 202 ResultCode HeapFree(VAddr target, u32 size);
188 203
189 ResultVal<VAddr> LinearAllocate(VAddr target, u32 size, VMAPermission perms);
190 ResultCode LinearFree(VAddr target, u32 size);
191
192 ResultCode MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size); 204 ResultCode MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size);
193 205
194 ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size); 206 ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size);
diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h
index cc689a27a..0fa141db3 100644
--- a/src/core/hle/kernel/resource_limit.h
+++ b/src/core/hle/kernel/resource_limit.h
@@ -5,7 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "core/hle/kernel/kernel.h" 8#include "core/hle/kernel/object.h"
9 9
10namespace Kernel { 10namespace Kernel {
11 11
diff --git a/src/core/hle/kernel/scheduler.h b/src/core/hle/kernel/scheduler.h
index cdc14808b..1a4ee8f36 100644
--- a/src/core/hle/kernel/scheduler.h
+++ b/src/core/hle/kernel/scheduler.h
@@ -8,6 +8,7 @@
8#include <vector> 8#include <vector>
9#include "common/common_types.h" 9#include "common/common_types.h"
10#include "common/thread_queue_list.h" 10#include "common/thread_queue_list.h"
11#include "core/hle/kernel/object.h"
11#include "core/hle/kernel/thread.h" 12#include "core/hle/kernel/thread.h"
12 13
13class ARM_Interface; 14class ARM_Interface;
diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp
index 0b7061403..7b6211fd8 100644
--- a/src/core/hle/kernel/server_port.cpp
+++ b/src/core/hle/kernel/server_port.cpp
@@ -6,7 +6,7 @@
6#include "common/assert.h" 6#include "common/assert.h"
7#include "core/hle/kernel/client_port.h" 7#include "core/hle/kernel/client_port.h"
8#include "core/hle/kernel/errors.h" 8#include "core/hle/kernel/errors.h"
9#include "core/hle/kernel/kernel.h" 9#include "core/hle/kernel/object.h"
10#include "core/hle/kernel/server_port.h" 10#include "core/hle/kernel/server_port.h"
11#include "core/hle/kernel/server_session.h" 11#include "core/hle/kernel/server_session.h"
12#include "core/hle/kernel/thread.h" 12#include "core/hle/kernel/thread.h"
diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h
index e6546687e..7f6d6b3eb 100644
--- a/src/core/hle/kernel/server_port.h
+++ b/src/core/hle/kernel/server_port.h
@@ -9,7 +9,7 @@
9#include <tuple> 9#include <tuple>
10#include <vector> 10#include <vector>
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "core/hle/kernel/kernel.h" 12#include "core/hle/kernel/object.h"
13#include "core/hle/kernel/wait_object.h" 13#include "core/hle/kernel/wait_object.h"
14 14
15namespace Kernel { 15namespace Kernel {
diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h
index c7656cc49..2bce54fee 100644
--- a/src/core/hle/kernel/server_session.h
+++ b/src/core/hle/kernel/server_session.h
@@ -9,7 +9,7 @@
9#include <vector> 9#include <vector>
10 10
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "core/hle/kernel/kernel.h" 12#include "core/hle/kernel/object.h"
13#include "core/hle/kernel/wait_object.h" 13#include "core/hle/kernel/wait_object.h"
14#include "core/hle/result.h" 14#include "core/hle/result.h"
15 15
diff --git a/src/core/hle/kernel/session.h b/src/core/hle/kernel/session.h
index e69b034a7..7a551f5e4 100644
--- a/src/core/hle/kernel/session.h
+++ b/src/core/hle/kernel/session.h
@@ -4,7 +4,7 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "core/hle/kernel/kernel.h" 7#include "core/hle/kernel/object.h"
8 8
9namespace Kernel { 9namespace Kernel {
10 10
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp
index a5b11bd87..21ddc2f7d 100644
--- a/src/core/hle/kernel/shared_memory.cpp
+++ b/src/core/hle/kernel/shared_memory.cpp
@@ -8,7 +8,6 @@
8#include "common/logging/log.h" 8#include "common/logging/log.h"
9#include "core/core.h" 9#include "core/core.h"
10#include "core/hle/kernel/errors.h" 10#include "core/hle/kernel/errors.h"
11#include "core/hle/kernel/memory.h"
12#include "core/hle/kernel/shared_memory.h" 11#include "core/hle/kernel/shared_memory.h"
13#include "core/memory.h" 12#include "core/memory.h"
14 13
@@ -30,35 +29,17 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u
30 shared_memory->other_permissions = other_permissions; 29 shared_memory->other_permissions = other_permissions;
31 30
32 if (address == 0) { 31 if (address == 0) {
33 // We need to allocate a block from the Linear Heap ourselves. 32 shared_memory->backing_block = std::make_shared<std::vector<u8>>(size);
34 // We'll manually allocate some memory from the linear heap in the specified region. 33 shared_memory->backing_block_offset = 0;
35 MemoryRegionInfo* memory_region = GetMemoryRegion(region);
36 auto& linheap_memory = memory_region->linear_heap_memory;
37
38 ASSERT_MSG(linheap_memory->size() + size <= memory_region->size,
39 "Not enough space in region to allocate shared memory!");
40
41 shared_memory->backing_block = linheap_memory;
42 shared_memory->backing_block_offset = linheap_memory->size();
43 // Allocate some memory from the end of the linear heap for this region.
44 linheap_memory->insert(linheap_memory->end(), size, 0);
45 memory_region->used += size;
46
47 shared_memory->linear_heap_phys_address =
48 Memory::FCRAM_PADDR + memory_region->base +
49 static_cast<PAddr>(shared_memory->backing_block_offset);
50
51 // Increase the amount of used linear heap memory for the owner process.
52 if (shared_memory->owner_process != nullptr) {
53 shared_memory->owner_process->linear_heap_used += size;
54 }
55 34
56 // Refresh the address mappings for the current process. 35 // Refresh the address mappings for the current process.
57 if (Core::CurrentProcess() != nullptr) { 36 if (Core::CurrentProcess() != nullptr) {
58 Core::CurrentProcess()->vm_manager.RefreshMemoryBlockMappings(linheap_memory.get()); 37 Core::CurrentProcess()->vm_manager.RefreshMemoryBlockMappings(
38 shared_memory->backing_block.get());
59 } 39 }
60 } else { 40 } else {
61 auto& vm_manager = shared_memory->owner_process->vm_manager; 41 auto& vm_manager = shared_memory->owner_process->vm_manager;
42
62 // The memory is already available and mapped in the owner process. 43 // The memory is already available and mapped in the owner process.
63 auto vma = vm_manager.FindVMA(address); 44 auto vma = vm_manager.FindVMA(address);
64 ASSERT_MSG(vma != vm_manager.vma_map.end(), "Invalid memory address"); 45 ASSERT_MSG(vma != vm_manager.vma_map.end(), "Invalid memory address");
@@ -74,6 +55,7 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u
74 } 55 }
75 56
76 shared_memory->base_address = address; 57 shared_memory->base_address = address;
58
77 return shared_memory; 59 return shared_memory;
78} 60}
79 61
@@ -124,11 +106,6 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
124 106
125 VAddr target_address = address; 107 VAddr target_address = address;
126 108
127 if (base_address == 0 && target_address == 0) {
128 // Calculate the address at which to map the memory block.
129 target_address = Memory::PhysicalToVirtualAddress(linear_heap_phys_address).value();
130 }
131
132 // Map the memory block into the target process 109 // Map the memory block into the target process
133 auto result = target_process->vm_manager.MapMemoryBlock( 110 auto result = target_process->vm_manager.MapMemoryBlock(
134 target_address, backing_block, backing_block_offset, size, MemoryState::Shared); 111 target_address, backing_block, backing_block_offset, size, MemoryState::Shared);
diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h
index 17b9cedc4..c50fee615 100644
--- a/src/core/hle/kernel/shared_memory.h
+++ b/src/core/hle/kernel/shared_memory.h
@@ -9,7 +9,7 @@
9#include <vector> 9#include <vector>
10 10
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "core/hle/kernel/kernel.h" 12#include "core/hle/kernel/object.h"
13#include "core/hle/kernel/process.h" 13#include "core/hle/kernel/process.h"
14#include "core/hle/result.h" 14#include "core/hle/result.h"
15 15
@@ -111,9 +111,6 @@ public:
111 SharedPtr<Process> owner_process; 111 SharedPtr<Process> owner_process;
112 /// Address of shared memory block in the owner process if specified. 112 /// Address of shared memory block in the owner process if specified.
113 VAddr base_address; 113 VAddr base_address;
114 /// Physical address of the shared memory block in the linear heap if no address was specified
115 /// during creation.
116 PAddr linear_heap_phys_address;
117 /// Backing memory for this shared memory block. 114 /// Backing memory for this shared memory block.
118 std::shared_ptr<std::vector<u8>> backing_block; 115 std::shared_ptr<std::vector<u8>> backing_block;
119 /// Offset into the backing block for this shared memory. 116 /// Offset into the backing block for this shared memory.
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index d1cbbc1f2..5db2db687 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -267,7 +267,7 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
267 LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id, 267 LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id,
268 info_sub_id, handle); 268 info_sub_id, handle);
269 269
270 auto& vm_manager = Core::CurrentProcess()->vm_manager; 270 const auto& vm_manager = Core::CurrentProcess()->vm_manager;
271 271
272 switch (static_cast<GetInfoType>(info_id)) { 272 switch (static_cast<GetInfoType>(info_id)) {
273 case GetInfoType::AllowedCpuIdBitmask: 273 case GetInfoType::AllowedCpuIdBitmask:
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 93ea58a1e..b9022feae 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -20,8 +20,7 @@
20#include "core/core_timing_util.h" 20#include "core/core_timing_util.h"
21#include "core/hle/kernel/errors.h" 21#include "core/hle/kernel/errors.h"
22#include "core/hle/kernel/handle_table.h" 22#include "core/hle/kernel/handle_table.h"
23#include "core/hle/kernel/kernel.h" 23#include "core/hle/kernel/object.h"
24#include "core/hle/kernel/memory.h"
25#include "core/hle/kernel/process.h" 24#include "core/hle/kernel/process.h"
26#include "core/hle/kernel/thread.h" 25#include "core/hle/kernel/thread.h"
27#include "core/hle/result.h" 26#include "core/hle/result.h"
@@ -81,8 +80,8 @@ void Thread::Stop() {
81 wait_objects.clear(); 80 wait_objects.clear();
82 81
83 // Mark the TLS slot in the thread's page as free. 82 // Mark the TLS slot in the thread's page as free.
84 u64 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE; 83 const u64 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE;
85 u64 tls_slot = 84 const u64 tls_slot =
86 ((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE; 85 ((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE;
87 Core::CurrentProcess()->tls_slots[tls_page].reset(tls_slot); 86 Core::CurrentProcess()->tls_slots[tls_page].reset(tls_slot);
88} 87}
@@ -252,13 +251,14 @@ void Thread::ResumeFromWait() {
252 * slot: The index of the first free slot in the indicated page. 251 * slot: The index of the first free slot in the indicated page.
253 * alloc_needed: Whether there's a need to allocate a new TLS page (All pages are full). 252 * alloc_needed: Whether there's a need to allocate a new TLS page (All pages are full).
254 */ 253 */
255std::tuple<u32, u32, bool> GetFreeThreadLocalSlot(std::vector<std::bitset<8>>& tls_slots) { 254static std::tuple<std::size_t, std::size_t, bool> GetFreeThreadLocalSlot(
255 const std::vector<std::bitset<8>>& tls_slots) {
256 // Iterate over all the allocated pages, and try to find one where not all slots are used. 256 // Iterate over all the allocated pages, and try to find one where not all slots are used.
257 for (unsigned page = 0; page < tls_slots.size(); ++page) { 257 for (std::size_t page = 0; page < tls_slots.size(); ++page) {
258 const auto& page_tls_slots = tls_slots[page]; 258 const auto& page_tls_slots = tls_slots[page];
259 if (!page_tls_slots.all()) { 259 if (!page_tls_slots.all()) {
260 // We found a page with at least one free slot, find which slot it is 260 // We found a page with at least one free slot, find which slot it is
261 for (unsigned slot = 0; slot < page_tls_slots.size(); ++slot) { 261 for (std::size_t slot = 0; slot < page_tls_slots.size(); ++slot) {
262 if (!page_tls_slots.test(slot)) { 262 if (!page_tls_slots.test(slot)) {
263 return std::make_tuple(page, slot, false); 263 return std::make_tuple(page, slot, false);
264 } 264 }
@@ -333,42 +333,22 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
333 333
334 // Find the next available TLS index, and mark it as used 334 // Find the next available TLS index, and mark it as used
335 auto& tls_slots = owner_process->tls_slots; 335 auto& tls_slots = owner_process->tls_slots;
336 bool needs_allocation = true;
337 u32 available_page; // Which allocated page has free space
338 u32 available_slot; // Which slot within the page is free
339
340 std::tie(available_page, available_slot, needs_allocation) = GetFreeThreadLocalSlot(tls_slots);
341 336
337 auto [available_page, available_slot, needs_allocation] = GetFreeThreadLocalSlot(tls_slots);
342 if (needs_allocation) { 338 if (needs_allocation) {
343 // There are no already-allocated pages with free slots, lets allocate a new one.
344 // TLS pages are allocated from the BASE region in the linear heap.
345 MemoryRegionInfo* memory_region = GetMemoryRegion(MemoryRegion::BASE);
346 auto& linheap_memory = memory_region->linear_heap_memory;
347
348 if (linheap_memory->size() + Memory::PAGE_SIZE > memory_region->size) {
349 LOG_ERROR(Kernel_SVC,
350 "Not enough space in region to allocate a new TLS page for thread");
351 return ERR_OUT_OF_MEMORY;
352 }
353
354 size_t offset = linheap_memory->size();
355
356 // Allocate some memory from the end of the linear heap for this region.
357 linheap_memory->insert(linheap_memory->end(), Memory::PAGE_SIZE, 0);
358 memory_region->used += Memory::PAGE_SIZE;
359 owner_process->linear_heap_used += Memory::PAGE_SIZE;
360
361 tls_slots.emplace_back(0); // The page is completely available at the start 339 tls_slots.emplace_back(0); // The page is completely available at the start
362 available_page = static_cast<u32>(tls_slots.size() - 1); 340 available_page = tls_slots.size() - 1;
363 available_slot = 0; // Use the first slot in the new page 341 available_slot = 0; // Use the first slot in the new page
364 342
343 // Allocate some memory from the end of the linear heap for this region.
344 const size_t offset = thread->tls_memory->size();
345 thread->tls_memory->insert(thread->tls_memory->end(), Memory::PAGE_SIZE, 0);
346
365 auto& vm_manager = owner_process->vm_manager; 347 auto& vm_manager = owner_process->vm_manager;
366 vm_manager.RefreshMemoryBlockMappings(linheap_memory.get()); 348 vm_manager.RefreshMemoryBlockMappings(thread->tls_memory.get());
367 349
368 // Map the page to the current process' address space.
369 // TODO(Subv): Find the correct MemoryState for this region.
370 vm_manager.MapMemoryBlock(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE, 350 vm_manager.MapMemoryBlock(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE,
371 linheap_memory, offset, Memory::PAGE_SIZE, 351 thread->tls_memory, 0, Memory::PAGE_SIZE,
372 MemoryState::ThreadLocal); 352 MemoryState::ThreadLocal);
373 } 353 }
374 354
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index a456745a1..adc804248 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -11,7 +11,7 @@
11 11
12#include "common/common_types.h" 12#include "common/common_types.h"
13#include "core/arm/arm_interface.h" 13#include "core/arm/arm_interface.h"
14#include "core/hle/kernel/kernel.h" 14#include "core/hle/kernel/object.h"
15#include "core/hle/kernel/wait_object.h" 15#include "core/hle/kernel/wait_object.h"
16#include "core/hle/result.h" 16#include "core/hle/result.h"
17 17
@@ -265,6 +265,8 @@ public:
265private: 265private:
266 Thread(); 266 Thread();
267 ~Thread() override; 267 ~Thread() override;
268
269 std::shared_ptr<std::vector<u8>> tls_memory = std::make_shared<std::vector<u8>>();
268}; 270};
269 271
270/** 272/**
@@ -288,12 +290,6 @@ Thread* GetCurrentThread();
288void WaitCurrentThread_Sleep(); 290void WaitCurrentThread_Sleep();
289 291
290/** 292/**
291 * Waits the current thread from an ArbitrateAddress call
292 * @param wait_address Arbitration address used to resume from wait
293 */
294void WaitCurrentThread_ArbitrateAddress(VAddr wait_address);
295
296/**
297 * Stops the current thread and removes it from the thread_list 293 * Stops the current thread and removes it from the thread_list
298 */ 294 */
299void ExitCurrentThread(); 295void ExitCurrentThread();
diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp
index 904a3d0a5..282360745 100644
--- a/src/core/hle/kernel/timer.cpp
+++ b/src/core/hle/kernel/timer.cpp
@@ -8,7 +8,7 @@
8#include "core/core_timing.h" 8#include "core/core_timing.h"
9#include "core/core_timing_util.h" 9#include "core/core_timing_util.h"
10#include "core/hle/kernel/handle_table.h" 10#include "core/hle/kernel/handle_table.h"
11#include "core/hle/kernel/kernel.h" 11#include "core/hle/kernel/object.h"
12#include "core/hle/kernel/thread.h" 12#include "core/hle/kernel/thread.h"
13#include "core/hle/kernel/timer.h" 13#include "core/hle/kernel/timer.h"
14 14
diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h
index c63f0ed90..4dddc67e0 100644
--- a/src/core/hle/kernel/timer.h
+++ b/src/core/hle/kernel/timer.h
@@ -5,7 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "core/hle/kernel/kernel.h" 8#include "core/hle/kernel/object.h"
9#include "core/hle/kernel/wait_object.h" 9#include "core/hle/kernel/wait_object.h"
10 10
11namespace Kernel { 11namespace Kernel {
diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp
index 9d26fd781..479cacb62 100644
--- a/src/core/hle/kernel/vm_manager.cpp
+++ b/src/core/hle/kernel/vm_manager.cpp
@@ -2,6 +2,7 @@
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 <algorithm>
5#include <iterator> 6#include <iterator>
6#include <utility> 7#include <utility>
7#include "common/assert.h" 8#include "common/assert.h"
@@ -175,9 +176,9 @@ VMManager::VMAIter VMManager::Unmap(VMAIter vma_handle) {
175 176
176ResultCode VMManager::UnmapRange(VAddr target, u64 size) { 177ResultCode VMManager::UnmapRange(VAddr target, u64 size) {
177 CASCADE_RESULT(VMAIter vma, CarveVMARange(target, size)); 178 CASCADE_RESULT(VMAIter vma, CarveVMARange(target, size));
178 VAddr target_end = target + size; 179 const VAddr target_end = target + size;
179 180
180 VMAIter end = vma_map.end(); 181 const VMAIter end = vma_map.end();
181 // The comparison against the end of the range must be done using addresses since VMAs can be 182 // The comparison against the end of the range must be done using addresses since VMAs can be
182 // merged during this process, causing invalidation of the iterators. 183 // merged during this process, causing invalidation of the iterators.
183 while (vma != end && vma->second.base < target_end) { 184 while (vma != end && vma->second.base < target_end) {
@@ -207,9 +208,9 @@ VMManager::VMAHandle VMManager::Reprotect(VMAHandle vma_handle, VMAPermission ne
207 208
208ResultCode VMManager::ReprotectRange(VAddr target, u64 size, VMAPermission new_perms) { 209ResultCode VMManager::ReprotectRange(VAddr target, u64 size, VMAPermission new_perms) {
209 CASCADE_RESULT(VMAIter vma, CarveVMARange(target, size)); 210 CASCADE_RESULT(VMAIter vma, CarveVMARange(target, size));
210 VAddr target_end = target + size; 211 const VAddr target_end = target + size;
211 212
212 VMAIter end = vma_map.end(); 213 const VMAIter end = vma_map.end();
213 // The comparison against the end of the range must be done using addresses since VMAs can be 214 // The comparison against the end of the range must be done using addresses since VMAs can be
214 // merged during this process, causing invalidation of the iterators. 215 // merged during this process, causing invalidation of the iterators.
215 while (vma != end && vma->second.base < target_end) { 216 while (vma != end && vma->second.base < target_end) {
@@ -258,14 +259,14 @@ ResultVal<VMManager::VMAIter> VMManager::CarveVMA(VAddr base, u64 size) {
258 return ERR_INVALID_ADDRESS; 259 return ERR_INVALID_ADDRESS;
259 } 260 }
260 261
261 VirtualMemoryArea& vma = vma_handle->second; 262 const VirtualMemoryArea& vma = vma_handle->second;
262 if (vma.type != VMAType::Free) { 263 if (vma.type != VMAType::Free) {
263 // Region is already allocated 264 // Region is already allocated
264 return ERR_INVALID_ADDRESS_STATE; 265 return ERR_INVALID_ADDRESS_STATE;
265 } 266 }
266 267
267 u64 start_in_vma = base - vma.base; 268 const VAddr start_in_vma = base - vma.base;
268 u64 end_in_vma = start_in_vma + size; 269 const VAddr end_in_vma = start_in_vma + size;
269 270
270 if (end_in_vma > vma.size) { 271 if (end_in_vma > vma.size) {
271 // Requested allocation doesn't fit inside VMA 272 // Requested allocation doesn't fit inside VMA
@@ -288,17 +289,16 @@ ResultVal<VMManager::VMAIter> VMManager::CarveVMARange(VAddr target, u64 size) {
288 ASSERT_MSG((size & Memory::PAGE_MASK) == 0, "non-page aligned size: 0x{:016X}", size); 289 ASSERT_MSG((size & Memory::PAGE_MASK) == 0, "non-page aligned size: 0x{:016X}", size);
289 ASSERT_MSG((target & Memory::PAGE_MASK) == 0, "non-page aligned base: 0x{:016X}", target); 290 ASSERT_MSG((target & Memory::PAGE_MASK) == 0, "non-page aligned base: 0x{:016X}", target);
290 291
291 VAddr target_end = target + size; 292 const VAddr target_end = target + size;
292 ASSERT(target_end >= target); 293 ASSERT(target_end >= target);
293 ASSERT(target_end <= MAX_ADDRESS); 294 ASSERT(target_end <= MAX_ADDRESS);
294 ASSERT(size > 0); 295 ASSERT(size > 0);
295 296
296 VMAIter begin_vma = StripIterConstness(FindVMA(target)); 297 VMAIter begin_vma = StripIterConstness(FindVMA(target));
297 VMAIter i_end = vma_map.lower_bound(target_end); 298 const VMAIter i_end = vma_map.lower_bound(target_end);
298 for (auto i = begin_vma; i != i_end; ++i) { 299 if (std::any_of(begin_vma, i_end,
299 if (i->second.type == VMAType::Free) { 300 [](const auto& entry) { return entry.second.type == VMAType::Free; })) {
300 return ERR_INVALID_ADDRESS_STATE; 301 return ERR_INVALID_ADDRESS_STATE;
301 }
302 } 302 }
303 303
304 if (target != begin_vma->second.base) { 304 if (target != begin_vma->second.base) {
@@ -346,7 +346,7 @@ VMManager::VMAIter VMManager::SplitVMA(VMAIter vma_handle, u64 offset_in_vma) {
346} 346}
347 347
348VMManager::VMAIter VMManager::MergeAdjacent(VMAIter iter) { 348VMManager::VMAIter VMManager::MergeAdjacent(VMAIter iter) {
349 VMAIter next_vma = std::next(iter); 349 const VMAIter next_vma = std::next(iter);
350 if (next_vma != vma_map.end() && iter->second.CanBeMergedWith(next_vma->second)) { 350 if (next_vma != vma_map.end() && iter->second.CanBeMergedWith(next_vma->second)) {
351 iter->second.size += next_vma->second.size; 351 iter->second.size += next_vma->second.size;
352 vma_map.erase(next_vma); 352 vma_map.erase(next_vma);
@@ -382,22 +382,22 @@ void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) {
382 } 382 }
383} 383}
384 384
385u64 VMManager::GetTotalMemoryUsage() { 385u64 VMManager::GetTotalMemoryUsage() const {
386 LOG_WARNING(Kernel, "(STUBBED) called"); 386 LOG_WARNING(Kernel, "(STUBBED) called");
387 return 0xF8000000; 387 return 0xF8000000;
388} 388}
389 389
390u64 VMManager::GetTotalHeapUsage() { 390u64 VMManager::GetTotalHeapUsage() const {
391 LOG_WARNING(Kernel, "(STUBBED) called"); 391 LOG_WARNING(Kernel, "(STUBBED) called");
392 return 0x0; 392 return 0x0;
393} 393}
394 394
395VAddr VMManager::GetAddressSpaceBaseAddr() { 395VAddr VMManager::GetAddressSpaceBaseAddr() const {
396 LOG_WARNING(Kernel, "(STUBBED) called"); 396 LOG_WARNING(Kernel, "(STUBBED) called");
397 return 0x8000000; 397 return 0x8000000;
398} 398}
399 399
400u64 VMManager::GetAddressSpaceSize() { 400u64 VMManager::GetAddressSpaceSize() const {
401 LOG_WARNING(Kernel, "(STUBBED) called"); 401 LOG_WARNING(Kernel, "(STUBBED) called");
402 return MAX_ADDRESS; 402 return MAX_ADDRESS;
403} 403}
diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h
index 38e4ebcd3..98bd04bea 100644
--- a/src/core/hle/kernel/vm_manager.h
+++ b/src/core/hle/kernel/vm_manager.h
@@ -190,16 +190,16 @@ public:
190 void LogLayout() const; 190 void LogLayout() const;
191 191
192 /// Gets the total memory usage, used by svcGetInfo 192 /// Gets the total memory usage, used by svcGetInfo
193 u64 GetTotalMemoryUsage(); 193 u64 GetTotalMemoryUsage() const;
194 194
195 /// Gets the total heap usage, used by svcGetInfo 195 /// Gets the total heap usage, used by svcGetInfo
196 u64 GetTotalHeapUsage(); 196 u64 GetTotalHeapUsage() const;
197 197
198 /// Gets the total address space base address, used by svcGetInfo 198 /// Gets the total address space base address, used by svcGetInfo
199 VAddr GetAddressSpaceBaseAddr(); 199 VAddr GetAddressSpaceBaseAddr() const;
200 200
201 /// Gets the total address space address size, used by svcGetInfo 201 /// Gets the total address space address size, used by svcGetInfo
202 u64 GetAddressSpaceSize(); 202 u64 GetAddressSpaceSize() const;
203 203
204 /// Each VMManager has its own page table, which is set as the main one when the owning process 204 /// Each VMManager has its own page table, which is set as the main one when the owning process
205 /// is scheduled. 205 /// is scheduled.
diff --git a/src/core/hle/kernel/wait_object.cpp b/src/core/hle/kernel/wait_object.cpp
index 97394bca2..7681cdee7 100644
--- a/src/core/hle/kernel/wait_object.cpp
+++ b/src/core/hle/kernel/wait_object.cpp
@@ -5,8 +5,7 @@
5#include <algorithm> 5#include <algorithm>
6#include "common/assert.h" 6#include "common/assert.h"
7#include "common/logging/log.h" 7#include "common/logging/log.h"
8#include "core/hle/kernel/kernel.h" 8#include "core/hle/kernel/object.h"
9#include "core/hle/kernel/memory.h"
10#include "core/hle/kernel/process.h" 9#include "core/hle/kernel/process.h"
11#include "core/hle/kernel/thread.h" 10#include "core/hle/kernel/thread.h"
12#include "core/hle/kernel/timer.h" 11#include "core/hle/kernel/timer.h"
diff --git a/src/core/hle/kernel/wait_object.h b/src/core/hle/kernel/wait_object.h
index 78bfd8c6c..b5fbc647b 100644
--- a/src/core/hle/kernel/wait_object.h
+++ b/src/core/hle/kernel/wait_object.h
@@ -7,7 +7,7 @@
7#include <vector> 7#include <vector>
8#include <boost/smart_ptr/intrusive_ptr.hpp> 8#include <boost/smart_ptr/intrusive_ptr.hpp>
9#include "common/common_types.h" 9#include "common/common_types.h"
10#include "core/hle/kernel/kernel.h" 10#include "core/hle/kernel/object.h"
11 11
12namespace Kernel { 12namespace Kernel {
13 13
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp
index 0b158e015..6d15b46ed 100644
--- a/src/core/hle/service/acc/acc.cpp
+++ b/src/core/hle/service/acc/acc.cpp
@@ -10,6 +10,7 @@
10#include "core/hle/service/acc/acc_su.h" 10#include "core/hle/service/acc/acc_su.h"
11#include "core/hle/service/acc/acc_u0.h" 11#include "core/hle/service/acc/acc_u0.h"
12#include "core/hle/service/acc/acc_u1.h" 12#include "core/hle/service/acc/acc_u1.h"
13#include "core/settings.h"
13 14
14namespace Service::Account { 15namespace Service::Account {
15 16
@@ -31,13 +32,14 @@ struct ProfileBase {
31}; 32};
32static_assert(sizeof(ProfileBase) == 0x38, "ProfileBase structure has incorrect size"); 33static_assert(sizeof(ProfileBase) == 0x38, "ProfileBase structure has incorrect size");
33 34
35// TODO(ogniK): Generate a real user id based on username, md5(username) maybe?
34static constexpr u128 DEFAULT_USER_ID{1ull, 0ull}; 36static constexpr u128 DEFAULT_USER_ID{1ull, 0ull};
35 37
36class IProfile final : public ServiceFramework<IProfile> { 38class IProfile final : public ServiceFramework<IProfile> {
37public: 39public:
38 explicit IProfile(u128 user_id) : ServiceFramework("IProfile"), user_id(user_id) { 40 explicit IProfile(u128 user_id) : ServiceFramework("IProfile"), user_id(user_id) {
39 static const FunctionInfo functions[] = { 41 static const FunctionInfo functions[] = {
40 {0, nullptr, "Get"}, 42 {0, &IProfile::Get, "Get"},
41 {1, &IProfile::GetBase, "GetBase"}, 43 {1, &IProfile::GetBase, "GetBase"},
42 {10, nullptr, "GetImageSize"}, 44 {10, nullptr, "GetImageSize"},
43 {11, nullptr, "LoadImage"}, 45 {11, nullptr, "LoadImage"},
@@ -46,14 +48,36 @@ public:
46 } 48 }
47 49
48private: 50private:
51 void Get(Kernel::HLERequestContext& ctx) {
52 LOG_WARNING(Service_ACC, "(STUBBED) called");
53 ProfileBase profile_base{};
54 profile_base.user_id = user_id;
55 if (Settings::values.username.size() > profile_base.username.size()) {
56 std::copy_n(Settings::values.username.begin(), profile_base.username.size(),
57 profile_base.username.begin());
58 } else {
59 std::copy(Settings::values.username.begin(), Settings::values.username.end(),
60 profile_base.username.begin());
61 }
62
63 IPC::ResponseBuilder rb{ctx, 16};
64 rb.Push(RESULT_SUCCESS);
65 rb.PushRaw(profile_base);
66 }
67
49 void GetBase(Kernel::HLERequestContext& ctx) { 68 void GetBase(Kernel::HLERequestContext& ctx) {
50 LOG_WARNING(Service_ACC, "(STUBBED) called"); 69 LOG_WARNING(Service_ACC, "(STUBBED) called");
51 70
52 // TODO(Subv): Retrieve this information from somewhere. 71 // TODO(Subv): Retrieve this information from somewhere.
53 ProfileBase profile_base{}; 72 ProfileBase profile_base{};
54 profile_base.user_id = user_id; 73 profile_base.user_id = user_id;
55 profile_base.username = {'y', 'u', 'z', 'u'}; 74 if (Settings::values.username.size() > profile_base.username.size()) {
56 75 std::copy_n(Settings::values.username.begin(), profile_base.username.size(),
76 profile_base.username.begin());
77 } else {
78 std::copy(Settings::values.username.begin(), Settings::values.username.end(),
79 profile_base.username.begin());
80 }
57 IPC::ResponseBuilder rb{ctx, 16}; 81 IPC::ResponseBuilder rb{ctx, 16};
58 rb.Push(RESULT_SUCCESS); 82 rb.Push(RESULT_SUCCESS);
59 rb.PushRaw(profile_base); 83 rb.PushRaw(profile_base);
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 94d2a973d..9404d6b8c 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -652,7 +652,8 @@ void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
652 // TODO(bunnei): This should be configurable 652 // TODO(bunnei): This should be configurable
653 IPC::ResponseBuilder rb{ctx, 4}; 653 IPC::ResponseBuilder rb{ctx, 4};
654 rb.Push(RESULT_SUCCESS); 654 rb.Push(RESULT_SUCCESS);
655 rb.Push(static_cast<u64>(Service::Set::LanguageCode::EN_US)); 655 rb.Push(
656 static_cast<u64>(Service::Set::GetLanguageCodeFromIndex(Settings::values.language_index)));
656 LOG_DEBUG(Service_AM, "called"); 657 LOG_DEBUG(Service_AM, "called");
657} 658}
658 659
diff --git a/src/core/hle/service/bpc/bpc.cpp b/src/core/hle/service/bpc/bpc.cpp
new file mode 100644
index 000000000..1c1ecdb60
--- /dev/null
+++ b/src/core/hle/service/bpc/bpc.cpp
@@ -0,0 +1,57 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <memory>
6
7#include "core/hle/service/bpc/bpc.h"
8#include "core/hle/service/service.h"
9#include "core/hle/service/sm/sm.h"
10
11namespace Service::BPC {
12
13class BPC final : public ServiceFramework<BPC> {
14public:
15 explicit BPC() : ServiceFramework{"bpc"} {
16 // clang-format off
17 static const FunctionInfo functions[] = {
18 {0, nullptr, "ShutdownSystem"},
19 {1, nullptr, "RebootSystem"},
20 {2, nullptr, "GetWakeupReason"},
21 {3, nullptr, "GetShutdownReason"},
22 {4, nullptr, "GetAcOk"},
23 {5, nullptr, "GetBoardPowerControlEvent"},
24 {6, nullptr, "GetSleepButtonState"},
25 {7, nullptr, "GetPowerEvent"},
26 {8, nullptr, "Unknown1"},
27 {9, nullptr, "Unknown2"},
28 {10, nullptr, "Unknown3"},
29 };
30 // clang-format on
31
32 RegisterHandlers(functions);
33 }
34};
35
36class BPC_R final : public ServiceFramework<BPC_R> {
37public:
38 explicit BPC_R() : ServiceFramework{"bpc:r"} {
39 // clang-format off
40 static const FunctionInfo functions[] = {
41 {0, nullptr, "GetExternalRtcValue"},
42 {1, nullptr, "SetExternalRtcValue"},
43 {2, nullptr, "ReadExternalRtcResetFlag"},
44 {3, nullptr, "ClearExternalRtcResetFlag"},
45 };
46 // clang-format on
47
48 RegisterHandlers(functions);
49 }
50};
51
52void InstallInterfaces(SM::ServiceManager& sm) {
53 std::make_shared<BPC>()->InstallAsService(sm);
54 std::make_shared<BPC_R>()->InstallAsService(sm);
55}
56
57} // namespace Service::BPC
diff --git a/src/core/hle/service/bpc/bpc.h b/src/core/hle/service/bpc/bpc.h
new file mode 100644
index 000000000..eaa37be8d
--- /dev/null
+++ b/src/core/hle/service/bpc/bpc.h
@@ -0,0 +1,15 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::BPC {
12
13void InstallInterfaces(SM::ServiceManager& sm);
14
15} // namespace Service::BPC
diff --git a/src/core/hle/service/caps/caps.cpp b/src/core/hle/service/caps/caps.cpp
new file mode 100644
index 000000000..ae7b0720b
--- /dev/null
+++ b/src/core/hle/service/caps/caps.cpp
@@ -0,0 +1,152 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <memory>
6
7#include "core/hle/service/caps/caps.h"
8#include "core/hle/service/service.h"
9#include "core/hle/service/sm/sm.h"
10
11namespace Service::Capture {
12
13class CAPS_A final : public ServiceFramework<CAPS_A> {
14public:
15 explicit CAPS_A() : ServiceFramework{"caps:a"} {
16 // clang-format off
17 static const FunctionInfo functions[] = {
18 {0, nullptr, "Unknown1"},
19 {1, nullptr, "Unknown2"},
20 {2, nullptr, "Unknown3"},
21 {3, nullptr, "Unknown4"},
22 {4, nullptr, "Unknown5"},
23 {5, nullptr, "Unknown6"},
24 {6, nullptr, "Unknown7"},
25 {7, nullptr, "Unknown8"},
26 {8, nullptr, "Unknown9"},
27 {9, nullptr, "Unknown10"},
28 {10, nullptr, "Unknown11"},
29 {11, nullptr, "Unknown12"},
30 {12, nullptr, "Unknown13"},
31 {13, nullptr, "Unknown14"},
32 {14, nullptr, "Unknown15"},
33 {301, nullptr, "Unknown16"},
34 {401, nullptr, "Unknown17"},
35 {501, nullptr, "Unknown18"},
36 {1001, nullptr, "Unknown19"},
37 {1002, nullptr, "Unknown20"},
38 {8001, nullptr, "Unknown21"},
39 {8002, nullptr, "Unknown22"},
40 {8011, nullptr, "Unknown23"},
41 {8012, nullptr, "Unknown24"},
42 {8021, nullptr, "Unknown25"},
43 {10011, nullptr, "Unknown26"},
44 };
45 // clang-format on
46
47 RegisterHandlers(functions);
48 }
49};
50
51class CAPS_C final : public ServiceFramework<CAPS_C> {
52public:
53 explicit CAPS_C() : ServiceFramework{"caps:c"} {
54 // clang-format off
55 static const FunctionInfo functions[] = {
56 {2001, nullptr, "Unknown1"},
57 {2002, nullptr, "Unknown2"},
58 {2011, nullptr, "Unknown3"},
59 {2012, nullptr, "Unknown4"},
60 {2013, nullptr, "Unknown5"},
61 {2014, nullptr, "Unknown6"},
62 {2101, nullptr, "Unknown7"},
63 {2102, nullptr, "Unknown8"},
64 {2201, nullptr, "Unknown9"},
65 {2301, nullptr, "Unknown10"},
66 };
67 // clang-format on
68
69 RegisterHandlers(functions);
70 }
71};
72
73class CAPS_SC final : public ServiceFramework<CAPS_SC> {
74public:
75 explicit CAPS_SC() : ServiceFramework{"caps:sc"} {
76 // clang-format off
77 static const FunctionInfo functions[] = {
78 {1, nullptr, "Unknown1"},
79 {2, nullptr, "Unknown2"},
80 {1001, nullptr, "Unknown3"},
81 {1002, nullptr, "Unknown4"},
82 {1003, nullptr, "Unknown5"},
83 {1011, nullptr, "Unknown6"},
84 {1012, nullptr, "Unknown7"},
85 {1201, nullptr, "Unknown8"},
86 {1202, nullptr, "Unknown9"},
87 {1203, nullptr, "Unknown10"},
88 };
89 // clang-format on
90
91 RegisterHandlers(functions);
92 }
93};
94
95class CAPS_SS final : public ServiceFramework<CAPS_SS> {
96public:
97 explicit CAPS_SS() : ServiceFramework{"caps:ss"} {
98 // clang-format off
99 static const FunctionInfo functions[] = {
100 {201, nullptr, "Unknown1"},
101 {202, nullptr, "Unknown2"},
102 {203, nullptr, "Unknown3"},
103 {204, nullptr, "Unknown4"},
104 };
105 // clang-format on
106
107 RegisterHandlers(functions);
108 }
109};
110
111class CAPS_SU final : public ServiceFramework<CAPS_SU> {
112public:
113 explicit CAPS_SU() : ServiceFramework{"caps:su"} {
114 // clang-format off
115 static const FunctionInfo functions[] = {
116 {201, nullptr, "SaveScreenShot"},
117 {203, nullptr, "SaveScreenShotEx0"},
118 };
119 // clang-format on
120
121 RegisterHandlers(functions);
122 }
123};
124
125class CAPS_U final : public ServiceFramework<CAPS_U> {
126public:
127 explicit CAPS_U() : ServiceFramework{"caps:u"} {
128 // clang-format off
129 static const FunctionInfo functions[] = {
130 {102, nullptr, "GetAlbumFileListByAruid"},
131 {103, nullptr, "DeleteAlbumFileByAruid"},
132 {104, nullptr, "GetAlbumFileSizeByAruid"},
133 {110, nullptr, "LoadAlbumScreenShotImageByAruid"},
134 {120, nullptr, "LoadAlbumScreenShotThumbnailImageByAruid"},
135 {60002, nullptr, "OpenAccessorSessionForApplication"},
136 };
137 // clang-format on
138
139 RegisterHandlers(functions);
140 }
141};
142
143void InstallInterfaces(SM::ServiceManager& sm) {
144 std::make_shared<CAPS_A>()->InstallAsService(sm);
145 std::make_shared<CAPS_C>()->InstallAsService(sm);
146 std::make_shared<CAPS_SC>()->InstallAsService(sm);
147 std::make_shared<CAPS_SS>()->InstallAsService(sm);
148 std::make_shared<CAPS_SU>()->InstallAsService(sm);
149 std::make_shared<CAPS_U>()->InstallAsService(sm);
150}
151
152} // namespace Service::Capture
diff --git a/src/core/hle/service/caps/caps.h b/src/core/hle/service/caps/caps.h
new file mode 100644
index 000000000..471185dfa
--- /dev/null
+++ b/src/core/hle/service/caps/caps.h
@@ -0,0 +1,15 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::Capture {
12
13void InstallInterfaces(SM::ServiceManager& sm);
14
15} // namespace Service::Capture
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp
index fdd2fda18..e17d637e4 100644
--- a/src/core/hle/service/filesystem/filesystem.cpp
+++ b/src/core/hle/service/filesystem/filesystem.cpp
@@ -14,6 +14,8 @@
14#include "core/file_sys/vfs_offset.h" 14#include "core/file_sys/vfs_offset.h"
15#include "core/file_sys/vfs_real.h" 15#include "core/file_sys/vfs_real.h"
16#include "core/hle/service/filesystem/filesystem.h" 16#include "core/hle/service/filesystem/filesystem.h"
17#include "core/hle/service/filesystem/fsp_ldr.h"
18#include "core/hle/service/filesystem/fsp_pr.h"
17#include "core/hle/service/filesystem/fsp_srv.h" 19#include "core/hle/service/filesystem/fsp_srv.h"
18 20
19namespace Service::FileSystem { 21namespace Service::FileSystem {
@@ -298,6 +300,8 @@ void RegisterFileSystems() {
298 300
299void InstallInterfaces(SM::ServiceManager& service_manager) { 301void InstallInterfaces(SM::ServiceManager& service_manager) {
300 RegisterFileSystems(); 302 RegisterFileSystems();
303 std::make_shared<FSP_LDR>()->InstallAsService(service_manager);
304 std::make_shared<FSP_PR>()->InstallAsService(service_manager);
301 std::make_shared<FSP_SRV>()->InstallAsService(service_manager); 305 std::make_shared<FSP_SRV>()->InstallAsService(service_manager);
302} 306}
303 307
diff --git a/src/core/hle/service/filesystem/fsp_ldr.cpp b/src/core/hle/service/filesystem/fsp_ldr.cpp
new file mode 100644
index 000000000..ee6d4d055
--- /dev/null
+++ b/src/core/hle/service/filesystem/fsp_ldr.cpp
@@ -0,0 +1,24 @@
1// Copyright 2018 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 "core/hle/service/filesystem/fsp_ldr.h"
8#include "core/hle/service/service.h"
9
10namespace Service::FileSystem {
11
12FSP_LDR::FSP_LDR() : ServiceFramework{"fsp:ldr"} {
13 // clang-format off
14 static const FunctionInfo functions[] = {
15 {0, nullptr, "OpenCodeFileSystem"},
16 {1, nullptr, "IsArchivedProgram"},
17 {2, nullptr, "SetCurrentProcess"},
18 };
19 // clang-format on
20
21 RegisterHandlers(functions);
22}
23
24} // namespace Service::FileSystem
diff --git a/src/core/hle/service/filesystem/fsp_ldr.h b/src/core/hle/service/filesystem/fsp_ldr.h
new file mode 100644
index 000000000..fa8e11b4c
--- /dev/null
+++ b/src/core/hle/service/filesystem/fsp_ldr.h
@@ -0,0 +1,16 @@
1// Copyright 2018 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 "core/hle/service/service.h"
8
9namespace Service::FileSystem {
10
11class FSP_LDR final : public ServiceFramework<FSP_LDR> {
12public:
13 explicit FSP_LDR();
14};
15
16} // namespace Service::FileSystem
diff --git a/src/core/hle/service/filesystem/fsp_pr.cpp b/src/core/hle/service/filesystem/fsp_pr.cpp
new file mode 100644
index 000000000..0b51385ee
--- /dev/null
+++ b/src/core/hle/service/filesystem/fsp_pr.cpp
@@ -0,0 +1,25 @@
1// Copyright 2018 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 "core/hle/service/filesystem/fsp_pr.h"
8#include "core/hle/service/service.h"
9
10namespace Service::FileSystem {
11
12FSP_PR::FSP_PR() : ServiceFramework{"fsp:pr"} {
13 // clang-format off
14 static const FunctionInfo functions[] = {
15 {0, nullptr, "RegisterProgram"},
16 {1, nullptr, "UnregisterProgram"},
17 {2, nullptr, "SetCurrentProcess"},
18 {256, nullptr, "SetEnabledProgramVerification"},
19 };
20 // clang-format on
21
22 RegisterHandlers(functions);
23}
24
25} // namespace Service::FileSystem
diff --git a/src/core/hle/service/filesystem/fsp_pr.h b/src/core/hle/service/filesystem/fsp_pr.h
new file mode 100644
index 000000000..62edcd08a
--- /dev/null
+++ b/src/core/hle/service/filesystem/fsp_pr.h
@@ -0,0 +1,16 @@
1// Copyright 2018 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 "core/hle/service/service.h"
8
9namespace Service::FileSystem {
10
11class FSP_PR final : public ServiceFramework<FSP_PR> {
12public:
13 explicit FSP_PR();
14};
15
16} // namespace Service::FileSystem
diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp
index b497376d7..2e99ddf51 100644
--- a/src/core/hle/service/lm/lm.cpp
+++ b/src/core/hle/service/lm/lm.cpp
@@ -13,11 +13,11 @@
13 13
14namespace Service::LM { 14namespace Service::LM {
15 15
16class Logger final : public ServiceFramework<Logger> { 16class ILogger final : public ServiceFramework<ILogger> {
17public: 17public:
18 Logger() : ServiceFramework("Logger") { 18 ILogger() : ServiceFramework("ILogger") {
19 static const FunctionInfo functions[] = { 19 static const FunctionInfo functions[] = {
20 {0x00000000, &Logger::Initialize, "Initialize"}, 20 {0x00000000, &ILogger::Initialize, "Initialize"},
21 {0x00000001, nullptr, "SetDestination"}, 21 {0x00000001, nullptr, "SetDestination"},
22 }; 22 };
23 RegisterHandlers(functions); 23 RegisterHandlers(functions);
@@ -182,7 +182,7 @@ public:
182 void OpenLogger(Kernel::HLERequestContext& ctx) { 182 void OpenLogger(Kernel::HLERequestContext& ctx) {
183 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 183 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
184 rb.Push(RESULT_SUCCESS); 184 rb.Push(RESULT_SUCCESS);
185 rb.PushIpcInterface<Logger>(); 185 rb.PushIpcInterface<ILogger>();
186 186
187 LOG_DEBUG(Service_LM, "called"); 187 LOG_DEBUG(Service_LM, "called");
188 } 188 }
diff --git a/src/core/hle/service/mig/mig.cpp b/src/core/hle/service/mig/mig.cpp
new file mode 100644
index 000000000..d16367f2c
--- /dev/null
+++ b/src/core/hle/service/mig/mig.cpp
@@ -0,0 +1,34 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <memory>
6
7#include "core/hle/service/mig/mig.h"
8#include "core/hle/service/service.h"
9#include "core/hle/service/sm/sm.h"
10
11namespace Service::Migration {
12
13class MIG_USR final : public ServiceFramework<MIG_USR> {
14public:
15 explicit MIG_USR() : ServiceFramework{"mig:usr"} {
16 // clang-format off
17 static const FunctionInfo functions[] = {
18 {10, nullptr, "TryGetLastMigrationInfo"},
19 {100, nullptr, "CreateServer"},
20 {101, nullptr, "ResumeServer"},
21 {200, nullptr, "CreateClient"},
22 {201, nullptr, "ResumeClient"},
23 };
24 // clang-format on
25
26 RegisterHandlers(functions);
27 }
28};
29
30void InstallInterfaces(SM::ServiceManager& sm) {
31 std::make_shared<MIG_USR>()->InstallAsService(sm);
32}
33
34} // namespace Service::Migration
diff --git a/src/core/hle/service/mig/mig.h b/src/core/hle/service/mig/mig.h
new file mode 100644
index 000000000..288c1c1b3
--- /dev/null
+++ b/src/core/hle/service/mig/mig.h
@@ -0,0 +1,15 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::Migration {
12
13void InstallInterfaces(SM::ServiceManager& sm);
14
15} // namespace Service::Migration
diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp
index 89c703310..98017267c 100644
--- a/src/core/hle/service/ns/ns.cpp
+++ b/src/core/hle/service/ns/ns.cpp
@@ -2,12 +2,459 @@
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 "core/hle/ipc_helpers.h"
6#include "core/hle/kernel/hle_ipc.h"
5#include "core/hle/service/ns/ns.h" 7#include "core/hle/service/ns/ns.h"
6#include "core/hle/service/ns/pl_u.h" 8#include "core/hle/service/ns/pl_u.h"
7 9
8namespace Service::NS { 10namespace Service::NS {
9 11
12class IAccountProxyInterface final : public ServiceFramework<IAccountProxyInterface> {
13public:
14 explicit IAccountProxyInterface() : ServiceFramework{"IAccountProxyInterface"} {
15 // clang-format off
16 static const FunctionInfo functions[] = {
17 {0, nullptr, "CreateUserAccount"},
18 };
19 // clang-format on
20
21 RegisterHandlers(functions);
22 }
23};
24
25class IApplicationManagerInterface final : public ServiceFramework<IApplicationManagerInterface> {
26public:
27 explicit IApplicationManagerInterface() : ServiceFramework{"IApplicationManagerInterface"} {
28 // clang-format off
29 static const FunctionInfo functions[] = {
30 {0, nullptr, "ListApplicationRecord"},
31 {1, nullptr, "GenerateApplicationRecordCount"},
32 {2, nullptr, "GetApplicationRecordUpdateSystemEvent"},
33 {3, nullptr, "GetApplicationViewDeprecated"},
34 {4, nullptr, "DeleteApplicationEntity"},
35 {5, nullptr, "DeleteApplicationCompletely"},
36 {6, nullptr, "IsAnyApplicationEntityRedundant"},
37 {7, nullptr, "DeleteRedundantApplicationEntity"},
38 {8, nullptr, "IsApplicationEntityMovable"},
39 {9, nullptr, "MoveApplicationEntity"},
40 {11, nullptr, "CalculateApplicationOccupiedSize"},
41 {16, nullptr, "PushApplicationRecord"},
42 {17, nullptr, "ListApplicationRecordContentMeta"},
43 {19, nullptr, "LaunchApplication"},
44 {21, nullptr, "GetApplicationContentPath"},
45 {22, nullptr, "TerminateApplication"},
46 {23, nullptr, "ResolveApplicationContentPath"},
47 {26, nullptr, "BeginInstallApplication"},
48 {27, nullptr, "DeleteApplicationRecord"},
49 {30, nullptr, "RequestApplicationUpdateInfo"},
50 {32, nullptr, "CancelApplicationDownload"},
51 {33, nullptr, "ResumeApplicationDownload"},
52 {35, nullptr, "UpdateVersionList"},
53 {36, nullptr, "PushLaunchVersion"},
54 {37, nullptr, "ListRequiredVersion"},
55 {38, nullptr, "CheckApplicationLaunchVersion"},
56 {39, nullptr, "CheckApplicationLaunchRights"},
57 {40, nullptr, "GetApplicationLogoData"},
58 {41, nullptr, "CalculateApplicationDownloadRequiredSize"},
59 {42, nullptr, "CleanupSdCard"},
60 {43, nullptr, "CheckSdCardMountStatus"},
61 {44, nullptr, "GetSdCardMountStatusChangedEvent"},
62 {45, nullptr, "GetGameCardAttachmentEvent"},
63 {46, nullptr, "GetGameCardAttachmentInfo"},
64 {47, nullptr, "GetTotalSpaceSize"},
65 {48, nullptr, "GetFreeSpaceSize"},
66 {49, nullptr, "GetSdCardRemovedEvent"},
67 {52, nullptr, "GetGameCardUpdateDetectionEvent"},
68 {53, nullptr, "DisableApplicationAutoDelete"},
69 {54, nullptr, "EnableApplicationAutoDelete"},
70 {55, nullptr, "GetApplicationDesiredLanguage"},
71 {56, nullptr, "SetApplicationTerminateResult"},
72 {57, nullptr, "ClearApplicationTerminateResult"},
73 {58, nullptr, "GetLastSdCardMountUnexpectedResult"},
74 {59, nullptr, "ConvertApplicationLanguageToLanguageCode"},
75 {60, nullptr, "ConvertLanguageCodeToApplicationLanguage"},
76 {61, nullptr, "GetBackgroundDownloadStressTaskInfo"},
77 {62, nullptr, "GetGameCardStopper"},
78 {63, nullptr, "IsSystemProgramInstalled"},
79 {64, nullptr, "StartApplyDeltaTask"},
80 {65, nullptr, "GetRequestServerStopper"},
81 {66, nullptr, "GetBackgroundApplyDeltaStressTaskInfo"},
82 {67, nullptr, "CancelApplicationApplyDelta"},
83 {68, nullptr, "ResumeApplicationApplyDelta"},
84 {69, nullptr, "CalculateApplicationApplyDeltaRequiredSize"},
85 {70, nullptr, "ResumeAll"},
86 {71, nullptr, "GetStorageSize"},
87 {80, nullptr, "RequestDownloadApplication"},
88 {81, nullptr, "RequestDownloadAddOnContent"},
89 {82, nullptr, "DownloadApplication"},
90 {83, nullptr, "CheckApplicationResumeRights"},
91 {84, nullptr, "GetDynamicCommitEvent"},
92 {85, nullptr, "RequestUpdateApplication2"},
93 {86, nullptr, "EnableApplicationCrashReport"},
94 {87, nullptr, "IsApplicationCrashReportEnabled"},
95 {90, nullptr, "BoostSystemMemoryResourceLimit"},
96 {100, nullptr, "ResetToFactorySettings"},
97 {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"},
98 {102, nullptr, "ResetToFactorySettingsForRefurbishment"},
99 {200, nullptr, "CalculateUserSaveDataStatistics"},
100 {201, nullptr, "DeleteUserSaveDataAll"},
101 {210, nullptr, "DeleteUserSystemSaveData"},
102 {220, nullptr, "UnregisterNetworkServiceAccount"},
103 {300, nullptr, "GetApplicationShellEvent"},
104 {301, nullptr, "PopApplicationShellEventInfo"},
105 {302, nullptr, "LaunchLibraryApplet"},
106 {303, nullptr, "TerminateLibraryApplet"},
107 {304, nullptr, "LaunchSystemApplet"},
108 {305, nullptr, "TerminateSystemApplet"},
109 {306, nullptr, "LaunchOverlayApplet"},
110 {307, nullptr, "TerminateOverlayApplet"},
111 {400, nullptr, "GetApplicationControlData"},
112 {401, nullptr, "InvalidateAllApplicationControlCache"},
113 {402, nullptr, "RequestDownloadApplicationControlData"},
114 {403, nullptr, "GetMaxApplicationControlCacheCount"},
115 {404, nullptr, "InvalidateApplicationControlCache"},
116 {405, nullptr, "ListApplicationControlCacheEntryInfo"},
117 {502, nullptr, "RequestCheckGameCardRegistration"},
118 {503, nullptr, "RequestGameCardRegistrationGoldPoint"},
119 {504, nullptr, "RequestRegisterGameCard"},
120 {505, nullptr, "GetGameCardMountFailureEvent"},
121 {506, nullptr, "IsGameCardInserted"},
122 {507, nullptr, "EnsureGameCardAccess"},
123 {508, nullptr, "GetLastGameCardMountFailureResult"},
124 {509, nullptr, "ListApplicationIdOnGameCard"},
125 {600, nullptr, "CountApplicationContentMeta"},
126 {601, nullptr, "ListApplicationContentMetaStatus"},
127 {602, nullptr, "ListAvailableAddOnContent"},
128 {603, nullptr, "GetOwnedApplicationContentMetaStatus"},
129 {604, nullptr, "RegisterContentsExternalKey"},
130 {605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"},
131 {606, nullptr, "GetContentMetaStorage"},
132 {700, nullptr, "PushDownloadTaskList"},
133 {701, nullptr, "ClearTaskStatusList"},
134 {702, nullptr, "RequestDownloadTaskList"},
135 {703, nullptr, "RequestEnsureDownloadTask"},
136 {704, nullptr, "ListDownloadTaskStatus"},
137 {705, nullptr, "RequestDownloadTaskListData"},
138 {800, nullptr, "RequestVersionList"},
139 {801, nullptr, "ListVersionList"},
140 {802, nullptr, "RequestVersionListData"},
141 {900, nullptr, "GetApplicationRecord"},
142 {901, nullptr, "GetApplicationRecordProperty"},
143 {902, nullptr, "EnableApplicationAutoUpdate"},
144 {903, nullptr, "DisableApplicationAutoUpdate"},
145 {904, nullptr, "TouchApplication"},
146 {905, nullptr, "RequestApplicationUpdate"},
147 {906, nullptr, "IsApplicationUpdateRequested"},
148 {907, nullptr, "WithdrawApplicationUpdateRequest"},
149 {908, nullptr, "ListApplicationRecordInstalledContentMeta"},
150 {909, nullptr, "WithdrawCleanupAddOnContentsWithNoRightsRecommendation"},
151 {1000, nullptr, "RequestVerifyApplicationDeprecated"},
152 {1001, nullptr, "CorruptApplicationForDebug"},
153 {1002, nullptr, "RequestVerifyAddOnContentsRights"},
154 {1003, nullptr, "RequestVerifyApplication"},
155 {1004, nullptr, "CorruptContentForDebug"},
156 {1200, nullptr, "NeedsUpdateVulnerability"},
157 {1300, nullptr, "IsAnyApplicationEntityInstalled"},
158 {1301, nullptr, "DeleteApplicationContentEntities"},
159 {1302, nullptr, "CleanupUnrecordedApplicationEntity"},
160 {1303, nullptr, "CleanupAddOnContentsWithNoRights"},
161 {1304, nullptr, "DeleteApplicationContentEntity"},
162 {1305, nullptr, "TryDeleteRunningApplicationEntity"},
163 {1306, nullptr, "TryDeleteRunningApplicationCompletely"},
164 {1307, nullptr, "TryDeleteRunningApplicationContentEntities"},
165 {1400, nullptr, "PrepareShutdown"},
166 {1500, nullptr, "FormatSdCard"},
167 {1501, nullptr, "NeedsSystemUpdateToFormatSdCard"},
168 {1502, nullptr, "GetLastSdCardFormatUnexpectedResult"},
169 {1504, nullptr, "InsertSdCard"},
170 {1505, nullptr, "RemoveSdCard"},
171 {1600, nullptr, "GetSystemSeedForPseudoDeviceId"},
172 {1601, nullptr, "ResetSystemSeedForPseudoDeviceId"},
173 {1700, nullptr, "ListApplicationDownloadingContentMeta"},
174 {1701, nullptr, "GetApplicationView"},
175 {1702, nullptr, "GetApplicationDownloadTaskStatus"},
176 {1703, nullptr, "GetApplicationViewDownloadErrorContext"},
177 {1800, nullptr, "IsNotificationSetupCompleted"},
178 {1801, nullptr, "GetLastNotificationInfoCount"},
179 {1802, nullptr, "ListLastNotificationInfo"},
180 {1803, nullptr, "ListNotificationTask"},
181 {1900, nullptr, "IsActiveAccount"},
182 {1901, nullptr, "RequestDownloadApplicationPrepurchasedRights"},
183 {1902, nullptr, "GetApplicationTicketInfo"},
184 {2000, nullptr, "GetSystemDeliveryInfo"},
185 {2001, nullptr, "SelectLatestSystemDeliveryInfo"},
186 {2002, nullptr, "VerifyDeliveryProtocolVersion"},
187 {2003, nullptr, "GetApplicationDeliveryInfo"},
188 {2004, nullptr, "HasAllContentsToDeliver"},
189 {2005, nullptr, "CompareApplicationDeliveryInfo"},
190 {2006, nullptr, "CanDeliverApplication"},
191 {2007, nullptr, "ListContentMetaKeyToDeliverApplication"},
192 {2008, nullptr, "NeedsSystemUpdateToDeliverApplication"},
193 {2009, nullptr, "EstimateRequiredSize"},
194 {2010, nullptr, "RequestReceiveApplication"},
195 {2011, nullptr, "CommitReceiveApplication"},
196 {2012, nullptr, "GetReceiveApplicationProgress"},
197 {2013, nullptr, "RequestSendApplication"},
198 {2014, nullptr, "GetSendApplicationProgress"},
199 {2015, nullptr, "CompareSystemDeliveryInfo"},
200 {2016, nullptr, "ListNotCommittedContentMeta"},
201 {2017, nullptr, "CreateDownloadTask"},
202 };
203 // clang-format on
204
205 RegisterHandlers(functions);
206 }
207};
208
209class IApplicationVersionInterface final : public ServiceFramework<IApplicationVersionInterface> {
210public:
211 explicit IApplicationVersionInterface() : ServiceFramework{"IApplicationVersionInterface"} {
212 // clang-format off
213 static const FunctionInfo functions[] = {
214 {0, nullptr, "GetLaunchRequiredVersion"},
215 {1, nullptr, "UpgradeLaunchRequiredVersion"},
216 {35, nullptr, "UpdateVersionList"},
217 {36, nullptr, "PushLaunchVersion"},
218 {37, nullptr, "ListRequiredVersion"},
219 {800, nullptr, "RequestVersionList"},
220 {801, nullptr, "ListVersionList"},
221 {802, nullptr, "RequestVersionListData"},
222 {1000, nullptr, "PerformAutoUpdate"},
223 };
224 // clang-format on
225
226 RegisterHandlers(functions);
227 }
228};
229
230class IContentManagerInterface final : public ServiceFramework<IContentManagerInterface> {
231public:
232 explicit IContentManagerInterface() : ServiceFramework{"IContentManagerInterface"} {
233 // clang-format off
234 static const FunctionInfo functions[] = {
235 {11, nullptr, "CalculateApplicationOccupiedSize"},
236 {43, nullptr, "CheckSdCardMountStatus"},
237 {47, nullptr, "GetTotalSpaceSize"},
238 {48, nullptr, "GetFreeSpaceSize"},
239 {600, nullptr, "CountApplicationContentMeta"},
240 {601, nullptr, "ListApplicationContentMetaStatus"},
241 {605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"},
242 {607, nullptr, "IsAnyApplicationRunning"},
243 };
244 // clang-format on
245
246 RegisterHandlers(functions);
247 }
248};
249
250class IDocumentInterface final : public ServiceFramework<IDocumentInterface> {
251public:
252 explicit IDocumentInterface() : ServiceFramework{"IDocumentInterface"} {
253 // clang-format off
254 static const FunctionInfo functions[] = {
255 {21, nullptr, "GetApplicationContentPath"},
256 {23, nullptr, "ResolveApplicationContentPath"},
257 };
258 // clang-format on
259
260 RegisterHandlers(functions);
261 }
262};
263
264class IDownloadTaskInterface final : public ServiceFramework<IDownloadTaskInterface> {
265public:
266 explicit IDownloadTaskInterface() : ServiceFramework{"IDownloadTaskInterface"} {
267 // clang-format off
268 static const FunctionInfo functions[] = {
269 {701, nullptr, "ClearTaskStatusList"},
270 {702, nullptr, "RequestDownloadTaskList"},
271 {703, nullptr, "RequestEnsureDownloadTask"},
272 {704, nullptr, "ListDownloadTaskStatus"},
273 {705, nullptr, "RequestDownloadTaskListData"},
274 {706, nullptr, "TryCommitCurrentApplicationDownloadTask"},
275 {707, nullptr, "EnableAutoCommit"},
276 {708, nullptr, "DisableAutoCommit"},
277 {709, nullptr, "TriggerDynamicCommitEvent"},
278 };
279 // clang-format on
280
281 RegisterHandlers(functions);
282 }
283};
284
285class IECommerceInterface final : public ServiceFramework<IECommerceInterface> {
286public:
287 explicit IECommerceInterface() : ServiceFramework{"IECommerceInterface"} {
288 // clang-format off
289 static const FunctionInfo functions[] = {
290 {0, nullptr, "RequestLinkDevice"},
291 };
292 // clang-format on
293
294 RegisterHandlers(functions);
295 }
296};
297
298class IFactoryResetInterface final : public ServiceFramework<IFactoryResetInterface> {
299public:
300 explicit IFactoryResetInterface() : ServiceFramework{"IFactoryResetInterface"} {
301 // clang-format off
302 static const FunctionInfo functions[] = {
303 {100, nullptr, "ResetToFactorySettings"},
304 {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"},
305 {102, nullptr, "ResetToFactorySettingsForRefurbishment "},
306 };
307 // clang-format on
308
309 RegisterHandlers(functions);
310 }
311};
312
313class NS final : public ServiceFramework<NS> {
314public:
315 explicit NS(const char* name) : ServiceFramework{name} {
316 // clang-format off
317 static const FunctionInfo functions[] = {
318 {7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"},
319 {7993, &NS::PushInterface<IApplicationVersionInterface>, "GetApplicationVersionInterface"},
320 {7994, &NS::PushInterface<IFactoryResetInterface>, "GetFactoryResetInterface"},
321 {7995, &NS::PushInterface<IAccountProxyInterface>, "GetAccountProxyInterface"},
322 {7996, &NS::PushInterface<IApplicationManagerInterface>, "GetApplicationManagerInterface"},
323 {7997, &NS::PushInterface<IDownloadTaskInterface>, "GetDownloadTaskInterface"},
324 {7998, &NS::PushInterface<IContentManagerInterface>, "GetContentManagementInterface"},
325 {7999, &NS::PushInterface<IDocumentInterface>, "GetDocumentInterface"},
326 };
327 // clang-format on
328
329 RegisterHandlers(functions);
330 }
331
332private:
333 template <typename T>
334 void PushInterface(Kernel::HLERequestContext& ctx) {
335 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
336 rb.Push(RESULT_SUCCESS);
337 rb.PushIpcInterface<T>();
338
339 LOG_DEBUG(Service_NS, "called");
340 }
341};
342
343class NS_DEV final : public ServiceFramework<NS_DEV> {
344public:
345 explicit NS_DEV() : ServiceFramework{"ns:dev"} {
346 // clang-format off
347 static const FunctionInfo functions[] = {
348 {0, nullptr, "LaunchProgram"},
349 {1, nullptr, "TerminateProcess"},
350 {2, nullptr, "TerminateProgram"},
351 {3, nullptr, "GetShellEventHandle"},
352 {4, nullptr, "GetShellEventInfo"},
353 {5, nullptr, "TerminateApplication"},
354 {6, nullptr, "PrepareLaunchProgramFromHost"},
355 {7, nullptr, "LaunchApplication"},
356 {8, nullptr, "LaunchApplicationWithStorageId"},
357 };
358 // clang-format on
359
360 RegisterHandlers(functions);
361 }
362};
363
364class ISystemUpdateControl final : public ServiceFramework<ISystemUpdateControl> {
365public:
366 explicit ISystemUpdateControl() : ServiceFramework{"ISystemUpdateControl"} {
367 // clang-format off
368 static const FunctionInfo functions[] = {
369 {0, nullptr, "HasDownloaded"},
370 {1, nullptr, "RequestCheckLatestUpdate"},
371 {2, nullptr, "RequestDownloadLatestUpdate"},
372 {3, nullptr, "GetDownloadProgress"},
373 {4, nullptr, "ApplyDownloadedUpdate"},
374 {5, nullptr, "RequestPrepareCardUpdate"},
375 {6, nullptr, "GetPrepareCardUpdateProgress"},
376 {7, nullptr, "HasPreparedCardUpdate"},
377 {8, nullptr, "ApplyCardUpdate"},
378 {9, nullptr, "GetDownloadedEulaDataSize"},
379 {10, nullptr, "GetDownloadedEulaData"},
380 {11, nullptr, "SetupCardUpdate"},
381 {12, nullptr, "GetPreparedCardUpdateEulaDataSize"},
382 {13, nullptr, "GetPreparedCardUpdateEulaData"},
383 {14, nullptr, "SetupCardUpdateViaSystemUpdater"},
384 {15, nullptr, "HasReceived"},
385 {16, nullptr, "RequestReceiveSystemUpdate"},
386 {17, nullptr, "GetReceiveProgress"},
387 {18, nullptr, "ApplyReceivedUpdate"},
388 {19, nullptr, "GetReceivedEulaDataSize"},
389 {20, nullptr, "GetReceivedEulaData"},
390 {21, nullptr, "SetupToReceiveSystemUpdate"},
391 };
392 // clang-format on
393
394 RegisterHandlers(functions);
395 }
396};
397
398class NS_SU final : public ServiceFramework<NS_SU> {
399public:
400 explicit NS_SU() : ServiceFramework{"ns:su"} {
401 // clang-format off
402 static const FunctionInfo functions[] = {
403 {0, nullptr, "GetBackgroundNetworkUpdateState"},
404 {1, &NS_SU::OpenSystemUpdateControl, "OpenSystemUpdateControl"},
405 {2, nullptr, "NotifyExFatDriverRequired"},
406 {3, nullptr, "ClearExFatDriverStatusForDebug"},
407 {4, nullptr, "RequestBackgroundNetworkUpdate"},
408 {5, nullptr, "NotifyBackgroundNetworkUpdate"},
409 {6, nullptr, "NotifyExFatDriverDownloadedForDebug"},
410 {9, nullptr, "GetSystemUpdateNotificationEventForContentDelivery"},
411 {10, nullptr, "NotifySystemUpdateForContentDelivery"},
412 {11, nullptr, "PrepareShutdown"},
413 {16, nullptr, "DestroySystemUpdateTask"},
414 {17, nullptr, "RequestSendSystemUpdate"},
415 {18, nullptr, "GetSendSystemUpdateProgress"},
416 };
417 // clang-format on
418
419 RegisterHandlers(functions);
420 }
421
422private:
423 void OpenSystemUpdateControl(Kernel::HLERequestContext& ctx) {
424 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
425 rb.Push(RESULT_SUCCESS);
426 rb.PushIpcInterface<ISystemUpdateControl>();
427
428 LOG_DEBUG(Service_NS, "called");
429 }
430};
431
432class NS_VM final : public ServiceFramework<NS_VM> {
433public:
434 explicit NS_VM() : ServiceFramework{"ns:vm"} {
435 // clang-format off
436 static const FunctionInfo functions[] = {
437 {1200, nullptr, "NeedsUpdateVulnerability"},
438 {1201, nullptr, "UpdateSafeSystemVersionForDebug"},
439 {1202, nullptr, "GetSafeSystemVersion"},
440 };
441 // clang-format on
442
443 RegisterHandlers(functions);
444 }
445};
446
10void InstallInterfaces(SM::ServiceManager& service_manager) { 447void InstallInterfaces(SM::ServiceManager& service_manager) {
448 std::make_shared<NS>("ns:am2")->InstallAsService(service_manager);
449 std::make_shared<NS>("ns:ec")->InstallAsService(service_manager);
450 std::make_shared<NS>("ns:rid")->InstallAsService(service_manager);
451 std::make_shared<NS>("ns:rt")->InstallAsService(service_manager);
452 std::make_shared<NS>("ns:web")->InstallAsService(service_manager);
453
454 std::make_shared<NS_DEV>()->InstallAsService(service_manager);
455 std::make_shared<NS_SU>()->InstallAsService(service_manager);
456 std::make_shared<NS_VM>()->InstallAsService(service_manager);
457
11 std::make_shared<PL_U>()->InstallAsService(service_manager); 458 std::make_shared<PL_U>()->InstallAsService(service_manager);
12} 459}
13 460
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp
index 7132b18ad..adf180509 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.cpp
+++ b/src/core/hle/service/nvflinger/buffer_queue.cpp
@@ -4,9 +4,8 @@
4 4
5#include <algorithm> 5#include <algorithm>
6 6
7#include "common/alignment.h" 7#include "common/assert.h"
8#include "common/scope_exit.h" 8#include "common/logging/log.h"
9#include "core/core_timing.h"
10#include "core/hle/service/nvflinger/buffer_queue.h" 9#include "core/hle/service/nvflinger/buffer_queue.h"
11 10
12namespace Service { 11namespace Service {
diff --git a/src/core/hle/service/pcv/pcv.cpp b/src/core/hle/service/pcv/pcv.cpp
new file mode 100644
index 000000000..d6891a659
--- /dev/null
+++ b/src/core/hle/service/pcv/pcv.cpp
@@ -0,0 +1,84 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <memory>
6
7#include "core/hle/service/pcv/pcv.h"
8#include "core/hle/service/service.h"
9#include "core/hle/service/sm/sm.h"
10
11namespace Service::PCV {
12
13class PCV final : public ServiceFramework<PCV> {
14public:
15 explicit PCV() : ServiceFramework{"pcv"} {
16 // clang-format off
17 static const FunctionInfo functions[] = {
18 {0, nullptr, "SetPowerEnabled"},
19 {1, nullptr, "SetClockEnabled"},
20 {2, nullptr, "SetClockRate"},
21 {3, nullptr, "GetClockRate"},
22 {4, nullptr, "GetState"},
23 {5, nullptr, "GetPossibleClockRates"},
24 {6, nullptr, "SetMinVClockRate"},
25 {7, nullptr, "SetReset"},
26 {8, nullptr, "SetVoltageEnabled"},
27 {9, nullptr, "GetVoltageEnabled"},
28 {10, nullptr, "GetVoltageRange"},
29 {11, nullptr, "SetVoltageValue"},
30 {12, nullptr, "GetVoltageValue"},
31 {13, nullptr, "GetTemperatureThresholds"},
32 {14, nullptr, "SetTemperature"},
33 {15, nullptr, "Initialize"},
34 {16, nullptr, "IsInitialized"},
35 {17, nullptr, "Finalize"},
36 {18, nullptr, "PowerOn"},
37 {19, nullptr, "PowerOff"},
38 {20, nullptr, "ChangeVoltage"},
39 {21, nullptr, "GetPowerClockInfoEvent"},
40 {22, nullptr, "GetOscillatorClock"},
41 {23, nullptr, "GetDvfsTable"},
42 {24, nullptr, "GetModuleStateTable"},
43 {25, nullptr, "GetPowerDomainStateTable"},
44 {26, nullptr, "GetFuseInfo"},
45 };
46 // clang-format on
47
48 RegisterHandlers(functions);
49 }
50};
51
52class PCV_ARB final : public ServiceFramework<PCV_ARB> {
53public:
54 explicit PCV_ARB() : ServiceFramework{"pcv:arb"} {
55 // clang-format off
56 static const FunctionInfo functions[] = {
57 {0, nullptr, "ReleaseControl"},
58 };
59 // clang-format on
60
61 RegisterHandlers(functions);
62 }
63};
64
65class PCV_IMM final : public ServiceFramework<PCV_IMM> {
66public:
67 explicit PCV_IMM() : ServiceFramework{"pcv:imm"} {
68 // clang-format off
69 static const FunctionInfo functions[] = {
70 {0, nullptr, "SetClockRate"},
71 };
72 // clang-format on
73
74 RegisterHandlers(functions);
75 }
76};
77
78void InstallInterfaces(SM::ServiceManager& sm) {
79 std::make_shared<PCV>()->InstallAsService(sm);
80 std::make_shared<PCV_ARB>()->InstallAsService(sm);
81 std::make_shared<PCV_IMM>()->InstallAsService(sm);
82}
83
84} // namespace Service::PCV
diff --git a/src/core/hle/service/pcv/pcv.h b/src/core/hle/service/pcv/pcv.h
new file mode 100644
index 000000000..219a893c3
--- /dev/null
+++ b/src/core/hle/service/pcv/pcv.h
@@ -0,0 +1,15 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::PCV {
12
13void InstallInterfaces(SM::ServiceManager& sm);
14
15} // namespace Service::PCV
diff --git a/src/core/hle/service/psc/psc.cpp b/src/core/hle/service/psc/psc.cpp
new file mode 100644
index 000000000..bbad870a2
--- /dev/null
+++ b/src/core/hle/service/psc/psc.cpp
@@ -0,0 +1,77 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <memory>
6
7#include "common/logging/log.h"
8#include "core/hle/ipc_helpers.h"
9#include "core/hle/service/psc/psc.h"
10#include "core/hle/service/service.h"
11#include "core/hle/service/sm/sm.h"
12
13namespace Service::PSC {
14
15class PSC_C final : public ServiceFramework<PSC_C> {
16public:
17 explicit PSC_C() : ServiceFramework{"psc:c"} {
18 // clang-format off
19 static const FunctionInfo functions[] = {
20 {0, nullptr, "Unknown1"},
21 {1, nullptr, "Unknown2"},
22 {2, nullptr, "Unknown3"},
23 {3, nullptr, "Unknown4"},
24 {4, nullptr, "Unknown5"},
25 {5, nullptr, "Unknown6"},
26 {6, nullptr, "Unknown7"},
27 };
28 // clang-format on
29
30 RegisterHandlers(functions);
31 }
32};
33
34class IPmModule final : public ServiceFramework<IPmModule> {
35public:
36 explicit IPmModule() : ServiceFramework{"IPmModule"} {
37 // clang-format off
38 static const FunctionInfo functions[] = {
39 {0, nullptr, "Initialize"},
40 {1, nullptr, "GetRequest"},
41 {2, nullptr, "Acknowledge"},
42 {3, nullptr, "Unknown1"},
43 };
44 // clang-format on
45
46 RegisterHandlers(functions);
47 }
48};
49
50class PSC_M final : public ServiceFramework<PSC_M> {
51public:
52 explicit PSC_M() : ServiceFramework{"psc:m"} {
53 // clang-format off
54 static const FunctionInfo functions[] = {
55 {0, &PSC_M::GetPmModule, "GetPmModule"},
56 };
57 // clang-format on
58
59 RegisterHandlers(functions);
60 }
61
62private:
63 void GetPmModule(Kernel::HLERequestContext& ctx) {
64 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
65 rb.Push(RESULT_SUCCESS);
66 rb.PushIpcInterface<IPmModule>();
67
68 LOG_DEBUG(Service_PSC, "called");
69 }
70};
71
72void InstallInterfaces(SM::ServiceManager& sm) {
73 std::make_shared<PSC_C>()->InstallAsService(sm);
74 std::make_shared<PSC_M>()->InstallAsService(sm);
75}
76
77} // namespace Service::PSC
diff --git a/src/core/hle/service/psc/psc.h b/src/core/hle/service/psc/psc.h
new file mode 100644
index 000000000..5052eb02c
--- /dev/null
+++ b/src/core/hle/service/psc/psc.h
@@ -0,0 +1,15 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::PSC {
12
13void InstallInterfaces(SM::ServiceManager& sm);
14
15} // namespace Service::PSC
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index fccc4c461..61e0c34a0 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -21,8 +21,10 @@
21#include "core/hle/service/apm/apm.h" 21#include "core/hle/service/apm/apm.h"
22#include "core/hle/service/audio/audio.h" 22#include "core/hle/service/audio/audio.h"
23#include "core/hle/service/bcat/bcat.h" 23#include "core/hle/service/bcat/bcat.h"
24#include "core/hle/service/bpc/bpc.h"
24#include "core/hle/service/btdrv/btdrv.h" 25#include "core/hle/service/btdrv/btdrv.h"
25#include "core/hle/service/btm/btm.h" 26#include "core/hle/service/btm/btm.h"
27#include "core/hle/service/caps/caps.h"
26#include "core/hle/service/erpt/erpt.h" 28#include "core/hle/service/erpt/erpt.h"
27#include "core/hle/service/es/es.h" 29#include "core/hle/service/es/es.h"
28#include "core/hle/service/eupld/eupld.h" 30#include "core/hle/service/eupld/eupld.h"
@@ -36,6 +38,7 @@
36#include "core/hle/service/ldn/ldn.h" 38#include "core/hle/service/ldn/ldn.h"
37#include "core/hle/service/ldr/ldr.h" 39#include "core/hle/service/ldr/ldr.h"
38#include "core/hle/service/lm/lm.h" 40#include "core/hle/service/lm/lm.h"
41#include "core/hle/service/mig/mig.h"
39#include "core/hle/service/mii/mii.h" 42#include "core/hle/service/mii/mii.h"
40#include "core/hle/service/mm/mm_u.h" 43#include "core/hle/service/mm/mm_u.h"
41#include "core/hle/service/ncm/ncm.h" 44#include "core/hle/service/ncm/ncm.h"
@@ -47,8 +50,10 @@
47#include "core/hle/service/nvdrv/nvdrv.h" 50#include "core/hle/service/nvdrv/nvdrv.h"
48#include "core/hle/service/pcie/pcie.h" 51#include "core/hle/service/pcie/pcie.h"
49#include "core/hle/service/pctl/pctl.h" 52#include "core/hle/service/pctl/pctl.h"
53#include "core/hle/service/pcv/pcv.h"
50#include "core/hle/service/pm/pm.h" 54#include "core/hle/service/pm/pm.h"
51#include "core/hle/service/prepo/prepo.h" 55#include "core/hle/service/prepo/prepo.h"
56#include "core/hle/service/psc/psc.h"
52#include "core/hle/service/service.h" 57#include "core/hle/service/service.h"
53#include "core/hle/service/set/settings.h" 58#include "core/hle/service/set/settings.h"
54#include "core/hle/service/sm/controller.h" 59#include "core/hle/service/sm/controller.h"
@@ -204,8 +209,10 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm) {
204 APM::InstallInterfaces(*sm); 209 APM::InstallInterfaces(*sm);
205 Audio::InstallInterfaces(*sm); 210 Audio::InstallInterfaces(*sm);
206 BCAT::InstallInterfaces(*sm); 211 BCAT::InstallInterfaces(*sm);
212 BPC::InstallInterfaces(*sm);
207 BtDrv::InstallInterfaces(*sm); 213 BtDrv::InstallInterfaces(*sm);
208 BTM::InstallInterfaces(*sm); 214 BTM::InstallInterfaces(*sm);
215 Capture::InstallInterfaces(*sm);
209 ERPT::InstallInterfaces(*sm); 216 ERPT::InstallInterfaces(*sm);
210 ES::InstallInterfaces(*sm); 217 ES::InstallInterfaces(*sm);
211 EUPLD::InstallInterfaces(*sm); 218 EUPLD::InstallInterfaces(*sm);
@@ -219,6 +226,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm) {
219 LDN::InstallInterfaces(*sm); 226 LDN::InstallInterfaces(*sm);
220 LDR::InstallInterfaces(*sm); 227 LDR::InstallInterfaces(*sm);
221 LM::InstallInterfaces(*sm); 228 LM::InstallInterfaces(*sm);
229 Migration::InstallInterfaces(*sm);
222 Mii::InstallInterfaces(*sm); 230 Mii::InstallInterfaces(*sm);
223 MM::InstallInterfaces(*sm); 231 MM::InstallInterfaces(*sm);
224 NCM::InstallInterfaces(*sm); 232 NCM::InstallInterfaces(*sm);
@@ -230,8 +238,10 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm) {
230 Nvidia::InstallInterfaces(*sm); 238 Nvidia::InstallInterfaces(*sm);
231 PCIe::InstallInterfaces(*sm); 239 PCIe::InstallInterfaces(*sm);
232 PCTL::InstallInterfaces(*sm); 240 PCTL::InstallInterfaces(*sm);
241 PCV::InstallInterfaces(*sm);
233 PlayReport::InstallInterfaces(*sm); 242 PlayReport::InstallInterfaces(*sm);
234 PM::InstallInterfaces(*sm); 243 PM::InstallInterfaces(*sm);
244 PSC::InstallInterfaces(*sm);
235 Set::InstallInterfaces(*sm); 245 Set::InstallInterfaces(*sm);
236 Sockets::InstallInterfaces(*sm); 246 Sockets::InstallInterfaces(*sm);
237 SPL::InstallInterfaces(*sm); 247 SPL::InstallInterfaces(*sm);
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index 180f22703..046c5e18d 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -8,10 +8,9 @@
8#include <string> 8#include <string>
9#include <unordered_map> 9#include <unordered_map>
10#include <boost/container/flat_map.hpp> 10#include <boost/container/flat_map.hpp>
11#include "common/bit_field.h"
12#include "common/common_types.h" 11#include "common/common_types.h"
13#include "core/hle/kernel/hle_ipc.h" 12#include "core/hle/kernel/hle_ipc.h"
14#include "core/hle/kernel/kernel.h" 13#include "core/hle/kernel/object.h"
15 14
16//////////////////////////////////////////////////////////////////////////////////////////////////// 15////////////////////////////////////////////////////////////////////////////////////////////////////
17// Namespace Service 16// Namespace Service
diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp
index 1651f6122..a461e72ec 100644
--- a/src/core/hle/service/set/set.cpp
+++ b/src/core/hle/service/set/set.cpp
@@ -8,6 +8,7 @@
8#include "core/hle/kernel/client_port.h" 8#include "core/hle/kernel/client_port.h"
9#include "core/hle/kernel/client_session.h" 9#include "core/hle/kernel/client_session.h"
10#include "core/hle/service/set/set.h" 10#include "core/hle/service/set/set.h"
11#include "core/settings.h"
11 12
12namespace Service::Set { 13namespace Service::Set {
13 14
@@ -31,6 +32,10 @@ constexpr std::array<LanguageCode, 17> available_language_codes = {{
31 LanguageCode::ZH_HANT, 32 LanguageCode::ZH_HANT,
32}}; 33}};
33 34
35LanguageCode GetLanguageCodeFromIndex(size_t index) {
36 return available_language_codes.at(index);
37}
38
34void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) { 39void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) {
35 ctx.WriteBuffer(available_language_codes); 40 ctx.WriteBuffer(available_language_codes);
36 41
@@ -49,9 +54,17 @@ void SET::GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx) {
49 LOG_DEBUG(Service_SET, "called"); 54 LOG_DEBUG(Service_SET, "called");
50} 55}
51 56
57void SET::GetLanguageCode(Kernel::HLERequestContext& ctx) {
58 IPC::ResponseBuilder rb{ctx, 4};
59 rb.Push(RESULT_SUCCESS);
60 rb.Push(static_cast<u64>(available_language_codes[Settings::values.language_index]));
61
62 LOG_DEBUG(Service_SET, "called {}", Settings::values.language_index);
63}
64
52SET::SET() : ServiceFramework("set") { 65SET::SET() : ServiceFramework("set") {
53 static const FunctionInfo functions[] = { 66 static const FunctionInfo functions[] = {
54 {0, nullptr, "GetLanguageCode"}, 67 {0, &SET::GetLanguageCode, "GetLanguageCode"},
55 {1, &SET::GetAvailableLanguageCodes, "GetAvailableLanguageCodes"}, 68 {1, &SET::GetAvailableLanguageCodes, "GetAvailableLanguageCodes"},
56 {2, nullptr, "MakeLanguageCode"}, 69 {2, nullptr, "MakeLanguageCode"},
57 {3, &SET::GetAvailableLanguageCodeCount, "GetAvailableLanguageCodeCount"}, 70 {3, &SET::GetAvailableLanguageCodeCount, "GetAvailableLanguageCodeCount"},
diff --git a/src/core/hle/service/set/set.h b/src/core/hle/service/set/set.h
index a2472ec4c..4232b6162 100644
--- a/src/core/hle/service/set/set.h
+++ b/src/core/hle/service/set/set.h
@@ -28,6 +28,7 @@ enum class LanguageCode : u64 {
28 ZH_HANS = 0x00736E61482D687A, 28 ZH_HANS = 0x00736E61482D687A,
29 ZH_HANT = 0x00746E61482D687A, 29 ZH_HANT = 0x00746E61482D687A,
30}; 30};
31LanguageCode GetLanguageCodeFromIndex(size_t idx);
31 32
32class SET final : public ServiceFramework<SET> { 33class SET final : public ServiceFramework<SET> {
33public: 34public:
@@ -35,6 +36,7 @@ public:
35 ~SET() = default; 36 ~SET() = default;
36 37
37private: 38private:
39 void GetLanguageCode(Kernel::HLERequestContext& ctx);
38 void GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx); 40 void GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx);
39 void GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx); 41 void GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx);
40}; 42};
diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h
index e2a00e4f6..e8ea62f08 100644
--- a/src/core/hle/service/sm/sm.h
+++ b/src/core/hle/service/sm/sm.h
@@ -4,9 +4,11 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <memory>
7#include <string> 8#include <string>
8#include <unordered_map> 9#include <unordered_map>
9#include "core/hle/kernel/kernel.h" 10
11#include "core/hle/kernel/object.h"
10#include "core/hle/result.h" 12#include "core/hle/result.h"
11#include "core/hle/service/service.h" 13#include "core/hle/service/service.h"
12 14
@@ -19,6 +21,8 @@ class SessionRequestHandler;
19 21
20namespace Service::SM { 22namespace Service::SM {
21 23
24class Controller;
25
22/// Interface to "sm:" service 26/// Interface to "sm:" service
23class SM final : public ServiceFramework<SM> { 27class SM final : public ServiceFramework<SM> {
24public: 28public:
@@ -32,8 +36,6 @@ private:
32 std::shared_ptr<ServiceManager> service_manager; 36 std::shared_ptr<ServiceManager> service_manager;
33}; 37};
34 38
35class Controller;
36
37constexpr ResultCode ERR_SERVICE_NOT_REGISTERED(-1); 39constexpr ResultCode ERR_SERVICE_NOT_REGISTERED(-1);
38constexpr ResultCode ERR_MAX_CONNECTIONS_REACHED(-1); 40constexpr ResultCode ERR_MAX_CONNECTIONS_REACHED(-1);
39constexpr ResultCode ERR_INVALID_NAME_SIZE(-1); 41constexpr ResultCode ERR_INVALID_NAME_SIZE(-1);
diff --git a/src/core/hw/aes/ccm.cpp b/src/core/hw/aes/ccm.cpp
deleted file mode 100644
index 1ee37aaa4..000000000
--- a/src/core/hw/aes/ccm.cpp
+++ /dev/null
@@ -1,28 +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 "common/alignment.h"
7#include "common/assert.h"
8#include "common/logging/log.h"
9#include "core/hw/aes/ccm.h"
10#include "core/hw/aes/key.h"
11
12namespace HW {
13namespace AES {
14
15std::vector<u8> EncryptSignCCM(const std::vector<u8>& pdata, const CCMNonce& nonce,
16 size_t slot_id) {
17 UNIMPLEMENTED();
18 return {};
19}
20
21std::vector<u8> DecryptVerifyCCM(const std::vector<u8>& cipher, const CCMNonce& nonce,
22 size_t slot_id) {
23 UNIMPLEMENTED();
24 return {};
25}
26
27} // namespace AES
28} // namespace HW
diff --git a/src/core/hw/hw.cpp b/src/core/hw/hw.cpp
deleted file mode 100644
index 2f48068c1..000000000
--- a/src/core/hw/hw.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/common_types.h"
6#include "common/logging/log.h"
7#include "core/hw/hw.h"
8#include "core/hw/lcd.h"
9
10namespace HW {
11
12template <typename T>
13inline void Read(T& var, const u32 addr) {
14 switch (addr & 0xFFFFF000) {
15 case VADDR_GPU:
16 case VADDR_GPU + 0x1000:
17 case VADDR_GPU + 0x2000:
18 case VADDR_GPU + 0x3000:
19 case VADDR_GPU + 0x4000:
20 case VADDR_GPU + 0x5000:
21 case VADDR_GPU + 0x6000:
22 case VADDR_GPU + 0x7000:
23 case VADDR_GPU + 0x8000:
24 case VADDR_GPU + 0x9000:
25 case VADDR_GPU + 0xA000:
26 case VADDR_GPU + 0xB000:
27 case VADDR_GPU + 0xC000:
28 case VADDR_GPU + 0xD000:
29 case VADDR_GPU + 0xE000:
30 case VADDR_GPU + 0xF000:
31 break;
32 case VADDR_LCD:
33 LCD::Read(var, addr);
34 break;
35 default:
36 LOG_ERROR(HW_Memory, "Unknown Read{} @ 0x{:08X}", sizeof(var) * 8, addr);
37 break;
38 }
39}
40
41template <typename T>
42inline void Write(u32 addr, const T data) {
43 switch (addr & 0xFFFFF000) {
44 case VADDR_GPU:
45 case VADDR_GPU + 0x1000:
46 case VADDR_GPU + 0x2000:
47 case VADDR_GPU + 0x3000:
48 case VADDR_GPU + 0x4000:
49 case VADDR_GPU + 0x5000:
50 case VADDR_GPU + 0x6000:
51 case VADDR_GPU + 0x7000:
52 case VADDR_GPU + 0x8000:
53 case VADDR_GPU + 0x9000:
54 case VADDR_GPU + 0xA000:
55 case VADDR_GPU + 0xB000:
56 case VADDR_GPU + 0xC000:
57 case VADDR_GPU + 0xD000:
58 case VADDR_GPU + 0xE000:
59 case VADDR_GPU + 0xF000:
60 break;
61 case VADDR_LCD:
62 LCD::Write(addr, data);
63 break;
64 default:
65 LOG_ERROR(HW_Memory, "Unknown Write{} 0x{:08X} @ 0x{:08X}", sizeof(data) * 8, data, addr);
66 break;
67 }
68}
69
70// Explicitly instantiate template functions because we aren't defining this in the header:
71
72template void Read<u64>(u64& var, const u32 addr);
73template void Read<u32>(u32& var, const u32 addr);
74template void Read<u16>(u16& var, const u32 addr);
75template void Read<u8>(u8& var, const u32 addr);
76
77template void Write<u64>(u32 addr, const u64 data);
78template void Write<u32>(u32 addr, const u32 data);
79template void Write<u16>(u32 addr, const u16 data);
80template void Write<u8>(u32 addr, const u8 data);
81
82/// Update hardware
83void Update() {}
84
85/// Initialize hardware
86void Init() {
87 LCD::Init();
88 LOG_DEBUG(HW, "Initialized OK");
89}
90
91/// Shutdown hardware
92void Shutdown() {
93 LCD::Shutdown();
94 LOG_DEBUG(HW, "Shutdown OK");
95}
96} // namespace HW
diff --git a/src/core/hw/hw.h b/src/core/hw/hw.h
deleted file mode 100644
index 5890d2b5c..000000000
--- a/src/core/hw/hw.h
+++ /dev/null
@@ -1,50 +0,0 @@
1// Copyright 2014 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 "common/common_types.h"
8
9namespace HW {
10
11/// Beginnings of IO register regions, in the user VA space.
12enum : u32 {
13 VADDR_HASH = 0x1EC01000,
14 VADDR_CSND = 0x1EC03000,
15 VADDR_DSP = 0x1EC40000,
16 VADDR_PDN = 0x1EC41000,
17 VADDR_CODEC = 0x1EC41000,
18 VADDR_SPI = 0x1EC42000,
19 VADDR_SPI_2 = 0x1EC43000, // Only used under TWL_FIRM?
20 VADDR_I2C = 0x1EC44000,
21 VADDR_CODEC_2 = 0x1EC45000,
22 VADDR_HID = 0x1EC46000,
23 VADDR_GPIO = 0x1EC47000,
24 VADDR_I2C_2 = 0x1EC48000,
25 VADDR_SPI_3 = 0x1EC60000,
26 VADDR_I2C_3 = 0x1EC61000,
27 VADDR_MIC = 0x1EC62000,
28 VADDR_PXI = 0x1EC63000,
29 VADDR_LCD = 0x1ED02000,
30 VADDR_DSP_2 = 0x1ED03000,
31 VADDR_HASH_2 = 0x1EE01000,
32 VADDR_GPU = 0x1EF00000,
33};
34
35template <typename T>
36void Read(T& var, const u32 addr);
37
38template <typename T>
39void Write(u32 addr, const T data);
40
41/// Update hardware
42void Update();
43
44/// Initialize hardware
45void Init();
46
47/// Shutdown hardware
48void Shutdown();
49
50} // namespace HW
diff --git a/src/core/hw/lcd.cpp b/src/core/hw/lcd.cpp
deleted file mode 100644
index 0b62174d5..000000000
--- a/src/core/hw/lcd.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <cstring>
6#include "common/common_types.h"
7#include "common/logging/log.h"
8#include "core/hw/hw.h"
9#include "core/hw/lcd.h"
10#include "core/tracer/recorder.h"
11
12namespace LCD {
13
14Regs g_regs;
15
16template <typename T>
17inline void Read(T& var, const u32 raw_addr) {
18 u32 addr = raw_addr - HW::VADDR_LCD;
19 u32 index = addr / 4;
20
21 // Reads other than u32 are untested, so I'd rather have them abort than silently fail
22 if (index >= 0x400 || !std::is_same<T, u32>::value) {
23 LOG_ERROR(HW_LCD, "Unknown Read{} @ 0x{:08X}", sizeof(var) * 8, addr);
24 return;
25 }
26
27 var = g_regs[index];
28}
29
30template <typename T>
31inline void Write(u32 addr, const T data) {
32 addr -= HW::VADDR_LCD;
33 u32 index = addr / 4;
34
35 // Writes other than u32 are untested, so I'd rather have them abort than silently fail
36 if (index >= 0x400 || !std::is_same<T, u32>::value) {
37 LOG_ERROR(HW_LCD, "Unknown Write{} 0x{:08X} @ 0x{:08X}", sizeof(data) * 8, data, addr);
38 return;
39 }
40
41 g_regs[index] = static_cast<u32>(data);
42}
43
44// Explicitly instantiate template functions because we aren't defining this in the header:
45
46template void Read<u64>(u64& var, const u32 addr);
47template void Read<u32>(u32& var, const u32 addr);
48template void Read<u16>(u16& var, const u32 addr);
49template void Read<u8>(u8& var, const u32 addr);
50
51template void Write<u64>(u32 addr, const u64 data);
52template void Write<u32>(u32 addr, const u32 data);
53template void Write<u16>(u32 addr, const u16 data);
54template void Write<u8>(u32 addr, const u8 data);
55
56/// Initialize hardware
57void Init() {
58 memset(&g_regs, 0, sizeof(g_regs));
59 LOG_DEBUG(HW_LCD, "Initialized OK");
60}
61
62/// Shutdown hardware
63void Shutdown() {
64 LOG_DEBUG(HW_LCD, "Shutdown OK");
65}
66
67} // namespace LCD
diff --git a/src/core/hw/lcd.h b/src/core/hw/lcd.h
deleted file mode 100644
index d2db9700f..000000000
--- a/src/core/hw/lcd.h
+++ /dev/null
@@ -1,86 +0,0 @@
1// Copyright 2015 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 <cstddef>
8#include <type_traits>
9#include "common/bit_field.h"
10#include "common/common_funcs.h"
11#include "common/common_types.h"
12
13#define LCD_REG_INDEX(field_name) (offsetof(LCD::Regs, field_name) / sizeof(u32))
14
15namespace LCD {
16
17struct Regs {
18
19 union ColorFill {
20 u32 raw;
21
22 BitField<0, 8, u32> color_r;
23 BitField<8, 8, u32> color_g;
24 BitField<16, 8, u32> color_b;
25 BitField<24, 1, u32> is_enabled;
26 };
27
28 INSERT_PADDING_WORDS(0x81);
29 ColorFill color_fill_top;
30 INSERT_PADDING_WORDS(0xE);
31 u32 backlight_top;
32
33 INSERT_PADDING_WORDS(0x1F0);
34
35 ColorFill color_fill_bottom;
36 INSERT_PADDING_WORDS(0xE);
37 u32 backlight_bottom;
38 INSERT_PADDING_WORDS(0x16F);
39
40 static constexpr size_t NumIds() {
41 return sizeof(Regs) / sizeof(u32);
42 }
43
44 const u32& operator[](int index) const {
45 const u32* content = reinterpret_cast<const u32*>(this);
46 return content[index];
47 }
48
49 u32& operator[](int index) {
50 u32* content = reinterpret_cast<u32*>(this);
51 return content[index];
52 }
53};
54static_assert(std::is_standard_layout<Regs>::value, "Structure does not use standard layout");
55
56// TODO: MSVC does not support using offsetof() on non-static data members even though this
57// is technically allowed since C++11. This macro should be enabled once MSVC adds
58// support for that.
59#ifndef _MSC_VER
60#define ASSERT_REG_POSITION(field_name, position) \
61 static_assert(offsetof(Regs, field_name) == position * 4, \
62 "Field " #field_name " has invalid position")
63
64ASSERT_REG_POSITION(color_fill_top, 0x81);
65ASSERT_REG_POSITION(backlight_top, 0x90);
66ASSERT_REG_POSITION(color_fill_bottom, 0x281);
67ASSERT_REG_POSITION(backlight_bottom, 0x290);
68
69#undef ASSERT_REG_POSITION
70#endif // !defined(_MSC_VER)
71
72extern Regs g_regs;
73
74template <typename T>
75void Read(T& var, const u32 addr);
76
77template <typename T>
78void Write(u32 addr, const T data);
79
80/// Initialize hardware
81void Init();
82
83/// Shutdown hardware
84void Shutdown();
85
86} // namespace LCD
diff --git a/src/core/loader/deconstructed_rom_directory.h b/src/core/loader/deconstructed_rom_directory.h
index 982a037f7..7319ba6ea 100644
--- a/src/core/loader/deconstructed_rom_directory.h
+++ b/src/core/loader/deconstructed_rom_directory.h
@@ -7,7 +7,7 @@
7#include <string> 7#include <string>
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "core/file_sys/program_metadata.h" 9#include "core/file_sys/program_metadata.h"
10#include "core/hle/kernel/kernel.h" 10#include "core/hle/kernel/object.h"
11#include "core/loader/loader.h" 11#include "core/loader/loader.h"
12 12
13namespace Loader { 13namespace Loader {
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp
index 352938dcb..a7133f5a6 100644
--- a/src/core/loader/elf.cpp
+++ b/src/core/loader/elf.cpp
@@ -311,11 +311,11 @@ SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) {
311 CodeSet::Segment* codeset_segment; 311 CodeSet::Segment* codeset_segment;
312 u32 permission_flags = p->p_flags & (PF_R | PF_W | PF_X); 312 u32 permission_flags = p->p_flags & (PF_R | PF_W | PF_X);
313 if (permission_flags == (PF_R | PF_X)) { 313 if (permission_flags == (PF_R | PF_X)) {
314 codeset_segment = &codeset->code; 314 codeset_segment = &codeset->CodeSegment();
315 } else if (permission_flags == (PF_R)) { 315 } else if (permission_flags == (PF_R)) {
316 codeset_segment = &codeset->rodata; 316 codeset_segment = &codeset->RODataSegment();
317 } else if (permission_flags == (PF_R | PF_W)) { 317 } else if (permission_flags == (PF_R | PF_W)) {
318 codeset_segment = &codeset->data; 318 codeset_segment = &codeset->DataSegment();
319 } else { 319 } else {
320 LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id {} with flags {:X}", i, 320 LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id {} with flags {:X}", i,
321 p->p_flags); 321 p->p_flags);
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h
index cd8b41bb6..e69ab85ef 100644
--- a/src/core/loader/loader.h
+++ b/src/core/loader/loader.h
@@ -14,7 +14,7 @@
14#include "common/common_types.h" 14#include "common/common_types.h"
15#include "common/file_util.h" 15#include "common/file_util.h"
16#include "core/file_sys/vfs.h" 16#include "core/file_sys/vfs.h"
17#include "core/hle/kernel/kernel.h" 17#include "core/hle/kernel/object.h"
18 18
19namespace Kernel { 19namespace Kernel {
20struct AddressMapping; 20struct AddressMapping;
diff --git a/src/core/loader/nca.h b/src/core/loader/nca.h
index fb96c0a22..e14d618b3 100644
--- a/src/core/loader/nca.h
+++ b/src/core/loader/nca.h
@@ -8,7 +8,7 @@
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "core/file_sys/content_archive.h" 9#include "core/file_sys/content_archive.h"
10#include "core/file_sys/program_metadata.h" 10#include "core/file_sys/program_metadata.h"
11#include "core/hle/kernel/kernel.h" 11#include "core/hle/kernel/object.h"
12#include "core/loader/loader.h" 12#include "core/loader/loader.h"
13 13
14namespace Loader { 14namespace Loader {
diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp
index 7d3ec2a76..dc053cdad 100644
--- a/src/core/loader/nro.cpp
+++ b/src/core/loader/nro.cpp
@@ -159,7 +159,7 @@ bool AppLoader_NRO::LoadNro(FileSys::VirtualFile file, VAddr load_base) {
159 // Resize program image to include .bss section and page align each section 159 // Resize program image to include .bss section and page align each section
160 bss_size = PageAlignSize(mod_header.bss_end_offset - mod_header.bss_start_offset); 160 bss_size = PageAlignSize(mod_header.bss_end_offset - mod_header.bss_start_offset);
161 } 161 }
162 codeset->data.size += bss_size; 162 codeset->DataSegment().size += bss_size;
163 program_image.resize(static_cast<u32>(program_image.size()) + bss_size); 163 program_image.resize(static_cast<u32>(program_image.size()) + bss_size);
164 164
165 // Load codeset for current process 165 // Load codeset for current process
diff --git a/src/core/loader/nro.h b/src/core/loader/nro.h
index 04a0f497e..bb01c9e25 100644
--- a/src/core/loader/nro.h
+++ b/src/core/loader/nro.h
@@ -6,7 +6,7 @@
6 6
7#include <string> 7#include <string>
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "core/hle/kernel/kernel.h" 9#include "core/hle/kernel/object.h"
10#include "core/loader/linker.h" 10#include "core/loader/linker.h"
11#include "core/loader/loader.h" 11#include "core/loader/loader.h"
12 12
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp
index 06b1b33f4..fee7d58c6 100644
--- a/src/core/loader/nso.cpp
+++ b/src/core/loader/nso.cpp
@@ -127,7 +127,7 @@ VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base) {
127 // Resize program image to include .bss section and page align each section 127 // Resize program image to include .bss section and page align each section
128 bss_size = PageAlignSize(mod_header.bss_end_offset - mod_header.bss_start_offset); 128 bss_size = PageAlignSize(mod_header.bss_end_offset - mod_header.bss_start_offset);
129 } 129 }
130 codeset->data.size += bss_size; 130 codeset->DataSegment().size += bss_size;
131 const u32 image_size{PageAlignSize(static_cast<u32>(program_image.size()) + bss_size)}; 131 const u32 image_size{PageAlignSize(static_cast<u32>(program_image.size()) + bss_size)};
132 program_image.resize(image_size); 132 program_image.resize(image_size);
133 133
diff --git a/src/core/loader/nso.h b/src/core/loader/nso.h
index 3f7567500..aaeb1f2a9 100644
--- a/src/core/loader/nso.h
+++ b/src/core/loader/nso.h
@@ -6,7 +6,7 @@
6 6
7#include <string> 7#include <string>
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "core/hle/kernel/kernel.h" 9#include "core/hle/kernel/object.h"
10#include "core/loader/linker.h" 10#include "core/loader/linker.h"
11#include "core/loader/loader.h" 11#include "core/loader/loader.h"
12 12
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index e753e3436..4b3bb7b31 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -14,7 +14,6 @@
14#include "common/swap.h" 14#include "common/swap.h"
15#include "core/arm/arm_interface.h" 15#include "core/arm/arm_interface.h"
16#include "core/core.h" 16#include "core/core.h"
17#include "core/hle/kernel/memory.h"
18#include "core/hle/kernel/process.h" 17#include "core/hle/kernel/process.h"
19#include "core/hle/lock.h" 18#include "core/hle/lock.h"
20#include "core/memory.h" 19#include "core/memory.h"
@@ -24,8 +23,6 @@
24 23
25namespace Memory { 24namespace Memory {
26 25
27static std::array<u8, Memory::VRAM_SIZE> vram;
28
29static PageTable* current_page_table = nullptr; 26static PageTable* current_page_table = nullptr;
30 27
31void SetCurrentPageTable(PageTable* page_table) { 28void SetCurrentPageTable(PageTable* page_table) {
@@ -102,22 +99,6 @@ void RemoveDebugHook(PageTable& page_table, VAddr base, u64 size, MemoryHookPoin
102} 99}
103 100
104/** 101/**
105 * This function should only be called for virtual addreses with attribute `PageType::Special`.
106 */
107static std::set<MemoryHookPointer> GetSpecialHandlers(const PageTable& page_table, VAddr vaddr,
108 u64 size) {
109 std::set<MemoryHookPointer> result;
110 auto interval = boost::icl::discrete_interval<VAddr>::closed(vaddr, vaddr + size - 1);
111 auto interval_list = page_table.special_regions.equal_range(interval);
112 for (auto it = interval_list.first; it != interval_list.second; ++it) {
113 for (const auto& region : it->second) {
114 result.insert(region.handler);
115 }
116 }
117 return result;
118}
119
120/**
121 * Gets a pointer to the exact memory at the virtual address (i.e. not page aligned) 102 * Gets a pointer to the exact memory at the virtual address (i.e. not page aligned)
122 * using a VMA from the current process 103 * using a VMA from the current process
123 */ 104 */
@@ -242,10 +223,6 @@ bool IsKernelVirtualAddress(const VAddr vaddr) {
242 return KERNEL_REGION_VADDR <= vaddr && vaddr < KERNEL_REGION_END; 223 return KERNEL_REGION_VADDR <= vaddr && vaddr < KERNEL_REGION_END;
243} 224}
244 225
245bool IsValidPhysicalAddress(const PAddr paddr) {
246 return GetPhysicalPointer(paddr) != nullptr;
247}
248
249u8* GetPointer(const VAddr vaddr) { 226u8* GetPointer(const VAddr vaddr) {
250 u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; 227 u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS];
251 if (page_pointer) { 228 if (page_pointer) {
@@ -274,61 +251,6 @@ std::string ReadCString(VAddr vaddr, std::size_t max_length) {
274 return string; 251 return string;
275} 252}
276 253
277u8* GetPhysicalPointer(PAddr address) {
278 struct MemoryArea {
279 PAddr paddr_base;
280 u32 size;
281 };
282
283 static constexpr MemoryArea memory_areas[] = {
284 {VRAM_PADDR, VRAM_SIZE},
285 {IO_AREA_PADDR, IO_AREA_SIZE},
286 {DSP_RAM_PADDR, DSP_RAM_SIZE},
287 {FCRAM_PADDR, FCRAM_N3DS_SIZE},
288 };
289
290 const auto area =
291 std::find_if(std::begin(memory_areas), std::end(memory_areas), [&](const auto& area) {
292 return address >= area.paddr_base && address < area.paddr_base + area.size;
293 });
294
295 if (area == std::end(memory_areas)) {
296 LOG_ERROR(HW_Memory, "Unknown GetPhysicalPointer @ 0x{:016X}", address);
297 return nullptr;
298 }
299
300 if (area->paddr_base == IO_AREA_PADDR) {
301 LOG_ERROR(HW_Memory, "MMIO mappings are not supported yet. phys_addr={:016X}", address);
302 return nullptr;
303 }
304
305 u64 offset_into_region = address - area->paddr_base;
306
307 u8* target_pointer = nullptr;
308 switch (area->paddr_base) {
309 case VRAM_PADDR:
310 target_pointer = vram.data() + offset_into_region;
311 break;
312 case DSP_RAM_PADDR:
313 break;
314 case FCRAM_PADDR:
315 for (const auto& region : Kernel::memory_regions) {
316 if (offset_into_region >= region.base &&
317 offset_into_region < region.base + region.size) {
318 target_pointer =
319 region.linear_heap_memory->data() + offset_into_region - region.base;
320 break;
321 }
322 }
323 ASSERT_MSG(target_pointer != nullptr, "Invalid FCRAM address");
324 break;
325 default:
326 UNREACHABLE();
327 }
328
329 return target_pointer;
330}
331
332void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached) { 254void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached) {
333 if (gpu_addr == 0) { 255 if (gpu_addr == 0) {
334 return; 256 return;
@@ -666,48 +588,4 @@ void CopyBlock(VAddr dest_addr, VAddr src_addr, size_t size) {
666 CopyBlock(*Core::CurrentProcess(), dest_addr, src_addr, size); 588 CopyBlock(*Core::CurrentProcess(), dest_addr, src_addr, size);
667} 589}
668 590
669boost::optional<PAddr> TryVirtualToPhysicalAddress(const VAddr addr) {
670 if (addr == 0) {
671 return 0;
672 } else if (addr >= VRAM_VADDR && addr < VRAM_VADDR_END) {
673 return addr - VRAM_VADDR + VRAM_PADDR;
674 } else if (addr >= LINEAR_HEAP_VADDR && addr < LINEAR_HEAP_VADDR_END) {
675 return addr - LINEAR_HEAP_VADDR + FCRAM_PADDR;
676 } else if (addr >= NEW_LINEAR_HEAP_VADDR && addr < NEW_LINEAR_HEAP_VADDR_END) {
677 return addr - NEW_LINEAR_HEAP_VADDR + FCRAM_PADDR;
678 } else if (addr >= DSP_RAM_VADDR && addr < DSP_RAM_VADDR_END) {
679 return addr - DSP_RAM_VADDR + DSP_RAM_PADDR;
680 } else if (addr >= IO_AREA_VADDR && addr < IO_AREA_VADDR_END) {
681 return addr - IO_AREA_VADDR + IO_AREA_PADDR;
682 }
683
684 return boost::none;
685}
686
687PAddr VirtualToPhysicalAddress(const VAddr addr) {
688 auto paddr = TryVirtualToPhysicalAddress(addr);
689 if (!paddr) {
690 LOG_ERROR(HW_Memory, "Unknown virtual address @ 0x{:016X}", addr);
691 // To help with debugging, set bit on address so that it's obviously invalid.
692 return addr | 0x80000000;
693 }
694 return *paddr;
695}
696
697boost::optional<VAddr> PhysicalToVirtualAddress(const PAddr addr) {
698 if (addr == 0) {
699 return 0;
700 } else if (addr >= VRAM_PADDR && addr < VRAM_PADDR_END) {
701 return addr - VRAM_PADDR + VRAM_VADDR;
702 } else if (addr >= FCRAM_PADDR && addr < FCRAM_PADDR_END) {
703 return addr - FCRAM_PADDR + Core::CurrentProcess()->GetLinearHeapAreaAddress();
704 } else if (addr >= DSP_RAM_PADDR && addr < DSP_RAM_PADDR_END) {
705 return addr - DSP_RAM_PADDR + DSP_RAM_VADDR;
706 } else if (addr >= IO_AREA_PADDR && addr < IO_AREA_PADDR_END) {
707 return addr - IO_AREA_PADDR + IO_AREA_VADDR;
708 }
709
710 return boost::none;
711}
712
713} // namespace Memory 591} // namespace Memory
diff --git a/src/core/memory.h b/src/core/memory.h
index 8d5d017a4..b5d885b8a 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -6,12 +6,9 @@
6 6
7#include <array> 7#include <array>
8#include <cstddef> 8#include <cstddef>
9#include <map>
10#include <string> 9#include <string>
11#include <tuple> 10#include <tuple>
12#include <vector>
13#include <boost/icl/interval_map.hpp> 11#include <boost/icl/interval_map.hpp>
14#include <boost/optional.hpp>
15#include "common/common_types.h" 12#include "common/common_types.h"
16#include "core/memory_hook.h" 13#include "core/memory_hook.h"
17#include "video_core/memory_manager.h" 14#include "video_core/memory_manager.h"
@@ -85,40 +82,6 @@ struct PageTable {
85 std::array<PageType, PAGE_TABLE_NUM_ENTRIES> attributes; 82 std::array<PageType, PAGE_TABLE_NUM_ENTRIES> attributes;
86}; 83};
87 84
88/// Physical memory regions as seen from the ARM11
89enum : PAddr {
90 /// IO register area
91 IO_AREA_PADDR = 0x10100000,
92 IO_AREA_SIZE = 0x01000000, ///< IO area size (16MB)
93 IO_AREA_PADDR_END = IO_AREA_PADDR + IO_AREA_SIZE,
94
95 /// MPCore internal memory region
96 MPCORE_RAM_PADDR = 0x17E00000,
97 MPCORE_RAM_SIZE = 0x00002000, ///< MPCore internal memory size (8KB)
98 MPCORE_RAM_PADDR_END = MPCORE_RAM_PADDR + MPCORE_RAM_SIZE,
99
100 /// Video memory
101 VRAM_PADDR = 0x18000000,
102 VRAM_SIZE = 0x00600000, ///< VRAM size (6MB)
103 VRAM_PADDR_END = VRAM_PADDR + VRAM_SIZE,
104
105 /// DSP memory
106 DSP_RAM_PADDR = 0x1FF00000,
107 DSP_RAM_SIZE = 0x00080000, ///< DSP memory size (512KB)
108 DSP_RAM_PADDR_END = DSP_RAM_PADDR + DSP_RAM_SIZE,
109
110 /// AXI WRAM
111 AXI_WRAM_PADDR = 0x1FF80000,
112 AXI_WRAM_SIZE = 0x00080000, ///< AXI WRAM size (512KB)
113 AXI_WRAM_PADDR_END = AXI_WRAM_PADDR + AXI_WRAM_SIZE,
114
115 /// Main FCRAM
116 FCRAM_PADDR = 0x20000000,
117 FCRAM_SIZE = 0x08000000, ///< FCRAM size on the Old 3DS (128MB)
118 FCRAM_N3DS_SIZE = 0x10000000, ///< FCRAM size on the New 3DS (256MB)
119 FCRAM_PADDR_END = FCRAM_PADDR + FCRAM_SIZE,
120};
121
122/// Virtual user-space memory regions 85/// Virtual user-space memory regions
123enum : VAddr { 86enum : VAddr {
124 /// Where the application text, data and bss reside. 87 /// Where the application text, data and bss reside.
@@ -126,24 +89,6 @@ enum : VAddr {
126 PROCESS_IMAGE_MAX_SIZE = 0x08000000, 89 PROCESS_IMAGE_MAX_SIZE = 0x08000000,
127 PROCESS_IMAGE_VADDR_END = PROCESS_IMAGE_VADDR + PROCESS_IMAGE_MAX_SIZE, 90 PROCESS_IMAGE_VADDR_END = PROCESS_IMAGE_VADDR + PROCESS_IMAGE_MAX_SIZE,
128 91
129 /// Maps 1:1 to an offset in FCRAM. Used for HW allocations that need to be linear in physical
130 /// memory.
131 LINEAR_HEAP_VADDR = 0x14000000,
132 LINEAR_HEAP_SIZE = 0x08000000,
133 LINEAR_HEAP_VADDR_END = LINEAR_HEAP_VADDR + LINEAR_HEAP_SIZE,
134
135 /// Maps 1:1 to the IO register area.
136 IO_AREA_VADDR = 0x1EC00000,
137 IO_AREA_VADDR_END = IO_AREA_VADDR + IO_AREA_SIZE,
138
139 /// Maps 1:1 to VRAM.
140 VRAM_VADDR = 0x1F000000,
141 VRAM_VADDR_END = VRAM_VADDR + VRAM_SIZE,
142
143 /// Maps 1:1 to DSP memory.
144 DSP_RAM_VADDR = 0x1FF00000,
145 DSP_RAM_VADDR_END = DSP_RAM_VADDR + DSP_RAM_SIZE,
146
147 /// Read-only page containing kernel and system configuration values. 92 /// Read-only page containing kernel and system configuration values.
148 CONFIG_MEMORY_VADDR = 0x1FF80000, 93 CONFIG_MEMORY_VADDR = 0x1FF80000,
149 CONFIG_MEMORY_SIZE = 0x00001000, 94 CONFIG_MEMORY_SIZE = 0x00001000,
@@ -154,13 +99,8 @@ enum : VAddr {
154 SHARED_PAGE_SIZE = 0x00001000, 99 SHARED_PAGE_SIZE = 0x00001000,
155 SHARED_PAGE_VADDR_END = SHARED_PAGE_VADDR + SHARED_PAGE_SIZE, 100 SHARED_PAGE_VADDR_END = SHARED_PAGE_VADDR + SHARED_PAGE_SIZE,
156 101
157 /// Equivalent to LINEAR_HEAP_VADDR, but expanded to cover the extra memory in the New 3DS.
158 NEW_LINEAR_HEAP_VADDR = 0x30000000,
159 NEW_LINEAR_HEAP_SIZE = 0x10000000,
160 NEW_LINEAR_HEAP_VADDR_END = NEW_LINEAR_HEAP_VADDR + NEW_LINEAR_HEAP_SIZE,
161
162 /// Area where TLS (Thread-Local Storage) buffers are allocated. 102 /// Area where TLS (Thread-Local Storage) buffers are allocated.
163 TLS_AREA_VADDR = NEW_LINEAR_HEAP_VADDR_END, 103 TLS_AREA_VADDR = 0x40000000,
164 TLS_ENTRY_SIZE = 0x200, 104 TLS_ENTRY_SIZE = 0x200,
165 TLS_AREA_SIZE = 0x10000000, 105 TLS_AREA_SIZE = 0x10000000,
166 TLS_AREA_VADDR_END = TLS_AREA_VADDR + TLS_AREA_SIZE, 106 TLS_AREA_VADDR_END = TLS_AREA_VADDR + TLS_AREA_SIZE,
@@ -205,8 +145,6 @@ bool IsValidVirtualAddress(const VAddr addr);
205/// Determines if the given VAddr is a kernel address 145/// Determines if the given VAddr is a kernel address
206bool IsKernelVirtualAddress(const VAddr addr); 146bool IsKernelVirtualAddress(const VAddr addr);
207 147
208bool IsValidPhysicalAddress(const PAddr addr);
209
210u8 Read8(VAddr addr); 148u8 Read8(VAddr addr);
211u16 Read16(VAddr addr); 149u16 Read16(VAddr addr);
212u32 Read32(VAddr addr); 150u32 Read32(VAddr addr);
@@ -230,30 +168,6 @@ u8* GetPointer(VAddr virtual_address);
230 168
231std::string ReadCString(VAddr virtual_address, std::size_t max_length); 169std::string ReadCString(VAddr virtual_address, std::size_t max_length);
232 170
233/**
234 * Converts a virtual address inside a region with 1:1 mapping to physical memory to a physical
235 * address. This should be used by services to translate addresses for use by the hardware.
236 */
237boost::optional<PAddr> TryVirtualToPhysicalAddress(VAddr addr);
238
239/**
240 * Converts a virtual address inside a region with 1:1 mapping to physical memory to a physical
241 * address. This should be used by services to translate addresses for use by the hardware.
242 *
243 * @deprecated Use TryVirtualToPhysicalAddress(), which reports failure.
244 */
245PAddr VirtualToPhysicalAddress(VAddr addr);
246
247/**
248 * Undoes a mapping performed by VirtualToPhysicalAddress().
249 */
250boost::optional<VAddr> PhysicalToVirtualAddress(PAddr addr);
251
252/**
253 * Gets a pointer to the memory region beginning at the specified physical address.
254 */
255u8* GetPhysicalPointer(PAddr address);
256
257enum class FlushMode { 171enum class FlushMode {
258 /// Write back modified surfaces to RAM 172 /// Write back modified surfaces to RAM
259 Flush, 173 Flush,
diff --git a/src/core/settings.cpp b/src/core/settings.cpp
index 444bcc387..79e0b347b 100644
--- a/src/core/settings.cpp
+++ b/src/core/settings.cpp
@@ -5,10 +5,9 @@
5#include "core/gdbstub/gdbstub.h" 5#include "core/gdbstub/gdbstub.h"
6#include "core/hle/service/hid/hid.h" 6#include "core/hle/service/hid/hid.h"
7#include "core/settings.h" 7#include "core/settings.h"
8#include "video_core/renderer_base.h"
8#include "video_core/video_core.h" 9#include "video_core/video_core.h"
9 10
10#include "core/frontend/emu_window.h"
11
12namespace Settings { 11namespace Settings {
13 12
14Values values = {}; 13Values values = {};
@@ -20,9 +19,8 @@ void Apply() {
20 19
21 VideoCore::g_toggle_framelimit_enabled = values.toggle_framelimit; 20 VideoCore::g_toggle_framelimit_enabled = values.toggle_framelimit;
22 21
23 if (VideoCore::g_emu_window) { 22 if (VideoCore::g_renderer) {
24 auto layout = VideoCore::g_emu_window->GetFramebufferLayout(); 23 VideoCore::g_renderer->UpdateCurrentFramebufferLayout();
25 VideoCore::g_emu_window->UpdateCurrentFramebufferLayout(layout.width, layout.height);
26 } 24 }
27 25
28 Service::HID::ReloadInputDevices(); 26 Service::HID::ReloadInputDevices();
diff --git a/src/core/settings.h b/src/core/settings.h
index 55da39b6c..73dc3061f 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -112,6 +112,8 @@ static const std::array<const char*, NumAnalogs> mapping = {{
112struct Values { 112struct Values {
113 // System 113 // System
114 bool use_docked_mode; 114 bool use_docked_mode;
115 std::string username;
116 int language_index;
115 117
116 // Controls 118 // Controls
117 std::array<std::string, NativeButton::NumButtons> buttons; 119 std::array<std::string, NativeButton::NumButtons> buttons;
diff --git a/src/input_common/keyboard.cpp b/src/input_common/keyboard.cpp
index 0f0d10f23..525fe6abc 100644
--- a/src/input_common/keyboard.cpp
+++ b/src/input_common/keyboard.cpp
@@ -5,6 +5,7 @@
5#include <atomic> 5#include <atomic>
6#include <list> 6#include <list>
7#include <mutex> 7#include <mutex>
8#include <utility>
8#include "input_common/keyboard.h" 9#include "input_common/keyboard.h"
9 10
10namespace InputCommon { 11namespace InputCommon {
@@ -12,9 +13,9 @@ namespace InputCommon {
12class KeyButton final : public Input::ButtonDevice { 13class KeyButton final : public Input::ButtonDevice {
13public: 14public:
14 explicit KeyButton(std::shared_ptr<KeyButtonList> key_button_list_) 15 explicit KeyButton(std::shared_ptr<KeyButtonList> key_button_list_)
15 : key_button_list(key_button_list_) {} 16 : key_button_list(std::move(key_button_list_)) {}
16 17
17 ~KeyButton(); 18 ~KeyButton() override;
18 19
19 bool GetStatus() const override { 20 bool GetStatus() const override {
20 return status.load(); 21 return status.load();
diff --git a/src/input_common/motion_emu.cpp b/src/input_common/motion_emu.cpp
index caffe48cb..9570c060e 100644
--- a/src/input_common/motion_emu.cpp
+++ b/src/input_common/motion_emu.cpp
@@ -131,7 +131,7 @@ public:
131 device = std::make_shared<MotionEmuDevice>(update_millisecond, sensitivity); 131 device = std::make_shared<MotionEmuDevice>(update_millisecond, sensitivity);
132 } 132 }
133 133
134 std::tuple<Math::Vec3<float>, Math::Vec3<float>> GetStatus() const { 134 std::tuple<Math::Vec3<float>, Math::Vec3<float>> GetStatus() const override {
135 return device->GetStatus(); 135 return device->GetStatus();
136 } 136 }
137 137
diff --git a/src/input_common/sdl/sdl.cpp b/src/input_common/sdl/sdl.cpp
index 8d117c2d4..d1b960fd7 100644
--- a/src/input_common/sdl/sdl.cpp
+++ b/src/input_common/sdl/sdl.cpp
@@ -82,7 +82,7 @@ private:
82class SDLButton final : public Input::ButtonDevice { 82class SDLButton final : public Input::ButtonDevice {
83public: 83public:
84 explicit SDLButton(std::shared_ptr<SDLJoystick> joystick_, int button_) 84 explicit SDLButton(std::shared_ptr<SDLJoystick> joystick_, int button_)
85 : joystick(joystick_), button(button_) {} 85 : joystick(std::move(joystick_)), button(button_) {}
86 86
87 bool GetStatus() const override { 87 bool GetStatus() const override {
88 return joystick->GetButton(button); 88 return joystick->GetButton(button);
@@ -96,7 +96,7 @@ private:
96class SDLDirectionButton final : public Input::ButtonDevice { 96class SDLDirectionButton final : public Input::ButtonDevice {
97public: 97public:
98 explicit SDLDirectionButton(std::shared_ptr<SDLJoystick> joystick_, int hat_, Uint8 direction_) 98 explicit SDLDirectionButton(std::shared_ptr<SDLJoystick> joystick_, int hat_, Uint8 direction_)
99 : joystick(joystick_), hat(hat_), direction(direction_) {} 99 : joystick(std::move(joystick_)), hat(hat_), direction(direction_) {}
100 100
101 bool GetStatus() const override { 101 bool GetStatus() const override {
102 return joystick->GetHatDirection(hat, direction); 102 return joystick->GetHatDirection(hat, direction);
@@ -112,7 +112,7 @@ class SDLAxisButton final : public Input::ButtonDevice {
112public: 112public:
113 explicit SDLAxisButton(std::shared_ptr<SDLJoystick> joystick_, int axis_, float threshold_, 113 explicit SDLAxisButton(std::shared_ptr<SDLJoystick> joystick_, int axis_, float threshold_,
114 bool trigger_if_greater_) 114 bool trigger_if_greater_)
115 : joystick(joystick_), axis(axis_), threshold(threshold_), 115 : joystick(std::move(joystick_)), axis(axis_), threshold(threshold_),
116 trigger_if_greater(trigger_if_greater_) {} 116 trigger_if_greater(trigger_if_greater_) {}
117 117
118 bool GetStatus() const override { 118 bool GetStatus() const override {
@@ -132,7 +132,7 @@ private:
132class SDLAnalog final : public Input::AnalogDevice { 132class SDLAnalog final : public Input::AnalogDevice {
133public: 133public:
134 SDLAnalog(std::shared_ptr<SDLJoystick> joystick_, int axis_x_, int axis_y_) 134 SDLAnalog(std::shared_ptr<SDLJoystick> joystick_, int axis_x_, int axis_y_)
135 : joystick(joystick_), axis_x(axis_x_), axis_y(axis_y_) {} 135 : joystick(std::move(joystick_)), axis_x(axis_x_), axis_y(axis_y_) {}
136 136
137 std::tuple<float, float> GetStatus() const override { 137 std::tuple<float, float> GetStatus() const override {
138 return joystick->GetAnalog(axis_x, axis_y); 138 return joystick->GetAnalog(axis_x, axis_y);
@@ -314,10 +314,6 @@ namespace Polling {
314 314
315class SDLPoller : public InputCommon::Polling::DevicePoller { 315class SDLPoller : public InputCommon::Polling::DevicePoller {
316public: 316public:
317 SDLPoller() = default;
318
319 ~SDLPoller() = default;
320
321 void Start() override { 317 void Start() override {
322 // SDL joysticks must be opened, otherwise they don't generate events 318 // SDL joysticks must be opened, otherwise they don't generate events
323 SDL_JoystickUpdate(); 319 SDL_JoystickUpdate();
@@ -341,10 +337,6 @@ private:
341 337
342class SDLButtonPoller final : public SDLPoller { 338class SDLButtonPoller final : public SDLPoller {
343public: 339public:
344 SDLButtonPoller() = default;
345
346 ~SDLButtonPoller() = default;
347
348 Common::ParamPackage GetNextInput() override { 340 Common::ParamPackage GetNextInput() override {
349 SDL_Event event; 341 SDL_Event event;
350 while (SDL_PollEvent(&event)) { 342 while (SDL_PollEvent(&event)) {
@@ -364,10 +356,6 @@ public:
364 356
365class SDLAnalogPoller final : public SDLPoller { 357class SDLAnalogPoller final : public SDLPoller {
366public: 358public:
367 SDLAnalogPoller() = default;
368
369 ~SDLAnalogPoller() = default;
370
371 void Start() override { 359 void Start() override {
372 SDLPoller::Start(); 360 SDLPoller::Start();
373 361
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt
index 6a0a62ecc..4d74bb395 100644
--- a/src/tests/CMakeLists.txt
+++ b/src/tests/CMakeLists.txt
@@ -3,7 +3,6 @@ add_executable(tests
3 core/arm/arm_test_common.cpp 3 core/arm/arm_test_common.cpp
4 core/arm/arm_test_common.h 4 core/arm/arm_test_common.h
5 core/core_timing.cpp 5 core/core_timing.cpp
6 core/memory/memory.cpp
7 glad.cpp 6 glad.cpp
8 tests.cpp 7 tests.cpp
9) 8)
diff --git a/src/tests/core/memory/memory.cpp b/src/tests/core/memory/memory.cpp
deleted file mode 100644
index 165496a54..000000000
--- a/src/tests/core/memory/memory.cpp
+++ /dev/null
@@ -1,56 +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 <catch.hpp>
6#include "core/hle/kernel/memory.h"
7#include "core/hle/kernel/process.h"
8#include "core/memory.h"
9
10TEST_CASE("Memory::IsValidVirtualAddress", "[core][memory][!hide]") {
11 SECTION("these regions should not be mapped on an empty process") {
12 auto process = Kernel::Process::Create("");
13 CHECK(Memory::IsValidVirtualAddress(*process, Memory::PROCESS_IMAGE_VADDR) == false);
14 CHECK(Memory::IsValidVirtualAddress(*process, Memory::HEAP_VADDR) == false);
15 CHECK(Memory::IsValidVirtualAddress(*process, Memory::LINEAR_HEAP_VADDR) == false);
16 CHECK(Memory::IsValidVirtualAddress(*process, Memory::VRAM_VADDR) == false);
17 CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == false);
18 CHECK(Memory::IsValidVirtualAddress(*process, Memory::SHARED_PAGE_VADDR) == false);
19 CHECK(Memory::IsValidVirtualAddress(*process, Memory::TLS_AREA_VADDR) == false);
20 }
21
22 SECTION("CONFIG_MEMORY_VADDR and SHARED_PAGE_VADDR should be valid after mapping them") {
23 auto process = Kernel::Process::Create("");
24 Kernel::MapSharedPages(process->vm_manager);
25 CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == true);
26 CHECK(Memory::IsValidVirtualAddress(*process, Memory::SHARED_PAGE_VADDR) == true);
27 }
28
29 SECTION("special regions should be valid after mapping them") {
30 auto process = Kernel::Process::Create("");
31 SECTION("VRAM") {
32 Kernel::HandleSpecialMapping(process->vm_manager,
33 {Memory::VRAM_VADDR, Memory::VRAM_SIZE, false, false});
34 CHECK(Memory::IsValidVirtualAddress(*process, Memory::VRAM_VADDR) == true);
35 }
36
37 SECTION("IO (Not yet implemented)") {
38 Kernel::HandleSpecialMapping(
39 process->vm_manager, {Memory::IO_AREA_VADDR, Memory::IO_AREA_SIZE, false, false});
40 CHECK_FALSE(Memory::IsValidVirtualAddress(*process, Memory::IO_AREA_VADDR) == true);
41 }
42
43 SECTION("DSP") {
44 Kernel::HandleSpecialMapping(
45 process->vm_manager, {Memory::DSP_RAM_VADDR, Memory::DSP_RAM_SIZE, false, false});
46 CHECK(Memory::IsValidVirtualAddress(*process, Memory::DSP_RAM_VADDR) == true);
47 }
48 }
49
50 SECTION("Unmapping a VAddr should make it invalid") {
51 auto process = Kernel::Process::Create("");
52 Kernel::MapSharedPages(process->vm_manager);
53 process->vm_manager.UnmapRange(Memory::CONFIG_MEMORY_VADDR, Memory::CONFIG_MEMORY_SIZE);
54 CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == false);
55 }
56}
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index 60c49d672..141e20444 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -40,6 +40,7 @@ u32 RenderTargetBytesPerPixel(RenderTargetFormat format) {
40 case RenderTargetFormat::RGBA8_UNORM: 40 case RenderTargetFormat::RGBA8_UNORM:
41 case RenderTargetFormat::RGB10_A2_UNORM: 41 case RenderTargetFormat::RGB10_A2_UNORM:
42 case RenderTargetFormat::BGRA8_UNORM: 42 case RenderTargetFormat::BGRA8_UNORM:
43 case RenderTargetFormat::R32_FLOAT:
43 return 4; 44 return 4;
44 default: 45 default:
45 UNIMPLEMENTED_MSG("Unimplemented render target format {}", static_cast<u32>(format)); 46 UNIMPLEMENTED_MSG("Unimplemented render target format {}", static_cast<u32>(format));
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index c464fc6d1..08aa75503 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -29,6 +29,7 @@ enum class RenderTargetFormat : u32 {
29 RG16_UINT = 0xDD, 29 RG16_UINT = 0xDD,
30 RG16_FLOAT = 0xDE, 30 RG16_FLOAT = 0xDE,
31 R11G11B10_FLOAT = 0xE0, 31 R11G11B10_FLOAT = 0xE0,
32 R32_FLOAT = 0xE5,
32 R16_FLOAT = 0xF2, 33 R16_FLOAT = 0xF2,
33 R8_UNORM = 0xF3, 34 R8_UNORM = 0xF3,
34}; 35};
diff --git a/src/video_core/renderer_base.cpp b/src/video_core/renderer_base.cpp
index 30075b23c..dbe3edf09 100644
--- a/src/video_core/renderer_base.cpp
+++ b/src/video_core/renderer_base.cpp
@@ -2,14 +2,22 @@
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 <atomic>
6#include <memory> 5#include <memory>
6#include "core/frontend/emu_window.h"
7#include "video_core/renderer_base.h" 7#include "video_core/renderer_base.h"
8#include "video_core/renderer_opengl/gl_rasterizer.h" 8#include "video_core/renderer_opengl/gl_rasterizer.h"
9#include "video_core/video_core.h" 9
10RendererBase::RendererBase(EmuWindow& window) : render_window{window} {}
11RendererBase::~RendererBase() = default;
12
13void RendererBase::UpdateCurrentFramebufferLayout() {
14 const Layout::FramebufferLayout& layout = render_window.GetFramebufferLayout();
15
16 render_window.UpdateCurrentFramebufferLayout(layout.width, layout.height);
17}
10 18
11void RendererBase::RefreshRasterizerSetting() { 19void RendererBase::RefreshRasterizerSetting() {
12 if (rasterizer == nullptr) { 20 if (rasterizer == nullptr) {
13 rasterizer = std::make_unique<RasterizerOpenGL>(); 21 rasterizer = std::make_unique<RasterizerOpenGL>(render_window);
14 } 22 }
15} 23}
diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h
index 89a960eaf..1cb161b7f 100644
--- a/src/video_core/renderer_base.h
+++ b/src/video_core/renderer_base.h
@@ -18,23 +18,21 @@ public:
18 /// Used to reference a framebuffer 18 /// Used to reference a framebuffer
19 enum kFramebuffer { kFramebuffer_VirtualXFB = 0, kFramebuffer_EFB, kFramebuffer_Texture }; 19 enum kFramebuffer { kFramebuffer_VirtualXFB = 0, kFramebuffer_EFB, kFramebuffer_Texture };
20 20
21 virtual ~RendererBase() {} 21 explicit RendererBase(EmuWindow& window);
22 virtual ~RendererBase();
22 23
23 /// Swap buffers (render frame) 24 /// Swap buffers (render frame)
24 virtual void SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) = 0; 25 virtual void SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) = 0;
25 26
26 /**
27 * Set the emulator window to use for renderer
28 * @param window EmuWindow handle to emulator window to use for rendering
29 */
30 virtual void SetWindow(EmuWindow* window) = 0;
31
32 /// Initialize the renderer 27 /// Initialize the renderer
33 virtual bool Init() = 0; 28 virtual bool Init() = 0;
34 29
35 /// Shutdown the renderer 30 /// Shutdown the renderer
36 virtual void ShutDown() = 0; 31 virtual void ShutDown() = 0;
37 32
33 /// Updates the framebuffer layout of the contained render window handle.
34 void UpdateCurrentFramebufferLayout();
35
38 // Getter/setter functions: 36 // Getter/setter functions:
39 // ------------------------ 37 // ------------------------
40 38
@@ -53,9 +51,8 @@ public:
53 void RefreshRasterizerSetting(); 51 void RefreshRasterizerSetting();
54 52
55protected: 53protected:
54 EmuWindow& render_window; ///< Reference to the render window handle.
56 std::unique_ptr<VideoCore::RasterizerInterface> rasterizer; 55 std::unique_ptr<VideoCore::RasterizerInterface> rasterizer;
57 f32 m_current_fps = 0.0f; ///< Current framerate, should be set by the renderer 56 f32 m_current_fps = 0.0f; ///< Current framerate, should be set by the renderer
58 int m_current_frame = 0; ///< Current frame, should be set by the renderer 57 int m_current_frame = 0; ///< Current frame, should be set by the renderer
59
60private:
61}; 58};
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index a1c47bae9..6555db5bb 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -14,7 +14,6 @@
14#include "common/logging/log.h" 14#include "common/logging/log.h"
15#include "common/math_util.h" 15#include "common/math_util.h"
16#include "common/microprofile.h" 16#include "common/microprofile.h"
17#include "common/scope_exit.h"
18#include "core/core.h" 17#include "core/core.h"
19#include "core/frontend/emu_window.h" 18#include "core/frontend/emu_window.h"
20#include "core/hle/kernel/process.h" 19#include "core/hle/kernel/process.h"
@@ -37,7 +36,7 @@ MICROPROFILE_DEFINE(OpenGL_Drawing, "OpenGL", "Drawing", MP_RGB(128, 128, 192));
37MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255)); 36MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255));
38MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100)); 37MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100));
39 38
40RasterizerOpenGL::RasterizerOpenGL() { 39RasterizerOpenGL::RasterizerOpenGL(EmuWindow& window) : emu_window{window} {
41 // Create sampler objects 40 // Create sampler objects
42 for (size_t i = 0; i < texture_samplers.size(); ++i) { 41 for (size_t i = 0; i < texture_samplers.size(); ++i) {
43 texture_samplers[i].Create(); 42 texture_samplers[i].Create();
@@ -395,7 +394,7 @@ void RasterizerOpenGL::Clear() {
395 if (clear_mask == 0) 394 if (clear_mask == 0)
396 return; 395 return;
397 396
398 ScopeAcquireGLContext acquire_context; 397 ScopeAcquireGLContext acquire_context{emu_window};
399 398
400 auto [dirty_color_surface, dirty_depth_surface] = 399 auto [dirty_color_surface, dirty_depth_surface] =
401 ConfigureFramebuffers(use_color_fb, use_depth_fb); 400 ConfigureFramebuffers(use_color_fb, use_depth_fb);
@@ -425,7 +424,7 @@ void RasterizerOpenGL::DrawArrays() {
425 MICROPROFILE_SCOPE(OpenGL_Drawing); 424 MICROPROFILE_SCOPE(OpenGL_Drawing);
426 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; 425 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
427 426
428 ScopeAcquireGLContext acquire_context; 427 ScopeAcquireGLContext acquire_context{emu_window};
429 428
430 auto [dirty_color_surface, dirty_depth_surface] = 429 auto [dirty_color_surface, dirty_depth_surface] =
431 ConfigureFramebuffers(true, regs.zeta.Address() != 0 && regs.zeta_enable != 0); 430 ConfigureFramebuffers(true, regs.zeta.Address() != 0 && regs.zeta_enable != 0);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index e150be58f..6d6d85cc1 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -21,11 +21,12 @@
21#include "video_core/renderer_opengl/gl_state.h" 21#include "video_core/renderer_opengl/gl_state.h"
22#include "video_core/renderer_opengl/gl_stream_buffer.h" 22#include "video_core/renderer_opengl/gl_stream_buffer.h"
23 23
24class EmuWindow;
24struct ScreenInfo; 25struct ScreenInfo;
25 26
26class RasterizerOpenGL : public VideoCore::RasterizerInterface { 27class RasterizerOpenGL : public VideoCore::RasterizerInterface {
27public: 28public:
28 RasterizerOpenGL(); 29 explicit RasterizerOpenGL(EmuWindow& renderer);
29 ~RasterizerOpenGL() override; 30 ~RasterizerOpenGL() override;
30 31
31 void DrawArrays() override; 32 void DrawArrays() override;
@@ -144,6 +145,8 @@ private:
144 145
145 RasterizerCacheOpenGL res_cache; 146 RasterizerCacheOpenGL res_cache;
146 147
148 EmuWindow& emu_window;
149
147 std::unique_ptr<GLShader::ProgramManager> shader_program_manager; 150 std::unique_ptr<GLShader::ProgramManager> shader_program_manager;
148 OGLVertexArray sw_vao; 151 OGLVertexArray sw_vao;
149 OGLVertexArray hw_vao; 152 OGLVertexArray hw_vao;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index a4d9707cb..c8f0c4e28 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -118,6 +118,7 @@ static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_form
118 {GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT, ComponentType::UInt, false}, // RG16UI 118 {GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT, ComponentType::UInt, false}, // RG16UI
119 {GL_RG16I, GL_RG_INTEGER, GL_SHORT, ComponentType::SInt, false}, // RG16I 119 {GL_RG16I, GL_RG_INTEGER, GL_SHORT, ComponentType::SInt, false}, // RG16I
120 {GL_RG16_SNORM, GL_RG, GL_SHORT, ComponentType::SNorm, false}, // RG16S 120 {GL_RG16_SNORM, GL_RG, GL_SHORT, ComponentType::SNorm, false}, // RG16S
121 {GL_RGB32F, GL_RGB, GL_FLOAT, ComponentType::Float, false}, // RGB32F
121 {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // SRGBA8 122 {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // SRGBA8
122 123
123 // DepthStencil formats 124 // DepthStencil formats
@@ -218,9 +219,10 @@ static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr),
218 MortonCopy<true, PixelFormat::R16UNORM>, MortonCopy<true, PixelFormat::RG16>, 219 MortonCopy<true, PixelFormat::R16UNORM>, MortonCopy<true, PixelFormat::RG16>,
219 MortonCopy<true, PixelFormat::RG16F>, MortonCopy<true, PixelFormat::RG16UI>, 220 MortonCopy<true, PixelFormat::RG16F>, MortonCopy<true, PixelFormat::RG16UI>,
220 MortonCopy<true, PixelFormat::RG16I>, MortonCopy<true, PixelFormat::RG16S>, 221 MortonCopy<true, PixelFormat::RG16I>, MortonCopy<true, PixelFormat::RG16S>,
221 MortonCopy<true, PixelFormat::SRGBA8>, MortonCopy<true, PixelFormat::Z24S8>, 222 MortonCopy<true, PixelFormat::RGB32F>, MortonCopy<true, PixelFormat::SRGBA8>,
222 MortonCopy<true, PixelFormat::S8Z24>, MortonCopy<true, PixelFormat::Z32F>, 223 MortonCopy<true, PixelFormat::Z24S8>, MortonCopy<true, PixelFormat::S8Z24>,
223 MortonCopy<true, PixelFormat::Z16>, MortonCopy<true, PixelFormat::Z32FS8>, 224 MortonCopy<true, PixelFormat::Z32F>, MortonCopy<true, PixelFormat::Z16>,
225 MortonCopy<true, PixelFormat::Z32FS8>,
224}; 226};
225 227
226static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr), 228static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr),
@@ -253,6 +255,7 @@ static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr),
253 MortonCopy<false, PixelFormat::RG16UI>, 255 MortonCopy<false, PixelFormat::RG16UI>,
254 MortonCopy<false, PixelFormat::RG16I>, 256 MortonCopy<false, PixelFormat::RG16I>,
255 MortonCopy<false, PixelFormat::RG16S>, 257 MortonCopy<false, PixelFormat::RG16S>,
258 MortonCopy<false, PixelFormat::RGB32F>,
256 MortonCopy<false, PixelFormat::SRGBA8>, 259 MortonCopy<false, PixelFormat::SRGBA8>,
257 MortonCopy<false, PixelFormat::Z24S8>, 260 MortonCopy<false, PixelFormat::Z24S8>,
258 MortonCopy<false, PixelFormat::S8Z24>, 261 MortonCopy<false, PixelFormat::S8Z24>,
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index bf0458b94..4e1e18d9c 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -48,16 +48,17 @@ struct SurfaceParams {
48 RG16UI = 23, 48 RG16UI = 23,
49 RG16I = 24, 49 RG16I = 24,
50 RG16S = 25, 50 RG16S = 25,
51 SRGBA8 = 26, 51 RGB32F = 26,
52 SRGBA8 = 27,
52 53
53 MaxColorFormat, 54 MaxColorFormat,
54 55
55 // DepthStencil formats 56 // DepthStencil formats
56 Z24S8 = 27, 57 Z24S8 = 28,
57 S8Z24 = 28, 58 S8Z24 = 29,
58 Z32F = 29, 59 Z32F = 30,
59 Z16 = 30, 60 Z16 = 31,
60 Z32FS8 = 31, 61 Z32FS8 = 32,
61 62
62 MaxDepthStencilFormat, 63 MaxDepthStencilFormat,
63 64
@@ -121,6 +122,7 @@ struct SurfaceParams {
121 1, // RG16UI 122 1, // RG16UI
122 1, // RG16I 123 1, // RG16I
123 1, // RG16S 124 1, // RG16S
125 1, // RGB32F
124 1, // SRGBA8 126 1, // SRGBA8
125 1, // Z24S8 127 1, // Z24S8
126 1, // S8Z24 128 1, // S8Z24
@@ -164,6 +166,7 @@ struct SurfaceParams {
164 32, // RG16UI 166 32, // RG16UI
165 32, // RG16I 167 32, // RG16I
166 32, // RG16S 168 32, // RG16S
169 96, // RGB32F
167 32, // SRGBA8 170 32, // SRGBA8
168 32, // Z24S8 171 32, // Z24S8
169 32, // S8Z24 172 32, // S8Z24
@@ -232,6 +235,8 @@ struct SurfaceParams {
232 return PixelFormat::RG16S; 235 return PixelFormat::RG16S;
233 case Tegra::RenderTargetFormat::R16_FLOAT: 236 case Tegra::RenderTargetFormat::R16_FLOAT:
234 return PixelFormat::R16F; 237 return PixelFormat::R16F;
238 case Tegra::RenderTargetFormat::R32_FLOAT:
239 return PixelFormat::R32F;
235 default: 240 default:
236 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); 241 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
237 UNREACHABLE(); 242 UNREACHABLE();
@@ -270,6 +275,8 @@ struct SurfaceParams {
270 UNREACHABLE(); 275 UNREACHABLE();
271 case Tegra::Texture::TextureFormat::R32_G32: 276 case Tegra::Texture::TextureFormat::R32_G32:
272 return PixelFormat::RG32F; 277 return PixelFormat::RG32F;
278 case Tegra::Texture::TextureFormat::R32_G32_B32:
279 return PixelFormat::RGB32F;
273 case Tegra::Texture::TextureFormat::R16: 280 case Tegra::Texture::TextureFormat::R16:
274 switch (component_type) { 281 switch (component_type) {
275 case Tegra::Texture::ComponentType::FLOAT: 282 case Tegra::Texture::ComponentType::FLOAT:
@@ -361,6 +368,8 @@ struct SurfaceParams {
361 return Tegra::Texture::TextureFormat::A8R8G8B8; 368 return Tegra::Texture::TextureFormat::A8R8G8B8;
362 case PixelFormat::RGBA32F: 369 case PixelFormat::RGBA32F:
363 return Tegra::Texture::TextureFormat::R32_G32_B32_A32; 370 return Tegra::Texture::TextureFormat::R32_G32_B32_A32;
371 case PixelFormat::RGB32F:
372 return Tegra::Texture::TextureFormat::R32_G32_B32;
364 case PixelFormat::RG32F: 373 case PixelFormat::RG32F:
365 return Tegra::Texture::TextureFormat::R32_G32; 374 return Tegra::Texture::TextureFormat::R32_G32;
366 case PixelFormat::R32F: 375 case PixelFormat::R32F:
@@ -439,6 +448,7 @@ struct SurfaceParams {
439 case Tegra::RenderTargetFormat::RG32_FLOAT: 448 case Tegra::RenderTargetFormat::RG32_FLOAT:
440 case Tegra::RenderTargetFormat::RG16_FLOAT: 449 case Tegra::RenderTargetFormat::RG16_FLOAT:
441 case Tegra::RenderTargetFormat::R16_FLOAT: 450 case Tegra::RenderTargetFormat::R16_FLOAT:
451 case Tegra::RenderTargetFormat::R32_FLOAT:
442 return ComponentType::Float; 452 return ComponentType::Float;
443 case Tegra::RenderTargetFormat::RGBA32_UINT: 453 case Tegra::RenderTargetFormat::RGBA32_UINT:
444 case Tegra::RenderTargetFormat::RG16_UINT: 454 case Tegra::RenderTargetFormat::RG16_UINT:
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index acf067050..68db3c22a 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -412,7 +412,6 @@ public:
412 } 412 }
413 declarations.AddNewLine(); 413 declarations.AddNewLine();
414 414
415 unsigned const_buffer_layout = 0;
416 for (const auto& entry : GetConstBuffersDeclarations()) { 415 for (const auto& entry : GetConstBuffersDeclarations()) {
417 declarations.AddLine("layout(std140) uniform " + entry.GetName()); 416 declarations.AddLine("layout(std140) uniform " + entry.GetName());
418 declarations.AddLine('{'); 417 declarations.AddLine('{');
@@ -420,7 +419,6 @@ public:
420 "[MAX_CONSTBUFFER_ELEMENTS];"); 419 "[MAX_CONSTBUFFER_ELEMENTS];");
421 declarations.AddLine("};"); 420 declarations.AddLine("};");
422 declarations.AddNewLine(); 421 declarations.AddNewLine();
423 ++const_buffer_layout;
424 } 422 }
425 declarations.AddNewLine(); 423 declarations.AddNewLine();
426 424
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp
index e81fcbbc4..415d42fda 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp
@@ -13,15 +13,16 @@ namespace Impl {
13static void SetShaderUniformBlockBinding(GLuint shader, const char* name, 13static void SetShaderUniformBlockBinding(GLuint shader, const char* name,
14 Maxwell3D::Regs::ShaderStage binding, 14 Maxwell3D::Regs::ShaderStage binding,
15 size_t expected_size) { 15 size_t expected_size) {
16 GLuint ub_index = glGetUniformBlockIndex(shader, name); 16 const GLuint ub_index = glGetUniformBlockIndex(shader, name);
17 if (ub_index != GL_INVALID_INDEX) { 17 if (ub_index == GL_INVALID_INDEX) {
18 GLint ub_size = 0; 18 return;
19 glGetActiveUniformBlockiv(shader, ub_index, GL_UNIFORM_BLOCK_DATA_SIZE, &ub_size);
20 ASSERT_MSG(ub_size == expected_size,
21 "Uniform block size did not match! Got {}, expected {}",
22 static_cast<int>(ub_size), expected_size);
23 glUniformBlockBinding(shader, ub_index, static_cast<GLuint>(binding));
24 } 19 }
20
21 GLint ub_size = 0;
22 glGetActiveUniformBlockiv(shader, ub_index, GL_UNIFORM_BLOCK_DATA_SIZE, &ub_size);
23 ASSERT_MSG(static_cast<size_t>(ub_size) == expected_size,
24 "Uniform block size did not match! Got {}, expected {}", ub_size, expected_size);
25 glUniformBlockBinding(shader, ub_index, static_cast<GLuint>(binding));
25} 26}
26 27
27void SetShaderUniformBlockBindings(GLuint shader) { 28void SetShaderUniformBlockBindings(GLuint shader) {
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h
index e29d551e1..716933a0b 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.h
+++ b/src/video_core/renderer_opengl/gl_shader_manager.h
@@ -105,20 +105,20 @@ public:
105 } 105 }
106 106
107 ShaderEntries UseProgrammableVertexShader(const MaxwellVSConfig& config, 107 ShaderEntries UseProgrammableVertexShader(const MaxwellVSConfig& config,
108 const ShaderSetup setup) { 108 const ShaderSetup& setup) {
109 ShaderEntries result; 109 ShaderEntries result;
110 std::tie(current.vs, result) = vertex_shaders.Get(config, setup); 110 std::tie(current.vs, result) = vertex_shaders.Get(config, setup);
111 return result; 111 return result;
112 } 112 }
113 113
114 ShaderEntries UseProgrammableFragmentShader(const MaxwellFSConfig& config, 114 ShaderEntries UseProgrammableFragmentShader(const MaxwellFSConfig& config,
115 const ShaderSetup setup) { 115 const ShaderSetup& setup) {
116 ShaderEntries result; 116 ShaderEntries result;
117 std::tie(current.fs, result) = fragment_shaders.Get(config, setup); 117 std::tie(current.fs, result) = fragment_shaders.Get(config, setup);
118 return result; 118 return result;
119 } 119 }
120 120
121 GLuint GetCurrentProgramStage(Maxwell3D::Regs::ShaderStage stage) { 121 GLuint GetCurrentProgramStage(Maxwell3D::Regs::ShaderStage stage) const {
122 switch (stage) { 122 switch (stage) {
123 case Maxwell3D::Regs::ShaderStage::Vertex: 123 case Maxwell3D::Regs::ShaderStage::Vertex:
124 return current.vs; 124 return current.vs;
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index 3398d7c04..24b1d956b 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -82,7 +82,7 @@ public:
82 GLenum logic_op; // GL_LOGIC_OP_MODE 82 GLenum logic_op; // GL_LOGIC_OP_MODE
83 83
84 // 3 texture units - one for each that is used in PICA fragment shader emulation 84 // 3 texture units - one for each that is used in PICA fragment shader emulation
85 struct { 85 struct TextureUnit {
86 GLuint texture_2d; // GL_TEXTURE_BINDING_2D 86 GLuint texture_2d; // GL_TEXTURE_BINDING_2D
87 GLuint sampler; // GL_SAMPLER_BINDING 87 GLuint sampler; // GL_SAMPLER_BINDING
88 struct { 88 struct {
@@ -104,7 +104,8 @@ public:
104 Unbind(); 104 Unbind();
105 sampler = 0; 105 sampler = 0;
106 } 106 }
107 } texture_units[32]; 107 };
108 std::array<TextureUnit, 32> texture_units;
108 109
109 struct { 110 struct {
110 GLuint read_framebuffer; // GL_READ_FRAMEBUFFER_BINDING 111 GLuint read_framebuffer; // GL_READ_FRAMEBUFFER_BINDING
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 7810b9147..74383c7cf 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -92,23 +92,23 @@ static std::array<GLfloat, 3 * 2> MakeOrthographicMatrix(const float width, cons
92 return matrix; 92 return matrix;
93} 93}
94 94
95ScopeAcquireGLContext::ScopeAcquireGLContext() { 95ScopeAcquireGLContext::ScopeAcquireGLContext(EmuWindow& emu_window_) : emu_window{emu_window_} {
96 if (Settings::values.use_multi_core) { 96 if (Settings::values.use_multi_core) {
97 VideoCore::g_emu_window->MakeCurrent(); 97 emu_window.MakeCurrent();
98 } 98 }
99} 99}
100ScopeAcquireGLContext::~ScopeAcquireGLContext() { 100ScopeAcquireGLContext::~ScopeAcquireGLContext() {
101 if (Settings::values.use_multi_core) { 101 if (Settings::values.use_multi_core) {
102 VideoCore::g_emu_window->DoneCurrent(); 102 emu_window.DoneCurrent();
103 } 103 }
104} 104}
105 105
106RendererOpenGL::RendererOpenGL() = default; 106RendererOpenGL::RendererOpenGL(EmuWindow& window) : RendererBase{window} {}
107RendererOpenGL::~RendererOpenGL() = default; 107RendererOpenGL::~RendererOpenGL() = default;
108 108
109/// Swap buffers (render frame) 109/// Swap buffers (render frame)
110void RendererOpenGL::SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) { 110void RendererOpenGL::SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) {
111 ScopeAcquireGLContext acquire_context; 111 ScopeAcquireGLContext acquire_context{render_window};
112 112
113 Core::System::GetInstance().perf_stats.EndSystemFrame(); 113 Core::System::GetInstance().perf_stats.EndSystemFrame();
114 114
@@ -130,10 +130,10 @@ void RendererOpenGL::SwapBuffers(boost::optional<const Tegra::FramebufferConfig&
130 // Load the framebuffer from memory, draw it to the screen, and swap buffers 130 // Load the framebuffer from memory, draw it to the screen, and swap buffers
131 LoadFBToScreenInfo(*framebuffer, screen_info); 131 LoadFBToScreenInfo(*framebuffer, screen_info);
132 DrawScreen(); 132 DrawScreen();
133 render_window->SwapBuffers(); 133 render_window.SwapBuffers();
134 } 134 }
135 135
136 render_window->PollEvents(); 136 render_window.PollEvents();
137 137
138 Core::System::GetInstance().frame_limiter.DoFrameLimiting(CoreTiming::GetGlobalTimeUs()); 138 Core::System::GetInstance().frame_limiter.DoFrameLimiting(CoreTiming::GetGlobalTimeUs());
139 Core::System::GetInstance().perf_stats.BeginSystemFrame(); 139 Core::System::GetInstance().perf_stats.BeginSystemFrame();
@@ -356,7 +356,7 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
356 * Draws the emulated screens to the emulator window. 356 * Draws the emulated screens to the emulator window.
357 */ 357 */
358void RendererOpenGL::DrawScreen() { 358void RendererOpenGL::DrawScreen() {
359 const auto& layout = render_window->GetFramebufferLayout(); 359 const auto& layout = render_window.GetFramebufferLayout();
360 const auto& screen = layout.screen; 360 const auto& screen = layout.screen;
361 361
362 glViewport(0, 0, layout.width, layout.height); 362 glViewport(0, 0, layout.width, layout.height);
@@ -380,14 +380,6 @@ void RendererOpenGL::DrawScreen() {
380/// Updates the framerate 380/// Updates the framerate
381void RendererOpenGL::UpdateFramerate() {} 381void RendererOpenGL::UpdateFramerate() {}
382 382
383/**
384 * Set the emulator window to use for renderer
385 * @param window EmuWindow handle to emulator window to use for rendering
386 */
387void RendererOpenGL::SetWindow(EmuWindow* window) {
388 render_window = window;
389}
390
391static const char* GetSource(GLenum source) { 383static const char* GetSource(GLenum source) {
392#define RET(s) \ 384#define RET(s) \
393 case GL_DEBUG_SOURCE_##s: \ 385 case GL_DEBUG_SOURCE_##s: \
@@ -445,7 +437,7 @@ static void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum
445 437
446/// Initialize the renderer 438/// Initialize the renderer
447bool RendererOpenGL::Init() { 439bool RendererOpenGL::Init() {
448 ScopeAcquireGLContext acquire_context; 440 ScopeAcquireGLContext acquire_context{render_window};
449 441
450 if (GLAD_GL_KHR_debug) { 442 if (GLAD_GL_KHR_debug) {
451 glEnable(GL_DEBUG_OUTPUT); 443 glEnable(GL_DEBUG_OUTPUT);
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h
index 59d92a3dc..ab7de41c8 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/renderer_opengl/renderer_opengl.h
@@ -34,24 +34,21 @@ struct ScreenInfo {
34/// Helper class to acquire/release OpenGL context within a given scope 34/// Helper class to acquire/release OpenGL context within a given scope
35class ScopeAcquireGLContext : NonCopyable { 35class ScopeAcquireGLContext : NonCopyable {
36public: 36public:
37 ScopeAcquireGLContext(); 37 explicit ScopeAcquireGLContext(EmuWindow& window);
38 ~ScopeAcquireGLContext(); 38 ~ScopeAcquireGLContext();
39
40private:
41 EmuWindow& emu_window;
39}; 42};
40 43
41class RendererOpenGL : public RendererBase { 44class RendererOpenGL : public RendererBase {
42public: 45public:
43 RendererOpenGL(); 46 explicit RendererOpenGL(EmuWindow& window);
44 ~RendererOpenGL() override; 47 ~RendererOpenGL() override;
45 48
46 /// Swap buffers (render frame) 49 /// Swap buffers (render frame)
47 void SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) override; 50 void SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) override;
48 51
49 /**
50 * Set the emulator window to use for renderer
51 * @param window EmuWindow handle to emulator window to use for rendering
52 */
53 void SetWindow(EmuWindow* window) override;
54
55 /// Initialize the renderer 52 /// Initialize the renderer
56 bool Init() override; 53 bool Init() override;
57 54
@@ -72,8 +69,6 @@ private:
72 void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, u8 color_a, 69 void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, u8 color_a,
73 const TextureInfo& texture); 70 const TextureInfo& texture);
74 71
75 EmuWindow* render_window; ///< Handle to render window
76
77 OpenGLState state; 72 OpenGLState state;
78 73
79 // OpenGL object IDs 74 // OpenGL object IDs
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp
index d794f8402..65db84ad3 100644
--- a/src/video_core/textures/decoders.cpp
+++ b/src/video_core/textures/decoders.cpp
@@ -57,6 +57,8 @@ u32 BytesPerPixel(TextureFormat format) {
57 case TextureFormat::BC7U: 57 case TextureFormat::BC7U:
58 // In this case a 'pixel' actually refers to a 4x4 tile. 58 // In this case a 'pixel' actually refers to a 4x4 tile.
59 return 16; 59 return 16;
60 case TextureFormat::R32_G32_B32:
61 return 12;
60 case TextureFormat::ASTC_2D_4X4: 62 case TextureFormat::ASTC_2D_4X4:
61 case TextureFormat::A8R8G8B8: 63 case TextureFormat::A8R8G8B8:
62 case TextureFormat::A2B10G10R10: 64 case TextureFormat::A2B10G10R10:
@@ -131,6 +133,7 @@ std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width,
131 case TextureFormat::R16_G16: 133 case TextureFormat::R16_G16:
132 case TextureFormat::BF10GF11RF11: 134 case TextureFormat::BF10GF11RF11:
133 case TextureFormat::ASTC_2D_4X4: 135 case TextureFormat::ASTC_2D_4X4:
136 case TextureFormat::R32_G32_B32:
134 CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data, 137 CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data,
135 unswizzled_data.data(), true, block_height); 138 unswizzled_data.data(), true, block_height);
136 break; 139 break;
@@ -190,6 +193,7 @@ std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat
190 case TextureFormat::R32: 193 case TextureFormat::R32:
191 case TextureFormat::R16: 194 case TextureFormat::R16:
192 case TextureFormat::R16_G16: 195 case TextureFormat::R16_G16:
196 case TextureFormat::R32_G32_B32:
193 // TODO(Subv): For the time being just forward the same data without any decoding. 197 // TODO(Subv): For the time being just forward the same data without any decoding.
194 rgba_data = texture_data; 198 rgba_data = texture_data;
195 break; 199 break;
diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp
index 289140f31..06b13e681 100644
--- a/src/video_core/video_core.cpp
+++ b/src/video_core/video_core.cpp
@@ -13,16 +13,13 @@
13 13
14namespace VideoCore { 14namespace VideoCore {
15 15
16EmuWindow* g_emu_window = nullptr; ///< Frontend emulator window
17std::unique_ptr<RendererBase> g_renderer; ///< Renderer plugin 16std::unique_ptr<RendererBase> g_renderer; ///< Renderer plugin
18 17
19std::atomic<bool> g_toggle_framelimit_enabled; 18std::atomic<bool> g_toggle_framelimit_enabled;
20 19
21/// Initialize the video core 20/// Initialize the video core
22bool Init(EmuWindow* emu_window) { 21bool Init(EmuWindow& emu_window) {
23 g_emu_window = emu_window; 22 g_renderer = std::make_unique<RendererOpenGL>(emu_window);
24 g_renderer = std::make_unique<RendererOpenGL>();
25 g_renderer->SetWindow(g_emu_window);
26 if (g_renderer->Init()) { 23 if (g_renderer->Init()) {
27 LOG_DEBUG(Render, "initialized OK"); 24 LOG_DEBUG(Render, "initialized OK");
28 } else { 25 } else {
diff --git a/src/video_core/video_core.h b/src/video_core/video_core.h
index 37da62436..519b757f5 100644
--- a/src/video_core/video_core.h
+++ b/src/video_core/video_core.h
@@ -18,17 +18,13 @@ namespace VideoCore {
18enum class Renderer { Software, OpenGL }; 18enum class Renderer { Software, OpenGL };
19 19
20extern std::unique_ptr<RendererBase> g_renderer; ///< Renderer plugin 20extern std::unique_ptr<RendererBase> g_renderer; ///< Renderer plugin
21extern EmuWindow* g_emu_window; ///< Emu window
22 21
23// TODO: Wrap these in a user settings struct along with any other graphics settings (often set from 22// TODO: Wrap these in a user settings struct along with any other graphics settings (often set from
24// qt ui) 23// qt ui)
25extern std::atomic<bool> g_toggle_framelimit_enabled; 24extern std::atomic<bool> g_toggle_framelimit_enabled;
26 25
27/// Start the video core
28void Start();
29
30/// Initialize the video core 26/// Initialize the video core
31bool Init(EmuWindow* emu_window); 27bool Init(EmuWindow& emu_window);
32 28
33/// Shutdown the video core 29/// Shutdown the video core
34void Shutdown(); 30void Shutdown();
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 2f2d8c4c5..bf469ee73 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -105,6 +105,8 @@ void Config::ReadValues() {
105 105
106 qt_config->beginGroup("System"); 106 qt_config->beginGroup("System");
107 Settings::values.use_docked_mode = qt_config->value("use_docked_mode", false).toBool(); 107 Settings::values.use_docked_mode = qt_config->value("use_docked_mode", false).toBool();
108 Settings::values.username = qt_config->value("username", "yuzu").toString().toStdString();
109 Settings::values.language_index = qt_config->value("language_index", 1).toInt();
108 qt_config->endGroup(); 110 qt_config->endGroup();
109 111
110 qt_config->beginGroup("Miscellaneous"); 112 qt_config->beginGroup("Miscellaneous");
@@ -215,6 +217,8 @@ void Config::SaveValues() {
215 217
216 qt_config->beginGroup("System"); 218 qt_config->beginGroup("System");
217 qt_config->setValue("use_docked_mode", Settings::values.use_docked_mode); 219 qt_config->setValue("use_docked_mode", Settings::values.use_docked_mode);
220 qt_config->setValue("username", QString::fromStdString(Settings::values.username));
221 qt_config->setValue("language_index", Settings::values.language_index);
218 qt_config->endGroup(); 222 qt_config->endGroup();
219 223
220 qt_config->beginGroup("Miscellaneous"); 224 qt_config->beginGroup("Miscellaneous");
diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp
index d09505a0f..9be2c939c 100644
--- a/src/yuzu/configuration/configure_system.cpp
+++ b/src/yuzu/configuration/configure_system.cpp
@@ -4,9 +4,10 @@
4 4
5#include <QMessageBox> 5#include <QMessageBox>
6#include "core/core.h" 6#include "core/core.h"
7#include "core/settings.h"
7#include "ui_configure_system.h" 8#include "ui_configure_system.h"
8#include "yuzu/configuration/configure_system.h" 9#include "yuzu/configuration/configure_system.h"
9#include "yuzu/ui_settings.h" 10#include "yuzu/main.h"
10 11
11static const std::array<int, 12> days_in_month = {{ 12static const std::array<int, 12> days_in_month = {{
12 31, 13 31,
@@ -38,6 +39,8 @@ ConfigureSystem::~ConfigureSystem() {}
38 39
39void ConfigureSystem::setConfiguration() { 40void ConfigureSystem::setConfiguration() {
40 enabled = !Core::System::GetInstance().IsPoweredOn(); 41 enabled = !Core::System::GetInstance().IsPoweredOn();
42 ui->edit_username->setText(QString::fromStdString(Settings::values.username));
43 ui->combo_language->setCurrentIndex(Settings::values.language_index);
41} 44}
42 45
43void ConfigureSystem::ReadSystemSettings() {} 46void ConfigureSystem::ReadSystemSettings() {}
@@ -45,6 +48,9 @@ void ConfigureSystem::ReadSystemSettings() {}
45void ConfigureSystem::applyConfiguration() { 48void ConfigureSystem::applyConfiguration() {
46 if (!enabled) 49 if (!enabled)
47 return; 50 return;
51 Settings::values.username = ui->edit_username->text().toStdString();
52 Settings::values.language_index = ui->combo_language->currentIndex();
53 Settings::Apply();
48} 54}
49 55
50void ConfigureSystem::updateBirthdayComboBox(int birthmonth_index) { 56void ConfigureSystem::updateBirthdayComboBox(int birthmonth_index) {
diff --git a/src/yuzu/configuration/configure_system.ui b/src/yuzu/configuration/configure_system.ui
index 8caf49623..f3f8db038 100644
--- a/src/yuzu/configuration/configure_system.ui
+++ b/src/yuzu/configuration/configure_system.ui
@@ -38,7 +38,7 @@
38 </sizepolicy> 38 </sizepolicy>
39 </property> 39 </property>
40 <property name="maxLength"> 40 <property name="maxLength">
41 <number>10</number> 41 <number>32</number>
42 </property> 42 </property>
43 </widget> 43 </widget>
44 </item> 44 </item>
@@ -164,7 +164,7 @@
164 </item> 164 </item>
165 <item> 165 <item>
166 <property name="text"> 166 <property name="text">
167 <string>Simplified Chinese (简体中文)</string> 167 <string>Chinese</string>
168 </property> 168 </property>
169 </item> 169 </item>
170 <item> 170 <item>
@@ -187,6 +187,31 @@
187 <string>Russian (Русский)</string> 187 <string>Russian (Русский)</string>
188 </property> 188 </property>
189 </item> 189 </item>
190 <item>
191 <property name="text">
192 <string>Taiwanese</string>
193 </property>
194 </item>
195 <item>
196 <property name="text">
197 <string>British English</string>
198 </property>
199 </item>
200 <item>
201 <property name="text">
202 <string>Canadian French</string>
203 </property>
204 </item>
205 <item>
206 <property name="text">
207 <string>Latin American Spanish</string>
208 </property>
209 </item>
210 <item>
211 <property name="text">
212 <string>Simplified Chinese</string>
213 </property>
214 </item>
190 <item> 215 <item>
191 <property name="text"> 216 <property name="text">
192 <string>Traditional Chinese (正體中文)</string> 217 <string>Traditional Chinese (正體中文)</string>
diff --git a/src/yuzu/debugger/graphics/graphics_breakpoint_observer.cpp b/src/yuzu/debugger/graphics/graphics_breakpoint_observer.cpp
index d6d61a739..5f459ccfb 100644
--- a/src/yuzu/debugger/graphics/graphics_breakpoint_observer.cpp
+++ b/src/yuzu/debugger/graphics/graphics_breakpoint_observer.cpp
@@ -10,12 +10,12 @@ BreakPointObserverDock::BreakPointObserverDock(std::shared_ptr<Tegra::DebugConte
10 : QDockWidget(title, parent), BreakPointObserver(debug_context) { 10 : QDockWidget(title, parent), BreakPointObserver(debug_context) {
11 qRegisterMetaType<Tegra::DebugContext::Event>("Tegra::DebugContext::Event"); 11 qRegisterMetaType<Tegra::DebugContext::Event>("Tegra::DebugContext::Event");
12 12
13 connect(this, SIGNAL(Resumed()), this, SLOT(OnResumed())); 13 connect(this, &BreakPointObserverDock::Resumed, this, &BreakPointObserverDock::OnResumed);
14 14
15 // NOTE: This signal is emitted from a non-GUI thread, but connect() takes 15 // NOTE: This signal is emitted from a non-GUI thread, but connect() takes
16 // care of delaying its handling to the GUI thread. 16 // care of delaying its handling to the GUI thread.
17 connect(this, SIGNAL(BreakPointHit(Tegra::DebugContext::Event, void*)), this, 17 connect(this, &BreakPointObserverDock::BreakPointHit, this,
18 SLOT(OnBreakPointHit(Tegra::DebugContext::Event, void*)), Qt::BlockingQueuedConnection); 18 &BreakPointObserverDock::OnBreakPointHit, Qt::BlockingQueuedConnection);
19} 19}
20 20
21void BreakPointObserverDock::OnMaxwellBreakPointHit(Tegra::DebugContext::Event event, void* data) { 21void BreakPointObserverDock::OnMaxwellBreakPointHit(Tegra::DebugContext::Event event, void* data) {
diff --git a/src/yuzu/debugger/graphics/graphics_breakpoint_observer.h b/src/yuzu/debugger/graphics/graphics_breakpoint_observer.h
index 9d05493cf..ab32f0115 100644
--- a/src/yuzu/debugger/graphics/graphics_breakpoint_observer.h
+++ b/src/yuzu/debugger/graphics/graphics_breakpoint_observer.h
@@ -23,11 +23,11 @@ public:
23 void OnMaxwellBreakPointHit(Tegra::DebugContext::Event event, void* data) override; 23 void OnMaxwellBreakPointHit(Tegra::DebugContext::Event event, void* data) override;
24 void OnMaxwellResume() override; 24 void OnMaxwellResume() override;
25 25
26private slots:
27 virtual void OnBreakPointHit(Tegra::DebugContext::Event event, void* data) = 0;
28 virtual void OnResumed() = 0;
29
30signals: 26signals:
31 void Resumed(); 27 void Resumed();
32 void BreakPointHit(Tegra::DebugContext::Event event, void* data); 28 void BreakPointHit(Tegra::DebugContext::Event event, void* data);
29
30private:
31 virtual void OnBreakPointHit(Tegra::DebugContext::Event event, void* data) = 0;
32 virtual void OnResumed() = 0;
33}; 33};
diff --git a/src/yuzu/debugger/graphics/graphics_breakpoints.cpp b/src/yuzu/debugger/graphics/graphics_breakpoints.cpp
index f98cc8152..eb16a38a0 100644
--- a/src/yuzu/debugger/graphics/graphics_breakpoints.cpp
+++ b/src/yuzu/debugger/graphics/graphics_breakpoints.cpp
@@ -144,21 +144,25 @@ GraphicsBreakPointsWidget::GraphicsBreakPointsWidget(
144 144
145 qRegisterMetaType<Tegra::DebugContext::Event>("Tegra::DebugContext::Event"); 145 qRegisterMetaType<Tegra::DebugContext::Event>("Tegra::DebugContext::Event");
146 146
147 connect(breakpoint_list, SIGNAL(doubleClicked(const QModelIndex&)), this, 147 connect(breakpoint_list, &QTreeView::doubleClicked, this,
148 SLOT(OnItemDoubleClicked(const QModelIndex&))); 148 &GraphicsBreakPointsWidget::OnItemDoubleClicked);
149 149
150 connect(resume_button, SIGNAL(clicked()), this, SLOT(OnResumeRequested())); 150 connect(resume_button, &QPushButton::clicked, this,
151 &GraphicsBreakPointsWidget::OnResumeRequested);
151 152
152 connect(this, SIGNAL(BreakPointHit(Tegra::DebugContext::Event, void*)), this, 153 connect(this, &GraphicsBreakPointsWidget::BreakPointHit, this,
153 SLOT(OnBreakPointHit(Tegra::DebugContext::Event, void*)), Qt::BlockingQueuedConnection); 154 &GraphicsBreakPointsWidget::OnBreakPointHit, Qt::BlockingQueuedConnection);
154 connect(this, SIGNAL(Resumed()), this, SLOT(OnResumed())); 155 connect(this, &GraphicsBreakPointsWidget::Resumed, this, &GraphicsBreakPointsWidget::OnResumed);
155 156
156 connect(this, SIGNAL(BreakPointHit(Tegra::DebugContext::Event, void*)), breakpoint_model, 157 connect(this, &GraphicsBreakPointsWidget::BreakPointHit, breakpoint_model,
157 SLOT(OnBreakPointHit(Tegra::DebugContext::Event)), Qt::BlockingQueuedConnection); 158 &BreakPointModel::OnBreakPointHit, Qt::BlockingQueuedConnection);
158 connect(this, SIGNAL(Resumed()), breakpoint_model, SLOT(OnResumed())); 159 connect(this, &GraphicsBreakPointsWidget::Resumed, breakpoint_model,
160 &BreakPointModel::OnResumed);
159 161
160 connect(this, SIGNAL(BreakPointsChanged(const QModelIndex&, const QModelIndex&)), 162 connect(this, &GraphicsBreakPointsWidget::BreakPointsChanged,
161 breakpoint_model, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&))); 163 [this](const QModelIndex& top_left, const QModelIndex& bottom_right) {
164 breakpoint_model->dataChanged(top_left, bottom_right);
165 });
162 166
163 QWidget* main_widget = new QWidget; 167 QWidget* main_widget = new QWidget;
164 auto main_layout = new QVBoxLayout; 168 auto main_layout = new QVBoxLayout;
diff --git a/src/yuzu/debugger/graphics/graphics_breakpoints.h b/src/yuzu/debugger/graphics/graphics_breakpoints.h
index ae0ede2e8..a920a2ae5 100644
--- a/src/yuzu/debugger/graphics/graphics_breakpoints.h
+++ b/src/yuzu/debugger/graphics/graphics_breakpoints.h
@@ -26,18 +26,17 @@ public:
26 void OnMaxwellBreakPointHit(Tegra::DebugContext::Event event, void* data) override; 26 void OnMaxwellBreakPointHit(Tegra::DebugContext::Event event, void* data) override;
27 void OnMaxwellResume() override; 27 void OnMaxwellResume() override;
28 28
29public slots:
30 void OnBreakPointHit(Tegra::DebugContext::Event event, void* data);
31 void OnItemDoubleClicked(const QModelIndex&);
32 void OnResumeRequested();
33 void OnResumed();
34
35signals: 29signals:
36 void Resumed(); 30 void Resumed();
37 void BreakPointHit(Tegra::DebugContext::Event event, void* data); 31 void BreakPointHit(Tegra::DebugContext::Event event, void* data);
38 void BreakPointsChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); 32 void BreakPointsChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight);
39 33
40private: 34private:
35 void OnBreakPointHit(Tegra::DebugContext::Event event, void* data);
36 void OnItemDoubleClicked(const QModelIndex&);
37 void OnResumeRequested();
38 void OnResumed();
39
41 QLabel* status_text; 40 QLabel* status_text;
42 QPushButton* resume_button; 41 QPushButton* resume_button;
43 42
diff --git a/src/yuzu/debugger/graphics/graphics_breakpoints_p.h b/src/yuzu/debugger/graphics/graphics_breakpoints_p.h
index 35a6876ae..7112b87e6 100644
--- a/src/yuzu/debugger/graphics/graphics_breakpoints_p.h
+++ b/src/yuzu/debugger/graphics/graphics_breakpoints_p.h
@@ -25,7 +25,6 @@ public:
25 25
26 bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override; 26 bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
27 27
28public slots:
29 void OnBreakPointHit(Tegra::DebugContext::Event event); 28 void OnBreakPointHit(Tegra::DebugContext::Event event);
30 void OnResumed(); 29 void OnResumed();
31 30
diff --git a/src/yuzu/debugger/graphics/graphics_surface.cpp b/src/yuzu/debugger/graphics/graphics_surface.cpp
index c41ff693b..ff3efcdaa 100644
--- a/src/yuzu/debugger/graphics/graphics_surface.cpp
+++ b/src/yuzu/debugger/graphics/graphics_surface.cpp
@@ -153,22 +153,24 @@ GraphicsSurfaceWidget::GraphicsSurfaceWidget(std::shared_ptr<Tegra::DebugContext
153 save_surface = new QPushButton(QIcon::fromTheme("document-save"), tr("Save")); 153 save_surface = new QPushButton(QIcon::fromTheme("document-save"), tr("Save"));
154 154
155 // Connections 155 // Connections
156 connect(this, SIGNAL(Update()), this, SLOT(OnUpdate())); 156 connect(this, &GraphicsSurfaceWidget::Update, this, &GraphicsSurfaceWidget::OnUpdate);
157 connect(surface_source_list, SIGNAL(currentIndexChanged(int)), this, 157 connect(surface_source_list,
158 SLOT(OnSurfaceSourceChanged(int))); 158 static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
159 connect(surface_address_control, SIGNAL(ValueChanged(qint64)), this, 159 &GraphicsSurfaceWidget::OnSurfaceSourceChanged);
160 SLOT(OnSurfaceAddressChanged(qint64))); 160 connect(surface_address_control, &CSpinBox::ValueChanged, this,
161 connect(surface_width_control, SIGNAL(valueChanged(int)), this, 161 &GraphicsSurfaceWidget::OnSurfaceAddressChanged);
162 SLOT(OnSurfaceWidthChanged(int))); 162 connect(surface_width_control, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
163 connect(surface_height_control, SIGNAL(valueChanged(int)), this, 163 this, &GraphicsSurfaceWidget::OnSurfaceWidthChanged);
164 SLOT(OnSurfaceHeightChanged(int))); 164 connect(surface_height_control, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
165 connect(surface_format_control, SIGNAL(currentIndexChanged(int)), this, 165 this, &GraphicsSurfaceWidget::OnSurfaceHeightChanged);
166 SLOT(OnSurfaceFormatChanged(int))); 166 connect(surface_format_control,
167 connect(surface_picker_x_control, SIGNAL(valueChanged(int)), this, 167 static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
168 SLOT(OnSurfacePickerXChanged(int))); 168 &GraphicsSurfaceWidget::OnSurfaceFormatChanged);
169 connect(surface_picker_y_control, SIGNAL(valueChanged(int)), this, 169 connect(surface_picker_x_control, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
170 SLOT(OnSurfacePickerYChanged(int))); 170 this, &GraphicsSurfaceWidget::OnSurfacePickerXChanged);
171 connect(save_surface, SIGNAL(clicked()), this, SLOT(SaveSurface())); 171 connect(surface_picker_y_control, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
172 this, &GraphicsSurfaceWidget::OnSurfacePickerYChanged);
173 connect(save_surface, &QPushButton::clicked, this, &GraphicsSurfaceWidget::SaveSurface);
172 174
173 auto main_widget = new QWidget; 175 auto main_widget = new QWidget;
174 auto main_layout = new QVBoxLayout; 176 auto main_layout = new QVBoxLayout;
diff --git a/src/yuzu/debugger/graphics/graphics_surface.h b/src/yuzu/debugger/graphics/graphics_surface.h
index 6a344bdfc..58f9db465 100644
--- a/src/yuzu/debugger/graphics/graphics_surface.h
+++ b/src/yuzu/debugger/graphics/graphics_surface.h
@@ -65,16 +65,15 @@ public slots:
65 void OnSurfacePickerYChanged(int new_value); 65 void OnSurfacePickerYChanged(int new_value);
66 void OnUpdate(); 66 void OnUpdate();
67 67
68private slots: 68signals:
69 void Update();
70
71private:
69 void OnBreakPointHit(Tegra::DebugContext::Event event, void* data) override; 72 void OnBreakPointHit(Tegra::DebugContext::Event event, void* data) override;
70 void OnResumed() override; 73 void OnResumed() override;
71 74
72 void SaveSurface(); 75 void SaveSurface();
73 76
74signals:
75 void Update();
76
77private:
78 QComboBox* surface_source_list; 77 QComboBox* surface_source_list;
79 CSpinBox* surface_address_control; 78 CSpinBox* surface_address_control;
80 QSpinBox* surface_width_control; 79 QSpinBox* surface_width_control;
diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h
index 10fc9e968..6cbce6856 100644
--- a/src/yuzu/debugger/wait_tree.h
+++ b/src/yuzu/debugger/wait_tree.h
@@ -9,7 +9,7 @@
9#include <QTreeView> 9#include <QTreeView>
10#include <boost/container/flat_set.hpp> 10#include <boost/container/flat_set.hpp>
11#include "core/core.h" 11#include "core/core.h"
12#include "core/hle/kernel/kernel.h" 12#include "core/hle/kernel/object.h"
13 13
14class EmuThread; 14class EmuThread;
15 15
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 34d4f0754..eac41553a 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -403,7 +403,7 @@ bool GMainWindow::LoadROM(const QString& filename) {
403 403
404 system.SetGPUDebugContext(debug_context); 404 system.SetGPUDebugContext(debug_context);
405 405
406 const Core::System::ResultStatus result{system.Load(render_window, filename.toStdString())}; 406 const Core::System::ResultStatus result{system.Load(*render_window, filename.toStdString())};
407 407
408 render_window->DoneCurrent(); 408 render_window->DoneCurrent();
409 409
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h
index 6553c7814..9a935a0d5 100644
--- a/src/yuzu_cmd/default_ini.h
+++ b/src/yuzu_cmd/default_ini.h
@@ -164,6 +164,16 @@ use_virtual_sd =
164# 1: Yes, 0 (default): No 164# 1: Yes, 0 (default): No
165use_docked_mode = 165use_docked_mode =
166 166
167# Sets the account username, max length is 32 characters
168# yuzu (default)
169username =
170
171# Sets the systems language index
172# 0: Japanese, 1: English (default), 2: French, 3: German, 4: Italian, 5: Spanish, 6: Chinese,
173# 7: Korean, 8: Dutch, 9: Portuguese, 10: Russian, 11: Taiwanese, 12: British English, 13: Canadian French,
174# 14: Latin American Spanish, 15: Simplified Chinese, 16: Traditional Chinese
175language_index =
176
167# The system region that yuzu will use during emulation 177# The system region that yuzu will use during emulation
168# -1: Auto-select (default), 0: Japan, 1: USA, 2: Europe, 3: Australia, 4: China, 5: Korea, 6: Taiwan 178# -1: Auto-select (default), 0: Japan, 1: USA, 2: Europe, 3: Australia, 4: China, 5: Korea, 6: Taiwan
169region_value = 179region_value =
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp
index c3b0d9f1f..b23213cf6 100644
--- a/src/yuzu_cmd/yuzu.cpp
+++ b/src/yuzu_cmd/yuzu.cpp
@@ -164,7 +164,7 @@ int main(int argc, char** argv) {
164 164
165 SCOPE_EXIT({ system.Shutdown(); }); 165 SCOPE_EXIT({ system.Shutdown(); });
166 166
167 const Core::System::ResultStatus load_result{system.Load(emu_window.get(), filepath)}; 167 const Core::System::ResultStatus load_result{system.Load(*emu_window, filepath)};
168 168
169 switch (load_result) { 169 switch (load_result) {
170 case Core::System::ResultStatus::ErrorGetLoader: 170 case Core::System::ResultStatus::ErrorGetLoader: