mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-07-05 06:21:19 +12:00
Merge branch 'main' into linux-overlay
This commit is contained in:
commit
6aa7a0c7b2
35 changed files with 144 additions and 81 deletions
14
.github/workflows/build.yml
vendored
14
.github/workflows/build.yml
vendored
|
@ -86,7 +86,11 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
cd build
|
cd build
|
||||||
ninja
|
ninja
|
||||||
|
|
||||||
|
- name: Prepare artifact
|
||||||
|
if: ${{ inputs.deploymode == 'release' }}
|
||||||
|
run: mv bin/Cemu_release bin/Cemu
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
if: ${{ inputs.deploymode == 'release' }}
|
if: ${{ inputs.deploymode == 'release' }}
|
||||||
|
@ -188,10 +192,14 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
cd build
|
cd build
|
||||||
cmake --build . --config ${{ env.BUILD_MODE }} -j 2
|
cmake --build . --config ${{ env.BUILD_MODE }} -j 2
|
||||||
|
|
||||||
|
- name: Prepare artifact
|
||||||
|
if: ${{ inputs.deploymode == 'release' }}
|
||||||
|
run: Rename-Item bin/Cemu_release.exe Cemu.exe
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
if: ${{ inputs.deploymode == 'release' }}
|
if: ${{ inputs.deploymode == 'release' }}
|
||||||
with:
|
with:
|
||||||
name: cemu-bin-windows-x64
|
name: cemu-bin-windows-x64
|
||||||
path: ./bin/Cemu.exe
|
path: ./bin/Cemu.exe
|
||||||
|
|
2
.github/workflows/deploy_experimental.yml
vendored
2
.github/workflows/deploy_experimental.yml
vendored
|
@ -63,4 +63,4 @@ jobs:
|
||||||
wget -O ghr.tar.gz https://github.com/tcnksm/ghr/releases/download/v0.15.0/ghr_v0.15.0_linux_amd64.tar.gz
|
wget -O ghr.tar.gz https://github.com/tcnksm/ghr/releases/download/v0.15.0/ghr_v0.15.0_linux_amd64.tar.gz
|
||||||
tar xvzf ghr.tar.gz; rm ghr.tar.gz
|
tar xvzf ghr.tar.gz; rm ghr.tar.gz
|
||||||
echo "[INFO] Release tag: v${{ env.CEMU_VERSION }}"
|
echo "[INFO] Release tag: v${{ env.CEMU_VERSION }}"
|
||||||
ghr_v0.15.0_linux_amd64/ghr -prerelease -t ${{ secrets.GITHUB_TOKEN }} -n "Cemu ${{ env.CEMU_VERSION }} (Experimental)" -b "" "v${{ env.CEMU_VERSION }}" ./upload
|
ghr_v0.15.0_linux_amd64/ghr -prerelease -t ${{ secrets.GITHUB_TOKEN }} -n "Cemu ${{ env.CEMU_VERSION }} (Experimental)" -b "Cemu experimental release - [changelog](https://cemu.info/changelog.html)" "v${{ env.CEMU_VERSION }}" ./upload
|
||||||
|
|
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -18,14 +18,15 @@
|
||||||
build/
|
build/
|
||||||
out/
|
out/
|
||||||
.cache/
|
.cache/
|
||||||
bin/Cemu
|
bin/Cemu_*
|
||||||
|
bin/Cemu_*.exe
|
||||||
|
|
||||||
# Cemu bin files
|
# Cemu bin files
|
||||||
bin/otp.bin
|
bin/otp.bin
|
||||||
bin/seeprom.bin
|
bin/seeprom.bin
|
||||||
bin/log.txt
|
bin/log.txt
|
||||||
bin/Cemu.pdb
|
bin/Cemu_*.pdb
|
||||||
bin/Cemu.ilk
|
bin/Cemu_*.ilk
|
||||||
bin/Cemu.exe.backup
|
bin/Cemu.exe.backup
|
||||||
bin/mlc01/*
|
bin/mlc01/*
|
||||||
bin/settings.xml
|
bin/settings.xml
|
||||||
|
|
|
@ -39,7 +39,15 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT CemuBin)
|
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT CemuBin)
|
||||||
# floating point model: precise, fiber safe optimizations
|
# floating point model: precise, fiber safe optimizations
|
||||||
add_compile_options(/EHsc /fp:precise /GT)
|
add_compile_options(/EHsc /fp:precise)
|
||||||
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
|
# Speeds up static linking (especially helpful in incremental compilation)
|
||||||
|
if((CMAKE_LINKER MATCHES ".*lld-link.*") AND (CMAKE_AR MATCHES ".*llvm-lib.*"))
|
||||||
|
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY STATIC_LIBRARY_OPTIONS /llvmlibthin)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
add_compile_options(/GT)
|
||||||
|
endif()
|
||||||
if (PUBLIC_RELEASE)
|
if (PUBLIC_RELEASE)
|
||||||
message(STATUS "Using additional optimization flags for MSVC")
|
message(STATUS "Using additional optimization flags for MSVC")
|
||||||
add_compile_options(/Oi /Ot) # enable intrinsic functions, favor speed
|
add_compile_options(/Oi /Ot) # enable intrinsic functions, favor speed
|
||||||
|
@ -81,7 +89,7 @@ find_package(ZLIB REQUIRED)
|
||||||
find_package(zstd MODULE REQUIRED) # MODULE so that zstd::zstd is available
|
find_package(zstd MODULE REQUIRED) # MODULE so that zstd::zstd is available
|
||||||
find_package(OpenSSL COMPONENTS Crypto SSL REQUIRED)
|
find_package(OpenSSL COMPONENTS Crypto SSL REQUIRED)
|
||||||
find_package(glm REQUIRED)
|
find_package(glm REQUIRED)
|
||||||
find_package(fmt 7.0.0 REQUIRED)
|
find_package(fmt 9.1.0 REQUIRED)
|
||||||
find_package(PNG REQUIRED)
|
find_package(PNG REQUIRED)
|
||||||
|
|
||||||
# glslang versions older than 11.11.0 define targets without a namespace
|
# glslang versions older than 11.11.0 define targets without a namespace
|
||||||
|
|
7
dependencies/DirectX_2010/XAudio2.h
vendored
7
dependencies/DirectX_2010/XAudio2.h
vendored
|
@ -48,10 +48,15 @@
|
||||||
//DEFINE_CLSID(XAudio2_Debug, 47199894, 7cc2, 444d, 98, 73, ce, d2, 56, 2c, c6, 0e);
|
//DEFINE_CLSID(XAudio2_Debug, 47199894, 7cc2, 444d, 98, 73, ce, d2, 56, 2c, c6, 0e);
|
||||||
|
|
||||||
// XAudio 2.7 (June 2010 SDK)
|
// XAudio 2.7 (June 2010 SDK)
|
||||||
|
#ifdef __clang__
|
||||||
|
class __declspec(uuid("5a508685-a254-4fba-9b82-9a24b00306af")) XAudio2; extern "C" const GUID CLSID_XAudio2;
|
||||||
|
class __declspec(uuid("db05ea35-0329-4d4b-a53a-6dead03d3852")) XAudio2_Debug; extern "C" const GUID CLSID_XAudio2_Debug;
|
||||||
|
struct __declspec(uuid("8bcf1f58-9fe7-4583-8ac6-e2adc465c8bb")) IXAudio2; extern "C" const GUID IID_IXAudio2;
|
||||||
|
#else
|
||||||
DEFINE_CLSID(XAudio2, 5a508685, a254, 4fba, 9b, 82, 9a, 24, b0, 03, 06, af);
|
DEFINE_CLSID(XAudio2, 5a508685, a254, 4fba, 9b, 82, 9a, 24, b0, 03, 06, af);
|
||||||
DEFINE_CLSID(XAudio2_Debug, db05ea35, 0329, 4d4b, a5, 3a, 6d, ea, d0, 3d, 38, 52);
|
DEFINE_CLSID(XAudio2_Debug, db05ea35, 0329, 4d4b, a5, 3a, 6d, ea, d0, 3d, 38, 52);
|
||||||
DEFINE_IID(IXAudio2, 8bcf1f58, 9fe7, 4583, 8a, c6, e2, ad, c4, 65, c8, bb);
|
DEFINE_IID(IXAudio2, 8bcf1f58, 9fe7, 4583, 8a, c6, e2, ad, c4, 65, c8, bb);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Ignore the rest of this header if only the GUID definitions were requested
|
// Ignore the rest of this header if only the GUID definitions were requested
|
||||||
#ifndef GUID_DEFS_ONLY
|
#ifndef GUID_DEFS_ONLY
|
||||||
|
|
|
@ -40,6 +40,9 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <immintrin.h>
|
#include <immintrin.h>
|
||||||
|
#if defined(_MSC_VER) && defined(__clang__)
|
||||||
|
#include <intrin.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define CLIP_U8(x) CLIP3(0, UINT8_MAX, (x))
|
#define CLIP_U8(x) CLIP3(0, UINT8_MAX, (x))
|
||||||
#define CLIP_S8(x) CLIP3(INT8_MIN, INT8_MAX, (x))
|
#define CLIP_S8(x) CLIP3(INT8_MIN, INT8_MAX, (x))
|
||||||
|
@ -71,7 +74,7 @@
|
||||||
|
|
||||||
/* For MSVC x64 */
|
/* For MSVC x64 */
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#if defined(_MSC_VER) && !defined(__clang__)
|
||||||
|
|
||||||
static inline int __builtin_clz(unsigned x)
|
static inline int __builtin_clz(unsigned x)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
vcpkg_from_github(
|
vcpkg_from_github(
|
||||||
OUT_SOURCE_PATH SOURCE_PATH
|
OUT_SOURCE_PATH SOURCE_PATH
|
||||||
REPO fmtlib/fmt
|
REPO fmtlib/fmt
|
||||||
REF 7bdf0628b1276379886c7f6dda2cef2b3b374f0b # v7.1.3
|
REF a33701196adfad74917046096bf5a2aa0ab0bb50 # v9.1.0
|
||||||
SHA512 52ea8f9d2c0cb52ec3a740e38fcdfd6a0318566e3b599bd2e8d557168642d005c0a59bc213cff2641a88fed3bb771d15f46c39035ccd64809569af982aba47aa
|
SHA512 0faf00e99b332fcb3d9fc50cc9649ddc004ca9035f3652c1a001facee725dab09f67b65a9dfcce0aedb47e76c74c45a9262a1fd6e250a9e9a27c7d021c8ee6b8
|
||||||
HEAD_REF master
|
HEAD_REF master
|
||||||
PATCHES fix-warning4189.patch
|
# PATCHES fix-warning4189.patch
|
||||||
)
|
)
|
||||||
|
|
||||||
vcpkg_cmake_configure(
|
vcpkg_cmake_configure(
|
||||||
|
|
6
dist/linux/info.cemu.Cemu.metainfo.xml
vendored
6
dist/linux/info.cemu.Cemu.metainfo.xml
vendored
|
@ -21,7 +21,7 @@
|
||||||
<p xml:lang="de">Cemu ist ein Nintendo Wii U-Emulator, der die meisten Wii U Spiele und Homebrew in einem spielbaren Zustand ausführen kann. Erstellt von Exzap, und geschrieben in C/C++.</p>
|
<p xml:lang="de">Cemu ist ein Nintendo Wii U-Emulator, der die meisten Wii U Spiele und Homebrew in einem spielbaren Zustand ausführen kann. Erstellt von Exzap, und geschrieben in C/C++.</p>
|
||||||
<p xml:lang="fr">Cemu est un émulateur de Wii U capable de lancer la plupart des jeux Wii U et des homebrews en interface de jeu. Crée par Exzap, et développé en C/C++.</p>
|
<p xml:lang="fr">Cemu est un émulateur de Wii U capable de lancer la plupart des jeux Wii U et des homebrews en interface de jeu. Crée par Exzap, et développé en C/C++.</p>
|
||||||
<p xml:lang="nl">Cemu is een Nintendo Wii U emulator die de meeste Wii U en Homebrew games speelbaar kan runnen. Het project is begonnen door Exzap, en het is geschreven in C/C++.</p>
|
<p xml:lang="nl">Cemu is een Nintendo Wii U emulator die de meeste Wii U en Homebrew games speelbaar kan runnen. Het project is begonnen door Exzap, en het is geschreven in C/C++.</p>
|
||||||
<p xml:lang="el">Το Cemu είναι ένας προσομοιωτής της κονσόλας Nintendo Wii U που υποστηρίζει τεπίσημα παιχνίδια, καθώς και μη επίσημα προγράμματα ("homebrew"), για το Wii U. Δημιουργήθηκε από τον Exzap σε C/C++.</p>
|
<p xml:lang="el">Το Cemu είναι ένας προσομοιωτής της κονσόλας Nintendo Wii U που προσομοιώνει επίσημα παιχνίδια, καθώς και μη επίσημα προγράμματα ("homebrew") του Wii U. Δημιουργήθηκε από τον Exzap σε C/C++.</p>
|
||||||
<p xml:lang="es">Cemu es un emulador de Nintendo Wii U que es capaz de ejecutar la mayoría de los juegos de Wii U y homebrew en un estado jugable. Creado por Exzap, y escrito en C y C++.</p>
|
<p xml:lang="es">Cemu es un emulador de Nintendo Wii U que es capaz de ejecutar la mayoría de los juegos de Wii U y homebrew en un estado jugable. Creado por Exzap, y escrito en C y C++.</p>
|
||||||
<p xml:lang="pt_BR">Cemu é um emulador de Nintendo Wii U que é capaz de executar a maioría dos jogos de Wii U e homebrew em um estado jogavel. Criado por Exzap, e escrito em C e C++.</p>
|
<p xml:lang="pt_BR">Cemu é um emulador de Nintendo Wii U que é capaz de executar a maioría dos jogos de Wii U e homebrew em um estado jogavel. Criado por Exzap, e escrito em C e C++.</p>
|
||||||
<p xml:lang="it">Cemu è un emulatore del Nintendo Wii U in grado di eseguire in stato giocabile la maggior parte dei giochi e homebrew per Wii U. Creato da Exzap, e scritto in C/C++.</p>
|
<p xml:lang="it">Cemu è un emulatore del Nintendo Wii U in grado di eseguire in stato giocabile la maggior parte dei giochi e homebrew per Wii U. Creato da Exzap, e scritto in C/C++.</p>
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
<p xml:lang="de">Dieser Emulator zielt darauf ab, sowohl hohe Genauigkeit als auch Leistung zu bieten, und wird aktiv mit neuen Funktionen und Korrekturen weiterentwickelt, um Kompatibilität, Komfort und Benutzerfreundlichkeit zu verbessern.</p>
|
<p xml:lang="de">Dieser Emulator zielt darauf ab, sowohl hohe Genauigkeit als auch Leistung zu bieten, und wird aktiv mit neuen Funktionen und Korrekturen weiterentwickelt, um Kompatibilität, Komfort und Benutzerfreundlichkeit zu verbessern.</p>
|
||||||
<p xml:lang="fr">Cet émulateur vise à la fois à offrir fidélité et performance, il est activement développé avec des nouvelles fonctionnalités et des correctifs pour augmenter la compatibilité, la commodité et la facilité d'utilisation.</p>
|
<p xml:lang="fr">Cet émulateur vise à la fois à offrir fidélité et performance, il est activement développé avec des nouvelles fonctionnalités et des correctifs pour augmenter la compatibilité, la commodité et la facilité d'utilisation.</p>
|
||||||
<p xml:lang="nl">De emulator richt zich op integriteit en snelheid, en wordt continu verder ontwikkeld met nieuwe toevoegingen en fixes om de compatibiliteit, het gemak en de gebruiksvriendelijkheid te verbeteren.</p>
|
<p xml:lang="nl">De emulator richt zich op integriteit en snelheid, en wordt continu verder ontwikkeld met nieuwe toevoegingen en fixes om de compatibiliteit, het gemak en de gebruiksvriendelijkheid te verbeteren.</p>
|
||||||
<p xml:lang="el">Ο προσομοιωτής αυτός στοχεύει τόσο στην ακρίβεια, όσο και στην ταχύτητα. Βελτιώνεται συνεχώς με νέες δυνατότητες και διορθώσεις που τον καθιστούν πιο βολικό, εύκολο στην χρήση και συμβατό με περισσότερα παιχνίδια.</p>
|
<p xml:lang="el">Ο προσομοιωτής αυτός στοχεύει τόσο στην ακρίβεια, όσο και στην ταχύτητα, και βελτιώνεται συνεχώς με νέες δυνατότητες και διορθώσεις που τον καθιστούν πιο βολικό, εύκολο στην χρήση και συμβατό με περισσότερα παιχνίδια.</p>
|
||||||
<p xml:lang="es">Este emulador tiene como objetivo proporcionar tanto alta precisión como rendimiento y se desarrolla activamente con nuevas características y correcciones para mejorar la compatibilidad, la comodidad y la usabilidad.</p>
|
<p xml:lang="es">Este emulador tiene como objetivo proporcionar tanto alta precisión como rendimiento y se desarrolla activamente con nuevas características y correcciones para mejorar la compatibilidad, la comodidad y la usabilidad.</p>
|
||||||
<p xml:lang="pt_BR">Esse emulador visa proporcionar tanto alta precisão como rendimento e está sendo ativamente desenvolvido com novas características e correções para melhorar a compatibilidade, a comodidade e a usabilidade.</p>
|
<p xml:lang="pt_BR">Esse emulador visa proporcionar tanto alta precisão como rendimento e está sendo ativamente desenvolvido com novas características e correções para melhorar a compatibilidade, a comodidade e a usabilidade.</p>
|
||||||
<p xml:lang="it">Questo emulatore ha l'obiettivo di fornire sia alta precisione che alte prestazioni, ed è in continuo sviluppo con nuove funzionalità e correzioni per aumentare la compatibilità, la comodità e l'usabilità.</p>
|
<p xml:lang="it">Questo emulatore ha l'obiettivo di fornire sia alta precisione che alte prestazioni, ed è in continuo sviluppo con nuove funzionalità e correzioni per aumentare la compatibilità, la comodità e l'usabilità.</p>
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
<p xml:lang="de">Er wird seit Anfang 2015 entwickelt.</p>
|
<p xml:lang="de">Er wird seit Anfang 2015 entwickelt.</p>
|
||||||
<p xml:lang="fr">Il a été écrit à partir de zéro et son développement a débuté vers le début de l'année 2015.</p>
|
<p xml:lang="fr">Il a été écrit à partir de zéro et son développement a débuté vers le début de l'année 2015.</p>
|
||||||
<p xml:lang="nl">Ontwikkeling van Cemu begon ongeveer in het voorjaar van 2015.</p>
|
<p xml:lang="nl">Ontwikkeling van Cemu begon ongeveer in het voorjaar van 2015.</p>
|
||||||
<p xml:lang="el">Το Cemu βρίσκεται υπό ανάπτυξη από το 2015.</p>
|
<p xml:lang="el">Αρχισε απο το τίποτα και βρίσκεται υπό ανάπτυξη από το 2015.</p>
|
||||||
<p xml:lang="es">Fue escrito desde cero y el desarrollo del proyecto comenzó aproximadamente a principios de 2015.</p>
|
<p xml:lang="es">Fue escrito desde cero y el desarrollo del proyecto comenzó aproximadamente a principios de 2015.</p>
|
||||||
<p xml:lang="pt_BR">Foi escrito do zero e o desenvolvimento do projeto começou aproximadamente a princípio de 2015.</p>
|
<p xml:lang="pt_BR">Foi escrito do zero e o desenvolvimento do projeto começou aproximadamente a princípio de 2015.</p>
|
||||||
<p xml:lang="it">È stato scritto da zero e lo sviluppo del progetto è cominciato intorno all'inizio del 2015.</p>
|
<p xml:lang="it">È stato scritto da zero e lo sviluppo del progetto è cominciato intorno all'inizio del 2015.</p>
|
||||||
|
|
|
@ -75,8 +75,10 @@ endif()
|
||||||
set_property(TARGET CemuBin PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
set_property(TARGET CemuBin PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||||
|
|
||||||
set_target_properties(CemuBin PROPERTIES
|
set_target_properties(CemuBin PROPERTIES
|
||||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../bin/"
|
# multi-configuration generators will add a config subdirectory to RUNTIME_OUTPUT_DIRECTORY if no generator expression is used
|
||||||
OUTPUT_NAME "Cemu"
|
# to get the same behavior everywhere we append an empty generator expression
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../bin/$<1:>"
|
||||||
|
OUTPUT_NAME "Cemu_$<LOWER_CASE:$<CONFIG>>"
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(CemuBin PRIVATE
|
target_link_libraries(CemuBin PRIVATE
|
||||||
|
|
|
@ -110,7 +110,8 @@ uint64 PPCTimer_tscToMicroseconds(uint64 us)
|
||||||
|
|
||||||
|
|
||||||
uint64 remainder;
|
uint64 remainder;
|
||||||
#if _MSC_VER < 1923
|
|
||||||
|
#if _MSC_VER < 1923 || defined(__clang__)
|
||||||
const uint64 microseconds = udiv128(r.low, r.high, _rdtscFrequency, &remainder);
|
const uint64 microseconds = udiv128(r.low, r.high, _rdtscFrequency, &remainder);
|
||||||
#else
|
#else
|
||||||
const uint64 microseconds = _udiv128(r.high, r.low, _rdtscFrequency, &remainder);
|
const uint64 microseconds = _udiv128(r.high, r.low, _rdtscFrequency, &remainder);
|
||||||
|
@ -158,7 +159,7 @@ uint64 PPCTimer_getFromRDTSC()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint64 remainder;
|
uint64 remainder;
|
||||||
#if _MSC_VER < 1923
|
#if _MSC_VER < 1923 || defined(__clang__)
|
||||||
uint64 elapsedTick = udiv128(_rdtscAcc.low, _rdtscAcc.high, _rdtscFrequency, &remainder);
|
uint64 elapsedTick = udiv128(_rdtscAcc.low, _rdtscAcc.high, _rdtscFrequency, &remainder);
|
||||||
#else
|
#else
|
||||||
uint64 elapsedTick = _udiv128(_rdtscAcc.high, _rdtscAcc.low, _rdtscFrequency, &remainder);
|
uint64 elapsedTick = _udiv128(_rdtscAcc.high, _rdtscAcc.low, _rdtscFrequency, &remainder);
|
||||||
|
|
|
@ -441,9 +441,9 @@ void LatteShaderCache_ShowProgress(const std::function <bool(void)>& loadUpdateF
|
||||||
ImGui::ProgressBar(percentLoaded, { -1, 0 }, "");
|
ImGui::ProgressBar(percentLoaded, { -1, 0 }, "");
|
||||||
|
|
||||||
if (isPipelines)
|
if (isPipelines)
|
||||||
text = fmt::format("{}/{} ({}%%)", g_shaderCacheLoaderState.loadedPipelines, g_shaderCacheLoaderState.pipelineFileCount, (int)(percentLoaded * 100));
|
text = fmt::format("{}/{} ({}%)", g_shaderCacheLoaderState.loadedPipelines, g_shaderCacheLoaderState.pipelineFileCount, (int)(percentLoaded * 100));
|
||||||
else
|
else
|
||||||
text = fmt::format("{}/{} ({}%%)", g_shaderCacheLoaderState.loadedShaderFiles, g_shaderCacheLoaderState.shaderFileCount, (int)(percentLoaded * 100));
|
text = fmt::format("{}/{} ({}%)", g_shaderCacheLoaderState.loadedShaderFiles, g_shaderCacheLoaderState.shaderFileCount, (int)(percentLoaded * 100));
|
||||||
ImGui::SetCursorPosX(width - ImGui::CalcTextSize(text.c_str()).x / 2);
|
ImGui::SetCursorPosX(width - ImGui::CalcTextSize(text.c_str()).x / 2);
|
||||||
ImGui::Text("%s", text.c_str());
|
ImGui::Text("%s", text.c_str());
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
|
|
@ -145,7 +145,7 @@ uint32 LatteTexture_CalculateTextureDataHash(LatteTexture* hostTexture)
|
||||||
bool isCompressedFormat = hostTexture->IsCompressedFormat();
|
bool isCompressedFormat = hostTexture->IsCompressedFormat();
|
||||||
if( isCompressedFormat == false )
|
if( isCompressedFormat == false )
|
||||||
{
|
{
|
||||||
#if BOOST_OS_WINDOWS
|
#if BOOST_OS_WINDOWS
|
||||||
if (_cpuExtension_AVX2)
|
if (_cpuExtension_AVX2)
|
||||||
{
|
{
|
||||||
__m256i h256 = { 0 };
|
__m256i h256 = { 0 };
|
||||||
|
@ -157,7 +157,11 @@ uint32 LatteTexture_CalculateTextureDataHash(LatteTexture* hostTexture)
|
||||||
readPtr += (288 / 32);
|
readPtr += (288 / 32);
|
||||||
h256 = _mm256_xor_si256(h256, temp);
|
h256 = _mm256_xor_si256(h256, temp);
|
||||||
}
|
}
|
||||||
|
#ifdef __clang__
|
||||||
|
hashVal = h256[0] + h256[1] + h256[2] + h256[3] + h256[4] + h256[5] + h256[6] + h256[7];
|
||||||
|
#else
|
||||||
hashVal = h256.m256i_u32[0] + h256.m256i_u32[1] + h256.m256i_u32[2] + h256.m256i_u32[3] + h256.m256i_u32[4] + h256.m256i_u32[5] + h256.m256i_u32[6] + h256.m256i_u32[7];
|
hashVal = h256.m256i_u32[0] + h256.m256i_u32[1] + h256.m256i_u32[2] + h256.m256i_u32[3] + h256.m256i_u32[4] + h256.m256i_u32[5] + h256.m256i_u32[6] + h256.m256i_u32[7];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if( false ) {}
|
if( false ) {}
|
||||||
|
|
|
@ -378,7 +378,7 @@ void OpenGLRenderer::GetVendorInformation()
|
||||||
forceLog_printf("GL_RENDERER: %s", glRendererString ? glRendererString : "unknown");
|
forceLog_printf("GL_RENDERER: %s", glRendererString ? glRendererString : "unknown");
|
||||||
forceLog_printf("GL_VERSION: %s", glVersionString ? glVersionString : "unknown");
|
forceLog_printf("GL_VERSION: %s", glVersionString ? glVersionString : "unknown");
|
||||||
|
|
||||||
if(boost::icontains(glVersionString, "Mesa") || IsRunningInWine())
|
if(boost::icontains(glVersionString, "Mesa"))
|
||||||
{
|
{
|
||||||
m_vendor = GfxVendor::Mesa;
|
m_vendor = GfxVendor::Mesa;
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -197,7 +197,9 @@ void VulkanRenderer::DetermineVendor()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsRunningInWine())
|
VkDriverId driverId = driverProperties.driverID;
|
||||||
|
|
||||||
|
if(driverId == VK_DRIVER_ID_MESA_RADV || driverId == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA)
|
||||||
m_vendor = GfxVendor::Mesa;
|
m_vendor = GfxVendor::Mesa;
|
||||||
|
|
||||||
forceLog_printf("Using GPU: %s", properties.properties.deviceName);
|
forceLog_printf("Using GPU: %s", properties.properties.deviceName);
|
||||||
|
@ -216,7 +218,7 @@ void VulkanRenderer::DetermineVendor()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
forceLog_printf("Driver version (as stored in device info): %08X", properties.properties.driverVersion);
|
forceLog_printf("Driver version (as stored in device info): %08X", properties.properties.driverVersion);
|
||||||
|
|
||||||
if(m_vendor == GfxVendor::Nvidia)
|
if(m_vendor == GfxVendor::Nvidia)
|
||||||
{
|
{
|
||||||
// if the driver does not support the extension,
|
// if the driver does not support the extension,
|
||||||
|
|
|
@ -219,7 +219,7 @@ namespace iosu
|
||||||
template <typename ... TArgs>
|
template <typename ... TArgs>
|
||||||
curl_slist* append_header_param(struct curl_slist* list, const char* format, TArgs&& ... args)
|
curl_slist* append_header_param(struct curl_slist* list, const char* format, TArgs&& ... args)
|
||||||
{
|
{
|
||||||
return curl_slist_append(list, fmt::format(format, std::forward<TArgs>(args)...).c_str());
|
return curl_slist_append(list, fmt::format(fmt::runtime(format), std::forward<TArgs>(args)...).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool starts_with(const char* str, const char* pre)
|
bool starts_with(const char* str, const char* pre)
|
||||||
|
|
|
@ -84,7 +84,7 @@ namespace iosu
|
||||||
name = tmp;
|
name = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_friend_notifications.emplace_back(fmt::format(msg_format, name), 5000);
|
g_friend_notifications.emplace_back(fmt::format(fmt::runtime(msg_format), name), 5000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace H264
|
||||||
// both of these are required to allow Breath of the Wild to playback the higher res (1080p) videos from the Switch version
|
// both of these are required to allow Breath of the Wild to playback the higher res (1080p) videos from the Switch version
|
||||||
// we mirror these hacks for user convenience and because there are no downsides
|
// we mirror these hacks for user convenience and because there are no downsides
|
||||||
uint64 currentTitleId = CafeSystem::GetForegroundTitleId();
|
uint64 currentTitleId = CafeSystem::GetForegroundTitleId();
|
||||||
if (currentTitleId == 0x00050000101c9500 || currentTitleId == 0x00050000101c9400 || currentTitleId == 0x0005000e101c9300)
|
if (currentTitleId == 0x00050000101c9500 || currentTitleId == 0x00050000101c9400 || currentTitleId == 0x00050000101c9300)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,8 @@ enum class LogType : sint32
|
||||||
template <>
|
template <>
|
||||||
struct fmt::formatter<std::u8string_view> : formatter<string_view> {
|
struct fmt::formatter<std::u8string_view> : formatter<string_view> {
|
||||||
template <typename FormatContext>
|
template <typename FormatContext>
|
||||||
auto format(std::u8string_view v, FormatContext& ctx) {
|
auto format(std::u8string_view v, FormatContext& ctx)
|
||||||
|
{
|
||||||
string_view s((char*)v.data(), v.size());
|
string_view s((char*)v.data(), v.size());
|
||||||
return formatter<string_view>::format(s, ctx);
|
return formatter<string_view>::format(s, ctx);
|
||||||
}
|
}
|
||||||
|
@ -52,17 +53,39 @@ bool cemuLog_log(LogType type, std::u8string_view text);
|
||||||
bool cemuLog_log(LogType type, std::wstring_view text);
|
bool cemuLog_log(LogType type, std::wstring_view text);
|
||||||
void cemuLog_waitForFlush(); // wait until all log lines are written
|
void cemuLog_waitForFlush(); // wait until all log lines are written
|
||||||
|
|
||||||
template<typename TFmt, typename ... TArgs>
|
template <typename T>
|
||||||
bool cemuLog_log(LogType type, TFmt format, TArgs&&... args)
|
auto ForwardEnum(T t)
|
||||||
|
{
|
||||||
|
if constexpr (std::is_enum_v<T>)
|
||||||
|
return fmt::underlying(t);
|
||||||
|
else
|
||||||
|
return std::forward<T>(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... TArgs>
|
||||||
|
auto ForwardEnum(std::tuple<TArgs...> t)
|
||||||
|
{
|
||||||
|
return std::apply([](auto... x) { return std::make_tuple(ForwardEnum(x)...); }, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename ... TArgs>
|
||||||
|
bool cemuLog_log(LogType type, std::basic_string<T> format, TArgs&&... args)
|
||||||
{
|
{
|
||||||
if (!cemuLog_isLoggingEnabled(type))
|
if (!cemuLog_isLoggingEnabled(type))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const auto format_view = fmt::to_string_view(format);
|
const auto format_view = fmt::basic_string_view<T>(format);
|
||||||
const auto text = fmt::vformat(format_view, fmt::make_args_checked<TArgs...>(format_view, args...));
|
const auto text = fmt::vformat(format_view, fmt::make_format_args<fmt::buffer_context<T>>(ForwardEnum(args)...));
|
||||||
cemuLog_log(type, std::basic_string_view(text.data(), text.size()));
|
cemuLog_log(type, std::basic_string_view(text.data(), text.size()));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T, typename ... TArgs>
|
||||||
|
bool cemuLog_log(LogType type, const T* format, TArgs&&... args)
|
||||||
|
{
|
||||||
|
auto format_str=std::basic_string<T>(format);
|
||||||
|
return cemuLog_log(type, format_str, std::forward<TArgs>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
// same as cemuLog_log, but only outputs in debug/release mode
|
// same as cemuLog_log, but only outputs in debug/release mode
|
||||||
template<typename TFmt, typename ... TArgs>
|
template<typename TFmt, typename ... TArgs>
|
||||||
|
|
|
@ -242,7 +242,7 @@ bool DownloadManager::_connect_queryAccountStatusAndServiceURLs()
|
||||||
NAPI::NAPI_ECSGetAccountStatus_Result accountStatusResult = NAPI::ECS_GetAccountStatus(authInfo);
|
NAPI::NAPI_ECSGetAccountStatus_Result accountStatusResult = NAPI::ECS_GetAccountStatus(authInfo);
|
||||||
if (accountStatusResult.apiError != NAPI_RESULT::SUCCESS)
|
if (accountStatusResult.apiError != NAPI_RESULT::SUCCESS)
|
||||||
{
|
{
|
||||||
cemuLog_log(LogType::Force, fmt::format("ECS - Failed to query account status (error: {0} {1})", accountStatusResult.apiError, accountStatusResult.serviceError));
|
cemuLog_log(LogType::Force, "ECS - Failed to query account status (error: {0} {1})", accountStatusResult.apiError, accountStatusResult.serviceError);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (accountStatusResult.accountStatus == NAPI::NAPI_ECSGetAccountStatus_Result::AccountStatus::UNREGISTERED)
|
if (accountStatusResult.accountStatus == NAPI::NAPI_ECSGetAccountStatus_Result::AccountStatus::UNREGISTERED)
|
||||||
|
|
|
@ -30,7 +30,7 @@ public:
|
||||||
[[nodiscard]] static fs::path GetPath(std::string_view format, TArgs&&... args)
|
[[nodiscard]] static fs::path GetPath(std::string_view format, TArgs&&... args)
|
||||||
{
|
{
|
||||||
cemu_assert_debug(format.empty() || (format[0] != '/' && format[0] != '\\'));
|
cemu_assert_debug(format.empty() || (format[0] != '/' && format[0] != '\\'));
|
||||||
std::string tmpPathStr = fmt::format(format, std::forward<TArgs>(args)...);
|
std::string tmpPathStr = fmt::format(fmt::runtime(format), std::forward<TArgs>(args)...);
|
||||||
std::basic_string_view<char8_t> s((const char8_t*)tmpPathStr.data(), tmpPathStr.size());
|
std::basic_string_view<char8_t> s((const char8_t*)tmpPathStr.data(), tmpPathStr.size());
|
||||||
return s_path / fs::path(s);
|
return s_path / fs::path(s);
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ public:
|
||||||
[[nodiscard]] static fs::path GetMlcPath(std::string_view format, TArgs&&... args)
|
[[nodiscard]] static fs::path GetMlcPath(std::string_view format, TArgs&&... args)
|
||||||
{
|
{
|
||||||
cemu_assert_debug(format.empty() || (format[0] != '/' && format[0] != '\\'));
|
cemu_assert_debug(format.empty() || (format[0] != '/' && format[0] != '\\'));
|
||||||
auto tmp = fmt::format(format, std::forward<TArgs>(args)...);
|
auto tmp = fmt::format(fmt::runtime(format), std::forward<TArgs>(args)...);
|
||||||
return GetMlcPath() / fs::path(_asUtf8(tmp));
|
return GetMlcPath() / fs::path(_asUtf8(tmp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ public:
|
||||||
[[nodiscard]] static fs::path GetMlcPath(std::wstring_view format, TArgs&&... args)
|
[[nodiscard]] static fs::path GetMlcPath(std::wstring_view format, TArgs&&... args)
|
||||||
{
|
{
|
||||||
cemu_assert_debug(format.empty() || (format[0] != L'/' && format[0] != L'\\'));
|
cemu_assert_debug(format.empty() || (format[0] != L'/' && format[0] != L'\\'));
|
||||||
return GetMlcPath() / fmt::format(format, std::forward<TArgs>(args)...);
|
return GetMlcPath() / fmt::format(fmt::runtime(format), std::forward<TArgs>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
// get mlc path to default cemu root dir/mlc01
|
// get mlc path to default cemu root dir/mlc01
|
||||||
|
|
|
@ -160,15 +160,15 @@ void CemuConfig::Load(XMLConfigParser& parser)
|
||||||
{
|
{
|
||||||
GameEntry entry{};
|
GameEntry entry{};
|
||||||
entry.rpx_file = boost::nowide::widen(rpx);
|
entry.rpx_file = boost::nowide::widen(rpx);
|
||||||
entry.title_id = element.get("title_id", 0LL);
|
entry.title_id = element.get<decltype(entry.title_id)>("title_id");
|
||||||
entry.legacy_name = boost::nowide::widen(element.get("name", ""));
|
entry.legacy_name = boost::nowide::widen(element.get("name", ""));
|
||||||
entry.custom_name = element.get("custom_name", "");
|
entry.custom_name = element.get("custom_name", "");
|
||||||
entry.legacy_region = element.get("region", 0);
|
entry.legacy_region = element.get("region", 0);
|
||||||
entry.legacy_version = element.get("version", 0);
|
entry.legacy_version = element.get("version", 0);
|
||||||
entry.legacy_update_version = element.get("version", 0);
|
entry.legacy_update_version = element.get("version", 0);
|
||||||
entry.legacy_dlc_version = element.get("dlc_version", 0);
|
entry.legacy_dlc_version = element.get("dlc_version", 0);
|
||||||
entry.legacy_time_played = element.get("time_played", 0ULL);
|
entry.legacy_time_played = element.get<decltype(entry.legacy_time_played)>("time_played");
|
||||||
entry.legacy_last_played = element.get("last_played", 0ULL);
|
entry.legacy_last_played = element.get<decltype(entry.legacy_last_played)>("last_played");
|
||||||
entry.favorite = element.get("favorite", false);
|
entry.favorite = element.get("favorite", false);
|
||||||
game_cache_entries.emplace_back(entry);
|
game_cache_entries.emplace_back(entry);
|
||||||
|
|
||||||
|
|
|
@ -217,7 +217,7 @@ void CemuApp::CreateDefaultFiles(bool first_start)
|
||||||
// check for mlc01 folder missing if custom path has been set
|
// check for mlc01 folder missing if custom path has been set
|
||||||
if (!fs::exists(mlc) && !first_start)
|
if (!fs::exists(mlc) && !first_start)
|
||||||
{
|
{
|
||||||
const std::wstring message = fmt::format(_(L"Your mlc01 folder seems to be missing.\n\nThis is where Cemu stores save files, game updates and other Wii U files.\n\nThe expected path is:\n{}\n\nDo you want to create the folder at the expected path?").ToStdWstring(), mlc);
|
const std::wstring message = fmt::format(fmt::runtime(_(L"Your mlc01 folder seems to be missing.\n\nThis is where Cemu stores save files, game updates and other Wii U files.\n\nThe expected path is:\n{}\n\nDo you want to create the folder at the expected path?").ToStdWstring()), mlc);
|
||||||
|
|
||||||
wxMessageDialog dialog(nullptr, message, "Error", wxCENTRE | wxYES_NO | wxCANCEL| wxICON_WARNING);
|
wxMessageDialog dialog(nullptr, message, "Error", wxCENTRE | wxYES_NO | wxCANCEL| wxICON_WARNING);
|
||||||
dialog.SetYesNoCancelLabels(_("Yes"), _("No"), _("Select a custom path"));
|
dialog.SetYesNoCancelLabels(_("Yes"), _("No"), _("Select a custom path"));
|
||||||
|
@ -293,7 +293,7 @@ void CemuApp::CreateDefaultFiles(bool first_start)
|
||||||
catch (const std::exception& ex)
|
catch (const std::exception& ex)
|
||||||
{
|
{
|
||||||
std::stringstream errorMsg;
|
std::stringstream errorMsg;
|
||||||
errorMsg << fmt::format(_("Couldn't create a required mlc01 subfolder or file!\n\nError: {0}\nTarget path:\n{1}").ToStdString(), ex.what(), boost::nowide::narrow(mlc));
|
errorMsg << fmt::format(fmt::runtime(_("Couldn't create a required mlc01 subfolder or file!\n\nError: {0}\nTarget path:\n{1}").ToStdString()), ex.what(), boost::nowide::narrow(mlc));
|
||||||
|
|
||||||
#if BOOST_OS_WINDOWS
|
#if BOOST_OS_WINDOWS
|
||||||
const DWORD lastError = GetLastError();
|
const DWORD lastError = GetLastError();
|
||||||
|
@ -319,7 +319,7 @@ void CemuApp::CreateDefaultFiles(bool first_start)
|
||||||
catch (const std::exception& ex)
|
catch (const std::exception& ex)
|
||||||
{
|
{
|
||||||
std::stringstream errorMsg;
|
std::stringstream errorMsg;
|
||||||
errorMsg << fmt::format(_("Couldn't create a required cemu directory or file!\n\nError: {0}").ToStdString(), ex.what());
|
errorMsg << fmt::format(fmt::runtime(_("Couldn't create a required cemu directory or file!\n\nError: {0}").ToStdString()), ex.what());
|
||||||
|
|
||||||
#if BOOST_OS_WINDOWS
|
#if BOOST_OS_WINDOWS
|
||||||
const DWORD lastError = GetLastError();
|
const DWORD lastError = GetLastError();
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "gui/helpers/wxCustomEvents.h"
|
#include "gui/helpers/wxCustomEvents.h"
|
||||||
#include "util/helpers/helpers.h"
|
#include "util/helpers/helpers.h"
|
||||||
#include "gui/helpers/wxHelpers.h"
|
#include "gui/helpers/wxHelpers.h"
|
||||||
|
#include "gui/wxHelper.h"
|
||||||
#include "Cafe/Filesystem/WUD/wud.h"
|
#include "Cafe/Filesystem/WUD/wud.h"
|
||||||
|
|
||||||
#include <zip.h>
|
#include <zip.h>
|
||||||
|
@ -518,7 +519,7 @@ void ChecksumTool::VerifyJsonEntry(const rapidjson::Document& doc)
|
||||||
file.flush();
|
file.flush();
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
wxLaunchDefaultBrowser(fmt::format("file:{}", path));
|
wxLaunchDefaultBrowser(wxHelper::FromUtf8(fmt::format("file:{}", path)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
wxMessageBox(_("Can't open file to write!"), _("Error"), wxOK | wxCENTRE | wxICON_ERROR, this);
|
wxMessageBox(_("Can't open file to write!"), _("Error"), wxOK | wxCENTRE | wxICON_ERROR, this);
|
||||||
|
|
|
@ -63,7 +63,7 @@ bool GameUpdateWindow::ParseUpdate(const fs::path& metaPath)
|
||||||
std::string typeStrCurrentlyInstalled = _GetTitleIdTypeStr(tmp.GetAppTitleId());
|
std::string typeStrCurrentlyInstalled = _GetTitleIdTypeStr(tmp.GetAppTitleId());
|
||||||
|
|
||||||
std::string wxMsg = wxHelper::MakeUTF8(_("It seems that there is already a title installed at the target location but it has a different type.\nCurrently installed: \'{}\' Installing: \'{}\'\n\nThis can happen for titles which were installed with very old Cemu versions.\nDo you still want to continue with the installation? It will replace the currently installed title."));
|
std::string wxMsg = wxHelper::MakeUTF8(_("It seems that there is already a title installed at the target location but it has a different type.\nCurrently installed: \'{}\' Installing: \'{}\'\n\nThis can happen for titles which were installed with very old Cemu versions.\nDo you still want to continue with the installation? It will replace the currently installed title."));
|
||||||
wxMessageDialog dialog(this, fmt::format(wxMsg, typeStrCurrentlyInstalled, typeStrToInstall), _("Warning"), wxCENTRE | wxYES_NO | wxICON_EXCLAMATION);
|
wxMessageDialog dialog(this, fmt::format(fmt::runtime(wxMsg), typeStrCurrentlyInstalled, typeStrToInstall), _("Warning"), wxCENTRE | wxYES_NO | wxICON_EXCLAMATION);
|
||||||
if (dialog.ShowModal() != wxID_YES)
|
if (dialog.ShowModal() != wxID_YES)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1110,7 +1110,7 @@ void GeneralSettings2::OnAccountDelete(wxCommandEvent& event)
|
||||||
auto& account = obj->GetAccount();
|
auto& account = obj->GetAccount();
|
||||||
|
|
||||||
const std::wstring format_str = _("Are you sure you want to delete the account {} with id {:x}?").ToStdWstring();
|
const std::wstring format_str = _("Are you sure you want to delete the account {} with id {:x}?").ToStdWstring();
|
||||||
const std::wstring msg = fmt::format(format_str,
|
const std::wstring msg = fmt::format(fmt::runtime(format_str),
|
||||||
std::wstring{ account.GetMiiName() }, account.GetPersistentId());
|
std::wstring{ account.GetMiiName() }, account.GetPersistentId());
|
||||||
|
|
||||||
const int answer = wxMessageBox(msg, _("Confirmation"), wxYES_NO | wxCENTRE | wxICON_QUESTION, this);
|
const int answer = wxMessageBox(msg, _("Confirmation"), wxYES_NO | wxCENTRE | wxICON_QUESTION, this);
|
||||||
|
|
|
@ -1803,7 +1803,7 @@ public:
|
||||||
|
|
||||||
void AddHeaderInfo(wxWindow* parent, wxSizer* sizer)
|
void AddHeaderInfo(wxWindow* parent, wxSizer* sizer)
|
||||||
{
|
{
|
||||||
auto versionString = fmt::format(_("Cemu\nVersion {0}\nCompiled on {1}\nOriginal authors: {2}").ToStdString(), BUILD_VERSION_STRING, BUILD_DATE, "Exzap, Petergov");
|
auto versionString = fmt::format(fmt::runtime(_("Cemu\nVersion {0}\nCompiled on {1}\nOriginal authors: {2}").ToStdString()), BUILD_VERSION_STRING, BUILD_DATE, "Exzap, Petergov");
|
||||||
|
|
||||||
sizer->Add(new wxStaticText(parent, wxID_ANY, versionString), wxSizerFlags().Border(wxALL, 3).Border(wxTOP, 10));
|
sizer->Add(new wxStaticText(parent, wxID_ANY, versionString), wxSizerFlags().Border(wxALL, 3).Border(wxTOP, 10));
|
||||||
sizer->Add(new wxHyperlinkCtrl(parent, -1, "https://cemu.info", "https://cemu.info"), wxSizerFlags().Expand().Border(wxTOP | wxBOTTOM, 3));
|
sizer->Add(new wxHyperlinkCtrl(parent, -1, "https://cemu.info", "https://cemu.info"), wxSizerFlags().Expand().Border(wxTOP | wxBOTTOM, 3));
|
||||||
|
@ -1945,7 +1945,7 @@ public:
|
||||||
"/*****************************************************************************/\r\n"
|
"/*****************************************************************************/\r\n"
|
||||||
);
|
);
|
||||||
delete fs;
|
delete fs;
|
||||||
wxLaunchDefaultBrowser(fmt::format("file:{}", _utf8Wrapper(tempPath)));
|
wxLaunchDefaultBrowser(wxHelper::FromUtf8(fmt::format("file:{}", _utf8Wrapper(tempPath))));
|
||||||
});
|
});
|
||||||
lineSizer->Add(noticeLink, 0);
|
lineSizer->Add(noticeLink, 0);
|
||||||
lineSizer->Add(new wxStaticText(parent, -1, ")"), 0);
|
lineSizer->Add(new wxStaticText(parent, -1, ")"), 0);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "Cafe/TitleList/GameInfo.h"
|
#include "Cafe/TitleList/GameInfo.h"
|
||||||
#include "util/helpers/helpers.h"
|
#include "util/helpers/helpers.h"
|
||||||
#include "gui/helpers/wxHelpers.h"
|
#include "gui/helpers/wxHelpers.h"
|
||||||
|
#include "gui/wxHelper.h"
|
||||||
#include "gui/components/wxTitleManagerList.h"
|
#include "gui/components/wxTitleManagerList.h"
|
||||||
#include "gui/components/wxDownloadManagerList.h"
|
#include "gui/components/wxDownloadManagerList.h"
|
||||||
#include "gui/GameUpdateWindow.h"
|
#include "gui/GameUpdateWindow.h"
|
||||||
|
@ -479,7 +480,7 @@ void TitleManager::OnSaveOpenDirectory(wxCommandEvent& event)
|
||||||
if (!fs::exists(target) || !fs::is_directory(target))
|
if (!fs::exists(target) || !fs::is_directory(target))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wxLaunchDefaultBrowser(fmt::format("file:{}", _utf8Wrapper(target)));
|
wxLaunchDefaultBrowser(wxHelper::FromUtf8(fmt::format("file:{}", _utf8Wrapper(target))));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TitleManager::OnSaveDelete(wxCommandEvent& event)
|
void TitleManager::OnSaveDelete(wxCommandEvent& event)
|
||||||
|
|
|
@ -27,7 +27,7 @@ VulkanCanvas::VulkanCanvas(wxWindow* parent, const wxSize& size, bool is_main_wi
|
||||||
}
|
}
|
||||||
catch(const std::exception& ex)
|
catch(const std::exception& ex)
|
||||||
{
|
{
|
||||||
const auto msg = fmt::format(_("Error when initializing Vulkan renderer:\n{}").ToStdString(), ex.what());
|
const auto msg = fmt::format(fmt::runtime(_("Error when initializing Vulkan renderer:\n{}").ToStdString()), ex.what());
|
||||||
forceLog_printf(const_cast<char*>(msg.c_str()));
|
forceLog_printf(const_cast<char*>(msg.c_str()));
|
||||||
wxMessageDialog dialog(this, msg, _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
|
wxMessageDialog dialog(this, msg, _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
|
||||||
dialog.ShowModal();
|
dialog.ShowModal();
|
||||||
|
|
|
@ -51,11 +51,18 @@ wxGameList::wxGameList(wxWindow* parent, wxWindowID id)
|
||||||
: wxListCtrl(parent, id, wxDefaultPosition, wxDefaultSize, GetStyleFlags(Style::kList)), m_style(Style::kList)
|
: wxListCtrl(parent, id, wxDefaultPosition, wxDefaultSize, GetStyleFlags(Style::kList)), m_style(Style::kList)
|
||||||
{
|
{
|
||||||
CreateListColumns();
|
CreateListColumns();
|
||||||
|
|
||||||
|
const char transparent_bitmap[kIconWidth * kIconWidth * 4] = {0};
|
||||||
|
wxBitmap blank(transparent_bitmap, kIconWidth, kIconWidth);
|
||||||
|
blank.UseAlpha(true);
|
||||||
|
|
||||||
m_image_list = new wxImageList(kIconWidth, kIconWidth);
|
m_image_list = new wxImageList(kIconWidth, kIconWidth);
|
||||||
|
m_image_list->Add(blank);
|
||||||
wxListCtrl::SetImageList(m_image_list, wxIMAGE_LIST_NORMAL);
|
wxListCtrl::SetImageList(m_image_list, wxIMAGE_LIST_NORMAL);
|
||||||
|
|
||||||
m_image_list_small = new wxImageList(kListIconWidth, kListIconWidth);
|
m_image_list_small = new wxImageList(kListIconWidth, kListIconWidth);
|
||||||
|
wxBitmap::Rescale(blank, {kListIconWidth, kListIconWidth});
|
||||||
|
m_image_list_small->Add(blank);
|
||||||
wxListCtrl::SetImageList(m_image_list_small, wxIMAGE_LIST_SMALL);
|
wxListCtrl::SetImageList(m_image_list_small, wxIMAGE_LIST_SMALL);
|
||||||
|
|
||||||
m_tooltip_window = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER);
|
m_tooltip_window = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER);
|
||||||
|
@ -556,7 +563,7 @@ void wxGameList::OnContextMenuSelected(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
fs::path path(gameInfo.GetBase().GetPath());
|
fs::path path(gameInfo.GetBase().GetPath());
|
||||||
_stripPathFilename(path);
|
_stripPathFilename(path);
|
||||||
wxLaunchDefaultBrowser(fmt::format("file:{}", _utf8Wrapper(path)));
|
wxLaunchDefaultBrowser(wxHelper::FromUtf8(fmt::format("file:{}", _utf8Wrapper(path))));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kWikiPage:
|
case kWikiPage:
|
||||||
|
@ -570,28 +577,28 @@ void wxGameList::OnContextMenuSelected(wxCommandEvent& event)
|
||||||
wxASSERT(!tokens.empty());
|
wxASSERT(!tokens.empty());
|
||||||
const std::string company_code = gameInfo.GetBase().GetMetaInfo()->GetCompanyCode();
|
const std::string company_code = gameInfo.GetBase().GetMetaInfo()->GetCompanyCode();
|
||||||
wxASSERT(company_code.size() >= 2);
|
wxASSERT(company_code.size() >= 2);
|
||||||
wxLaunchDefaultBrowser(fmt::format("https://wiki.cemu.info/wiki/{}{}", *tokens.rbegin(), company_code.substr(company_code.size() - 2).c_str()));
|
wxLaunchDefaultBrowser(wxHelper::FromUtf8(fmt::format("https://wiki.cemu.info/wiki/{}{}", *tokens.rbegin(), company_code.substr(company_code.size() - 2).c_str())));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case kContextMenuSaveFolder:
|
case kContextMenuSaveFolder:
|
||||||
{
|
{
|
||||||
wxLaunchDefaultBrowser(fmt::format("file:{}", _utf8Wrapper(gameInfo.GetSaveFolder())));
|
wxLaunchDefaultBrowser(wxHelper::FromUtf8(fmt::format("file:{}", _utf8Wrapper(gameInfo.GetSaveFolder()))));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kContextMenuUpdateFolder:
|
case kContextMenuUpdateFolder:
|
||||||
{
|
{
|
||||||
fs::path path(gameInfo.GetUpdate().GetPath());
|
fs::path path(gameInfo.GetUpdate().GetPath());
|
||||||
_stripPathFilename(path);
|
_stripPathFilename(path);
|
||||||
wxLaunchDefaultBrowser(fmt::format("file:{}", _utf8Wrapper(path)));
|
wxLaunchDefaultBrowser(wxHelper::FromUtf8(fmt::format("file:{}", _utf8Wrapper(path))));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kContextMenuDLCFolder:
|
case kContextMenuDLCFolder:
|
||||||
{
|
{
|
||||||
fs::path path(gameInfo.GetAOC().front().GetPath());
|
fs::path path(gameInfo.GetAOC().front().GetPath());
|
||||||
_stripPathFilename(path);
|
_stripPathFilename(path);
|
||||||
wxLaunchDefaultBrowser(fmt::format("file:{}", _utf8Wrapper(path)));
|
wxLaunchDefaultBrowser(wxHelper::FromUtf8(fmt::format("file:{}", _utf8Wrapper(path))));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kContextMenuEditGraphicPacks:
|
case kContextMenuEditGraphicPacks:
|
||||||
|
@ -857,15 +864,14 @@ void wxGameList::OnGameEntryUpdatedByTitleId(wxTitleIdEvent& event)
|
||||||
isNewEntry = true;
|
isNewEntry = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int icon = 0;
|
int icon = 0; /* 0 is the default empty icon */
|
||||||
int icon_small = 0;
|
int icon_small = 0; /* 0 is the default empty icon */
|
||||||
bool hasIcon = QueryIconForTitle(baseTitleId, icon, icon_small);
|
QueryIconForTitle(baseTitleId, icon, icon_small);
|
||||||
|
|
||||||
if (m_style == Style::kList)
|
if (m_style == Style::kList)
|
||||||
{
|
{
|
||||||
if(hasIcon)
|
SetItemColumnImage(index, ColumnIcon, icon_small);
|
||||||
SetItemColumnImage(index, ColumnIcon, icon_small);
|
|
||||||
|
|
||||||
SetItem(index, ColumnName, wxHelper::FromUtf8(GetNameByTitleId(baseTitleId)));
|
SetItem(index, ColumnName, wxHelper::FromUtf8(GetNameByTitleId(baseTitleId)));
|
||||||
|
|
||||||
SetItem(index, ColumnVersion, fmt::format("{}", gameInfo.GetVersion()));
|
SetItem(index, ColumnVersion, fmt::format("{}", gameInfo.GetVersion()));
|
||||||
|
@ -912,13 +918,11 @@ void wxGameList::OnGameEntryUpdatedByTitleId(wxTitleIdEvent& event)
|
||||||
}
|
}
|
||||||
else if (m_style == Style::kIcons)
|
else if (m_style == Style::kIcons)
|
||||||
{
|
{
|
||||||
if(hasIcon)
|
SetItemImage(index, icon);
|
||||||
SetItemImage(index, icon);
|
|
||||||
}
|
}
|
||||||
else if (m_style == Style::kSmallIcons)
|
else if (m_style == Style::kSmallIcons)
|
||||||
{
|
{
|
||||||
if (hasIcon)
|
SetItemImage(index, icon_small);
|
||||||
SetItemImage(index, icon_small);
|
|
||||||
}
|
}
|
||||||
if (isNewEntry)
|
if (isNewEntry)
|
||||||
UpdateItemColors(index);
|
UpdateItemColors(index);
|
||||||
|
|
|
@ -293,23 +293,23 @@ void wxTitleManagerList::OnConvertToCompressedFormat(uint64 titleId)
|
||||||
std::string msg = wxHelper::MakeUTF8(_("The following content will be converted to a compressed Wii U archive file (.wua):\n \n"));
|
std::string msg = wxHelper::MakeUTF8(_("The following content will be converted to a compressed Wii U archive file (.wua):\n \n"));
|
||||||
|
|
||||||
if (titleInfo_base.IsValid())
|
if (titleInfo_base.IsValid())
|
||||||
msg.append(fmt::format(wxHelper::MakeUTF8(_("Base game: {}")), _utf8Wrapper(titleInfo_base.GetPath())));
|
msg.append(fmt::format(fmt::runtime(wxHelper::MakeUTF8(_("Base game: {}"))), _utf8Wrapper(titleInfo_base.GetPath())));
|
||||||
else
|
else
|
||||||
msg.append(fmt::format(wxHelper::MakeUTF8(_("Base game: Not installed"))));
|
msg.append(fmt::format(fmt::runtime(wxHelper::MakeUTF8(_("Base game: Not installed")))));
|
||||||
|
|
||||||
msg.append("\n");
|
msg.append("\n");
|
||||||
|
|
||||||
if (titleInfo_update.IsValid())
|
if (titleInfo_update.IsValid())
|
||||||
msg.append(fmt::format(wxHelper::MakeUTF8(_("Update: {}")), _utf8Wrapper(titleInfo_update.GetPath())));
|
msg.append(fmt::format(fmt::runtime(wxHelper::MakeUTF8(_("Update: {}"))), _utf8Wrapper(titleInfo_update.GetPath())));
|
||||||
else
|
else
|
||||||
msg.append(fmt::format(wxHelper::MakeUTF8(_("Update: Not installed"))));
|
msg.append(fmt::format(fmt::runtime(wxHelper::MakeUTF8(_("Update: Not installed")))));
|
||||||
|
|
||||||
msg.append("\n");
|
msg.append("\n");
|
||||||
|
|
||||||
if (titleInfo_aoc.IsValid())
|
if (titleInfo_aoc.IsValid())
|
||||||
msg.append(fmt::format(wxHelper::MakeUTF8(_("DLC: {}")), _utf8Wrapper(titleInfo_aoc.GetPath())));
|
msg.append(fmt::format(fmt::runtime(wxHelper::MakeUTF8(_("DLC: {}"))), _utf8Wrapper(titleInfo_aoc.GetPath())));
|
||||||
else
|
else
|
||||||
msg.append(fmt::format(wxHelper::MakeUTF8(_("DLC: Not installed"))));
|
msg.append(fmt::format(fmt::runtime(wxHelper::MakeUTF8(_("DLC: Not installed")))));
|
||||||
|
|
||||||
const int answer = wxMessageBox(wxString::FromUTF8(msg), _("Confirmation"), wxOK | wxCANCEL | wxCENTRE | wxICON_QUESTION, this);
|
const int answer = wxMessageBox(wxString::FromUTF8(msg), _("Confirmation"), wxOK | wxCANCEL | wxCENTRE | wxICON_QUESTION, this);
|
||||||
if (answer != wxOK)
|
if (answer != wxOK)
|
||||||
|
@ -852,7 +852,7 @@ void wxTitleManagerList::OnContextMenuSelected(wxCommandEvent& event)
|
||||||
case kContextMenuOpenDirectory:
|
case kContextMenuOpenDirectory:
|
||||||
{
|
{
|
||||||
const auto path = fs::is_directory(entry->path) ? entry->path : entry->path.parent_path();
|
const auto path = fs::is_directory(entry->path) ? entry->path : entry->path.parent_path();
|
||||||
wxLaunchDefaultBrowser(fmt::format("file:{}", _utf8Wrapper(path)));
|
wxLaunchDefaultBrowser(wxHelper::FromUtf8(fmt::format("file:{}", _utf8Wrapper(path))));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kContextMenuDelete:
|
case kContextMenuDelete:
|
||||||
|
|
|
@ -71,7 +71,7 @@ void wxCreateAccountDialog::OnOK(wxCommandEvent& event)
|
||||||
const auto id = GetPersistentId();
|
const auto id = GetPersistentId();
|
||||||
if(id < Account::kMinPersistendId)
|
if(id < Account::kMinPersistendId)
|
||||||
{
|
{
|
||||||
wxMessageBox(fmt::format(_("The persistent id must be greater than {:x}!").ToStdString(), Account::kMinPersistendId),
|
wxMessageBox(fmt::format(fmt::runtime(_("The persistent id must be greater than {:x}!").ToStdString()), Account::kMinPersistendId),
|
||||||
_("Error"), wxOK | wxCENTRE | wxICON_ERROR, this);
|
_("Error"), wxOK | wxCENTRE | wxICON_ERROR, this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ void wxCreateAccountDialog::OnOK(wxCommandEvent& event)
|
||||||
const auto& account = Account::GetAccount(id);
|
const auto& account = Account::GetAccount(id);
|
||||||
if(account.GetPersistentId() == id)
|
if(account.GetPersistentId() == id)
|
||||||
{
|
{
|
||||||
const std::wstring msg = fmt::format(_("The persistent id {:x} is already in use by account {}!").ToStdWstring(),
|
const std::wstring msg = fmt::format(fmt::runtime(_("The persistent id {:x} is already in use by account {}!").ToStdWstring()),
|
||||||
account.GetPersistentId(), std::wstring{ account.GetMiiName() });
|
account.GetPersistentId(), std::wstring{ account.GetMiiName() });
|
||||||
wxMessageBox(msg, _("Error"), wxOK | wxCENTRE | wxICON_ERROR, this);
|
wxMessageBox(msg, _("Error"), wxOK | wxCENTRE | wxICON_ERROR, this);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -48,13 +48,13 @@ template<typename ...TArgs>
|
||||||
wxString wxStringFormat2(const wxString& format, TArgs&&...args)
|
wxString wxStringFormat2(const wxString& format, TArgs&&...args)
|
||||||
{
|
{
|
||||||
// ignores locale?
|
// ignores locale?
|
||||||
return fmt::format(format.ToStdString(), std::forward<TArgs>(args)...);
|
return fmt::format(fmt::runtime(format.ToStdString()), std::forward<TArgs>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ...TArgs>
|
template<typename ...TArgs>
|
||||||
wxString wxStringFormat2W(const wxString& format, TArgs&&...args)
|
wxString wxStringFormat2W(const wxString& format, TArgs&&...args)
|
||||||
{
|
{
|
||||||
return fmt::format(format.ToStdWstring(), std::forward<TArgs>(args)...);
|
return fmt::format(fmt::runtime(format.ToStdWstring()), std::forward<TArgs>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
// executes a function when destroying the obj
|
// executes a function when destroying the obj
|
||||||
|
|
Binary file not shown.
|
@ -35,7 +35,7 @@ public:
|
||||||
void appendFmt(const char* format_str, Args... args)
|
void appendFmt(const char* format_str, Args... args)
|
||||||
{
|
{
|
||||||
char* buf = (char*)(m_strBuffer + m_offsetEnd);
|
char* buf = (char*)(m_strBuffer + m_offsetEnd);
|
||||||
char* r = fmt::format_to(buf, format_str, std::forward<Args>(args)...);
|
char* r = fmt::format_to(buf, fmt::runtime(format_str), std::forward<Args>(args)...);
|
||||||
cemu_assert_debug(r <= (char*)(m_strBuffer + N));
|
cemu_assert_debug(r <= (char*)(m_strBuffer + N));
|
||||||
m_offsetEnd += (uint32)(r - buf);
|
m_offsetEnd += (uint32)(r - buf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ public:
|
||||||
template<typename TFmt, typename ... TArgs>
|
template<typename TFmt, typename ... TArgs>
|
||||||
void addFmt(const TFmt& format, TArgs&&... args)
|
void addFmt(const TFmt& format, TArgs&&... args)
|
||||||
{
|
{
|
||||||
auto r = fmt::vformat_to_n((char*)(this->str + this->length), (size_t)(this->limit - this->length), fmt::to_string_view(format), fmt::make_args_checked<TArgs...>(format, args...));
|
auto r = fmt::vformat_to_n((char*)(this->str + this->length), (size_t)(this->limit - this->length), fmt::detail::to_string_view(format), fmt::make_format_args(args...));
|
||||||
this->length += (uint32)r.size;
|
this->length += (uint32)r.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue