Compare commits

..

1 Commits

Author SHA1 Message Date
Eden CI 526ca072b4 [dist, android] Update translations from Transifex
Signed-off-by: Eden CI <ci@eden-emu.dev>
2026-08-10 12:01:39 -04:00
60 changed files with 14720 additions and 14605 deletions
+540 -531
View File
File diff suppressed because it is too large Load Diff
+538 -529
View File
File diff suppressed because it is too large Load Diff
+534 -525
View File
File diff suppressed because it is too large Load Diff
+534 -525
View File
File diff suppressed because it is too large Load Diff
+539 -532
View File
File diff suppressed because it is too large Load Diff
+534 -525
View File
File diff suppressed because it is too large Load Diff
+539 -532
View File
File diff suppressed because it is too large Load Diff
+534 -525
View File
File diff suppressed because it is too large Load Diff
+537 -529
View File
File diff suppressed because it is too large Load Diff
+534 -525
View File
File diff suppressed because it is too large Load Diff
+533 -525
View File
File diff suppressed because it is too large Load Diff
+539 -532
View File
File diff suppressed because it is too large Load Diff
+536 -527
View File
File diff suppressed because it is too large Load Diff
+559 -552
View File
File diff suppressed because it is too large Load Diff
+541 -532
View File
File diff suppressed because it is too large Load Diff
+535 -528
View File
File diff suppressed because it is too large Load Diff
+539 -532
View File
File diff suppressed because it is too large Load Diff
+539 -532
View File
File diff suppressed because it is too large Load Diff
+534 -525
View File
File diff suppressed because it is too large Load Diff
+539 -532
View File
File diff suppressed because it is too large Load Diff
+539 -532
View File
File diff suppressed because it is too large Load Diff
+539 -531
View File
File diff suppressed because it is too large Load Diff
+539 -532
View File
File diff suppressed because it is too large Load Diff
+534 -525
View File
File diff suppressed because it is too large Load Diff
+534 -525
View File
File diff suppressed because it is too large Load Diff
+539 -534
View File
File diff suppressed because it is too large Load Diff
+535 -527
View File
File diff suppressed because it is too large Load Diff
@@ -30,6 +30,7 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
RENDERER_REACTIVE_FLUSHING("use_reactive_flushing"),
ENABLE_BUFFER_HISTORY("enable_buffer_history"),
USE_OPTIMIZED_VERTEX_BUFFERS("use_optimized_vertex_buffers"),
ENABLE_GPU_BUFFER_READBACK("enable_gpu_buffer_readback"),
SYNC_MEMORY_OPERATIONS("sync_memory_operations"),
BUFFER_REORDER_DISABLE("disable_buffer_reorder"),
RENDERER_DEBUG("debug"),
@@ -808,6 +808,13 @@ abstract class SettingsItem(
descriptionId = R.string.enable_buffer_history_description
)
)
put(
SwitchSetting(
BooleanSetting.ENABLE_GPU_BUFFER_READBACK,
titleId = R.string.enable_gpu_buffer_readback,
descriptionId = R.string.enable_gpu_buffer_readback_description
)
)
put(
SwitchSetting(
BooleanSetting.USE_OPTIMIZED_VERTEX_BUFFERS,
@@ -294,6 +294,7 @@ class SettingsFragmentPresenter(
add(BooleanSetting.RENDERER_FORCE_MAX_CLOCK.key)
add(BooleanSetting.RENDERER_REACTIVE_FLUSHING.key)
add(BooleanSetting.ENABLE_BUFFER_HISTORY.key)
add(BooleanSetting.ENABLE_GPU_BUFFER_READBACK.key)
add(BooleanSetting.USE_OPTIMIZED_VERTEX_BUFFERS.key)
add(HeaderSetting(R.string.hacks))
@@ -444,8 +444,8 @@
<string name="set_custom_rtc">تعيين ساعة مخصصة في الوقت الحقيقي</string>
<!-- CPU -->
<string name="fast_cpu_time">رفع تردد المعالج</string>
<string name="fast_cpu_time_description">يجبر وحدة المعالجة المركزية المحاكاة على العمل بتردد أعلى، مما يقلل بعض محددات معدل الإطارات. استخدم وضع التعزيز (1700 ميجاهرتز) لتشغيلها عند أعلى تردد أصلي لجهاز Switch، أو وضع السرعة (2000 ميجاهرتز) لتشغيلها بتردد مضاعف.</string>
<string name="fast_cpu_time">ترددات وحدة المعالجة المركزية</string>
<string name="fast_cpu_time_description">يرفع هذا الإعداد تردد المعالج المُحاكى، مما يُزيل بعض مُحددات معدل الإطارات. قد تُلاحظ المعالجات الأضعف انخفاضًا في الأداء، وقد تعمل بعض الألعاب بشكل غير صحيح.</string>
<string name="custom_cpu_ticks">تخصيص دورات المعالج</string>
<string name="custom_cpu_ticks_description">قم بتعيين قيمة مخصصة لدورات المعالج. القيم الأعلى يمكن أن تزيد من الأداء، ولكنها قد تتسبب أيضًا في تجميد اللعبة. يوصى باستخدام نطاق 77-21000.</string>
<string name="cpu_ticks">دورات</string>
@@ -499,13 +499,15 @@
<string name="renderer_reactive_flushing_description">يحسن دقة العرض في بعض الألعاب على حساب الأداء.</string>
<string name="enable_buffer_history">تمكين سجل التخزين المؤقت</string>
<string name="enable_buffer_history_description">يُتيح هذا الخيار الوصول إلى حالات التخزين المؤقت السابقة. وقد يُحسّن جودة العرض وثبات الأداء في بعض الألعاب.</string>
<string name="enable_gpu_buffer_readback">تفعيل قراءة مخزن وحدة معالجة الرسومات</string>
<string name="enable_gpu_buffer_readback_description">يحافظ هذا النظام على بيانات المخزن المؤقت المُعدّلة بواسطة وحدة معالجة الرسومات عن طريق قراءتها مرة أخرى قبل التحميل. تتطلب بعض الألعاب ذلك لعرض بعض التأثيرات بشكل صحيح. قد يُسبب ذلك مشاكل إذا لم يتمكن الجهاز من التعامل مع عبء العمل الإضافي.</string>
<string name="use_optimized_vertex_buffers">مخازن الرؤوس المُحسّنة</string>
<string name="use_optimized_vertex_buffers_description">يُتيح ربطًا مُحسَّنًا لمخازن الرؤوس لتحسين الأداء. يتطلب برامج تشغيل Mesa 26.0+ Turnip/ برامج تشغيل QCOM. قد يتعطل على برامج تشغيل Turnip القديمة (25.3 وما دون).</string>
<string name="hacks">اختراقات</string>
<string name="fast_gpu_time">وقت معالجة الرسومات السريع</string>
<string name="fast_gpu_time_description">يُجبر هذا الخيار معظم الألعاب على العمل بأعلى دقة عرض أصلية. استخدم 256 للحصول على أقصى أداء و512 للحصول على أعلى جودة رسومات.</string>
<string name="fast_gpu_time">سرعات معالج الرسوميات</string>
<string name="fast_gpu_time_description">يجعل اللعبة تعتقد أن عمل وحدة معالجة الرسومات ينتهي بشكل أسرع مما هو عليه في الواقع، لذلك تتوقف عن خفض الدقة ومسافة العرض لتتناسب مع سرعات جهاز Switch.</string>
<string name="skip_cpu_inner_invalidation">تخطي إبطال صلاحية وحدة المعالجة المركزية الداخلية</string>
<string name="skip_cpu_inner_invalidation_description">يتخطى بعض عمليات إبطال ذاكرة التخزين المؤقتة من جانب وحدة المعالجة المركزية أثناء تحديثات الذاكرة، مما يقلل من استخدام وحدة المعالجة المركزية ويحسن أداءها. قد يتسبب ذلك في حدوث أعطال أو تعطل في بعض الألعاب.</string>
<string name="fix_bloom_effects">إصلاح تأثيرات التوهج</string>
@@ -552,6 +554,7 @@
<!-- Debug settings strings -->
<string name="cpu">وحدة المعالج المركزية</string>
<string name="clocks">ترددات</string>
<string name="use_auto_stub">استخدم الملحق التلقائي</string>
<string name="use_auto_stub_description">استبدال الخدمات والوظائف المفقودة تلقائيًا. قد يؤدي ذلك إلى تحسين التوافق، ولكنه قد يتسبب في حدوث أعطال ومشكلات في الاستقرار.</string>
@@ -951,13 +954,15 @@
<string name="memory_6gb">6 جيجابايت (غير آمن)</string>
<string name="memory_8gb">8 جيجابايت (غير آمن)</string>
<!--CPU clock speeds-->
<string name="clock_boost">تعزيز (1700MHz)</string>
<string name="clock_fast">سريع (2000MHz)</string>
<!-- CPU clock levels -->
<string name="clock_normal">طبيعي</string>
<string name="clock_boost">طبيعي</string>
<string name="clock_fast">كسر السرعة</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">متوسط (256)</string>
<string name="fast_gpu_high">مرتفع (512)</string>
<!-- GPU clock levels -->
<string name="fast_gpu_normal">طبيعي</string>
<string name="fast_gpu_medium">تعزيز</string>
<string name="fast_gpu_high">كسر السرعة</string>
<!-- GPU swizzle texture size -->
<string name="gpu_texturesizeswizzle_verysmall">صغير جدًا (16 ميغابايت)</string>
@@ -553,10 +553,6 @@
<string name="memory_6gb">6GB (نائاسایش)</string>
<string name="memory_8gb">8GB (نائاسایش)</string>
<!--CPU clock speeds-->
<string name="clock_boost">زۆرکردن (1700MHz)</string>
<string name="clock_fast">خێرا (2000MHz)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">سیلیزی</string>
<string name="temperature_fahrenheit">فارینهایت</string>
@@ -417,9 +417,6 @@
<string name="use_custom_rtc_description">Umožňuje nastavit vlastní hodiny reálného času nezávisle na systému.</string>
<string name="set_custom_rtc">Nastavit vlastní RTC</string>
<!-- CPU -->
<string name="fast_cpu_time">Přetaktování CPU</string>
<string name="fast_cpu_time_description">Vynutí běh CPU na vyšší frekvenci, což může pomoci obejít některé omezovače FPS. Režim Boost (1700 MHz) odpovídá maximální taktu konzole Switch, režim Fast (2000 MHz) je dvojnásobek základního taktu konzole.</string>
<string name="custom_cpu_ticks">Vlastní hodnota CPU cyků</string>
<string name="custom_cpu_ticks_description">Nastavte vlastní hodnotu cyklů CPU. Vyšší hodnoty mohou zvýšit výkon, ale mohou také způsobit zamrznutí hry. Doporučený rozsah hodnot je 7721000.</string>
<string name="cpu_ticks">Cykly</string>
@@ -466,8 +463,6 @@
<string name="enable_buffer_history_description">Umožňuje přístup k předchozím stavům bufferu. Tato volba může u některých her zvýšit kvalitu vykreslování a zlepšit stabilitu výkonu.</string>
<string name="hacks">Hacky</string>
<string name="fast_gpu_time">Rychlé časování GPU</string>
<string name="fast_gpu_time_description">Nutí většinu her běžet v nejvyšším nativním rozlišení. Použijte hodnotu 256 pro maximální výkon a 512 pro nejlepší kvalitu.</string>
<string name="skip_cpu_inner_invalidation">Přeskočit vnitřní invalidaci CPU</string>
<string name="skip_cpu_inner_invalidation_description">Přeskočí určité invalidace mezipaměti procesoru při aktualizacích paměti, čímž snižuje vytížení CPU a zvyšuje jeho výkon. Může způsobit chyby nebo pády některých hrách.</string>
<string name="renderer_asynchronous_shaders">Asynchronní kompilace shaderů</string>
@@ -694,10 +689,6 @@
<string name="memory_6gb">6GB (Nebezpečné)</string>
<string name="memory_8gb">8GB (Nebezpečné)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Boost (1700MHz)</string>
<string name="clock_fast">Rychlé (2000MHz)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsia</string>
<string name="temperature_fahrenheit">Fahrenheita</string>
@@ -429,9 +429,6 @@ Wird der Handheld-Modus verwendet, verringert es die Auflösung und erhöht die
<string name="use_custom_rtc_description">Ermöglicht Ihnen, eine benutzerdefinierte Echtzeituhr unabhängig von Ihrer aktuellen Systemzeit einzustellen.</string>
<string name="set_custom_rtc">Legen Sie eine benutzerdefinierte Echtzeituhr fest</string>
<!-- CPU -->
<string name="fast_cpu_time">CPU-Übertaktung</string>
<string name="fast_cpu_time_description">Zwingt die emulierte CPU, mit höherer Taktrate zu laufen, wodurch bestimmte FPS-Begrenzungen reduziert werden. Verwende Boost (1700MHz), um mit der höchsten nativen Taktrate der Switch zu laufen, oder Fast (2000MHz), um mit der doppelten Taktrate zu laufen.</string>
<string name="custom_cpu_ticks">Benutzerdefinierte CPU-Ticks</string>
<string name="custom_cpu_ticks_description">Legen Sie einen benutzerdefinierten Wert für CPU-Ticks fest. Höhere Werte können die Leistung steigern, aber auch zum Einfrieren des Spiels führen. Ein Bereich von 7721000 wird empfohlen.</string>
<string name="cpu_ticks">Ticks</string>
@@ -476,8 +473,6 @@ Wird der Handheld-Modus verwendet, verringert es die Auflösung und erhöht die
<string name="renderer_reactive_flushing_description">Verbessert die Genauigkeit in einigen Spielen.</string>
<string name="hacks">Hacks</string>
<string name="fast_gpu_time">Schnelle GPU-Zeit</string>
<string name="fast_gpu_time_description">Erzwingt bei den meisten Spielen die höchste native Auflösung. Verwende 256 für maximale Leistung und 512 für maximale Grafikqualität</string>
<string name="skip_cpu_inner_invalidation">CPU-interne Invalidierung überspringen</string>
<string name="skip_cpu_inner_invalidation_description">Überspringt bestimmte Cache-Invalidierungen auf CPU-Seite während Speicherupdates, reduziert die CPU-Auslastung und verbessert die Leistung. Kann in einigen Spielen zu Fehlern oder Abstürzen führen.</string>
<string name="renderer_asynchronous_shaders">Asynchrone Shader</string>
@@ -879,14 +874,6 @@ Wirklich fortfahren?</string>
<string name="memory_6gb">6 GB (Unsicher)</string>
<string name="memory_8gb">8 GB (Unsicher)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Boost (1700MHz)</string>
<string name="clock_fast">Schnell (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Mittel (256)</string>
<string name="fast_gpu_high">Hoch (512)</string>
<!-- GPU swizzle texture size -->
<string name="gpu_texturesizeswizzle_verysmall">Sehr klein (16 MB)</string>
<string name="gpu_texturesizeswizzle_small">Klein (32 MB)</string>
@@ -437,9 +437,6 @@
<string name="use_custom_rtc_description">Le permite tener un reloj personalizado en tiempo real diferente de la hora de su sistema.</string>
<string name="set_custom_rtc">Configurar RTC personalizado</string>
<!-- CPU -->
<string name="fast_cpu_time">Overclock de la CPU</string>
<string name="fast_cpu_time_description">Fuerza a la CPU emulada a ejecutarser a una velocidad de reloj más alta, lo cual reduce ciertos limitadores de fotogramas por segundo. Usa Boost (1700 MHz) para ejecutar a la velocidad de reloj nativa más alta de la Switch, o Fast (2000 MHz) para ejecutar a una velocidad doble de reloj.</string>
<string name="custom_cpu_ticks">Ticks de CPU personalizados</string>
<string name="custom_cpu_ticks_description">Establezca un valor personalizado de los ciclos de la CPU. Los valores más altos pueden aumentar el rendimiento, pero también pueden hacer que el juego se congele. Se recomienda un rango de 7721000.</string>
<string name="cpu_ticks">Ciclos</string>
@@ -491,13 +488,13 @@
<string name="renderer_reactive_flushing_description">Mejora la precisión de renderizado en algunos juegos, pero reduce el rendimiento.</string>
<string name="enable_buffer_history">Activar el historial del búfer</string>
<string name="enable_buffer_history_description">Permite el acceso al estado del búfer anterior. Esta opción puede mejorar la calidad de renderizado y la consistencia en el rendimiento de algunos juegos.</string>
<string name="enable_gpu_buffer_readback">Activar la lectura del buffer de la GPU</string>
<string name="enable_gpu_buffer_readback_description">Conserva los datos del búfer modificados por la GPU leyéndolos antes de subirlos.\nAlgunos juegos requieren esto para renderizar correctamente ciertos efectos.\nPuede causar problemas si el hardware no puede soportar la carga de trabajo adicional.</string>
<string name="use_optimized_vertex_buffers">Búferes de vértices optimizados</string>
<string name="use_optimized_vertex_buffers_description">Permite la optimización del enlace del búfer de vértices para un mejor rendimiento. Requiere controladores Mesa 26.0+ Turnip/ controladores QCOM. Fallará con controladores Turnip más antiguos (versión 25.3 o inferior).</string>
<string name="hacks">Hacks</string>
<string name="fast_gpu_time">Tiempo rápido de la GPU</string>
<string name="fast_gpu_time_description">Fuerza a la mayoría de los juegos a ejecutarse a su resolución nativa más alta. Usa 256 para un máximo rendimiento y 512 para una fidelidad gráfica óptima.</string>
<string name="skip_cpu_inner_invalidation">Omitir invalidación interna de la CPU</string>
<string name="skip_cpu_inner_invalidation_description">Omite ciertas invalidaciones de caché de la CPU durante las actualizaciones de memoria, lo que reduce el uso de la CPU y mejora su rendimiento. Esto puede causar fallos o bloqueos en algunos juegos.</string>
<string name="fix_bloom_effects">Arreglar los efectos de resplandor</string>
@@ -943,13 +940,13 @@
<string name="memory_6gb">6GB (Inseguro)</string>
<string name="memory_8gb">8GB (Inseguro)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Impulsado (1700MHz)</string>
<string name="clock_fast">Rápido (2000MHz)</string>
<!-- CPU clock levels -->
<string name="clock_normal">Normal</string>
<string name="clock_fast">Overclock</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Medio (256)</string>
<string name="fast_gpu_high">Alto (512)</string>
<!-- GPU clock levels -->
<string name="fast_gpu_normal">Normal</string>
<string name="fast_gpu_high">Overclock</string>
<!-- GPU swizzle texture size -->
<string name="gpu_texturesizeswizzle_verysmall">Muy pequeño (16 MB)</string>
@@ -432,9 +432,6 @@
<string name="use_custom_rtc_description">Vous permet de définir une horloge en temps réel personnalisée distincte de l\'heure actuelle de votre système.</string>
<string name="set_custom_rtc">Définir l\'horloge RTC personnalisée</string>
<!-- CPU -->
<string name="fast_cpu_time">Overclock du CPU</string>
<string name="fast_cpu_time_description">Force le CPU émulé à fonctionner à une fréquence plus élevée, en contournant certaines limitations de FPS. Utilisez Boost (1700MHz) pour atteindre la fréquence native maximale de la Nintendo Switch, ou Fast (2000MHz) pour doubler la fréquence. Cest un “hack”. Certains chipsets moins puissants peuvent voir leurs performances réduites et les jeux peuvent se comporter différemment.</string>
<string name="custom_cpu_ticks">Ticks CPU personnalisés</string>
<string name="custom_cpu_ticks_description">Définissez une valeur personnalisée de ticks CPU. Des valeurs plus élevées peuvent améliorer les performances, mais peuvent aussi provoquer des gels du jeu. Une plage de 77 à 21000 est recommandée.</string>
<string name="cpu_ticks">Ticks</string>
@@ -482,7 +479,6 @@
<string name="enable_buffer_history">Activer l\'historique du tampon</string>
<string name="hacks">Contournements</string>
<string name="fast_gpu_time">Temps GPU rapide</string>
<string name="skip_cpu_inner_invalidation">Ignorer l\'invalidation interne du CPU</string>
<string name="skip_cpu_inner_invalidation_description">Ignore certaines invalidations de cache côté CPU lors des mises à jour mémoire, réduisant l\'utilisation du CPU et améliorant ses performances. Peut causer des bugs ou plantages sur certains jeux.</string>
<string name="emulate_bgr565">Emuler BGR565</string>
@@ -892,14 +888,6 @@
<string name="memory_6gb">6 Go (Dangereux)</string>
<string name="memory_8gb">8 Go (Dangereux)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Boost (1700MHz)</string>
<string name="clock_fast">Rapide (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Moyen (256)</string>
<string name="fast_gpu_high">Élevé (512)</string>
<!-- GPU swizzle texture size -->
<string name="gpu_texturesizeswizzle_verysmall">Très petit (16 Mo)</string>
<string name="gpu_texturesizeswizzle_small">Petit (32 Mo)</string>
@@ -592,10 +592,6 @@
<string name="memory_6gb">6GB (לא בטוח)</string>
<string name="memory_8gb">8GB (לא בטוח)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Boost (1700MHz)</string>
<string name="clock_fast">מהיר (2000MHz)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">צלזיוס</string>
<string name="temperature_fahrenheit">פרנהייט</string>
@@ -681,10 +681,6 @@
<string name="memory_6gb">6GB (Nem biztonságos)</string>
<string name="memory_8gb">8GB (Nem biztonságos)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Boost (1700MHz)</string>
<string name="clock_fast">Gyors (2000MHz)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsius</string>
<string name="temperature_fahrenheit">Fahrenheit</string>
@@ -727,10 +727,6 @@
<string name="memory_6gb">6GB (Tidak Aman)</string>
<string name="memory_8gb">8GB (Tidak Aman)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Boost (1700MHz)</string>
<string name="clock_fast">Cepat (2000MHz)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsius</string>
<string name="temperature_fahrenheit">Fahrenheit</string>
@@ -764,10 +764,6 @@
<string name="memory_6gb">6GB (Non sicuro)</string>
<string name="memory_8gb">8GB (Non sicuro)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Boost (1700MHz)</string>
<string name="clock_fast">Veloce (2000MHz)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsius</string>
<string name="temperature_fahrenheit">Fahrenheit</string>
@@ -590,10 +590,6 @@
<string name="memory_6gb">6GB (安全でない)</string>
<string name="memory_8gb">8GB (安全でない)</string>
<!--CPU clock speeds-->
<string name="clock_boost">ブースト (1700MHz)</string>
<string name="clock_fast">高速 (2000MHz)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">摂氏</string>
<string name="temperature_fahrenheit">華氏</string>
@@ -642,10 +642,6 @@
<string name="memory_6gb">6GB (안전하지 않음)</string>
<string name="memory_8gb">8GB (안전하지 않음)</string>
<!--CPU clock speeds-->
<string name="clock_boost">부스트 (1700MHz)</string>
<string name="clock_fast">빠름 (2000MHz)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">섭씨</string>
<string name="temperature_fahrenheit">화씨</string>
@@ -566,10 +566,6 @@
<string name="memory_6gb">6GB (Usikkert)</string>
<string name="memory_8gb">8GB (Usikkert)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Boost (1700MHz)</string>
<string name="clock_fast">Rask (2000MHz)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsius</string>
<string name="temperature_fahrenheit">Fahrenheit</string>
@@ -417,9 +417,6 @@
<string name="use_custom_rtc_description">Ta opcja pozwala na wybranie własnych ustawień czasu używanych w czasie emulacji, innych niż czas systemu Android.</string>
<string name="set_custom_rtc">Ustaw niestandardowy czas RTC</string>
<!-- CPU -->
<string name="fast_cpu_time">Podkręcanie CPU</string>
<string name="fast_cpu_time_description">Wymusza działanie emulowanego CPU z wyższym taktowaniem, ograniczając niektóre blokady FPS. Użyj Boost (1700 MHz), aby działać z najwyższym natywnym taktowaniem Switcha, lub Fast (2000 MHz), aby działać z taktowaniem 2×.</string>
<string name="custom_cpu_ticks">Niestandardowe takty CPU</string>
<string name="custom_cpu_ticks_description">Ustaw niestandardową wartość taktów CPU. Wyższe wartości mogą zwiększyć wydajność, ale mogą też powodować zawieszanie się gry. Zalecany zakres to 7721000.</string>
<string name="cpu_ticks">Takty</string>
@@ -464,8 +461,6 @@
<string name="renderer_reactive_flushing_description">Poprawia jakość renderowania w kilku grach, kosztem wydajności.</string>
<string name="hacks">Hacki</string>
<string name="fast_gpu_time">Szybki czas GPU</string>
<string name="fast_gpu_time_description">Wymusza działanie większości gier w ich najwyższej natywnej rozdzielczości. Ustaw 256 dla maksymalnej wydajności, a 512 dla maksymalnej jakości grafiki.</string>
<string name="skip_cpu_inner_invalidation">Pomiń wewnętrzne unieważnienie CPU</string>
<string name="skip_cpu_inner_invalidation_description">Pomija niektóre unieważnienia pamięci podręcznej po stronie CPU podczas aktualizacji pamięci, zmniejszając użycie CPU i poprawiając jego wydajność. Może powodować błędy lub awarie w niektórych grach.</string>
<string name="renderer_asynchronous_shaders">Wyłącz synchronizację shaderów</string>
@@ -866,14 +861,6 @@
<string name="memory_6gb">6GB (Niebezpieczne)</string>
<string name="memory_8gb">8GB (Niebezpieczne)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Boost (1700MHz)</string>
<string name="clock_fast">Szybkie (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Średnie (256)</string>
<string name="fast_gpu_high">Wysokie (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsjusza</string>
<string name="temperature_fahrenheit">Fahrenheita</string>
@@ -409,8 +409,6 @@
<string name="use_custom_rtc_description">Permite a você configurar um relógio em tempo real separado do relógio do seu dispositivo.</string>
<string name="set_custom_rtc">Definir um relógio em tempo real personalizado</string>
<!-- CPU -->
<string name="fast_cpu_time">Overclock da CPU</string>
<string name="custom_cpu_ticks">Ciclos da CPU Personalizados</string>
<string name="custom_cpu_ticks_description">Defina um valor personalizado de ciclos da CPU. Valores mais altos podem aumentar o desempenho, mas também podem fazer o jogo travar. Recomenda-se usar valores entre 77 e 21000.</string>
<string name="cpu_ticks">Ciclos</string>
@@ -821,10 +819,6 @@
<string name="memory_6gb">6GB (Inseguro)</string>
<string name="memory_8gb">8GB (Inseguro)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Boost (1700MHz)</string>
<string name="clock_fast">Rápido (2000MHz)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsius</string>
<string name="temperature_fahrenheit">Fahrenheit</string>
@@ -693,10 +693,6 @@ uma tentativa de mapeamento automático</string>
<string name="memory_6gb">6GB (Inseguro)</string>
<string name="memory_8gb">8GB (Inseguro)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Boost (1700MHz)</string>
<string name="clock_fast">Rápido (2000MHz)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsius</string>
<string name="temperature_fahrenheit">Fahrenheit</string>
@@ -439,9 +439,6 @@
<string name="use_custom_rtc_description">Позволяет установить пользовательские часы реального времени отдельно от текущего системного времени.</string>
<string name="set_custom_rtc">Установить пользовательский RTC</string>
<!-- CPU -->
<string name="fast_cpu_time">Разгон ЦП</string>
<string name="fast_cpu_time_description">Принудительно повышает тактовую частоту эмулируемого ЦП, снижая влияние некоторых ограничителей FPS. Используйте Разгон (1700 МГц) для работы на максимальной штатной частоте Switch или Быстрая (2000 МГц) для удвоенной частоты.</string>
<string name="custom_cpu_ticks">Пользовательские такты ЦП</string>
<string name="custom_cpu_ticks_description">Установите пользовательское значение тактов ЦП. Более высокие значения могут увеличить производительность, но также могут вызвать зависание игры. Рекомендуется диапазон 77–21000.</string>
<string name="cpu_ticks">Такты</string>
@@ -502,8 +499,6 @@
<string name="hacks">Хаки</string>
<string name="fast_gpu_time">Быстрое время ГПУ</string>
<string name="fast_gpu_time_description">Принудительно запускает большинство игр в их максимальном нативном разрешении. Используйте значение 256 для максимальной производительности и 512 для максимального качества графики.</string>
<string name="skip_cpu_inner_invalidation">Пропустить внутреннюю инвалидацию ЦП</string>
<string name="skip_cpu_inner_invalidation_description">Пропускает некоторые инвалидации кэша на стороне ЦП при обновлениях памяти, уменьшая нагрузку на процессор и повышая производительность. Может вызывать сбои в некоторых играх.</string>
<string name="fix_bloom_effects">Исправить эффекты размытия</string>
@@ -949,14 +944,6 @@
<string name="memory_6gb">6 ГБ (Небезопасно)</string>
<string name="memory_8gb">8 ГБ (Небезопасно)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Разгон (1700MHz)</string>
<string name="clock_fast">Быстрая (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Среднее (256)</string>
<string name="fast_gpu_high">Высокое (512)</string>
<!-- GPU swizzle texture size -->
<string name="gpu_texturesizeswizzle_verysmall">Очень малый (16 МБ)</string>
<string name="gpu_texturesizeswizzle_small">Малый (32 МБ)</string>
@@ -690,10 +690,6 @@
<string name="memory_6gb">6ГБ (несигуран)</string>
<string name="memory_8gb">8ГБ (несигурно)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Боост (1700МХз)</string>
<string name="clock_fast">Брзи (2000МХз)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Целзијус</string>
<string name="temperature_fahrenheit">Фаренхајт</string>
@@ -439,9 +439,6 @@
<string name="use_custom_rtc_description">Дозволяє встановити власний час (Real-time clock, або RTC), відмінний від системного.</string>
<string name="set_custom_rtc">Встановити RTC</string>
<!-- CPU -->
<string name="fast_cpu_time">Розгін ЦП</string>
<string name="fast_cpu_time_description">Примушує емульований ЦП працювати з вищою тактовою частотою, послаблюючи деякі обмежувачі частоти кадрів. Використовуйте «Підвищення (1700 МГц)», щоб емулювати максимальну тактову частоту справжнього Switch, або «Швидко (2000 МГц)», щоб подвоїти частоту.</string>
<string name="custom_cpu_ticks">Користувацькі такти CPU</string>
<string name="custom_cpu_ticks_description">Встановіть користувацьке значення тактів CPU. Вищі значення можуть покращити продуктивність, але також можуть спричинити зависання гри. Рекомендується діапазон 77–21000.</string>
<string name="cpu_ticks">Такти</string>
@@ -497,8 +494,6 @@
<string name="hacks">Обхідні рішення</string>
<string name="fast_gpu_time">Швидкий час роботи ГП</string>
<string name="fast_gpu_time_description">Примушує більшість ігор працювати на їхній максимальній нативній роздільності. Використовуйте 256 для максимальної продуктивності та 512 для найкращої якості.</string>
<string name="skip_cpu_inner_invalidation">Пропустити внутрішнє інвалідування CPU</string>
<string name="skip_cpu_inner_invalidation_description">Пропускає деякі інвалідації кешу на стороні CPU під час оновлення пам\'яті, зменшуючи навантаження на процесор і покращуючи продуктивність. Може спричинити збої в деяких іграх.</string>
<string name="fix_bloom_effects">Виправити ефекти світіння</string>
@@ -938,14 +933,6 @@
<string name="memory_6gb">6 ГБ (Небезпечно)</string>
<string name="memory_8gb">8 ГБ (Небезпечно)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Підвищення (1700 МГц)</string>
<string name="clock_fast">Швидко (2000 МГц)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Середньо (256)</string>
<string name="fast_gpu_high">Високо (512)</string>
<!-- GPU swizzle texture size -->
<string name="gpu_texturesizeswizzle_verysmall">Дуже малий (16 МБ)</string>
<string name="gpu_texturesizeswizzle_small">Малий (32 МБ)</string>
@@ -562,10 +562,6 @@
<string name="memory_6gb">6GB (Không an toàn)</string>
<string name="memory_8gb">8GB (Không an toàn)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Boost (1700MHz)</string>
<string name="clock_fast">Nhanh (2000MHz)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsius</string>
<string name="temperature_fahrenheit">Fahrenheit</string>
@@ -434,8 +434,8 @@
<string name="set_custom_rtc">设置自定义系统时间</string>
<!-- CPU -->
<string name="fast_cpu_time">CPU 超频</string>
<string name="fast_cpu_time_description">强制模拟 CPU 以更高的时钟频率运行,从而消除某些帧率限制。使用“升频”(1700MHz)以在 Switch 的最高原生时钟频率运行,或使用“快速”(2000MHz)以 2 倍时钟频率运行</string>
<string name="fast_cpu_time">CPU 时钟频率</string>
<string name="fast_cpu_time_description">提高模拟 CPU 报告的时钟频率,从而消除部分帧率限制。性能较弱的 CPU 可能会出现可见性能下降,甚至会导致某些游戏运行异常</string>
<string name="custom_cpu_ticks">自定义 CPU 时钟周期</string>
<string name="custom_cpu_ticks_description">设定自定义的 CPU 时钟周期值。更高的值可以提升性能,但也可能导致游戏冻结卡死。建议的赋值范围为77-21000。</string>
<string name="cpu_ticks">时钟周期</string>
@@ -489,13 +489,15 @@
<string name="renderer_reactive_flushing_description">通过牺牲性能来提升某些游戏的渲染精度。</string>
<string name="enable_buffer_history">启用缓冲区历史</string>
<string name="enable_buffer_history_description">启用对先前缓冲区状态的访问。此选项可在某些游戏中提升渲染质量并保持性能的一致性。</string>
<string name="enable_gpu_buffer_readback">启用 GPU 缓冲区回读</string>
<string name="enable_gpu_buffer_readback_description">在上传前回读经由 GPU 修改过的缓冲区数据,以将其保留。一些游戏会用到这项设定以正确渲染某些效果。如果硬件无法处理额外的工作负载,则可能会导致问题。</string>
<string name="use_optimized_vertex_buffers">优化顶点缓冲区</string>
<string name="use_optimized_vertex_buffers_description">启用经过优化的顶点缓冲区绑定以提升性能。需要 Mesa 26.0 及以上版本的 Turnip 或 QCOM 驱动程序。若使用较旧版本的 Turnip 驱动 (25.3 及以下版本) 则会导致崩溃。</string>
<string name="hacks">Hacks</string>
<string name="fast_gpu_time">快速 GPU 时</string>
<string name="fast_gpu_time_description">强制大多数游戏以其最高原生分辨率运行。设置为 256 可获得最佳性能,设置为 512 可获得最佳画面保真度</string>
<string name="fast_gpu_time">GPU 时钟频率</string>
<string name="fast_gpu_time_description">通过让游戏误以为 GPU 的处理速度比实际更快,以避免游戏为了适应 Switch 的时钟频率而降低分辨率和渲染距离</string>
<string name="skip_cpu_inner_invalidation">跳过CPU内部无效化</string>
<string name="skip_cpu_inner_invalidation_description">在更新内存时跳过某些 CPU 端的缓存失效操作,从而降低 CPU 占用率并提升性能。可能会在某些游戏中引发故障点或崩溃。</string>
<string name="fix_bloom_effects">修复 Bloom 效果</string>
@@ -542,6 +544,7 @@
<!-- Debug settings strings -->
<string name="cpu">CPU</string>
<string name="clocks">时钟频率</string>
<string name="use_auto_stub">使用自动占位处理</string>
<string name="use_auto_stub_description">自动为缺失的服务和功能生成占位代码。这可能会提高兼容性,但也可能导致崩溃和稳定性问题</string>
@@ -941,13 +944,15 @@
<string name="memory_6gb">6GB (不安全)</string>
<string name="memory_8gb">8GB (不安全)</string>
<!--CPU clock speeds-->
<string name="clock_boost">加速 (1700MHz)</string>
<string name="clock_fast">快速 (2000MHz)</string>
<!-- CPU clock levels -->
<string name="clock_normal">正常</string>
<string name="clock_boost">升频</string>
<string name="clock_fast">超频</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">中 (256)</string>
<string name="fast_gpu_high">高 (512)</string>
<!-- GPU clock levels -->
<string name="fast_gpu_normal">正常</string>
<string name="fast_gpu_medium">升频</string>
<string name="fast_gpu_high">超频</string>
<!-- GPU swizzle texture size -->
<string name="gpu_texturesizeswizzle_verysmall">极小 (16 MB)</string>
@@ -433,9 +433,6 @@
<string name="use_custom_rtc_description">允許您設定與您的目前系統時間相互獨立的自訂時間</string>
<string name="set_custom_rtc">設定自訂 RTC</string>
<!-- CPU -->
<string name="fast_cpu_time">CPU 超頻</string>
<string name="fast_cpu_time_description">強制模擬 CPU 以更高的時脈運作,減少某些 FPS 限制。使用 加速 (1700MHz) 以 Switch 的最高原生時脈執行,或 高速 (2000MHz) 以雙倍時脈執行</string>
<string name="custom_cpu_ticks">自訂CPU時脈</string>
<string name="custom_cpu_ticks_description">自訂CPU時脈。更高的值可能提高效能,但也可能導致遊戲卡死。建議範圍為77-21000。</string>
<string name="cpu_ticks">時脈</string>
@@ -481,6 +478,8 @@
<string name="use_disk_shader_cache_description">將產生的著色器快取儲存至硬碟以減少中斷</string>
<string name="renderer_force_max_clock">強制使用最大時脈 (僅限Adreno)</string>
<string name="renderer_force_max_clock_description">強制 GPU 以可能的最大時脈執行 (熱溫限制仍會被套用)</string>
<string name="renderer_asynchronous_gpu_emulation">GPU 非同步模擬</string>
<string name="renderer_asynchronous_gpu_emulation_description">此修改可透過使用 GPU 非同步模擬來提升性能,不過可能會導致圖形問題且會提高在進行時序相關操作時崩潰的機率</string>
<string name="renderer_reactive_flushing">使用重新啟用排清</string>
<string name="renderer_reactive_flushing_description">犧牲效能,以改善部分遊戲的轉譯準確度。</string>
<string name="skip_cpu_inner_invalidation">跳過CPU內部失效處理</string>
@@ -850,10 +849,6 @@
<string name="memory_6gb">6GB (不穩定)</string>
<string name="memory_8gb">8GB (不穩定)</string>
<!--CPU clock speeds-->
<string name="clock_boost">加速 (1700MHz)</string>
<string name="clock_fast">快速 (2000MHz)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">攝氏度</string>
<string name="temperature_fahrenheit">華氏度</string>
@@ -505,6 +505,8 @@
<string name="renderer_reactive_flushing_description">Improves rendering accuracy in some games at the cost of performance.</string>
<string name="enable_buffer_history">Enable buffer history</string>
<string name="enable_buffer_history_description">Enables access to previous buffer states. This option may improve rendering quality and performance consistency in some games.</string>
<string name="enable_gpu_buffer_readback">Enable GPU Buffer Readback</string>
<string name="enable_gpu_buffer_readback_description">Preserves GPU-modified buffer data by reading it back before uploads. Some games require this to render certain effects properly. May cause issues if the hardware cannot handle the additional workload.</string>
<string name="use_optimized_vertex_buffers">Optimized Vertex Buffers</string>
<string name="use_optimized_vertex_buffers_description">Enables optimized vertex buffer binding for improved performance. Requires Mesa 26.0+ Turnip drivers/ QCOM drivers. Will crash on older Turnip drivers (25.3 and below).</string>
+7
View File
@@ -576,6 +576,13 @@ struct Values {
false,
#endif
"rescale_hack", Category::RendererHacks};
SwitchableSetting<bool> enable_gpu_buffer_readback{linkage,
false,
"enable_gpu_buffer_readback",
Category::RendererAdvanced,
Specialization::Default,
true,
true};
SwitchableSetting<bool> use_asynchronous_shaders{linkage, false, "use_asynchronous_shaders",
Category::RendererHacks};
@@ -223,6 +223,8 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject* parent) {
tr("Controls the DMA read mode.\nUnsafe is faster, while Safe is more stable and can fix issues in some games.\nDefault follows the GPU Accuracy setting."));
INSERT(Settings, gpu_fence_behavior, tr("GPU Fence Behavior:"),
tr("Controls the GPU fence synchronization behavior.\nImmediate is the fastest option, but can introduce some issues.\nBalanced offers better compatibility and may fix issues in some games.\nAccurate further improves compatibility at the cost of some performance.\nStrict is the slowest option, but can fix issues that require stricter synchronization.\nDefault follows the GPU Accuracy setting."));
INSERT(Settings, enable_gpu_buffer_readback, tr("Enable GPU buffer readback"),
tr("Preserves GPU-modified data by reading it back before uploading.\nSome games require this to render certain effects properly."));
INSERT(Settings, use_asynchronous_shaders, tr("Enable asynchronous shader compilation"),
tr("May reduce shader stutter."));
INSERT(Settings, gpu_clock, tr("GPU Clocks"),
+17 -23
View File
@@ -1448,8 +1448,8 @@ BufferId BufferCache<P>::FindBuffer(DAddr device_addr, u32 size) {
const BufferId buffer_id = page_table[page];
if (buffer_id) {
Buffer& buffer = slot_buffers[buffer_id];
WaitForGpuFenceIfNeeded(buffer);
if (buffer.IsInBounds(device_addr, size)) {
SynchronizeBufferIfNeeded(buffer);
return buffer_id;
}
}
@@ -1457,28 +1457,16 @@ BufferId BufferCache<P>::FindBuffer(DAddr device_addr, u32 size) {
}
template <class P>
void BufferCache<P>::SynchronizeBufferIfNeeded(Buffer& buffer) {
const bool gpu_fence_accurate = Settings::IsGPUFenceBehaviorAccurate();
const bool gpu_fence_strict = Settings::IsGPUFenceBehaviorStrict();
const bool should_sync = gpu_fence_accurate || gpu_fence_strict;
if (should_sync) {
if (gpu_fence_accurate) {
if constexpr (!IS_OPENGL) {
const bool should_wait = buffer.getWriteTick() > runtime.KnownGpuTick() + 3;
if (should_wait) {
runtime.Wait(buffer.getWriteTick());
}
}
} else if (gpu_fence_strict) {
bool should_download = true;
if constexpr (!IS_OPENGL) {
should_download = buffer.getWriteTick() > runtime.KnownGpuTick();
if (should_download) {
runtime.Wait(buffer.getWriteTick());
}
}
if (should_download) {
DownloadBufferMemory(buffer);
void BufferCache<P>::WaitForGpuFenceIfNeeded(Buffer& buffer) {
if constexpr (!IS_OPENGL) {
const bool gpu_fence_accurate = Settings::IsGPUFenceBehaviorAccurate();
const bool gpu_fence_strict = Settings::IsGPUFenceBehaviorStrict();
if (gpu_fence_accurate || gpu_fence_strict) {
const u64 gpu_tick_delay = gpu_fence_strict ? 0 : 3;
const u64 buffer_tick = buffer.getWriteTick();
const u64 gpu_tick = runtime.KnownGpuTick();
if (buffer_tick > gpu_tick + gpu_tick_delay) {
runtime.Wait(buffer_tick);
}
}
}
@@ -1700,6 +1688,9 @@ void BufferCache<P>::ImmediateUploadMemory([[maybe_unused]] Buffer& buffer,
if (immediate_buffer.empty()) {
immediate_buffer = ImmediateBuffer(largest_copy);
}
if (Settings::values.enable_gpu_buffer_readback.GetValue()) {
DownloadBufferMemory(buffer, device_addr, copy.size);
}
device_memory.ReadBlockUnsafe(device_addr, immediate_buffer.data(), copy.size);
upload_span = immediate_buffer.subspan(0, copy.size);
}
@@ -1718,6 +1709,9 @@ void BufferCache<P>::MappedUploadMemory([[maybe_unused]] Buffer& buffer,
for (BufferCopy& copy : copies) {
u8* const src_pointer = staging_pointer.data() + copy.src_offset;
const DAddr device_addr = buffer.CpuAddr() + copy.dst_offset;
if (Settings::values.enable_gpu_buffer_readback.GetValue()) {
DownloadBufferMemory(buffer, device_addr, copy.size);
}
device_memory.ReadBlockUnsafe(device_addr, src_pointer, copy.size);
// Apply the staging offset
copy.src_offset += upload_staging.offset;
@@ -435,8 +435,6 @@ private:
bool SynchronizeBuffer(Buffer& buffer, DAddr device_addr, u32 size);
void SynchronizeBufferIfNeeded(Buffer& buffer);
void UploadMemory(Buffer& buffer, u64 total_size_bytes, u64 largest_copy,
std::span<BufferCopy> copies);
+56 -36
View File
@@ -5,10 +5,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <SDL3/SDL.h>
#include <SDL3/SDL_timer.h>
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include "common/logging.h"
#include "common/scm_rev.h"
@@ -30,17 +26,9 @@ EmuWindow_SDL3::EmuWindow_SDL3(InputCommon::InputSubsystem* input_subsystem_, Co
LOG_CRITICAL(Frontend, "Failed to initialize SDL3: {}, Exiting...", SDL_GetError());
exit(1);
}
titlebar_timer = SDL_AddTimer(2000, [](void *userdata, SDL_TimerID, Uint32) -> Uint32 {
auto* this_ = (EmuWindow_SDL3*)userdata;
auto const results = this_->system.GetAndResetPerfStats();
auto const title = fmt::format("{} | {}-{} | FPS: {:.0f} ({:.0f}%)", Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc, results.average_game_fps, results.emulation_speed * 100.0f);
SDL_SetWindowTitle(this_->render_window, title.c_str());
return 2000;
}, this);
}
EmuWindow_SDL3::~EmuWindow_SDL3() {
SDL_RemoveTimer(titlebar_timer);
system.HIDCore().UnloadInputDevices();
input_subsystem->Shutdown();
SDL_Quit();
@@ -144,7 +132,8 @@ void EmuWindow_SDL3::Fullscreen() {
switch (Settings::values.fullscreen_mode.GetValue()) {
case Settings::FullscreenMode::Exclusive:
// Set window size to render size before entering fullscreen in exclusive mode.
if (const SDL_DisplayMode* display_mode_ptr = SDL_GetDesktopDisplayMode(SDL_GetDisplayForWindow(render_window))) {
if (const SDL_DisplayMode* display_mode_ptr =
SDL_GetDesktopDisplayMode(SDL_GetDisplayForWindow(render_window))) {
display_mode = *display_mode_ptr;
SDL_SetWindowSize(render_window, display_mode.w, display_mode.h);
SDL_SetWindowFullscreenMode(render_window, &display_mode);
@@ -176,60 +165,92 @@ void EmuWindow_SDL3::Fullscreen() {
}
}
void EmuWindow_SDL3::OnEvent(SDL_Event& event) {
// Notice how we skip the "update title" aspect on most events
// this is because some WMs do NOT like changing titles while resizing
// so let's just... not do that, thanks :)
// Afterall we don't really expect the user to pay attention to the titlebar
// while they're moving a lot of shit around...
void EmuWindow_SDL3::WaitEvent() {
// Called on main thread
SDL_Event event;
if (!SDL_WaitEvent(&event)) {
const char* error = SDL_GetError();
if (!error || strcmp(error, "") == 0) {
// https://github.com/libsdl-org/SDL/issues/5780
// Sometimes SDL will return without actually having hit an error condition;
// just ignore it in this case.
return;
}
LOG_CRITICAL(Frontend, "SDL_WaitEvent failed: {}", error);
exit(1);
}
switch (event.type) {
case SDL_EVENT_WINDOW_RESIZED:
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
case SDL_EVENT_WINDOW_MAXIMIZED:
case SDL_EVENT_WINDOW_RESTORED:
return OnResize();
OnResize();
break;
case SDL_EVENT_WINDOW_MINIMIZED:
is_shown = false;
return OnResize();
OnResize();
break;
case SDL_EVENT_WINDOW_EXPOSED:
is_shown = true;
return OnResize();
OnResize();
break;
case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
is_open = false;
return;
break;
case SDL_EVENT_KEY_DOWN:
case SDL_EVENT_KEY_UP:
return OnKeyEvent(int(event.key.scancode), event.key.down ? 1 : 0);
OnKeyEvent(static_cast<int>(event.key.scancode), event.key.down ? 1 : 0);
break;
case SDL_EVENT_MOUSE_MOTION:
// ignore if it came from touch
if (event.button.which != SDL_TOUCH_MOUSEID)
OnMouseMotion(event.motion.x, event.motion.y);
return;
break;
case SDL_EVENT_MOUSE_BUTTON_DOWN:
case SDL_EVENT_MOUSE_BUTTON_UP:
// ignore if it came from touch
if (event.button.which != SDL_TOUCH_MOUSEID)
OnMouseButton(event.button.button, event.button.down ? 1 : 0, s32(event.button.x), s32(event.button.y));
return;
if (event.button.which != SDL_TOUCH_MOUSEID) {
OnMouseButton(event.button.button, event.button.down ? 1 : 0,
static_cast<s32>(event.button.x), static_cast<s32>(event.button.y));
}
break;
case SDL_EVENT_FINGER_DOWN:
return OnFingerDown(event.tfinger.x, event.tfinger.y, std::size_t(event.tfinger.touchID));
OnFingerDown(event.tfinger.x, event.tfinger.y,
static_cast<std::size_t>(event.tfinger.touchID));
break;
case SDL_EVENT_FINGER_MOTION:
return OnFingerMotion(event.tfinger.x, event.tfinger.y, std::size_t(event.tfinger.touchID));
OnFingerMotion(event.tfinger.x, event.tfinger.y,
static_cast<std::size_t>(event.tfinger.touchID));
break;
case SDL_EVENT_FINGER_UP:
return OnFingerUp();
OnFingerUp();
break;
case SDL_EVENT_QUIT:
is_open = false;
return;
break;
default:
break;
}
const u32 current_time = SDL_GetTicks();
if (current_time > last_time + 2000) {
const auto results = system.GetAndResetPerfStats();
const auto title = fmt::format("{} | {}-{} | FPS: {:.0f} ({:.0f}%)",
Common::g_build_fullname,
Common::g_scm_branch,
Common::g_scm_desc,
results.average_game_fps,
results.emulation_speed * 100.0);
SDL_SetWindowTitle(render_window, title.c_str());
last_time = current_time;
}
}
// Credits to Samantas5855 and others for this function.
void EmuWindow_SDL3::SetWindowIcon() {
#if defined(__EMSCRIPTEN__) || defined(__wasi__)
// Icons do not work yet
#else
SDL_IOStream* const yuzu_icon_stream = SDL_IOFromConstMem((void*)yuzu_icon, yuzu_icon_size);
if (yuzu_icon_stream == nullptr) {
LOG_WARNING(Frontend, "Failed to create Eden icon stream.");
@@ -243,7 +264,6 @@ void EmuWindow_SDL3::SetWindowIcon() {
// The icon is attached to the window pointer
SDL_SetWindowIcon(render_window, window_icon);
SDL_DestroySurface(window_icon);
#endif
}
void EmuWindow_SDL3::OnMinimalClientAreaChangeRequest(std::pair<u32, u32> minimal_size) {
+6 -7
View File
@@ -9,12 +9,11 @@
#include <tuple>
#include <utility>
#include <SDL3/SDL.h>
#include <SDL3/SDL_timer.h>
#include "core/frontend/emu_window.h"
#include "core/frontend/graphics_context.h"
struct SDL_Window;
namespace Core {
class System;
}
@@ -36,7 +35,7 @@ public:
bool IsShown() const override;
/// Wait for the next event on the main thread.
void OnEvent(SDL_Event& event);
void WaitEvent();
// Sets the window icon from yuzu.bmp
void SetWindowIcon();
@@ -81,9 +80,6 @@ protected:
/// Called when a configuration change affects the minimal size of the window
void OnMinimalClientAreaChangeRequest(std::pair<u32, u32> minimal_size) override;
/// Periodic changer of titlebar (independent of event loop)
SDL_TimerID titlebar_timer;
/// Is the window still open?
bool is_open = true;
@@ -93,6 +89,9 @@ protected:
/// Internal SDL3 render window
SDL_Window* render_window{};
/// Keeps track of how often to update the title bar during gameplay
u32 last_time = 0;
/// Input subsystem to use with this window.
InputCommon::InputSubsystem* input_subsystem;
+65 -75
View File
@@ -8,12 +8,6 @@
#include <memory>
#include <regex>
#include <string>
#include "common/settings_enums.h"
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#define SDL_MAIN_USE_CALLBACKS 1
#include <SDL3/SDL_main.h>
#include <fmt/ostream.h>
@@ -45,7 +39,9 @@
#ifdef _WIN32
// windows.h needs to be included before shellapi.h
#include <windows.h>
#include <shellapi.h>
#include "common/windows/timer_resolution.h"
#endif
@@ -178,14 +174,8 @@ static void OnStatusMessageReceived(const Network::StatusMessageEntry& msg) {
std::cout << std::endl << "* " << message << std::endl << std::endl;
}
struct SdlState {
Core::System system{};
std::unique_ptr<EmuWindow_SDL3> emu_window;
};
extern "C" SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
SdlState* state = new SdlState();
/// Application entry point
int main(int argc, char** argv) {
#ifdef _WIN32
if (AttachConsole(ATTACH_PARENT_PROCESS)) {
freopen("CONOUT$", "wb", stdout);
@@ -203,7 +193,7 @@ extern "C" SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
auto argv_w = CommandLineToArgvW(GetCommandLineW(), &argc_w);
if (argv_w == nullptr) {
LOG_CRITICAL(Frontend, "Failed to get command line arguments");
return SDL_APP_FAILURE;
return -1;
}
#endif
std::string filepath;
@@ -257,7 +247,7 @@ extern "C" SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
break;
case 'h':
PrintHelp(argv[0]);
return SDL_APP_FAILURE;
return 0;
case 'g':
filepath = std::string(optarg);
break;
@@ -274,7 +264,7 @@ extern "C" SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
if (!std::regex_match(str_arg, re)) {
std::cout << "Wrong format for option --multiplayer\n";
PrintHelp(argv[0]);
return SDL_APP_FAILURE;
return -1;
}
std::smatch match;
@@ -289,11 +279,11 @@ extern "C" SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
std::regex nickname_re("^[a-zA-Z0-9._\\- ]+$");
if (!std::regex_match(nickname, nickname_re)) {
LOG_ERROR(Frontend, "Nickname is not valid. Must be 4 to 20 alphanumeric characters");
return SDL_APP_FAILURE;
return -1;
}
if (address.empty()) {
LOG_ERROR(Frontend, "Address to room must not be empty");
return SDL_APP_FAILURE;
return -1;
}
break;
}
@@ -306,7 +296,7 @@ extern "C" SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
break;
case 'v':
PrintVersion();
return SDL_APP_FAILURE;
return -1;
case 'n':
force_null_render = true;
break;
@@ -368,73 +358,79 @@ extern "C" SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
if (filepath.empty()) {
LOG_CRITICAL(Frontend, "Failed to load ROM: No ROM specified");
return SDL_APP_FAILURE;
return -1;
}
state->system.Initialize();
Core::System system{};
system.Initialize();
InputCommon::InputSubsystem input_subsystem{};
// Apply the command line arguments
state->system.ApplySettings();
system.ApplySettings();
std::unique_ptr<EmuWindow_SDL3> emu_window;
switch (Settings::values.renderer_backend.GetValue()) {
#ifdef HAS_OPENGL
case Settings::RendererBackend::OpenGL_GLSL:
case Settings::RendererBackend::OpenGL_GLASM:
case Settings::RendererBackend::OpenGL_SPIRV:
state->emu_window = std::make_unique<EmuWindow_SDL3_GL>(&input_subsystem, state->system, fullscreen);
emu_window = std::make_unique<EmuWindow_SDL3_GL>(&input_subsystem, system, fullscreen);
break;
#endif
case Settings::RendererBackend::Vulkan:
state->emu_window = std::make_unique<EmuWindow_SDL3_VK>(&input_subsystem, state->system, fullscreen);
emu_window = std::make_unique<EmuWindow_SDL3_VK>(&input_subsystem, system, fullscreen);
break;
case Settings::RendererBackend::Null:
state->emu_window = std::make_unique<EmuWindow_SDL3_Null>(&input_subsystem, state->system, fullscreen);
emu_window = std::make_unique<EmuWindow_SDL3_Null>(&input_subsystem, system, fullscreen);
break;
default:
LOG_CRITICAL(Frontend, "Invalid renderer backend");
return SDL_APP_FAILURE;
return -1;
}
#ifdef _WIN32
Common::Windows::SetCurrentTimerResolutionToMaximum();
state->system.CoreTiming().SetTimerResolutionNs(Common::Windows::GetCurrentTimerResolution());
system.CoreTiming().SetTimerResolutionNs(Common::Windows::GetCurrentTimerResolution());
#endif
state->system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
state->system.SetFilesystem(std::make_shared<FileSys::RealVfsFilesystem>());
state->system.GetFileSystemController().CreateFactories(*state->system.GetFilesystem());
state->system.GetUserChannel().clear();
system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
system.SetFilesystem(std::make_shared<FileSys::RealVfsFilesystem>());
system.GetFileSystemController().CreateFactories(*system.GetFilesystem());
system.GetUserChannel().clear();
Service::AM::FrontendAppletParameters load_parameters{
.applet_id = Service::AM::AppletId::Application,
};
const Core::SystemResultStatus load_result = state->system.Load(*state->emu_window, filepath, load_parameters);
const Core::SystemResultStatus load_result{system.Load(*emu_window, filepath, load_parameters)};
switch (load_result) {
case Core::SystemResultStatus::Success:
break; // Expected case
case Core::SystemResultStatus::ErrorGetLoader:
LOG_CRITICAL(Frontend, "Failed to obtain loader for {}!", filepath);
return SDL_APP_FAILURE;
return -1;
case Core::SystemResultStatus::ErrorLoader:
LOG_CRITICAL(Frontend, "Failed to load ROM!");
return SDL_APP_FAILURE;
return -1;
case Core::SystemResultStatus::ErrorNotInitialized:
LOG_CRITICAL(Frontend, "CPUCore not initialized");
return SDL_APP_FAILURE;
return -1;
case Core::SystemResultStatus::ErrorVideoCore:
LOG_CRITICAL(Frontend, "Failed to initialize VideoCore!");
return SDL_APP_FAILURE;
return -1;
case Core::SystemResultStatus::Success:
break; // Expected case
default:
const u16 loader_id = u16(Core::SystemResultStatus::ErrorLoader);
const u16 error_id = u16(load_result) - loader_id;
LOG_CRITICAL(Frontend,
"While attempting to load the ROM requested, an error occurred. Please "
"refer to the Eden wiki for more information or the Eden discord for "
"additional help.\n\nError Code: {:04X}-{:04X}\nError Description: {}",
loader_id, error_id, Loader::ResultStatus(error_id));
return SDL_APP_FAILURE;
if (static_cast<u32>(load_result) >
static_cast<u32>(Core::SystemResultStatus::ErrorLoader)) {
const u16 loader_id = static_cast<u16>(Core::SystemResultStatus::ErrorLoader);
const u16 error_id = static_cast<u16>(load_result) - loader_id;
LOG_CRITICAL(Frontend,
"While attempting to load the ROM requested, an error occurred. Please "
"refer to the Eden wiki for more information or the Eden discord for "
"additional help.\n\nError Code: {:04X}-{:04X}\nError Description: {}",
loader_id, error_id, static_cast<Loader::ResultStatus>(error_id));
}
break;
}
if (use_multiplayer) {
@@ -443,46 +439,40 @@ extern "C" SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
member->BindOnStatusMessageReceived(OnStatusMessageReceived);
member->BindOnStateChanged(OnStateChanged);
member->BindOnError(OnNetworkError);
LOG_DEBUG(Network, "Start connection to {}:{} with nickname {}", address, port, nickname);
LOG_DEBUG(Network, "Start connection to {}:{} with nickname {}", address, port,
nickname);
member->Join(nickname, address.c_str(), port, 0, Network::NoPreferredIP, password);
} else {
LOG_ERROR(Network, "Could not access RoomMember");
return SDL_APP_FAILURE;
return 0;
}
}
// Core is loaded, start the GPU (makes the GPU contexts current to this thread)
state->system.GPU().Start();
state->system.GetCpuManager().OnGpuReady();
system.GPU().Start();
system.GetCpuManager().OnGpuReady();
if (Settings::values.use_disk_shader_cache.GetValue()) {
state->system.Renderer().ReadRasterizer()->LoadDiskResources(
state->system.GetApplicationProcessProgramID(), std::stop_token{},
system.Renderer().ReadRasterizer()->LoadDiskResources(
system.GetApplicationProcessProgramID(), std::stop_token{},
[](VideoCore::LoadCallbackStage, size_t value, size_t total) {});
}
// don't do anything, SDL3 already exists for us :D
state->system.RegisterExitCallback([] {});
void(state->system.Run());
if (state->system.DebuggerEnabled())
state->system.InitializeDebugger();
return SDL_APP_SUCCESS;
}
extern "C" SDL_AppResult SDL_AppIterate(void *appstate) {
SdlState *state = (SdlState *)appstate;
return state->emu_window->IsOpen() ? SDL_APP_CONTINUE : SDL_APP_SUCCESS;
}
extern "C" SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) {
SdlState *state = (SdlState *)appstate;
state->emu_window->OnEvent(*event);
return SDL_APP_SUCCESS;
}
extern "C" void SDL_AppQuit(void *appstate, SDL_AppResult result) {
SdlState *state = (SdlState *)appstate;
state->system.DetachDebugger();
void(state->system.Pause());
state->system.ShutdownMainProcess();
delete state;
system.RegisterExitCallback([&] {
// Just exit right away.
exit(0);
});
void(system.Run());
if (system.DebuggerEnabled()) {
system.InitializeDebugger();
}
while (emu_window->IsOpen()) {
emu_window->WaitEvent();
}
system.DetachDebugger();
void(system.Pause());
system.ShutdownMainProcess();
return 0;
}
#define VMA_IMPLEMENTATION