Compare commits

...

12 Commits

Author SHA1 Message Date
Behunin
e55480fb55 web_service: Add cookie parser 2023-08-29 13:11:57 -06:00
liamwhite
3d5ecc1f08 Merge pull request #11406 from german77/sdl2-28-2
externals: Update SDL to 2.28.2
2023-08-29 09:27:54 -04:00
liamwhite
52c71e7eb6 Merge pull request #11408 from Kelebek1/fix_audio_node_id
[Audio] Fix node id index in DropVoices
2023-08-29 09:27:40 -04:00
liamwhite
1f04a3dd55 Merge pull request #11409 from liamwhite/splatoon-nsd-v2
sfdnsres: ensure lp1 is not resolved
2023-08-29 09:27:32 -04:00
liamwhite
d360abadba Merge pull request #11112 from danilaml/nvdec-deinterlace
Use initial_frame to check interlaced flag
2023-08-29 09:27:22 -04:00
Charles Lombardo
2f18fa5cd1 Merge pull request #11392 from t895/layout-troubles
android: Emulation activity fixes
2023-08-29 02:11:13 -04:00
Liam
6c68b07a67 sfdnsres: ensure lp1 is not resolved 2023-08-28 11:55:53 -04:00
Kelebek1
1d201c71dc Fix node id index in DropVoices 2023-08-28 10:35:30 +01:00
german77
4077ff6851 externals: Update SDL to 2.28.2 2023-08-27 21:08:28 -06:00
Danila Malyutin
164f880f23 Use initial_frame to check interlaced flag
If final frame was transferred from GPU, it won't carry the props.

Fixes #11089
2023-08-28 00:48:53 +04:00
Charles Lombardo
037f82025c android: Don't set a default emulation orientation
Could cause unnecessary configuration change when setting an orientation other than "Landscape"
2023-08-27 00:19:03 -04:00
Charles Lombardo
338d6f29b1 android: Properly adjust emulation surface aspect ratio
Previously the emulation surface wouldn't respond properly to orientation changes. This would result in the screen appearing stretched when starting in one orientation and switching to another.

The code for calculating the bounds of the view have been changed to match the expected behavior now. Before the view would just match parent in height and width. Now instead of using setLeftTopRightBottom (which is intended to be used for animations) we pass newly calculated bounds for the view into super. Now the view bounds match the emulation output.

This also means that we don't need the overload for the SettingsActivity to launch it using an ActivityResultLauncher. We can just update the view in onResume.
2023-08-27 00:16:53 -04:00
14 changed files with 1213 additions and 54 deletions

View File

@@ -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()

2
externals/SDL vendored

View File

@@ -164,7 +164,7 @@ if (NOT WIN32 AND NOT ANDROID)
--enable-decoder=h264
--enable-decoder=vp8
--enable-decoder=vp9
--enable-filter=yadif
--enable-filter=yadif,scale
--cc="${FFmpeg_CC}"
--cxx="${FFmpeg_CXX}"
${FFmpeg_HWACCEL_FLAGS}
@@ -254,7 +254,7 @@ elseif(ANDROID)
set(FFmpeg_INCLUDE_DIR "${FFmpeg_INCLUDE_DIR}" PARENT_SCOPE)
elseif(WIN32)
# Use yuzu FFmpeg binaries
set(FFmpeg_EXT_NAME "ffmpeg-5.1.3")
set(FFmpeg_EXT_NAME "ffmpeg-6.0")
set(FFmpeg_PATH "${CMAKE_BINARY_DIR}/externals/${FFmpeg_EXT_NAME}")
download_bundled_external("ffmpeg/" ${FFmpeg_EXT_NAME} "")
set(FFmpeg_FOUND YES)

View File

@@ -56,7 +56,6 @@ SPDX-License-Identifier: GPL-3.0-or-later
android:name="org.yuzu.yuzu_emu.activities.EmulationActivity"
android:theme="@style/Theme.Yuzu.Main"
android:launchMode="singleTop"
android:screenOrientation="userLandscape"
android:supportsPictureInPicture="true"
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|uiMode"
android:exported="true">

View File

