fix a large variety of issues
Some checks failed
eden-build / source (pull_request) Has been skipped
eden-build / linux (pull_request) Successful in 1h49m41s
eden-build / android (pull_request) Has been cancelled
eden-build / windows (msvc) (pull_request) Has been cancelled
eden-license / license-header (pull_request_target) Failing after 28s

- GLASM/SPIR-V issues on Android
- potential greenscreen fix (thx suyu)
- save memory layout and add 10gb/12gb options
- potential samsung gaming hub fix
- fix layout of controller UI
- fix default settings to sensible defaults.
- note to TotK that you should increase memory layout
- Error checking for Windows linking
- fix an IDE error

TODO: fix duplicate edens veil code

Signed-off-by: swurl <swurl@swurl.xyz>
This commit is contained in:
swurl 2025-05-10 19:22:26 -04:00
parent 5bbb9eba32
commit 0184a5f772
Signed by: crueter
GPG key ID: A5A7629F109C8FD1
35 changed files with 318 additions and 88 deletions

View file

@ -44,6 +44,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.GAME" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
</activity>

View file

@ -87,6 +87,7 @@
<string name="shader_backend">خلفية Shader</string>
<string name="shader_backend_description">اختيار طريقة ترجمة Shaders</string>
<string name="shader_backend_glsl">GLSL</string>
<string name="shader_backend_glasm">GLASM</string>
<string name="shader_backend_spirv">SPIR-V</string>
<!-- محاكاة NVDEC -->

View file

@ -88,6 +88,7 @@
<string name="shader_backend">شادەر باکند</string>
<string name="shader_backend_description">هەڵبژاردنی ڕێگای پێکهێنانی شادەر</string>
<string name="shader_backend_glsl">GLSL</string>
<string name="shader_backend_glasm">GLASM</string>
<string name="shader_backend_spirv">SPIR-V</string>
<!-- ئیمولەیشنی NVDEC -->

View file

@ -87,6 +87,7 @@
<string name="shader_backend">Backend shaderů</string>
<string name="shader_backend_description">Způsob kompilace shaderů</string>
<string name="shader_backend_glsl">GLSL</string>
<string name="shader_backend_glasm">GLASM</string>
<string name="shader_backend_spirv">SPIR-V</string>
<!-- Emulace NVDEC -->

View file

@ -88,6 +88,7 @@
<string name="shader_backend">Shader-Backend</string>
<string name="shader_backend_description">Methode zur Shader-Kompilierung</string>
<string name="shader_backend_glsl">GLSL</string>
<string name="shader_backend_glasm">GLASM</string>
<string name="shader_backend_spirv">SPIR-V</string>
<!-- NVDEC Emulation -->

View file

@ -88,6 +88,7 @@
<string name="shader_backend">Backend de shaders</string>
<string name="shader_backend_description">Elegir cómo se compilan shaders</string>
<string name="shader_backend_glsl">GLSL</string>
<string name="shader_backend_glasm">GLASM</string>
<string name="shader_backend_spirv">SPIR-V</string>
<!-- Emulación NVDEC -->

View file

@ -88,6 +88,7 @@
<string name="shader_backend">بک‌اند شیدر</string>
<string name="shader_backend_description">انتخاب روش کامپایل و ترجمه شیدرها</string>
<string name="shader_backend_glsl">GLSL</string>
<string name="shader_backend_glasm">GLASM</string>
<string name="shader_backend_spirv">SPIR-V</string>
<!-- شبیه‌سازی NVDEC -->

View file

@ -88,6 +88,7 @@
<string name="shader_backend">Backend shader</string>
<string name="shader_backend_description">Méthode de compilation</string>
<string name="shader_backend_glsl">GLSL</string>
<string name="shader_backend_glasm">GLASM</string>
<string name="shader_backend_spirv">SPIR-V</string>
<!-- NVDEC -->

View file

@ -88,6 +88,7 @@
<string name="shader_backend">מנוע שיידרים</string>
<string name="shader_backend_description">בחר כיצד לקמפל שיידרים</string>
<string name="shader_backend_glsl">GLSL</string>
<string name="shader_backend_glasm">GLASM</string>
<string name="shader_backend_spirv">SPIR-V</string>
<!-- אמולציית NVDEC -->

View file

@ -88,6 +88,7 @@
<string name="shader_backend">Shader backend</string>
<string name="shader_backend_description">Shaderek fordításának módja</string>
<string name="shader_backend_glsl">GLSL</string>
<string name="shader_backend_glasm">GLASM</string>
<string name="shader_backend_spirv">SPIR-V</string>
<!-- NVDEC Emuláció -->

View file

@ -88,6 +88,7 @@
<string name="shader_backend">Backend Shader</string>
<string name="shader_backend_description">Pilih cara shader dikompilasi dan diterjemahkan untuk GPU Anda.</string>
<string name="shader_backend_glsl">GLSL</string>
<string name="shader_backend_glasm">GLASM</string>
<string name="shader_backend_spirv">SPIR-V</string>
<!-- Emulasi NVDEC -->

View file

@ -88,6 +88,7 @@
<string name="shader_backend">Backend shader</string>
<string name="shader_backend_description">Scegli come compilare gli shader</string>
<string name="shader_backend_glsl">GLSL</string>
<string name="shader_backend_glasm">GLASM</string>
<string name="shader_backend_spirv">SPIR-V</string>
<!-- Emulazione NVDEC -->

View file

@ -88,6 +88,7 @@
<string name="shader_backend">シェーダーバックエンド</string>
<string name="shader_backend_description">シェーダーのコンパイル方法</string>
<string name="shader_backend_glsl">GLSL</string>
<string name="shader_backend_glasm">GLASM</string>
<string name="shader_backend_spirv">SPIR-V</string>
<!-- NVDEC Emulation -->

View file

@ -88,6 +88,7 @@
<string name="shader_backend">셰이더 백엔드</string>
<string name="shader_backend_description">셰이더 컴파일 방식 선택</string>
<string name="shader_backend_glsl">GLSL</string>
<string name="shader_backend_glasm">GLASM</string>
<string name="shader_backend_spirv">SPIR-V</string>
<!-- NVDEC Emulation -->

View file

@ -88,6 +88,7 @@
<string name="shader_backend">Shader-backend</string>
<string name="shader_backend_description">Velg hvordan shadere kompileres</string>
<string name="shader_backend_glsl">GLSL</string>
<string name="shader_backend_glasm">GLASM</string>
<string name="shader_backend_spirv">SPIR-V</string>
<!-- NVDEC-emulering -->

View file

@ -88,6 +88,7 @@
<string name="shader_backend">Backend shaderów</string>
<string name="shader_backend_description">Wybierz metodę kompilacji shaderów.</string>
<string name="shader_backend_glsl">GLSL</string>
<string name="shader_backend_glasm">GLASM</string>
<string name="shader_backend_spirv">SPIR-V</string>
<!-- Emulacja NVDEC -->

View file

@ -88,6 +88,7 @@
<string name="shader_backend">Backend de shader</string>
<string name="shader_backend_description">Define como shaders são compilados</string>
<string name="shader_backend_glsl">GLSL</string>
<string name="shader_backend_glasm">GLASM</string>
<string name="shader_backend_spirv">SPIR-V</string>
<!-- Emulação NVDEC -->

View file

@ -88,6 +88,7 @@
<string name="shader_backend">Backend de Shader</string>
<string name="shader_backend_description">Método de compilação de shaders.</string>
<string name="shader_backend_glsl">GLSL</string>
<string name="shader_backend_glasm">GLASM</string>
<string name="shader_backend_spirv">SPIR-V</string>
<!-- Emulação NVDEC -->

View file

@ -88,6 +88,7 @@
<string name="shader_backend">Шейдерный бэкенд</string>
<string name="shader_backend_description">Метод компиляции шейдеров</string>
<string name="shader_backend_glsl">GLSL</string>
<string name="shader_backend_glasm">GLASM</string>
<string name="shader_backend_spirv">SPIR-V</string>
<!-- NVDEC Emulation -->

View file

@ -88,6 +88,7 @@
<string name="shader_backend">Вершинний шейдер</string>
<string name="shader_backend_description">Спосіб компіляції шейдерів</string>
<string name="shader_backend_glsl">GLSL</string>
<string name="shader_backend_glasm">GLASM</string>
<string name="shader_backend_spirv">SPIR-V</string>
<!-- NVDEC Emulation -->

