diff options
Diffstat (limited to '')
-rw-r--r-- | appveyor.yml | 2 | ||||
-rw-r--r-- | src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp | 41 | ||||
-rw-r--r-- | src/core/hle/service/apt/apt.cpp | 132 | ||||
-rw-r--r-- | src/core/hle/service/apt/apt.h | 6 | ||||
-rw-r--r-- | src/network/room.cpp | 5 | ||||
-rw-r--r-- | src/network/room.h | 2 |
6 files changed, 128 insertions, 60 deletions
diff --git a/appveyor.yml b/appveyor.yml index 6b5d23b03..9a6206a8b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -22,7 +22,7 @@ install: before_build: - mkdir build - cd build - - cmake -G "Visual Studio 15 2017 Win64" -DCITRA_USE_BUNDLED_QT=1 -DCITRA_USE_BUNDLED_SDL2=1 .. + - cmake -G "Visual Studio 15 2017 Win64" -DCITRA_USE_BUNDLED_QT=1 -DCITRA_USE_BUNDLED_SDL2=1 -DCMAKE_USE_OPENSSL=0 .. - cd .. build: 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 print_input(output, src1, swizzle.negate_src1, SelectorToString(swizzle.src1_selector)); AlignToColumn(kInputOperandColumnWidth); - if (src_is_inverted) { - print_input(output, src2, swizzle.negate_src2, - SelectorToString(swizzle.src2_selector)); - } else { - print_input(output, src2, swizzle.negate_src2, - SelectorToString(swizzle.src2_selector), true, - instr.mad.AddressRegisterName()); - } + print_input(output, src2, swizzle.negate_src2, + SelectorToString(swizzle.src2_selector), true, + src_is_inverted ? "" : instr.mad.AddressRegisterName()); AlignToColumn(kInputOperandColumnWidth); - if (src_is_inverted) { - print_input(output, src3, swizzle.negate_src3, - SelectorToString(swizzle.src3_selector), true, - instr.mad.AddressRegisterName()); - } else { - print_input(output, src3, swizzle.negate_src3, - SelectorToString(swizzle.src3_selector)); - } + print_input(output, src3, swizzle.negate_src3, + SelectorToString(swizzle.src3_selector), true, + src_is_inverted ? instr.mad.AddressRegisterName() : ""); AlignToColumn(kInputOperandColumnWidth); break; } @@ -222,16 +212,15 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con SourceRegister src1 = instr.common.GetSrc1(src_is_inverted); print_input(output, src1, swizzle.negate_src1, swizzle.SelectorToString(false), true, - instr.common.AddressRegisterName()); + src_is_inverted ? "" : instr.common.AddressRegisterName()); AlignToColumn(kInputOperandColumnWidth); } - // TODO: In some cases, the Address Register is used as an index for SRC2 - // instead of SRC1 if (opcode_info.subtype & OpCode::Info::Src2) { SourceRegister src2 = instr.common.GetSrc2(src_is_inverted); print_input(output, src2, swizzle.negate_src2, - swizzle.SelectorToString(true)); + swizzle.SelectorToString(true), true, + src_is_inverted ? instr.common.AddressRegisterName() : ""); AlignToColumn(kInputOperandColumnWidth); } break; @@ -247,7 +236,9 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con switch (opcode.EffectiveOpCode()) { case OpCode::Id::LOOP: - output << "(unknown instruction format)"; + output << 'i' << instr.flow_control.int_uniform_id << " (end on 0x" + << std::setw(4) << std::right << std::setfill('0') << std::hex + << (4 * instr.flow_control.dest_offset) << ")"; break; default: @@ -255,7 +246,7 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con output << '('; if (instr.flow_control.op != instr.flow_control.JustY) { - if (instr.flow_control.refx) + if (!instr.flow_control.refx) output << '!'; output << "cc.x"; } @@ -267,13 +258,17 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con } if (instr.flow_control.op != instr.flow_control.JustX) { - if (instr.flow_control.refy) + if (!instr.flow_control.refy) output << '!'; output << "cc.y"; } output << ") "; } else if (opcode_info.subtype & OpCode::Info::HasUniformIndex) { + if (opcode.EffectiveOpCode() == OpCode::Id::JMPU && + (instr.flow_control.num_instructions & 1) == 1) { + output << '!'; + } output << 'b' << instr.flow_control.bool_uniform_id << ' '; } 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 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <boost/optional.hpp> #include "common/common_paths.h" #include "common/file_util.h" #include "common/logging/log.h" @@ -44,7 +45,7 @@ static u8 unknown_ns_state_field; static ScreencapPostPermission screen_capture_post_permission; /// Parameter data to be returned in the next call to Glance/ReceiveParameter -static MessageParameter next_parameter; +static boost::optional<MessageParameter> next_parameter; void SendParameter(const MessageParameter& parameter) { next_parameter = parameter; @@ -189,8 +190,20 @@ void SendParameter(Service::Interface* self) { std::shared_ptr<HLE::Applets::Applet> dest_applet = HLE::Applets::Applet::Get(static_cast<AppletId>(dst_app_id)); + LOG_DEBUG(Service_APT, + "called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X," + "buffer_size=0x%08X, handle=0x%08X, size=0x%08zX, in_param_buffer_ptr=0x%08X", + src_app_id, dst_app_id, signal_type, buffer_size, handle, size, buffer); + IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); + // A new parameter can not be sent if the previous one hasn't been consumed yet + if (next_parameter) { + rb.Push(ResultCode(ErrCodes::ParameterPresent, ErrorModule::Applet, + ErrorSummary::InvalidState, ErrorLevel::Status)); + return; + } + if (dest_applet == nullptr) { LOG_ERROR(Service_APT, "Unknown applet id=0x%08X", dst_app_id); rb.Push<u32>(-1); // TODO(Subv): Find the right error code @@ -206,11 +219,6 @@ void SendParameter(Service::Interface* self) { Memory::ReadBlock(buffer, param.buffer.data(), param.buffer.size()); rb.Push(dest_applet->ReceiveParameter(param)); - - LOG_WARNING(Service_APT, - "(STUBBED) called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X," - "buffer_size=0x%08X, handle=0x%08X, size=0x%08zX, in_param_buffer_ptr=0x%08X", - src_app_id, dst_app_id, signal_type, buffer_size, handle, size, buffer); } void ReceiveParameter(Service::Interface* self) { @@ -226,21 +234,40 @@ void ReceiveParameter(Service::Interface* self) { "buffer_size is bigger than the size in the buffer descriptor (0x%08X > 0x%08zX)", buffer_size, static_buff_size); + LOG_DEBUG(Service_APT, "called app_id=0x%08X, buffer_size=0x%08zX", app_id, buffer_size); + + if (!next_parameter) { + IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); + rb.Push(ResultCode(ErrorDescription::NoData, ErrorModule::Applet, + ErrorSummary::InvalidState, ErrorLevel::Status)); + return; + } + + if (next_parameter->destination_id != app_id) { + IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); + rb.Push(ResultCode(ErrorDescription::NotFound, ErrorModule::Applet, ErrorSummary::NotFound, + ErrorLevel::Status)); + return; + } + IPC::RequestBuilder rb = rp.MakeBuilder(4, 4); + rb.Push(RESULT_SUCCESS); // No error - rb.Push(next_parameter.sender_id); - rb.Push(next_parameter.signal); // Signal type - ASSERT_MSG(next_parameter.buffer.size() <= buffer_size, "Input static buffer is too small !"); - rb.Push(static_cast<u32>(next_parameter.buffer.size())); // Parameter buffer size + rb.Push(next_parameter->sender_id); + rb.Push(next_parameter->signal); // Signal type + ASSERT_MSG(next_parameter->buffer.size() <= buffer_size, "Input static buffer is too small !"); + rb.Push(static_cast<u32>(next_parameter->buffer.size())); // Parameter buffer size - rb.PushMoveHandles((next_parameter.object != nullptr) - ? Kernel::g_handle_table.Create(next_parameter.object).Unwrap() + rb.PushMoveHandles((next_parameter->object != nullptr) + ? Kernel::g_handle_table.Create(next_parameter->object).Unwrap() : 0); - rb.PushStaticBuffer(buffer, static_cast<u32>(next_parameter.buffer.size()), 0); - Memory::WriteBlock(buffer, next_parameter.buffer.data(), next_parameter.buffer.size()); + rb.PushStaticBuffer(buffer, static_cast<u32>(next_parameter->buffer.size()), 0); - LOG_WARNING(Service_APT, "called app_id=0x%08X, buffer_size=0x%08zX", app_id, buffer_size); + Memory::WriteBlock(buffer, next_parameter->buffer.data(), next_parameter->buffer.size()); + + // Clear the parameter + next_parameter = boost::none; } void GlanceParameter(Service::Interface* self) { @@ -256,37 +283,74 @@ void GlanceParameter(Service::Interface* self) { "buffer_size is bigger than the size in the buffer descriptor (0x%08X > 0x%08zX)", buffer_size, static_buff_size); + LOG_DEBUG(Service_APT, "called app_id=0x%08X, buffer_size=0x%08zX", app_id, buffer_size); + + if (!next_parameter) { + IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); + rb.Push(ResultCode(ErrorDescription::NoData, ErrorModule::Applet, + ErrorSummary::InvalidState, ErrorLevel::Status)); + return; + } + + if (next_parameter->destination_id != app_id) { + IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); + rb.Push(ResultCode(ErrorDescription::NotFound, ErrorModule::Applet, ErrorSummary::NotFound, + ErrorLevel::Status)); + return; + } + IPC::RequestBuilder rb = rp.MakeBuilder(4, 4); rb.Push(RESULT_SUCCESS); // No error - rb.Push(next_parameter.sender_id); - rb.Push(next_parameter.signal); // Signal type - ASSERT_MSG(next_parameter.buffer.size() <= buffer_size, "Input static buffer is too small !"); - rb.Push(static_cast<u32>(next_parameter.buffer.size())); // Parameter buffer size + rb.Push(next_parameter->sender_id); + rb.Push(next_parameter->signal); // Signal type + ASSERT_MSG(next_parameter->buffer.size() <= buffer_size, "Input static buffer is too small !"); + rb.Push(static_cast<u32>(next_parameter->buffer.size())); // Parameter buffer size - rb.PushCopyHandles((next_parameter.object != nullptr) - ? Kernel::g_handle_table.Create(next_parameter.object).Unwrap() + rb.PushMoveHandles((next_parameter->object != nullptr) + ? Kernel::g_handle_table.Create(next_parameter->object).Unwrap() : 0); - rb.PushStaticBuffer(buffer, static_cast<u32>(next_parameter.buffer.size()), 0); - Memory::WriteBlock(buffer, next_parameter.buffer.data(), next_parameter.buffer.size()); + rb.PushStaticBuffer(buffer, static_cast<u32>(next_parameter->buffer.size()), 0); - LOG_WARNING(Service_APT, "called app_id=0x%08X, buffer_size=0x%08zX", app_id, buffer_size); + Memory::WriteBlock(buffer, next_parameter->buffer.data(), next_parameter->buffer.size()); + + // Note: The NS module always clears the DSPSleep and DSPWakeup signals even in GlanceParameter. + if (next_parameter->signal == static_cast<u32>(SignalType::DspSleep) || + next_parameter->signal == static_cast<u32>(SignalType::DspWakeup)) + next_parameter = boost::none; } void CancelParameter(Service::Interface* self) { IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0xF, 4, 0); // 0xF0100 - u32 check_sender = rp.Pop<u32>(); + bool check_sender = rp.Pop<bool>(); u32 sender_appid = rp.Pop<u32>(); - u32 check_receiver = rp.Pop<u32>(); + bool check_receiver = rp.Pop<bool>(); u32 receiver_appid = rp.Pop<u32>(); + + bool cancellation_success = true; + + if (!next_parameter) { + cancellation_success = false; + } else { + if (check_sender && next_parameter->sender_id != sender_appid) + cancellation_success = false; + + if (check_receiver && next_parameter->destination_id != receiver_appid) + cancellation_success = false; + } + + if (cancellation_success) + next_parameter = boost::none; + IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); + rb.Push(RESULT_SUCCESS); // No error - rb.Push(true); // Set to Success + rb.Push(cancellation_success); - LOG_WARNING(Service_APT, "(STUBBED) called check_sender=0x%08X, sender_appid=0x%08X, " - "check_receiver=0x%08X, receiver_appid=0x%08X", - check_sender, sender_appid, check_receiver, receiver_appid); + LOG_DEBUG(Service_APT, "called check_sender=%u, sender_appid=0x%08X, " + "check_receiver=%u, receiver_appid=0x%08X", + check_sender, sender_appid, check_receiver, receiver_appid); } void PrepareToStartApplication(Service::Interface* self) { @@ -800,8 +864,10 @@ void Init() { notification_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "APT_U:Notification"); parameter_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "APT_U:Start"); - next_parameter.signal = static_cast<u32>(SignalType::Wakeup); - next_parameter.destination_id = 0x300; + // Initialize the parameter to wake up the application. + next_parameter.emplace(); + next_parameter->signal = static_cast<u32>(SignalType::Wakeup); + next_parameter->destination_id = static_cast<u32>(AppletId::Application); } void Shutdown() { @@ -812,7 +878,7 @@ void Shutdown() { notification_event = nullptr; parameter_event = nullptr; - next_parameter.object = nullptr; + next_parameter = boost::none; HLE::Applets::Shutdown(); } 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 { DisableScreenshotPostingToMiiverse = 3 }; +namespace ErrCodes { +enum { + ParameterPresent = 2, +}; +} + /// Send a parameter to the currently-running application, which will read it via ReceiveParameter void SendParameter(const MessageParameter& parameter); 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; class Room::RoomImpl { public: // This MAC address is used to generate a 'Nintendo' like Mac address. - const MacAddress NintendoOUI = {0x00, 0x1F, 0x32, 0x00, 0x00, 0x00}; + const MacAddress NintendoOUI; std::mt19937 random_gen; ///< Random number generator. Used for GenerateMacAddress ENetHost* server = nullptr; ///< Network interface. @@ -36,7 +36,8 @@ public: using MemberList = std::vector<Member>; MemberList members; ///< Information about the members of this room. - RoomImpl() : random_gen(std::random_device()()) {} + RoomImpl() + : random_gen(std::random_device()()), NintendoOUI{0x00, 0x1F, 0x32, 0x00, 0x00, 0x00} {} /// Thread that receives and dispatches network packets 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 { using MacAddress = std::array<u8, 6>; /// A special MAC address that tells the room we're joining to assign us a MAC address /// automatically. -const MacAddress NoPreferredMac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +constexpr MacAddress NoPreferredMac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // 802.11 broadcast MAC address constexpr MacAddress BroadcastMac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; |