summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/logging/backend.cpp1
-rw-r--r--src/common/logging/log.h1
-rw-r--r--src/common/threadsafe_queue.h32
-rw-r--r--src/core/CMakeLists.txt8
-rw-r--r--src/core/hle/service/am/am.cpp6
-rw-r--r--src/core/hle/service/am/idle.cpp24
-rw-r--r--src/core/hle/service/am/idle.h16
-rw-r--r--src/core/hle/service/am/omm.cpp42
-rw-r--r--src/core/hle/service/am/omm.h16
-rw-r--r--src/core/hle/service/am/spsm.cpp30
-rw-r--r--src/core/hle/service/am/spsm.h16
-rw-r--r--src/core/hle/service/fgm/fgm.cpp75
-rw-r--r--src/core/hle/service/fgm/fgm.h15
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp14
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp9
-rw-r--r--src/core/hle/service/service.cpp2
-rw-r--r--src/video_core/macro_interpreter.cpp4
-rw-r--r--src/video_core/macro_interpreter.h4
18 files changed, 305 insertions, 10 deletions
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index b8f7f473d..d86c40d26 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -171,6 +171,7 @@ void FileBackend::Write(const Entry& entry) {
171 SUB(Service, BCAT) \ 171 SUB(Service, BCAT) \
172 SUB(Service, BTM) \ 172 SUB(Service, BTM) \
173 SUB(Service, Fatal) \ 173 SUB(Service, Fatal) \
174 SUB(Service, FGM) \
174 SUB(Service, Friend) \ 175 SUB(Service, Friend) \
175 SUB(Service, FS) \ 176 SUB(Service, FS) \
176 SUB(Service, HID) \ 177 SUB(Service, HID) \
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index e770f660b..140cd8e47 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -58,6 +58,7 @@ enum class Class : ClassType {
58 Service_BCAT, ///< The BCAT service 58 Service_BCAT, ///< The BCAT service
59 Service_BTM, ///< The BTM service 59 Service_BTM, ///< The BTM service
60 Service_Fatal, ///< The Fatal service 60 Service_Fatal, ///< The Fatal service
61 Service_FGM, ///< The FGM service
61 Service_Friend, ///< The friend service 62 Service_Friend, ///< The friend service
62 Service_FS, ///< The FS (Filesystem) service 63 Service_FS, ///< The FS (Filesystem) service
63 Service_HID, ///< The HID (Human interface device) service 64 Service_HID, ///< The HID (Human interface device) service
diff --git a/src/common/threadsafe_queue.h b/src/common/threadsafe_queue.h
index a0c731e8c..edf13bc49 100644
--- a/src/common/threadsafe_queue.h
+++ b/src/common/threadsafe_queue.h
@@ -33,9 +33,11 @@ public:
33 bool Empty() const { 33 bool Empty() const {
34 return !read_ptr->next.load(); 34 return !read_ptr->next.load();
35 } 35 }
36
36 T& Front() const { 37 T& Front() const {
37 return read_ptr->current; 38 return read_ptr->current;
38 } 39 }
40
39 template <typename Arg> 41 template <typename Arg>
40 void Push(Arg&& t) { 42 void Push(Arg&& t) {
41 // create the element, add it to the queue 43 // create the element, add it to the queue
@@ -108,15 +110,41 @@ private:
108// single reader, multiple writer queue 110// single reader, multiple writer queue
109 111
110template <typename T, bool NeedSize = true> 112template <typename T, bool NeedSize = true>
111class MPSCQueue : public SPSCQueue<T, NeedSize> { 113class MPSCQueue {
112public: 114public:
115 u32 Size() const {
116 return spsc_queue.Size();
117 }
118
119 bool Empty() const {
120 return spsc_queue.Empty();
121 }
122
123 T& Front() const {
124 return spsc_queue.Front();
125 }
126
113 template <typename Arg> 127 template <typename Arg>
114 void Push(Arg&& t) { 128 void Push(Arg&& t) {
115 std::lock_guard<std::mutex> lock(write_lock); 129 std::lock_guard<std::mutex> lock(write_lock);
116 SPSCQueue<T, NeedSize>::Push(t); 130 spsc_queue.Push(t);
131 }
132
133 void Pop() {
134 return spsc_queue.Pop();
135 }
136
137 bool Pop(T& t) {
138 return spsc_queue.Pop(t);
139 }
140
141 // not thread-safe
142 void Clear() {
143 spsc_queue.Clear();
117 } 144 }
118 145
119private: 146private:
147 SPSCQueue<T, NeedSize> spsc_queue;
120 std::mutex write_lock; 148 std::mutex write_lock;
121}; 149};
122} // namespace Common 150} // namespace Common
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 6bb066145..3e13fc25b 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -114,6 +114,12 @@ add_library(core STATIC
114 hle/service/am/applet_ae.h 114 hle/service/am/applet_ae.h
115 hle/service/am/applet_oe.cpp 115 hle/service/am/applet_oe.cpp
116 hle/service/am/applet_oe.h 116 hle/service/am/applet_oe.h
117 hle/service/am/idle.cpp
118 hle/service/am/idle.h
119 hle/service/am/omm.cpp
120 hle/service/am/omm.h
121 hle/service/am/spsm.cpp
122 hle/service/am/spsm.h
117 hle/service/aoc/aoc_u.cpp 123 hle/service/aoc/aoc_u.cpp
118 hle/service/aoc/aoc_u.h 124 hle/service/aoc/aoc_u.h
119 hle/service/apm/apm.cpp 125 hle/service/apm/apm.cpp
@@ -160,6 +166,8 @@ add_library(core STATIC
160 hle/service/filesystem/filesystem.h 166 hle/service/filesystem/filesystem.h
161 hle/service/filesystem/fsp_srv.cpp 167 hle/service/filesystem/fsp_srv.cpp
162 hle/service/filesystem/fsp_srv.h 168 hle/service/filesystem/fsp_srv.h
169 hle/service/fgm/fgm.cpp
170 hle/service/fgm/fgm.h
163 hle/service/friend/friend.cpp 171 hle/service/friend/friend.cpp
164 hle/service/friend/friend.h 172 hle/service/friend/friend.h
165 hle/service/friend/interface.cpp 173 hle/service/friend/interface.cpp
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 97ef07bf9..94d2a973d 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -11,6 +11,9 @@
11#include "core/hle/service/am/am.h" 11#include "core/hle/service/am/am.h"
12#include "core/hle/service/am/applet_ae.h" 12#include "core/hle/service/am/applet_ae.h"
13#include "core/hle/service/am/applet_oe.h" 13#include "core/hle/service/am/applet_oe.h"
14#include "core/hle/service/am/idle.h"
15#include "core/hle/service/am/omm.h"
16#include "core/hle/service/am/spsm.h"
14#include "core/hle/service/apm/apm.h" 17#include "core/hle/service/apm/apm.h"
15#include "core/hle/service/filesystem/filesystem.h" 18#include "core/hle/service/filesystem/filesystem.h"
16#include "core/hle/service/nvflinger/nvflinger.h" 19#include "core/hle/service/nvflinger/nvflinger.h"
@@ -689,6 +692,9 @@ void InstallInterfaces(SM::ServiceManager& service_manager,
689 std::shared_ptr<NVFlinger::NVFlinger> nvflinger) { 692 std::shared_ptr<NVFlinger::NVFlinger> nvflinger) {
690 std::make_shared<AppletAE>(nvflinger)->InstallAsService(service_manager); 693 std::make_shared<AppletAE>(nvflinger)->InstallAsService(service_manager);
691 std::make_shared<AppletOE>(nvflinger)->InstallAsService(service_manager); 694 std::make_shared<AppletOE>(nvflinger)->InstallAsService(service_manager);
695 std::make_shared<IdleSys>()->InstallAsService(service_manager);
696 std::make_shared<OMM>()->InstallAsService(service_manager);
697 std::make_shared<SPSM>()->InstallAsService(service_manager);
692} 698}
693 699
694IHomeMenuFunctions::IHomeMenuFunctions() : ServiceFramework("IHomeMenuFunctions") { 700IHomeMenuFunctions::IHomeMenuFunctions() : ServiceFramework("IHomeMenuFunctions") {
diff --git a/src/core/hle/service/am/idle.cpp b/src/core/hle/service/am/idle.cpp
new file mode 100644
index 000000000..af46e9494
--- /dev/null
+++ b/src/core/hle/service/am/idle.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#include "core/hle/service/am/idle.h"
6
7namespace Service::AM {
8
9IdleSys::IdleSys() : ServiceFramework{"idle:sys"} {
10 // clang-format off
11 static const FunctionInfo functions[] = {
12 {0, nullptr, "GetAutoPowerDownEvent"},
13 {1, nullptr, "Unknown1"},
14 {2, nullptr, "Unknown2"},
15 {3, nullptr, "Unknown3"},
16 {4, nullptr, "Unknown4"},
17 {5, nullptr, "Unknown5"},
18 };
19 // clang-format on
20
21 RegisterHandlers(functions);
22}
23
24} // namespace Service::AM
diff --git a/src/core/hle/service/am/idle.h b/src/core/hle/service/am/idle.h
new file mode 100644
index 000000000..1eb68d2c9
--- /dev/null
+++ b/src/core/hle/service/am/idle.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::AM {
10
11class IdleSys final : public ServiceFramework<IdleSys> {
12public:
13 explicit IdleSys();
14};
15
16} // namespace Service::AM
diff --git a/src/core/hle/service/am/omm.cpp b/src/core/hle/service/am/omm.cpp
new file mode 100644
index 000000000..447fe8669
--- /dev/null
+++ b/src/core/hle/service/am/omm.cpp
@@ -0,0 +1,42 @@
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 "core/hle/service/am/omm.h"
6
7namespace Service::AM {
8
9OMM::OMM() : ServiceFramework{"omm"} {
10 // clang-format off
11 static const FunctionInfo functions[] = {
12 {0, nullptr, "GetOperationMode"},
13 {1, nullptr, "GetOperationModeChangeEvent"},
14 {2, nullptr, "EnableAudioVisual"},
15 {3, nullptr, "DisableAudioVisual"},
16 {4, nullptr, "EnterSleepAndWait"},
17 {5, nullptr, "GetCradleStatus"},
18 {6, nullptr, "FadeInDisplay"},
19 {7, nullptr, "FadeOutDisplay"},
20 {8, nullptr, "Unknown1"},
21 {9, nullptr, "Unknown2"},
22 {10, nullptr, "Unknown3"},
23 {11, nullptr, "Unknown4"},
24 {12, nullptr, "Unknown5"},
25 {13, nullptr, "Unknown6"},
26 {14, nullptr, "Unknown7"},
27 {15, nullptr, "Unknown8"},
28 {16, nullptr, "Unknown9"},
29 {17, nullptr, "Unknown10"},
30 {18, nullptr, "Unknown11"},
31 {19, nullptr, "Unknown12"},
32 {20, nullptr, "Unknown13"},
33 {21, nullptr, "Unknown14"},
34 {22, nullptr, "Unknown15"},
35 {23, nullptr, "Unknown16"},
36 };
37 // clang-format on
38
39 RegisterHandlers(functions);
40}
41
42} // namespace Service::AM
diff --git a/src/core/hle/service/am/omm.h b/src/core/hle/service/am/omm.h
new file mode 100644
index 000000000..49e5d331c
--- /dev/null
+++ b/src/core/hle/service/am/omm.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::AM {
10
11class OMM final : public ServiceFramework<OMM> {
12public:
13 explicit OMM();
14};
15
16} // namespace Service::AM
diff --git a/src/core/hle/service/am/spsm.cpp b/src/core/hle/service/am/spsm.cpp
new file mode 100644
index 000000000..a05d433d0
--- /dev/null
+++ b/src/core/hle/service/am/spsm.cpp
@@ -0,0 +1,30 @@
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 "core/hle/service/am/spsm.h"
6
7namespace Service::AM {
8
9SPSM::SPSM() : ServiceFramework{"spsm"} {
10 // clang-format off
11 static const FunctionInfo functions[] = {
12 {0, nullptr, "GetState"},
13 {1, nullptr, "SleepSystemAndWaitAwake"},
14 {2, nullptr, "Unknown1"},
15 {3, nullptr, "Unknown2"},
16 {4, nullptr, "GetNotificationMessageEventHandle"},
17 {5, nullptr, "Unknown3"},
18 {6, nullptr, "Unknown4"},
19 {7, nullptr, "Unknown5"},
20 {8, nullptr, "AnalyzePerformanceLogForLastSleepWakeSequence"},
21 {9, nullptr, "ChangeHomeButtonLongPressingTime"},
22 {10, nullptr, "Unknown6"},
23 {11, nullptr, "Unknown7"},
24 };
25 // clang-format on
26
27 RegisterHandlers(functions);
28}
29
30} // namespace Service::AM
diff --git a/src/core/hle/service/am/spsm.h b/src/core/hle/service/am/spsm.h
new file mode 100644
index 000000000..57dde62e1
--- /dev/null
+++ b/src/core/hle/service/am/spsm.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::AM {
10
11class SPSM final : public ServiceFramework<SPSM> {
12public:
13 explicit SPSM();
14};
15
16} // namespace Service::AM
diff --git a/src/core/hle/service/fgm/fgm.cpp b/src/core/hle/service/fgm/fgm.cpp
new file mode 100644
index 000000000..566fbf924
--- /dev/null
+++ b/src/core/hle/service/fgm/fgm.cpp
@@ -0,0 +1,75 @@
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/ipc_helpers.h"
8#include "core/hle/kernel/hle_ipc.h"
9#include "core/hle/service/fgm/fgm.h"
10#include "core/hle/service/service.h"
11#include "core/hle/service/sm/sm.h"
12
13namespace Service::FGM {
14
15class IRequest final : public ServiceFramework<IRequest> {
16public:
17 explicit IRequest() : ServiceFramework{"IRequest"} {
18 // clang-format off
19 static const FunctionInfo functions[] = {
20 {0, nullptr, "Initialize"},
21 {1, nullptr, "Set"},
22 {2, nullptr, "Get"},
23 {3, nullptr, "Cancel"},
24 };
25 // clang-format on
26
27 RegisterHandlers(functions);
28 }
29};
30
31class FGM final : public ServiceFramework<FGM> {
32public:
33 explicit FGM(const char* name) : ServiceFramework{name} {
34 // clang-format off
35 static const FunctionInfo functions[] = {
36 {0, &FGM::Initialize, "Initialize"},
37 };
38 // clang-format on
39
40 RegisterHandlers(functions);
41 }
42
43private:
44 void Initialize(Kernel::HLERequestContext& ctx) {
45 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
46 rb.Push(RESULT_SUCCESS);
47 rb.PushIpcInterface<IRequest>();
48
49 LOG_DEBUG(Service_FGM, "called");
50 }
51};
52
53class FGM_DBG final : public ServiceFramework<FGM_DBG> {
54public:
55 explicit FGM_DBG() : ServiceFramework{"fgm:dbg"} {
56 // clang-format off
57 static const FunctionInfo functions[] = {
58 {0, nullptr, "Initialize"},
59 {1, nullptr, "Read"},
60 {2, nullptr, "Cancel"},
61 };
62 // clang-format on
63
64 RegisterHandlers(functions);
65 }
66};
67
68void InstallInterfaces(SM::ServiceManager& sm) {
69 std::make_shared<FGM>("fgm")->InstallAsService(sm);
70 std::make_shared<FGM>("fgm:0")->InstallAsService(sm);
71 std::make_shared<FGM>("fgm:9")->InstallAsService(sm);
72 std::make_shared<FGM_DBG>()->InstallAsService(sm);
73}
74
75} // namespace Service::FGM
diff --git a/src/core/hle/service/fgm/fgm.h b/src/core/hle/service/fgm/fgm.h
new file mode 100644
index 000000000..e59691264
--- /dev/null
+++ b/src/core/hle/service/fgm/fgm.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::FGM {
12
13void InstallInterfaces(SM::ServiceManager& sm);
14
15} // namespace Service::FGM
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
index 44e062f50..010072a5b 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
@@ -97,7 +97,9 @@ u32 nvhost_ctrl_gpu::GetTPCMasks(const std::vector<u8>& input, std::vector<u8>&
97u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector<u8>& output) { 97u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector<u8>& output) {
98 LOG_DEBUG(Service_NVDRV, "called"); 98 LOG_DEBUG(Service_NVDRV, "called");
99 IoctlActiveSlotMask params{}; 99 IoctlActiveSlotMask params{};
100 std::memcpy(&params, input.data(), input.size()); 100 if (input.size() > 0) {
101 std::memcpy(&params, input.data(), input.size());
102 }
101 params.slot = 0x07; 103 params.slot = 0x07;
102 params.mask = 0x01; 104 params.mask = 0x01;
103 std::memcpy(output.data(), &params, output.size()); 105 std::memcpy(output.data(), &params, output.size());
@@ -107,7 +109,9 @@ u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector
107u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u8>& output) { 109u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u8>& output) {
108 LOG_DEBUG(Service_NVDRV, "called"); 110 LOG_DEBUG(Service_NVDRV, "called");
109 IoctlZcullGetCtxSize params{}; 111 IoctlZcullGetCtxSize params{};
110 std::memcpy(&params, input.data(), input.size()); 112 if (input.size() > 0) {
113 std::memcpy(&params, input.data(), input.size());
114 }
111 params.size = 0x1; 115 params.size = 0x1;
112 std::memcpy(output.data(), &params, output.size()); 116 std::memcpy(output.data(), &params, output.size());
113 return 0; 117 return 0;
@@ -116,7 +120,11 @@ u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u
116u32 nvhost_ctrl_gpu::ZCullGetInfo(const std::vector<u8>& input, std::vector<u8>& output) { 120u32 nvhost_ctrl_gpu::ZCullGetInfo(const std::vector<u8>& input, std::vector<u8>& output) {
117 LOG_DEBUG(Service_NVDRV, "called"); 121 LOG_DEBUG(Service_NVDRV, "called");
118 IoctlNvgpuGpuZcullGetInfoArgs params{}; 122 IoctlNvgpuGpuZcullGetInfoArgs params{};
119 std::memcpy(&params, input.data(), input.size()); 123
124 if (input.size() > 0) {
125 std::memcpy(&params, input.data(), input.size());
126 }
127
120 params.width_align_pixels = 0x20; 128 params.width_align_pixels = 0x20;
121 params.height_align_pixels = 0x20; 129 params.height_align_pixels = 0x20;
122 params.pixel_squares_by_aliquots = 0x400; 130 params.pixel_squares_by_aliquots = 0x400;
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
index 126782573..5a1123ad2 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
@@ -132,9 +132,12 @@ u32 nvhost_gpu::SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& outp
132 LOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}", 132 LOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}",
133 params.address, params.num_entries, params.flags); 133 params.address, params.num_entries, params.flags);
134 134
135 auto entries = std::vector<IoctlGpfifoEntry>(); 135 ASSERT_MSG(input.size() ==
136 entries.resize(params.num_entries); 136 sizeof(IoctlSubmitGpfifo) + params.num_entries * sizeof(IoctlGpfifoEntry),
137 std::memcpy(&entries[0], &input.data()[sizeof(IoctlSubmitGpfifo)], 137 "Incorrect input size");
138
139 std::vector<IoctlGpfifoEntry> entries(params.num_entries);
140 std::memcpy(entries.data(), &input[sizeof(IoctlSubmitGpfifo)],
138 params.num_entries * sizeof(IoctlGpfifoEntry)); 141 params.num_entries * sizeof(IoctlGpfifoEntry));
139 for (auto entry : entries) { 142 for (auto entry : entries) {
140 Tegra::GPUVAddr va_addr = entry.Address(); 143 Tegra::GPUVAddr va_addr = entry.Address();
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index bbaf7f601..fccc4c461 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -27,6 +27,7 @@
27#include "core/hle/service/es/es.h" 27#include "core/hle/service/es/es.h"
28#include "core/hle/service/eupld/eupld.h" 28#include "core/hle/service/eupld/eupld.h"
29#include "core/hle/service/fatal/fatal.h" 29#include "core/hle/service/fatal/fatal.h"
30#include "core/hle/service/fgm/fgm.h"
30#include "core/hle/service/filesystem/filesystem.h" 31#include "core/hle/service/filesystem/filesystem.h"
31#include "core/hle/service/friend/friend.h" 32#include "core/hle/service/friend/friend.h"
32#include "core/hle/service/grc/grc.h" 33#include "core/hle/service/grc/grc.h"
@@ -209,6 +210,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm) {
209 ES::InstallInterfaces(*sm); 210 ES::InstallInterfaces(*sm);
210 EUPLD::InstallInterfaces(*sm); 211 EUPLD::InstallInterfaces(*sm);
211 Fatal::InstallInterfaces(*sm); 212 Fatal::InstallInterfaces(*sm);
213 FGM::InstallInterfaces(*sm);
212 FileSystem::InstallInterfaces(*sm); 214 FileSystem::InstallInterfaces(*sm);
213 Friend::InstallInterfaces(*sm); 215 Friend::InstallInterfaces(*sm);
214 GRC::InstallInterfaces(*sm); 216 GRC::InstallInterfaces(*sm);
diff --git a/src/video_core/macro_interpreter.cpp b/src/video_core/macro_interpreter.cpp
index 44ece01c1..377bd66ab 100644
--- a/src/video_core/macro_interpreter.cpp
+++ b/src/video_core/macro_interpreter.cpp
@@ -102,11 +102,11 @@ bool MacroInterpreter::Step(const std::vector<u32>& code, bool is_delay_slot) {
102 if (taken) { 102 if (taken) {
103 // Ignore the delay slot if the branch has the annul bit. 103 // Ignore the delay slot if the branch has the annul bit.
104 if (opcode.branch_annul) { 104 if (opcode.branch_annul) {
105 pc = base_address + (opcode.immediate << 2); 105 pc = base_address + opcode.GetBranchTarget();
106 return true; 106 return true;
107 } 107 }
108 108
109 delayed_pc = base_address + (opcode.immediate << 2); 109 delayed_pc = base_address + opcode.GetBranchTarget();
110 // Execute one more instruction due to the delay slot. 110 // Execute one more instruction due to the delay slot.
111 return Step(code, true); 111 return Step(code, true);
112 } 112 }
diff --git a/src/video_core/macro_interpreter.h b/src/video_core/macro_interpreter.h
index a71e359d8..7d836b816 100644
--- a/src/video_core/macro_interpreter.h
+++ b/src/video_core/macro_interpreter.h
@@ -91,6 +91,10 @@ private:
91 u32 GetBitfieldMask() const { 91 u32 GetBitfieldMask() const {
92 return (1 << bf_size) - 1; 92 return (1 << bf_size) - 1;
93 } 93 }
94
95 s32 GetBranchTarget() const {
96 return static_cast<s32>(immediate * sizeof(u32));
97 }
94 }; 98 };
95 99
96 union MethodAddress { 100 union MethodAddress {