@@ -11,7 +11,6 @@ import android.view.View
import android.view.ViewGroup.MarginLayoutParams
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
@@ -246,17 +245,5 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView {
settings.putExtra(ARG_GAME_ID, gameId)
context.startActivity(settings)
}
fun launch(
context: Context,
launcher: ActivityResultLauncher<Intent>,
menuTag: String?,
gameId: String?
) {
val settings = Intent(context, SettingsActivity::class.java)
settings.putExtra(ARG_MENU_TAG, menuTag)
settings.putExtra(ARG_GAME_ID, gameId)
launcher.launch(settings)
}
}
}

View File

@@ -7,7 +7,6 @@ import android.annotation.SuppressLint
import android.app.AlertDialog
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.SharedPreferences
import android.content.pm.ActivityInfo
import android.content.res.Configuration
@@ -19,8 +18,6 @@ import android.util.Rational
import android.view.*
import android.widget.TextView
import androidx.activity.OnBackPressedCallback
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.widget.PopupMenu
import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.Insets
@@ -66,8 +63,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
private var isInFoldableLayout = false
private lateinit var onReturnFromSettings: ActivityResultLauncher<Intent>
override fun onAttach(context: Context) {
super.onAttach(context)
if (context is EmulationActivity) {
@@ -81,11 +76,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
.collect { updateFoldableLayout(context, it) }
}
}
onReturnFromSettings = context.activityResultRegistry.register(
"SettingsResult",
ActivityResultContracts.StartActivityForResult()
) { updateScreenLayout() }
} else {
throw IllegalStateException("EmulationFragment must have EmulationActivity parent")
}
@@ -149,12 +139,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
}
R.id.menu_settings -> {
SettingsActivity.launch(
requireContext(),
onReturnFromSettings,
SettingsFile.FILE_NAME_CONFIG,
""
)
SettingsActivity.launch(requireContext(), SettingsFile.FILE_NAME_CONFIG, "")
true
}

View File

