summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp41
-rw-r--r--src/core/hle/service/apt/apt.cpp132
-rw-r--r--src/core/hle/service/apt/apt.h6
-rw-r--r--src/network/room.cpp5
-rw-r--r--src/network/room.h2
5 files changed, 127 insertions, 59 deletions
diff --git a/src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp b/src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp
index e3f3194db..7f4ec0c52 100644
--- a/src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp
+++ b/src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp
@@ -183,23 +183,13 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con
183 print_input(output, src1, swizzle.negate_src1, 183 print_input(output, src1, swizzle.negate_src1,
184 SelectorToString(swizzle.src1_selector)); 184 SelectorToString(swizzle.src1_selector));
185 AlignToColumn(kInputOperandColumnWidth); 185 AlignToColumn(kInputOperandColumnWidth);
186 if (src_is_inverted) { 186 print_input(output, src2, swizzle.negate_src2,
187 print_input(output, src2, swizzle.negate_src2, 187 SelectorToString(swizzle.src2_selector), true,
188 SelectorToString(swizzle.src2_selector)); 188 src_is_inverted ? "" : instr.mad.AddressRegisterName());
189 } else {
190 print_input(output, src2, swizzle.negate_src2,
191 SelectorToString(swizzle.src2_selector), true,
192 instr.mad.AddressRegisterName());
193 }
194 AlignToColumn(kInputOperandColumnWidth); 189 AlignToColumn(kInputOperandColumnWidth);
195 if (src_is_inverted) { 190 print_input(output, src3, swizzle.negate_src3,
196 print_input(output, src3, swizzle.negate_src3, 191 SelectorToString(swizzle.src3_selector), true,
197 SelectorToString(swizzle.src3_selector), true, 192 src_is_inverted ? instr.mad.AddressRegisterName() : "");
198 instr.mad.AddressRegisterName());
199 } else {
200 print_input(output, src3, swizzle.negate_src3,
201 SelectorToString(swizzle.src3_selector));
202 }
203 AlignToColumn(kInputOperandColumnWidth); 193 AlignToColumn(kInputOperandColumnWidth);
204 break; 194 break;
205 } 195 }
@@ -222,16 +212,15 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con
222 SourceRegister src1 = instr.common.GetSrc1(src_is_inverted); 212 SourceRegister src1 = instr.common.GetSrc1(src_is_inverted);
223 print_input(output, src1, swizzle.negate_src1, 213 print_input(output, src1, swizzle.negate_src1,
224 swizzle.SelectorToString(false), true, 214 swizzle.SelectorToString(false), true,
225 instr.common.AddressRegisterName()); 215 src_is_inverted ? "" : instr.common.AddressRegisterName());
226 AlignToColumn(kInputOperandColumnWidth); 216 AlignToColumn(kInputOperandColumnWidth);
227 } 217 }
228 218
229 // TODO: In some cases, the Address Register is used as an index for SRC2
230 // instead of SRC1
231 if (opcode_info.subtype & OpCode::Info::Src2) { 219 if (opcode_info.subtype & OpCode::Info::Src2) {
232 SourceRegister src2 = instr.common.GetSrc2(src_is_inverted); 220 SourceRegister src2 = instr.common.GetSrc2(src_is_inverted);
233 print_input(output, src2, swizzle.negate_src2, 221 print_input(output, src2, swizzle.negate_src2,
234 swizzle.SelectorToString(true)); 222 swizzle.SelectorToString(true), true,
223 src_is_inverted ? instr.common.AddressRegisterName() : "");
235 AlignToColumn(kInputOperandColumnWidth); 224 AlignToColumn(kInputOperandColumnWidth);
236 } 225 }
237 break; 226 break;
@@ -247,7 +236,9 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con
247 236
248 switch (opcode.EffectiveOpCode()) { 237 switch (opcode.EffectiveOpCode()) {
249 case OpCode::Id::LOOP: 238 case OpCode::Id::LOOP:
250 output << "(unknown instruction format)"; 239 output << 'i' << instr.flow_control.int_uniform_id << " (end on 0x"
240 << std::setw(4) << std::right << std::setfill('0') << std::hex
241 << (4 * instr.flow_control.dest_offset) << ")";
251 break; 242 break;
252 243
253 default: 244 default:
@@ -255,7 +246,7 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con
255 output << '('; 246 output << '(';
256 247
257 if (instr.flow_control.op != instr.flow_control.JustY) { 248 if (instr.flow_control.op != instr.flow_control.JustY) {
258 if (instr.flow_control.refx) 249 if (!instr.flow_control.refx)
259 output << '!'; 250 output << '!';
260 output << "cc.x"; 251 output << "cc.x";
261 } 252 }
@@ -267,13 +258,17 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con
267 } 258 }
268 259
269 if (instr.flow_control.op != instr.flow_control.JustX) { 260 if (instr.flow_control.op != instr.flow_control.JustX) {
270 if (instr.flow_control.refy) 261 if (!instr.flow_control.refy)
271 output << '!'; 262 output << '!';
272 output << "cc.y"; 263 output << "cc.y";
273 } 264 }
274 265
275 output << ") "; 266 output << ") ";
276 } else if (opcode_info.subtype & OpCode::Info::HasUniformIndex) { 267 } else if (opcode_info.subtype & OpCode::Info::HasUniformIndex) {
268 if (opcode.EffectiveOpCode() == OpCode::Id::JMPU &&
269 (instr.flow_control.num_instructions & 1) == 1) {
270 output << '!';
271 }
277 output << 'b' << instr.flow_control.bool_uniform_id << ' '; 272 output << 'b' << instr.flow_control.bool_uniform_id << ' ';
278 } 273 }
279 274
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp
index 5c44b43bb..4e6b7b6f5 100644
--- a/src/core/hle/service/apt/apt.cpp
+++ b/src/core/hle/service/apt/apt.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 <boost/optional.hpp>
5#include "common/common_paths.h" 6#include "common/common_paths.h"
6#include "common/file_util.h" 7#include "common/file_util.h"
7#include "common/logging/log.h" 8#include "common/logging/log.h"
@@ -44,7 +45,7 @@ static u8 unknown_ns_state_field;
44static ScreencapPostPermission screen_capture_post_permission; 45static ScreencapPostPermission screen_capture_post_permission;
45 46
46/// Parameter data to be returned in the next call to Glance/ReceiveParameter 47/// Parameter data to be returned in the next call to Glance/ReceiveParameter
47static MessageParameter next_parameter; 48static boost::optional<MessageParameter> next_parameter;
48 49
49void SendParameter(const MessageParameter& parameter) { 50void SendParameter(const MessageParameter& parameter) {
50 next_parameter = parameter; 51 next_parameter = parameter;
@@ -189,8 +190,20 @@ void SendParameter(Service::Interface* self) {
189 std::shared_ptr<HLE::Applets::Applet> dest_applet = 190 std::shared_ptr<HLE::Applets::Applet> dest_applet =
190 HLE::Applets::Applet::Get(static_cast<AppletId>(dst_app_id)); 191 HLE::Applets::Applet::Get(static_cast<AppletId>(dst_app_id));
191 192
193 LOG_DEBUG(Service_APT,
194 "called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X,"
195 "buffer_size=0x%08X, handle=0x%08X, size=0x%08zX, in_param_buffer_ptr=0x%08X",
196 src_app_id, dst_app_id, signal_type, buffer_size, handle, size, buffer);
197
192 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); 198 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
193 199
200 // A new parameter can not be sent if the previous one hasn't been consumed yet
201 if (next_parameter) {
202 rb.Push(ResultCode(ErrCodes::ParameterPresent, ErrorModule::Applet,
203 ErrorSummary::InvalidState, ErrorLevel::Status));
204 return;
205 }
206
194 if (dest_applet == nullptr) { 207 if (dest_applet == nullptr) {
195 LOG_ERROR(Service_APT, "Unknown applet id=0x%08X", dst_app_id); 208 LOG_ERROR(Service_APT, "Unknown applet id=0x%08X", dst_app_id);
196 rb.Push<u32>(-1); // TODO(Subv): Find the right error code 209 rb.Push<u32>(-1); // TODO(Subv): Find the right error code
@@ -206,11 +219,6 @@ void SendParameter(Service::Interface* self) {
206 Memory::ReadBlock(buffer, param.buffer.data(), param.buffer.size()); 219 Memory::ReadBlock(buffer, param.buffer.data(), param.buffer.size());
207 220
208 rb.Push(dest_applet->ReceiveParameter(param)); 221 rb.Push(dest_applet->ReceiveParameter(param));
209
210 LOG_WARNING(Service_APT,
211 "(STUBBED) called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X,"
212 "buffer_size=0x%08X, handle=0x%08X, size=0x%08zX, in_param_buffer_ptr=0x%08X",
213 src_app_id, dst_app_id, signal_type, buffer_size, handle, size, buffer);
214} 222}
215 223
216void ReceiveParameter(Service::Interface* self) { 224void ReceiveParameter(Service::Interface* self) {
@@ -226,21 +234,40 @@ void ReceiveParameter(Service::Interface* self) {
226 "buffer_size is bigger than the size in the buffer descriptor (0x%08X > 0x%08zX)", 234 "buffer_size is bigger than the size in the buffer descriptor (0x%08X > 0x%08zX)",
227 buffer_size, static_buff_size); 235 buffer_size, static_buff_size);
228 236
237 LOG_DEBUG(Service_APT, "called app_id=0x%08X, buffer_size=0x%08zX", app_id, buffer_size);
238
239 if (!next_parameter) {
240 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
241 rb.Push(ResultCode(ErrorDescription::NoData, ErrorModule::Applet,
242 ErrorSummary::InvalidState, ErrorLevel::Status));
243 return;
244 }
245
246 if (next_parameter->destination_id != app_id) {
247 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
248 rb.Push(ResultCode(ErrorDescription::NotFound, ErrorModule::Applet, ErrorSummary::NotFound,
249 ErrorLevel::Status));
250 return;
251 }
252
229 IPC::RequestBuilder rb = rp.MakeBuilder(4, 4); 253 IPC::RequestBuilder rb = rp.MakeBuilder(4, 4);
254
230 rb.Push(RESULT_SUCCESS); // No error 255 rb.Push(RESULT_SUCCESS); // No error
231 rb.Push(next_parameter.sender_id); 256 rb.Push(next_parameter->sender_id);
232 rb.Push(next_parameter.signal); // Signal type 257 rb.Push(next_parameter->signal); // Signal type
233 ASSERT_MSG(next_parameter.buffer.size() <= buffer_size, "Input static buffer is too small !"); 258 ASSERT_MSG(next_parameter->buffer.size() <= buffer_size, "Input static buffer is too small !");
234 rb.Push(static_cast<u32>(next_parameter.buffer.size())); // Parameter buffer size 259 rb.Push(static_cast<u32>(next_parameter->buffer.size())); // Parameter buffer size
235 260
236 rb.PushMoveHandles((next_parameter.object != nullptr) 261 rb.PushMoveHandles((next_parameter->object != nullptr)
237 ? Kernel::g_handle_table.Create(next_parameter.object).Unwrap() 262 ? Kernel::g_handle_table.Create(next_parameter->object).Unwrap()
238 : 0); 263 : 0);
239 rb.PushStaticBuffer(buffer, static_cast<u32>(next_parameter.buffer.size()), 0);
240 264
241 Memory::WriteBlock(buffer, next_parameter.buffer.data(), next_parameter.buffer.size()); 265 rb.PushStaticBuffer(buffer, static_cast<u32>(next_parameter->buffer.size()), 0);
242 266
243 LOG_WARNING(Service_APT, "called app_id=0x%08X, buffer_size=0x%08zX", app_id, buffer_size); 267 Memory::WriteBlock(buffer, next_parameter->buffer.data(), next_parameter->buffer.size());
268
269 // Clear the parameter
270 next_parameter = boost::none;
244} 271}
245 272
246void GlanceParameter(Service::Interface* self) { 273void GlanceParameter(Service::Interface* self) {
@@ -256,37 +283,74 @@ void GlanceParameter(Service::Interface* self) {
256 "buffer_size is bigger than the size in the buffer descriptor (0x%08X > 0x%08zX)", 283 "buffer_size is bigger than the size in the buffer descriptor (0x%08X > 0x%08zX)",
257 buffer_size, static_buff_size); 284 buffer_size, static_buff_size);
258 285
286 LOG_DEBUG(Service_APT, "called app_id=0x%08X, buffer_size=0x%08zX", app_id, buffer_size);
287
288 if (!next_parameter) {
289 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
290 rb.Push(ResultCode(ErrorDescription::NoData, ErrorModule::Applet,
291 ErrorSummary::InvalidState, ErrorLevel::Status));
292 return;
293 }
294
295 if (next_parameter->destination_id != app_id) {
296 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
297 rb.Push(ResultCode(ErrorDescription::NotFound, ErrorModule::Applet, ErrorSummary::NotFound,
298 ErrorLevel::Status));
299 return;
300 }
301
259 IPC::RequestBuilder rb = rp.MakeBuilder(4, 4); 302 IPC::RequestBuilder rb = rp.MakeBuilder(4, 4);
260 rb.Push(RESULT_SUCCESS); // No error 303 rb.Push(RESULT_SUCCESS); // No error
261 rb.Push(next_parameter.sender_id); 304 rb.Push(next_parameter->sender_id);
262 rb.Push(next_parameter.signal); // Signal type 305 rb.Push(next_parameter->signal); // Signal type
263 ASSERT_MSG(next_parameter.buffer.size() <= buffer_size, "Input static buffer is too small !"); 306 ASSERT_MSG(next_parameter->buffer.size() <= buffer_size, "Input static buffer is too small !");
264 rb.Push(static_cast<u32>(next_parameter.buffer.size())); // Parameter buffer size 307 rb.Push(static_cast<u32>(next_parameter->buffer.size())); // Parameter buffer size
265 308
266 rb.PushCopyHandles((next_parameter.object != nullptr) 309 rb.PushMoveHandles((next_parameter->object != nullptr)
267 ? Kernel::g_handle_table.Create(next_parameter.object).Unwrap() 310 ? Kernel::g_handle_table.Create(next_parameter->object).Unwrap()
268 : 0); 311 : 0);
269 rb.PushStaticBuffer(buffer, static_cast<u32>(next_parameter.buffer.size()), 0);
270 312
271 Memory::WriteBlock(buffer, next_parameter.buffer.data(), next_parameter.buffer.size()); 313 rb.PushStaticBuffer(buffer, static_cast<u32>(next_parameter->buffer.size()), 0);
272 314
273 LOG_WARNING(Service_APT, "called app_id=0x%08X, buffer_size=0x%08zX", app_id, buffer_size); 315 Memory::WriteBlock(buffer, next_parameter->buffer.data(), next_parameter->buffer.size());
316
317 // Note: The NS module always clears the DSPSleep and DSPWakeup signals even in GlanceParameter.
318 if (next_parameter->signal == static_cast<u32>(SignalType::DspSleep) ||
319 next_parameter->signal == static_cast<u32>(SignalType::DspWakeup))
320 next_parameter = boost::none;
274} 321}
275 322
276void CancelParameter(Service::Interface* self) { 323void CancelParameter(Service::Interface* self) {
277 IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0xF, 4, 0); // 0xF0100 324 IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0xF, 4, 0); // 0xF0100
278 325
279 u32 check_sender = rp.Pop<u32>(); 326 bool check_sender = rp.Pop<bool>();
280 u32 sender_appid = rp.Pop<u32>(); 327 u32 sender_appid = rp.Pop<u32>();
281 u32 check_receiver = rp.Pop<u32>(); 328 bool check_receiver = rp.Pop<bool>();
282 u32 receiver_appid = rp.Pop<u32>(); 329 u32 receiver_appid = rp.Pop<u32>();
330
331 bool cancellation_success = true;
332
333 if (!next_parameter) {
334 cancellation_success = false;
335 } else {
336 if (check_sender && next_parameter->sender_id != sender_appid)
337 cancellation_success = false;
338
339 if (check_receiver && next_parameter->destination_id != receiver_appid)
340 cancellation_success = false;
341 }
342
343 if (cancellation_success)
344 next_parameter = boost::none;
345
283 IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); 346 IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
347
284 rb.Push(RESULT_SUCCESS); // No error 348 rb.Push(RESULT_SUCCESS); // No error
285 rb.Push(true); // Set to Success 349 rb.Push(cancellation_success);
286 350
287 LOG_WARNING(Service_APT, "(STUBBED) called check_sender=0x%08X, sender_appid=0x%08X, " 351 LOG_DEBUG(Service_APT, "called check_sender=%u, sender_appid=0x%08X, "
288 "check_receiver=0x%08X, receiver_appid=0x%08X", 352 "check_receiver=%u, receiver_appid=0x%08X",
289 check_sender, sender_appid, check_receiver, receiver_appid); 353 check_sender, sender_appid, check_receiver, receiver_appid);
290} 354}
291 355
292void PrepareToStartApplication(Service::Interface* self) { 356void PrepareToStartApplication(Service::Interface* self) {
@@ -800,8 +864,10 @@ void Init() {
800 notification_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "APT_U:Notification"); 864 notification_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "APT_U:Notification");
801 parameter_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "APT_U:Start"); 865 parameter_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "APT_U:Start");
802 866
803 next_parameter.signal = static_cast<u32>(SignalType::Wakeup); 867 // Initialize the parameter to wake up the application.
804 next_parameter.destination_id = 0x300; 868 next_parameter.emplace();
869 next_parameter->signal = static_cast<u32>(SignalType::Wakeup);
870 next_parameter->destination_id = static_cast<u32>(AppletId::Application);
805} 871}
806 872
807void Shutdown() { 873void Shutdown() {
@@ -812,7 +878,7 @@ void Shutdown() {
812 notification_event = nullptr; 878 notification_event = nullptr;
813 parameter_event = nullptr; 879 parameter_event = nullptr;
814 880
815 next_parameter.object = nullptr; 881 next_parameter = boost::none;
816 882
817 HLE::Applets::Shutdown(); 883 HLE::Applets::Shutdown();
818} 884}
diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h
index ee80926d2..106754853 100644
--- a/src/core/hle/service/apt/apt.h
+++ b/src/core/hle/service/apt/apt.h
@@ -116,6 +116,12 @@ enum class ScreencapPostPermission : u32 {
116 DisableScreenshotPostingToMiiverse = 3 116 DisableScreenshotPostingToMiiverse = 3
117}; 117};
118 118
119namespace ErrCodes {
120enum {
121 ParameterPresent = 2,
122};
123}
124
119/// Send a parameter to the currently-running application, which will read it via ReceiveParameter 125/// Send a parameter to the currently-running application, which will read it via ReceiveParameter
120void SendParameter(const MessageParameter& parameter); 126void SendParameter(const MessageParameter& parameter);
121 127
diff --git a/src/network/room.cpp b/src/network/room.cpp
index 8b7915bb7..fbbaf8b93 100644
--- a/src/network/room.cpp
+++ b/src/network/room.cpp
@@ -19,7 +19,7 @@ static constexpr u32 MaxConcurrentConnections = 10;
19class Room::RoomImpl { 19class Room::RoomImpl {
20public: 20public:
21 // This MAC address is used to generate a 'Nintendo' like Mac address. 21 // This MAC address is used to generate a 'Nintendo' like Mac address.
22 const MacAddress NintendoOUI = {0x00, 0x1F, 0x32, 0x00, 0x00, 0x00}; 22 const MacAddress NintendoOUI;
23 std::mt19937 random_gen; ///< Random number generator. Used for GenerateMacAddress 23 std::mt19937 random_gen; ///< Random number generator. Used for GenerateMacAddress
24 24
25 ENetHost* server = nullptr; ///< Network interface. 25 ENetHost* server = nullptr; ///< Network interface.
@@ -36,7 +36,8 @@ public:
36 using MemberList = std::vector<Member>; 36 using MemberList = std::vector<Member>;
37 MemberList members; ///< Information about the members of this room. 37 MemberList members; ///< Information about the members of this room.
38 38
39 RoomImpl() : random_gen(std::random_device()()) {} 39 RoomImpl()
40 : random_gen(std::random_device()()), NintendoOUI{0x00, 0x1F, 0x32, 0x00, 0x00, 0x00} {}
40 41
41 /// Thread that receives and dispatches network packets 42 /// Thread that receives and dispatches network packets
42 std::unique_ptr<std::thread> room_thread; 43 std::unique_ptr<std::thread> room_thread;
diff --git a/src/network/room.h b/src/network/room.h
index 54cccf0ae..65b0d008a 100644
--- a/src/network/room.h
+++ b/src/network/room.h
@@ -24,7 +24,7 @@ struct RoomInformation {
24using MacAddress = std::array<u8, 6>; 24using MacAddress = std::array<u8, 6>;
25/// A special MAC address that tells the room we're joining to assign us a MAC address 25/// A special MAC address that tells the room we're joining to assign us a MAC address
26/// automatically. 26/// automatically.
27const MacAddress NoPreferredMac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 27constexpr MacAddress NoPreferredMac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
28 28
29// 802.11 broadcast MAC address 29// 802.11 broadcast MAC address
30constexpr MacAddress BroadcastMac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 30constexpr MacAddress BroadcastMac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};