mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-08-22 10:19:01 +00:00
fix all compile errors. no functionality yet (#77)
* fix all compile errors. can't link zlib * fix oopsie * nogui still has zlib error. need to unlink in public. dolphin-gui compiles and runs! * fix cmakelists include
This commit is contained in:
parent
b4b0bf21b3
commit
b3f0422234
47 changed files with 827 additions and 744 deletions
|
@ -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")
|
||||
|
|
19
Externals/SlippiLib/CMakeLists.txt
vendored
19
Externals/SlippiLib/CMakeLists.txt
vendored
|
@ -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})
|
||||
|
3
Externals/imgui/imgui_widgets.cpp
vendored
3
Externals/imgui/imgui_widgets.cpp
vendored
|
@ -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<int, float>(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<typename TYPE, typename SIGNEDTYPE, typename FLOATTYPE>
|
||||
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)
|
||||
|
|
7
Externals/open-vcdiff/CMakeLists.txt
vendored
7
Externals/open-vcdiff/CMakeLists.txt
vendored
|
@ -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)
|
||||
|
|
6
Externals/open-vcdiff/src/checksum.h
vendored
6
Externals/open-vcdiff/src/checksum.h
vendored
|
@ -19,7 +19,7 @@
|
|||
#define OPEN_VCDIFF_CHECKSUM_H_
|
||||
|
||||
#include "config.h"
|
||||
#include "zlib/zlib.h"
|
||||
#include "zlib/zlib_old.h"
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#include <stddef.h>
|
||||
|
@ -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<const Bytef*>(buffer),
|
||||
static_cast<uInt>(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<const Bytef*>(buffer),
|
||||
static_cast<uInt>(size));
|
||||
}
|
||||
|
|
6
Externals/open-vcdiff/src/zlib/adler32.c
vendored
6
Externals/open-vcdiff/src/zlib/adler32.c
vendored
|
@ -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;
|
||||
|
|
|
@ -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
|
|
@ -78,7 +78,6 @@ SpacesInContainerLiterals: true
|
|||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Latest
|
||||
TabWidth: 2
|
||||
UseTab: Never
|
||||
---
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 = "";
|
||||
|
|
|
@ -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<u32>(codelist_base_address + i));
|
||||
PowerPC::HostWrite_U8(guard, bootloaderData[i], static_cast<u32>(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
|
||||
|
|
|
@ -374,11 +374,12 @@ void DVDThread::ReadFile(std::string& fileName, std::vector<u8>& 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
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#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<u8>& 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<u8>& buf);
|
||||
std::string GetFileName(const DiscIO::Partition& partition, u64 offset);
|
||||
|
||||
struct ReadRequest
|
||||
|
|
|
@ -165,7 +165,7 @@ std::unique_ptr<IEXIDevice> EXIDevice_Create(Core::System& system, const EXIDevi
|
|||
break;
|
||||
|
||||
case EXIDeviceType::Slippi:
|
||||
result = std::make_unique<CEXISlippi>();
|
||||
result = std::make_unique<CEXISlippi>(system);
|
||||
break;
|
||||
|
||||
case EXIDeviceType::AMBaseboard:
|
||||
|
|
|
@ -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<SlippiPlaybackStatus> g_playbackStatus;
|
||||
extern std::unique_ptr<SlippiReplayComm> 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<SlippiUser>();
|
||||
g_playbackStatus = std::make_unique<SlippiPlaybackStatus>();
|
||||
|
@ -125,7 +126,7 @@ CEXISlippi::CEXISlippi()
|
|||
directCodes = std::make_unique<SlippiDirectCodes>("direct-codes.json");
|
||||
teamsCodes = std::make_unique<SlippiDirectCodes>("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<WriteMessage> 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<WriteMessage> 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<WriteMessage> msg)
|
|||
{
|
||||
// Write the number of bytes for the raw output
|
||||
std::vector<u8> 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<u8> 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<u32>(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<u8> 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<SlippiMatchmaking> 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
|
||||
|
|
|
@ -4,12 +4,11 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <SlippiGame.h>
|
||||
|
||||
#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;
|
||||
|
|
|
@ -179,7 +179,7 @@ void CameraLogic::Update(const std::array<CameraPoint, NUM_POINTS>& 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<u32, bool> visited;
|
||||
// static std::unordered_map<u32, bool> 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<u32, bool> visited = {};
|
||||
// static std::unordered_map<std::string, bool> 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<u32, bool> visited = {};
|
||||
// static std::unordered_map<std::string, bool> whitelist = {
|
||||
// {"PlayerThink_CameraBehavior", true}, // Per-Player update camera position function
|
||||
// {"CameraFunctionBlrl", true}, // Update camera position
|
||||
//};
|
||||
|
||||
// static std::vector<SlippiSavestate::PreserveBlock> soundStuff = {
|
||||
//
|
||||
//};
|
||||
// static std::vector<SlippiSavestate::PreserveBlock> soundStuff = {
|
||||
//
|
||||
//};
|
||||
|
||||
// auto sceneController = ReadFromHardware<FLAG_READ, u32>(0x80479d30);
|
||||
// if ((sceneController & 0xFF0000FF) != 0x08000002)
|
||||
//{
|
||||
// return;
|
||||
//}
|
||||
|
||||
// auto isLoading = ReadFromHardware<FLAG_READ, u32>(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<Dolphin_Debugger::CallstackEntry> 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<u32, bool> visited = {};
|
||||
// static std::unordered_map<std::string, bool> whitelist = {
|
||||
// {"__AIDHandler", true}, // lol
|
||||
// {"__AXOutAiCallback", true}, // lol
|
||||
// {"__AXOutNewFrame", true}, // lol
|
||||
// {"__AXSyncPBs", true}, // lol
|
||||
// {"SFX_PlaySFX", true}, // lol
|
||||
// {"__DSPHandler", true},
|
||||
//};
|
||||
|
||||
// static std::vector<SlippiSavestate::PreserveBlock> 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<FLAG_READ, u32>(0x80479d30);
|
||||
// if ((sceneController & 0xFF0000FF) != 0x08000002)
|
||||
//{
|
||||
// return;
|
||||
//}
|
||||
|
||||
// auto isLoading = ReadFromHardware<FLAG_READ, u32>(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<Dolphin_Debugger::CallstackEntry> 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<u32, bool> visited = {};
|
||||
|
||||
//auto sceneController = ReadFromHardware<FLAG_READ, u32>(0x80479d30);
|
||||
//if ((sceneController & 0xFF0000FF) != 0x08000002)
|
||||
//{
|
||||
// return;
|
||||
//}
|
||||
|
||||
//auto isLoading = ReadFromHardware<FLAG_READ, u32>(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<FLAG_READ, u32>(0x80479d30);
|
||||
// if ((sceneController & 0xFF0000FF) != 0x08000002)
|
||||
//{
|
||||
// return;
|
||||
//}
|
||||
|
||||
// auto isLoading = ReadFromHardware<FLAG_READ, u32>(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<Dolphin_Debugger::CallstackEntry> 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<u32, bool> visited = {};
|
||||
// static std::unordered_map<std::string, bool> whitelist = {
|
||||
// {"__AIDHandler", true}, // lol
|
||||
// {"__AXOutAiCallback", true}, // lol
|
||||
// {"__AXOutNewFrame", true}, // lol
|
||||
// {"__AXSyncPBs", true}, // lol
|
||||
// {"SFX_PlaySFX", true}, // lol
|
||||
// {"__DSPHandler", true},
|
||||
//};
|
||||
|
||||
// static std::vector<SlippiSavestate::PreserveBlock> 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<FLAG_READ, u32>(0x80479d30);
|
||||
// if ((sceneController & 0xFF0000FF) != 0x08000002)
|
||||
//{
|
||||
// return;
|
||||
//}
|
||||
|
||||
// auto isLoading = ReadFromHardware<FLAG_READ, u32>(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<Dolphin_Debugger::CallstackEntry> 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<u32, bool> visited = {};
|
||||
|
||||
// auto sceneController = ReadFromHardware<FLAG_READ, u32>(0x80479d30);
|
||||
// if ((sceneController & 0xFF0000FF) != 0x08000002)
|
||||
//{
|
||||
// return;
|
||||
// }
|
||||
|
||||
// auto isLoading = ReadFromHardware<FLAG_READ, u32>(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<ReadResult<u32>> HostTryReadInstruction(const Core::CPUThreadGuard& guard,
|
||||
const u32 address,
|
||||
RequestedAddressSpace space)
|
||||
|
|
23
Source/Core/Core/Slippi/SlippiConfig.h
Normal file
23
Source/Core/Core/Slippi/SlippiConfig.h
Normal file
|
@ -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
|
||||
};
|
||||
}
|
|
@ -215,7 +215,7 @@ std::vector<SlippiDirectCodes::CodeInfo> 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<std::array<uint16_t, NAMETAG_SIZE>, 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<std::array<uint8_t, DISPLAY_NAME_SIZE>, 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<std::array<uint8_t, CONNECT_CODE_SIZE>, 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<uint32_t, Slippi::GAME_INFO_HEADER_SIZE> 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<uint32_t, Slippi::GAME_INFO_HEADER_SIZE> 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>();
|
||||
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<uint32_t>(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>();
|
||||
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<uint8_t, PlayerFrameData> *target;
|
||||
std::unordered_map<uint8_t, PlayerFrameData>* 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<uint32_t>(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<uint8_t, uint32_t> getMessageSizes(std::ifstream *f,
|
||||
int position) {
|
||||
std::unordered_map<uint8_t, uint32_t> 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<uint8_t, uint32_t> messageSizes = {
|
||||
{EVENT_PAYLOAD_SIZES, payloadLength}};
|
||||
std::unordered_map<uint8_t, uint32_t> messageSizes = {{EVENT_PAYLOAD_SIZES, payloadLength}};
|
||||
|
||||
std::vector<char> 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<uint8_t, uint32_t> 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> SlippiGame::FromFile(std::string path) {
|
||||
std::unique_ptr<SlippiGame> SlippiGame::FromFile(std::string path)
|
||||
{
|
||||
auto result = std::make_unique<SlippiGame>();
|
||||
result->game = std::make_unique<Game>();
|
||||
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<std::codecvt_utf8<wchar_t>>().from_bytes(path);
|
||||
result->file = std::make_unique<std::ifstream>(
|
||||
convertedPath, std::ios::in | std::ios::binary);
|
||||
std::wstring convertedPath = std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(path);
|
||||
result->file = std::make_unique<std::ifstream>(convertedPath, std::ios::in | std::ios::binary);
|
||||
#else
|
||||
result->file =
|
||||
std::make_unique<std::ifstream>(path, std::ios::in | std::ios::binary);
|
||||
result->file = std::make_unique<std::ifstream>(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> 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<bool>(game->framesByIndex.count(frame));
|
||||
}
|
||||
|
||||
std::array<uint8_t, 4> SlippiGame::GetVersion() { return game->version; }
|
||||
std::array<uint8_t, 4> 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
|
|
@ -8,7 +8,8 @@
|
|||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
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<uint8_t, PlayerFrameData> followers;
|
||||
} FrameData;
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
// Static data
|
||||
uint8_t characterId;
|
||||
uint8_t characterColor;
|
||||
|
@ -89,8 +93,9 @@ typedef struct {
|
|||
std::array<uint8_t, CONNECT_CODE_SIZE> connectCode;
|
||||
} PlayerSettings;
|
||||
|
||||
typedef struct {
|
||||
uint16_t stage; // Stage ID
|
||||
typedef struct
|
||||
{
|
||||
uint16_t stage; // Stage ID
|
||||
uint32_t randomSeed;
|
||||
std::array<uint32_t, GAME_INFO_HEADER_SIZE> header;
|
||||
std::array<uint32_t, UCF_TOGGLE_SIZE> ucfToggles;
|
||||
|
@ -102,14 +107,15 @@ typedef struct {
|
|||
std::vector<uint8_t> geckoCodes;
|
||||
} GameSettings;
|
||||
|
||||
typedef struct Game {
|
||||
typedef struct Game
|
||||
{
|
||||
std::array<uint8_t, 4> version;
|
||||
std::unordered_map<int32_t, FrameData *> framesByIndex;
|
||||
std::unordered_map<int32_t, FrameData*> framesByIndex;
|
||||
std::vector<std::unique_ptr<FrameData>> 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<uint8_t, uint32_t> 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<uint8_t, uint32_t> 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<SlippiGame> FromFile(std::string path);
|
||||
bool AreSettingsLoaded();
|
||||
bool DoesFrameExist(int32_t frame);
|
||||
std::array<uint8_t, 4> 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
|
|
@ -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<u8> 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();
|
||||
}
|
||||
|
|
|
@ -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<u8>(res));
|
||||
}
|
||||
|
||||
gameIndex++;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 <SlippiGame.h>
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
|
@ -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<std::string> 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<std::string> 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<u8>(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<u8>(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>(NetPlay::MessageID::SLIPPI_MATCH_SELECTIONS);
|
||||
packet << static_cast<u8>(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>(NetPlay::MessageID::SLIPPI_CHAT_MESSAGE);
|
||||
packet << static_cast<u8>(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<sf::Packet> 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<bool> 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<u32>(remoteAddrs[i].host),
|
||||
static_cast<u32>(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<u32>(netEvent.peer->address.host),
|
||||
static_cast<u32>(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<u32>(m_server[i]->connectID),
|
||||
static_cast<u32>(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<u8>(m_client->peers[i].state));
|
||||
}
|
||||
INFO_LOG_FMT(SLIPPI_ONLINE, "[Netplay] Not yet connected. Res: {}, Type: {}", net,
|
||||
netEvent.type);
|
||||
static_cast<u8>(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<u32>(m_server[i]->address.host),
|
||||
static_cast<u16>(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<sf::Packet>();
|
||||
*spac << static_cast<NetPlay::MessageId>(NetPlay::MessageID::SLIPPI_CONN_SELECTED);
|
||||
*spac << static_cast<u8>(NetPlay::MessageID::SLIPPI_CONN_SELECTED);
|
||||
SendAsync(std::move(spac));
|
||||
}
|
||||
void SlippiNetplayClient::SendSlippiPad(std::unique_ptr<SlippiPad> pad)
|
||||
|
@ -1037,7 +1043,7 @@ void SlippiNetplayClient::SendSlippiPad(std::unique_ptr<SlippiPad> pad)
|
|||
}
|
||||
auto frame = localPadQueue.front()->frame;
|
||||
auto spac = std::make_unique<sf::Packet>();
|
||||
*spac << static_cast<NetPlay::MessageId>(NetPlay::MessageID::SLIPPI_PAD);
|
||||
*spac << static_cast<u8>(NetPlay::MessageID::SLIPPI_PAD);
|
||||
*spac << frame;
|
||||
*spac << this->m_player_idx;
|
||||
|
||||
|
@ -1045,7 +1051,7 @@ void SlippiNetplayClient::SendSlippiPad(std::unique_ptr<SlippiPad> 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;
|
||||
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
#include <share.h>
|
||||
#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<u8> iState, std::vector<u8> 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<std::mutex> 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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,12 +5,12 @@
|
|||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include <SlippiLib/SlippiGame.h>
|
||||
#include <open-vcdiff/src/google/vcdecoder.h>
|
||||
#include <open-vcdiff/src/google/vcencoder.h>
|
||||
|
||||
#include "../../Common/CommonTypes.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "SlippiGame.h"
|
||||
|
||||
class SlippiPlaybackStatus
|
||||
{
|
||||
|
|
|
@ -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<u8> data = {};
|
||||
std::vector<u8> empty = {};
|
||||
|
@ -222,7 +222,7 @@ public:
|
|||
u16 sht = static_cast<u16>((TEXT_OP_CODE::COMMON_CHARACTER << 8) | pos);
|
||||
u8 r = static_cast<u8>(sht >> 8);
|
||||
u8 r2 = static_cast<u8>(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);
|
||||
|
|
|
@ -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<Slippi::SlippiGame> 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?
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include <SlippiGame.h>
|
||||
#include <limits.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <queue>
|
||||
|
@ -8,6 +7,8 @@
|
|||
|
||||
#include <Common/CommonTypes.h>
|
||||
|
||||
#include "SlippiGame.h"
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
class SlippiReplayComm
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <vector>
|
||||
#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<PreserveBlock> 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<PreserveBlock> blocks)
|
|||
preservationMap[*it] = std::vector<u8>(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<PreserveBlock> 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<SlippiSocket> 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
|
||||
#include <enet/enet.h>
|
||||
#include "Common/SPSCQueue.h"
|
||||
#pragma warning(push, 0)
|
||||
#include "nlohmann/json.hpp"
|
||||
#pragma warning(pop)
|
||||
using json = nlohmann::json;
|
||||
|
||||
// Sockets in windows are unsigned
|
||||
|
|
|
@ -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<int>(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<u8>(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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()));
|
||||
|
||||
|
|
|
@ -92,7 +92,8 @@ void SlippiPane::CreateLayout()
|
|||
[](int index) {
|
||||
SConfig::GetInstance().m_slippiEnableQuickChat = static_cast<Slippi::Chat>(index);
|
||||
});
|
||||
netplay_quick_chat_combo->setCurrentIndex(SConfig::GetInstance().m_slippiEnableQuickChat);
|
||||
netplay_quick_chat_combo->setCurrentIndex(
|
||||
static_cast<u32>(SConfig::GetInstance().m_slippiEnableQuickChat));
|
||||
|
||||
online_settings_layout->addRow(tr("Quick Chat:"), netplay_quick_chat_combo);
|
||||
|
||||
|
|
|
@ -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<int, float>(
|
||||
ImGuiDataType_S32, new_value, v_min, v_max, power, linear_zero_pos);
|
||||
float curr_grab_t = ImGui::SliderCalcRatioFromValueT<int, float>(ImGuiDataType_S32, *v, v_min,
|
||||
v_max, power, linear_zero_pos);
|
||||
float new_grab_t = ImGui::ScaleRatioFromValueT<int, float>(ImGuiDataType_S32, new_value, v_min,
|
||||
v_max, power, linear_zero_pos);
|
||||
float curr_grab_t = ImGui::ScaleRatioFromValueT<int, float>(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<int, float>(ImGuiDataType_S32, *v, v_min, v_max,
|
||||
power, linear_zero_pos);
|
||||
float grab_t = ImGui::ScaleRatioFromValueT<int, float>(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");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue