diff --git a/Assets/dll/librcheevos.dll b/Assets/dll/librcheevos.dll index ea41b748df..578e6cf83f 100644 Binary files a/Assets/dll/librcheevos.dll and b/Assets/dll/librcheevos.dll differ diff --git a/Assets/dll/librcheevos.so b/Assets/dll/librcheevos.so index 3a7c5bc20e..6477f4e879 100644 Binary files a/Assets/dll/librcheevos.so and b/Assets/dll/librcheevos.so differ diff --git a/ExternalProjects/librcheevos/.gitignore b/ExternalProjects/librcheevos/.gitignore new file mode 100644 index 0000000000..3722ac63ca --- /dev/null +++ b/ExternalProjects/librcheevos/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/ExternalProjects/librcheevos/CMakeLists.txt b/ExternalProjects/librcheevos/CMakeLists.txt new file mode 100644 index 0000000000..e0a3690d7a --- /dev/null +++ b/ExternalProjects/librcheevos/CMakeLists.txt @@ -0,0 +1,136 @@ +cmake_minimum_required(VERSION 3.12 FATAL_ERROR) + +if(POLICY CMP0092) + cmake_policy(SET CMP0092 NEW) +endif() + +project(rcheevos C) + +set(CMAKE_C_STANDARD 90) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS OFF) + +if(MSVC) + # silence dumb warnings over CRT functions be "unsafe" + add_compile_definitions(_CRT_SECURE_NO_WARNINGS) + + # MSVC targets don't export all symbols unless this is on + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) + + # max warnings, treat as errors + add_compile_options(/W4) + add_compile_options(/WX) + + # ignore some warnings + # this differs between clang-cl and cl + if(CMAKE_C_COMPILER_ID MATCHES "Clang") + add_compile_options( + -Wno-missing-field-initializers + -Wno-unused-parameter + -Wno-null-pointer-subtraction + ) + else() + add_compile_options( + /wd4100 # "unreferenced formal parameter" + /wd4701 # "potentially uninitialized local variable used" (detection here is just faulty) + ) + endif() + + # all files are utf8 + add_compile_options(/utf-8) + + # max conformance mode + add_compile_options(/permissive-) + add_compile_options(/volatile:iso) + add_compile_options(/fp:precise) + + # cmake will not insert a lib prefix for libraries on MSVC targets + set(RC_TARGET librcheevos) +else() + # max warnings, treat as errors + add_compile_options(-Wall -Wextra) + add_compile_options(-Werror) + + # ignore some warnings + add_compile_options( + -Wno-missing-field-initializers + -Wno-unused-parameter + -Wno-null-pointer-subtraction + -Wno-implicit-fallthrough + -Wno-array-bounds # interestingly this warning isn't triggered with lto active, it's likely just a false positive when there isn't lto + ) + + # strip in release, optimize for gdb usage in debug + add_link_options($<$:-s>) + add_compile_options($<$:-ggdb>) + + # use lld for clang (needed if doing lto) + if(CMAKE_C_COMPILER_ID MATCHES "Clang") + add_link_options(-fuse-ld=lld) + endif() + + # cmake will insert a lib prefix for libraries on non-MSVC targets + set(RC_TARGET rcheevos) +endif() + +set(RC_RAPI_DIR ${CMAKE_SOURCE_DIR}/rcheevos/src/rapi) +set(RC_RCHEEVOS_DIR ${CMAKE_SOURCE_DIR}/rcheevos/src/rcheevos) +set(RC_RHASH_DIR ${CMAKE_SOURCE_DIR}/rcheevos/src/rhash) +set(RC_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/rcheevos/include) + +add_library( + ${RC_TARGET} + SHARED + ${RC_RAPI_DIR}/rc_api_common.c + ${RC_RAPI_DIR}/rc_api_common.h + ${RC_RAPI_DIR}/rc_api_editor.c + ${RC_RAPI_DIR}/rc_api_info.c + ${RC_RAPI_DIR}/rc_api_runtime.c + ${RC_RAPI_DIR}/rc_api_user.c + ${RC_RCHEEVOS_DIR}/alloc.c + ${RC_RCHEEVOS_DIR}/compat.c + ${RC_RCHEEVOS_DIR}/condition.c + ${RC_RCHEEVOS_DIR}/condset.c + ${RC_RCHEEVOS_DIR}/consoleinfo.c + ${RC_RCHEEVOS_DIR}/format.c + ${RC_RCHEEVOS_DIR}/lboard.c + ${RC_RCHEEVOS_DIR}/memref.c + ${RC_RCHEEVOS_DIR}/operand.c + ${RC_RCHEEVOS_DIR}/rc_compat.h + ${RC_RCHEEVOS_DIR}/rc_internal.h + ${RC_RCHEEVOS_DIR}/rc_validate.c + ${RC_RCHEEVOS_DIR}/rc_validate.h + ${RC_RCHEEVOS_DIR}/richpresence.c + ${RC_RCHEEVOS_DIR}/runtime.c + ${RC_RCHEEVOS_DIR}/runtime_progress.c + ${RC_RCHEEVOS_DIR}/trigger.c + ${RC_RCHEEVOS_DIR}/value.c + ${RC_RHASH_DIR}/cdreader.c + ${RC_RHASH_DIR}/hash.c + ${RC_RHASH_DIR}/md5.c + ${RC_RHASH_DIR}/md5.h + ${RC_INCLUDE_DIR}/rc_api_editor.h + ${RC_INCLUDE_DIR}/rc_api_info.h + ${RC_INCLUDE_DIR}/rc_api_request.h + ${RC_INCLUDE_DIR}/rc_api_runtime.h + ${RC_INCLUDE_DIR}/rc_api_user.h + ${RC_INCLUDE_DIR}/rc_consoles.h + ${RC_INCLUDE_DIR}/rc_error.h + ${RC_INCLUDE_DIR}/rc_hash.h + ${RC_INCLUDE_DIR}/rc_runtime.h + ${RC_INCLUDE_DIR}/rc_runtime_types.h + ${RC_INCLUDE_DIR}/rc_url.h + ${RC_INCLUDE_DIR}/rcheevos.h +) + +target_compile_definitions(${RC_TARGET} PRIVATE -DRC_DISABLE_LUA) +target_include_directories(${RC_TARGET} PRIVATE ${RC_INCLUDE_DIR}) + +add_custom_command( + TARGET ${RC_TARGET} + POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS -E copy $ ${CMAKE_SOURCE_DIR}/../../Assets/dll + COMMAND ${CMAKE_COMMAND} + ARGS -E copy $ ${CMAKE_SOURCE_DIR}/../../output/dll +) diff --git a/ExternalProjects/librcheevos/build_debug.bat b/ExternalProjects/librcheevos/build_debug.bat new file mode 100644 index 0000000000..7707e36a85 --- /dev/null +++ b/ExternalProjects/librcheevos/build_debug.bat @@ -0,0 +1,6 @@ +rmdir /s /q build +mkdir build +cd build +cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=clang-cl -G Ninja +ninja +cd .. diff --git a/ExternalProjects/librcheevos/build_debug.sh b/ExternalProjects/librcheevos/build_debug.sh new file mode 100644 index 0000000000..4441cff9e4 --- /dev/null +++ b/ExternalProjects/librcheevos/build_debug.sh @@ -0,0 +1,6 @@ +#!/bin/sh +rm -rf build +mkdir build +cd build +cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=clang -G Ninja +ninja diff --git a/ExternalProjects/librcheevos/build_release.bat b/ExternalProjects/librcheevos/build_release.bat new file mode 100644 index 0000000000..bb115070c6 --- /dev/null +++ b/ExternalProjects/librcheevos/build_release.bat @@ -0,0 +1,6 @@ +rmdir /s /q build +mkdir build +cd build +cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=TRUE -DCMAKE_C_COMPILER=clang-cl -G Ninja +ninja +cd .. diff --git a/ExternalProjects/librcheevos/build_release.sh b/ExternalProjects/librcheevos/build_release.sh new file mode 100644 index 0000000000..ff3b380109 --- /dev/null +++ b/ExternalProjects/librcheevos/build_release.sh @@ -0,0 +1,6 @@ +#!/bin/sh +rm -rf build +mkdir build +cd build +cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=TRUE -DCMAKE_C_COMPILER=clang -G Ninja +ninja diff --git a/ExternalProjects/librcheevos/rcheevos b/ExternalProjects/librcheevos/rcheevos index 165d1a3b18..f0a5f96e10 160000 --- a/ExternalProjects/librcheevos/rcheevos +++ b/ExternalProjects/librcheevos/rcheevos @@ -1 +1 @@ -Subproject commit 165d1a3b189c472c4547ac385e59be2f527e688e +Subproject commit f0a5f96e10c2c6167af8bda24fdbf2c23ecaa01d diff --git a/src/BizHawk.Client.EmuHawk/RetroAchievements/RetroAchievements.ConsoleID.cs b/src/BizHawk.Client.EmuHawk/RetroAchievements/RetroAchievements.ConsoleID.cs index b67645d2f0..11d1c98fe0 100644 --- a/src/BizHawk.Client.EmuHawk/RetroAchievements/RetroAchievements.ConsoleID.cs +++ b/src/BizHawk.Client.EmuHawk/RetroAchievements/RetroAchievements.ConsoleID.cs @@ -1,6 +1,7 @@ using BizHawk.Emulation.Common; using BizHawk.Emulation.Cores.Atari.Jaguar; using BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy; +using BizHawk.Emulation.Cores.Consoles.Nintendo.NDS; using BizHawk.Emulation.Cores.Consoles.Sega.gpgx; using BizHawk.Emulation.Cores.Consoles.Sega.PicoDrive; using BizHawk.Emulation.Cores.Nintendo.SNES; @@ -89,6 +90,7 @@ namespace BizHawk.Client.EmuHawk ElektorTVGamesComputer = 75, PCEngineCD = 76, JaguarCD = 77, + DSi = 78, NumConsoleIDs } @@ -127,6 +129,7 @@ namespace BizHawk.Client.EmuHawk VSystemID.Raw.Lynx => ConsoleID.Lynx, VSystemID.Raw.MSX => ConsoleID.MSX, VSystemID.Raw.N64 => ConsoleID.N64, + VSystemID.Raw.NDS when Emu is NDS { IsDSi: true } => ConsoleID.DSi, VSystemID.Raw.NDS => ConsoleID.DS, VSystemID.Raw.NeoGeoCD => ConsoleID.NeoGeoCD, VSystemID.Raw.NES => ConsoleID.NES, diff --git a/src/BizHawk.Client.EmuHawk/RetroAchievements/RetroAchievements.GameVerification.cs b/src/BizHawk.Client.EmuHawk/RetroAchievements/RetroAchievements.GameVerification.cs index 250cccde7d..66dea84cfa 100644 --- a/src/BizHawk.Client.EmuHawk/RetroAchievements/RetroAchievements.GameVerification.cs +++ b/src/BizHawk.Client.EmuHawk/RetroAchievements/RetroAchievements.GameVerification.cs @@ -19,7 +19,7 @@ namespace BizHawk.Client.EmuHawk private int? HashDisc(string path, ConsoleID consoleID, int discCount) { // this shouldn't throw in practice, this is only called when loading was successful! - using var disc = DiscExtensions.CreateAnyType(path, e => throw new Exception(e)); + using var disc = DiscExtensions.CreateAnyType(path, e => throw new(e)); var dsr = new DiscSectorReader(disc) { Policy = { DeterministicClearBuffer = false } // let's make this a little faster @@ -107,16 +107,19 @@ namespace BizHawk.Client.EmuHawk dsr.ReadLBA_2048(sector, buf2048, 0); exePath = Encoding.ASCII.GetString(buf2048); - // "BOOT = cdrom:\" or "BOOT = cdrom:" precedes the path - var index = exePath.IndexOf("BOOT = cdrom:\\"); - if (index < 0) index = exePath.IndexOf("BOOT = cdrom:") - 1; + // "BOOT = cdrom:" precedes the path + var index = exePath.IndexOf("BOOT = cdrom:"); if (index < -1) break; - exePath = exePath.Remove(0, index + 14); + exePath = exePath.Remove(0, index + 13); + + // the path might start with a number of slashes, remove these + index = 0; + while (index < exePath.Length && exePath[index] is '\\') index++; // end of the path has ; var end = exePath.IndexOf(';'); if (end < 0) break; - exePath = exePath.Substring(0, end); + exePath = exePath.Substring(index, end - index); } buffer.AddRange(Encoding.ASCII.GetBytes(exePath));