View file

@ -88,6 +88,7 @@
<string name="shader_backend">Backend Shader</string>
<string name="shader_backend_description">Chọn cách biên dịch shader</string>
<string name="shader_backend_glsl">GLSL</string>
<string name="shader_backend_glasm">GLASM</string>
<string name="shader_backend_spirv">SPIR-V</string>
<!-- Giả lập NVDEC -->

View file

@ -88,6 +88,7 @@
<string name="shader_backend">着色器后端</string>
<string name="shader_backend_description">选择着色器编译方式</string>
<string name="shader_backend_glsl">GLSL</string>
<string name="shader_backend_glasm">GLASM</string>
<string name="shader_backend_spirv">SPIR-V</string>
<!-- NVDEC模拟 -->

View file

@ -88,6 +88,7 @@
<string name="shader_backend">著色器後端</string>
<string name="shader_backend_description">選擇著色器的編譯與轉譯方式</string>
<string name="shader_backend_glsl">GLSL</string>
<string name="shader_backend_glasm">GLASM</string>
<string name="shader_backend_spirv">SPIR-V</string>
<!-- NVDEC模擬 -->

View file

@ -88,11 +88,13 @@
<string-array name="rendererShaderNames">
<item>@string/shader_backend_glsl</item>
<item>@string/shader_backend_spirv</item>
<item>@string/shader_backend_glasm</item>
</string-array>
<integer-array name="rendererShaderValues">
<item>0</item>
<item>1</item>
<item>2</item>
</integer-array>
<!-- VRAM USAGE MODE CHOICES -->

View file

@ -65,6 +65,7 @@
<string name="shader_backend">Shader Backend</string>
<string name="shader_backend_description">Choose how shaders are compiled and translated for your GPU.</string>
<string name="shader_backend_glsl">GLSL</string>
<string name="shader_backend_glasm">GLASM</string>
<string name="shader_backend_spirv">SPIR-V</string>
<!-- NVDEC Emulation -->

View file

