summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Zach Hilman2019-03-11 19:36:36 -0400
committerGravatar Zach Hilman2019-04-17 11:35:24 -0400
commitde3cfb1d37462a4843b8cd4e27ac400e1d479748 (patch)
treee880724ae0657a34c601b83e5323d4ba865a5496 /src
parentapplets: Port current applets to take frontend in constructor (diff)
downloadyuzu-de3cfb1d37462a4843b8cd4e27ac400e1d479748.tar.gz
yuzu-de3cfb1d37462a4843b8cd4e27ac400e1d479748.tar.xz
yuzu-de3cfb1d37462a4843b8cd4e27ac400e1d479748.zip
applets: Add Error applet
Responsible for displaying error codes and messages
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/am/applets/error.cpp177
-rw-r--r--src/core/hle/service/am/applets/error.h47
-rw-r--r--src/core/hle/service/am/applets/stub_applet.h24
3 files changed, 224 insertions, 24 deletions
diff --git a/src/core/hle/service/am/applets/error.cpp b/src/core/hle/service/am/applets/error.cpp
new file mode 100644
index 000000000..df0408edc
--- /dev/null
+++ b/src/core/hle/service/am/applets/error.cpp
@@ -0,0 +1,177 @@
1// Copyright 2019 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/string_util.h"
6#include "core/core.h"
7#include "core/frontend/applets/error.h"
8#include "core/hle/service/am/am.h"
9#include "core/hle/service/am/applets/error.h"
10
11namespace Service::AM::Applets {
12
13#pragma pack(push, 4)
14struct ShowError {
15 u8 mode;
16 bool jump;
17 INSERT_PADDING_BYTES(4);
18 bool use_64bit_error_code;
19 INSERT_PADDING_BYTES(1);
20 u64 error_code_64;
21 u32 error_code_32;
22};
23static_assert(sizeof(ShowError) == 0x14, "ShowError has incorrect size.");
24#pragma pack(pop)
25
26struct ShowErrorRecord {
27 u8 mode;
28 bool jump;
29 INSERT_PADDING_BYTES(6);
30 u64 error_code_64;
31 u64 posix_time;
32};
33static_assert(sizeof(ShowErrorRecord) == 0x18, "ShowErrorRecord has incorrect size.");
34
35struct SystemErrorArg {
36 u8 mode;
37 bool jump;
38 INSERT_PADDING_BYTES(6);
39 u64 error_code_64;
40 std::array<char, 8> language_code;
41 std::array<char, 0x800> main_text;
42 std::array<char, 0x800> detail_text;
43};
44static_assert(sizeof(SystemErrorArg) == 0x1018, "ApplicationErrorArg has incorrect size.");
45
46struct ApplicationErrorArg {
47 u8 mode;
48 bool jump;
49 INSERT_PADDING_BYTES(6);
50 u32 error_code;
51 std::array<char, 8> language_code;
52 std::array<char, 0x800> main_text;
53 std::array<char, 0x800> detail_text;
54};
55static_assert(sizeof(ApplicationErrorArg) == 0x1014, "ApplicationErrorArg has incorrect size.");
56
57union ErrorArguments {
58 ShowError error;
59 ShowErrorRecord error_record;
60 SystemErrorArg system_error;
61 ApplicationErrorArg application_error;
62};
63
64namespace {
65template <typename T>
66void CopyArgumentData(const std::vector<u8>& data, T& variable) {
67 ASSERT(data.size() >= sizeof(T));
68 std::memcpy(&variable, data.data(), sizeof(T));
69}
70
71ResultCode Decode64BitError(u64 error) {
72 const auto description = (error >> 32) & 0x1FFF;
73 auto module = error & 0x3FF;
74 if (module >= 2000)
75 module -= 2000;
76 module &= 0x1FF;
77 return {static_cast<ErrorModule>(module), static_cast<u32>(description)};
78}
79
80} // namespace
81
82Error::Error(const Core::Frontend::ErrorApplet& frontend) : frontend(frontend) {}
83
84Error::~Error() = default;
85
86void Error::Initialize() {
87 Applet::Initialize();
88 args = std::make_unique<ErrorArguments>();
89 complete = false;
90
91 const auto storage = broker.PopNormalDataToApplet();
92 ASSERT(storage != nullptr);
93 const auto data = storage->GetData();
94
95 ASSERT(!data.empty());
96 std::memcpy(&mode, data.data(), sizeof(ErrorAppletMode));
97
98 switch (mode) {
99 case ErrorAppletMode::ShowError:
100 CopyArgumentData(data, args->error);
101 if (args->error.use_64bit_error_code) {
102 error_code = Decode64BitError(args->error.error_code_64);
103 } else {
104 error_code = ResultCode(args->error.error_code_32);
105 }
106 break;
107 case ErrorAppletMode::ShowSystemError:
108 CopyArgumentData(data, args->system_error);
109 error_code = ResultCode(Decode64BitError(args->system_error.error_code_64));
110 case ErrorAppletMode::ShowApplicationError:
111 CopyArgumentData(data, args->application_error);
112 error_code = ResultCode(args->application_error.error_code);
113 break;
114 case ErrorAppletMode::ShowErrorRecord:
115 CopyArgumentData(data, args->error_record);
116 error_code = Decode64BitError(args->error_record.error_code_64);
117 break;
118 default:
119 UNIMPLEMENTED_MSG("Unimplemented LibAppletError mode={:02X}!", static_cast<u8>(mode));
120 }
121}
122
123bool Error::TransactionComplete() const {
124 return complete;
125}
126
127ResultCode Error::GetStatus() const {
128 return RESULT_SUCCESS;
129}
130
131void Error::ExecuteInteractive() {
132 UNREACHABLE_MSG("Unexpected interactive applet data!");
133}
134
135void Error::Execute() {
136 if (complete) {
137 return;
138 }
139
140 const auto callback = [this] { DisplayCompleted(); };
141
142 switch (mode) {
143 case ErrorAppletMode::ShowError:
144 frontend.ShowError(error_code, callback);
145 break;
146 case ErrorAppletMode::ShowSystemError:
147 case ErrorAppletMode::ShowApplicationError: {
148 const auto system = mode == ErrorAppletMode::ShowSystemError;
149 const auto& main_text =
150 system ? args->system_error.main_text : args->application_error.main_text;
151 const auto& detail_text =
152 system ? args->system_error.detail_text : args->application_error.detail_text;
153
154 frontend.ShowCustomErrorText(
155 error_code,
156 Common::StringFromFixedZeroTerminatedBuffer(main_text.data(), main_text.size()),
157 Common::StringFromFixedZeroTerminatedBuffer(detail_text.data(), detail_text.size()),
158 callback);
159 break;
160 }
161 case ErrorAppletMode::ShowErrorRecord:
162 frontend.ShowErrorWithTimestamp(
163 error_code, std::chrono::seconds{args->error_record.posix_time}, callback);
164 break;
165 default:
166 UNIMPLEMENTED_MSG("Unimplemented LibAppletError mode={:02X}!", static_cast<u8>(mode));
167 DisplayCompleted();
168 }
169}
170
171void Error::DisplayCompleted() {
172 complete = true;
173 broker.PushNormalDataFromApplet(IStorage{{}});
174 broker.SignalStateChanged();
175}
176
177} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/am/applets/error.h b/src/core/hle/service/am/applets/error.h
new file mode 100644
index 000000000..fcf9caef2
--- /dev/null
+++ b/src/core/hle/service/am/applets/error.h
@@ -0,0 +1,47 @@
1// Copyright 2019 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/result.h"
8#include "core/hle/service/am/applets/applets.h"
9
10namespace Service::AM::Applets {
11
12union ErrorArguments;
13
14enum class ErrorAppletMode : u8 {
15 ShowError = 0,
16 ShowSystemError = 1,
17 ShowApplicationError = 2,
18 ShowEula = 3,
19 ShowErrorPctl = 4,
20 ShowErrorRecord = 5,
21 ShowUpdateEula = 8,
22};
23
24class Error final : public Applet {
25public:
26 Error(const Core::Frontend::ErrorApplet& frontend);
27 ~Error() override;
28
29 void Initialize() override;
30
31 bool TransactionComplete() const override;
32 ResultCode GetStatus() const override;
33 void ExecuteInteractive() override;
34 void Execute() override;
35
36 void DisplayCompleted();
37
38private:
39 const Core::Frontend::ErrorApplet& frontend;
40 ResultCode error_code = RESULT_SUCCESS;
41 ErrorAppletMode mode;
42 std::unique_ptr<ErrorArguments> args;
43
44 bool complete;
45};
46
47} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/am/applets/stub_applet.h b/src/core/hle/service/am/applets/stub_applet.h
deleted file mode 100644
index 7d8dc968d..000000000
--- a/src/core/hle/service/am/applets/stub_applet.h
+++ /dev/null
@@ -1,24 +0,0 @@
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/am/applets/applets.h"
8
9namespace Service::AM::Applets {
10
11class StubApplet final : public Applet {
12public:
13 StubApplet();
14 ~StubApplet() override;
15
16 void Initialize() override;
17
18 bool TransactionComplete() const override;
19 ResultCode GetStatus() const override;
20 void ExecuteInteractive() override;
21 void Execute() override;
22};
23
24} // namespace Service::AM::Applets