2 Commits
443 changed files with 13834 additions and 49916 deletions
-51
View File
@@ -1,51 +0,0 @@
name: Android build
on:
workflow_call:
workflow_dispatch:
push:
branches: ["android"]
pull_request:
branches: ["android"]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
submodules: "recursive"
fetch-depth: 0
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: "17"
distribution: "temurin"
- name: Create store file
env:
ANDROID_STORE_FILE_BASE64: ${{ secrets.ANDROID_STORE_FILE_BASE64 }}
ANDROID_KEY_STORE_PASSWORD: ${{ secrets.ANDROID_KEY_STORE_PASSWORD }}
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
if: "${{ env.ANDROID_STORE_FILE_BASE64 != '' }}"
run: |
cd ./src/android
base64 --decode <<< "${ANDROID_STORE_FILE_BASE64}" > store.jks
ANDROID_STORE_FILE=$(pwd)/store.jks
echo -e "keyStorePassword=$ANDROID_KEY_STORE_PASSWORD\nkeyAlias=$ANDROID_KEY_ALIAS\nstoreFile=$ANDROID_STORE_FILE\n" > keystore.properties
- name: Build Cemu for Android
run: |
cd ./src/android
./gradlew assembleRelease
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: cemu-android
path: |
./src/android/app/build/outputs/apk/release/*.apk
./src/android/app/build/outputs/apk/release/*.aab
@@ -1,46 +0,0 @@
name: Deploy experimental android release
on:
workflow_dispatch:
jobs:
call-release-build:
uses: ./.github/workflows/android_build.yml
secrets: inherit
deploy:
name: Deploy experimental release
runs-on: ubuntu-22.04
needs: [call-release-build]
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/download-artifact@v4
with:
name: cemu-android
path: cemu-android
- name: Initialize
run: |
mkdir upload
sudo apt install zip
- name: Set version dependent vars
run: |
echo "CEMU_VERSION=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
- name: Create release from apk
run: |
VERSION=${{ env.CEMU_VERSION }}
echo "Cemu Version is $VERSION"
ls cemu-android
mv cemu-android/*.apk upload/Cemu-$VERSION.apk
- name: Create release
run: |
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
echo "[INFO] Release tag: v${{ env.CEMU_VERSION }}"
RELEASE_BODY=$(printf "Experimental release\n%s" "Latest commit ${{ env.CEMU_VERSION }}")
ghr_v0.15.0_linux_amd64/ghr -b "$RELEASE_BODY" -t ${{ secrets.GITHUB_TOKEN }} -n "Cemu ${{ env.CEMU_VERSION }}" "${{ env.CEMU_VERSION }}" ./upload
-1
View File
@@ -17,7 +17,6 @@
.idea/ .idea/
build/ build/
build_arm
cmake-build-*/ cmake-build-*/
out/ out/
.cache/ .cache/
+1 -4
View File
@@ -1,6 +1,6 @@
[submodule "dependencies/ZArchive"] [submodule "dependencies/ZArchive"]
path = dependencies/ZArchive path = dependencies/ZArchive
url = https://github.com/SSimco/ZArchive url = https://github.com/Exzap/ZArchive
shallow = true shallow = true
[submodule "dependencies/cubeb"] [submodule "dependencies/cubeb"]
path = dependencies/cubeb path = dependencies/cubeb
@@ -18,6 +18,3 @@
path = dependencies/imgui path = dependencies/imgui
url = https://github.com/ocornut/imgui url = https://github.com/ocornut/imgui
shallow = true shallow = true
[submodule "dependencies/xbyak_aarch64"]
path = dependencies/xbyak_aarch64
url = https://github.com/fujitsu/xbyak_aarch64
+8 -27
View File
@@ -35,22 +35,15 @@ if (ENABLE_VCPKG)
) )
endif() endif()
if(UNIX AND NOT APPLE)
if(UNIX AND NOT APPLE AND NOT VCPKG_TARGET_ANDROID)
set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports_linux") set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports_linux")
elseif(APPLE) elseif(APPLE)
set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports_mac") set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports_mac")
else() else()
set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports") set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports")
endif() endif()
if(VCPKG_TARGET_ANDROID) set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/vcpkg/scripts/buildsystems/vcpkg.cmake"
set(ENV{ANDROID_NDK_HOME} ${ANDROID_NDK}) CACHE STRING "Vcpkg toolchain file")
set(ENV{VCPKG_ROOT} "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/vcpkg")
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/vcpkg_android.cmake")
else()
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/vcpkg/scripts/buildsystems/vcpkg.cmake"
CACHE STRING "Vcpkg toolchain file")
endif()
# Set this so that all the various find_package() calls don't need an explicit # Set this so that all the various find_package() calls don't need an explicit
# CONFIG option # CONFIG option
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE) set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE)
@@ -77,10 +70,8 @@ add_definitions(-DEMULATOR_VERSION_PATCH=${EMULATOR_VERSION_PATCH})
set_property(GLOBAL PROPERTY USE_FOLDERS ON) set_property(GLOBAL PROPERTY USE_FOLDERS ON)
# enable link time optimization for release builds # enable link time optimization for release builds
if(NOT ANDROID) set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON) set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO ON)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO ON)
endif()
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)
@@ -152,17 +143,11 @@ option(ENABLE_WXWIDGETS "Build with wxWidgets UI (Currently required)" ON)
set(THREADS_PREFER_PTHREAD_FLAG true) set(THREADS_PREFER_PTHREAD_FLAG true)
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
if(ENABLE_SDL) find_package(SDL2 REQUIRED)
find_package(SDL2 REQUIRED)
add_compile_definitions("HAS_SDL=1")
endif()
find_package(CURL REQUIRED) find_package(CURL REQUIRED)
find_package(pugixml REQUIRED) find_package(pugixml REQUIRED)
find_package(RapidJSON REQUIRED) find_package(RapidJSON REQUIRED)
find_package(Boost COMPONENTS program_options filesystem nowide REQUIRED) find_package(Boost COMPONENTS program_options filesystem nowide REQUIRED)
if(ANDROID)
find_package(Boost COMPONENTS context iostreams REQUIRED)
endif()
find_package(libzip REQUIRED) find_package(libzip REQUIRED)
find_package(glslang REQUIRED) find_package(glslang REQUIRED)
find_package(ZLIB REQUIRED) find_package(ZLIB REQUIRED)
@@ -177,7 +162,7 @@ if (NOT TARGET glslang::SPIRV AND TARGET SPIRV)
add_library(glslang::SPIRV ALIAS SPIRV) add_library(glslang::SPIRV ALIAS SPIRV)
endif() endif()
if (UNIX AND NOT APPLE AND NOT ANDROID) if (UNIX AND NOT APPLE)
find_package(X11 REQUIRED) find_package(X11 REQUIRED)
if (ENABLE_WAYLAND) if (ENABLE_WAYLAND)
find_package(Wayland REQUIRED Client) find_package(Wayland REQUIRED Client)
@@ -216,7 +201,7 @@ if (ENABLE_HIDAPI)
add_compile_definitions(HAS_HIDAPI) add_compile_definitions(HAS_HIDAPI)
endif () endif ()
if(UNIX AND NOT APPLE AND NOT ANDROID) if(UNIX AND NOT APPLE)
if(ENABLE_FERAL_GAMEMODE) if(ENABLE_FERAL_GAMEMODE)
add_compile_definitions(ENABLE_FERAL_GAMEMODE) add_compile_definitions(ENABLE_FERAL_GAMEMODE)
add_subdirectory(dependencies/gamemode EXCLUDE_FROM_ALL) add_subdirectory(dependencies/gamemode EXCLUDE_FROM_ALL)
@@ -246,10 +231,6 @@ endif()
add_subdirectory("dependencies/ih264d" EXCLUDE_FROM_ALL) add_subdirectory("dependencies/ih264d" EXCLUDE_FROM_ALL)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "(aarch64)|(AARCH64)")
add_subdirectory("dependencies/xbyak_aarch64" EXCLUDE_FROM_ALL)
endif()
find_package(ZArchive) find_package(ZArchive)
if (NOT ZArchive_FOUND) if (NOT ZArchive_FOUND)
add_subdirectory("dependencies/ZArchive" EXCLUDE_FROM_ALL) add_subdirectory("dependencies/ZArchive" EXCLUDE_FROM_ALL)
-11
View File
@@ -1,11 +0,0 @@
#! /bin/env bash
# rm -rf build_arm
set -e
cmake -S . -B build_arm -DCMAKE_BUILD_TYPE=$BUILD_TYPE \
-DENABLE_VCPKG=OFF \
-DCMAKE_TOOLCHAIN_FILE=./cmake/debian-arm64toolchain.cmake \
-DENABLE_WAYLAND=OFF \
-DENABLE_HIDAPI=OFF \
-DENABLE_NSYSHID_LIBUSB=OFF \
-G Ninja
cmake --build build_arm
-9
View File
@@ -1,9 +0,0 @@
set(CMAKE_SYSTEM_NAME "Linux")
set(CMAKE_SYSTEM_PROCESSOR "aarch64")
set(CMAKE_ASM_COMPILER_TARGET aarch64-linux-gnu)
set(CMAKE_C_COMPILER clang-16)
set(CMAKE_C_COMPILER_TARGET aarch64-linux-gnu)
set(CMAKE_CXX_COMPILER clang++-16)
set(CMAKE_CXX_COMPILER_TARGET aarch64-linux-gnu)
set(PKG_CONFIG_EXECUTABLE "aarch64-linux-gnu-pkg-config")
set(PKGCONFIG_EXECUTABLE "aarch64-linux-gnu-pkg-config")
-99
View File
@@ -1,99 +0,0 @@
#
# vcpkg_android.cmake
#
# Helper script when using vcpkg with cmake. It should be triggered via the variable VCPKG_TARGET_ANDROID
#
# For example:
# if (VCPKG_TARGET_ANDROID)
# include("cmake/vcpkg_android.cmake")
# endif()
#
# This script will:
# 1 & 2. check the presence of needed env variables: ANDROID_NDK_HOME and VCPKG_ROOT
# 3. set VCPKG_TARGET_TRIPLET according to ANDROID_ABI
# 4. Combine vcpkg and Android toolchains by setting CMAKE_TOOLCHAIN_FILE
# and VCPKG_CHAINLOAD_TOOLCHAIN_FILE
# Note: VCPKG_TARGET_ANDROID is not an official Vcpkg variable.
# it is introduced for the need of this script
if (VCPKG_TARGET_ANDROID)
#
# 1. Check the presence of environment variable ANDROID_NDK_HOME
#
if (NOT DEFINED ENV{ANDROID_NDK_HOME})
message(FATAL_ERROR "
Please set an environment variable ANDROID_NDK_HOME
For example:
export ANDROID_NDK_HOME=/home/your-account/Android/Sdk/ndk-bundle
Or:
export ANDROID_NDK_HOME=/home/your-account/Android/android-ndk-r21b
")
endif()
#
# 2. Check the presence of environment variable VCPKG_ROOT
#
if (NOT DEFINED ENV{VCPKG_ROOT})
message(FATAL_ERROR "
Please set an environment variable VCPKG_ROOT
For example:
export VCPKG_ROOT=/path/to/vcpkg
")
endif()
#
# 3. Set VCPKG_TARGET_TRIPLET according to ANDROID_ABI
#
# There are four different Android ABI, each of which maps to
# a vcpkg triplet. The following table outlines the mapping from vcpkg architectures to android architectures
#
# |VCPKG_TARGET_TRIPLET | ANDROID_ABI |
# |---------------------------|----------------------|
# |arm64-android | arm64-v8a |
# |arm-android | armeabi-v7a |
# |x64-android | x86_64 |
# |x86-android | x86 |
#
# The variable must be stored in the cache in order to successfully the two toolchains.
#
if (ANDROID_ABI MATCHES "arm64-v8a")
set(VCPKG_TARGET_TRIPLET "arm64-android" CACHE STRING "" FORCE)
elseif(ANDROID_ABI MATCHES "armeabi-v7a")
set(VCPKG_TARGET_TRIPLET "arm-android" CACHE STRING "" FORCE)
elseif(ANDROID_ABI MATCHES "x86_64")
set(VCPKG_TARGET_TRIPLET "x64-android" CACHE STRING "" FORCE)
elseif(ANDROID_ABI MATCHES "x86")
set(VCPKG_TARGET_TRIPLET "x86-android" CACHE STRING "" FORCE)
else()
message(FATAL_ERROR "
Please specify ANDROID_ABI
For example
cmake ... -DANDROID_ABI=armeabi-v7a
Possible ABIs are: arm64-v8a, armeabi-v7a, x64-android, x86-android
")
endif()
message("vcpkg_android.cmake: VCPKG_TARGET_TRIPLET was set to ${VCPKG_TARGET_TRIPLET}")
#
# 4. Combine vcpkg and Android toolchains
#
# vcpkg and android both provide dedicated toolchains:
#
# vcpkg_toolchain_file=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake
# android_toolchain_file=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake
#
# When using vcpkg, the vcpkg toolchain shall be specified first.
# However, vcpkg provides a way to preload and additional toolchain,
# with the VCPKG_CHAINLOAD_TOOLCHAIN_FILE option.
set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE $ENV{ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake)
set(CMAKE_TOOLCHAIN_FILE $ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake)
message("vcpkg_android.cmake: CMAKE_TOOLCHAIN_FILE was set to ${CMAKE_TOOLCHAIN_FILE}")
message("vcpkg_android.cmake: VCPKG_CHAINLOAD_TOOLCHAIN_FILE was set to ${VCPKG_CHAINLOAD_TOOLCHAIN_FILE}")
endif(VCPKG_TARGET_ANDROID)
+7
View File
@@ -17,6 +17,9 @@
***************************************************************************** *****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/ */
#ifdef __ANDROID__
#include <log/log.h>
#endif
#include "ih264_typedefs.h" #include "ih264_typedefs.h"
#include "ih264_macros.h" #include "ih264_macros.h"
#include "ih264_platform_macros.h" #include "ih264_platform_macros.h"
@@ -899,6 +902,10 @@ WORD32 ih264d_read_mmco_commands(struct _DecStruct * ps_dec)
{ {
if (j >= MAX_REF_BUFS) if (j >= MAX_REF_BUFS)
{ {
#ifdef __ANDROID__
ALOGE("b/25818142");
android_errorWriteLog(0x534e4554, "25818142");
#endif
ps_dpb_cmds->u1_num_of_commands = 0; ps_dpb_cmds->u1_num_of_commands = 0;
return -1; return -1;
} }
+20 -41
View File
@@ -18,8 +18,6 @@ elseif(UNIX)
VK_USE_PLATFORM_MACOS_MVK VK_USE_PLATFORM_MACOS_MVK
VK_USE_PLATFORM_METAL_EXT VK_USE_PLATFORM_METAL_EXT
) )
elseif(ANDROID)
add_compile_definitions(VK_USE_PLATFORM_ANDROID_KHR)
else() else()
add_compile_definitions( add_compile_definitions(
VK_USE_PLATFORM_XLIB_KHR # legacy. Do we need to support XLIB surfaces? VK_USE_PLATFORM_XLIB_KHR # legacy. Do we need to support XLIB surfaces?
@@ -42,11 +40,7 @@ add_compile_definitions(VK_NO_PROTOTYPES)
set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_subdirectory(Common) add_subdirectory(Common)
if(ANDROID) add_subdirectory(gui)
add_subdirectory(android/app/src/main/cpp)
else()
add_subdirectory(gui)
endif()
add_subdirectory(Cafe) add_subdirectory(Cafe)
add_subdirectory(Cemu) add_subdirectory(Cemu)
add_subdirectory(config) add_subdirectory(config)
@@ -57,34 +51,28 @@ add_subdirectory(imgui)
add_subdirectory(resource) add_subdirectory(resource)
add_subdirectory(asm) add_subdirectory(asm)
if(ANDROID) add_executable(CemuBin
add_library(CemuBin STATIC main.cpp
main.cpp mainLLE.cpp
mainLLE.cpp )
)
else()
add_executable(CemuBin
main.cpp
mainLLE.cpp
)
if(MSVC AND MSVC_VERSION EQUAL 1940) if(MSVC AND MSVC_VERSION EQUAL 1940)
# workaround for an msvc issue on VS 17.10 where generated ILK files are too large # workaround for an msvc issue on VS 17.10 where generated ILK files are too large
# see https://developercommunity.visualstudio.com/t/After-updating-to-VS-1710-the-size-of-/10665511 # see https://developercommunity.visualstudio.com/t/After-updating-to-VS-1710-the-size-of-/10665511
set_target_properties(CemuBin PROPERTIES LINK_FLAGS "/INCREMENTAL:NO") set_target_properties(CemuBin PROPERTIES LINK_FLAGS "/INCREMENTAL:NO")
endif() endif()
if(WIN32) if(WIN32)
target_sources(CemuBin PRIVATE target_sources(CemuBin PRIVATE
resource/cemu.rc resource/cemu.rc
../dist/windows/cemu.manifest ../dist/windows/cemu.manifest
) )
endif()
set_property(TARGET CemuBin PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
set_property(TARGET CemuBin PROPERTY WIN32_EXECUTABLE $<NOT:$<CONFIG:Debug>>)
set(OUTPUT_NAME "Cemu_$<LOWER_CASE:$<CONFIG>>")
endif() endif()
set_property(TARGET CemuBin PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
set_property(TARGET CemuBin PROPERTY WIN32_EXECUTABLE $<NOT:$<CONFIG:Debug>>)
set(OUTPUT_NAME "Cemu_$<LOWER_CASE:$<CONFIG>>")
if (MACOS_BUNDLE) if (MACOS_BUNDLE)
set_property(TARGET CemuBin PROPERTY MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/resource/MacOSXBundleInfo.plist.in") set_property(TARGET CemuBin PROPERTY MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/resource/MacOSXBundleInfo.plist.in")
@@ -134,22 +122,13 @@ target_link_libraries(CemuBin PRIVATE
CemuCommon CemuCommon
CemuComponents CemuComponents
CemuConfig CemuConfig
CemuGui
CemuInput CemuInput
CemuUtil CemuUtil
OpenGL::GL
SDL2::SDL2
) )
if(NOT ANDROID)
target_link_libraries(CemuBin PRIVATE CemuGui)
endif()
if(ENABLE_OPENGL)
target_link_libraries(CemuBin PRIVATE OpenGL::GL)
endif()
if(ENABLE_SDL)
target_link_libraries(CemuBin PRIVATE SDL2::SDL2)
endif()
if(UNIX AND NOT APPLE) if(UNIX AND NOT APPLE)
# due to nasm output some linkers will make stack executable # due to nasm output some linkers will make stack executable
# cemu does not require this so we explicity disable it # cemu does not require this so we explicity disable it
+17 -41
View File
@@ -67,23 +67,24 @@ add_library(CemuCafe
HW/Espresso/Recompiler/PPCFunctionBoundaryTracker.h HW/Espresso/Recompiler/PPCFunctionBoundaryTracker.h
HW/Espresso/Recompiler/PPCRecompiler.cpp HW/Espresso/Recompiler/PPCRecompiler.cpp
HW/Espresso/Recompiler/PPCRecompiler.h HW/Espresso/Recompiler/PPCRecompiler.h
HW/Espresso/Recompiler/RecompilerTests.cpp HW/Espresso/Recompiler/PPCRecompilerImlAnalyzer.cpp
HW/Espresso/Recompiler/IML/IML.h
HW/Espresso/Recompiler/IML/IMLSegment.cpp
HW/Espresso/Recompiler/IML/IMLSegment.h
HW/Espresso/Recompiler/IML/IMLInstruction.cpp
HW/Espresso/Recompiler/IML/IMLInstruction.h
HW/Espresso/Recompiler/IML/IMLDebug.cpp
HW/Espresso/Recompiler/IML/IMLAnalyzer.cpp
HW/Espresso/Recompiler/IML/IMLOptimizer.cpp
HW/Espresso/Recompiler/IML/IMLRegisterAllocator.cpp
HW/Espresso/Recompiler/IML/IMLRegisterAllocator.h
HW/Espresso/Recompiler/IML/IMLRegisterAllocatorRanges.cpp
HW/Espresso/Recompiler/IML/IMLRegisterAllocatorRanges.h
HW/Espresso/Recompiler/PPCRecompilerImlGen.cpp HW/Espresso/Recompiler/PPCRecompilerImlGen.cpp
HW/Espresso/Recompiler/PPCRecompilerImlGenFPU.cpp HW/Espresso/Recompiler/PPCRecompilerImlGenFPU.cpp
HW/Espresso/Recompiler/PPCRecompilerIml.h HW/Espresso/Recompiler/PPCRecompilerIml.h
HW/Espresso/Recompiler/PPCRecompilerImlOptimizer.cpp
HW/Espresso/Recompiler/PPCRecompilerImlRanges.cpp
HW/Espresso/Recompiler/PPCRecompilerImlRanges.h
HW/Espresso/Recompiler/PPCRecompilerImlRegisterAllocator2.cpp
HW/Espresso/Recompiler/PPCRecompilerImlRegisterAllocator.cpp
HW/Espresso/Recompiler/PPCRecompilerIntermediate.cpp HW/Espresso/Recompiler/PPCRecompilerIntermediate.cpp
HW/Espresso/Recompiler/PPCRecompilerX64AVX.cpp
HW/Espresso/Recompiler/PPCRecompilerX64BMI.cpp
HW/Espresso/Recompiler/PPCRecompilerX64.cpp
HW/Espresso/Recompiler/PPCRecompilerX64FPU.cpp
HW/Espresso/Recompiler/PPCRecompilerX64Gen.cpp
HW/Espresso/Recompiler/PPCRecompilerX64GenFPU.cpp
HW/Espresso/Recompiler/PPCRecompilerX64.h
HW/Espresso/Recompiler/x64Emit.hpp
HW/Latte/Common/RegisterSerializer.cpp HW/Latte/Common/RegisterSerializer.cpp
HW/Latte/Common/RegisterSerializer.h HW/Latte/Common/RegisterSerializer.h
HW/Latte/Common/ShaderSerializer.cpp HW/Latte/Common/ShaderSerializer.cpp
@@ -521,36 +522,10 @@ add_library(CemuCafe
TitleList/TitleList.h TitleList/TitleList.h
) )
if(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(X86)|(amd64)|(AMD64)")
target_sources(CemuCafe PRIVATE
HW/Espresso/Recompiler/BackendX64/BackendX64AVX.cpp
HW/Espresso/Recompiler/BackendX64/BackendX64BMI.cpp
HW/Espresso/Recompiler/BackendX64/BackendX64.cpp
HW/Espresso/Recompiler/BackendX64/BackendX64FPU.cpp
HW/Espresso/Recompiler/BackendX64/BackendX64Gen.cpp
HW/Espresso/Recompiler/BackendX64/BackendX64GenFPU.cpp
HW/Espresso/Recompiler/BackendX64/BackendX64.h
HW/Espresso/Recompiler/BackendX64/X64Emit.hpp
HW/Espresso/Recompiler/BackendX64/x86Emitter.h
)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(aarch64)|(AARCH64)")
target_sources(CemuCafe PRIVATE
HW/Espresso/Recompiler/BackendAArch64/BackendAArch64.cpp
HW/Espresso/Recompiler/BackendAArch64/BackendAArch64.h
)
endif()
if(APPLE) if(APPLE)
target_sources(CemuCafe PRIVATE "HW/Latte/Renderer/Vulkan/CocoaSurface.mm") target_sources(CemuCafe PRIVATE "HW/Latte/Renderer/Vulkan/CocoaSurface.mm")
endif() endif()
if(ANDROID)
target_sources(CemuCafe PRIVATE
Filesystem/fscDeviceAndroidSAF.cpp
Filesystem/fscDeviceAndroidSAF.h
)
endif()
set_property(TARGET CemuCafe PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") set_property(TARGET CemuCafe PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
target_include_directories(CemuCafe PUBLIC "../") target_include_directories(CemuCafe PUBLIC "../")
@@ -561,6 +536,7 @@ target_link_libraries(CemuCafe PRIVATE
CemuCommon CemuCommon
CemuComponents CemuComponents
CemuConfig CemuConfig
CemuGui
CemuInput CemuInput
CemuResource CemuResource
CemuUtil CemuUtil
@@ -596,8 +572,8 @@ if (ENABLE_NSYSHID_LIBUSB)
endif () endif ()
endif () endif ()
if(CMAKE_SYSTEM_PROCESSOR MATCHES "(aarch64)|(AARCH64)") if (ENABLE_WXWIDGETS)
target_link_libraries(CemuCafe PRIVATE xbyak_aarch64) target_link_libraries(CemuCafe PRIVATE wx::base wx::core)
endif() endif()
if(WIN32) if(WIN32)
+11 -27
View File
@@ -1,4 +1,5 @@
#include "Cafe/OS/common/OSCommon.h" #include "Cafe/OS/common/OSCommon.h"
#include "gui/wxgui.h"
#include "Cafe/OS/libs/gx2/GX2.h" #include "Cafe/OS/libs/gx2/GX2.h"
#include "Cafe/GameProfile/GameProfile.h" #include "Cafe/GameProfile/GameProfile.h"
#include "Cafe/HW/Espresso/Interpreter/PPCInterpreterInternal.h" #include "Cafe/HW/Espresso/Interpreter/PPCInterpreterInternal.h"
@@ -63,6 +64,9 @@
// HW interfaces // HW interfaces
#include "Cafe/HW/SI/si.h" #include "Cafe/HW/SI/si.h"
// dependency to be removed
#include "gui/guiWrapper.h"
#include <time.h> #include <time.h>
#if BOOST_OS_LINUX #if BOOST_OS_LINUX
@@ -167,7 +171,7 @@ void LoadMainExecutable()
applicationRPX = RPLLoader_LoadFromMemory(rpxData, rpxSize, (char*)_pathToExecutable.c_str()); applicationRPX = RPLLoader_LoadFromMemory(rpxData, rpxSize, (char*)_pathToExecutable.c_str());
if (!applicationRPX) if (!applicationRPX)
{ {
cemuLog_log(LogType::Force, "Failed to run this title because the executable is damaged"); wxMessageBox(_("Failed to run this title because the executable is damaged"));
cemuLog_createLogFile(false); cemuLog_createLogFile(false);
cemuLog_waitForFlush(); cemuLog_waitForFlush();
exit(0); exit(0);
@@ -352,9 +356,7 @@ uint32 LoadSharedData()
void cemu_initForGame() void cemu_initForGame()
{ {
auto cafeSystemCallbacks = CafeSystem::getCafeSystemCallbacks(); gui_updateWindowTitles(false, true, 0.0);
if (cafeSystemCallbacks)
cafeSystemCallbacks->updateWindowTitles(false, true, 0.0);
// input manager apply game profile // input manager apply game profile
InputManager::instance().apply_game_profile(); InputManager::instance().apply_game_profile();
// log info for launched title // log info for launched title
@@ -424,20 +426,6 @@ void cemu_initForGame()
namespace CafeSystem namespace CafeSystem
{ {
CafeSystemCallbacks* sCafeSystemCallbacks = nullptr;
void registerCafeSystemCallbacks(CafeSystemCallbacks* cafeSystemCallbacks)
{
sCafeSystemCallbacks = cafeSystemCallbacks;
}
void unregisterCafeSystemCallbacks()
{
sCafeSystemCallbacks = nullptr;
}
CafeSystemCallbacks* getCafeSystemCallbacks()
{
return sCafeSystemCallbacks;
}
void InitVirtualMlcStorage(); void InitVirtualMlcStorage();
void MlcStorageMountTitle(TitleInfo& titleInfo); void MlcStorageMountTitle(TitleInfo& titleInfo);
void MlcStorageUnmountAllTitles(); void MlcStorageUnmountAllTitles();
@@ -518,9 +506,7 @@ namespace CafeSystem
{ {
std::string buffer; std::string buffer;
const char* platform = NULL; const char* platform = NULL;
#if __ANDROID__ #if BOOST_OS_WINDOWS
platform = "Android";
#elif BOOST_OS_WINDOWS
uint32 buildNumber; uint32 buildNumber;
std::string windowsVersionName = GetWindowsNamedVersion(buildNumber); std::string windowsVersionName = GetWindowsNamedVersion(buildNumber);
buffer = fmt::format("{} (Build {})", windowsVersionName, buildNumber); buffer = fmt::format("{} (Build {})", windowsVersionName, buildNumber);
@@ -819,10 +805,10 @@ namespace CafeSystem
// check for content folder // check for content folder
fs::path contentPath = executablePath.parent_path().parent_path().append("content"); fs::path contentPath = executablePath.parent_path().parent_path().append("content");
std::error_code ec; std::error_code ec;
if (cemu::fs::is_directory(contentPath, ec)) if (fs::is_directory(contentPath, ec))
{ {
// mounting content folder // mounting content folder
bool r = FSCDeviceHost_Mount(std::string("/vol/content").c_str(), _pathToUtf8(contentPath), FSC_PRIORITY_BASE); bool r = FSCDeviceHostFS_Mount(std::string("/vol/content").c_str(), _pathToUtf8(contentPath), FSC_PRIORITY_BASE);
if (!r) if (!r)
{ {
cemuLog_log(LogType::Force, "Failed to mount {}", _pathToUtf8(contentPath)); cemuLog_log(LogType::Force, "Failed to mount {}", _pathToUtf8(contentPath));
@@ -831,7 +817,7 @@ namespace CafeSystem
} }
} }
// mount code folder to a virtual temporary path // mount code folder to a virtual temporary path
FSCDeviceHost_Mount(std::string("/internal/code/").c_str(), _pathToUtf8(executablePath.parent_path()), FSC_PRIORITY_BASE); FSCDeviceHostFS_Mount(std::string("/internal/code/").c_str(), _pathToUtf8(executablePath.parent_path()), FSC_PRIORITY_BASE);
std::string internalExecutablePath = "/internal/code/"; std::string internalExecutablePath = "/internal/code/";
internalExecutablePath.append(_pathToUtf8(executablePath.filename())); internalExecutablePath.append(_pathToUtf8(executablePath.filename()));
_pathToExecutable = internalExecutablePath; _pathToExecutable = internalExecutablePath;
@@ -868,9 +854,7 @@ namespace CafeSystem
PPCTimer_waitForInit(); PPCTimer_waitForInit();
// start system // start system
sSystemRunning = true; sSystemRunning = true;
auto cafeSystemCallbacks = CafeSystem::getCafeSystemCallbacks(); gui_notifyGameLoaded();
if (cafeSystemCallbacks)
cafeSystemCallbacks->notifyGameLoaded();
std::thread t(_LaunchTitleThread); std::thread t(_LaunchTitleThread);
t.detach(); t.detach();
} }
-11
View File
@@ -23,17 +23,6 @@ namespace CafeSystem
//BAD_META_DATA, - the title list only stores titles with valid meta, so this error code is impossible //BAD_META_DATA, - the title list only stores titles with valid meta, so this error code is impossible
}; };
class CafeSystemCallbacks
{
public:
virtual void updateWindowTitles(bool isIdle, bool isLoading, double fps) = 0;
virtual void notifyGameLoaded() = 0;
};
void registerCafeSystemCallbacks(CafeSystemCallbacks* cafeSystemCallbacks);
void unregisterCafeSystemCallbacks();
CafeSystemCallbacks* getCafeSystemCallbacks();
void Initialize(); void Initialize();
void SetImplementation(SystemImplementation* impl); void SetImplementation(SystemImplementation* impl);
void Shutdown(); void Shutdown();
+5 -2
View File
@@ -1,4 +1,6 @@
#include <wx/msgdlg.h>
#include <mutex> #include <mutex>
#include <gui/helpers/wxHelpers.h>
#include "config/ActiveSettings.h" #include "config/ActiveSettings.h"
#include "util/crypto/aes128.h" #include "util/crypto/aes128.h"
@@ -73,7 +75,7 @@ void KeyCache_Prepare()
} }
else else
{ {
cemuLog_log(LogType::Force, "Unable to create file keys.txt\nThis can happen if Cemu does not have write permission to it's own directory, the disk is full or if anti-virus software is blocking Cemu."); wxMessageBox(_("Unable to create file keys.txt\nThis can happen if Cemu does not have write permission to its own directory, the disk is full or if anti-virus software is blocking Cemu."), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
} }
mtxKeyCache.unlock(); mtxKeyCache.unlock();
return; return;
@@ -106,7 +108,8 @@ void KeyCache_Prepare()
continue; continue;
if( strishex(line) == false ) if( strishex(line) == false )
{ {
cemuLog_log(LogType::Force, "rror in keys.txt in line {}", lineNumber); auto errorMsg = formatWxString(_("Error in keys.txt at line {}"), lineNumber);
wxMessageBox(errorMsg, _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
continue; continue;
} }
if(line.size() == 32 ) if(line.size() == 32 )
-15
View File
@@ -213,18 +213,3 @@ bool FSCDeviceHostFS_Mount(std::string_view mountPath, std::string_view hostTarg
// redirect device // redirect device
void fscDeviceRedirect_map(); void fscDeviceRedirect_map();
void fscDeviceRedirect_add(std::string_view virtualSourcePath, size_t fileSize, const fs::path& targetFilePath, sint32 priority); void fscDeviceRedirect_add(std::string_view virtualSourcePath, size_t fileSize, const fs::path& targetFilePath, sint32 priority);
#if __ANDROID__
#include "Common/unix/FilesystemAndroid.h"
bool FSCDeviceAndroidSAF_Mount(std::string_view mountPath, std::string_view hostTargetPath, sint32 priority);
#endif // __ANDROID__
inline bool FSCDeviceHost_Mount(std::string_view mountPath, std::string_view hostTargetPath, sint32 priority)
{
#if __ANDROID__
if (FilesystemAndroid::isContentUri(std::string(hostTargetPath)))
return FSCDeviceAndroidSAF_Mount(mountPath, hostTargetPath, priority);
else
#endif // __ANDROID__
return FSCDeviceHostFS_Mount(mountPath, hostTargetPath, priority);
}
-235
View File
@@ -1,235 +0,0 @@
#include "Cafe/Filesystem/fscDeviceAndroidSAF.h"
#include <memory>
#include <stdexcept>
#include "Cafe/Filesystem/fsc.h"
#include "Common/FileStream.h"
#include "Common/unix/FilesystemAndroid.h"
FSCVirtualFile_AndroidSAF::~FSCVirtualFile_AndroidSAF()
{
if (m_type == FSC_TYPE_FILE)
delete m_fs;
}
sint32 FSCVirtualFile_AndroidSAF::fscGetType()
{
return m_type;
}
uint32 FSCVirtualFile_AndroidSAF::fscDeviceAndroidSAFFSFile_getFileSize()
{
if (m_type == FSC_TYPE_FILE)
{
if (m_fileSize > 0xFFFFFFFFULL)
cemu_assert_suspicious(); // files larger than 4GB are not supported by Wii U filesystem
return (uint32)m_fileSize;
}
return 0;
}
uint64 FSCVirtualFile_AndroidSAF::fscQueryValueU64(uint32 id)
{
if (m_type == FSC_TYPE_FILE)
{
if (id == FSC_QUERY_SIZE)
return fscDeviceAndroidSAFFSFile_getFileSize();
else if (id == FSC_QUERY_WRITEABLE)
return m_isWritable;
else
cemu_assert_unimplemented();
}
else if (m_type == FSC_TYPE_DIRECTORY)
{
if (id == FSC_QUERY_SIZE)
return fscDeviceAndroidSAFFSFile_getFileSize();
else
cemu_assert_unimplemented();
}
cemu_assert_unimplemented();
return 0;
}
uint32 FSCVirtualFile_AndroidSAF::fscWriteData(void* buffer, uint32 size)
{
throw std::logic_error("write not supported with SAF");
return 0;
}
uint32 FSCVirtualFile_AndroidSAF::fscReadData(void* buffer, uint32 size)
{
if (m_type != FSC_TYPE_FILE)
return 0;
if (size >= (2UL * 1024UL * 1024UL * 1024UL))
{
cemu_assert_suspicious();
return 0;
}
uint32 bytesLeft = (uint32)(m_fileSize - m_seek);
bytesLeft = std::min(bytesLeft, 0x7FFFFFFFu);
sint32 bytesToRead = std::min(bytesLeft, size);
uint32 bytesRead = m_fs->readData(buffer, bytesToRead);
m_seek += bytesRead;
return bytesRead;
}
void FSCVirtualFile_AndroidSAF::fscSetSeek(uint64 seek)
{
if (m_type != FSC_TYPE_FILE)
return;
this->m_seek = seek;
cemu_assert_debug(seek <= m_fileSize);
m_fs->SetPosition(seek);
}
uint64 FSCVirtualFile_AndroidSAF::fscGetSeek()
{
if (m_type != FSC_TYPE_FILE)
return 0;
return m_seek;
}
void FSCVirtualFile_AndroidSAF::fscSetFileLength(uint64 endOffset)
{
if (m_type != FSC_TYPE_FILE)
return;
m_fs->SetPosition(endOffset);
bool r = m_fs->SetEndOfFile();
m_seek = std::min(m_seek, endOffset);
m_fileSize = m_seek;
m_fs->SetPosition(m_seek);
if (!r)
cemuLog_log(LogType::Force, "fscSetFileLength: Failed to set size to 0x{:x}", endOffset);
}
bool FSCVirtualFile_AndroidSAF::fscDirNext(FSCDirEntry* dirEntry)
{
if (m_type != FSC_TYPE_DIRECTORY)
return false;
if (!m_files)
{
// init iterator on first iteration attempt
m_files = std::make_unique<std::vector<fs::path>>(FilesystemAndroid::listFiles(*m_path));
m_filesIterator = m_files->begin();
if (!m_files)
{
cemuLog_log(LogType::Force, "Failed to iterate directory: {}", _pathToUtf8(*m_path));
return false;
}
}
if (m_filesIterator == m_files->end())
return false;
const fs::path& file = *m_filesIterator;
std::string fileName = file.filename().generic_string();
if (fileName.size() >= sizeof(dirEntry->path) - 1)
fileName.resize(sizeof(dirEntry->path) - 1);
strncpy(dirEntry->path, fileName.data(), sizeof(dirEntry->path));
if (FilesystemAndroid::isDirectory(file))
{
dirEntry->isDirectory = true;
dirEntry->isFile = false;
dirEntry->fileSize = 0;
}
else
{
dirEntry->isDirectory = false;
dirEntry->isFile = true;
dirEntry->fileSize = 0;
auto fs = FileStream::openFile2(file);
if (fs)
{
dirEntry->fileSize = fs->GetSize();
delete fs;
}
}
m_filesIterator++;
return true;
}
FSCVirtualFile* FSCVirtualFile_AndroidSAF::OpenFile(const fs::path& path, FSC_ACCESS_FLAG accessFlags, sint32& fscStatus)
{
if (!HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_FILE) && !HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_DIR))
cemu_assert_debug(false); // not allowed. At least one of both flags must be set
if (HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::WRITE_PERMISSION) ||
HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::FILE_ALLOW_CREATE) ||
HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::FILE_ALWAYS_CREATE))
throw std::logic_error("writing and creating a file is not supported with SAF");
// attempt to open as file
if (HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_FILE))
{
FileStream* fs = FileStream::openFile2(path);
if (fs)
{
FSCVirtualFile_AndroidSAF* vf = new FSCVirtualFile_AndroidSAF(FSC_TYPE_FILE);
vf->m_fs = fs;
vf->m_isWritable = false;
vf->m_fileSize = fs->GetSize();
fscStatus = FSC_STATUS_OK;
return vf;
}
}
// attempt to open as directory
if (HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_DIR))
{
bool isExistingDir = FilesystemAndroid::exists(path);
if (isExistingDir)
{
FSCVirtualFile_AndroidSAF* vf = new FSCVirtualFile_AndroidSAF(FSC_TYPE_DIRECTORY);
vf->m_path.reset(new std::filesystem::path(path));
fscStatus = FSC_STATUS_OK;
return vf;
}
}
fscStatus = FSC_STATUS_FILE_NOT_FOUND;
return nullptr;
}
/* Device implementation */
class fscDeviceAndroidSAFFSC : public fscDeviceC
{
public:
FSCVirtualFile* fscDeviceOpenByPath(std::string_view path, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) override
{
*fscStatus = FSC_STATUS_OK;
FSCVirtualFile* vf = FSCVirtualFile_AndroidSAF::OpenFile(_utf8ToPath(path), accessFlags, *fscStatus);
cemu_assert_debug((bool)vf == (*fscStatus == FSC_STATUS_OK));
return vf;
}
bool fscDeviceCreateDir(std::string_view path, void* ctx, sint32* fscStatus) override
{
throw std::logic_error("creating a directory is not supported with SAF");
return false;
}
bool fscDeviceRemoveFileOrDir(std::string_view path, void* ctx, sint32* fscStatus) override
{
throw std::logic_error("removing a file or dir is not supported with SAF");
return false;
}
bool fscDeviceRename(std::string_view srcPath, std::string_view dstPath, void* ctx, sint32* fscStatus) override
{
throw std::logic_error("renaming not supported with SAF");
return false;
}
// singleton
public:
static fscDeviceAndroidSAFFSC& instance()
{
static fscDeviceAndroidSAFFSC _instance;
return _instance;
}
};
bool FSCDeviceAndroidSAF_Mount(std::string_view mountPath, std::string_view hostTargetPath, sint32 priority)
{
return fsc_mount(mountPath, hostTargetPath, &fscDeviceAndroidSAFFSC::instance(), nullptr, priority) == FSC_STATUS_OK;
}
-36
View File
@@ -1,36 +0,0 @@
#pragma once
#include "Cafe/Filesystem/fsc.h"
class FSCVirtualFile_AndroidSAF : public FSCVirtualFile
{
public:
static FSCVirtualFile* OpenFile(const fs::path& path, FSC_ACCESS_FLAG accessFlags, sint32& fscStatus);
~FSCVirtualFile_AndroidSAF() override;
sint32 fscGetType() override;
uint32 fscDeviceAndroidSAFFSFile_getFileSize();
uint64 fscQueryValueU64(uint32 id) override;
uint32 fscWriteData(void* buffer, uint32 size) override;
uint32 fscReadData(void* buffer, uint32 size) override;
void fscSetSeek(uint64 seek) override;
uint64 fscGetSeek() override;
void fscSetFileLength(uint64 endOffset) override;
bool fscDirNext(FSCDirEntry* dirEntry) override;
private:
FSCVirtualFile_AndroidSAF(uint32 type) : m_type(type){};
uint32 m_type; // FSC_TYPE_*
class FileStream* m_fs{};
// file
uint64 m_seek{0};
uint64 m_fileSize{0};
bool m_isWritable{false};
// directory
std::unique_ptr<fs::path> m_path{};
std::unique_ptr<std::vector<fs::path>> m_files{};
std::vector<fs::path>::iterator m_filesIterator;
};
+13 -7
View File
@@ -5,6 +5,9 @@
#include "Cafe/OS/RPL/rpl_structs.h" #include "Cafe/OS/RPL/rpl_structs.h"
#include "boost/algorithm/string.hpp" #include "boost/algorithm/string.hpp"
#include "gui/wxgui.h" // for wxMessageBox
#include "gui/helpers/wxHelpers.h"
// error handler // error handler
void PatchErrorHandler::printError(class PatchGroup* patchGroup, sint32 lineNumber, std::string_view errorMsg) void PatchErrorHandler::printError(class PatchGroup* patchGroup, sint32 lineNumber, std::string_view errorMsg)
{ {
@@ -37,13 +40,13 @@ void PatchErrorHandler::printError(class PatchGroup* patchGroup, sint32 lineNumb
void PatchErrorHandler::showStageErrorMessageBox() void PatchErrorHandler::showStageErrorMessageBox()
{ {
std::string errorMsg; wxString errorMsg;
if (m_gp) if (m_gp)
{ {
if (m_stage == STAGE::PARSER) if (m_stage == STAGE::PARSER)
errorMsg = fmt::format("Failed to load patches for graphic pack \'{}\'", m_gp->GetName()); errorMsg.assign(formatWxString(_("Failed to load patches for graphic pack \'{}\'"), m_gp->GetName()));
else else
errorMsg = fmt::format("Failed to apply patches for graphic pack \'{}\'", m_gp->GetName()); errorMsg.assign(formatWxString(_("Failed to apply patches for graphic pack \'{}\'"), m_gp->GetName()));
} }
else else
{ {
@@ -51,14 +54,17 @@ void PatchErrorHandler::showStageErrorMessageBox()
} }
if (cemuLog_isLoggingEnabled(LogType::Patches)) if (cemuLog_isLoggingEnabled(LogType::Patches))
{ {
errorMsg += "\n\nDetails:\n"; errorMsg.append("\n \n")
.append(_("Details:"))
.append("\n");
for (auto& itr : errorMessages) for (auto& itr : errorMessages)
{ {
errorMsg += itr; errorMsg.append(itr);
errorMsg += "\n"; errorMsg.append("\n");
} }
} }
cemuLog_log(LogType::Force, "Graphic pack error: {}", errorMsg);
wxMessageBox(errorMsg, _("Graphic pack error"));
} }
// loads Cemu-style patches (patch_<anything>.asm) // loads Cemu-style patches (patch_<anything>.asm)

Some files were not shown because too many files have changed in this diff Show More