@ -196,11 +196,11 @@ struct Values {
SwitchableSetting<MemoryLayout, true> memory_layout_mode{linkage,
MemoryLayout::Memory_4Gb,
MemoryLayout::Memory_4Gb,
MemoryLayout::Memory_8Gb,
MemoryLayout::Memory_12Gb,
"memory_layout_mode",
Category::Core,
Specialization::Default,
false};
true};
SwitchableSetting<bool> use_speed_limit{
linkage, true, "use_speed_limit", Category::Core, Specialization::Paired, true, true};
SwitchableSetting<u16, true> speed_limit{linkage,
@ -447,9 +447,9 @@ struct Values {
SwitchableSetting<u8, true> dyna_state{linkage,
#ifdef ANDROID
0,
2,
#else
1,
2,
#endif
0,
2,
@ -457,9 +457,9 @@ struct Values {
Category::RendererExtensions,
Specialization::Scalar};
SwitchableSetting<bool> dyna_state3{linkage, false, "dyna_state3", Category::RendererExtensions};
SwitchableSetting<bool> provoking_vertex{linkage, false, "provoking_vertex", Category::RendererExtensions};
SwitchableSetting<bool> descriptor_indexing{linkage, false, "descriptor_indexing", Category::RendererExtensions};
SwitchableSetting<bool> dyna_state3{linkage, true, "dyna_state3", Category::RendererExtensions};
SwitchableSetting<bool> provoking_vertex{linkage, true, "provoking_vertex", Category::RendererExtensions};
SwitchableSetting<bool> descriptor_indexing{linkage, true, "descriptor_indexing", Category::RendererExtensions};
Setting<bool> renderer_debug{linkage, false, "debug", Category::RendererDebug};
Setting<bool> renderer_shader_feedback{linkage, false, "shader_feedback",

View file

@ -134,7 +134,7 @@ ENUM(CpuBackend, Dynarmic, Nce);
ENUM(CpuAccuracy, Auto, Accurate, Unsafe, Paranoid);
ENUM(MemoryLayout, Memory_4Gb, Memory_6Gb, Memory_8Gb);
ENUM(MemoryLayout, Memory_4Gb, Memory_6Gb, Memory_8Gb, Memory_10Gb, Memory_12Gb);
ENUM(ConfirmStop, Ask_Always, Ask_Based_On_Game, Ask_Never);

View file

@ -48,6 +48,10 @@ u32 GetMemorySizeForInit() {
return Smc::MemorySize_6GB;
case Settings::MemoryLayout::Memory_8Gb:
return Smc::MemorySize_8GB;
case Settings::MemoryLayout::Memory_10Gb:
return Smc::MemorySize_10GB;
case Settings::MemoryLayout::Memory_12Gb:
return Smc::MemorySize_12GB;
}
return Smc::MemorySize_4GB;
}
@ -60,6 +64,10 @@ Smc::MemoryArrangement GetMemoryArrangeForInit() {
return Smc::MemoryArrangement_6GB;
case Settings::MemoryLayout::Memory_8Gb:
return Smc::MemoryArrangement_8GB;
case Settings::MemoryLayout::Memory_10Gb:
return Smc::MemoryArrangement_10GB;
case Settings::MemoryLayout::Memory_12Gb:
return Smc::MemoryArrangement_12GB;
}
return Smc::MemoryArrangement_4GB;
}
@ -79,6 +87,10 @@ size_t KSystemControl::Init::GetIntendedMemorySize() {
return 6_GiB;
case Smc::MemorySize_8GB:
return 8_GiB;
case Smc::MemorySize_10GB:
return 10_GiB;
case Smc::MemorySize_12GB:
return 12_GiB;
}
}
@ -114,6 +126,10 @@ std::size_t KSystemControl::Init::GetApplicationPoolSize() {
case Smc::MemoryArrangement_8GB:
// Real kernel sets this to 4916_MiB. We are not debugging applets.
return 6547_MiB;
case Smc::MemoryArrangement_10GB:
return 8178_MiB;
case Smc::MemoryArrangement_12GB:
return 9809_MiB;
}
}();
@ -139,6 +155,10 @@ size_t KSystemControl::Init::GetAppletPoolSize() {
case Smc::MemoryArrangement_8GB:
//! Real kernel sets this to 2193_MiB. We are not debugging applets.
return 562_MiB;
case Smc::MemoryArrangement_10GB:
return 562_MiB;
case Smc::MemoryArrangement_12GB:
return 562_MiB;
}
}();

View file

@ -9,6 +9,8 @@ enum MemorySize {
MemorySize_4GB = 0,
MemorySize_6GB = 1,
MemorySize_8GB = 2,
MemorySize_10GB = 3,
MemorySize_12GB = 4,
};
enum MemoryArrangement {
@ -18,6 +20,8 @@ enum MemoryArrangement {
MemoryArrangement_6GB = 3,
MemoryArrangement_6GBForAppletDev = 4,
MemoryArrangement_8GB = 5,
MemoryArrangement_10GB = 6,
MemoryArrangement_12GB = 7,
};
} // namespace Kernel::Board::Nintendo::Nx::Smc

View file