@@ -7,7 +7,6 @@ import android.content.Context
import android.util.AttributeSet
import android.util.Rational
import android.view.SurfaceView
import kotlin.math.roundToInt
class FixedRatioSurfaceView @JvmOverloads constructor(
context: Context,
@@ -22,27 +21,44 @@ class FixedRatioSurfaceView @JvmOverloads constructor(
*/
fun setAspectRatio(ratio: Rational?) {
aspectRatio = ratio?.toFloat() ?: 0f
requestLayout()
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val width = MeasureSpec.getSize(widthMeasureSpec)
val height = MeasureSpec.getSize(heightMeasureSpec)
val displayWidth: Float = MeasureSpec.getSize(widthMeasureSpec).toFloat()
val displayHeight: Float = MeasureSpec.getSize(heightMeasureSpec).toFloat()
if (aspectRatio != 0f) {
val newWidth: Int
val newHeight: Int
if (height * aspectRatio < width) {
newWidth = (height * aspectRatio).roundToInt()
newHeight = height
val displayAspect = displayWidth / displayHeight
if (displayAspect < aspectRatio) {
// Max out width
val halfHeight = displayHeight / 2
val surfaceHeight = displayWidth / aspectRatio
val newTop: Float = halfHeight - (surfaceHeight / 2)
val newBottom: Float = halfHeight + (surfaceHeight / 2)
super.onMeasure(
widthMeasureSpec,
MeasureSpec.makeMeasureSpec(
newBottom.toInt() - newTop.toInt(),
MeasureSpec.EXACTLY
)
)
return
} else {
newWidth = width
newHeight = (width / aspectRatio).roundToInt()
// Max out height
val halfWidth = displayWidth / 2
val surfaceWidth = displayHeight * aspectRatio
val newLeft: Float = halfWidth - (surfaceWidth / 2)
val newRight: Float = halfWidth + (surfaceWidth / 2)
super.onMeasure(
MeasureSpec.makeMeasureSpec(
newRight.toInt() - newLeft.toInt(),
MeasureSpec.EXACTLY
),
heightMeasureSpec
)
return
}
val left = (width - newWidth) / 2
val top = (height - newHeight) / 2
setLeftTopRightBottom(left, top, left + newWidth, top + newHeight)
} else {
setLeftTopRightBottom(0, 0, width, height)
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
}
}

View File

@@ -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) {

View File

@@ -19,6 +19,12 @@ enum class ServerEnvironmentType : u8 {
Dp,
};
// This is nn::nsd::EnvironmentIdentifier
struct EnvironmentIdentifier {
std::array<u8, 8> 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);

View File

@@ -150,6 +150,12 @@ static std::pair<u32, GetAddrInfoError> 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<u32, GetAddrInfoError> 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<std::string> service = std::nullopt;
if (ctx.CanReadBuffer(1)) {
const std::span<const u8> service_buffer = ctx.ReadBuffer(1);

View File

@@ -319,6 +319,7 @@ void Codec::Decode() {
LOG_WARNING(Service_NVDRV, "Zero width or height in frame");
return;
}
bool is_interlaced = initial_frame->interlaced_frame != 0;
if (av_codec_ctx->hw_device_ctx) {
final_frame = AVFramePtr{av_frame_alloc(), AVFrameDeleter};
ASSERT_MSG(final_frame, "av_frame_alloc final_frame failed");
@@ -334,7 +335,7 @@ void Codec::Decode() {
UNIMPLEMENTED_MSG("Unexpected video format: {}", final_frame->format);
return;
}
if (!final_frame->interlaced_frame) {
if (!is_interlaced) {
av_frames.push(std::move(final_frame));
} else {
if (!filters_initialized) {

View File

@@ -4,6 +4,8 @@
add_library(web_service STATIC
announce_room_json.cpp
announce_room_json.h
cookie.cpp
cookie.h
precompiled_headers.h
telemetry_json.cpp
telemetry_json.h

1052
src/web_service/cookie.cpp Normal file

File diff suppressed because it is too large Load Diff

98
src/web_service/cookie.h Normal file
View File

@@ -0,0 +1,98 @@
// SPDX-FileCopyrightText: 2023 Yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <ctime>
#include <regex>
#include <string>
#include <utility>
#include <vector>
namespace WebService {
class Cookie {
public:
explicit Cookie(std::string name, std::string value);
Cookie() = default;
~Cookie() = default;
enum class RawForm { NameAndValueOnly, Full };
enum class SameSite { Default, None, Lax, Strict };
static constexpr bool IsTerminator(char c) {
return c == '\n' || c == '\r';
}
static constexpr bool IsValueSeparator(char c) {
return IsTerminator(c) || c == ';';
}
static constexpr bool IsWS(char c) {
return c == ' ' || c == '\t' || c == '\r' || c == '\n';
}
static size_t AdvanceTo(std::string_view text, size_t from) {
// RFC 2616 defines linear whitespace as:
// LWS = [CRLF] 1*( SP | HT )
// We ignore the fact that CRLF must come as a pair at this point
// It's an invalid HTTP header if that happens.
while (from < text.size()) {
if (IsWS(text[from]))
++from;
else
return from; // non-whitespace
}
// reached the end
return text.size();
}
bool IsSecure() const;
void SetSecure(bool enable);
bool IsHttpOnly() const;
void SetHttpOnly(bool enable);
SameSite SameSitePolicy() const;
void SetSameSitePolicy(SameSite same_site);
std::tm ExpirationDate() const;
void SetExpirationDate(std::tm date);
std::string Domain() const;
void SetDomain(std::string domain);
std::string Path() const;
void SetPath(std::string path);
std::string Name() const;
void SetName(std::string cookieName);
std::string Value() const;
void SetValue(std::string value);
std::string ToString(RawForm form = RawForm::Full) const;
static bool ParseTimeString(const std::string& string, std::tm* result);
static Cookie::SameSite SameSiteFromString(std::string_view str);
static std::string SameSiteToString(SameSite same_site);
static std::pair<std::string, std::string> NextPair(const std::string& text, size_t& position,
bool is_name_value);
static std::vector<Cookie> ParseAllCookies(const std::string& cookie_string);
static std::vector<Cookie> ParseCookie(const std::string& cookie_string);
private:
std::tm m_expiration_date{};
std::string m_domain;
std::string m_path;
std::string m_comment;
std::string m_name;
std::string m_value;
SameSite m_same_site = SameSite::Default;
bool m_secure = false;
bool m_http_only = false;
};
} // namespace WebService