diff --git a/CMakeLists.txt b/CMakeLists.txt index 46fff48cd..f3ee4e1fb 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -524,7 +524,7 @@ if (ENABLE_SDL2) if (YUZU_USE_BUNDLED_SDL2) # Detect toolchain and platform if ((MSVC_VERSION GREATER_EQUAL 1920 AND MSVC_VERSION LESS 1940) AND ARCHITECTURE_x86_64) - set(SDL2_VER "SDL2-2.28.1") + set(SDL2_VER "SDL2-2.28.2") else() message(FATAL_ERROR "No bundled SDL2 binaries for your toolchain. Disable YUZU_USE_BUNDLED_SDL2 and provide your own.") endif() diff --git a/README.md b/README.md index b708bb2b1..a7888abd9 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 3841. +This is the source code for early-access 3842. ## Legal Notice diff --git a/src/audio_core/renderer/system.cpp b/src/audio_core/renderer/system.cpp index 895d239d3..faa91d8fa 100755 --- a/src/audio_core/renderer/system.cpp +++ b/src/audio_core/renderer/system.cpp @@ -778,7 +778,7 @@ u32 System::DropVoices(CommandBuffer& command_buffer, u32 estimated_process_time while (i < command_buffer.count) { const auto node_id{cmd->node_id}; const auto node_id_type{cmd->node_id >> 28}; - const auto node_id_base{cmd->node_id & 0xFFF}; + const auto node_id_base{(cmd->node_id >> 16) & 0xFFF}; // If the new estimated process time falls below the limit, we're done dropping. if (estimated_process_time <= time_limit) { diff --git a/src/core/hle/service/audio/hwopus.cpp b/src/core/hle/service/audio/hwopus.cpp index f09d41712..6856cb3cb 100755 --- a/src/core/hle/service/audio/hwopus.cpp +++ b/src/core/hle/service/audio/hwopus.cpp @@ -174,7 +174,7 @@ public: {6, &IHardwareOpusDecoderManager::DecodeInterleaved, "DecodeInterleavedWithPerfAndResetOld"}, {7, nullptr, "DecodeInterleavedForMultiStreamWithPerfAndResetOld"}, {8, &IHardwareOpusDecoderManager::DecodeInterleaved, "DecodeInterleaved"}, - {9, nullptr, "DecodeInterleavedForMultiStream"}, + {9, &IHardwareOpusDecoderManager::DecodeInterleavedForMultiStream, "DecodeInterleavedForMultiStream"}, }; // clang-format on @@ -206,6 +206,16 @@ private: decoder_state.DecodeInterleaved(ctx, OpusDecoderState::PerfTime::Enabled, extra_behavior); } + void DecodeInterleavedForMultiStream(HLERequestContext& ctx) { + LOG_DEBUG(Audio, "called"); + + IPC::RequestParser rp{ctx}; + const auto extra_behavior = rp.Pop() ? OpusDecoderState::ExtraBehavior::ResetContext + : OpusDecoderState::ExtraBehavior::None; + + decoder_state.DecodeInterleaved(ctx, OpusDecoderState::PerfTime::Enabled, extra_behavior); + } + OpusDecoderState decoder_state; }; @@ -354,6 +364,40 @@ void HwOpus::OpenHardwareOpusDecoderEx(HLERequestContext& ctx) { system, OpusDecoderState{std::move(decoder), sample_rate, channel_count}); } +void HwOpus::OpenHardwareOpusDecoderForMultiStreamEx(HLERequestContext& ctx) { + OpusMultiStreamParametersEx params; + std::memcpy(¶ms, ctx.ReadBuffer().data(), ctx.GetReadBufferSize()); + + const auto& sample_rate = params.sample_rate; + const auto& channel_count = params.channel_count; + + LOG_INFO( + Audio, + "called with sample_rate={}, channel_count={}, number_streams={}, number_stereo_streams={}", + sample_rate, channel_count, params.number_streams, params.number_stereo_streams); + + ASSERT_MSG(sample_rate == 48000 || sample_rate == 24000 || sample_rate == 16000 || + sample_rate == 12000 || sample_rate == 8000, + "Invalid sample rate"); + + int error = 0; + OpusDecoderPtr decoder{opus_multistream_decoder_create( + sample_rate, static_cast(channel_count), params.number_streams, + params.number_stereo_streams, params.channel_mappings.data(), &error)}; + if (error != OPUS_OK || decoder == nullptr) { + LOG_ERROR(Audio, "Failed to create Opus decoder (error={}).", error); + IPC::ResponseBuilder rb{ctx, 2}; + // TODO(ogniK): Use correct error code + rb.Push(ResultUnknown); + return; + } + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface( + system, OpusDecoderState{std::move(decoder), sample_rate, channel_count}); +} + HwOpus::HwOpus(Core::System& system_) : ServiceFramework{system_, "hwopus"} { static const FunctionInfo functions[] = { {0, &HwOpus::OpenHardwareOpusDecoder, "OpenHardwareOpusDecoder"}, @@ -362,7 +406,8 @@ HwOpus::HwOpus(Core::System& system_) : ServiceFramework{system_, "hwopus"} { {3, nullptr, "GetWorkBufferSizeForMultiStream"}, {4, &HwOpus::OpenHardwareOpusDecoderEx, "OpenHardwareOpusDecoderEx"}, {5, &HwOpus::GetWorkBufferSizeEx, "GetWorkBufferSizeEx"}, - {6, nullptr, "OpenHardwareOpusDecoderForMultiStreamEx"}, + {6, &HwOpus::OpenHardwareOpusDecoderForMultiStreamEx, + "OpenHardwareOpusDecoderForMultiStreamEx"}, {7, &HwOpus::GetWorkBufferSizeForMultiStreamEx, "GetWorkBufferSizeForMultiStreamEx"}, {8, nullptr, "GetWorkBufferSizeExEx"}, {9, nullptr, "GetWorkBufferSizeForMultiStreamExEx"}, diff --git a/src/core/hle/service/audio/hwopus.h b/src/core/hle/service/audio/hwopus.h index 92c3c0ff3..eab6de99e 100755 --- a/src/core/hle/service/audio/hwopus.h +++ b/src/core/hle/service/audio/hwopus.h @@ -18,8 +18,10 @@ struct OpusMultiStreamParametersEx { u32 number_stereo_streams; u32 use_large_frame_size; u32 padding; - std::array channel_mappings; + std::array channel_mappings; }; +static_assert(sizeof(OpusMultiStreamParametersEx) == 0x118, + "OpusMultiStreamParametersEx has incorrect size"); class HwOpus final : public ServiceFramework { public: @@ -29,6 +31,7 @@ public: private: void OpenHardwareOpusDecoder(HLERequestContext& ctx); void OpenHardwareOpusDecoderEx(HLERequestContext& ctx); + void OpenHardwareOpusDecoderForMultiStreamEx(HLERequestContext& ctx); void GetWorkBufferSize(HLERequestContext& ctx); void GetWorkBufferSizeEx(HLERequestContext& ctx); void GetWorkBufferSizeForMultiStreamEx(HLERequestContext& ctx); diff --git a/src/core/hle/service/sockets/nsd.cpp b/src/core/hle/service/sockets/nsd.cpp index 14c055878..e802ae8b7 100755 --- a/src/core/hle/service/sockets/nsd.cpp +++ b/src/core/hle/service/sockets/nsd.cpp @@ -19,6 +19,12 @@ enum class ServerEnvironmentType : u8 { Dp, }; +// This is nn::nsd::EnvironmentIdentifier +struct EnvironmentIdentifier { + std::array identifier; +}; +static_assert(sizeof(EnvironmentIdentifier) == 0x8); + NSD::NSD(Core::System& system_, const char* name) : ServiceFramework{system_, name} { // clang-format off static const FunctionInfo functions[] = { @@ -101,8 +107,9 @@ void NSD::ResolveEx(HLERequestContext& ctx) { } void NSD::GetEnvironmentIdentifier(HLERequestContext& ctx) { - const std::string environment_identifier = "lp1"; - ctx.WriteBuffer(environment_identifier); + constexpr EnvironmentIdentifier lp1 = { + .identifier = {'l', 'p', '1', '\0', '\0', '\0', '\0', '\0'}}; + ctx.WriteBuffer(lp1); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); diff --git a/src/core/hle/service/sockets/sfdnsres.cpp b/src/core/hle/service/sockets/sfdnsres.cpp index 4b0e106ce..86f9334a4 100755 --- a/src/core/hle/service/sockets/sfdnsres.cpp +++ b/src/core/hle/service/sockets/sfdnsres.cpp @@ -150,6 +150,12 @@ static std::pair GetHostByNameRequestImpl(HLERequestConte const std::string host = Common::StringFromBuffer(host_buffer); // For now, ignore options, which are in input buffer 1 for GetHostByNameRequestWithOptions. + // Prevent resolution of Nintendo servers + if (host.find("srv.nintendo.net") != std::string::npos) { + LOG_WARNING(Network, "Resolution of hostname {} requested, returning EAI_AGAIN", host); + return {0, GetAddrInfoError::AGAIN}; + } + auto res = Network::GetAddressInfo(host, /*service*/ std::nullopt); if (!res.has_value()) { return {0, Translate(res.error())}; @@ -261,6 +267,12 @@ static std::pair GetAddrInfoRequestImpl(HLERequestContext const auto host_buffer = ctx.ReadBuffer(0); const std::string host = Common::StringFromBuffer(host_buffer); + // Prevent resolution of Nintendo servers + if (host.find("srv.nintendo.net") != std::string::npos) { + LOG_WARNING(Network, "Resolution of hostname {} requested, returning EAI_AGAIN", host); + return {0, GetAddrInfoError::AGAIN}; + } + std::optional service = std::nullopt; if (ctx.CanReadBuffer(1)) { const std::span service_buffer = ctx.ReadBuffer(1);