Compare commits

..

1 Commits

Author SHA1 Message Date
yuzubot
808e285985 Android #50 2023-08-25 00:57:16 +00:00
70 changed files with 224 additions and 674 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.2")
set(SDL2_VER "SDL2-2.28.1")
else()
message(FATAL_ERROR "No bundled SDL2 binaries for your toolchain. Disable YUZU_USE_BUNDLED_SDL2 and provide your own.")
endif()

View File

@@ -78,11 +78,6 @@ QPushButton#buttonRefreshDevices {
max-height: 21px;
}
QPushButton#button_reset_defaults {
min-width: 57px;
padding: 4px 8px;
}
QWidget#bottomPerGameInput,
QWidget#topControllerApplet,
QWidget#bottomControllerApplet,

View File

@@ -2228,10 +2228,6 @@ QPushButton#buttonRefreshDevices {
padding: 0px 0px;
}
QPushButton#button_reset_defaults {
padding: 3px 6px;
}
QSpinBox#spinboxLStickRange,
QSpinBox#spinboxRStickRange,
QSpinBox#vibrationSpinPlayer1,

View File

@@ -42,11 +42,6 @@ endif()
# mbedtls
add_subdirectory(mbedtls)
target_include_directories(mbedtls PUBLIC ./mbedtls/include)
if (NOT MSVC)
target_compile_options(mbedcrypto PRIVATE
-Wno-unused-but-set-variable
-Wno-string-concatenation)
endif()
# MicroProfile
add_library(microprofile INTERFACE)
@@ -99,12 +94,6 @@ if (ENABLE_CUBEB AND NOT TARGET cubeb::cubeb)
set(BUILD_TOOLS OFF)
add_subdirectory(cubeb)
add_library(cubeb::cubeb ALIAS cubeb)
if (NOT MSVC)
if (TARGET speex)
target_compile_options(speex PRIVATE -Wno-sign-compare)
endif()
target_compile_options(cubeb PRIVATE -Wno-implicit-const-int-float-conversion)
endif()
endif()
# DiscordRPC
@@ -162,9 +151,6 @@ endif()
if (NOT TARGET LLVM::Demangle)
add_library(demangle demangle/ItaniumDemangle.cpp)
target_include_directories(demangle PUBLIC ./demangle)
if (NOT MSVC)
target_compile_options(demangle PRIVATE -Wno-deprecated-declarations) # std::is_pod
endif()
add_library(LLVM::Demangle ALIAS demangle)
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,scale
--enable-filter=yadif
--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-6.0")
set(FFmpeg_EXT_NAME "ffmpeg-5.1.3")
set(FFmpeg_PATH "${CMAKE_BINARY_DIR}/externals/${FFmpeg_EXT_NAME}")
download_bundled_external("ffmpeg/" ${FFmpeg_EXT_NAME} "")
set(FFmpeg_FOUND YES)

View File

@@ -114,18 +114,15 @@ else()
-Wno-attributes
-Wno-invalid-offsetof
-Wno-unused-parameter
)
if (CMAKE_CXX_COMPILER_ID MATCHES Clang) # Clang or AppleClang
add_compile_options(
-Wno-braced-scalar-init
-Wno-unused-private-field
-Wno-nullability-completeness
-Werror=shadow-uncaptured-local
-Werror=implicit-fallthrough
-Werror=type-limits
)
endif()
$<$<CXX_COMPILER_ID:Clang>:-Wno-braced-scalar-init>
$<$<CXX_COMPILER_ID:Clang>:-Wno-unused-private-field>
$<$<CXX_COMPILER_ID:Clang>:-Werror=shadow-uncaptured-local>
$<$<CXX_COMPILER_ID:Clang>:-Werror=implicit-fallthrough>
$<$<CXX_COMPILER_ID:Clang>:-Werror=type-limits>
$<$<CXX_COMPILER_ID:AppleClang>:-Wno-braced-scalar-init>
$<$<CXX_COMPILER_ID:AppleClang>:-Wno-unused-private-field>
)
if (ARCHITECTURE_x86_64)
add_compile_options("-mcx16")

View File

@@ -25,7 +25,6 @@ SPDX-License-Identifier: GPL-3.0-or-later
android:hasFragileUserData="false"
android:supportsRtl="true"
android:isGame="true"
android:appCategory="game"
android:localeConfig="@xml/locales_config"
android:banner="@drawable/tv_banner"
android:extractNativeLibs="true"
@@ -56,6 +55,7 @@ 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">
@@ -66,14 +66,6 @@ SPDX-License-Identifier: GPL-3.0-or-later
<data android:mimeType="application/octet-stream" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data
android:mimeType="application/octet-stream"
android:scheme="content"/>
</intent-filter>
<meta-data
android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="@xml/nfc_tech_filter" />

View File

@@ -11,6 +11,7 @@ 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
@@ -245,5 +246,17 @@ 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,11 +7,11 @@ 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
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.Looper
@@ -19,6 +19,8 @@ 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
@@ -48,7 +50,6 @@ import org.yuzu.yuzu_emu.features.settings.model.IntSetting
import org.yuzu.yuzu_emu.features.settings.model.Settings
import org.yuzu.yuzu_emu.features.settings.ui.SettingsActivity
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
import org.yuzu.yuzu_emu.model.Game
import org.yuzu.yuzu_emu.overlay.InputOverlay
import org.yuzu.yuzu_emu.utils.*
@@ -61,12 +62,12 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
private var _binding: FragmentEmulationBinding? = null
private val binding get() = _binding!!
private val args by navArgs<EmulationFragmentArgs>()
private lateinit var game: Game
val args by navArgs<EmulationFragmentArgs>()
private var isInFoldableLayout = false
private lateinit var onReturnFromSettings: ActivityResultLauncher<Intent>
override fun onAttach(context: Context) {
super.onAttach(context)
if (context is EmulationActivity) {
@@ -80,6 +81,11 @@ 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")
}
@@ -91,25 +97,10 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val intentUri: Uri? = requireActivity().intent.data
var intentGame: Game? = null
if (intentUri != null) {
intentGame = if (Game.extensions.contains(FileUtil.getExtension(intentUri))) {
GameHelper.getGame(requireActivity().intent.data!!, false)
} else {
null
}
}
game = if (args.game != null) {
args.game!!
} else {
intentGame ?: error("[EmulationFragment] No bootable game present!")
}
// So this fragment doesn't restart on configuration changes; i.e. rotation.
retainInstance = true
preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
emulationState = EmulationState(game.path)
emulationState = EmulationState(args.game.path)
}
/**
@@ -133,7 +124,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
updateShowFpsOverlay()
binding.inGameMenu.getHeaderView(0).findViewById<TextView>(R.id.text_game_title).text =
game.title
args.game.title
binding.inGameMenu.setNavigationItemSelectedListener {
when (it.itemId) {
R.id.menu_pause_emulation -> {
@@ -158,7 +149,12 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
}
R.id.menu_settings -> {
SettingsActivity.launch(requireContext(), SettingsFile.FILE_NAME_CONFIG, "")
SettingsActivity.launch(
requireContext(),
onReturnFromSettings,
SettingsFile.FILE_NAME_CONFIG,
""
)
true
}

View File

@@ -63,13 +63,13 @@ object GameHelper {
)
} else {
if (Game.extensions.contains(FileUtil.getExtension(it.uri))) {
games.add(getGame(it.uri, true))
games.add(getGame(it.uri))
}
}
}
}
fun getGame(uri: Uri, addedToLibrary: Boolean): Game {
private fun getGame(uri: Uri): Game {
val filePath = uri.toString()
var name = NativeLibrary.getTitle(filePath)
@@ -94,13 +94,11 @@ object GameHelper {
NativeLibrary.isHomebrew(filePath)
)
if (addedToLibrary) {
val addedTime = preferences.getLong(newGame.keyAddedToLibraryTime, 0L)
if (addedTime == 0L) {
preferences.edit()
.putLong(newGame.keyAddedToLibraryTime, System.currentTimeMillis())
.apply()
}
val addedTime = preferences.getLong(newGame.keyAddedToLibraryTime, 0L)
if (addedTime == 0L) {
preferences.edit()
.putLong(newGame.keyAddedToLibraryTime, System.currentTimeMillis())
.apply()
}
return newGame

View File

@@ -7,6 +7,7 @@ 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,
@@ -21,44 +22,27 @@ class FixedRatioSurfaceView @JvmOverloads constructor(
*/
fun setAspectRatio(ratio: Rational?) {
aspectRatio = ratio?.toFloat() ?: 0f
requestLayout()
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val displayWidth: Float = MeasureSpec.getSize(widthMeasureSpec).toFloat()
val displayHeight: Float = MeasureSpec.getSize(heightMeasureSpec).toFloat()
if (aspectRatio != 0f) {
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 {
// 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
}
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val width = MeasureSpec.getSize(widthMeasureSpec)
val height = MeasureSpec.getSize(heightMeasureSpec)
if (aspectRatio != 0f) {
val newWidth: Int
val newHeight: Int
if (height * aspectRatio < width) {
newWidth = (height * aspectRatio).roundToInt()
newHeight = height
} else {
newWidth = width
newHeight = (width / aspectRatio).roundToInt()
}
val left = (width - newWidth) / 2
val top = (height - newHeight) / 2
setLeftTopRightBottom(left, top, left + newWidth, top + newHeight)
} else {
setLeftTopRightBottom(0, 0, width, height)
}
}
}