@ -1,6 +1,12 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 suyu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: Copyright 2025 eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "common/assert.h"
#include "common/logging/log.h"
#include "common/scope_exit.h"
@ -218,6 +224,166 @@ bool DecoderContext::OpenContext(const Decoder& decoder) {
return true;
}
// Nasty but allows linux builds to pass.
// Requires double checks when FFMPEG gets updated.
// Hopefully a future FFMPEG update will all and expose a solution in the public API.
namespace {
typedef struct FFCodecDefault {
const char* key;
const char* value;
} FFCodecDefault;
typedef struct FFCodec {
/**
* The public AVCodec. See codec.h for it.
*/
AVCodec p;
/**
* Internal codec capabilities FF_CODEC_CAP_*.
*/
unsigned caps_internal : 29;
/**
* This field determines the type of the codec (decoder/encoder)
* and also the exact callback cb implemented by the codec.
* cb_type uses enum FFCodecType values.
*/
unsigned cb_type : 3;
int priv_data_size;
/**
* @name Frame-level threading support functions
* @{
*/
/**
* Copy necessary context variables from a previous thread context to the current one.
* If not defined, the next thread will start automatically; otherwise, the codec
* must call ff_thread_finish_setup().
*
* dst and src will (rarely) point to the same context, in which case memcpy should be skipped.
*/
int (*update_thread_context)(struct AVCodecContext* dst, const struct AVCodecContext* src);
/**
* Copy variables back to the user-facing context
*/
int (*update_thread_context_for_user)(struct AVCodecContext* dst,
const struct AVCodecContext* src);
/** @} */
/**
* Private codec-specific defaults.
*/
const FFCodecDefault* defaults;
/**
* Initialize codec static data, called from av_codec_iterate().
*
* This is not intended for time consuming operations as it is
* run for every codec regardless of that codec being used.
*/
void (*init_static_data)(struct FFCodec* codec);
int (*init)(struct AVCodecContext*);
union {
/**
* Decode to an AVFrame.
* cb is in this state if cb_type is FF_CODEC_CB_TYPE_DECODE.
*
* @param avctx codec context
* @param[out] frame AVFrame for output
* @param[out] got_frame_ptr decoder sets to 0 or 1 to indicate that
* a non-empty frame was returned in frame.
* @param[in] avpkt AVPacket containing the data to be decoded
* @return amount of bytes read from the packet on success,
* negative error code on failure
*/
int (*decode)(struct AVCodecContext* avctx, struct AVFrame* frame, int* got_frame_ptr,
struct AVPacket* avpkt);
/**
* Decode subtitle data to an AVSubtitle.
* cb is in this state if cb_type is FF_CODEC_CB_TYPE_DECODE_SUB.
*
* Apart from that this is like the decode callback.
*/
int (*decode_sub)(struct AVCodecContext* avctx, struct AVSubtitle* sub, int* got_frame_ptr,
const struct AVPacket* avpkt);
/**
* Decode API with decoupled packet/frame dataflow.
* cb is in this state if cb_type is FF_CODEC_CB_TYPE_RECEIVE_FRAME.
*
* This function is called to get one output frame. It should call
* ff_decode_get_packet() to obtain input data.
*/
int (*receive_frame)(struct AVCodecContext* avctx, struct AVFrame* frame);
/**
* Encode data to an AVPacket.
* cb is in this state if cb_type is FF_CODEC_CB_TYPE_ENCODE
*
* @param avctx codec context
* @param[out] avpkt output AVPacket
* @param[in] frame AVFrame containing the input to be encoded
* @param[out] got_packet_ptr encoder sets to 0 or 1 to indicate that a
* non-empty packet was returned in avpkt.
* @return 0 on success, negative error code on failure
*/
int (*encode)(struct AVCodecContext* avctx, struct AVPacket* avpkt,
const struct AVFrame* frame, int* got_packet_ptr);
/**
* Encode subtitles to a raw buffer.
* cb is in this state if cb_type is FF_CODEC_CB_TYPE_ENCODE_SUB.
*/
int (*encode_sub)(struct AVCodecContext* avctx, uint8_t* buf, int buf_size,
const struct AVSubtitle* sub);
/**
* Encode API with decoupled frame/packet dataflow.
* cb is in this state if cb_type is FF_CODEC_CB_TYPE_RECEIVE_PACKET.
*
* This function is called to get one output packet.
* It should call ff_encode_get_frame() to obtain input data.
*/
int (*receive_packet)(struct AVCodecContext* avctx, struct AVPacket* avpkt);
} cb;
int (*close)(struct AVCodecContext*);
/**
* Flush buffers.
* Will be called when seeking
*/
void (*flush)(struct AVCodecContext*);
/**
* Decoding only, a comma-separated list of bitstream filters to apply to
* packets before decoding.
*/
const char* bsfs;
/**
* Array of pointers to hardware configurations supported by the codec,
* or NULL if no hardware supported. The array is terminated by a NULL
* pointer.
*
* The user can only access this field via avcodec_get_hw_config().
*/
const struct AVCodecHWConfigInternal* const* hw_configs;
/**
* List of supported codec_tags, terminated by FF_CODEC_TAGS_END.
*/
const uint32_t* codec_tags;
} FFCodec;
static av_always_inline const FFCodec* ffcodec(const AVCodec* codec) {
return (const FFCodec*)codec;
}
} // namespace
bool DecoderContext::SendPacket(const Packet& packet) {
m_temp_frame = std::make_shared<Frame>();
m_got_frame = 0;
@ -227,8 +393,10 @@ bool DecoderContext::SendPacket(const Packet& packet) {
#ifndef ANDROID
if (!m_codec_context->hw_device_ctx && m_codec_context->codec_id == AV_CODEC_ID_H264) {
m_decode_order = true;
const int ret = avcodec_send_frame(m_codec_context, m_temp_frame->GetFrame());
if (ret < 0) {
auto* codec{ffcodec(m_decoder.GetCodec())};
if (const int ret = codec->cb.decode(m_codec_context, m_temp_frame->GetFrame(),
&m_got_frame, packet.GetPacket());
ret < 0) {
LOG_DEBUG(Service_NVDRV, "avcodec_send_packet error {}", AVError(ret));
return false;
}
@ -250,6 +418,7 @@ std::shared_ptr<Frame> DecoderContext::ReceiveFrame() {
#ifndef ANDROID
if (!m_codec_context->hw_device_ctx && m_codec_context->codec_id == AV_CODEC_ID_H264) {
m_decode_order = true;
auto* codec{ffcodec(m_decoder.GetCodec())};
int ret{0};
if (m_got_frame == 0) {
@ -257,7 +426,7 @@ std::shared_ptr<Frame> DecoderContext::ReceiveFrame() {
auto* pkt = packet.GetPacket();
pkt->data = nullptr;
pkt->size = 0;
ret = avcodec_receive_packet(m_codec_context, pkt);
ret = codec->cb.decode(m_codec_context, m_temp_frame->GetFrame(), &m_got_frame, pkt);
m_codec_context->has_b_frames = 0;
}

View file

@ -176,7 +176,7 @@ public:
PauseCounter();
}
AbandonCurrentQuery();
std::function<void()> func([this, counts = pending_flush_queries.size()] {
std::function<void()> func([this] {
amend_value = 0;
accumulation_value = 0;
});

View file

@ -424,7 +424,7 @@
<item row="6" column="0">
<widget class="QCheckBox" name="use_auto_stub">
<property name="text">
<string>Enable Auto-Stub**</string>
<string>Enable Auto-Stub</string>
</property>
</widget>
</item>

View file

@ -1363,55 +1363,6 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="buttonMiscButtonsPlusGroup">
<property name="title">
<string>Plus</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
<layout class="QVBoxLayout" name="buttonMiscPlusVerticalLayout">
<property name="spacing">
<number>3</number>
</property>
<property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<item>
<widget class="QPushButton" name="buttonPlus">
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>68</width>
<height>16777215</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">min-width: 68px;</string>
</property>
<property name="text">
<string>Plus</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="buttonMiscButtonsMinusGroup">
<property name="title">
@ -1461,6 +1412,55 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="buttonMiscButtonsPlusGroup">
<property name="title">
<string>Plus</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
<layout class="QVBoxLayout" name="buttonMiscPlusVerticalLayout">
<property name="spacing">
<number>3</number>
</property>
<property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<item>
<widget class="QPushButton" name="buttonPlus">
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>68</width>
<height>16777215</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">min-width: 68px;</string>
</property>
<property name="text">
<string>Plus</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="horizontalSpacerShoulderButtonsWidget3" native="true">
<layout class="QHBoxLayout" name="horizontalSpacerShoulderButtonsWidget3Layout">

View file

@ -1806,11 +1806,11 @@ bool GMainWindow::LoadROM(const QString& filename, Service::AM::FrontendAppletPa
msg->setWindowTitle(tr("Game Updates Warning"));
msg->setIcon(QMessageBox::Warning);
msg->setText(tr("The game you are trying to launch is known to have performance or booting "
"issues when updates are applied. It's recommended to disable any updates "
"to this game before attempting to launch, or switch to an earlier update. "
"If you don't have any updates installed or enabled, you can safely ignore "
"this message.<br><br>Press \"OK\" to continue launching, or \"Cancel\" to "
"cancel the launch."));
"issues when updates are applied. Please try increasing the memory layout to "
"6GB or 8GB if any issues occur.<br><br>Press \"OK\" to continue launching, or "
"\"Cancel\" to cancel the launch."));
// TODO: TMP: Recommends more memory for TotK.
msg->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);

View file

@ -21,8 +21,7 @@
namespace fs = std::filesystem;
UserDataMigrator::UserDataMigrator(
QMainWindow *main_window)
UserDataMigrator::UserDataMigrator(QMainWindow *main_window)
{
// NOTE: Logging is not initialized yet, do not produce logs here.
@ -34,8 +33,7 @@ UserDataMigrator::UserDataMigrator(
}
}
void UserDataMigrator::ShowMigrationPrompt(
QMainWindow *main_window)
void UserDataMigrator::ShowMigrationPrompt(QMainWindow *main_window)
{
namespace fs = std::filesystem;
@ -96,9 +94,9 @@ void UserDataMigrator::ShowMigrationPrompt(
#define EMU_MAP(name) \
const bool name##_found = fs::is_directory( \
Common::FS::GetLegacyPath(Common::FS::LegacyPath::name##Dir)); \
legacyMap[main_window->tr(#name)] = LegacyEmu::name; \
found[main_window->tr(#name)] = name##_found; \
if (name##_found) \
legacyMap[main_window->tr(#name)] = LegacyEmu::name; \
found[main_window->tr(#name)] = name##_found; \
if (name##_found) \
any_found = true;
EMU_MAP(Citron)
@ -159,8 +157,7 @@ void UserDataMigrator::ShowMigrationPrompt(
return;
}
void UserDataMigrator::ShowMigrationCancelledMessage(
QMainWindow *main_window)
void UserDataMigrator::ShowMigrationCancelledMessage(QMainWindow *main_window)
{
QMessageBox::information(main_window,
main_window->tr("Migration"),
@ -173,11 +170,10 @@ void UserDataMigrator::ShowMigrationCancelledMessage(
QMessageBox::Ok);
}
void UserDataMigrator::MigrateUserData(
QMainWindow *main_window,
const LegacyEmu selected_legacy_emu,
const bool clear_shader_cache,
const MigrationStrategy strategy)
void UserDataMigrator::MigrateUserData(QMainWindow *main_window,
const LegacyEmu selected_legacy_emu,
const bool clear_shader_cache,
const MigrationStrategy strategy)
{
namespace fs = std::filesystem;
const auto copy_options = fs::copy_options::update_existing | fs::copy_options::recursive;
@ -189,12 +185,12 @@ void UserDataMigrator::MigrateUserData(
std::string legacy_cache_dir;
#define LEGACY_EMU(emu) \
case LegacyEmu::emu: \
case LegacyEmu::emu: \
legacy_user_dir = Common::FS::GetLegacyPath(Common::FS::LegacyPath::emu##Dir).string(); \
legacy_config_dir = Common::FS::GetLegacyPath(Common::FS::LegacyPath::emu##ConfigDir) \
.string(); \
.string(); \
legacy_cache_dir = Common::FS::GetLegacyPath(Common::FS::LegacyPath::emu##CacheDir) \
.string(); \
.string(); \
break;
switch (selected_legacy_emu) {
@ -216,7 +212,20 @@ case LegacyEmu::emu: \
switch (strategy) {
case MigrationStrategy::Link:
// Create symlinks/directory junctions if requested
fs::create_directory_symlink(legacy_user_dir, eden_dir);
// Windows 11 has random permission nonsense to deal with.
try {
fs::create_directory_symlink(legacy_user_dir, eden_dir);
} catch (const fs::filesystem_error &e) {
QMessageBox::critical(
main_window,
main_window->tr("Link Failed"),
main_window
->tr("Linking the old directory failed. You may need to re-run with "
"administrative privileges on Windows.\nOS gave error: %1")
.arg(main_window->tr(e.what())));
std::exit(127);
}
// Windows doesn't need any more links, because cache and config
// are already children of the root directory
@ -260,9 +269,11 @@ case LegacyEmu::emu: \
}
success_text.append(
main_window->tr("\n\nIf you wish to clean up the files which were left in the old "
"data location, you can do so by deleting the following directory:\n"
"%1").arg(QString::fromStdString(legacy_user_dir)));
main_window
->tr("\n\nIf you wish to clean up the files which were left in the old "
"data location, you can do so by deleting the following directory:\n"
"%1")
.arg(QString::fromStdString(legacy_user_dir)));
break;
}