diff --git a/CMakeLists.txt b/CMakeLists.txt index 7078bd37c5..14a281184a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -699,8 +699,6 @@ endif() add_subdirectory(Externals/imgui) add_subdirectory(Externals/implot) add_subdirectory(Externals/glslang) -add_subdirectory(Externals/SlippiLib) -include_directories(Externals/SlippiLib) include_directories(Externals/nlohmann) add_subdirectory(Externals/semver) include_directories(Externals/semver/include) @@ -795,6 +793,8 @@ endif() add_subdirectory(Externals/zlib-ng) +find_package(ZLIB REQUIRED) + pkg_check_modules(MINIZIP minizip>=3.0.0) if(MINIZIP_FOUND) message(STATUS "Using shared minizip") diff --git a/Externals/SlippiLib/CMakeLists.txt b/Externals/SlippiLib/CMakeLists.txt deleted file mode 100644 index 2bb64cc7c9..0000000000 --- a/Externals/SlippiLib/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -project(SlippiLib - VERSION 1.0.0) - -set(SRCS - SlippiGame.h - SlippiGame.cpp -) -cmake_minimum_required(VERSION 3.10 FATAL_ERROR) - -set(CMAKE_CXX_STANDARD 17) -add_definitions(-std=c++17) - -if(NOT MSVC) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wno-unused-parameter") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-unused-parameter") -endif() - -add_library(SlippiLib STATIC ${SRCS}) - diff --git a/Externals/imgui/imgui_widgets.cpp b/Externals/imgui/imgui_widgets.cpp index 5e3cca6333..7da069b6be 100644 --- a/Externals/imgui/imgui_widgets.cpp +++ b/Externals/imgui/imgui_widgets.cpp @@ -2712,9 +2712,6 @@ float ImGui::ScaleRatioFromValueT(ImGuiDataType data_type, TYPE v, TYPE v_min, T return (float)((FLOATTYPE)(SIGNEDTYPE)(v_clamped - v_min) / (FLOATTYPE)(SIGNEDTYPE)(v_max - v_min)); } -template float ImGui::SliderCalcRatioFromValueT(ImGuiDataType, int, int, int, float, float); - -// FIXME: Move some of the code into SliderBehavior(). Current responsability is larger than what the equivalent DragBehaviorT<> does, we also do some rendering, etc. // Convert a parametric position on a slider into a value v in the output space (the logical opposite of ScaleRatioFromValueT) template TYPE ImGui::ScaleValueFromRatioT(ImGuiDataType data_type, float t, TYPE v_min, TYPE v_max, bool is_logarithmic, float logarithmic_zero_epsilon, float zero_deadzone_halfsize) diff --git a/Externals/open-vcdiff/CMakeLists.txt b/Externals/open-vcdiff/CMakeLists.txt index a600499a92..fd80b0fc60 100644 --- a/Externals/open-vcdiff/CMakeLists.txt +++ b/Externals/open-vcdiff/CMakeLists.txt @@ -70,7 +70,7 @@ set (VCDCOM_SRC "src/unique_ptr.h" "src/varint_bigendian.h" "src/vcdiff_defs.h" - "src/zlib/zlib.h" + "src/zlib/zlib_old.h" "src/zlib/zconf.h" "src/zlib/adler32.c" "src/addrcache.cc" @@ -128,12 +128,17 @@ if (BUILD_STATIC_LIBS) add_library (vcdcom ALIAS vcdcom_STATIC) add_library (vcddec ALIAS vcddec_STATIC) add_library (vcdenc ALIAS vcdenc_STATIC) + target_compile_options(vcdcom_STATIC PRIVATE -w) + target_compile_options(vcddec_STATIC PRIVATE -w) + target_compile_options(vcdenc_STATIC PRIVATE -w) else () add_library (vcdcom ALIAS vcdcom_SHARED) add_library (vcddec ALIAS vcddec_SHARED) add_library (vcdenc ALIAS vcdenc_SHARED) endif() + + if (vcdiff_build_exec) add_executable (vcdiff "src/vcdiff_main.cc") target_link_libraries (vcdiff vcddec vcdenc gflags) diff --git a/Externals/open-vcdiff/src/checksum.h b/Externals/open-vcdiff/src/checksum.h index 3e1350e0b2..9a5658b49a 100644 --- a/Externals/open-vcdiff/src/checksum.h +++ b/Externals/open-vcdiff/src/checksum.h @@ -19,7 +19,7 @@ #define OPEN_VCDIFF_CHECKSUM_H_ #include "config.h" -#include "zlib/zlib.h" +#include "zlib/zlib_old.h" #ifdef __MINGW32__ #include @@ -33,7 +33,7 @@ const VCDChecksum kNoPartialChecksum = 0; inline VCDChecksum ComputeAdler32(const char* buffer, size_t size) { - return adler32(kNoPartialChecksum, + return adler32_old(kNoPartialChecksum, reinterpret_cast(buffer), static_cast(size)); } @@ -41,7 +41,7 @@ inline VCDChecksum ComputeAdler32(const char* buffer, inline VCDChecksum UpdateAdler32(VCDChecksum partial_checksum, const char* buffer, size_t size) { - return adler32(partial_checksum, + return adler32_old(partial_checksum, reinterpret_cast(buffer), static_cast(size)); } diff --git a/Externals/open-vcdiff/src/zlib/adler32.c b/Externals/open-vcdiff/src/zlib/adler32.c index b8f37bb447..ab8efe14d6 100644 --- a/Externals/open-vcdiff/src/zlib/adler32.c +++ b/Externals/open-vcdiff/src/zlib/adler32.c @@ -6,7 +6,7 @@ /* @(#) $Id$ */ #define ZLIB_INTERNAL -#include "zlib.h" +#include "zlib_old.h" #define BASE 65521UL /* largest prime smaller than 65536 */ #define NMAX 5552 @@ -94,7 +94,7 @@ void ZEXPORT adler32_range(min, max) *max = ((BASE-1) << 16) | (BASE-1); } -uLong ZEXPORT adler32(adler, buf, len) +uLong ZEXPORT adler32_old(adler, buf, len) uLong adler; const Bytef *buf; uInt len; @@ -165,7 +165,7 @@ uLong ZEXPORT adler32(adler, buf, len) } /* ========================================================================= */ -uLong ZEXPORT adler32_combine(adler1, adler2, len2) +uLong ZEXPORT adler32_combine_old(adler1, adler2, len2) uLong adler1; uLong adler2; z_off_t len2; diff --git a/Externals/open-vcdiff/src/zlib/zlib.h b/Externals/open-vcdiff/src/zlib/zlib_old.h similarity index 99% rename from Externals/open-vcdiff/src/zlib/zlib.h rename to Externals/open-vcdiff/src/zlib/zlib_old.h index 6f64b988ea..02f4b2fe9d 100644 --- a/Externals/open-vcdiff/src/zlib/zlib.h +++ b/Externals/open-vcdiff/src/zlib/zlib_old.h @@ -28,6 +28,8 @@ (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). */ +#pragma once + #ifndef ZLIB_H #define ZLIB_H @@ -1260,7 +1262,7 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); compression library. */ -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +ZEXTERN uLong ZEXPORT adler32_old OF((uLong adler, const Bytef *buf, uInt len)); /* Update a running Adler-32 checksum with the bytes buf[0..len-1] and return the updated checksum. If buf is NULL, this function returns @@ -1289,7 +1291,7 @@ ZEXTERN void ZEXPORT adler32_range OF((uLong* min, uLong* max)); software. */ -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, +ZEXTERN uLong ZEXPORT adler32_combine_old OF((uLong adler1, uLong adler2, z_off_t len2)); /* Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 diff --git a/Source/.clang-format b/Source/.clang-format index 2262cdaa26..52c446cc13 100644 --- a/Source/.clang-format +++ b/Source/.clang-format @@ -78,7 +78,6 @@ SpacesInContainerLiterals: true SpacesInCStyleCastParentheses: false SpacesInParentheses: false SpacesInSquareBrackets: false -Standard: Latest TabWidth: 2 UseTab: Never --- diff --git a/Source/Core/Common/FileUtil.cpp b/Source/Core/Common/FileUtil.cpp index 74daae72a3..ce5f64675f 100644 --- a/Source/Core/Common/FileUtil.cpp +++ b/Source/Core/Common/FileUtil.cpp @@ -924,7 +924,6 @@ static void RebuildUserDirectories(unsigned int dir_index) s_user_paths[F_ARAMDUMP_IDX] = s_user_paths[D_DUMP_IDX] + ARAM_DUMP; s_user_paths[F_FAKEVMEMDUMP_IDX] = s_user_paths[D_DUMP_IDX] + FAKEVMEM_DUMP; s_user_paths[F_GCSRAM_IDX] = s_user_paths[D_GCUSER_IDX] + GC_SRAM; - s_user_paths[F_WIISDCARD_IDX] = s_user_paths[D_WIIROOT_IDX] + DIR_SEP WII_SDCARD; s_user_paths[F_USERJSON_IDX] = s_user_paths[D_SLIPPI_IDX] + USER_JSON; s_user_paths[F_WIISDCARDIMAGE_IDX] = s_user_paths[D_LOAD_IDX] + WII_SD_CARD_IMAGE; diff --git a/Source/Core/Common/IOFile.cpp b/Source/Core/Common/IOFile.cpp index a70dfdbd81..cf7762ea68 100644 --- a/Source/Core/Common/IOFile.cpp +++ b/Source/Core/Common/IOFile.cpp @@ -41,12 +41,6 @@ IOFile::IOFile(const std::string& filename, const char openmode[], SharedAccess Open(filename, openmode, sh); } -IOFile::IOFile(const std::string& filename, const char openmode[], int shflag) - : m_file(nullptr), m_good(true) -{ - OpenShared(filename, openmode, shflag); -} - IOFile::~IOFile() { Close(); @@ -98,19 +92,6 @@ bool IOFile::Open(const std::string& filename, const char openmode[], return m_good; } -bool IOFile::OpenShared(const std::string& filename, const char openmode[], int shflag) -{ - Close(); -#ifdef _WIN32 - m_file = _fsopen(filename.c_str(), openmode, shflag); -#else - m_file = fopen(filename.c_str(), openmode); -#endif - - m_good = IsOpen(); - return m_good; -} - bool IOFile::Close() { if (!IsOpen() || 0 != std::fclose(m_file)) diff --git a/Source/Core/Common/IOFile.h b/Source/Core/Common/IOFile.h index eb65ebf51b..eab0f08cb6 100644 --- a/Source/Core/Common/IOFile.h +++ b/Source/Core/Common/IOFile.h @@ -34,7 +34,6 @@ class IOFile public: IOFile(); IOFile(std::FILE* file); - IOFile(const std::string& filename, const char openmode[]); IOFile(const std::string& filename, const char openmode[], SharedAccess sh = SharedAccess::Default); @@ -48,8 +47,6 @@ public: void Swap(IOFile& other) noexcept; - bool Open(const std::string& filename, const char openmode[]); - bool Open(const std::string& filename, const char openmode[], SharedAccess sh = SharedAccess::Default); diff --git a/Source/Core/Common/Version.cpp b/Source/Core/Common/Version.cpp index 08449d7128..db9d9ed133 100644 --- a/Source/Core/Common/Version.cpp +++ b/Source/Core/Common/Version.cpp @@ -18,13 +18,15 @@ namespace Common #endif #ifndef IS_PLAYBACK -#define SLIPPI_REV_STR "2.4.0" // netplay version +#define SLIPPI_REV_STR "2.4.0" // netplay version #else -#define SLIPPI_REV_STR "2.4.1" // playback version +#define SLIPPI_REV_STR "2.4.1" // playback version #endif -const std::string& GetSemVerStr() { - return SLIPPI_REV_STR; +const std::string& GetSemVerStr() +{ + static const std::string sem_ver_str = SLIPPI_REV_STR; + return sem_ver_str; } const std::string& GetScmRevStr() @@ -32,7 +34,8 @@ const std::string& GetScmRevStr() #ifndef IS_PLAYBACK static const std::string scm_rev_str = "Mainline - Slippi (" SLIPPI_REV_STR ")" BUILD_TYPE_STR; #else - static const std::string scm_rev_str = "Mainline - Slippi (" SLIPPI_REV_STR ") - Playback" BUILD_TYPE_STR; + static const std::string scm_rev_str = + "Mainline - Slippi (" SLIPPI_REV_STR ") - Playback" BUILD_TYPE_STR; #endif return scm_rev_str; } diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index 974d197289..e34e12469b 100644 --- a/Source/Core/Core/CMakeLists.txt +++ b/Source/Core/Core/CMakeLists.txt @@ -530,6 +530,8 @@ add_library(core Slippi/SlippiSpectate.h Slippi/SlippiUser.cpp Slippi/SlippiUser.h + Slippi/SlippiGame.cpp + Slippi/SlippiGame.h Slippi/SlippiGameReporter.cpp Slippi/SlippiGameReporter.h Slippi/SlippiDirectCodes.cpp @@ -644,11 +646,9 @@ PUBLIC videoogl videosoftware semver - SlippiLib vcdcom vcddec vcdenc - z PRIVATE FatFs diff --git a/Source/Core/Core/ConfigManager.h b/Source/Core/Core/ConfigManager.h index 786625e5c5..0807bfbe40 100644 --- a/Source/Core/Core/ConfigManager.h +++ b/Source/Core/Core/ConfigManager.h @@ -13,6 +13,7 @@ #include "Common/Common.h" #include "Common/CommonTypes.h" +#include "Slippi/SlippiConfig.h" class IniFile; @@ -39,6 +40,9 @@ struct BootParameters; struct SConfig { + // Melee Version + Melee::Version m_melee_version; + // Settings bool bAutomaticStart = false; bool bBootToPause = false; @@ -51,8 +55,10 @@ struct SConfig bool bWii = false; bool m_is_mios = false; - // SLIPPITODO: MOVE THESE + // SLIPPITODO: MOVE SOME OF THESE TO Config/Config.h // enable Slippi Networking output + bool m_OCEnable = true; + float m_OCFactor = 1.0f; bool m_enableSpectator = true; int m_spectatorPort = 51441; std::string m_strSlippiInput = ""; diff --git a/Source/Core/Core/GeckoCode.cpp b/Source/Core/Core/GeckoCode.cpp index ba3ff8fa47..68da24c356 100644 --- a/Source/Core/Core/GeckoCode.cpp +++ b/Source/Core/Core/GeckoCode.cpp @@ -189,7 +189,7 @@ static Installation InstallCodeHandlerLocked(const Core::CPUThreadGuard& guard) // Install bootloader gct for (size_t i = 0; i < bootloaderData.length(); ++i) - PowerPC::HostWrite_U8(bootloaderData[i], static_cast(codelist_base_address + i)); + PowerPC::HostWrite_U8(guard, bootloaderData[i], static_cast(codelist_base_address + i)); } else { @@ -223,8 +223,8 @@ static Installation InstallCodeHandlerLocked(const Core::CPUThreadGuard& guard) for (const GeckoCode::Code& code : active_code.codes) { - PowerPC::HostWrite_U32(code.address, next_address); - PowerPC::HostWrite_U32(code.data, next_address + 4); + PowerPC::HostWrite_U32(guard, code.address, next_address); + PowerPC::HostWrite_U32(guard, code.data, next_address + 4); next_address += CODE_SIZE; } } @@ -233,16 +233,13 @@ static Installation InstallCodeHandlerLocked(const Core::CPUThreadGuard& guard) end_address - start_address); // Stop code. Tells the handler that this is the end of the list. - PowerPC::HostWrite_U32(0xF0000000, next_address); - PowerPC::HostWrite_U32(0x00000000, next_address + 4); + PowerPC::HostWrite_U32(guard, 0xF0000000, next_address); + PowerPC::HostWrite_U32(guard, 0x00000000, next_address + 4); + WARN_LOG_FMT(ACTIONREPLAY, "GeckoCodes: Using {} of {} bytes", next_address - start_address, + end_address - start_address); } - WARN_LOG_FMT(ACTIONREPLAY, "GeckoCodes: Using {} of {} bytes", next_address - start_address, - end_address - start_address); - - // Stop code. Tells the handler that this is the end of the list. - PowerPC::HostWrite_U32(guard, 0xF0000000, next_address); - PowerPC::HostWrite_U32(guard, 0x00000000, next_address + 4); + // Write 0 to trampoline address, not sure why this is necessary PowerPC::HostWrite_U32(guard, 0, HLE_TRAMPOLINE_ADDRESS); // Turn on codes diff --git a/Source/Core/Core/HW/DVD/DVDThread.cpp b/Source/Core/Core/HW/DVD/DVDThread.cpp index 3ece13fac1..b7174c7e04 100644 --- a/Source/Core/Core/HW/DVD/DVDThread.cpp +++ b/Source/Core/Core/HW/DVD/DVDThread.cpp @@ -374,11 +374,12 @@ void DVDThread::ReadFile(std::string& fileName, std::vector& buf) } else { - INFO_LOG_FMT(SLIPPI, "Failed to open file: %s", fileName.c_str()); + INFO_LOG_FMT(SLIPPI, "Failed to open file: {}", fileName.c_str()); } } -std::string DVDThread::GetFileName(const DiscIO::Partition &partition, u64 offset) { +std::string DVDThread::GetFileName(const DiscIO::Partition& partition, u64 offset) +{ return m_disc->GetFileSystem(partition)->FindFileInfo(offset)->GetName(); } } // namespace DVD diff --git a/Source/Core/Core/HW/DVD/DVDThread.h b/Source/Core/Core/HW/DVD/DVDThread.h index 810acc8d80..22dd6095ce 100644 --- a/Source/Core/Core/HW/DVD/DVDThread.h +++ b/Source/Core/Core/HW/DVD/DVDThread.h @@ -6,10 +6,10 @@ #include #include #include +#include #include #include #include -#include #include "Common/CommonTypes.h" #include "Common/Event.h" #include "Common/Flag.h" @@ -85,6 +85,8 @@ public: void StartReadToEmulatedRAM(u32 output_address, u64 dvd_offset, u32 length, const DiscIO::Partition& partition, DVD::ReplyType reply_type, s64 ticks_until_completion); + // SLIPPINOTES: Used for checking if the MxDt.dat file exists + void ReadFile(std::string& fileName, std::vector& buf); private: void StartDVDThread(); @@ -99,9 +101,6 @@ private: void FinishRead(u64 id, s64 cycles_late); void DVDThreadMain(); - - // SLIPPINOTES: Used for checking if the MxDt.dat file exists - void ReadFile(std::string& fileName, std::vector& buf); std::string GetFileName(const DiscIO::Partition& partition, u64 offset); struct ReadRequest diff --git a/Source/Core/Core/HW/EXI/EXI_Device.cpp b/Source/Core/Core/HW/EXI/EXI_Device.cpp index 4f4ef304a9..cf3142dc5c 100644 --- a/Source/Core/Core/HW/EXI/EXI_Device.cpp +++ b/Source/Core/Core/HW/EXI/EXI_Device.cpp @@ -165,7 +165,7 @@ std::unique_ptr EXIDevice_Create(Core::System& system, const EXIDevi break; case EXIDeviceType::Slippi: - result = std::make_unique(); + result = std::make_unique(system); break; case EXIDeviceType::AMBaseboard: diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceSlippi.cpp b/Source/Core/Core/HW/EXI/EXI_DeviceSlippi.cpp index db2b39d4a5..283c633a92 100644 --- a/Source/Core/Core/HW/EXI/EXI_DeviceSlippi.cpp +++ b/Source/Core/Core/HW/EXI/EXI_DeviceSlippi.cpp @@ -8,7 +8,6 @@ #include "Common/CommonPaths.h" #include "Common/CommonTypes.h" - #include "Common/Logging/Log.h" #include "Common/MemoryUtil.h" #include "Common/MsgHandler.h" @@ -16,6 +15,7 @@ #include "Common/Thread.h" #include "Common/Version.h" +#include "Core/Config/MainSettings.h" #include "Core/ConfigManager.h" #include "Core/Core.h" #include "Core/CoreTiming.h" @@ -32,14 +32,15 @@ #include "Core/Slippi/SlippiPremadeText.h" #include "Core/Slippi/SlippiReplayComm.h" #include "Core/State.h" +#include "Core/System.h" #include "VideoCommon/OnScreenDisplay.h" #define FRAME_INTERVAL 900 #define SLEEP_TIME_MS 8 #define WRITE_FILE_SLEEP_TIME_MS 85 -//#define LOCAL_TESTING -//#define CREATE_DIFF_FILES +// #define LOCAL_TESTING +// #define CREATE_DIFF_FILES extern std::unique_ptr g_playbackStatus; extern std::unique_ptr g_replayComm; extern bool g_needInputForFrame; @@ -112,9 +113,9 @@ std::string ConvertConnectCodeForGame(const std::string& input) return connectCode; } -CEXISlippi::CEXISlippi() +CEXISlippi::CEXISlippi(Core::System& system) : IEXIDevice(system) { - INFO_LOG(SLIPPI, "EXI SLIPPI Constructor called."); + INFO_LOG_FMT(SLIPPI, "EXI SLIPPI Constructor called."); user = std::make_unique(); g_playbackStatus = std::make_unique(); @@ -125,7 +126,7 @@ CEXISlippi::CEXISlippi() directCodes = std::make_unique("direct-codes.json"); teamsCodes = std::make_unique("teams-codes.json"); - generator = std::default_random_engine(Common::Timer::GetTimeMs()); + generator = std::default_random_engine(Common::Timer::NowMs()); // Loggers will check 5 bytes, make sure we own that memory m_read_queue.reserve(5); @@ -405,7 +406,7 @@ void CEXISlippi::writeToFileAsync(u8* payload, u32 length, std::string fileOptio if (fileOption == "create" && !writeThreadRunning) { - WARN_LOG(SLIPPI, "Creating file write thread..."); + WARN_LOG_FMT(SLIPPI, "Creating file write thread..."); writeThreadRunning = true; m_fileWriteThread = std::thread(&CEXISlippi::FileWriteThread, this); } @@ -446,7 +447,7 @@ void CEXISlippi::writeToFile(std::unique_ptr msg) { if (!msg) { - ERROR_LOG(SLIPPI, "Unexpected error: write message is falsy."); + ERROR_LOG_FMT(SLIPPI, "Unexpected error: write message is falsy."); return; } @@ -518,7 +519,7 @@ void CEXISlippi::writeToFile(std::unique_ptr msg) bool result = m_file.WriteBytes(&dataToWrite[0], dataToWrite.size()); if (!result) { - ERROR_LOG(EXPANSIONINTERFACE, "Failed to write data to file."); + ERROR_LOG_FMT(EXPANSIONINTERFACE, "Failed to write data to file."); } // If file should be closed, close it @@ -526,7 +527,7 @@ void CEXISlippi::writeToFile(std::unique_ptr msg) { // Write the number of bytes for the raw output std::vector sizeBytes = uint32ToVector(writtenByteCount); - m_file.Seek(11, 0); + m_file.Seek(11, File::SeekOrigin::Begin); m_file.WriteBytes(&sizeBytes[0], sizeBytes.size()); // Close file @@ -579,22 +580,22 @@ void CEXISlippi::createNewFile() } std::string filepath = dirpath + DIR_SEP + generateFileName(); - INFO_LOG(SLIPPI, "EXI_DeviceSlippi.cpp: Creating new replay file %s", filepath.c_str()); + INFO_LOG_FMT(SLIPPI, "EXI_DeviceSlippi.cpp: Creating new replay file {}", filepath.c_str()); #ifdef _WIN32 - m_file = File::IOFile(filepath, "wb", _SH_DENYWR); + m_file = File::IOFile(filepath, "wb", File::SharedAccess::Read); #else m_file = File::IOFile(filepath, "wb"); #endif if (!m_file) { - PanicAlertFmtT("Could not create .slp replay file [%s].\n\n" - "The replay folder's path might be invalid, or you might " - "not have permission to write to it.\n\n" - "You can change the replay folder in Config > Slippi > " - "Slippi Replay Settings.", - filepath.c_str()); + PanicAlertFmtT("Could not create .slp replay file [{0}].\n\n" + "The replay folder's path might be invalid, or you might " + "not have permission to write to it.\n\n" + "You can change the replay folder in Config > Slippi > " + "Slippi Replay Settings.", + filepath); } } @@ -1152,7 +1153,7 @@ void CEXISlippi::prepareGeckoList() } std::vector source = settings->geckoCodes; - INFO_LOG(SLIPPI, "Booting codes with source size: %d", source.size()); + INFO_LOG_FMT(SLIPPI, "Booting codes with source size: {}", source.size()); int idx = 0; while (idx < source.size()) @@ -1192,8 +1193,8 @@ void CEXISlippi::prepareGeckoList() if (deny_list.count(address)) continue; - INFO_LOG(SLIPPI, "Codetype [%x] Inserting section: %d - %d (%x, %d)", codeType, - idx - codeOffset, idx, address, codeOffset); + INFO_LOG_FMT(SLIPPI, "Codetype [{:x}] Inserting section: {} - {} ({:x}, {})", codeType, + idx - codeOffset, idx, address, codeOffset); // If not blacklisted, add code to return vector geckoList.insert(geckoList.end(), source.begin() + (idx - codeOffset), source.begin() + idx); @@ -1226,7 +1227,7 @@ void CEXISlippi::prepareCharacterFrameData(Slippi::FrameData* frame, u8 port, u8 // << data.animation // << "\n"; - // WARN_LOG(EXPANSIONINTERFACE, "[Frame %d] [Player %d] Positions: %f | %f", frameIndex, port, + // WARN_LOG_FMT(EXPANSIONINTERFACE, "[Frame {}] [Player {}] Positions: %f | %f", frameIndex, port, // data.locationX, data.locationY); // Add all of the inputs in order @@ -1288,7 +1289,7 @@ void CEXISlippi::prepareFrameData(u8* payload) auto watchSettings = g_replayComm->current; if (frameIndex > watchSettings.endFrame) { - INFO_LOG(SLIPPI, "Killing game because we are past endFrame"); + INFO_LOG_FMT(SLIPPI, "Killing game because we are past endFrame"); m_read_queue.push_back(FRAME_RESP_TERMINATE); return; } @@ -1506,12 +1507,12 @@ void CEXISlippi::prepareIsFileReady() { // Do not start if replay file doesn't exist // TODO: maybe display error message? - INFO_LOG(SLIPPI, "EXI_DeviceSlippi.cpp: Replay file does not exist?"); + INFO_LOG_FMT(SLIPPI, "EXI_DeviceSlippi.cpp: Replay file does not exist?"); m_read_queue.push_back(0); return; } - INFO_LOG(SLIPPI, "EXI_DeviceSlippi.cpp: Replay file loaded successfully!?"); + INFO_LOG_FMT(SLIPPI, "EXI_DeviceSlippi.cpp: Replay file loaded successfully!?"); // Clear playback control related vars g_playbackStatus->resetPlayback(); @@ -1735,11 +1736,12 @@ bool CEXISlippi::shouldAdvanceOnlineFrame(s32 frame) } auto dynamicEmulationSpeed = 1.0f + deviation; - SConfig::GetInstance().m_EmulationSpeed = dynamicEmulationSpeed; - // SConfig::GetInstance().m_EmulationSpeed = 0.97f; // used for testing + Config::SetCurrent(Config::MAIN_EMULATION_SPEED, dynamicEmulationSpeed); + // SConfig::GetInstance().m_EmulationSpeed = dynamicEmulationSpeed; + // SConfig::GetInstance().m_EmulationSpeed = 0.97f; // used for testing - INFO_LOG(SLIPPI_ONLINE, "[Frame %d] Offset for advance is: %d us. New speed: %.2f%%", frame, - offsetUs, dynamicEmulationSpeed * 100.0f); + INFO_LOG_FMT(SLIPPI_ONLINE, "[Frame {}] Offset for advance is: {} us. New speed: {.4}%", frame, + offsetUs, dynamicEmulationSpeed * 100.0f); s32 frameTime = 16683; s32 t1 = 10000; @@ -1869,7 +1871,7 @@ void CEXISlippi::prepareOpponentInputs(s32 frame, bool shouldSkip) latestFrame = frame; latestFrameRead[i] = latestFrame; appendWordToBuffer(&m_read_queue, static_cast(latestFrame)); - // INFO_LOG(SLIPPI_ONLINE, "Sending frame num %d for pIdx %d (offset: %d)", latestFrame, i, + // INFO_LOG_FMT(SLIPPI_ONLINE, "Sending frame num {} for pIdx {} (offset: {})", latestFrame, i, // offset[i]); } // Send the current frame for any unused player slots. @@ -1900,7 +1902,7 @@ void CEXISlippi::prepareOpponentInputs(s32 frame, bool shouldSkip) m_read_queue.insert(m_read_queue.end(), tx.begin(), tx.end()); } - // ERROR_LOG(SLIPPI_ONLINE, "EXI: [%d] %X %X %X %X %X %X %X %X", latestFrame, m_read_queue[5], + // ERROR_LOG_FMT(SLIPPI_ONLINE, "EXI: [{}] %X %X %X %X %X %X %X %X", latestFrame, m_read_queue[5], // m_read_queue[6], m_read_queue[7], m_read_queue[8], m_read_queue[9], m_read_queue[10], // m_read_queue[11], m_read_queue[12]); } @@ -1939,8 +1941,8 @@ void CEXISlippi::handleCaptureSavestate(u8* payload) ss->Capture(); activeSavestates[frame] = std::move(ss); - // u32 timeDiff = (u32)(Common::Timer::GetTimeUs() - startTime); - // INFO_LOG(SLIPPI_ONLINE, "SLIPPI ONLINE: Captured savestate for frame %d in: %f ms", frame, + // u32 timeDiff = (u32)(Common::Timer::NowUs() - startTime); + // INFO_LOG_FMT(SLIPPI_ONLINE, "SLIPPI ONLINE: Captured savestate for frame {} in: %f ms", frame, // ((double)timeDiff) / 1000); } @@ -1980,8 +1982,8 @@ void CEXISlippi::handleLoadSavestate(u8* payload) activeSavestates.clear(); - // u32 timeDiff = (u32)(Common::Timer::GetTimeUs() - startTime); - // INFO_LOG(SLIPPI_ONLINE, "SLIPPI ONLINE: Loaded savestate for frame %d in: %f ms", frame, + // u32 timeDiff = (u32)(Common::Timer::NowUs() - startTime); + // INFO_LOG_FMT(SLIPPI_ONLINE, "SLIPPI ONLINE: Loaded savestate for frame {} in: %f ms", frame, // ((double)timeDiff) / 1000); } @@ -2070,7 +2072,7 @@ bool CEXISlippi::doesTagMatchInput(u8* input, u8 inputLen, std::string tag) bool isMatch = true; for (int i = 0; i < inputLen; i++) { - // ERROR_LOG(SLIPPI_ONLINE, "Entered: %X%X. History: %X%X", input[i * 3], input[i * 3 + 1], + // ERROR_LOG_FMT(SLIPPI_ONLINE, "Entered: %X%X. History: %X%X", input[i * 3], input[i * 3 + 1], // (u8)jisTag[i * 2], (u8)jisTag[i * 2 + 1]); if (input[i * 3] != (u8)jisTag[i * 2] || input[i * 3 + 1] != (u8)jisTag[i * 2 + 1]) { @@ -2421,7 +2423,7 @@ void CEXISlippi::prepareOnlineMatchState() // Check if someone is picking dumb characters in non-direct auto localCharOk = lps.characterId < 26; auto remoteCharOk = true; - INFO_LOG(SLIPPI_ONLINE, "remotePlayerCount: %d", remotePlayerCount); + INFO_LOG_FMT(SLIPPI_ONLINE, "remotePlayerCount: {}", remotePlayerCount); for (int i = 0; i < remotePlayerCount; i++) { if (rps[i].characterId >= 26) @@ -2497,7 +2499,7 @@ void CEXISlippi::prepareOnlineMatchState() // Set rng offset rngOffset = isDecider ? lps.rngOffset : rps[0].rngOffset; - INFO_LOG(SLIPPI_ONLINE, "Rng Offset: 0x%x", rngOffset); + INFO_LOG_FMT(SLIPPI_ONLINE, "Rng Offset: {:#x}", rngOffset); // Check if everyone is the same color auto color = orderedSelections[0].teamId; @@ -2726,8 +2728,8 @@ void CEXISlippi::setMatchSelections(u8* payload) s.stageId = getRandomStage(); } - INFO_LOG(SLIPPI, "LPS set char: %d, iSS: %d, %d, stage: %d, team: %d", s.isCharacterSelected, - stageSelectOption, s.isStageSelected, s.stageId, s.teamId); + INFO_LOG_FMT(SLIPPI, "LPS set char: {}, iSS: {}, {}, stage: {}, team: {}", s.isCharacterSelected, + stageSelectOption, s.isStageSelected, s.stageId, s.teamId); s.rngOffset = generator() % 0xFFFF; @@ -2749,7 +2751,7 @@ void CEXISlippi::prepareFileLength(u8* payload) std::string contents; u32 size = gameFileLoader->LoadFile(fileName, contents); - INFO_LOG(SLIPPI, "Getting file size for: %s -> %d", fileName.c_str(), size); + INFO_LOG_FMT(SLIPPI, "Getting file size for: {} -> {}", fileName.c_str(), size); // Write size to output appendWordToBuffer(&m_read_queue, size); @@ -2765,7 +2767,7 @@ void CEXISlippi::prepareFileLoad(u8* payload) u32 size = gameFileLoader->LoadFile(fileName, contents); std::vector buf(contents.begin(), contents.end()); - INFO_LOG(SLIPPI, "Writing file contents: %s -> %d", fileName.c_str(), size); + INFO_LOG_FMT(SLIPPI, "Writing file contents: {} -> {}", fileName.c_str(), size); // Write the contents to output m_read_queue.insert(m_read_queue.end(), buf.begin(), buf.end()); @@ -2777,7 +2779,7 @@ void CEXISlippi::prepareGctLength() u32 size = Gecko::GetGctLength(); - INFO_LOG(SLIPPI, "Getting gct size: %d", size); + INFO_LOG_FMT(SLIPPI, "Getting gct size: {}", size); // Write size to output appendWordToBuffer(&m_read_queue, size); @@ -2792,7 +2794,7 @@ void CEXISlippi::prepareGctLoad(u8* payload) // This is the address where the codes will be written to auto address = Common::swap32(&payload[0]); - INFO_LOG(SLIPPI, "Preparing to write gecko codes at: 0x%X", address); + INFO_LOG_FMT(SLIPPI, "Preparing to write gecko codes at: {:#x}", address); m_read_queue.insert(m_read_queue.end(), gct.begin(), gct.end()); } @@ -2883,7 +2885,7 @@ void CEXISlippi::handleChatMessage(u8* payload) return; int messageId = payload[0]; - INFO_LOG(SLIPPI, "SLIPPI CHAT INPUT: 0x%x", messageId); + INFO_LOG_FMT(SLIPPI, "SLIPPI CHAT INPUT: {:#x}", messageId); #ifdef LOCAL_TESTING localChatMessageId = 11; @@ -2902,15 +2904,16 @@ void CEXISlippi::handleChatMessage(u8* payload) void CEXISlippi::logMessageFromGame(u8* payload) { + // The first byte indicates whether to log the time or not if (payload[0] == 0) { - // The first byte indicates whether to log the time or not - GENERIC_LOG(Common::Log::SLIPPI, (Common::Log::LOG_LEVELS)payload[1], "%s", (char*)&payload[2]); + GENERIC_LOG_FMT(Common::Log::LogType::SLIPPI, (Common::Log::LogLevel)payload[1], "{}", + (char*)&payload[2]); } else { - GENERIC_LOG(Common::Log::SLIPPI, (Common::Log::LOG_LEVELS)payload[1], "%s: %llu", - (char*)&payload[2], Common::Timer::GetTimeUs()); + GENERIC_LOG_FMT(Common::Log::LogType::SLIPPI, (Common::Log::LogLevel)payload[1], "{}: {}", + (char*)&payload[2], Common::Timer::NowUs()); } } @@ -2944,7 +2947,7 @@ void CEXISlippi::prepareOnlineStatus() { // Check if we have the latest version, and if not, indicate we need to update version::Semver200_version latestVersion(userInfo.latest_version); - version::Semver200_version currentVersion(Common::scm_slippi_semver_str); + version::Semver200_version currentVersion(Common::GetSemVerStr()); appState = latestVersion > currentVersion ? 2 : 1; } @@ -2976,7 +2979,7 @@ void doConnectionCleanup(std::unique_ptr mm, void CEXISlippi::handleConnectionCleanup() { - ERROR_LOG(SLIPPI_ONLINE, "Connection cleanup started..."); + ERROR_LOG_FMT(SLIPPI_ONLINE, "Connection cleanup started..."); // Handle destructors in a separate thread to not block the main thread std::thread cleanup(doConnectionCleanup, std::move(matchmaking), std::move(slippi_netplay)); @@ -3004,7 +3007,7 @@ void CEXISlippi::handleConnectionCleanup() isLocalConnected = false; #endif - ERROR_LOG(SLIPPI_ONLINE, "Connection cleanup completed..."); + ERROR_LOG_FMT(SLIPPI_ONLINE, "Connection cleanup completed..."); } void CEXISlippi::prepareNewSeed() @@ -3022,7 +3025,7 @@ void CEXISlippi::handleReportGame(u8* payload) SlippiGameReporter::GameReport r; r.duration_frames = Common::swap32(&payload[0]); - // ERROR_LOG(SLIPPI_ONLINE, "Frames: %d", r.duration_frames); + // ERROR_LOG_FMT(SLIPPI_ONLINE, "Frames: {}", r.duration_frames); for (auto i = 0; i < 2; ++i) { @@ -3033,7 +3036,8 @@ void CEXISlippi::handleReportGame(u8* payload) auto swappedDamageDone = Common::swap32(&payload[6 + offset]); p.damage_done = *(float*)&swappedDamageDone; - // ERROR_LOG(SLIPPI_ONLINE, "Stocks: %d, DamageDone: %f", p.stocks_remaining, p.damage_done); + // ERROR_LOG_FMT(SLIPPI_ONLINE, "Stocks: {}, DamageDone: %f", p.stocks_remaining, + // p.damage_done); r.players.push_back(p); } @@ -3058,14 +3062,19 @@ void CEXISlippi::prepareDelayResponse() void CEXISlippi::DMAWrite(u32 _uAddr, u32 _uSize) { - u8* memPtr = Memory::GetPointer(_uAddr); + auto& system = Core::System::GetInstance(); + auto& memory = system.GetMemory(); + u8* memPtr = memory.GetPointer(_uAddr); u32 bufLoc = 0; if (memPtr == nullptr) { - NOTICE_LOG(SLIPPI, "DMA Write was passed an invalid address: %x", _uAddr); - Dolphin_Debugger::PrintCallstack(Common::Log::SLIPPI, Common::Log::LNOTICE); + ASSERT(Core::IsCPUThread()); + Core::CPUThreadGuard guard(system); + NOTICE_LOG_FMT(SLIPPI, "DMA Write was passed an invalid address: {:x}", _uAddr); + Dolphin_Debugger::PrintCallstack(system, guard, Common::Log::LogType::SLIPPI, + Common::Log::LogLevel::LNOTICE); m_read_queue.clear(); return; } @@ -3089,10 +3098,10 @@ void CEXISlippi::DMAWrite(u32 _uAddr, u32 _uSize) g_needInputForFrame = true; } - INFO_LOG(EXPANSIONINTERFACE, - "EXI SLIPPI DMAWrite: addr: 0x%08x size: %d, bufLoc:[%02x %02x %02x %02x %02x]", _uAddr, - _uSize, memPtr[bufLoc], memPtr[bufLoc + 1], memPtr[bufLoc + 2], memPtr[bufLoc + 3], - memPtr[bufLoc + 4]); + INFO_LOG_FMT(EXPANSIONINTERFACE, + "EXI SLIPPI DMAWrite: addr: {:#x} size: {}, bufLoc:[{} {} {} {} {}]", _uAddr, _uSize, + memPtr[bufLoc], memPtr[bufLoc + 1], memPtr[bufLoc + 2], memPtr[bufLoc + 3], + memPtr[bufLoc + 4]); while (bufLoc < _uSize) { @@ -3100,7 +3109,7 @@ void CEXISlippi::DMAWrite(u32 _uAddr, u32 _uSize) if (!payloadSizes.count(byte)) { // This should never happen. Do something else if it does? - WARN_LOG(EXPANSIONINTERFACE, "EXI SLIPPI: Invalid command byte: 0x%x", byte); + WARN_LOG_FMT(EXPANSIONINTERFACE, "EXI SLIPPI: Invalid command byte: {:#x}", byte); return; } @@ -3217,19 +3226,21 @@ void CEXISlippi::DMARead(u32 addr, u32 size) { if (m_read_queue.empty()) { - ERROR_LOG(SLIPPI, "EXI SLIPPI DMARead: Empty"); + ERROR_LOG_FMT(SLIPPI, "EXI SLIPPI DMARead: Empty"); return; } m_read_queue.resize(size, 0); // Resize response array to make sure it's all full/allocated auto queueAddr = &m_read_queue[0]; - INFO_LOG(EXPANSIONINTERFACE, - "EXI SLIPPI DMARead: addr: 0x%08x size: %d, startResp: [%02x %02x %02x %02x %02x]", addr, - size, queueAddr[0], queueAddr[1], queueAddr[2], queueAddr[3], queueAddr[4]); + INFO_LOG_FMT(EXPANSIONINTERFACE, + "EXI SLIPPI DMARead: addr: {:#x} size: {}, startResp: [{} {} {} {} {}]", addr, size, + queueAddr[0], queueAddr[1], queueAddr[2], queueAddr[3], queueAddr[4]); // Copy buffer data to memory - Memory::CopyToEmu(addr, queueAddr, size); + auto& system = Core::System::GetInstance(); + auto& memory = system.GetMemory(); + memory.CopyToEmu(addr, queueAddr, size); } bool CEXISlippi::IsPresent() const diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceSlippi.h b/Source/Core/Core/HW/EXI/EXI_DeviceSlippi.h index 6b0e4b826d..69d58de3dd 100644 --- a/Source/Core/Core/HW/EXI/EXI_DeviceSlippi.h +++ b/Source/Core/Core/HW/EXI/EXI_DeviceSlippi.h @@ -4,12 +4,11 @@ #pragma once -#include - #include "Common/CommonTypes.h" -#include "Common/File.h" #include "Common/FileUtil.h" +#include "Common/IOFile.h" #include "Core/Slippi/SlippiDirectCodes.h" +#include "Core/Slippi/SlippiGame.h" #include "Core/Slippi/SlippiGameFileLoader.h" #include "Core/Slippi/SlippiGameReporter.h" #include "Core/Slippi/SlippiMatchmaking.h" @@ -31,7 +30,7 @@ namespace ExpansionInterface class CEXISlippi : public IEXIDevice { public: - CEXISlippi(); + CEXISlippi(Core::System& system); virtual ~CEXISlippi(); void DMAWrite(u32 _uAddr, u32 _uSize) override; diff --git a/Source/Core/Core/HW/WiimoteEmu/Camera.cpp b/Source/Core/Core/HW/WiimoteEmu/Camera.cpp index fb79f12702..c4239c6872 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Camera.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Camera.cpp @@ -179,7 +179,7 @@ void CameraLogic::Update(const std::array& camera_point break; default: // This seems to be fairly common, 0xff data is sent in this case: - // WARN_LOG(WIIMOTE, "Game is requesting IR data before setting IR mode."); + // WARN_LOG_FMT(WIIMOTE, "Game is requesting IR data before setting IR mode."); break; } } diff --git a/Source/Core/Core/PowerPC/MMU.cpp b/Source/Core/Core/PowerPC/MMU.cpp index ddacf26bf3..9b9e334152 100644 --- a/Source/Core/Core/PowerPC/MMU.cpp +++ b/Source/Core/Core/PowerPC/MMU.cpp @@ -15,8 +15,8 @@ #include "Common/CommonTypes.h" #include "Common/Logging/Log.h" -#include "Core/Slippi/SlippiSavestate.h" #include "Core/ConfigManager.h" +#include "Core/Debugger/Debugger_SymbolMap.h" #include "Core/HW/CPU.h" #include "Core/HW/GPFifo.h" #include "Core/HW/MMIO.h" @@ -25,7 +25,7 @@ #include "Core/PowerPC/GDBStub.h" #include "Core/PowerPC/JitInterface.h" #include "Core/PowerPC/PowerPC.h" -#include "Core/Debugger/Debugger_SymbolMap.h" +#include "Core/Slippi/SlippiSavestate.h" #include "Core/System.h" #include "VideoCommon/VideoBackendBase.h" @@ -533,269 +533,268 @@ u32 HostRead_Instruction(const Core::CPUThreadGuard& guard, const u32 address) } // Taken from Ishii. SLIPPITODO: ask jas -//static void Memcheck(u32 address, u32 var, bool write, size_t size) +// static void Memcheck(u32 address, u32 var, bool write, size_t size) //{ - //********************************************************************* - //* How to test memory sections - //********************************************************************* - // 1. Uncomment once of the memory analysis blocks below - // 2. Start the application (release version is fine) - // 3. At a bp somewhere before where you want to start looking for mem access - // 4. Once hit, add a MBP in code section (something that will never get hit) - // and turn off JIT Core - // 5. Start the emulation again and memory accesses should get logged - // 6. Make sure you have logging enabled for MI memmap +//********************************************************************* +//* How to test memory sections +//********************************************************************* +// 1. Uncomment once of the memory analysis blocks below +// 2. Start the application (release version is fine) +// 3. At a bp somewhere before where you want to start looking for mem access +// 4. Once hit, add a MBP in code section (something that will never get hit) +// and turn off JIT Core +// 5. Start the emulation again and memory accesses should get logged +// 6. Make sure you have logging enabled for MI memmap - //********************************************************************* - //* Looking for heap writes? - //********************************************************************* - // if (!write || size != 4) - //{ - // return; - // } +//********************************************************************* +//* Looking for heap writes? +//********************************************************************* +// if (!write || size != 4) +//{ +// return; +// } - // static u32 heapStart = 0x80bd5c40; - // static u32 heapEnd = 0x811AD5A0; +// static u32 heapStart = 0x80bd5c40; +// static u32 heapEnd = 0x811AD5A0; - // static std::unordered_map visited; +// static std::unordered_map visited; - // // If we are writting to somewhere in heap, return - // if (address >= heapStart && address < heapEnd) - // return; +// // If we are writting to somewhere in heap, return +// if (address >= heapStart && address < heapEnd) +// return; - // // If we are not writting a pointer the somewhere in heap, return - // if (var < heapStart || var >= heapEnd) - // return; +// // If we are not writting a pointer the somewhere in heap, return +// if (var < heapStart || var >= heapEnd) +// return; - // if (visited.count(address)) - // return; +// if (visited.count(address)) +// return; - // visited[address] = true; - // ERROR_LOG(SLIPPI_ONLINE, "%x (%s) %x -> %x", PC, PowerPC::debug_interface.GetDescription(PC).c_str(), address, - // var); +// visited[address] = true; +// ERROR_LOG_FMT(SLIPPI_ONLINE, "%x (%s) %x -> %x", PC, +// PowerPC::debug_interface.GetDescription(PC).c_str(), address, var); - //********************************************************************* - //* Looking for camera player position memory - //********************************************************************* - // static std::unordered_map visited = {}; - // static std::unordered_map whitelist = { - // {"PlayerThink_CameraBehavior", true}, // Per-Player update camera position function - // {"CameraFunctionBlrl", true}, // Update camera position - //}; +//********************************************************************* +//* Looking for camera player position memory +//********************************************************************* +// static std::unordered_map visited = {}; +// static std::unordered_map whitelist = { +// {"PlayerThink_CameraBehavior", true}, // Per-Player update camera position function +// {"CameraFunctionBlrl", true}, // Update camera position +//}; - // static std::vector soundStuff = { - // - //}; +// static std::vector soundStuff = { +// +//}; - // auto sceneController = ReadFromHardware(0x80479d30); - // if ((sceneController & 0xFF0000FF) != 0x08000002) - //{ - // return; - //} - - // auto isLoading = ReadFromHardware(0x80479d64); - // if (isLoading) - //{ - // return; - //} - - // if (!write) - //{ - // return; - //} - - // if (address >= 0x804dec00 && address < 0x804eec00) - //{ - // return; - //} - - // if (visited.count(address)) - //{ - // return; - //} - - // visited[address] = true; - - // for (auto it = soundStuff.begin(); it != soundStuff.end(); ++it) - //{ - // if (address >= it->address && address < it->address + it->length) - // { - // return; - // } - //} - - // if ((address & 0xFF000000) == 0xcc000000) - //{ - // return; - //} - - // std::vector callstack; - // Dolphin_Debugger::GetCallstack(callstack); - - // bool isFound = false; - // for (auto it = callstack.begin(); it != callstack.end(); ++it) - //{ - // std::string func = PowerPC::debug_interface.GetDescription(it->vAddress).c_str(); - // if (whitelist.count(func)) - // { - // isFound = true; - // break; - // } - //} - - // if (!isFound) - //{ - // return; - //} - - // NOTICE_LOG(MEMMAP, "(%s) %x (%s) | %x (%x) <-> %x", write ? "Write" : "Read", PC, - // PowerPC::debug_interface.GetDescription(PC).c_str(), var, size, address); - - //********************************************************************* - //* Looking for sound memory - //********************************************************************* - // static std::unordered_map visited = {}; - // static std::unordered_map whitelist = { - // {"__AIDHandler", true}, // lol - // {"__AXOutAiCallback", true}, // lol - // {"__AXOutNewFrame", true}, // lol - // {"__AXSyncPBs", true}, // lol - // {"SFX_PlaySFX", true}, // lol - // {"__DSPHandler", true}, - //}; - - // static std::vector soundStuff = { - // {0x804031A0, 0x24}, // [804031A0 - 804031C4) - // {0x80407FB4, 0x34C}, // [80407FB4 - 80408300) - // {0x80433C64, 0x1EE80}, // [80433C64 - 80452AE4) - // {0x804A8D78, 0x17A68}, // [804A8D78 - 804C07E0) - // {0x804C28E0, 0x399C}, // [804C28E0 - 804C627C) - // {0x804D7474, 0x8}, // [804D7474 - 804D747C) - // {0x804D74F0, 0x50}, // [804D74F0 - 804D7540) - // {0x804D7548, 0x4}, // [804D7548 - 804D754C) - // {0x804D7558, 0x24}, // [804D7558 - 804D757C) - // {0x804D7580, 0xC}, // [804D7580 - 804D758C) - // {0x804D759C, 0x4}, // [804D759C - 804D75A0) - // {0x804D7720, 0x4}, // [804D7720 - 804D7724) - // {0x804D7744, 0x4}, // [804D7744 - 804D7748) - // {0x804D774C, 0x8}, // [804D774C - 804D7754) - // {0x804D7758, 0x8}, // [804D7758 - 804D7760) - // {0x804D7788, 0x10}, // [804D7788 - 804D7798) - // {0x804D77C8, 0x4}, // [804D77C8 - 804D77CC) - // {0x804D77D0, 0x4}, // [804D77D0 - 804D77D4) - // {0x804D77E0, 0x4}, // [804D77E0 - 804D77E4) - // {0x804DE358, 0x80}, // [804DE358 - 804DE3D8) - // {0x804DE800, 0x70}, // [804DE800 - 804DE870) - //}; - - // auto sceneController = ReadFromHardware(0x80479d30); - // if ((sceneController & 0xFF0000FF) != 0x08000002) - //{ - // return; - //} - - // auto isLoading = ReadFromHardware(0x80479d64); - // if (isLoading) - //{ - // return; - //} - - // if (address >= 0x804dec00) - //{ - // return; - //} - ////if (!write) - ////{ - //// return; - ////} - - // if (visited.count(address)) - //{ - // return; - //} - - // visited[address] = true; - - // for (auto it = soundStuff.begin(); it != soundStuff.end(); ++it) - //{ - // if (address >= it->address && address < it->address + it->length) - // { - // return; - // } - //} - - // if ((address & 0xFF000000) == 0xcc000000) - //{ - // return; - //} - - // std::vector callstack; - // Dolphin_Debugger::GetCallstack(callstack); - - // bool isFound = false; - // for (auto it = callstack.begin(); it != callstack.end(); ++it) - //{ - // std::string func = PowerPC::debug_interface.GetDescription(it->vAddress).c_str(); - // if (whitelist.count(func)) - // { - // isFound = true; - // break; - // } - //} - - // if (!isFound) - //{ - // return; - //} - - // NOTICE_LOG(MEMMAP, "(%s) %x (%s) | %x (%x) <-> %x", write ? "Write" : "Read", PC, - // PowerPC::debug_interface.GetDescription(PC).c_str(), var, size, address); - - //********************************************************************* - //* Detect writes in unknown memory region - //********************************************************************* - //static std::unordered_map visited = {}; - - //auto sceneController = ReadFromHardware(0x80479d30); - //if ((sceneController & 0xFF0000FF) != 0x08000002) - //{ - // return; - //} - - //auto isLoading = ReadFromHardware(0x80479d64); - //if (isLoading) - //{ - // return; - //} - - //if (!write) - //{ - // return; - //} - - //// [804fec00 - 80BD5C40) - //if (address < 0x8071b000 || address >= 0x80bb0000) - //{ - // return; - //} - - //if (visited.count(address)) - //{ - // return; - //} - - //visited[address] = true; - - //if ((address & 0xFF000000) == 0xcc000000) - //{ - // return; - //} - - //NOTICE_LOG(MEMMAP, "(%s) %x (%s) | %x (%x) <-> %x", write ? "Write" : "Read", PC, - // PowerPC::debug_interface.GetDescription(PC).c_str(), var, size, address); +// auto sceneController = ReadFromHardware(0x80479d30); +// if ((sceneController & 0xFF0000FF) != 0x08000002) +//{ +// return; +//} + +// auto isLoading = ReadFromHardware(0x80479d64); +// if (isLoading) +//{ +// return; +//} + +// if (!write) +//{ +// return; +//} + +// if (address >= 0x804dec00 && address < 0x804eec00) +//{ +// return; +//} + +// if (visited.count(address)) +//{ +// return; +//} + +// visited[address] = true; + +// for (auto it = soundStuff.begin(); it != soundStuff.end(); ++it) +//{ +// if (address >= it->address && address < it->address + it->length) +// { +// return; +// } +//} + +// if ((address & 0xFF000000) == 0xcc000000) +//{ +// return; +//} + +// std::vector callstack; +// Dolphin_Debugger::GetCallstack(callstack); + +// bool isFound = false; +// for (auto it = callstack.begin(); it != callstack.end(); ++it) +//{ +// std::string func = PowerPC::debug_interface.GetDescription(it->vAddress).c_str(); +// if (whitelist.count(func)) +// { +// isFound = true; +// break; +// } +//} + +// if (!isFound) +//{ +// return; +//} + +// NOTICE_LOG(MEMMAP, "(%s) %x (%s) | %x (%x) <-> %x", write ? "Write" : "Read", PC, +// PowerPC::debug_interface.GetDescription(PC).c_str(), var, size, address); + +//********************************************************************* +//* Looking for sound memory +//********************************************************************* +// static std::unordered_map visited = {}; +// static std::unordered_map whitelist = { +// {"__AIDHandler", true}, // lol +// {"__AXOutAiCallback", true}, // lol +// {"__AXOutNewFrame", true}, // lol +// {"__AXSyncPBs", true}, // lol +// {"SFX_PlaySFX", true}, // lol +// {"__DSPHandler", true}, +//}; + +// static std::vector soundStuff = { +// {0x804031A0, 0x24}, // [804031A0 - 804031C4) +// {0x80407FB4, 0x34C}, // [80407FB4 - 80408300) +// {0x80433C64, 0x1EE80}, // [80433C64 - 80452AE4) +// {0x804A8D78, 0x17A68}, // [804A8D78 - 804C07E0) +// {0x804C28E0, 0x399C}, // [804C28E0 - 804C627C) +// {0x804D7474, 0x8}, // [804D7474 - 804D747C) +// {0x804D74F0, 0x50}, // [804D74F0 - 804D7540) +// {0x804D7548, 0x4}, // [804D7548 - 804D754C) +// {0x804D7558, 0x24}, // [804D7558 - 804D757C) +// {0x804D7580, 0xC}, // [804D7580 - 804D758C) +// {0x804D759C, 0x4}, // [804D759C - 804D75A0) +// {0x804D7720, 0x4}, // [804D7720 - 804D7724) +// {0x804D7744, 0x4}, // [804D7744 - 804D7748) +// {0x804D774C, 0x8}, // [804D774C - 804D7754) +// {0x804D7758, 0x8}, // [804D7758 - 804D7760) +// {0x804D7788, 0x10}, // [804D7788 - 804D7798) +// {0x804D77C8, 0x4}, // [804D77C8 - 804D77CC) +// {0x804D77D0, 0x4}, // [804D77D0 - 804D77D4) +// {0x804D77E0, 0x4}, // [804D77E0 - 804D77E4) +// {0x804DE358, 0x80}, // [804DE358 - 804DE3D8) +// {0x804DE800, 0x70}, // [804DE800 - 804DE870) +//}; + +// auto sceneController = ReadFromHardware(0x80479d30); +// if ((sceneController & 0xFF0000FF) != 0x08000002) +//{ +// return; +//} + +// auto isLoading = ReadFromHardware(0x80479d64); +// if (isLoading) +//{ +// return; +//} + +// if (address >= 0x804dec00) +//{ +// return; +//} +////if (!write) +////{ +//// return; +////} + +// if (visited.count(address)) +//{ +// return; +//} + +// visited[address] = true; + +// for (auto it = soundStuff.begin(); it != soundStuff.end(); ++it) +//{ +// if (address >= it->address && address < it->address + it->length) +// { +// return; +// } +//} + +// if ((address & 0xFF000000) == 0xcc000000) +//{ +// return; +//} + +// std::vector callstack; +// Dolphin_Debugger::GetCallstack(callstack); + +// bool isFound = false; +// for (auto it = callstack.begin(); it != callstack.end(); ++it) +//{ +// std::string func = PowerPC::debug_interface.GetDescription(it->vAddress).c_str(); +// if (whitelist.count(func)) +// { +// isFound = true; +// break; +// } +//} + +// if (!isFound) +//{ +// return; +//} + +// NOTICE_LOG(MEMMAP, "(%s) %x (%s) | %x (%x) <-> %x", write ? "Write" : "Read", PC, +// PowerPC::debug_interface.GetDescription(PC).c_str(), var, size, address); + +//********************************************************************* +//* Detect writes in unknown memory region +//********************************************************************* +// static std::unordered_map visited = {}; + +// auto sceneController = ReadFromHardware(0x80479d30); +// if ((sceneController & 0xFF0000FF) != 0x08000002) +//{ +// return; +// } + +// auto isLoading = ReadFromHardware(0x80479d64); +// if (isLoading) +//{ +// return; +// } + +// if (!write) +//{ +// return; +// } + +//// [804fec00 - 80BD5C40) +// if (address < 0x8071b000 || address >= 0x80bb0000) +//{ +// return; +// } + +// if (visited.count(address)) +//{ +// return; +// } + +// visited[address] = true; + +// if ((address & 0xFF000000) == 0xcc000000) +//{ +// return; +// } + +// NOTICE_LOG(MEMMAP, "(%s) %x (%s) | %x (%x) <-> %x", write ? "Write" : "Read", PC, +// PowerPC::debug_interface.GetDescription(PC).c_str(), var, size, address); //} -static void Memcheck(u32 address, u32 var, bool write, size_t size) std::optional> HostTryReadInstruction(const Core::CPUThreadGuard& guard, const u32 address, RequestedAddressSpace space) diff --git a/Source/Core/Core/Slippi/SlippiConfig.h b/Source/Core/Core/Slippi/SlippiConfig.h new file mode 100644 index 0000000000..e400734ef3 --- /dev/null +++ b/Source/Core/Core/Slippi/SlippiConfig.h @@ -0,0 +1,23 @@ +#pragma once + +namespace Melee +{ +enum class Version +{ + NTSC, + TwentyXX, + UPTM, + MEX, + OTHER, +}; +} + +namespace Slippi +{ +enum class Chat +{ + ON, + DIRECT_ONLY, + OFF +}; +} diff --git a/Source/Core/Core/Slippi/SlippiDirectCodes.cpp b/Source/Core/Core/Slippi/SlippiDirectCodes.cpp index e57736905e..d5bf1550d4 100644 --- a/Source/Core/Core/Slippi/SlippiDirectCodes.cpp +++ b/Source/Core/Core/Slippi/SlippiDirectCodes.cpp @@ -215,7 +215,7 @@ std::vector SlippiDirectCodes::parseFile(std::strin // Unlike the user.json, the encapsulating type should be an array. if (res.is_discarded() || !res.is_array()) { - WARN_LOG(SLIPPI_ONLINE, "Malformed json in direct codes file."); + WARN_LOG_FMT(SLIPPI_ONLINE, "Malformed json in direct codes file."); return directCodes; } diff --git a/Externals/SlippiLib/SlippiGame.cpp b/Source/Core/Core/Slippi/SlippiGame.cpp similarity index 74% rename from Externals/SlippiLib/SlippiGame.cpp rename to Source/Core/Core/Slippi/SlippiGame.cpp index 166645bc3e..9ea9dcdaf4 100644 --- a/Externals/SlippiLib/SlippiGame.cpp +++ b/Source/Core/Core/Slippi/SlippiGame.cpp @@ -4,14 +4,17 @@ #include "SlippiGame.h" -namespace Slippi { +namespace Slippi +{ //********************************************************************** //* Event Handlers //********************************************************************** // The read operators will read a value and increment the index so the next read // will read in the correct location -uint8_t readByte(uint8_t *a, int &idx, uint32_t maxSize, uint8_t defaultValue) { - if (idx >= (int)maxSize) { +uint8_t readByte(uint8_t* a, int& idx, uint32_t maxSize, uint8_t defaultValue) +{ + if (idx >= (int)maxSize) + { idx += 1; return defaultValue; } @@ -19,9 +22,10 @@ uint8_t readByte(uint8_t *a, int &idx, uint32_t maxSize, uint8_t defaultValue) { return a[idx++]; } -uint16_t readHalf(uint8_t *a, int &idx, uint32_t maxSize, - uint16_t defaultValue) { - if (idx >= (int)maxSize) { +uint16_t readHalf(uint8_t* a, int& idx, uint32_t maxSize, uint16_t defaultValue) +{ + if (idx >= (int)maxSize) + { idx += 2; return defaultValue; } @@ -31,34 +35,38 @@ uint16_t readHalf(uint8_t *a, int &idx, uint32_t maxSize, return value; } -uint32_t readWord(uint8_t *a, int &idx, uint32_t maxSize, - uint32_t defaultValue) { - if (idx >= (int)maxSize) { +uint32_t readWord(uint8_t* a, int& idx, uint32_t maxSize, uint32_t defaultValue) +{ + if (idx >= (int)maxSize) + { idx += 4; return defaultValue; } - uint32_t value = - a[idx] << 24 | a[idx + 1] << 16 | a[idx + 2] << 8 | a[idx + 3]; + uint32_t value = a[idx] << 24 | a[idx + 1] << 16 | a[idx + 2] << 8 | a[idx + 3]; idx += 4; return value; } -float readFloat(uint8_t *a, int &idx, uint32_t maxSize, float defaultValue) { - uint32_t bytes = readWord(a, idx, maxSize, *(uint32_t *)(&defaultValue)); - return *(float *)(&bytes); +float readFloat(uint8_t* a, int& idx, uint32_t maxSize, float defaultValue) +{ + uint32_t bytes = readWord(a, idx, maxSize, *(uint32_t*)(&defaultValue)); + return *(float*)(&bytes); } -void handleGameInit(Game *game, uint32_t maxSize) { +void handleGameInit(Game* game, uint32_t maxSize) +{ int idx = 0; // Read version number - for (int i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) + { game->version[i] = readByte(data, idx, maxSize, 0); } // Read entire game info header - for (int i = 0; i < GAME_INFO_HEADER_SIZE; i++) { + for (int i = 0; i < GAME_INFO_HEADER_SIZE; i++) + { game->settings.header[i] = readWord(data, idx, maxSize, 0); } @@ -67,15 +75,18 @@ void handleGameInit(Game *game, uint32_t maxSize) { // Read UCF toggle bytes bool shouldRead = game->version[0] >= 1; - for (int i = 0; i < UCF_TOGGLE_SIZE; i++) { + for (int i = 0; i < UCF_TOGGLE_SIZE; i++) + { uint32_t value = shouldRead ? readWord(data, idx, maxSize, 0) : 0; game->settings.ucfToggles[i] = value; } // Read nametag for each player std::array, 4> playerNametags; - for (int i = 0; i < 4; i++) { - for (int j = 0; j < NAMETAG_SIZE; j++) { + for (int i = 0; i < 4; i++) + { + for (int j = 0; j < NAMETAG_SIZE; j++) + { playerNametags[i][j] = readHalf(data, idx, maxSize, 0); } } @@ -94,32 +105,37 @@ void handleGameInit(Game *game, uint32_t maxSize) { // Read display name for each player std::array, 4> playerDisplayNames; - for (int i = 0; i < 4; i++) { - for (int j = 0; j < DISPLAY_NAME_SIZE; j++) { + for (int i = 0; i < 4; i++) + { + for (int j = 0; j < DISPLAY_NAME_SIZE; j++) + { playerDisplayNames[i][j] = readByte(data, idx, maxSize, 0); } } // Read connectCodes std::array, 4> playerConnectCodes; - for (int i = 0; i < 4; i++) { - for (int j = 0; j < CONNECT_CODE_SIZE; j++) { + for (int i = 0; i < 4; i++) + { + for (int j = 0; j < CONNECT_CODE_SIZE; j++) + { playerConnectCodes[i][j] = readByte(data, idx, maxSize, 0); } } // Pull header data into struct - int player1Pos = 24; // This is the index of the first players character info - std::array gameInfoHeader = - game->settings.header; - for (int i = 0; i < 4; i++) { + int player1Pos = 24; // This is the index of the first players character info + std::array gameInfoHeader = game->settings.header; + for (int i = 0; i < 4; i++) + { // this is the position in the array that this player's character info is // stored int pos = player1Pos + (9 * i); uint32_t playerInfo = gameInfoHeader[pos]; uint8_t playerType = (playerInfo & 0x00FF0000) >> 16; - if (playerType == 0x3) { + if (playerType == 0x3) + { // Player type 3 is an empty slot continue; } @@ -143,12 +159,15 @@ void handleGameInit(Game *game, uint32_t maxSize) { auto majorVersion = game->version[0]; auto minorVersion = game->version[1]; - if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 1)) { + if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 1)) + { // After version 3.1.0 we added a dynamic gecko loading process. These // are needed before starting the game. areSettingsLoaded will be set // to true when they are received game->areSettingsLoaded = false; - } else if (majorVersion > 1 || (majorVersion == 1 && minorVersion >= 6)) { + } + else if (majorVersion > 1 || (majorVersion == 1 && minorVersion >= 6)) + { // Indicate settings loaded immediately if after version 1.6.0 // Sheik game info was added in this version and so we no longer // need to wait @@ -156,16 +175,17 @@ void handleGameInit(Game *game, uint32_t maxSize) { } } -void handleGeckoList(Game *game, uint32_t maxSize) { +void handleGeckoList(Game* game, uint32_t maxSize) +{ game->settings.geckoCodes.clear(); - game->settings.geckoCodes.insert(game->settings.geckoCodes.end(), data, - data + maxSize); + game->settings.geckoCodes.insert(game->settings.geckoCodes.end(), data, data + maxSize); // File is good to load game->areSettingsLoaded = true; } -void handleFrameStart(Game *game, uint32_t maxSize) { +void handleFrameStart(Game* game, uint32_t maxSize) +{ int idx = 0; // Check frame count @@ -173,7 +193,7 @@ void handleFrameStart(Game *game, uint32_t maxSize) { game->frameCount = frameCount; auto frameUniquePtr = std::make_unique(); - FrameData *frame = frameUniquePtr.get(); + FrameData* frame = frameUniquePtr.get(); frame->frame = frameCount; frame->randomSeedExists = true; @@ -181,12 +201,13 @@ void handleFrameStart(Game *game, uint32_t maxSize) { // Add frame to game. The frames are stored in multiple ways because // for games with rollback, the same frame may be replayed multiple times - frame->numSinceStart = game->frames.size(); + frame->numSinceStart = static_cast(game->frames.size()); game->frames.push_back(std::move(frameUniquePtr)); game->framesByIndex[frameCount] = frame; } -void handlePreFrameUpdate(Game *game, uint32_t maxSize) { +void handlePreFrameUpdate(Game* game, uint32_t maxSize) +{ int idx = 0; // Check frame count @@ -194,10 +215,11 @@ void handlePreFrameUpdate(Game *game, uint32_t maxSize) { game->frameCount = frameCount; auto frameUniquePtr = std::make_unique(); - FrameData *frame = frameUniquePtr.get(); + FrameData* frame = frameUniquePtr.get(); bool isNewFrame = true; - if (game->framesByIndex.count(frameCount)) { + if (game->framesByIndex.count(frameCount)) + { // If this frame already exists, get the current frame frame = game->frames.back().get(); isNewFrame = false; @@ -232,36 +254,40 @@ void handlePreFrameUpdate(Game *game, uint32_t maxSize) { p.lTrigger = readFloat(data, idx, maxSize, 0); p.rTrigger = readFloat(data, idx, maxSize, 0); - if (asmEvents[EVENT_PRE_FRAME_UPDATE] >= 59) { + if (asmEvents[EVENT_PRE_FRAME_UPDATE] >= 59) + { p.joystickXRaw = readByte(data, idx, maxSize, 0); } uint32_t noPercent = 0xFFFFFFFF; - p.percent = readFloat(data, idx, maxSize, *(float *)(&noPercent)); + p.percent = readFloat(data, idx, maxSize, *(float*)(&noPercent)); // Add player data to frame - std::unordered_map *target; + std::unordered_map* target; target = isFollower ? &frame->followers : &frame->players; // Set the player data for the player or follower target->operator[](playerSlot) = p; // Add frame to game - if (isNewFrame) { - frame->numSinceStart = game->frames.size(); + if (isNewFrame) + { + frame->numSinceStart = static_cast(game->frames.size()); game->frames.push_back(std::move(frameUniquePtr)); game->framesByIndex[frameCount] = frame; } } -void handlePostFrameUpdate(Game *game, uint32_t maxSize) { +void handlePostFrameUpdate(Game* game, uint32_t maxSize) +{ int idx = 0; // Check frame count int32_t frameCount = readWord(data, idx, maxSize, 0); - FrameData *frame; - if (game->framesByIndex.count(frameCount)) { + FrameData* frame = nullptr; + if (game->framesByIndex.count(frameCount)) + { // If this frame already exists, get the current frame frame = game->frames.back().get(); } @@ -274,35 +300,39 @@ void handlePostFrameUpdate(Game *game, uint32_t maxSize) { uint8_t playerSlot = readByte(data, idx, maxSize, 0); uint8_t isFollower = readByte(data, idx, maxSize, 0); - PlayerFrameData *p = - isFollower ? &frame->followers[playerSlot] : &frame->players[playerSlot]; + PlayerFrameData* p = isFollower ? &frame->followers[playerSlot] : &frame->players[playerSlot]; p->internalCharacterId = readByte(data, idx, maxSize, 0); // Check if a player started as sheik and update - if (frameCount == GAME_FIRST_FRAME && - p->internalCharacterId == GAME_SHEIK_INTERNAL_ID) { + if (frameCount == GAME_FIRST_FRAME && p->internalCharacterId == GAME_SHEIK_INTERNAL_ID) + { game->settings.players[playerSlot].characterId = GAME_SHEIK_EXTERNAL_ID; } // Set settings loaded if this is the last character - if (frameCount == GAME_FIRST_FRAME) { + if (frameCount == GAME_FIRST_FRAME) + { uint8_t lastPlayerIndex = 0; - for (auto it = frame->players.begin(); it != frame->players.end(); ++it) { - if (it->first <= lastPlayerIndex) { + for (auto it = frame->players.begin(); it != frame->players.end(); ++it) + { + if (it->first <= lastPlayerIndex) + { continue; } lastPlayerIndex = it->first; } - if (playerSlot >= lastPlayerIndex) { + if (playerSlot >= lastPlayerIndex) + { game->areSettingsLoaded = true; } } } -void handleFrameEnd(Game *game, uint32_t maxSize) { +void handleFrameEnd(Game* game, uint32_t maxSize) +{ int idx = 0; int32_t frameCount = readWord(data, idx, maxSize, 0); @@ -311,23 +341,27 @@ void handleFrameEnd(Game *game, uint32_t maxSize) { game->lastFinalizedFrame = lastFinalizedFrame; } -void handleGameEnd(Game *game, uint32_t maxSize) { +void handleGameEnd(Game* game, uint32_t maxSize) +{ int idx = 0; game->winCondition = readByte(data, idx, maxSize, 0); } // This function gets the position where the raw data starts -int getRawDataPosition(std::ifstream *f) { +int getRawDataPosition(std::ifstream* f) +{ char buffer[2]; f->seekg(0, std::ios::beg); f->read(buffer, 2); - if (buffer[0] == 0x36) { + if (buffer[0] == 0x36) + { return 0; } - if (buffer[0] != '{') { + if (buffer[0] != '{') + { // TODO: Do something here to cause an error return 0; } @@ -338,8 +372,10 @@ int getRawDataPosition(std::ifstream *f) { return 15; } -uint32_t getRawDataLength(std::ifstream *f, int position, int fileSize) { - if (position == 0) { +uint32_t getRawDataLength(std::ifstream* f, int position, int fileSize) +{ + if (position == 0) + { return fileSize; } @@ -347,28 +383,28 @@ uint32_t getRawDataLength(std::ifstream *f, int position, int fileSize) { f->seekg(position - 4, std::ios::beg); f->read(buffer, 4); - uint8_t *byteBuf = (uint8_t *)&buffer[0]; - uint32_t length = - byteBuf[0] << 24 | byteBuf[1] << 16 | byteBuf[2] << 8 | byteBuf[3]; + uint8_t* byteBuf = (uint8_t*)&buffer[0]; + uint32_t length = byteBuf[0] << 24 | byteBuf[1] << 16 | byteBuf[2] << 8 | byteBuf[3]; return length; } -std::unordered_map getMessageSizes(std::ifstream *f, - int position) { +std::unordered_map getMessageSizes(std::ifstream* f, int position) +{ char buffer[2]; f->seekg(position, std::ios::beg); f->read(buffer, 2); - if (buffer[0] != EVENT_PAYLOAD_SIZES) { + if (buffer[0] != EVENT_PAYLOAD_SIZES) + { return {}; } int payloadLength = buffer[1]; - std::unordered_map messageSizes = { - {EVENT_PAYLOAD_SIZES, payloadLength}}; + std::unordered_map messageSizes = {{EVENT_PAYLOAD_SIZES, payloadLength}}; std::vector messageSizesBuffer(payloadLength - 1); f->read(&messageSizesBuffer[0], payloadLength - 1); - for (int i = 0; i < payloadLength - 1; i += 3) { + for (int i = 0; i < payloadLength - 1; i += 3) + { uint8_t command = messageSizesBuffer[i]; // Extract the bytes in u8s. Without this the chars don't or together well @@ -382,8 +418,10 @@ std::unordered_map getMessageSizes(std::ifstream *f, return messageSizes; } -void SlippiGame::processData() { - if (isProcessingComplete) { +void SlippiGame::processData() +{ + if (isProcessingComplete) + { // If we have finished processing this file, return return; } @@ -391,17 +429,20 @@ void SlippiGame::processData() { // This function will process as much data as possible int startPos = (int)file->tellg(); file->seekg(startPos); - if (startPos == 0) { + if (startPos == 0) + { file->seekg(0, std::ios::end); int len = (int)file->tellg(); - if (len < 2) { + if (len < 2) + { // If we can't read message sizes payload size yet, return return; } int rawDataPos = getRawDataPosition(file.get()); int rawDataLen = len - rawDataPos; - if (rawDataLen < 2) { + if (rawDataLen < 2) + { // If we don't have enough raw data yet to read the replay file, return // Reset to begining so that the startPos condition will be hit again file->seekg(0); @@ -415,7 +456,8 @@ void SlippiGame::processData() { file->read(buffer, 2); file->seekg(startPos); auto messageSizesSize = (int)buffer[1]; - if (rawDataLen < messageSizesSize) { + if (rawDataLen < messageSizesSize) + { // If we haven't received the full payload sizes message, return // Reset to begining so that the startPos condition will be hit again file->seekg(0); @@ -433,7 +475,8 @@ void SlippiGame::processData() { // log << "Size to read: " << sizeToRead << "\n"; // log << "Start Pos: " << startPos << "\n"; // log << "End Pos: " << endPos << "\n\n"; - if (sizeToRead <= 0) { + if (sizeToRead <= 0) + { return; } @@ -441,7 +484,8 @@ void SlippiGame::processData() { file->read(&newData[0], sizeToRead); int newDataPos = 0; - while (newDataPos < sizeToRead) { + while (newDataPos < sizeToRead) + { auto command = newData[newDataPos]; auto payloadSize = asmEvents[command]; @@ -450,32 +494,35 @@ void SlippiGame::processData() { // log << "Command: " << buff << " | Payload Size: " << payloadSize << "\n"; auto remainingLen = sizeToRead - newDataPos; - if (remainingLen < ((int)payloadSize + 1)) { + if (remainingLen < ((int)payloadSize + 1)) + { // Here we don't have enough data to read the whole payload // Will be processed after getting more data (hopefully) file->seekg(-remainingLen, std::ios::cur); return; } - data = (uint8_t *)&newData[newDataPos + 1]; + data = (uint8_t*)&newData[newDataPos + 1]; uint8_t isSplitComplete = false; uint32_t outerPayloadSize = payloadSize; // Handle a split message, combining in until we possess the entire message - if (command == EVENT_SPLIT_MESSAGE) { - if (shouldResetSplitMessageBuf) { + if (command == EVENT_SPLIT_MESSAGE) + { + if (shouldResetSplitMessageBuf) + { splitMessageBuf.clear(); shouldResetSplitMessageBuf = false; } int _ = 0; - uint16_t blockSize = - readHalf(&data[SPLIT_MESSAGE_INTERNAL_DATA_LEN], _, payloadSize, 0); + uint16_t blockSize = readHalf(&data[SPLIT_MESSAGE_INTERNAL_DATA_LEN], _, payloadSize, 0); splitMessageBuf.insert(splitMessageBuf.end(), data, data + blockSize); isSplitComplete = data[SPLIT_MESSAGE_INTERNAL_DATA_LEN + 3]; - if (isSplitComplete) { + if (isSplitComplete) + { // Transform this message into a different message command = data[SPLIT_MESSAGE_INTERNAL_DATA_LEN + 2]; data = &splitMessageBuf[0]; @@ -484,7 +531,8 @@ void SlippiGame::processData() { } } - switch (command) { + switch (command) + { case EVENT_GAME_INIT: handleGameInit(game.get(), payloadSize); break; @@ -523,24 +571,23 @@ void SlippiGame::processData() { } } -std::unique_ptr SlippiGame::FromFile(std::string path) { +std::unique_ptr SlippiGame::FromFile(std::string path) +{ auto result = std::make_unique(); result->game = std::make_unique(); result->path = path; #ifdef _WIN32 // On Windows, we need to convert paths to std::wstring to deal with UTF-8 - std::wstring convertedPath = - std::wstring_convert>().from_bytes(path); - result->file = std::make_unique( - convertedPath, std::ios::in | std::ios::binary); + std::wstring convertedPath = std::wstring_convert>().from_bytes(path); + result->file = std::make_unique(convertedPath, std::ios::in | std::ios::binary); #else - result->file = - std::make_unique(path, std::ios::in | std::ios::binary); + result->file = std::make_unique(path, std::ios::in | std::ios::binary); #endif // result->log.open("log.txt"); - if (!result->file->is_open()) { + if (!result->file->is_open()) + { return nullptr; } @@ -558,59 +605,77 @@ std::unique_ptr SlippiGame::FromFile(std::string path) { return std::move(result); } -bool SlippiGame::IsProcessingComplete() { return isProcessingComplete; } +bool SlippiGame::IsProcessingComplete() +{ + return isProcessingComplete; +} -bool SlippiGame::AreSettingsLoaded() { +bool SlippiGame::AreSettingsLoaded() +{ processData(); return game->areSettingsLoaded; } -bool SlippiGame::DoesFrameExist(int32_t frame) { +bool SlippiGame::DoesFrameExist(int32_t frame) +{ processData(); return static_cast(game->framesByIndex.count(frame)); } -std::array SlippiGame::GetVersion() { return game->version; } +std::array SlippiGame::GetVersion() +{ + return game->version; +} -std::string SlippiGame::GetVersionString() { +std::string SlippiGame::GetVersionString() +{ char version[30]; - sprintf(version, "%d.%d.%d", game->version[0], game->version[1], - game->version[2]); + sprintf(version, "%d.%d.%d", game->version[0], game->version[1], game->version[2]); return std::string(version); } -FrameData *SlippiGame::GetFrame(int32_t frame) { +FrameData* SlippiGame::GetFrame(int32_t frame) +{ // Get the frame we want return game->framesByIndex.at(frame); } -FrameData *SlippiGame::GetFrameAt(uint32_t pos) { - if (pos >= game->frames.size()) { +FrameData* SlippiGame::GetFrameAt(uint32_t pos) +{ + if (pos >= game->frames.size()) + { return nullptr; } // Get the frame we want return game->frames[pos].get(); } -int32_t SlippiGame::GetLastFinalizedFrame() { +int32_t SlippiGame::GetLastFinalizedFrame() +{ processData(); return game->lastFinalizedFrame; } -int32_t SlippiGame::GetLatestIndex() { +int32_t SlippiGame::GetLatestIndex() +{ processData(); return game->frameCount; } -GameSettings *SlippiGame::GetSettings() { +GameSettings* SlippiGame::GetSettings() +{ processData(); return &game->settings; } -bool SlippiGame::DoesPlayerExist(int8_t port) { +bool SlippiGame::DoesPlayerExist(int8_t port) +{ return game->settings.players.find(port) != game->settings.players.end(); } -uint8_t SlippiGame::GetGameEndMethod() { return game->winCondition; } -} // namespace Slippi +uint8_t SlippiGame::GetGameEndMethod() +{ + return game->winCondition; +} +} // namespace Slippi diff --git a/Externals/SlippiLib/SlippiGame.h b/Source/Core/Core/Slippi/SlippiGame.h similarity index 75% rename from Externals/SlippiLib/SlippiGame.h rename to Source/Core/Core/Slippi/SlippiGame.h index 9d628e84e5..a88b49b2c9 100644 --- a/Externals/SlippiLib/SlippiGame.h +++ b/Source/Core/Core/Slippi/SlippiGame.h @@ -8,7 +8,8 @@ #include #include -namespace Slippi { +namespace Slippi +{ const uint8_t EVENT_SPLIT_MESSAGE = 0x10; const uint8_t EVENT_PAYLOAD_SIZES = 0x35; const uint8_t EVENT_GAME_INIT = 0x36; @@ -31,9 +32,10 @@ const uint8_t GAME_SHEIK_EXTERNAL_ID = 0x13; const uint32_t SPLIT_MESSAGE_INTERNAL_DATA_LEN = 512; -static uint8_t *data; +static uint8_t* data; -typedef struct { +typedef struct +{ // Every player update has its own rng seed because it might change in between // players uint32_t randomSeed; @@ -56,19 +58,20 @@ typedef struct { float cstickX; float cstickY; float trigger; - uint32_t buttons; // This will include multiple "buttons" pressed on special - // buttons. For example I think pressing z sets 3 bits + uint32_t buttons; // This will include multiple "buttons" pressed on special + // buttons. For example I think pressing z sets 3 bits // This is extra controller information - uint16_t physicalButtons; // A better representation of what a player is - // actually pressing + uint16_t physicalButtons; // A better representation of what a player is + // actually pressing float lTrigger; float rTrigger; uint8_t joystickXRaw; } PlayerFrameData; -typedef struct FrameData { +typedef struct FrameData +{ int32_t frame; uint32_t numSinceStart; bool randomSeedExists = false; @@ -78,7 +81,8 @@ typedef struct FrameData { std::unordered_map followers; } FrameData; -typedef struct { +typedef struct +{ // Static data uint8_t characterId; uint8_t characterColor; @@ -89,8 +93,9 @@ typedef struct { std::array connectCode; } PlayerSettings; -typedef struct { - uint16_t stage; // Stage ID +typedef struct +{ + uint16_t stage; // Stage ID uint32_t randomSeed; std::array header; std::array ucfToggles; @@ -102,14 +107,15 @@ typedef struct { std::vector geckoCodes; } GameSettings; -typedef struct Game { +typedef struct Game +{ std::array version; - std::unordered_map framesByIndex; + std::unordered_map framesByIndex; std::vector> frames; GameSettings settings; bool areSettingsLoaded = false; - int32_t frameCount; // Current/last frame count + int32_t frameCount; // Current/last frame count int32_t lastFinalizedFrame = -124; // From OnGameEnd event @@ -118,25 +124,25 @@ typedef struct Game { // TODO: This shouldn't be static. Doesn't matter too much atm because we always // TODO: only read one file at a time -static std::unordered_map asmEvents = { - {EVENT_GAME_INIT, 320}, - {EVENT_PRE_FRAME_UPDATE, 58}, - {EVENT_POST_FRAME_UPDATE, 33}, - {EVENT_GAME_END, 1}, - {EVENT_FRAME_START, 8}}; +static std::unordered_map asmEvents = {{EVENT_GAME_INIT, 320}, + {EVENT_PRE_FRAME_UPDATE, 58}, + {EVENT_POST_FRAME_UPDATE, 33}, + {EVENT_GAME_END, 1}, + {EVENT_FRAME_START, 8}}; -class SlippiGame { +class SlippiGame +{ public: static std::unique_ptr FromFile(std::string path); bool AreSettingsLoaded(); bool DoesFrameExist(int32_t frame); std::array GetVersion(); std::string GetVersionString(); - FrameData *GetFrame(int32_t frame); - FrameData *GetFrameAt(uint32_t pos); + FrameData* GetFrame(int32_t frame); + FrameData* GetFrameAt(uint32_t pos); int32_t GetLastFinalizedFrame(); int32_t GetLatestIndex(); - GameSettings *GetSettings(); + GameSettings* GetSettings(); uint8_t GetGameEndMethod(); bool DoesPlayerExist(int8_t port); bool IsProcessingComplete(); @@ -153,4 +159,4 @@ private: bool isProcessingComplete = false; void processData(); }; -} // namespace Slippi +} // namespace Slippi diff --git a/Source/Core/Core/Slippi/SlippiGameFileLoader.cpp b/Source/Core/Core/Slippi/SlippiGameFileLoader.cpp index 0e4bdd936a..03bb1d0319 100644 --- a/Source/Core/Core/Slippi/SlippiGameFileLoader.cpp +++ b/Source/Core/Core/Slippi/SlippiGameFileLoader.cpp @@ -1,12 +1,13 @@ #include "SlippiGameFileLoader.h" -#include "Common/File.h" #include "Common/FileUtil.h" +#include "Common/IOFile.h" #include "Common/Logging/Log.h" #include "Core/Boot/Boot.h" #include "Core/ConfigManager.h" #include "Core/Core.h" #include "Core/HW/DVD/DVDThread.h" +#include "Core/System.h" std::string getFilePath(std::string fileName) { @@ -36,7 +37,7 @@ u32 SlippiGameFileLoader::LoadFile(std::string fileName, std::string& data) return (u32)data.size(); } - INFO_LOG(SLIPPI, "Loading file: %s", fileName.c_str()); + INFO_LOG_FMT(SLIPPI, "Loading file: {}", fileName.c_str()); std::string gameFilePath = getFilePath(fileName); if (gameFilePath.empty()) @@ -55,14 +56,14 @@ u32 SlippiGameFileLoader::LoadFile(std::string fileName, std::string& data) Core::GetState() == Core::State::Running) { std::vector buf; - INFO_LOG(SLIPPI, "Will process diff"); - DVDThread::ReadFile(fileName, buf); + INFO_LOG_FMT(SLIPPI, "Will process diff"); + Core::System::GetInstance().GetDVDThread().ReadFile(fileName, buf); std::string diffContents = fileContents; decoder.Decode((char*)buf.data(), buf.size(), diffContents, &fileContents); } fileCache[fileName] = fileContents; data = fileCache[fileName]; - INFO_LOG(SLIPPI, "File size: %d", (u32)data.size()); + INFO_LOG_FMT(SLIPPI, "File size: {}", (u32)data.size()); return (u32)data.size(); } diff --git a/Source/Core/Core/Slippi/SlippiGameReporter.cpp b/Source/Core/Core/Slippi/SlippiGameReporter.cpp index fcd2af3d21..883d404064 100644 --- a/Source/Core/Core/Slippi/SlippiGameReporter.cpp +++ b/Source/Core/Core/Slippi/SlippiGameReporter.cpp @@ -116,7 +116,8 @@ void SlippiGameReporter::ReportThreadHandler() if (res != 0) { - ERROR_LOG(SLIPPI_ONLINE, "[GameReport] Got error executing request. Err code: %d", res); + ERROR_LOG_FMT(SLIPPI_ONLINE, "[GameReport] Got error executing request. Err code : {}", + static_cast(res)); } gameIndex++; diff --git a/Source/Core/Core/Slippi/SlippiMatchmaking.cpp b/Source/Core/Core/Slippi/SlippiMatchmaking.cpp index 8f06f2e1e6..b7c0f07235 100644 --- a/Source/Core/Core/Slippi/SlippiMatchmaking.cpp +++ b/Source/Core/Core/Slippi/SlippiMatchmaking.cpp @@ -36,10 +36,9 @@ SlippiMatchmaking::SlippiMatchmaking(SlippiUser* user) m_client = nullptr; m_server = nullptr; - MM_HOST = - Common::scm_slippi_semver_str.find("dev") == std::string::npos ? MM_HOST_PROD : MM_HOST_DEV; + MM_HOST = Common::GetSemVerStr().find("dev") == std::string::npos ? MM_HOST_PROD : MM_HOST_DEV; - generator = std::default_random_engine(Common::Timer::GetTimeMs()); + generator = std::default_random_engine(Common::Timer::NowMs()); } SlippiMatchmaking::~SlippiMatchmaking() @@ -367,7 +366,7 @@ void SlippiMatchmaking::startMatchmaking() if (SConfig::GetInstance().m_slippiForceLanIp) { - WARN_LOG(SLIPPI_ONLINE, "[Matchmaking] Overwriting LAN IP sent with configured address"); + WARN_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Overwriting LAN IP sent with configured address"); sprintf(lan_addr, "%s:%d", SConfig::GetInstance().m_slippiLanIp.c_str(), m_hostPort); } @@ -382,7 +381,7 @@ void SlippiMatchmaking::startMatchmaking() request["type"] = MmMessageType::CREATE_TICKET; request["user"] = {{"uid", userInfo.uid}, {"playKey", userInfo.play_key}}; request["search"] = {{"mode", m_searchSettings.mode}, {"connectCode", connectCodeBuf}}; - request["appVersion"] = Common::scm_slippi_semver_str; + request["appVersion"] = Common::GetSemVerStr(); request["ipAddressLan"] = lan_addr; sendMessage(request); diff --git a/Source/Core/Core/Slippi/SlippiNetplay.cpp b/Source/Core/Core/Slippi/SlippiNetplay.cpp index 1662dc2d15..be069f0a2d 100644 --- a/Source/Core/Core/Slippi/SlippiNetplay.cpp +++ b/Source/Core/Core/Slippi/SlippiNetplay.cpp @@ -13,11 +13,11 @@ #include "Core/ConfigManager.h" #include "Core/Core.h" #include "Core/NetPlayProto.h" +#include "SlippiGame.h" #include "SlippiPremadeText.h" #include "VideoCommon/OnScreenDisplay.h" #include "VideoCommon/VideoConfig.h" -#include #include #include #include @@ -52,7 +52,7 @@ SlippiNetplayClient::~SlippiNetplayClient() SLIPPI_NETPLAY = nullptr; - WARN_LOG(SLIPPI_ONLINE, "Netplay client cleanup complete"); + WARN_LOG_FMT(SLIPPI_ONLINE, "Netplay client cleanup complete"); } // called from ---SLIPPI EXI--- thread @@ -98,7 +98,7 @@ SlippiNetplayClient::SlippiNetplayClient(std::vector addrs, std::ve // the NAT on some routers if (localPort > 0) { - INFO_LOG(SLIPPI_ONLINE, "Setting up local address"); + INFO_LOG_FMT(SLIPPI_ONLINE, "Setting up local address"); localAddrDef.host = ENET_HOST_ANY; localAddrDef.port = localPort; @@ -129,7 +129,7 @@ SlippiNetplayClient::SlippiNetplayClient(std::vector addrs, std::ve std::stringstream keyStrm; keyStrm << addr.host << "-" << addr.port; activeConnections[keyStrm.str()][peer] = true; - INFO_LOG_FMT(SLIPPI_ONLINE, "New connection (constr): {}", keyStrm.str().c_str()); + INFO_LOG_FMT(SLIPPI_ONLINE, "New connection (constr): {}", keyStrm.str()); if (peer == nullptr) { @@ -173,31 +173,32 @@ u8 SlippiNetplayClient::LocalPlayerPort() // called from ---NETPLAY--- thread unsigned int SlippiNetplayClient::OnData(sf::Packet& packet, ENetPeer* peer) { - Netplay::MessageID mid = 0; - if (!(packet >> mid)) + u8 message_value = 0; + if (!(packet >> message_value)) { - ERROR_LOG(SLIPPI_ONLINE, "Received empty netplay packet"); + ERROR_LOG_FMT(SLIPPI_ONLINE, "Received empty netplay packet"); return 0; } + NetPlay::MessageID mid{message_value}; switch (mid) { - case Netplay::MessageID::SLIPPI_PAD: + case NetPlay::MessageID::SLIPPI_PAD: { // Fetch current time immediately for the most accurate timing calculations - u64 curTime = Common::Timer::GetTimeUs(); + u64 curTime = Common::Timer::NowUs(); int32_t frame; if (!(packet >> frame)) { - ERROR_LOG(SLIPPI_ONLINE, "Netplay packet too small to read frame count"); + ERROR_LOG_FMT(SLIPPI_ONLINE, "Netplay packet too small to read frame count"); break; } u8 packetPlayerPort; if (!(packet >> packetPlayerPort)) { - ERROR_LOG(SLIPPI_ONLINE, "Netplay packet too small to read player index"); + ERROR_LOG_FMT(SLIPPI_ONLINE, "Netplay packet too small to read player index"); break; } u8 pIdx = PlayerIdxFromPort(packetPlayerPort); @@ -318,7 +319,7 @@ unsigned int SlippiNetplayClient::OnData(sf::Packet& packet, ENetPeer* peer) // Send Ack sf::Packet spac; - spac << NetPlay::MessageID::SLIPPI_PAD_ACK; + spac << static_cast(NetPlay::MessageID::SLIPPI_PAD_ACK); spac << frame; spac << m_player_idx; // INFO_LOG_FMT(SLIPPI_ONLINE, "Sending ack packet for frame {} (player {}) to peer at {}:{}", @@ -338,14 +339,14 @@ unsigned int SlippiNetplayClient::OnData(sf::Packet& packet, ENetPeer* peer) int32_t frame; if (!(packet >> frame)) { - ERROR_LOG(SLIPPI_ONLINE, "Ack packet too small to read frame"); + ERROR_LOG_FMT(SLIPPI_ONLINE, "Ack packet too small to read frame"); break; } u8 packetPlayerPort; if (!(packet >> packetPlayerPort)) { - ERROR_LOG(SLIPPI_ONLINE, "Netplay ack packet too small to read player index"); + ERROR_LOG_FMT(SLIPPI_ONLINE, "Netplay ack packet too small to read player index"); break; } u8 pIdx = PlayerIdxFromPort(packetPlayerPort); @@ -376,7 +377,7 @@ unsigned int SlippiNetplayClient::OnData(sf::Packet& packet, ENetPeer* peer) auto sendTime = ackTimers[pIdx].front().timeUs; ackTimers[pIdx].pop(); - pingUs[pIdx] = Common::Timer::GetTimeUs() - sendTime; + pingUs[pIdx] = Common::Timer::NowUs() - sendTime; if (g_ActiveConfig.bShowNetPlayPing && frame % SLIPPI_PING_DISPLAY_INTERVAL == 0 && pIdx == 0) { std::stringstream pingDisplay; @@ -440,7 +441,7 @@ unsigned int SlippiNetplayClient::OnData(sf::Packet& packet, ENetPeer* peer) break; default: - WARN_LOG_FMT(SLIPPI_ONLINE, "Unknown message received with id : {}", mid); + WARN_LOG_FMT(SLIPPI_ONLINE, "Unknown message received with id : {}", static_cast(mid)); break; } @@ -449,7 +450,7 @@ unsigned int SlippiNetplayClient::OnData(sf::Packet& packet, ENetPeer* peer) void SlippiNetplayClient::writeToPacket(sf::Packet& packet, SlippiPlayerSelections& s) { - packet << static_cast(NetPlay::MessageID::SLIPPI_MATCH_SELECTIONS); + packet << static_cast(NetPlay::MessageID::SLIPPI_MATCH_SELECTIONS); packet << s.characterId << s.characterColor << s.isCharacterSelected; packet << s.playerIdx; packet << s.stageId << s.isStageSelected; @@ -459,7 +460,7 @@ void SlippiNetplayClient::writeToPacket(sf::Packet& packet, SlippiPlayerSelectio void SlippiNetplayClient::WriteChatMessageToPacket(sf::Packet& packet, int messageId, u8 player_id) { - packet << static_cast(NetPlay::MessageID::SLIPPI_CHAT_MESSAGE); + packet << static_cast(NetPlay::MessageID::SLIPPI_CHAT_MESSAGE); packet << messageId; packet << player_id; } @@ -471,13 +472,13 @@ SlippiNetplayClient::ReadChatMessageFromPacket(sf::Packet& packet) if (!(packet >> s->messageId)) { - ERROR_LOG(SLIPPI_ONLINE, "Chat packet too small to read message ID"); + ERROR_LOG_FMT(SLIPPI_ONLINE, "Chat packet too small to read message ID"); s->error = true; return std::move(s); } if (!(packet >> s->playerIdx)) { - ERROR_LOG(SLIPPI_ONLINE, "Chat packet too small to read player index"); + ERROR_LOG_FMT(SLIPPI_ONLINE, "Chat packet too small to read player index"); s->error = true; return std::move(s); } @@ -524,42 +525,42 @@ SlippiNetplayClient::readSelectionsFromPacket(sf::Packet& packet) if (!(packet >> s->characterId)) { - ERROR_LOG(SLIPPI_ONLINE, "Received invalid player selection"); + ERROR_LOG_FMT(SLIPPI_ONLINE, "Received invalid player selection"); s->error = true; } if (!(packet >> s->characterColor)) { - ERROR_LOG(SLIPPI_ONLINE, "Received invalid player selection"); + ERROR_LOG_FMT(SLIPPI_ONLINE, "Received invalid player selection"); s->error = true; } if (!(packet >> s->isCharacterSelected)) { - ERROR_LOG(SLIPPI_ONLINE, "Received invalid player selection"); + ERROR_LOG_FMT(SLIPPI_ONLINE, "Received invalid player selection"); s->error = true; } if (!(packet >> s->playerIdx)) { - ERROR_LOG(SLIPPI_ONLINE, "Received invalid player selection"); + ERROR_LOG_FMT(SLIPPI_ONLINE, "Received invalid player selection"); s->error = true; } if (!(packet >> s->stageId)) { - ERROR_LOG(SLIPPI_ONLINE, "Received invalid player selection"); + ERROR_LOG_FMT(SLIPPI_ONLINE, "Received invalid player selection"); s->error = true; } if (!(packet >> s->isStageSelected)) { - ERROR_LOG(SLIPPI_ONLINE, "Received invalid player selection"); + ERROR_LOG_FMT(SLIPPI_ONLINE, "Received invalid player selection"); s->error = true; } if (!(packet >> s->rngOffset)) { - ERROR_LOG(SLIPPI_ONLINE, "Received invalid player selection"); + ERROR_LOG_FMT(SLIPPI_ONLINE, "Received invalid player selection"); s->error = true; } if (!(packet >> s->teamId)) { - ERROR_LOG(SLIPPI_ONLINE, "Received invalid player selection"); + ERROR_LOG_FMT(SLIPPI_ONLINE, "Received invalid player selection"); s->error = true; } @@ -573,7 +574,7 @@ void SlippiNetplayClient::Send(sf::Packet& packet) for (int i = 0; i < m_server.size(); i++) { - NetPlay::MessageId mid = ((u8*)packet.getData())[0]; + NetPlay::MessageID mid{((u8*)packet.getData())[0]}; if (mid == NetPlay::MessageID::SLIPPI_PAD || mid == NetPlay::MessageID::SLIPPI_PAD_ACK) { // Slippi communications do not need reliable connection and do not need to @@ -645,7 +646,7 @@ void SlippiNetplayClient::SendAsync(std::unique_ptr packet) void SlippiNetplayClient::ThreadFunc() { // Let client die 1 second before host such that after a swap, the client won't be connected to - u64 startTime = Common::Timer::GetTimeMs(); + u64 startTime = Common::Timer::NowMs(); u64 timeout = 8000; std::vector connections; @@ -669,7 +670,7 @@ void SlippiNetplayClient::ThreadFunc() case ENET_EVENT_TYPE_RECEIVE: if (!netEvent.peer) { - INFO_LOG(SLIPPI_ONLINE, "[Netplay] got receive event with nil peer"); + INFO_LOG_FMT(SLIPPI_ONLINE, "[Netplay] got receive event with nil peer"); continue; } INFO_LOG_FMT(SLIPPI_ONLINE, "[Netplay] got receive event with peer addr {}:{}", @@ -684,7 +685,7 @@ void SlippiNetplayClient::ThreadFunc() case ENET_EVENT_TYPE_DISCONNECT: if (!netEvent.peer) { - INFO_LOG(SLIPPI_ONLINE, "[Netplay] got disconnect event with nil peer"); + INFO_LOG_FMT(SLIPPI_ONLINE, "[Netplay] got disconnect event with nil peer"); continue; } INFO_LOG_FMT(SLIPPI_ONLINE, "[Netplay] got disconnect event with peer addr {}:{}", @@ -695,7 +696,7 @@ void SlippiNetplayClient::ThreadFunc() { if (!netEvent.peer) { - INFO_LOG(SLIPPI_ONLINE, "[Netplay] got connect event with nil peer"); + INFO_LOG_FMT(SLIPPI_ONLINE, "[Netplay] got connect event with nil peer"); continue; } @@ -724,7 +725,7 @@ void SlippiNetplayClient::ThreadFunc() // Don't add this person again if they are already connected. Not doing this can cause // one person to take up 2 or more spots, denying one or more players from connecting // and thus getting stuck on the "Waiting" step - INFO_LOG(SLIPPI_ONLINE, "Already connected!"); + INFO_LOG_FMT(SLIPPI_ONLINE, "Already connected!"); break; // Breaks out of case } @@ -740,14 +741,17 @@ void SlippiNetplayClient::ThreadFunc() // out of two that are on your LAN, it might report that you failed to connect to the // wrong person. There might be more problems tho, not sure INFO_LOG_FMT(SLIPPI_ONLINE, "[Netplay] Comparing connection address: {} - {}", - remoteAddrs[i].host, netEvent.peer->address.host); + static_cast(remoteAddrs[i].host), + static_cast(netEvent.peer->address.host)); if (remoteAddrs[i].host == netEvent.peer->address.host && !connections[i]) { INFO_LOG_FMT(SLIPPI_ONLINE, "[Netplay] Overwriting ENetPeer for address: {}:{}", - netEvent.peer->address.host, netEvent.peer->address.port); + static_cast(netEvent.peer->address.host), + static_cast(netEvent.peer->address.port)); INFO_LOG_FMT(SLIPPI_ONLINE, "[Netplay] Overwriting ENetPeer with id ({}) with new peer of id {}", - m_server[i]->connectID, netEvent.peer->connectID); + static_cast(m_server[i]->connectID), + static_cast(netEvent.peer->connectID)); m_server[i] = netEvent.peer; connections[i] = true; break; @@ -768,20 +772,21 @@ void SlippiNetplayClient::ThreadFunc() if (allConnected) { m_client->intercept = ENetUtil::InterceptCallback; - INFO_LOG(SLIPPI_ONLINE, "Slippi online connection successful!"); + INFO_LOG_FMT(SLIPPI_ONLINE, "Slippi online connection successful!"); slippiConnectStatus = SlippiConnectStatus::NET_CONNECT_STATUS_CONNECTED; break; } for (int i = 0; i < m_remotePlayerCount; i++) { - INFO_LOG_FMT(SLIPPI_ONLINE, "m_client peer {} state: {}", i, m_client->peers[i].state); + INFO_LOG_FMT(SLIPPI_ONLINE, "m_client peer {} state: {}", i, + static_cast(m_client->peers[i].state)); } INFO_LOG_FMT(SLIPPI_ONLINE, "[Netplay] Not yet connected. Res: {}, Type: {}", net, - netEvent.type); + static_cast(netEvent.type)); // Time out after enough time has passed - u64 curTime = Common::Timer::GetTimeMs(); + u64 curTime = Common::Timer::NowMs(); if ((curTime - startTime) >= timeout || !m_do_loop.IsSet()) { for (int i = 0; i < m_remotePlayerCount; i++) @@ -793,7 +798,7 @@ void SlippiNetplayClient::ThreadFunc() } slippiConnectStatus = SlippiConnectStatus::NET_CONNECT_STATUS_FAILED; - INFO_LOG(SLIPPI_ONLINE, "Slippi online connection failed"); + INFO_LOG_FMT(SLIPPI_ONLINE, "Slippi online connection failed"); return; } } @@ -801,8 +806,9 @@ void SlippiNetplayClient::ThreadFunc() INFO_LOG_FMT(SLIPPI_ONLINE, "Successfully initialized {} connections", m_server.size()); for (int i = 0; i < m_server.size(); i++) { - INFO_LOG_FMT(SLIPPI_ONLINE, "Connection {}: {}, {}", i, m_server[i]->address.host, - m_server[i]->address.port); + INFO_LOG_FMT(SLIPPI_ONLINE, "Connection {}: {}, {}", i, + static_cast(m_server[i]->address.host), + static_cast(m_server[i]->address.port)); } bool qos_success = false; @@ -906,7 +912,7 @@ void SlippiNetplayClient::ThreadFunc() // it can be safely ignored if (isConnectedClient && activeConnections[keyStrm.str()].empty()) { - INFO_LOG(SLIPPI_ONLINE, "[Netplay] Final disconnect received for a client."); + INFO_LOG_FMT(SLIPPI_ONLINE, "[Netplay] Final disconnect received for a client."); m_do_loop.Clear(); // Stop the loop, will trigger a disconnect } break; @@ -974,7 +980,7 @@ void SlippiNetplayClient::StartSlippiGame() { FrameTiming timing; timing.frame = 0; - timing.timeUs = Common::Timer::GetTimeUs(); + timing.timeUs = Common::Timer::NowUs(); lastFrameTiming[i] = timing; lastFrameAcked[i] = 0; @@ -991,7 +997,7 @@ void SlippiNetplayClient::SendConnectionSelected() { isConnectionSelected = true; auto spac = std::make_unique(); - *spac << static_cast(NetPlay::MessageID::SLIPPI_CONN_SELECTED); + *spac << static_cast(NetPlay::MessageID::SLIPPI_CONN_SELECTED); SendAsync(std::move(spac)); } void SlippiNetplayClient::SendSlippiPad(std::unique_ptr pad) @@ -1037,7 +1043,7 @@ void SlippiNetplayClient::SendSlippiPad(std::unique_ptr pad) } auto frame = localPadQueue.front()->frame; auto spac = std::make_unique(); - *spac << static_cast(NetPlay::MessageID::SLIPPI_PAD); + *spac << static_cast(NetPlay::MessageID::SLIPPI_PAD); *spac << frame; *spac << this->m_player_idx; @@ -1045,7 +1051,7 @@ void SlippiNetplayClient::SendSlippiPad(std::unique_ptr pad) spac->append((*it)->padBuf, SLIPPI_PAD_DATA_SIZE); // only transfer 8 bytes per pad SendAsync(std::move(spac)); - u64 time = Common::Timer::GetTimeUs(); + u64 time = Common::Timer::NowUs(); hasGameStarted = true; diff --git a/Source/Core/Core/Slippi/SlippiPlayback.cpp b/Source/Core/Core/Slippi/SlippiPlayback.cpp index ed440b4aa6..c23e4582a5 100644 --- a/Source/Core/Core/Slippi/SlippiPlayback.cpp +++ b/Source/Core/Core/Slippi/SlippiPlayback.cpp @@ -5,7 +5,9 @@ #include #endif +#include "Common/Config/Config.h" #include "Common/Logging/Log.h" +#include "Core/Config/MainSettings.h" #include "Core/Core.h" #include "Core/HW/EXI/EXI_DeviceSlippi.h" #include "Core/NetPlayClient.h" @@ -37,14 +39,14 @@ s32 emod(s32 a, s32 b) std::string processDiff(std::vector iState, std::vector cState) { - INFO_LOG(SLIPPI, "Processing diff"); + INFO_LOG_FMT(SLIPPI, "Processing diff"); numDiffsProcessing += 1; cv_processingDiff.notify_one(); std::string diff = std::string(); open_vcdiff::VCDiffEncoder encoder((char*)iState.data(), iState.size()); encoder.Encode((char*)cState.data(), cState.size(), &diff); - INFO_LOG(SLIPPI, "done processing"); + INFO_LOG_FMT(SLIPPI, "done processing"); numDiffsProcessing -= 1; cv_processingDiff.notify_one(); return diff; @@ -75,7 +77,7 @@ void SlippiPlaybackStatus::prepareSlippiPlayback(s32& frameIndex) // block if there's too many diffs being processed while (shouldRunThreads && numDiffsProcessing > 2) { - INFO_LOG(SLIPPI, "Processing too many diffs, blocking main process"); + INFO_LOG_FMT(SLIPPI, "Processing too many diffs, blocking main process"); cv_processingDiff.wait(processingLock); } @@ -86,7 +88,7 @@ void SlippiPlaybackStatus::prepareSlippiPlayback(s32& frameIndex) // TODO: figure out why sometimes playback frame increments past targetFrameNum if (inSlippiPlayback && frameIndex >= targetFrameNum) { - INFO_LOG(SLIPPI, "Reached frame %d. Target was %d. Unblocking", frameIndex, targetFrameNum); + INFO_LOG_FMT(SLIPPI, "Reached frame {}. Target was {}. Unblocking", frameIndex, targetFrameNum); cv_waitingForTargetFrame.notify_one(); } } @@ -115,7 +117,7 @@ void SlippiPlaybackStatus::resetPlayback() void SlippiPlaybackStatus::processInitialState() { - INFO_LOG(SLIPPI, "saving iState"); + INFO_LOG_FMT(SLIPPI, "saving iState"); State::SaveToBuffer(iState); // The initial save to cState causes a stutter of about 5-10 frames // Doing it here to get it out of the way and prevent stutters later @@ -123,7 +125,7 @@ void SlippiPlaybackStatus::processInitialState() State::SaveToBuffer(cState); if (SConfig::GetInstance().m_slippiEnableSeek) { - SConfig::GetInstance().bHideCursor = false; + Config::SetCurrent(Config::MAIN_SHOW_CURSOR, Config::ShowCursor::Constantly); } }; @@ -132,7 +134,7 @@ void SlippiPlaybackStatus::SavestateThread() Common::SetCurrentThreadName("Savestate thread"); std::unique_lock intervalLock(mtx); - INFO_LOG(SLIPPI, "Entering savestate thread"); + INFO_LOG_FMT(SLIPPI, "Entering savestate thread"); while (shouldRunThreads) { @@ -159,7 +161,7 @@ void SlippiPlaybackStatus::SavestateThread() } else if (SConfig::GetInstance().m_slippiEnableSeek && !hasStateBeenProcessed && !isStartFrame) { - INFO_LOG(SLIPPI, "saving diff at frame: %d", fixedFrameNumber); + INFO_LOG_FMT(SLIPPI, "saving diff at frame: {}", fixedFrameNumber); State::SaveToBuffer(cState); futureDiffs[fixedFrameNumber] = std::async(processDiff, iState, cState); @@ -167,7 +169,7 @@ void SlippiPlaybackStatus::SavestateThread() Common::SleepCurrentThread(SLEEP_TIME_MS); } - INFO_LOG(SLIPPI, "Exiting savestate thread"); + INFO_LOG_FMT(SLIPPI, "Exiting savestate thread"); } void SlippiPlaybackStatus::seekToFrame() @@ -251,7 +253,7 @@ void SlippiPlaybackStatus::seekToFrame() } else { - INFO_LOG(SLIPPI, "Already seeking. Ignoring this call"); + INFO_LOG_FMT(SLIPPI, "Already seeking. Ignoring this call"); } } diff --git a/Source/Core/Core/Slippi/SlippiPlayback.h b/Source/Core/Core/Slippi/SlippiPlayback.h index 8870076a60..af4a797412 100644 --- a/Source/Core/Core/Slippi/SlippiPlayback.h +++ b/Source/Core/Core/Slippi/SlippiPlayback.h @@ -5,12 +5,12 @@ #include #include -#include #include #include #include "../../Common/CommonTypes.h" #include "Core/ConfigManager.h" +#include "SlippiGame.h" class SlippiPlaybackStatus { diff --git a/Source/Core/Core/Slippi/SlippiPremadeText.h b/Source/Core/Core/Slippi/SlippiPremadeText.h index 1ef834c3e6..8f52c7f0ad 100644 --- a/Source/Core/Core/Slippi/SlippiPremadeText.h +++ b/Source/Core/Core/Slippi/SlippiPremadeText.h @@ -98,7 +98,7 @@ public: va_start(args, textId); vsprintf(str, format.c_str(), args); va_end(args); - // INFO_LOG(SLIPPI, "%s", str); + // INFO_LOG_FMT(SLIPPI, "%s", str); std::vector data = {}; std::vector empty = {}; @@ -222,7 +222,7 @@ public: u16 sht = static_cast((TEXT_OP_CODE::COMMON_CHARACTER << 8) | pos); u8 r = static_cast(sht >> 8); u8 r2 = static_cast(sht & 0xFF); - // INFO_LOG(SLIPPI, "%x %x %x %c", sht, r, r2, chr); + // INFO_LOG_FMT(SLIPPI, "%x %x %x %c", sht, r, r2, chr); data.push_back(r); data.push_back(r2); diff --git a/Source/Core/Core/Slippi/SlippiReplayComm.cpp b/Source/Core/Core/Slippi/SlippiReplayComm.cpp index c4a91d8137..2662b0f0b8 100644 --- a/Source/Core/Core/Slippi/SlippiReplayComm.cpp +++ b/Source/Core/Core/Slippi/SlippiReplayComm.cpp @@ -31,8 +31,8 @@ static inline void trim(std::string& s) SlippiReplayComm::SlippiReplayComm() { - INFO_LOG(EXPANSIONINTERFACE, "SlippiReplayComm: Using playback config path: %s", - SConfig::GetInstance().m_strSlippiInput.c_str()); + INFO_LOG_FMT(EXPANSIONINTERFACE, "SlippiReplayComm: Using playback config path: {}", + SConfig::GetInstance().m_strSlippiInput.c_str()); configFilePath = SConfig::GetInstance().m_strSlippiInput.c_str(); } @@ -96,7 +96,7 @@ void SlippiReplayComm::nextReplay() std::unique_ptr SlippiReplayComm::loadGame() { auto replayFilePath = getReplayPath(); - INFO_LOG(EXPANSIONINTERFACE, "Attempting to load replay file %s", replayFilePath.c_str()); + INFO_LOG_FMT(EXPANSIONINTERFACE, "Attempting to load replay file {}", replayFilePath.c_str()); auto result = Slippi::SlippiGame::FromFile(replayFilePath); if (result) { @@ -147,7 +147,7 @@ void SlippiReplayComm::loadFile() return; } - WARN_LOG(EXPANSIONINTERFACE, "File change detected in comm file: %s", configFilePath.c_str()); + WARN_LOG_FMT(EXPANSIONINTERFACE, "File change detected in comm file: {}", configFilePath.c_str()); configLastLoadModTime = modTime; // TODO: Maybe load file in a more intelligent way to save @@ -179,7 +179,7 @@ void SlippiReplayComm::loadFile() } else { - WARN_LOG(EXPANSIONINTERFACE, "Comm file load error detected. Check file format"); + WARN_LOG_FMT(EXPANSIONINTERFACE, "Comm file load error detected. Check file format"); // Reset in the case of read error. this fixes a race condition where file mod time changes // but the file is not readable yet? diff --git a/Source/Core/Core/Slippi/SlippiReplayComm.h b/Source/Core/Core/Slippi/SlippiReplayComm.h index fd9a54b81c..f0959a6a9e 100644 --- a/Source/Core/Core/Slippi/SlippiReplayComm.h +++ b/Source/Core/Core/Slippi/SlippiReplayComm.h @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include @@ -8,6 +7,8 @@ #include +#include "SlippiGame.h" + using json = nlohmann::json; class SlippiReplayComm diff --git a/Source/Core/Core/Slippi/SlippiSavestate.cpp b/Source/Core/Core/Slippi/SlippiSavestate.cpp index d40e46a8b8..7e3cf6c788 100644 --- a/Source/Core/Core/Slippi/SlippiSavestate.cpp +++ b/Source/Core/Core/Slippi/SlippiSavestate.cpp @@ -2,6 +2,7 @@ #include #include "Common/CommonFuncs.h" #include "Common/MemoryUtil.h" +#include "Core/Core.h" #include "Core/HW/AudioInterface.h" #include "Core/HW/DSP.h" #include "Core/HW/DVD/DVDInterface.h" @@ -13,6 +14,7 @@ #include "Core/HW/SI/SI.h" #include "Core/HW/VideoInterface.h" #include "Core/PowerPC/PowerPC.h" +#include "Core/System.h" bool SlippiSavestate::shouldForceInit; @@ -108,11 +110,13 @@ void SlippiSavestate::initBackupLocs() return; } + ASSERT(Core::IsCPUThread()); + Core::CPUThreadGuard guard(Core::System::GetInstance()); // Get Main Heap Boundaries - fullBackupRegions[3].startAddress = PowerPC::HostRead_U32(0x804d76b8); - fullBackupRegions[3].endAddress = PowerPC::HostRead_U32(0x804d76bc); - WARN_LOG(SLIPPI_ONLINE, "Heap start is: 0x%X", fullBackupRegions[3].startAddress); - WARN_LOG(SLIPPI_ONLINE, "Heap end is: 0x%X", fullBackupRegions[3].endAddress); + fullBackupRegions[3].startAddress = PowerPC::HostRead_U32(guard, 0x804d76b8); + fullBackupRegions[3].endAddress = PowerPC::HostRead_U32(guard, 0x804d76bc); + WARN_LOG_FMT(SLIPPI_ONLINE, "Heap start is: {:#x}", fullBackupRegions[3].startAddress); + WARN_LOG_FMT(SLIPPI_ONLINE, "Heap end is: {:#x}", fullBackupRegions[3].endAddress); // Sort exclude sections std::sort(excludeSections.begin(), excludeSections.end(), cmpFn); @@ -194,7 +198,7 @@ void SlippiSavestate::getDolphinState(PointerWrap& p) // p.DoMarker("DVDInterface"); // GPFifo::DoState(p); // p.DoMarker("GPFifo"); - ExpansionInterface::DoState(p); + Core::System::GetInstance().GetExpansionInterface().DoState(p); p.DoMarker("ExpansionInterface"); // AudioInterface::DoState(p); // p.DoMarker("AudioInterface"); @@ -206,7 +210,7 @@ void SlippiSavestate::Capture() for (auto it = backupLocs.begin(); it != backupLocs.end(); ++it) { auto size = it->endAddress - it->startAddress; - Memory::CopyFromEmu(it->data, it->startAddress, size); + Core::System::GetInstance().GetMemory().CopyFromEmu(it->data, it->startAddress, size); } //// Second copy dolphin states @@ -228,6 +232,7 @@ void SlippiSavestate::Load(std::vector blocks) // { // blocks.push_back(*it); // } + auto& memory = Core::System::GetInstance().GetMemory(); // Back up for (auto it = blocks.begin(); it != blocks.end(); ++it) @@ -238,14 +243,14 @@ void SlippiSavestate::Load(std::vector blocks) preservationMap[*it] = std::vector(it->length); } - Memory::CopyFromEmu(&preservationMap[*it][0], it->address, it->length); + memory.CopyFromEmu(&preservationMap[*it][0], it->address, it->length); } // Restore memory blocks for (auto it = backupLocs.begin(); it != backupLocs.end(); ++it) { auto size = it->endAddress - it->startAddress; - Memory::CopyToEmu(it->startAddress, it->data, size); + memory.CopyToEmu(it->startAddress, it->data, size); } //// Restore audio @@ -256,6 +261,6 @@ void SlippiSavestate::Load(std::vector blocks) // Restore for (auto it = blocks.begin(); it != blocks.end(); ++it) { - Memory::CopyToEmu(it->address, &preservationMap[*it][0], it->length); + memory.CopyToEmu(it->address, &preservationMap[*it][0], it->length); } } diff --git a/Source/Core/Core/Slippi/SlippiSpectate.cpp b/Source/Core/Core/Slippi/SlippiSpectate.cpp index ce6154020a..038ea96cf6 100644 --- a/Source/Core/Core/Slippi/SlippiSpectate.cpp +++ b/Source/Core/Core/Slippi/SlippiSpectate.cpp @@ -253,7 +253,7 @@ void SlippiSpectateServer::handleMessage(u8* buffer, u32 length, u16 peer_id) json reply; reply["type"] = "connect_reply"; reply["nick"] = "Slippi Online"; - reply["version"] = Common::scm_slippi_semver_str; + reply["version"] = Common::GetSemVerStr(); reply["cursor"] = sent_cursor; std::string packet_buffer = reply.dump(); @@ -273,7 +273,7 @@ void SlippiSpectateServer::SlippicommSocketThread(void) { if (enet_initialize() != 0) { - WARN_LOG(SLIPPI, "An error occurred while initializing spectator server."); + WARN_LOG_FMT(SLIPPI, "An error occurred while initializing spectator server."); return; } @@ -297,7 +297,7 @@ void SlippiSpectateServer::SlippicommSocketThread(void) if (server == nullptr) { - WARN_LOG(SLIPPI, "Could not create spectator server"); + WARN_LOG_FMT(SLIPPI, "Could not create spectator server"); enet_deinitialize(); return; } @@ -332,8 +332,8 @@ void SlippiSpectateServer::SlippicommSocketThread(void) { case ENET_EVENT_TYPE_CONNECT: { - INFO_LOG(SLIPPI, "A new spectator connected from %x:%u.\n", event.peer->address.host, - event.peer->address.port); + INFO_LOG_FMT(SLIPPI, "A new spectator connected from {:x}:{}.\n", event.peer->address.host, + event.peer->address.port); std::shared_ptr newSlippiSocket(new SlippiSocket()); newSlippiSocket->m_peer = event.peer; @@ -351,8 +351,8 @@ void SlippiSpectateServer::SlippicommSocketThread(void) } case ENET_EVENT_TYPE_DISCONNECT: { - INFO_LOG(SLIPPI, "A spectator disconnected from %x:%u.\n", event.peer->address.host, - event.peer->address.port); + INFO_LOG_FMT(SLIPPI, "A spectator disconnected from {:x}:{}.\n", event.peer->address.host, + event.peer->address.port); // Delete the item in the m_sockets map m_sockets.erase(event.peer->incomingPeerID); @@ -362,7 +362,7 @@ void SlippiSpectateServer::SlippicommSocketThread(void) } default: { - INFO_LOG(SLIPPI, "Spectator sent an unknown ENet event type"); + INFO_LOG_FMT(SLIPPI, "Spectator sent an unknown ENet event type"); break; } } diff --git a/Source/Core/Core/Slippi/SlippiSpectate.h b/Source/Core/Core/Slippi/SlippiSpectate.h index 488c8fa0f4..85b77b4da7 100644 --- a/Source/Core/Core/Slippi/SlippiSpectate.h +++ b/Source/Core/Core/Slippi/SlippiSpectate.h @@ -7,7 +7,9 @@ #include #include "Common/SPSCQueue.h" +#pragma warning(push, 0) #include "nlohmann/json.hpp" +#pragma warning(pop) using json = nlohmann::json; // Sockets in windows are unsigned diff --git a/Source/Core/Core/Slippi/SlippiUser.cpp b/Source/Core/Core/Slippi/SlippiUser.cpp index b2236fb6e2..e35fcfba60 100644 --- a/Source/Core/Core/Slippi/SlippiUser.cpp +++ b/Source/Core/Core/Slippi/SlippiUser.cpp @@ -58,7 +58,7 @@ static void RunSystemCommand(const std::string& command) static size_t receive(char* ptr, size_t size, size_t nmemb, void* rcvBuf) { size_t len = size * nmemb; - INFO_LOG(SLIPPI_ONLINE, "[User] Received data: %d", len); + INFO_LOG_FMT(SLIPPI_ONLINE, "[User] Received data: {}", len); std::string* buf = (std::string*)rcvBuf; @@ -106,7 +106,7 @@ bool SlippiUser::AttemptLogin() { std::string user_file_path = getUserFilePath(); - // INFO_LOG(SLIPPI_ONLINE, "Looking for file at: %s", user_file_path.c_str()); + // INFO_LOG_FMT(SLIPPI_ONLINE, "Looking for file at: {}", user_file_path); { // Put the filename here in its own scope because we don't really need it elsewhere @@ -116,14 +116,15 @@ bool SlippiUser::AttemptLogin() // If both files exist we just log they exist and take no further action if (File::Exists(user_file_path)) { - INFO_LOG(SLIPPI_ONLINE, "Found both .json.txt and .json file for user data. Using .json " - "and ignoring the .json.txt"); + INFO_LOG_FMT(SLIPPI_ONLINE, + "Found both .json.txt and .json file for user data. Using .json " + "and ignoring the .json.txt"); } // If only the .txt file exists move the contents to a json file and log if it fails else if (!File::Rename(user_file_path_txt, user_file_path)) { - WARN_LOG(SLIPPI_ONLINE, "Could not move file %s to %s", user_file_path_txt.c_str(), - user_file_path.c_str()); + WARN_LOG_FMT(SLIPPI_ONLINE, "Could not move file {} to {}", user_file_path_txt, + user_file_path); } } } @@ -138,8 +139,7 @@ bool SlippiUser::AttemptLogin() if (m_is_logged_in) { overwriteFromServer(); - WARN_LOG(SLIPPI_ONLINE, "Found user %s (%s)", m_user_info.display_name.c_str(), - m_user_info.uid.c_str()); + WARN_LOG_FMT(SLIPPI_ONLINE, "Found user {} ({})", m_user_info.display_name, m_user_info.uid); } return m_is_logged_in; @@ -158,14 +158,14 @@ void SlippiUser::OpenLogInPage() #endif #ifndef __APPLE__ - char* escaped_path = curl_easy_escape(nullptr, path.c_str(), (int)path.length()); + char* escaped_path = curl_easy_escape(nullptr, path.c_str(), static_cast(path.length())); path = std::string(escaped_path); curl_free(escaped_path); #endif std::string full_url = url + "?path=" + path; - INFO_LOG(SLIPPI_ONLINE, "[User] Login at path: %s", full_url.c_str()); + INFO_LOG_FMT(SLIPPI_ONLINE, "[User] Login at path: {}", full_url); #ifdef _WIN32 std::string command = "explorer \"" + full_url + "\""; @@ -181,23 +181,24 @@ void SlippiUser::OpenLogInPage() void SlippiUser::UpdateApp() { #if defined(__APPLE__) || defined(_WIN32) - CriticalAlertT("Dolphin auto updates are not available on standalone builds. Migrate to " - "the Slippi Launcher at your earliest convenience"); + CriticalAlertFmtT("Dolphin auto updates are not available on standalone builds. Migrate to " + "the Slippi Launcher at your earliest convenience"); return; #else const char* appimage_path = getenv("APPIMAGE"); const char* appmount_path = getenv("APPDIR"); if (!appimage_path) { - CriticalAlertT("Automatic updates are not available for non-AppImage Linux builds."); + CriticalAlertFmtT("Automatic updates are not available for non-AppImage Linux builds."); return; } std::string path(appimage_path); std::string mount_path(appmount_path); std::string command = mount_path + "/usr/bin/appimageupdatetool " + path; - WARN_LOG(SLIPPI, "Executing app update command: %s", command.c_str()); + WARN_LOG_FMT(SLIPPI, "Executing app update command: {}", command); RunSystemCommand(command); - CriticalAlertT("Dolphin failed to update, please head over to the Slippi Discord for support."); + CriticalAlertFmtT( + "Dolphin failed to update, please head over to the Slippi Discord for support."); return; #endif } @@ -317,7 +318,8 @@ void SlippiUser::overwriteFromServer() if (res != 0) { - ERROR_LOG(SLIPPI, "[User] Error fetching user info from server, code: %d", res); + ERROR_LOG_FMT(SLIPPI, "[User] Error fetching user info from server, code: {}", + static_cast(res)); return; } @@ -325,7 +327,7 @@ void SlippiUser::overwriteFromServer() curl_easy_getinfo(m_curl, CURLINFO_RESPONSE_CODE, &response_code); if (response_code != 200) { - ERROR_LOG(SLIPPI, "[User] Server responded with non-success status: %d", response_code); + ERROR_LOG_FMT(SLIPPI, "[User] Server responded with non-success status: {}", response_code); return; } diff --git a/Source/Core/DolphinNoGUI/CMakeLists.txt b/Source/Core/DolphinNoGUI/CMakeLists.txt index 202a612b5d..d612ff7b1d 100644 --- a/Source/Core/DolphinNoGUI/CMakeLists.txt +++ b/Source/Core/DolphinNoGUI/CMakeLists.txt @@ -20,10 +20,13 @@ endif() set_target_properties(dolphin-nogui PROPERTIES OUTPUT_NAME dolphin-emu-nogui) target_link_libraries(dolphin-nogui +PUBLIC + z PRIVATE core uicommon cpp-optparse + ZLIB::ZLIB ) if(MSVC) diff --git a/Source/Core/DolphinQt/HotkeyScheduler.cpp b/Source/Core/DolphinQt/HotkeyScheduler.cpp index 5655430c80..7eb4394448 100644 --- a/Source/Core/DolphinQt/HotkeyScheduler.cpp +++ b/Source/Core/DolphinQt/HotkeyScheduler.cpp @@ -28,9 +28,9 @@ #include "Core/HotkeyManager.h" #include "Core/IOS/IOS.h" #include "Core/IOS/USB/Bluetooth/BTBase.h" +#include "Core/IOS/USB/Bluetooth/BTReal.h" #include "Core/Slippi/SlippiNetplay.h" #include "Core/Slippi/SlippiPlayback.h" -#include "Core/IOS/USB/Bluetooth/BTReal.h" #include "Core/State.h" #include "Core/System.h" #include "Core/WiiUtils.h" @@ -560,7 +560,7 @@ void HotkeyScheduler::Run() // Slippi Playback if (IsHotkey(HK_SLIPPI_JUMP_BACK)) { - INFO_LOG(SLIPPI, "jump back"); + INFO_LOG_FMT(SLIPPI, "jump back"); if (g_playbackStatus->targetFrameNum == INT_MAX) { g_playbackStatus->targetFrameNum = g_playbackStatus->currentPlaybackFrame - 1200; @@ -570,7 +570,7 @@ void HotkeyScheduler::Run() if (IsHotkey(HK_SLIPPI_STEP_BACK)) { - INFO_LOG(SLIPPI, "step back"); + INFO_LOG_FMT(SLIPPI, "step back"); if (g_playbackStatus->targetFrameNum == INT_MAX) { g_playbackStatus->targetFrameNum = g_playbackStatus->currentPlaybackFrame - 300; @@ -580,7 +580,7 @@ void HotkeyScheduler::Run() if (IsHotkey(HK_SLIPPI_STEP_FORWARD)) { - INFO_LOG(SLIPPI, "step forward"); + INFO_LOG_FMT(SLIPPI, "step forward"); if (g_playbackStatus->targetFrameNum == INT_MAX) { g_playbackStatus->targetFrameNum = g_playbackStatus->currentPlaybackFrame + 300; @@ -590,7 +590,7 @@ void HotkeyScheduler::Run() if (IsHotkey(HK_SLIPPI_JUMP_FORWARD)) { - INFO_LOG(SLIPPI, "jump forward"); + INFO_LOG_FMT(SLIPPI, "jump forward"); if (g_playbackStatus->targetFrameNum == INT_MAX) { g_playbackStatus->targetFrameNum = g_playbackStatus->currentPlaybackFrame + 1200; diff --git a/Source/Core/DolphinQt/Main.cpp b/Source/Core/DolphinQt/Main.cpp index 217c28029b..2d547037a8 100644 --- a/Source/Core/DolphinQt/Main.cpp +++ b/Source/Core/DolphinQt/Main.cpp @@ -27,8 +27,8 @@ #include "Core/Boot/Boot.h" #include "Core/Config/MainSettings.h" #include "Core/Core.h" -#include "Core/Slippi/SlippiSpectate.h" #include "Core/DolphinAnalytics.h" +#include "Core/Slippi/SlippiSpectate.h" #include "DolphinQt/Host.h" #include "DolphinQt/MainWindow.h" @@ -261,10 +261,12 @@ int main(int argc, char* argv[]) else { #ifndef IS_PLAYBACK - if (Settings::Instance().IsBootDefaultISO() && !Settings::Instance().GetDefaultGame().isEmpty()) + if (!Config::Get(Config::MAIN_DEFAULT_ISO).empty() && + !Settings::Instance().GetDefaultGame().isEmpty()) { - boot = BootParameters::GenerateFromFile(Settings::Instance().GetDefaultGame().toStdString(), - save_state_path); + boot = BootParameters::GenerateFromFile( + Settings::Instance().GetDefaultGame().toStdString(), + BootSessionData(save_state_path, DeleteSavestateAfterBoot::No)); } #endif diff --git a/Source/Core/DolphinQt/Settings.cpp b/Source/Core/DolphinQt/Settings.cpp index fdb8fcb9a6..96b042d003 100644 --- a/Source/Core/DolphinQt/Settings.cpp +++ b/Source/Core/DolphinQt/Settings.cpp @@ -715,11 +715,6 @@ void Settings::SetSlippiSeekbarEnabled(bool enabled) SConfig::GetInstance().m_slippiEnableSeek = enabled; } -bool Settings::IsBootDefaultISO() const -{ - return SConfig::GetInstance().bBootDefaultISO; -} - bool Settings::IsSDCardInserted() const { return Config::Get(Config::MAIN_WII_SD_CARD); diff --git a/Source/Core/DolphinQt/Settings.h b/Source/Core/DolphinQt/Settings.h index 7b88ee0db3..52c56692dd 100644 --- a/Source/Core/DolphinQt/Settings.h +++ b/Source/Core/DolphinQt/Settings.h @@ -103,7 +103,6 @@ public: void SetSDCardInserted(bool inserted); bool IsUSBKeyboardConnected() const; void SetUSBKeyboardConnected(bool connected); - bool IsBootDefaultISO() const; // Graphics void SetCursorVisibility(Config::ShowCursor hideCursor); diff --git a/Source/Core/DolphinQt/Settings/GeneralPane.cpp b/Source/Core/DolphinQt/Settings/GeneralPane.cpp index 9bc3a4ab84..507eec70de 100644 --- a/Source/Core/DolphinQt/Settings/GeneralPane.cpp +++ b/Source/Core/DolphinQt/Settings/GeneralPane.cpp @@ -211,11 +211,13 @@ void GeneralPane::CreateAnalytics() void GeneralPane::LoadConfig() { - m_checkbox_dualcore->setChecked(SConfig::GetInstance().bCPUThread); - m_checkbox_cheats->setChecked(Settings::Instance().GetCheatsEnabled()); - m_checkbox_default_boot_iso->setChecked(SConfig::GetInstance().bBootDefaultISO); - m_checkbox_override_region_settings->setChecked(SConfig::GetInstance().bOverrideRegionSettings); - m_checkbox_auto_disc_change->setChecked(Config::Get(Config::MAIN_AUTO_DISC_CHANGE)); + const QSignalBlocker blocker(this); + SignalBlocking(m_checkbox_dualcore)->setChecked(Config::Get(Config::MAIN_CPU_THREAD)); + SignalBlocking(m_checkbox_cheats)->setChecked(Settings::Instance().GetCheatsEnabled()); + SignalBlocking(m_checkbox_override_region_settings) + ->setChecked(Config::Get(Config::MAIN_OVERRIDE_REGION_SETTINGS)); + SignalBlocking(m_checkbox_auto_disc_change) + ->setChecked(Config::Get(Config::MAIN_AUTO_DISC_CHANGE)); #ifdef USE_DISCORD_PRESENCE SignalBlocking(m_checkbox_discord_presence) ->setChecked(Config::Get(Config::MAIN_USE_DISCORD_PRESENCE)); @@ -278,14 +280,10 @@ void GeneralPane::OnSaveConfig() #endif Config::SetBaseOrCurrent(Config::MAIN_CPU_THREAD, m_checkbox_dualcore->isChecked()); Settings::Instance().SetCheatsEnabled(m_checkbox_cheats->isChecked()); - settings.bBootDefaultISO = m_checkbox_default_boot_iso->isChecked(); - settings.bOverrideRegionSettings = m_checkbox_override_region_settings->isChecked(); Config::SetBaseOrCurrent(Config::MAIN_OVERRIDE_REGION_SETTINGS, m_checkbox_override_region_settings->isChecked()); Config::SetBase(Config::MAIN_AUTO_DISC_CHANGE, m_checkbox_auto_disc_change->isChecked()); Config::SetBaseOrCurrent(Config::MAIN_ENABLE_CHEATS, m_checkbox_cheats->isChecked()); - if (!IsOnline()) - settings.m_EmulationSpeed = m_combobox_speedlimit->currentIndex() * 0.1f; Settings::Instance().SetFallbackRegion( UpdateFallbackRegionFromIndex(m_combobox_fallback_region->currentIndex())); diff --git a/Source/Core/DolphinQt/Settings/SlippiPane.cpp b/Source/Core/DolphinQt/Settings/SlippiPane.cpp index 74cfeaf624..88450c61cd 100644 --- a/Source/Core/DolphinQt/Settings/SlippiPane.cpp +++ b/Source/Core/DolphinQt/Settings/SlippiPane.cpp @@ -92,7 +92,8 @@ void SlippiPane::CreateLayout() [](int index) { SConfig::GetInstance().m_slippiEnableQuickChat = static_cast(index); }); - netplay_quick_chat_combo->setCurrentIndex(SConfig::GetInstance().m_slippiEnableQuickChat); + netplay_quick_chat_combo->setCurrentIndex( + static_cast(SConfig::GetInstance().m_slippiEnableQuickChat)); online_settings_layout->addRow(tr("Quick Chat:"), netplay_quick_chat_combo); diff --git a/Source/Core/VideoCommon/OnScreenDisplay.cpp b/Source/Core/VideoCommon/OnScreenDisplay.cpp index 29ea62bbf9..e66b985395 100644 --- a/Source/Core/VideoCommon/OnScreenDisplay.cpp +++ b/Source/Core/VideoCommon/OnScreenDisplay.cpp @@ -187,15 +187,13 @@ static std::string GetTimeForFrame(s32 currFrame) bool show_help = false; bool show_settings = false; -u32 idle_tick = Common::Timer::GetTimeMs(); +u32 idle_tick = Common::Timer::NowMs(); ImVec2 prev_mouse(0, 0); -bool ButtonCustom( - const char* label, - const ImVec2& size_arg, - ImU32 fill = ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 0.0f)), - ImU32 hover_fill = ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 0.0f)), - ImGuiButtonFlags flags = 0) +bool ButtonCustom(const char* label, const ImVec2& size_arg, + ImU32 fill = ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 0.0f)), + ImU32 hover_fill = ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 0.0f)), + ImGuiButtonFlags flags = 0) { // ImGui::GetWindowDrawList()->AddRectFilled( // ImGui::GetCurrentWindow()->DC.CursorPos, @@ -358,10 +356,10 @@ bool SeekBarBehavior(const ImRect& bb, ImGuiID id, int* v, int v_min, int v_max, else isHeld = hovered && isDown; - float new_grab_t = ImGui::SliderCalcRatioFromValueT( - ImGuiDataType_S32, new_value, v_min, v_max, power, linear_zero_pos); - float curr_grab_t = ImGui::SliderCalcRatioFromValueT(ImGuiDataType_S32, *v, v_min, - v_max, power, linear_zero_pos); + float new_grab_t = ImGui::ScaleRatioFromValueT(ImGuiDataType_S32, new_value, v_min, + v_max, power, linear_zero_pos); + float curr_grab_t = ImGui::ScaleRatioFromValueT(ImGuiDataType_S32, *v, v_min, v_max, + power, linear_zero_pos); if (axis == ImGuiAxis_Y) { @@ -513,8 +511,8 @@ bool VolumeBarBehavior(const ImRect& bb, ImGuiID id, int* v, int v_min, int v_ma isHeld = isHeld ? isHeld && isDown : hovered && isDown; - float grab_t = ImGui::SliderCalcRatioFromValueT(ImGuiDataType_S32, *v, v_min, v_max, - power, linear_zero_pos); + float grab_t = ImGui::ScaleRatioFromValueT(ImGuiDataType_S32, *v, v_min, v_max, power, + linear_zero_pos); if (axis == ImGuiAxis_Y) { grab_t = 1.0f - grab_t; @@ -595,7 +593,7 @@ void DrawSlippiPlaybackControls() auto mousePos = ImGui::GetMousePos(); - auto currTime = Common::Timer::GetTimeMs(); + auto currTime = Common::Timer::NowMs(); if (!(mousePos[0] == prev_mouse[0] && mousePos[1] == prev_mouse[1])) { idle_tick = currTime; @@ -640,7 +638,7 @@ void DrawSlippiPlaybackControls() ImGui::SetCursorPos(ImVec2(0.0f, height - scaled_height * 0.0265f)); ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.5f, 0.45f)); // if (ButtonCustom(paused ? ICON_FA_PLAY : ICON_FA_PAUSE, ImVec2(40.0f, BUTTON_WIDTH))) { - // INFO_LOG(SLIPPI, "playing"); + // INFO_LOG_FMT(SLIPPI, "playing"); //} // ImGui::SameLine(0.0f, 5.0f); if (ButtonCustom(ICON_FA_FAST_BACKWARD, ImVec2(BUTTON_WIDTH, BUTTON_WIDTH))) @@ -757,39 +755,39 @@ void DrawSlippiPlaybackControls() if (show_help) { ImGui::GetWindowDrawList()->AddRectFilled( - ImVec2(width - BUTTON_WIDTH * 10.0f, height - scaled_height * 0.21f), - ImVec2(width - BUTTON_WIDTH, LABEL_BOX_BOTTOM), - ImGui::ColorConvertFloat4ToU32(ImVec4(0.0f, 0.0f, 0.0f, 0.8f * style.Alpha))); + ImVec2(width - BUTTON_WIDTH * 10.0f, height - scaled_height * 0.21f), + ImVec2(width - BUTTON_WIDTH, LABEL_BOX_BOTTOM), + ImGui::ColorConvertFloat4ToU32(ImVec4(0.0f, 0.0f, 0.0f, 0.8f * style.Alpha))); auto divide = - (height - scaled_height * 0.2f - LABEL_BOX_BOTTOM - 0.01f * scaled_height) / 7.0f; + (height - scaled_height * 0.2f - LABEL_BOX_BOTTOM - 0.01f * scaled_height) / 7.0f; ImGui::SetCursorPos(ImVec2(width - BUTTON_WIDTH * 10.0f + scaled_height * 0.005f, - LABEL_BOX_BOTTOM + 0.005f * scaled_height + divide * 7.0f)); + LABEL_BOX_BOTTOM + 0.005f * scaled_height + divide * 7.0f)); ImGui::Text("Play/Pause: Spacebar"); ImGui::SetCursorPos(ImVec2(width - BUTTON_WIDTH * 10.0f + scaled_height * 0.005f, - LABEL_BOX_BOTTOM + 0.005f * scaled_height + divide * 6.0f)); + LABEL_BOX_BOTTOM + 0.005f * scaled_height + divide * 6.0f)); ImGui::Text("Step Back (5s): Left Arrow"); ImGui::SetCursorPos(ImVec2(width - BUTTON_WIDTH * 10.0f + scaled_height * 0.005f, - LABEL_BOX_BOTTOM + 0.005f * scaled_height + divide * 5.0f)); + LABEL_BOX_BOTTOM + 0.005f * scaled_height + divide * 5.0f)); ImGui::Text("Step Forward (5s): Right Arrow"); ImGui::SetCursorPos(ImVec2(width - BUTTON_WIDTH * 10.0f + scaled_height * 0.005f, - LABEL_BOX_BOTTOM + 0.005f * scaled_height + divide * 4.0f)); + LABEL_BOX_BOTTOM + 0.005f * scaled_height + divide * 4.0f)); ImGui::Text("Jump Back (20s): Shift + Left Arrow"); ImGui::SetCursorPos(ImVec2(width - BUTTON_WIDTH * 10.0f + scaled_height * 0.005f, - LABEL_BOX_BOTTOM + 0.005f * scaled_height + divide * 3.0f)); + LABEL_BOX_BOTTOM + 0.005f * scaled_height + divide * 3.0f)); ImGui::Text("Jump Forward (20s): Shift + Right Arrow"); ImGui::SetCursorPos(ImVec2(width - BUTTON_WIDTH * 10.0f + scaled_height * 0.005f, - LABEL_BOX_BOTTOM + 0.005f * scaled_height + divide * 2.0f)); + LABEL_BOX_BOTTOM + 0.005f * scaled_height + divide * 2.0f)); ImGui::Text("Frame Advance: Period"); ImGui::SetCursorPos(ImVec2(width - BUTTON_WIDTH * 10.0f + scaled_height * 0.005f, - LABEL_BOX_BOTTOM + 0.005f * scaled_height + divide)); + LABEL_BOX_BOTTOM + 0.005f * scaled_height + divide)); ImGui::Text("Big jumps may take several seconds."); } if (ImGui::IsItemHovered() && !show_help) { ImGui::GetWindowDrawList()->AddRectFilled( - ImVec2(width - scaled_height * 0.095f, LABEL_BOX_TOP), - ImVec2(width - (scaled_height * 0.005f + BUTTON_WIDTH), LABEL_BOX_BOTTOM), - ImGui::ColorConvertFloat4ToU32(ImVec4(0.0f, 0.0f, 0.0f, 0.9f))); + ImVec2(width - scaled_height * 0.095f, LABEL_BOX_TOP), + ImVec2(width - (scaled_height * 0.005f + BUTTON_WIDTH), LABEL_BOX_BOTTOM), + ImGui::ColorConvertFloat4ToU32(ImVec4(0.0f, 0.0f, 0.0f, 0.9f))); ImGui::SetCursorPos(ImVec2(width - (scaled_height * 0.09f), LABEL_TEXT_HEIGHT)); ImGui::Text("View Help"); } @@ -803,7 +801,7 @@ void DrawSlippiPlaybackControls() } if (show_settings) { - //bool show_speed_options = false; + // bool show_speed_options = false; auto option_height = (scaled_height * 0.05f) / 2.0f; ImGui::GetWindowDrawList()->AddRectFilled( @@ -811,47 +809,45 @@ void DrawSlippiPlaybackControls() ImVec2(width - BUTTON_WIDTH, LABEL_BOX_BOTTOM), ImGui::ColorConvertFloat4ToU32(ImVec4(0.0f, 0.0f, 0.0f, 0.8f * style.Alpha))); - ImGui::SetCursorPos(ImVec2(width - BUTTON_WIDTH * 5.0f + 0.005 * scaled_height, LABEL_BOX_BOTTOM - option_height * 4.0f + 0.005 * scaled_height)); + ImGui::SetCursorPos(ImVec2(width - BUTTON_WIDTH * 5.0f + 0.005 * scaled_height, + LABEL_BOX_BOTTOM - option_height * 4.0f + 0.005 * scaled_height)); ImGui::Text("Playback Speed"); - auto quarter_speed = ImRect( - ImVec2(width - BUTTON_WIDTH * 5.0f, LABEL_BOX_BOTTOM - option_height * 3.0f), - ImVec2(width - BUTTON_WIDTH, LABEL_BOX_BOTTOM - option_height * 2.0)); - auto half_speed = ImRect( - ImVec2(width - BUTTON_WIDTH * 5.0f, LABEL_BOX_BOTTOM - option_height * 2.0f), - ImVec2(width - BUTTON_WIDTH, LABEL_BOX_BOTTOM - option_height)); - auto normal_speed = ImRect( - ImVec2(width - BUTTON_WIDTH * 5.0f, LABEL_BOX_BOTTOM - option_height), - ImVec2(width - BUTTON_WIDTH, LABEL_BOX_BOTTOM)); + auto quarter_speed = + ImRect(ImVec2(width - BUTTON_WIDTH * 5.0f, LABEL_BOX_BOTTOM - option_height * 3.0f), + ImVec2(width - BUTTON_WIDTH, LABEL_BOX_BOTTOM - option_height * 2.0)); + auto half_speed = + ImRect(ImVec2(width - BUTTON_WIDTH * 5.0f, LABEL_BOX_BOTTOM - option_height * 2.0f), + ImVec2(width - BUTTON_WIDTH, LABEL_BOX_BOTTOM - option_height)); + auto normal_speed = + ImRect(ImVec2(width - BUTTON_WIDTH * 5.0f, LABEL_BOX_BOTTOM - option_height), + ImVec2(width - BUTTON_WIDTH, LABEL_BOX_BOTTOM)); - ImGui::SetCursorPos(ImVec2(width - BUTTON_WIDTH * 5.0f, LABEL_BOX_BOTTOM - option_height * 3.0f)); + ImGui::SetCursorPos( + ImVec2(width - BUTTON_WIDTH * 5.0f, LABEL_BOX_BOTTOM - option_height * 3.0f)); if (ButtonCustom( - "0.25", - ImVec2(quarter_speed.GetWidth(), quarter_speed.GetHeight()), - ImGui::ColorConvertFloat4ToU32(ImVec4(0.0f, 0.0f, 0.0f, 0.0f)), - ImGui::ColorConvertFloat4ToU32(ImVec4(255.0f, 255.0f, 255.0f, 0.3f * style.Alpha)) - )) + "0.25", ImVec2(quarter_speed.GetWidth(), quarter_speed.GetHeight()), + ImGui::ColorConvertFloat4ToU32(ImVec4(0.0f, 0.0f, 0.0f, 0.0f)), + ImGui::ColorConvertFloat4ToU32(ImVec4(255.0f, 255.0f, 255.0f, 0.3f * style.Alpha)))) { SConfig::GetInstance().m_EmulationSpeed = 0.25f; } - ImGui::SetCursorPos(ImVec2(width - BUTTON_WIDTH * 5.0f, LABEL_BOX_BOTTOM - option_height * 2.0f)); + ImGui::SetCursorPos( + ImVec2(width - BUTTON_WIDTH * 5.0f, LABEL_BOX_BOTTOM - option_height * 2.0f)); if (ButtonCustom( - "0.5", - ImVec2(half_speed.GetWidth(), half_speed.GetHeight()), - ImGui::ColorConvertFloat4ToU32(ImVec4(0.0f, 0.0f, 0.0f, 0.0f)), - ImGui::ColorConvertFloat4ToU32(ImVec4(255.0f, 255.0f, 255.0f, 0.3f * style.Alpha)) - )) + "0.5", ImVec2(half_speed.GetWidth(), half_speed.GetHeight()), + ImGui::ColorConvertFloat4ToU32(ImVec4(0.0f, 0.0f, 0.0f, 0.0f)), + ImGui::ColorConvertFloat4ToU32(ImVec4(255.0f, 255.0f, 255.0f, 0.3f * style.Alpha)))) { SConfig::GetInstance().m_EmulationSpeed = 0.5f; } - ImGui::SetCursorPos(ImVec2(width - BUTTON_WIDTH * 5.0f, LABEL_BOX_BOTTOM - option_height * 1.0f)); + ImGui::SetCursorPos( + ImVec2(width - BUTTON_WIDTH * 5.0f, LABEL_BOX_BOTTOM - option_height * 1.0f)); if (ButtonCustom( - "Normal", - ImVec2(normal_speed.GetWidth(), normal_speed.GetHeight()), - ImGui::ColorConvertFloat4ToU32(ImVec4(0.0f, 0.0f, 0.0f, 0.0f)), - ImGui::ColorConvertFloat4ToU32(ImVec4(255.0f, 255.0f, 255.0f, 0.3f * style.Alpha)) - )) + "Normal", ImVec2(normal_speed.GetWidth(), normal_speed.GetHeight()), + ImGui::ColorConvertFloat4ToU32(ImVec4(0.0f, 0.0f, 0.0f, 0.0f)), + ImGui::ColorConvertFloat4ToU32(ImVec4(255.0f, 255.0f, 255.0f, 0.3f * style.Alpha)))) { SConfig::GetInstance().m_EmulationSpeed = 1.0f; } @@ -859,9 +855,9 @@ void DrawSlippiPlaybackControls() if (ImGui::IsItemHovered() && !show_settings) { ImGui::GetWindowDrawList()->AddRectFilled( - ImVec2(width - scaled_height * 0.087f, LABEL_BOX_TOP), - ImVec2(width - (scaled_height * 0.005f + BUTTON_WIDTH), LABEL_BOX_BOTTOM), - ImGui::ColorConvertFloat4ToU32(ImVec4(0.0f, 0.0f, 0.0f, 0.9f))); + ImVec2(width - scaled_height * 0.087f, LABEL_BOX_TOP), + ImVec2(width - (scaled_height * 0.005f + BUTTON_WIDTH), LABEL_BOX_BOTTOM), + ImGui::ColorConvertFloat4ToU32(ImVec4(0.0f, 0.0f, 0.0f, 0.9f))); ImGui::SetCursorPos(ImVec2(width - (scaled_height * 0.082f), LABEL_TEXT_HEIGHT)); ImGui::Text("Settings"); }