View File

@@ -11,7 +11,6 @@
#include "common/fs/path_util.h"
#include "common/logging/log.h"
#include "common/settings.h"
#include "common/settings_enums.h"
#include "core/hle/service/acc/profile_manager.h"
#include "input_common/main.h"
#include "jni/config.h"
@@ -145,9 +144,7 @@ void Config::ReadValues() {
Service::Account::MAX_USERS - 1);
// Disable docked mode by default on Android
Settings::values.use_docked_mode.SetValue(config->GetBoolean("System", "use_docked_mode", false)
? Settings::ConsoleMode::Docked
: Settings::ConsoleMode::Handheld);
Settings::values.use_docked_mode = config->GetBoolean("System", "use_docked_mode", false);
const auto rng_seed_enabled = config->GetBoolean("System", "rng_seed_enabled", false);
if (rng_seed_enabled) {

View File

@@ -30,7 +30,6 @@
#include "core/cpu_manager.h"
#include "core/crypto/key_manager.h"
#include "core/file_sys/card_image.h"
#include "core/file_sys/content_archive.h"
#include "core/file_sys/registered_cache.h"
#include "core/file_sys/submission_package.h"
#include "core/file_sys/vfs.h"
@@ -225,42 +224,6 @@ public:
m_system.Renderer().NotifySurfaceChanged();
}
void ConfigureFilesystemProvider(const std::string& filepath) {
const auto file = m_system.GetFilesystem()->OpenFile(filepath, FileSys::Mode::Read);
if (!file) {
return;
}
auto loader = Loader::GetLoader(m_system, file);
if (!loader) {
return;
}
const auto file_type = loader->GetFileType();
if (file_type == Loader::FileType::Unknown || file_type == Loader::FileType::Error) {
return;
}
u64 program_id = 0;
const auto res2 = loader->ReadProgramId(program_id);
if (res2 == Loader::ResultStatus::Success && file_type == Loader::FileType::NCA) {
m_manual_provider->AddEntry(FileSys::TitleType::Application,
FileSys::GetCRTypeFromNCAType(FileSys::NCA{file}.GetType()),
program_id, file);
} else if (res2 == Loader::ResultStatus::Success &&
(file_type == Loader::FileType::XCI || file_type == Loader::FileType::NSP)) {
const auto nsp = file_type == Loader::FileType::NSP
? std::make_shared<FileSys::NSP>(file)
: FileSys::XCI{file}.GetSecurePartitionNSP();
for (const auto& title : nsp->GetNCAs()) {
for (const auto& entry : title.second) {
m_manual_provider->AddEntry(entry.first.first, entry.first.second, title.first,
entry.second->GetBaseFile());
}
}
}
}
Core::SystemResultStatus InitializeEmulation(const std::string& filepath) {
std::scoped_lock lock(m_mutex);
@@ -291,14 +254,8 @@ public:
std::move(android_keyboard), // Software Keyboard
nullptr, // Web Browser
});
// Initialize filesystem.
m_manual_provider = std::make_unique<FileSys::ManualContentProvider>();
m_system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
m_system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::FrontendManual,
m_manual_provider.get());
m_system.GetFileSystemController().CreateFactories(*m_vfs);
ConfigureFilesystemProvider(filepath);
// Initialize account manager
m_profile_manager = std::make_unique<Service::Account::ProfileManager>();
@@ -420,7 +377,7 @@ public:
return false;
}
return !Settings::IsDockedMode();
return !Settings::values.use_docked_mode.GetValue();
}
void SetDeviceType([[maybe_unused]] int index, int type) {
@@ -532,7 +489,6 @@ private:
bool m_is_paused{};
SoftwareKeyboard::AndroidKeyboard* m_software_keyboard{};
std::unique_ptr<Service::Account::ProfileManager> m_profile_manager;
std::unique_ptr<FileSys::ManualContentProvider> m_manual_provider;
// GPU driver parameters
std::shared_ptr<Common::DynamicLibrary> m_vulkan_library;

View File

@@ -12,9 +12,7 @@
tools:layout="@layout/fragment_emulation" >
<argument
android:name="game"
app:argType="org.yuzu.yuzu_emu.model.Game"
app:nullable="true"
android:defaultValue="@null" />
app:argType="org.yuzu.yuzu_emu.model.Game" />
</fragment>
</navigation>

View File

@@ -62,9 +62,7 @@
android:label="EmulationActivity">
<argument
android:name="game"
app:argType="org.yuzu.yuzu_emu.model.Game"
app:nullable="true"
android:defaultValue="@null" />
app:argType="org.yuzu.yuzu_emu.model.Game" />
</activity>
<action

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 >> 16) & 0xFFF};
const auto node_id_base{cmd->node_id & 0xFFF};
// If the new estimated process time falls below the limit, we're done dropping.
if (estimated_process_time <= time_limit) {

View File

@@ -8,7 +8,6 @@
#include "audio_core/sink/cubeb_sink.h"
#include "audio_core/sink/sink_stream.h"
#include "common/logging/log.h"
#include "common/scope_exit.h"
#include "core/core.h"
#ifdef _WIN32
@@ -333,38 +332,25 @@ std::vector<std::string> ListCubebSinkDevices(bool capture) {
return device_list;
}
namespace {
static long TmpDataCallback(cubeb_stream*, void*, const void*, void*, long) {
return TargetSampleCount;
}
static void TmpStateCallback(cubeb_stream*, void*, cubeb_state) {}
} // namespace
bool IsCubebSuitable() {
#if !defined(HAVE_CUBEB)
return false;
#else
cubeb* ctx{nullptr};
u32 GetCubebLatency() {
cubeb* ctx;
#ifdef _WIN32
auto com_init_result = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
#endif
// Init cubeb
if (cubeb_init(&ctx, "yuzu Latency Getter", nullptr) != CUBEB_OK) {
LOG_ERROR(Audio_Sink, "Cubeb failed to init, it is not suitable.");
return false;
LOG_CRITICAL(Audio_Sink, "cubeb_init failed");
// Return a large latency so we choose SDL instead.
return 10000u;
}
SCOPE_EXIT({ cubeb_destroy(ctx); });
#ifdef _WIN32
if (SUCCEEDED(com_init_result)) {
CoUninitialize();
}
#endif
// Get min latency
cubeb_stream_params params{};
params.rate = TargetSampleRate;
params.channels = 2;
@@ -375,27 +361,12 @@ bool IsCubebSuitable() {
u32 latency{0};
const auto latency_error = cubeb_get_min_latency(ctx, &params, &latency);
if (latency_error != CUBEB_OK) {
LOG_ERROR(Audio_Sink, "Cubeb could not get min latency, it is not suitable.");
return false;
LOG_CRITICAL(Audio_Sink, "Error getting minimum latency, error: {}", latency_error);
latency = TargetSampleCount * 2;
}
latency = std::max(latency, TargetSampleCount * 2);
// Test opening a device with standard parameters
cubeb_devid output_device{0};
cubeb_devid input_device{0};
std::string name{"Yuzu test"};
cubeb_stream* stream{nullptr};
if (cubeb_stream_init(ctx, &stream, name.c_str(), input_device, nullptr, output_device, &params,
latency, &TmpDataCallback, &TmpStateCallback, nullptr) != CUBEB_OK) {
LOG_CRITICAL(Audio_Sink, "Cubeb could not open a device, it is not suitable.");
return false;
}
cubeb_stream_stop(stream);
cubeb_stream_destroy(stream);
return true;
#endif
cubeb_destroy(ctx);
return latency;
}
} // namespace AudioCore::Sink

View File

@@ -97,11 +97,10 @@ private:
std::vector<std::string> ListCubebSinkDevices(bool capture);
/**
* Check if this backend is suitable for use.
* Checks if enabled, its latency, whether it opens successfully, etc.
* Get the reported latency for this sink.
*
* @return True is this backend is suitable, false otherwise.
* @return Minimum latency for this sink.
*/
bool IsCubebSuitable();
u32 GetCubebLatency();
} // namespace AudioCore::Sink

View File

@@ -9,7 +9,6 @@
#include "audio_core/sink/sdl2_sink.h"
#include "audio_core/sink/sink_stream.h"
#include "common/logging/log.h"
#include "common/scope_exit.h"
#include "core/core.h"
namespace AudioCore::Sink {
@@ -85,7 +84,6 @@ public:
}
Stop();
SDL_ClearQueuedAudio(device);
SDL_CloseAudioDevice(device);
}
@@ -229,42 +227,8 @@ std::vector<std::string> ListSDLSinkDevices(bool capture) {
return device_list;
}
bool IsSDLSuitable() {
#if !defined(HAVE_SDL2)
return false;
#else
// Check SDL can init
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
LOG_ERROR(Audio_Sink, "SDL failed to init, it is not suitable. Error: {}",
SDL_GetError());
return false;
}
}
// We can set any latency frequency we want with SDL, so no need to check that.
// Check we can open a device with standard parameters
SDL_AudioSpec spec;
spec.freq = TargetSampleRate;
spec.channels = 2u;
spec.format = AUDIO_S16SYS;
spec.samples = TargetSampleCount * 2;
spec.callback = nullptr;
spec.userdata = nullptr;
SDL_AudioSpec obtained;
auto device = SDL_OpenAudioDevice(nullptr, false, &spec, &obtained, false);
if (device == 0) {
LOG_ERROR(Audio_Sink, "SDL failed to open a device, it is not suitable. Error: {}",
SDL_GetError());
return false;
}
SDL_CloseAudioDevice(device);
return true;
#endif
u32 GetSDLLatency() {
return TargetSampleCount * 2;
}
} // namespace AudioCore::Sink

View File

@@ -88,11 +88,10 @@ private:
std::vector<std::string> ListSDLSinkDevices(bool capture);
/**
* Check if this backend is suitable for use.
* Checks if enabled, its latency, whether it opens successfully, etc.
* Get the reported latency for this sink.
*
* @return True is this backend is suitable, false otherwise.
* @return Minimum latency for this sink.
*/
bool IsSDLSuitable();
u32 GetSDLLatency();
} // namespace AudioCore::Sink

View File

@@ -22,7 +22,7 @@ namespace {
struct SinkDetails {
using FactoryFn = std::unique_ptr<Sink> (*)(std::string_view);
using ListDevicesFn = std::vector<std::string> (*)(bool);
using SuitableFn = bool (*)();
using LatencyFn = u32 (*)();
/// Name for this sink.
Settings::AudioEngine id;
@@ -30,8 +30,8 @@ struct SinkDetails {
FactoryFn factory;
/// A method to call to list available devices.
ListDevicesFn list_devices;
/// Check whether this backend is suitable to be used.
SuitableFn is_suitable;
/// Method to get the latency of this backend.
LatencyFn latency;
};
// sink_details is ordered in terms of desirability, with the best choice at the top.
@@ -43,7 +43,7 @@ constexpr SinkDetails sink_details[] = {
return std::make_unique<CubebSink>(device_id);
},
&ListCubebSinkDevices,
&IsCubebSuitable,
&GetCubebLatency,
},
#endif
#ifdef HAVE_SDL2
@@ -53,17 +53,14 @@ constexpr SinkDetails sink_details[] = {
return std::make_unique<SDLSink>(device_id);
},
&ListSDLSinkDevices,
&IsSDLSuitable,
&GetSDLLatency,
},
#endif
SinkDetails{
Settings::AudioEngine::Null,
[](std::string_view device_id) -> std::unique_ptr<Sink> {
return std::make_unique<NullSink>(device_id);
},
[](bool capture) { return std::vector<std::string>{"null"}; },
[]() { return true; },
},
SinkDetails{Settings::AudioEngine::Null,
[](std::string_view device_id) -> std::unique_ptr<Sink> {
return std::make_unique<NullSink>(device_id);
},
[](bool capture) { return std::vector<std::string>{"null"}; }, []() { return 0u; }},
};
const SinkDetails& GetOutputSinkDetails(Settings::AudioEngine sink_id) {
@@ -75,22 +72,18 @@ const SinkDetails& GetOutputSinkDetails(Settings::AudioEngine sink_id) {
auto iter = find_backend(sink_id);
if (sink_id == Settings::AudioEngine::Auto) {
// Auto-select a backend. Use the sink details ordering, preferring cubeb first, checking
// that the backend is available and suitable to use.
for (auto& details : sink_details) {
if (details.is_suitable()) {
iter = &details;
break;
}
// Auto-select a backend. Prefer CubeB, but it may report a large minimum latency which
// causes audio issues, in that case go with SDL.
#if defined(HAVE_CUBEB) && defined(HAVE_SDL2)
iter = find_backend(Settings::AudioEngine::Cubeb);
if (iter->latency() > TargetSampleCount * 3) {
iter = find_backend(Settings::AudioEngine::Sdl2);
}
#else
iter = std::begin(sink_details);
#endif
LOG_INFO(Service_Audio, "Auto-selecting the {} backend",
Settings::CanonicalizeEnum(iter->id));
} else {
if (iter != std::end(sink_details) && !iter->is_suitable()) {
LOG_ERROR(Service_Audio, "Selected backend {} is not suitable, falling back to null",
Settings::CanonicalizeEnum(iter->id));
iter = find_backend(Settings::AudioEngine::Null);
}
}
if (iter == std::end(sink_details)) {

View File

@@ -2,7 +2,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <version>
#include "common/settings_enums.h"
#if __cpp_lib_chrono >= 201907L
#include <chrono>
#include <exception>
@@ -146,10 +145,6 @@ bool IsFastmemEnabled() {
return true;
}
bool IsDockedMode() {
return values.use_docked_mode.GetValue() == Settings::ConsoleMode::Docked;
}
float Volume() {
if (values.audio_muted) {
return 0.0f;

View File

@@ -379,13 +379,7 @@ struct Values {
Setting<s32> current_user{linkage, 0, "current_user", Category::System};
SwitchableSetting<ConsoleMode> use_docked_mode{linkage,
ConsoleMode::Docked,
"use_docked_mode",
Category::System,
Specialization::Radio,
true,
true};
SwitchableSetting<bool> use_docked_mode{linkage, true, "use_docked_mode", Category::System};
// Controls
InputSetting<std::array<PlayerInput, 10>> players;
@@ -525,8 +519,6 @@ bool IsGPULevelHigh();
bool IsFastmemEnabled();
bool IsDockedMode();
float Volume();
std::string GetTimeZoneString(TimeZone time_zone);

View File

@@ -56,7 +56,6 @@ enum Specialization : u8 {
Scalar = 5, // Values are continuous
Countable = 6, // Can be stepped through
Paired = 7, // Another setting is associated with this setting
Radio = 8, // Setting should be presented in a radio group
Percentage = (1 << SpecializationAttributeOffset), // Should be represented as a percentage
};

View File

@@ -146,8 +146,6 @@ ENUM(AntiAliasing, None, Fxaa, Smaa, MaxEnum);
ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch);
ENUM(ConsoleMode, Handheld, Docked);
template <typename Type>
inline std::string CanonicalizeEnum(Type id) {
const auto group = EnumMetadata<Type>::Canonicalizations();

View File

@@ -460,6 +460,11 @@ S operator&(const S& i, const swap_struct_t<T, F> v) {
return i & v.swap();
}
template <typename S, typename T, typename F>
S operator&(const swap_struct_t<T, F> v, const S& i) {
return static_cast<S>(v.swap() & i);
}
// Comparison
template <typename S, typename T, typename F>
bool operator<(const S& p, const swap_struct_t<T, F> v) {

View File

@@ -606,9 +606,9 @@ InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_ex
const auto result = RemoveExistingEntry(title_id);
// Install Metadata File
const auto meta_result = RawInstallNCA(**meta_iter, copy, overwrite_if_exists, meta_id_data);
if (meta_result != InstallResult::Success) {
return meta_result;
const auto res = RawInstallNCA(**meta_iter, copy, overwrite_if_exists, meta_id_data);
if (res != InstallResult::Success) {
return res;
}
// Install all the other NCAs
@@ -621,19 +621,9 @@ InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_ex
if (nca == nullptr) {
return InstallResult::ErrorCopyFailed;
}
if (nca->GetStatus() == Loader::ResultStatus::ErrorMissingBKTRBaseRomFS &&
nca->GetTitleId() != title_id) {
// Create fake cnmt for patch to multiprogram application
const auto sub_nca_result =
InstallEntry(*nca, TitleType::Update, overwrite_if_exists, copy);
if (sub_nca_result != InstallResult::Success) {
return sub_nca_result;
}
continue;
}
const auto nca_result = RawInstallNCA(*nca, copy, overwrite_if_exists, record.nca_id);
if (nca_result != InstallResult::Success) {
return nca_result;
const auto res2 = RawInstallNCA(*nca, copy, overwrite_if_exists, record.nca_id);
if (res2 != InstallResult::Success) {
return res2;
}
}
@@ -673,8 +663,6 @@ InstallResult RegisteredCache::InstallEntry(const NCA& nca, TitleType type,
}
bool RegisteredCache::RemoveExistingEntry(u64 title_id) const {
bool removed_data = false;
const auto delete_nca = [this](const NcaID& id) {
const auto path = GetRelativePathFromNcaID(id, false, true, false);
@@ -718,18 +706,11 @@ bool RegisteredCache::RemoveExistingEntry(u64 title_id) const {
const auto deleted_html = delete_nca(html_id);
const auto deleted_legal = delete_nca(legal_id);
removed_data |= (deleted_meta || deleted_program || deleted_data || deleted_control ||
deleted_html || deleted_legal);
return deleted_meta && (deleted_meta || deleted_program || deleted_data ||
deleted_control || deleted_html || deleted_legal);
}
// If patch entries for any program exist in yuzu meta, remove them
for (u8 i = 0; i < 0x10; i++) {
const auto meta_dir = dir->CreateDirectoryRelative("yuzu_meta");
const auto filename = GetCNMTName(TitleType::Update, title_id + i);
removed_data |= meta_dir->DeleteFile(filename);
}
return removed_data;
return false;
}
InstallResult RegisteredCache::RawInstallNCA(const NCA& nca, const VfsCopyFunction& copy,

View File

@@ -3,8 +3,6 @@
#include "common/assert.h"
#include "common/logging/log.h"
#include "common/settings.h"
#include "common/settings_enums.h"
#include "core/frontend/applets/controller.h"
#include "core/hid/emulated_controller.h"
#include "core/hid/hid_core.h"
@@ -64,7 +62,7 @@ void DefaultControllerApplet::ReconfigureControllers(ReconfigureCallback callbac
controller->Connect(true);
}
} else if (index == 0 && parameters.enable_single_mode && parameters.allow_handheld &&
!Settings::IsDockedMode()) {
!Settings::values.use_docked_mode.GetValue()) {
// We should *never* reach here under any normal circumstances.
controller->SetNpadStyleIndex(Core::HID::NpadStyleIndex::Handheld);
controller->Connect(true);

View File

@@ -5,7 +5,6 @@
#include "common/assert.h"
#include "common/settings.h"
#include "common/settings_enums.h"
#include "core/frontend/framebuffer_layout.h"
namespace Layout {
@@ -50,7 +49,7 @@ FramebufferLayout DefaultFrameLayout(u32 width, u32 height) {
}
FramebufferLayout FrameLayoutFromResolutionScale(f32 res_scale) {
const bool is_docked = Settings::IsDockedMode();
const bool is_docked = Settings::values.use_docked_mode.GetValue();
const u32 screen_width = is_docked ? ScreenDocked::Width : ScreenUndocked::Width;
const u32 screen_height = is_docked ? ScreenDocked::Height : ScreenUndocked::Height;

View File

@@ -38,7 +38,7 @@ namespace {
*/
void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority,
KProcessAddress stack_top) {
const KProcessAddress entry_point = owner_process.GetEntryPoint();
const KProcessAddress entry_point = owner_process.GetPageTable().GetCodeRegionStart();
ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::ThreadCountMax, 1));
KThread* thread = KThread::Create(system.Kernel());
@@ -358,21 +358,6 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
m_system_resource_size = metadata.GetSystemResourceSize();
m_image_size = code_size;
if (metadata.GetAddressSpaceType() == FileSys::ProgramAddressSpaceType::Is39Bit) {
// For 39-bit processes, the ASLR region starts at 0x800'0000 and is ~512GiB large.
// However, some (buggy) programs/libraries like skyline incorrectly depend on the
// existence of ASLR pages before the entry point, so we will adjust the load address
// to point to about 2GiB into the ASLR region.
m_code_address = 0x8000'0000;
} else {
// All other processes can be mapped at the beginning of the code region.
if (metadata.GetAddressSpaceType() == FileSys::ProgramAddressSpaceType::Is36Bit) {
m_code_address = 0x800'0000;
} else {
m_code_address = 0x20'0000;
}
}
KScopedResourceReservation memory_reservation(
m_resource_limit, LimitableResource::PhysicalMemoryMax, code_size + m_system_resource_size);
if (!memory_reservation.Succeeded()) {
@@ -383,15 +368,15 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
// Initialize process address space
if (const Result result{m_page_table.InitializeForProcess(
metadata.GetAddressSpaceType(), false, false, false, KMemoryManager::Pool::Application,
this->GetEntryPoint(), code_size, std::addressof(m_kernel.GetAppSystemResource()),
m_resource_limit, m_kernel.System().ApplicationMemory())};
0x8000000, code_size, std::addressof(m_kernel.GetAppSystemResource()), m_resource_limit,
m_kernel.System().ApplicationMemory())};
result.IsError()) {
R_RETURN(result);
}
// Map process code region
if (const Result result{m_page_table.MapProcessCode(this->GetEntryPoint(), code_size / PageSize,
KMemoryState::Code,
if (const Result result{m_page_table.MapProcessCode(m_page_table.GetCodeRegionStart(),
code_size / PageSize, KMemoryState::Code,
KMemoryPermission::None)};
result.IsError()) {
R_RETURN(result);

View File

@@ -177,10 +177,6 @@ public:
return m_program_id;
}
KProcessAddress GetEntryPoint() const {
return m_code_address;
}
/// Gets the resource limit descriptor for this process
KResourceLimit* GetResourceLimit() const;
@@ -489,9 +485,6 @@ private:
/// Address indicating the location of the process' dedicated TLS region.
KProcessAddress m_plr_address = 0;
/// Address indicating the location of the process's entry point.
KProcessAddress m_code_address = 0;
/// Random values for svcGetInfo RandomEntropy
std::array<u64, RANDOM_ENTROPY_SIZE> m_random_entropy{};

View File

@@ -6,7 +6,6 @@
#include <cinttypes>
#include <cstring>
#include "common/settings.h"
#include "common/settings_enums.h"
#include "core/core.h"
#include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h"
@@ -834,7 +833,7 @@ void ICommonStateGetter::GetDefaultDisplayResolution(HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
if (Settings::IsDockedMode()) {
if (Settings::values.use_docked_mode.GetValue()) {
rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedWidth));
rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedHeight));
} else {
@@ -922,7 +921,7 @@ void IStorage::Open(HLERequestContext& ctx) {
}
void ICommonStateGetter::GetOperationMode(HLERequestContext& ctx) {
const bool use_docked_mode{Settings::IsDockedMode()};
const bool use_docked_mode{Settings::values.use_docked_mode.GetValue()};
LOG_DEBUG(Service_AM, "called, use_docked_mode={}", use_docked_mode);
IPC::ResponseBuilder rb{ctx, 3};

View File

@@ -7,7 +7,6 @@
#include "common/logging/log.h"
#include "common/settings.h"
#include "common/settings_enums.h"
#include "core/core_timing.h"
#include "core/hle/service/apm/apm_controller.h"
@@ -68,7 +67,8 @@ void Controller::SetFromCpuBoostMode(CpuBoostMode mode) {
}
PerformanceMode Controller::GetCurrentPerformanceMode() const {
return Settings::IsDockedMode() ? PerformanceMode::Boost : PerformanceMode::Normal;
return Settings::values.use_docked_mode.GetValue() ? PerformanceMode::Boost
: PerformanceMode::Normal;
}
PerformanceConfiguration Controller::GetCurrentPerformanceConfiguration(PerformanceMode mode) {

View File

@@ -174,7 +174,7 @@ public:
{6, &IHardwareOpusDecoderManager::DecodeInterleaved, "DecodeInterleavedWithPerfAndResetOld"},
{7, nullptr, "DecodeInterleavedForMultiStreamWithPerfAndResetOld"},
{8, &IHardwareOpusDecoderManager::DecodeInterleaved, "DecodeInterleaved"},
{9, &IHardwareOpusDecoderManager::DecodeInterleavedForMultiStream, "DecodeInterleavedForMultiStream"},
{9, nullptr, "DecodeInterleavedForMultiStream"},
};
// clang-format on
@@ -206,16 +206,6 @@ 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<bool>() ? OpusDecoderState::ExtraBehavior::ResetContext
: OpusDecoderState::ExtraBehavior::None;
decoder_state.DecodeInterleaved(ctx, OpusDecoderState::PerfTime::Enabled, extra_behavior);
}
OpusDecoderState decoder_state;
};
@@ -364,40 +354,6 @@ void HwOpus::OpenHardwareOpusDecoderEx(HLERequestContext& ctx) {
system, OpusDecoderState{std::move(decoder), sample_rate, channel_count});
}
void HwOpus::OpenHardwareOpusDecoderForMultiStreamEx(HLERequestContext& ctx) {
OpusMultiStreamParametersEx params;
std::memcpy(&params, 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<int>(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<IHardwareOpusDecoderManager>(
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"},
@@ -406,8 +362,7 @@ HwOpus::HwOpus(Core::System& system_) : ServiceFramework{system_, "hwopus"} {
{3, nullptr, "GetWorkBufferSizeForMultiStream"},
{4, &HwOpus::OpenHardwareOpusDecoderEx, "OpenHardwareOpusDecoderEx"},
{5, &HwOpus::GetWorkBufferSizeEx, "GetWorkBufferSizeEx"},
{6, &HwOpus::OpenHardwareOpusDecoderForMultiStreamEx,
"OpenHardwareOpusDecoderForMultiStreamEx"},
{6, nullptr, "OpenHardwareOpusDecoderForMultiStreamEx"},
{7, &HwOpus::GetWorkBufferSizeForMultiStreamEx, "GetWorkBufferSizeForMultiStreamEx"},
{8, nullptr, "GetWorkBufferSizeExEx"},
{9, nullptr, "GetWorkBufferSizeForMultiStreamExEx"},

View File

@@ -18,10 +18,8 @@ struct OpusMultiStreamParametersEx {
u32 number_stereo_streams;
u32 use_large_frame_size;
u32 padding;
std::array<u8, 0x100> channel_mappings;
std::array<u32, 64> channel_mappings;
};
static_assert(sizeof(OpusMultiStreamParametersEx) == 0x118,
"OpusMultiStreamParametersEx has incorrect size");
class HwOpus final : public ServiceFramework<HwOpus> {
public:
@@ -31,7 +29,6 @@ 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);

View File

@@ -4,7 +4,6 @@
#include <utility>
#include "common/assert.h"
#include "common/fs/fs.h"
#include "common/fs/path_util.h"
#include "common/settings.h"
#include "core/core.h"
@@ -155,18 +154,10 @@ Result VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path_,
std::string src_path(Common::FS::SanitizePath(src_path_));
std::string dest_path(Common::FS::SanitizePath(dest_path_));
auto src = backing->GetFileRelative(src_path);
auto dst = backing->GetFileRelative(dest_path);
if (Common::FS::GetParentPath(src_path) == Common::FS::GetParentPath(dest_path)) {
// Use more-optimized vfs implementation rename.
if (src == nullptr) {
if (src == nullptr)
return FileSys::ERROR_PATH_NOT_FOUND;
}
if (dst && Common::FS::Exists(dst->GetFullPath())) {
LOG_ERROR(Service_FS, "File at new_path={} already exists", dst->GetFullPath());
return FileSys::ERROR_PATH_ALREADY_EXISTS;
}
if (!src->Rename(Common::FS::GetFilename(dest_path))) {
// TODO(DarkLordZach): Find a better error code for this
return ResultUnknown;

View File

@@ -331,7 +331,7 @@ Controller_Gesture::GestureProperties Controller_Gesture::GetGestureProperties()
};
// Hack: There is no touch in docked but games still allow it
if (Settings::IsDockedMode()) {
if (Settings::values.use_docked_mode.GetValue()) {
gesture.points[id] = {
.x = static_cast<s32>(active_x * Layout::ScreenDocked::Width),
.y = static_cast<s32>(active_y * Layout::ScreenDocked::Height),

View File

@@ -1518,7 +1518,7 @@ bool Controller_NPad::IsControllerSupported(Core::HID::NpadStyleIndex controller
return false;
}
// Handheld shouldn't be supported in docked mode
if (Settings::IsDockedMode()) {
if (Settings::values.use_docked_mode.GetValue()) {
return false;
}

View File

@@ -204,11 +204,9 @@ void nvhost_as_gpu::FreeMappingLocked(u64 offset) {
if (!mapping->fixed) {
auto& allocator{mapping->big_page ? *vm.big_page_allocator : *vm.small_page_allocator};
u32 page_size_bits{mapping->big_page ? vm.big_page_size_bits : VM::PAGE_SIZE_BITS};
u32 page_size{mapping->big_page ? vm.big_page_size : VM::YUZU_PAGESIZE};
u64 aligned_size{Common::AlignUp(mapping->size, page_size)};
allocator.Free(static_cast<u32>(mapping->offset >> page_size_bits),
static_cast<u32>(aligned_size >> page_size_bits));
static_cast<u32>(mapping->size >> page_size_bits));
}
// Sparse mappings shouldn't be fully unmapped, just returned to their sparse state

View File

@@ -19,12 +19,6 @@ 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[] = {
@@ -107,9 +101,8 @@ void NSD::ResolveEx(HLERequestContext& ctx) {
}
void NSD::GetEnvironmentIdentifier(HLERequestContext& ctx) {
constexpr EnvironmentIdentifier lp1 = {
.identifier = {'l', 'p', '1', '\0', '\0', '\0', '\0', '\0'}};
ctx.WriteBuffer(lp1);
const std::string environment_identifier = "lp1";
ctx.WriteBuffer(environment_identifier);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);

View File

@@ -150,12 +150,6 @@ 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())};
@@ -267,12 +261,6 @@ 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

@@ -139,6 +139,7 @@ private:
bool do_not_close_socket = false;
bool get_server_cert_chain = false;
std::shared_ptr<Network::SocketBase> socket;
bool did_set_host_name = false;
bool did_handshake = false;
Result SetSocketDescriptorImpl(s32* out_fd, s32 fd) {
@@ -173,7 +174,11 @@ private:
Result SetHostNameImpl(const std::string& hostname) {
LOG_DEBUG(Service_SSL, "called. hostname={}", hostname);
ASSERT(!did_handshake);
return backend->SetHostName(hostname);
Result res = backend->SetHostName(hostname);
if (res == ResultSuccess) {
did_set_host_name = true;
}
return res;
}
Result SetVerifyOptionImpl(u32 option) {
@@ -203,6 +208,9 @@ private:
Result DoHandshakeImpl() {
ASSERT_OR_EXECUTE(!did_handshake && socket, { return ResultNoSocket; });
ASSERT_OR_EXECUTE_MSG(
did_set_host_name, { return ResultInternalError; },
"Expected SetHostName before DoHandshake");
Result res = backend->DoHandshake();
did_handshake = res.IsSuccess();
return res;

View File

@@ -167,8 +167,9 @@ public:
}
~SSLConnectionBackendOpenSSL() {
// this is null-tolerant:
// these are null-tolerant:
SSL_free(ssl);
BIO_free(bio);
}
static void KeyLogCallback(const SSL* ssl, const char* line) {

View File

@@ -31,9 +31,9 @@ CredHandle cred_handle;
static void OneTimeInit() {
schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
schannel_cred.dwFlags =
SCH_USE_STRONG_CRYPTO | // don't allow insecure protocols
SCH_CRED_NO_SERVERNAME_CHECK | // don't validate server names
SCH_CRED_NO_DEFAULT_CREDS; // don't automatically present a client certificate
SCH_USE_STRONG_CRYPTO | // don't allow insecure protocols
SCH_CRED_AUTO_CRED_VALIDATION | // validate certs
SCH_CRED_NO_DEFAULT_CREDS; // don't automatically present a client certificate
// ^ I'm assuming that nobody would want to connect Yuzu to a
// service that requires some OS-provided corporate client
// certificate, and presenting one to some arbitrary server
@@ -227,15 +227,16 @@ public:
ciphertext_read_buf.size());
}
char* hostname_ptr = hostname ? const_cast<char*>(hostname->c_str()) : nullptr;
const SECURITY_STATUS ret = InitializeSecurityContextA(
&cred_handle, initial_call_done ? &ctxt : nullptr, hostname_ptr, req,
0, // Reserved1
0, // TargetDataRep not used with Schannel
initial_call_done ? &input_desc : nullptr,
0, // Reserved2
initial_call_done ? nullptr : &ctxt, &output_desc, &attr,
nullptr); // ptsExpiry
const SECURITY_STATUS ret =
InitializeSecurityContextA(&cred_handle, initial_call_done ? &ctxt : nullptr,
// Caller ensured we have set a hostname:
const_cast<char*>(hostname.value().c_str()), req,
0, // Reserved1
0, // TargetDataRep not used with Schannel
initial_call_done ? &input_desc : nullptr,
0, // Reserved2
initial_call_done ? nullptr : &ctxt, &output_desc, &attr,
nullptr); // ptsExpiry
if (output_buffers[0].pvBuffer) {
const std::span span(static_cast<u8*>(output_buffers[0].pvBuffer),

View File

@@ -217,7 +217,7 @@ private:
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(ResultSuccess);
if (Settings::IsDockedMode()) {
if (Settings::values.use_docked_mode.GetValue()) {
rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedWidth));
rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedHeight));
} else {

View File

@@ -153,7 +153,7 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect
// Load NSO modules
modules.clear();
const VAddr base_address{GetInteger(process.GetEntryPoint())};
const VAddr base_address{GetInteger(process.GetPageTable().GetCodeRegionStart())};
VAddr next_load_addr{base_address};
const FileSys::PatchManager pm{metadata.GetTitleID(), system.GetFileSystemController(),
system.GetContentProvider()};

View File

@@ -96,7 +96,7 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::KProcess& process,
}
codeset.memory = std::move(program_image);
const VAddr base_address = GetInteger(process.GetEntryPoint());
const VAddr base_address = GetInteger(process.GetPageTable().GetCodeRegionStart());
process.LoadModule(std::move(codeset), base_address);
LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", kip->GetName(), base_address);

View File

@@ -203,7 +203,7 @@ static bool LoadNroImpl(Kernel::KProcess& process, const std::vector<u8>& data)
// Load codeset for current process
codeset.memory = std::move(program_image);
process.LoadModule(std::move(codeset), process.GetEntryPoint());
process.LoadModule(std::move(codeset), process.GetPageTable().GetCodeRegionStart());
return true;
}

View File

@@ -167,7 +167,7 @@ AppLoader_NSO::LoadResult AppLoader_NSO::Load(Kernel::KProcess& process, Core::S
modules.clear();
// Load module
const VAddr base_address = GetInteger(process.GetEntryPoint());
const VAddr base_address = GetInteger(process.GetPageTable().GetCodeRegionStart());
if (!LoadModule(process, system, *file, base_address, true, true)) {
return {ResultStatus::ErrorLoadingNSO, {}};
}

View File

@@ -117,8 +117,8 @@ json GetProcessorStateDataAuto(Core::System& system) {
arm.SaveContext(context);
return GetProcessorStateData(process->Is64BitProcess() ? "AArch64" : "AArch32",
GetInteger(process->GetEntryPoint()), context.sp, context.pc,
context.pstate, context.cpu_registers);
GetInteger(process->GetPageTable().GetCodeRegionStart()),
context.sp, context.pc, context.pstate, context.cpu_registers);
}
json GetBacktraceData(Core::System& system) {

View File

@@ -14,7 +14,6 @@
#include "common/logging/log.h"
#include "common/settings.h"
#include "common/settings_enums.h"
#include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h"
#include "core/loader/loader.h"
@@ -276,7 +275,7 @@ void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader,
static_cast<u32>(Settings::values.shader_backend.GetValue()));
AddField(field_type, "Renderer_UseAsynchronousShaders",
Settings::values.use_asynchronous_shaders.GetValue());
AddField(field_type, "System_UseDockedMode", Settings::IsDockedMode());
AddField(field_type, "System_UseDockedMode", Settings::values.use_docked_mode.GetValue());
}
bool TelemetrySession::SubmitTestcase() {

View File

@@ -835,15 +835,15 @@ public:
return input_engine->SupportsNfc(identifier);
}
Common::Input::NfcState StartNfcPolling() override {
Common::Input::NfcState StartNfcPolling() {
return input_engine->StartNfcPolling(identifier);
}
Common::Input::NfcState StopNfcPolling() override {
Common::Input::NfcState StopNfcPolling() {
return input_engine->StopNfcPolling(identifier);
}
Common::Input::NfcState ReadAmiiboData(std::vector<u8>& out_data) override {
Common::Input::NfcState ReadAmiiboData(std::vector<u8>& out_data) {
return input_engine->ReadAmiiboData(identifier, out_data);
}
@@ -852,11 +852,11 @@ public:
}
Common::Input::NfcState ReadMifareData(const Common::Input::MifareRequest& request,
Common::Input::MifareRequest& out_data) override {
Common::Input::MifareRequest& out_data) {
return input_engine->ReadMifareData(identifier, request, out_data);
}
Common::Input::NfcState WriteMifareData(const Common::Input::MifareRequest& request) override {
Common::Input::NfcState WriteMifareData(const Common::Input::MifareRequest& request) {
return input_engine->WriteMifareData(identifier, request);
}

View File

@@ -289,11 +289,8 @@ std::pair<typename P::Buffer*, u32> BufferCache<P>::ObtainBuffer(GPUVAddr gpu_ad
MarkWrittenBuffer(buffer_id, *cpu_addr, size);
break;
case ObtainBufferOperation::DiscardWrite: {
VAddr cpu_addr_start = Common::AlignDown(*cpu_addr, 64);
VAddr cpu_addr_end = Common::AlignUp(*cpu_addr + size, 64);
IntervalType interval{cpu_addr_start, cpu_addr_end};
IntervalType interval{*cpu_addr, size};
ClearDownload(interval);
common_ranges.subtract(interval);
break;
}
default:
@@ -1162,11 +1159,6 @@ void BufferCache<P>::UpdateDrawIndirect() {
.size = static_cast<u32>(size),
.buffer_id = FindBuffer(*cpu_addr, static_cast<u32>(size)),
};
VAddr cpu_addr_start = Common::AlignDown(*cpu_addr, 64);
VAddr cpu_addr_end = Common::AlignUp(*cpu_addr + size, 64);
IntervalType interval{cpu_addr_start, cpu_addr_end};
ClearDownload(interval);
common_ranges.subtract(interval);
};
if (current_draw_indirect->include_count) {
update(current_draw_indirect->count_start_address, sizeof(u32),

View File

@@ -319,7 +319,6 @@ 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");
@@ -335,7 +334,7 @@ void Codec::Decode() {
UNIMPLEMENTED_MSG("Unexpected video format: {}", final_frame->format);
return;
}
if (!is_interlaced) {
if (!final_frame->interlaced_frame) {
av_frames.push(std::move(final_frame));
} else {
if (!filters_initialized) {

View File

@@ -27,24 +27,14 @@ MICROPROFILE_DEFINE(MacroHLE, "GPU", "Execute macro HLE", MP_RGB(128, 192, 192))
namespace Tegra {
static void Dump(u64 hash, std::span<const u32> code, bool decompiled = false) {
static void Dump(u64 hash, std::span<const u32> code) {
const auto base_dir{Common::FS::GetYuzuPath(Common::FS::YuzuPath::DumpDir)};
const auto macro_dir{base_dir / "macros"};
if (!Common::FS::CreateDir(base_dir) || !Common::FS::CreateDir(macro_dir)) {
LOG_ERROR(Common_Filesystem, "Failed to create macro dump directories");
return;
}
auto name{macro_dir / fmt::format("{:016x}.macro", hash)};
if (decompiled) {
auto new_name{macro_dir / fmt::format("decompiled_{:016x}.macro", hash)};
if (Common::FS::Exists(name)) {
(void)Common::FS::RenameFile(name, new_name);
return;
}
name = new_name;
}
const auto name{macro_dir / fmt::format("{:016x}.macro", hash)};
std::fstream macro_file(name, std::ios::out | std::ios::binary);
if (!macro_file) {
LOG_ERROR(Common_Filesystem, "Unable to open or create file at {}",
@@ -100,6 +90,9 @@ void MacroEngine::Execute(u32 method, const std::vector<u32>& parameters) {
if (!mid_method.has_value()) {
cache_info.lle_program = Compile(macro_code->second);
cache_info.hash = Common::HashValue(macro_code->second);
if (Settings::values.dump_macros) {
Dump(cache_info.hash, macro_code->second);
}
} else {
const auto& macro_cached = uploaded_macro_code[mid_method.value()];
const auto rebased_method = method - mid_method.value();
@@ -109,6 +102,9 @@ void MacroEngine::Execute(u32 method, const std::vector<u32>& parameters) {
code.size() * sizeof(u32));
cache_info.hash = Common::HashValue(code);
cache_info.lle_program = Compile(code);
if (Settings::values.dump_macros) {
Dump(cache_info.hash, code);
}
}
auto hle_program = hle_macros->GetHLEProgram(cache_info.hash);
@@ -121,10 +117,6 @@ void MacroEngine::Execute(u32 method, const std::vector<u32>& parameters) {
MICROPROFILE_SCOPE(MacroHLE);
cache_info.hle_program->Execute(parameters, method);
}
if (Settings::values.dump_macros) {
Dump(cache_info.hash, macro_code->second, cache_info.has_hle_program);
}
}
}

View File

@@ -611,6 +611,9 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
const u32 cfg_offset{static_cast<u32>(env.StartAddress() + sizeof(Shader::ProgramHeader))};
Shader::Maxwell::Flow::CFG cfg(env, pools.flow_block, cfg_offset, index == 0);
if (Settings::values.dump_shaders) {
env.Dump(hash, key.unique_hashes[index]);
}
if (!uses_vertex_a || index != 1) {
// Normal path
programs[index] = TranslateProgram(pools.inst, pools.block, env, cfg, host_info);
@@ -621,10 +624,6 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
programs[index] = MergeDualVertexPrograms(program_va, program_vb, env);
}
if (Settings::values.dump_shaders) {
env.Dump(hash, key.unique_hashes[index]);
}
if (programs[index].info.requires_layer_emulation) {
layer_source_program = &programs[index];
}

View File

@@ -4,7 +4,6 @@
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // for deprecated OpenSSL functions
#endif
#include <jwt/jwt.hpp>
#if defined(__GNUC__) || defined(__clang__)

View File

@@ -5,8 +5,6 @@
#include <thread>
#include "common/assert.h"
#include "common/settings.h"
#include "common/settings_enums.h"
#include "common/string_util.h"
#include "core/core.h"
#include "core/hid/emulated_controller.h"
@@ -228,11 +226,9 @@ int QtControllerSelectorDialog::exec() {
}
void QtControllerSelectorDialog::ApplyConfiguration() {
const bool pre_docked_mode = Settings::IsDockedMode();
const bool docked_mode_selected = ui->radioDocked->isChecked();
Settings::values.use_docked_mode.SetValue(
docked_mode_selected ? Settings::ConsoleMode::Docked : Settings::ConsoleMode::Handheld);
OnDockedModeChanged(pre_docked_mode, docked_mode_selected, system);
const bool pre_docked_mode = Settings::values.use_docked_mode.GetValue();
Settings::values.use_docked_mode.SetValue(ui->radioDocked->isChecked());
OnDockedModeChanged(pre_docked_mode, Settings::values.use_docked_mode.GetValue(), system);
Settings::values.vibration_enabled.SetValue(ui->vibrationGroup->isChecked());
Settings::values.motion_enabled.SetValue(ui->motionGroup->isChecked());
@@ -620,8 +616,8 @@ void QtControllerSelectorDialog::UpdateDockedState(bool is_handheld) {
ui->radioDocked->setEnabled(!is_handheld);
ui->radioUndocked->setEnabled(!is_handheld);
ui->radioDocked->setChecked(Settings::IsDockedMode());
ui->radioUndocked->setChecked(!Settings::IsDockedMode());
ui->radioDocked->setChecked(Settings::values.use_docked_mode.GetValue());
ui->radioUndocked->setChecked(!Settings::values.use_docked_mode.GetValue());
// Also force into undocked mode if the controller type is handheld.
if (is_handheld) {

View File

@@ -928,8 +928,8 @@ void GRenderWindow::CaptureScreenshot(const QString& screenshot_path) {
const Layout::FramebufferLayout layout{[]() {
u32 height = UISettings::values.screenshot_height.GetValue();
if (height == 0) {
height = Settings::IsDockedMode() ? Layout::ScreenDocked::Height
: Layout::ScreenUndocked::Height;
height = Settings::values.use_docked_mode.GetValue() ? Layout::ScreenDocked::Height
: Layout::ScreenUndocked::Height;
height *= Settings::values.resolution_info.up_factor;
}
const u32 width =

View File

@@ -9,7 +9,6 @@
#include "common/fs/path_util.h"
#include "common/settings.h"
#include "common/settings_common.h"
#include "common/settings_enums.h"
#include "core/core.h"
#include "core/hle/service/acc/profile_manager.h"
#include "core/hle/service/hid/controllers/npad.h"
@@ -86,9 +85,9 @@ const std::map<Settings::ScalingFilter, QString> Config::scaling_filter_texts_ma
{Settings::ScalingFilter::Fsr, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "FSR"))},
};
const std::map<Settings::ConsoleMode, QString> Config::use_docked_mode_texts_map = {
{Settings::ConsoleMode::Docked, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Docked"))},
{Settings::ConsoleMode::Handheld, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Handheld"))},
const std::map<bool, QString> Config::use_docked_mode_texts_map = {
{true, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Docked"))},
{false, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Handheld"))},
};
const std::map<Settings::GpuAccuracy, QString> Config::gpu_accuracy_texts_map = {
@@ -377,7 +376,7 @@ void Config::ReadControlValues() {
const auto controller_type = Settings::values.players.GetValue()[0].controller_type;
if (controller_type == Settings::ControllerType::Handheld) {
Settings::values.use_docked_mode.SetGlobal(!IsCustomConfig());
Settings::values.use_docked_mode.SetValue(Settings::ConsoleMode::Handheld);
Settings::values.use_docked_mode.SetValue(false);
}
if (IsCustomConfig()) {

View File

@@ -9,7 +9,6 @@
#include <QMetaType>
#include <QVariant>
#include "common/settings.h"
#include "common/settings_enums.h"
#include "yuzu/uisettings.h"
class QSettings;
@@ -52,7 +51,7 @@ public:
static const std::map<Settings::AntiAliasing, QString> anti_aliasing_texts_map;
static const std::map<Settings::ScalingFilter, QString> scaling_filter_texts_map;
static const std::map<Settings::ConsoleMode, QString> use_docked_mode_texts_map;
static const std::map<bool, QString> use_docked_mode_texts_map;
static const std::map<Settings::GpuAccuracy, QString> gpu_accuracy_texts_map;
static const std::map<Settings::RendererBackend, QString> renderer_backend_texts_map;
static const std::map<Settings::ShaderBackend, QString> shader_backend_texts_map;

View File

@@ -4,8 +4,6 @@
#include <memory>
#include <thread>
#include "common/settings.h"
#include "common/settings_enums.h"
#include "core/core.h"
#include "core/hid/emulated_controller.h"
#include "core/hid/hid_core.h"
@@ -199,11 +197,9 @@ void ConfigureInput::ApplyConfiguration() {
advanced->ApplyConfiguration();
const bool pre_docked_mode = Settings::IsDockedMode();
const bool docked_mode_selected = ui->radioDocked->isChecked();
Settings::values.use_docked_mode.SetValue(
docked_mode_selected ? Settings::ConsoleMode::Docked : Settings::ConsoleMode::Handheld);
OnDockedModeChanged(pre_docked_mode, docked_mode_selected, system);
const bool pre_docked_mode = Settings::values.use_docked_mode.GetValue();
Settings::values.use_docked_mode.SetValue(ui->radioDocked->isChecked());
OnDockedModeChanged(pre_docked_mode, Settings::values.use_docked_mode.GetValue(), system);
Settings::values.vibration_enabled.SetValue(ui->vibrationGroup->isChecked());
Settings::values.motion_enabled.SetValue(ui->motionGroup->isChecked());
@@ -271,8 +267,8 @@ void ConfigureInput::UpdateDockedState(bool is_handheld) {
ui->radioDocked->setEnabled(!is_handheld);
ui->radioUndocked->setEnabled(!is_handheld);
ui->radioDocked->setChecked(Settings::IsDockedMode());
ui->radioUndocked->setChecked(!Settings::IsDockedMode());
ui->radioDocked->setChecked(Settings::values.use_docked_mode.GetValue());
ui->radioUndocked->setChecked(!Settings::values.use_docked_mode.GetValue());
// Also force into undocked mode if the controller type is handheld.
if (is_handheld) {

View File

@@ -18,7 +18,6 @@
#include "common/fs/fs_util.h"
#include "common/settings_enums.h"
#include "common/settings_input.h"
#include "configuration/shared_widget.h"
#include "core/core.h"
#include "core/file_sys/control_metadata.h"
@@ -99,12 +98,6 @@ void ConfigurePerGame::ApplyConfiguration() {
addons_tab->ApplyConfiguration();
input_tab->ApplyConfiguration();
if (Settings::IsDockedMode() && Settings::values.players.GetValue()[0].controller_type ==
Settings::ControllerType::Handheld) {
Settings::values.use_docked_mode.SetValue(Settings::ConsoleMode::Handheld);
Settings::values.use_docked_mode.SetGlobal(true);
}
system.ApplySettings();
Settings::LogSettings();

View File

@@ -106,11 +106,6 @@ void ConfigureSystem::Setup(const ConfigurationShared::Builder& builder) {
push(Settings::values.linkage.by_category[Settings::Category::System]);
for (auto setting : settings) {
if (setting->Id() == Settings::values.use_docked_mode.Id() &&
Settings::IsConfiguringGlobal()) {
continue;
}
ConfigurationShared::Widget* widget = builder.BuildWidget(setting, apply_funcs);
if (widget == nullptr) {

View File

@@ -135,7 +135,7 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
INSERT(Settings, region_index, "Region:", "");
INSERT(Settings, time_zone_index, "Time Zone:", "");
INSERT(Settings, sound_index, "Sound Output Mode:", "");
INSERT(Settings, use_docked_mode, "Console Mode:", "");
INSERT(Settings, use_docked_mode, "", "");
INSERT(Settings, current_user, "", "");
// Controls
@@ -379,9 +379,6 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QWidget* parent) {
PAIR(MemoryLayout, Memory_6Gb, "6GB DRAM (Unsafe)"),
PAIR(MemoryLayout, Memory_8Gb, "8GB DRAM (Unsafe)"),
}});
translations->insert(
{Settings::EnumMetadata<Settings::ConsoleMode>::Index(),
{PAIR(ConsoleMode, Docked, "Docked"), PAIR(ConsoleMode, Handheld, "Handheld")}});
#undef PAIR
#undef CTX_PAIR

View File

@@ -23,7 +23,6 @@
#include <QLineEdit>
#include <QObject>
#include <QPushButton>
#include <QRadioButton>
#include <QRegularExpression>
#include <QSizePolicy>
#include <QSlider>
@@ -172,65 +171,6 @@ QWidget* Widget::CreateCombobox(std::function<std::string()>& serializer,
return combobox;
}
QWidget* Widget::CreateRadioGroup(std::function<std::string()>& serializer,
std::function<void()>& restore_func,
const std::function<void()>& touch) {
const auto type = setting.EnumIndex();
QWidget* group = new QWidget(this);
QHBoxLayout* layout = new QHBoxLayout(group);
layout->setContentsMargins(0, 0, 0, 0);
group->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
const ComboboxTranslations* enumeration{nullptr};
if (combobox_enumerations.contains(type)) {
enumeration = &combobox_enumerations.at(type);
for (const auto& [id, name] : *enumeration) {
QRadioButton* radio_button = new QRadioButton(name, group);
layout->addWidget(radio_button);
radio_buttons.push_back({id, radio_button});
}
} else {
return group;
}
const auto get_selected = [=]() -> u32 {
for (const auto& [id, button] : radio_buttons) {
if (button->isChecked()) {
return id;
}
}
return -1;
};
const auto set_index = [=](u32 value) {
for (const auto& [id, button] : radio_buttons) {
button->setChecked(id == value);
}
};
const u32 setting_value = std::stoi(setting.ToString());
set_index(setting_value);
serializer = [get_selected]() {
int current = get_selected();
return std::to_string(current);
};
restore_func = [this, set_index]() {
const u32 global_value = std::stoi(RelevantDefault(setting));
set_index(global_value);
};
if (!Settings::IsConfiguringGlobal()) {
for (const auto& [id, button] : radio_buttons) {
QObject::connect(button, &QAbstractButton::clicked, [touch]() { touch(); });
}
}
return group;
}
QWidget* Widget::CreateLineEdit(std::function<std::string()>& serializer,
std::function<void()>& restore_func,
const std::function<void()>& touch, bool managed) {
@@ -295,7 +235,6 @@ QWidget* Widget::CreateSlider(bool reversed, float multiplier, const QString& gi
slider->setValue(std::stoi(setting.ToString()));
slider->setInvertedAppearance(reversed);
slider->setInvertedControls(reversed);
serializer = [this]() { return std::to_string(slider->value()); };
restore_func = [this]() { slider->setValue(std::stoi(RelevantDefault(setting))); };
@@ -471,8 +410,6 @@ void Widget::SetupComponent(const QString& label, std::function<void()>& load_fu
return RequestType::Slider;
case Settings::Specialization::Countable:
return RequestType::SpinBox;
case Settings::Specialization::Radio:
return RequestType::RadioGroup;
default:
break;
}
@@ -501,11 +438,7 @@ void Widget::SetupComponent(const QString& label, std::function<void()>& load_fu
if (setting.TypeId() == typeid(bool)) {
data_component = CreateCheckBox(&setting, label, serializer, restore_func, touch);
} else if (setting.IsEnum()) {
if (request == RequestType::RadioGroup) {
data_component = CreateRadioGroup(serializer, restore_func, touch);
} else {
data_component = CreateCombobox(serializer, restore_func, touch);
}
data_component = CreateCombobox(serializer, restore_func, touch);
} else if (type == typeid(u32) || type == typeid(int) || type == typeid(u16) ||
type == typeid(s64) || type == typeid(u8)) {
switch (request) {

View File

@@ -22,7 +22,6 @@ class QObject;
class QPushButton;
class QSlider;
class QSpinBox;
class QRadioButton;
namespace Settings {
class BasicSetting;
@@ -39,7 +38,6 @@ enum class RequestType {
LineEdit,
HexEdit,
DateTimeEdit,
RadioGroup,
MaxEnum,
};
@@ -93,7 +91,6 @@ public:
QSlider* slider{};
QComboBox* combobox{};
QDateTimeEdit* date_time_edit{};
std::vector<std::pair<u32, QRadioButton*>> radio_buttons{};
private:
void SetupComponent(const QString& label, std::function<void()>& load_func, bool managed,
@@ -109,9 +106,6 @@ private:
QWidget* CreateCombobox(std::function<std::string()>& serializer,
std::function<void()>& restore_func,
const std::function<void()>& touch);
QWidget* CreateRadioGroup(std::function<std::string()>& serializer,
std::function<void()>& restore_func,
const std::function<void()>& touch);
QWidget* CreateLineEdit(std::function<std::string()>& serializer,
std::function<void()>& restore_func, const std::function<void()>& touch,
bool managed = true);

View File

@@ -1158,9 +1158,9 @@ void GMainWindow::InitializeWidgets() {
[this](const QPoint& menu_location) {
QMenu context_menu;
for (auto const& pair : Config::use_docked_mode_texts_map) {
context_menu.addAction(pair.second, [this, &pair] {
if (pair.first != Settings::values.use_docked_mode.GetValue()) {
for (auto const& docked_mode_pair : Config::use_docked_mode_texts_map) {
context_menu.addAction(docked_mode_pair.second, [this, docked_mode_pair] {
if (docked_mode_pair.first != Settings::values.use_docked_mode.GetValue()) {
OnToggleDockedMode();
}
});
@@ -1811,43 +1811,6 @@ bool GMainWindow::SelectAndSetCurrentUser(
return true;
}
void GMainWindow::ConfigureFilesystemProvider(const std::string& filepath) {
// Ensure all NCAs are registered before launching the game
const auto file = vfs->OpenFile(filepath, FileSys::Mode::Read);
if (!file) {
return;
}
auto loader = Loader::GetLoader(*system, file);
if (!loader) {
return;
}
const auto file_type = loader->GetFileType();
if (file_type == Loader::FileType::Unknown || file_type == Loader::FileType::Error) {
return;
}
u64 program_id = 0;
const auto res2 = loader->ReadProgramId(program_id);
if (res2 == Loader::ResultStatus::Success && file_type == Loader::FileType::NCA) {
provider->AddEntry(FileSys::TitleType::Application,
FileSys::GetCRTypeFromNCAType(FileSys::NCA{file}.GetType()), program_id,
file);
} else if (res2 == Loader::ResultStatus::Success &&
(file_type == Loader::FileType::XCI || file_type == Loader::FileType::NSP)) {
const auto nsp = file_type == Loader::FileType::NSP
? std::make_shared<FileSys::NSP>(file)
: FileSys::XCI{file}.GetSecurePartitionNSP();
for (const auto& title : nsp->GetNCAs()) {
for (const auto& entry : title.second) {
provider->AddEntry(entry.first.first, entry.first.second, title.first,
entry.second->GetBaseFile());
}
}
}
}
void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t program_index,
StartGameType type) {
LOG_INFO(Frontend, "yuzu starting...");
@@ -1862,7 +1825,6 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
last_filename_booted = filename;
ConfigureFilesystemProvider(filename.toStdString());
const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData());
const auto loader = Loader::GetLoader(*system, v_file, program_id, program_index);
@@ -3674,7 +3636,7 @@ void GMainWindow::OnTasReset() {
}
void GMainWindow::OnToggleDockedMode() {
const bool is_docked = Settings::IsDockedMode();
const bool is_docked = Settings::values.use_docked_mode.GetValue();
auto* player_1 = system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
auto* handheld = system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld);
@@ -3688,8 +3650,7 @@ void GMainWindow::OnToggleDockedMode() {
controller_dialog->refreshConfiguration();
}
Settings::values.use_docked_mode.SetValue(is_docked ? Settings::ConsoleMode::Handheld
: Settings::ConsoleMode::Docked);
Settings::values.use_docked_mode.SetValue(!is_docked);
UpdateDockedButton();
OnDockedModeChanged(is_docked, !is_docked, *system);
}
@@ -4119,10 +4080,10 @@ void GMainWindow::UpdateGPUAccuracyButton() {
}
void GMainWindow::UpdateDockedButton() {
const auto console_mode = Settings::values.use_docked_mode.GetValue();
dock_status_button->setChecked(Settings::IsDockedMode());
const bool is_docked = Settings::values.use_docked_mode.GetValue();
dock_status_button->setChecked(is_docked);
dock_status_button->setText(
Config::use_docked_mode_texts_map.find(console_mode)->second.toUpper());
Config::use_docked_mode_texts_map.find(is_docked)->second.toUpper());
}
void GMainWindow::UpdateAPIText() {

View File

@@ -399,7 +399,6 @@ private:
void OpenPerGameConfiguration(u64 title_id, const std::string& file_name);
bool CheckDarkMode();
bool CheckSystemArchiveDecryption();
void ConfigureFilesystemProvider(const std::string& filepath);
QString GetTasStateDescription() const;
bool CreateShortcut(const std::string& shortcut_path, const std::string& title,