mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
Merge pull request #10209 from Pokechu22/assert-fmt
Assertion and panic alert improvements
This commit is contained in:
@@ -10,16 +10,10 @@ SRCDIR=Source
|
||||
find $SRCDIR -name '*.cpp' -o -name '*.h' -o -name '*.c' | \
|
||||
xgettext -s -p ./Languages/po -o dolphin-emu.pot --package-name="Dolphin Emulator" \
|
||||
--keyword=_ \
|
||||
--keyword=wxTRANSLATE \
|
||||
--keyword=AskYesNoT \
|
||||
--keyword=AskYesNoFmtT \
|
||||
--keyword=CriticalAlertT \
|
||||
--keyword=CriticalAlertFmtT \
|
||||
--keyword=PanicAlertT \
|
||||
--keyword=PanicAlertFmtT \
|
||||
--keyword=PanicYesNoT \
|
||||
--keyword=PanicYesNoFmtT \
|
||||
--keyword=SuccessAlertT \
|
||||
--keyword=SuccessAlertFmtT \
|
||||
--keyword=GetStringT \
|
||||
--keyword=_trans \
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <UICommon/GameFile.h>
|
||||
#include <android/log.h>
|
||||
#include <android/native_window_jni.h>
|
||||
#include <cinttypes>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <jni.h>
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <thread>
|
||||
|
||||
#include "Common/Assert.h"
|
||||
#include "Common/HRWrap.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Common/StringUtil.h"
|
||||
#include "Common/Thread.h"
|
||||
@@ -66,11 +67,11 @@ static bool HandleWinAPI(std::string_view message, HRESULT result)
|
||||
error = "Audio endpoint already in use!";
|
||||
break;
|
||||
default:
|
||||
error = TStrToUTF8(_com_error(result).ErrorMessage()).c_str();
|
||||
error = Common::GetHResultMessage(result);
|
||||
break;
|
||||
}
|
||||
|
||||
ERROR_LOG_FMT(AUDIO, "WASAPI: {}: {}", message, error);
|
||||
ERROR_LOG_FMT(AUDIO, "WASAPI: {}: {} ({:08x})", message, error, result);
|
||||
}
|
||||
|
||||
return SUCCEEDED(result);
|
||||
|
||||
+120
-126
File diff suppressed because it is too large
Load Diff
+15
-13
@@ -13,31 +13,33 @@
|
||||
{ \
|
||||
if (!(_a_)) \
|
||||
{ \
|
||||
if (!PanicYesNo(_fmt_, ##__VA_ARGS__)) \
|
||||
if (!PanicYesNoFmtAssert(_t_, \
|
||||
"An error occurred.\n\n" _fmt_ "\n\n" \
|
||||
" Condition: {}\n File: {}\n Line: {}\n Function: {}\n\n" \
|
||||
"Ignore and continue?", \
|
||||
##__VA_ARGS__, #_a_, __FILE__, __LINE__, __func__)) \
|
||||
Crash(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DEBUG_ASSERT_MSG(_t_, _a_, _msg_, ...) \
|
||||
#define DEBUG_ASSERT_MSG(_t_, _a_, _fmt_, ...) \
|
||||
do \
|
||||
{ \
|
||||
if constexpr (Common::Log::MAX_LOGLEVEL >= Common::Log::LogLevel::LDEBUG) \
|
||||
{ \
|
||||
if (!(_a_)) \
|
||||
{ \
|
||||
ERROR_LOG(_t_, _msg_, ##__VA_ARGS__); \
|
||||
if (!PanicYesNo(_msg_, ##__VA_ARGS__)) \
|
||||
Crash(); \
|
||||
} \
|
||||
} \
|
||||
ASSERT_MSG(_t_, _a_, _fmt_, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define ASSERT(_a_) \
|
||||
do \
|
||||
{ \
|
||||
ASSERT_MSG(MASTER_LOG, _a_, \
|
||||
_trans("An error occurred.\n\n Line: %d\n File: %s\n\nIgnore and continue?"), \
|
||||
__LINE__, __FILE__); \
|
||||
if (!(_a_)) \
|
||||
{ \
|
||||
if (!PanicYesNoFmt("An error occurred.\n\n" \
|
||||
" Condition: {}\n File: {}\n Line: {}\n Function: {}\n\n" \
|
||||
"Ignore and continue?", \
|
||||
#_a_, __FILE__, __LINE__, __func__)) \
|
||||
Crash(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DEBUG_ASSERT(_a_) \
|
||||
|
||||
@@ -164,7 +164,7 @@ elseif(WIN32)
|
||||
winmm.lib
|
||||
)
|
||||
if (_M_X86_64)
|
||||
target_link_libraries(common PRIVATE opengl32.lib)
|
||||
target_link_libraries(common PRIVATE opengl32.lib)
|
||||
endif()
|
||||
elseif (ANDROID)
|
||||
target_link_libraries(common
|
||||
@@ -286,6 +286,10 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
target_link_libraries(common PUBLIC dl rt)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
target_sources(common PUBLIC HRWrap.h HRWrap.cpp)
|
||||
endif()
|
||||
|
||||
if(USE_UPNP)
|
||||
target_link_libraries(common PRIVATE Miniupnpc::miniupnpc)
|
||||
endif()
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "Common/Assert.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/EnumMap.h"
|
||||
@@ -332,8 +334,8 @@ private:
|
||||
|
||||
case MODE_VERIFY:
|
||||
DEBUG_ASSERT_MSG(COMMON, !memcmp(data, *ptr, size),
|
||||
"Savestate verification failure: buf %p != %p (size %u).\n", data, *ptr,
|
||||
size);
|
||||
"Savestate verification failure: buf {} != {} (size {}).\n", fmt::ptr(data),
|
||||
fmt::ptr(*ptr), size);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#define CHECK_HEAP_INTEGRITY() \
|
||||
{ \
|
||||
if (!_CrtCheckMemory()) \
|
||||
PanicAlert("memory corruption detected. see log."); \
|
||||
PanicAlertFmt("memory corruption detected. see log."); \
|
||||
}
|
||||
// If you want to see how much a pain in the ass singletons are, for example:
|
||||
// {614} normal block at 0x030C5310, 188 bytes long.
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright 2021 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "HRWrap.h"
|
||||
|
||||
#include <comdef.h>
|
||||
#include "Common/StringUtil.h"
|
||||
|
||||
namespace Common
|
||||
{
|
||||
std::string GetHResultMessage(HRESULT hr)
|
||||
{
|
||||
// See https://stackoverflow.com/a/7008111
|
||||
_com_error err(hr);
|
||||
return TStrToUTF8(err.ErrorMessage());
|
||||
}
|
||||
} // namespace Common
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright 2021 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <string>
|
||||
#include <winerror.h>
|
||||
|
||||
namespace Common
|
||||
{
|
||||
std::string GetHResultMessage(HRESULT hr);
|
||||
|
||||
// Wrapper for HRESULT to be used with fmt. Note that we can't create a fmt::formatter directly
|
||||
// for HRESULT as HRESULT is simply a typedef on long and not a distinct type.
|
||||
struct HRWrap
|
||||
{
|
||||
constexpr explicit HRWrap(HRESULT hr) : m_hr(hr) {}
|
||||
const HRESULT m_hr;
|
||||
};
|
||||
} // namespace Common
|
||||
|
||||
template <>
|
||||
struct fmt::formatter<Common::HRWrap>
|
||||
{
|
||||
constexpr auto parse(fmt::format_parse_context& ctx) { return ctx.begin(); }
|
||||
template <typename FormatContext>
|
||||
auto format(const Common::HRWrap& hr, FormatContext& ctx)
|
||||
{
|
||||
return fmt::format_to(ctx.out(), "{} ({:#010x})", Common::GetHResultMessage(hr.m_hr),
|
||||
static_cast<u32>(hr.m_hr));
|
||||
}
|
||||
};
|
||||
@@ -80,7 +80,7 @@ bool SavePNG(const std::string& path, const u8* input, ImageByteFormat format, u
|
||||
byte_per_pixel = 4;
|
||||
break;
|
||||
default:
|
||||
ASSERT_MSG(FRAMEDUMP, false, "Invalid format %d", static_cast<int>(format));
|
||||
ASSERT_MSG(FRAMEDUMP, false, "Invalid format {}", format);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -106,10 +106,14 @@ std::string GetStringT(const char* string)
|
||||
return s_str_translator(string);
|
||||
}
|
||||
|
||||
static bool ShowMessageAlert(std::string_view text, bool yes_no, MsgType style)
|
||||
static bool ShowMessageAlert(std::string_view text, bool yes_no, Common::Log::LogType log_type,
|
||||
MsgType style, const char* file, int line)
|
||||
{
|
||||
const char* caption = GetCaption(style);
|
||||
ERROR_LOG_FMT(MASTER_LOG, "{}: {}", caption, text);
|
||||
// Directly call GenericLogFmt rather than using the normal log macros so that we can use the
|
||||
// caller's line file and line number
|
||||
Common::Log::GenericLogFmt<2>(Common::Log::LogLevel::LERROR, log_type, file, line,
|
||||
FMT_STRING("{}: {}"), caption, text);
|
||||
|
||||
// Panic alerts.
|
||||
if (style == MsgType::Warning && s_abort_on_panic_alert)
|
||||
@@ -127,27 +131,13 @@ static bool ShowMessageAlert(std::string_view text, bool yes_no, MsgType style)
|
||||
return true;
|
||||
}
|
||||
|
||||
// This is the first stop for gui alerts where the log is updated and the
|
||||
// correct window is shown, but only for legacy printf-style messages
|
||||
bool MsgAlert(bool yes_no, MsgType style, const char* format, ...)
|
||||
{
|
||||
char buffer[2048];
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
CharArrayFromFormatV(buffer, sizeof(buffer) - 1, s_str_translator(format).c_str(), args);
|
||||
va_end(args);
|
||||
|
||||
return ShowMessageAlert(buffer, yes_no, style);
|
||||
}
|
||||
|
||||
// This is the first stop for gui alerts where the log is updated and the
|
||||
// correct window is shown, when using fmt
|
||||
bool MsgAlertFmtImpl(bool yes_no, MsgType style, fmt::string_view format,
|
||||
const fmt::format_args& args)
|
||||
bool MsgAlertFmtImpl(bool yes_no, MsgType style, Common::Log::LogType log_type, const char* file,
|
||||
int line, fmt::string_view format, const fmt::format_args& args)
|
||||
{
|
||||
const auto message = fmt::vformat(format, args);
|
||||
|
||||
return ShowMessageAlert(message, yes_no, style);
|
||||
return ShowMessageAlert(message, yes_no, log_type, style, file, line);
|
||||
}
|
||||
} // namespace Common
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "Common/FormatUtil.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
|
||||
namespace Common
|
||||
{
|
||||
@@ -30,22 +31,39 @@ void RegisterStringTranslator(StringTranslator translator);
|
||||
|
||||
std::string GetStringT(const char* string);
|
||||
|
||||
bool MsgAlert(bool yes_no, MsgType style, const char* format, ...)
|
||||
#ifdef __GNUC__
|
||||
__attribute__((format(printf, 3, 4)))
|
||||
#endif
|
||||
;
|
||||
|
||||
bool MsgAlertFmtImpl(bool yes_no, MsgType style, fmt::string_view format,
|
||||
const fmt::format_args& args);
|
||||
bool MsgAlertFmtImpl(bool yes_no, MsgType style, Common::Log::LogType log_type, const char* file,
|
||||
int line, fmt::string_view format, const fmt::format_args& args);
|
||||
|
||||
template <std::size_t NumFields, typename S, typename... Args>
|
||||
bool MsgAlertFmt(bool yes_no, MsgType style, const S& format, const Args&... args)
|
||||
bool MsgAlertFmt(bool yes_no, MsgType style, Common::Log::LogType log_type, const char* file,
|
||||
int line, const S& format, const Args&... args)
|
||||
{
|
||||
static_assert(NumFields == sizeof...(args),
|
||||
"Unexpected number of replacement fields in format string; did you pass too few or "
|
||||
"too many arguments?");
|
||||
return MsgAlertFmtImpl(yes_no, style, format, fmt::make_args_checked<Args...>(format, args...));
|
||||
static_assert(fmt::is_compile_string<S>::value);
|
||||
return MsgAlertFmtImpl(yes_no, style, log_type, file, line, format,
|
||||
fmt::make_args_checked<Args...>(format, args...));
|
||||
}
|
||||
|
||||
template <std::size_t NumFields, bool has_non_positional_args, typename S, typename... Args>
|
||||
bool MsgAlertFmtT(bool yes_no, MsgType style, Common::Log::LogType log_type, const char* file,
|
||||
int line, const S& format, fmt::string_view translated_format,
|
||||
const Args&... args)
|
||||
{
|
||||
static_assert(!has_non_positional_args,
|
||||
"Translatable strings must use positional arguments (e.g. {0} instead of {})");
|
||||
static_assert(NumFields == sizeof...(args),
|
||||
"Unexpected number of replacement fields in format string; did you pass too few or "
|
||||
"too many arguments?");
|
||||
static_assert(fmt::is_compile_string<S>::value);
|
||||
// It's only possible for us to compile-time check the English-language string.
|
||||
// make_args_checked uses static_asserts to verify that a string is formattable with the given
|
||||
// arguments. But it can't do that if the string varies at runtime, so we can't check
|
||||
// translations. Still, verifying that the English string is correct will help ensure that
|
||||
// translations use valid strings.
|
||||
auto arg_list = fmt::make_args_checked<Args...>(format, args...);
|
||||
return MsgAlertFmtImpl(yes_no, style, log_type, file, line, translated_format, arg_list);
|
||||
}
|
||||
|
||||
void SetEnableAlert(bool enable);
|
||||
@@ -59,86 +77,50 @@ std::string FmtFormatT(const char* string, Args&&... args)
|
||||
}
|
||||
} // namespace Common
|
||||
|
||||
// Deprecated variants of the alert macros. See the fmt variants down below.
|
||||
|
||||
#define SuccessAlert(format, ...) \
|
||||
Common::MsgAlert(false, Common::MsgType::Information, format, ##__VA_ARGS__)
|
||||
|
||||
#define PanicAlert(format, ...) \
|
||||
Common::MsgAlert(false, Common::MsgType::Warning, format, ##__VA_ARGS__)
|
||||
|
||||
#define PanicYesNo(format, ...) \
|
||||
Common::MsgAlert(true, Common::MsgType::Warning, format, ##__VA_ARGS__)
|
||||
|
||||
#define AskYesNo(format, ...) \
|
||||
Common::MsgAlert(true, Common::MsgType::Question, format, ##__VA_ARGS__)
|
||||
|
||||
#define CriticalAlert(format, ...) \
|
||||
Common::MsgAlert(false, Common::MsgType::Critical, format, ##__VA_ARGS__)
|
||||
|
||||
// Use these macros (that do the same thing) if the message should be translated.
|
||||
#define SuccessAlertT(format, ...) \
|
||||
Common::MsgAlert(false, Common::MsgType::Information, format, ##__VA_ARGS__)
|
||||
|
||||
#define PanicAlertT(format, ...) \
|
||||
Common::MsgAlert(false, Common::MsgType::Warning, format, ##__VA_ARGS__)
|
||||
|
||||
#define PanicYesNoT(format, ...) \
|
||||
Common::MsgAlert(true, Common::MsgType::Warning, format, ##__VA_ARGS__)
|
||||
|
||||
#define AskYesNoT(format, ...) \
|
||||
Common::MsgAlert(true, Common::MsgType::Question, format, ##__VA_ARGS__)
|
||||
|
||||
#define CriticalAlertT(format, ...) \
|
||||
Common::MsgAlert(false, Common::MsgType::Critical, format, ##__VA_ARGS__)
|
||||
|
||||
// Fmt-capable variants of the macros
|
||||
|
||||
#define GenericAlertFmt(yes_no, style, format, ...) \
|
||||
[&] { \
|
||||
/* Use a macro-like name to avoid shadowing warnings */ \
|
||||
constexpr auto GENERIC_ALERT_FMT_N = Common::CountFmtReplacementFields(format); \
|
||||
return Common::MsgAlertFmt<GENERIC_ALERT_FMT_N>(yes_no, style, FMT_STRING(format), \
|
||||
##__VA_ARGS__); \
|
||||
}()
|
||||
#define GenericAlertFmt(yes_no, style, log_type, format, ...) \
|
||||
Common::MsgAlertFmt<Common::CountFmtReplacementFields(format)>( \
|
||||
yes_no, style, Common::Log::LogType::log_type, __FILE__, __LINE__, FMT_STRING(format), \
|
||||
##__VA_ARGS__)
|
||||
|
||||
#define GenericAlertFmtT(yes_no, style, format, ...) \
|
||||
[&] { \
|
||||
static_assert(!Common::ContainsNonPositionalArguments(format), \
|
||||
"Translatable strings must use positional arguments (e.g. {0} instead of {})"); \
|
||||
/* Use a macro-like name to avoid shadowing warnings */ \
|
||||
constexpr auto GENERIC_ALERT_FMT_N = Common::CountFmtReplacementFields(format); \
|
||||
return Common::MsgAlertFmt<GENERIC_ALERT_FMT_N>(yes_no, style, FMT_STRING(format), \
|
||||
##__VA_ARGS__); \
|
||||
}()
|
||||
#define GenericAlertFmtT(yes_no, style, log_type, format, ...) \
|
||||
Common::MsgAlertFmtT<Common::CountFmtReplacementFields(format), \
|
||||
Common::ContainsNonPositionalArguments(format)>( \
|
||||
yes_no, style, Common::Log::LogType::log_type, __FILE__, __LINE__, FMT_STRING(format), \
|
||||
Common::GetStringT(format), ##__VA_ARGS__)
|
||||
|
||||
#define SuccessAlertFmt(format, ...) \
|
||||
GenericAlertFmt(false, Common::MsgType::Information, format, ##__VA_ARGS__)
|
||||
GenericAlertFmt(false, Common::MsgType::Information, MASTER_LOG, format, ##__VA_ARGS__)
|
||||
|
||||
#define PanicAlertFmt(format, ...) \
|
||||
GenericAlertFmt(false, Common::MsgType::Warning, format, ##__VA_ARGS__)
|
||||
GenericAlertFmt(false, Common::MsgType::Warning, MASTER_LOG, format, ##__VA_ARGS__)
|
||||
|
||||
#define PanicYesNoFmt(format, ...) \
|
||||
GenericAlertFmt(true, Common::MsgType::Warning, format, ##__VA_ARGS__)
|
||||
GenericAlertFmt(true, Common::MsgType::Warning, MASTER_LOG, format, ##__VA_ARGS__)
|
||||
|
||||
#define AskYesNoFmt(format, ...) \
|
||||
GenericAlertFmt(true, Common::MsgType::Question, format, ##__VA_ARGS__)
|
||||
GenericAlertFmt(true, Common::MsgType::Question, MASTER_LOG, format, ##__VA_ARGS__)
|
||||
|
||||
#define CriticalAlertFmt(format, ...) \
|
||||
GenericAlertFmt(false, Common::MsgType::Critical, format, ##__VA_ARGS__)
|
||||
GenericAlertFmt(false, Common::MsgType::Critical, MASTER_LOG, format, ##__VA_ARGS__)
|
||||
|
||||
// Use these macros (that do the same thing) if the message should be translated.
|
||||
#define SuccessAlertFmtT(format, ...) \
|
||||
GenericAlertFmtT(false, Common::MsgType::Information, format, ##__VA_ARGS__)
|
||||
GenericAlertFmtT(false, Common::MsgType::Information, MASTER_LOG, format, ##__VA_ARGS__)
|
||||
|
||||
#define PanicAlertFmtT(format, ...) \
|
||||
GenericAlertFmtT(false, Common::MsgType::Warning, format, ##__VA_ARGS__)
|
||||
GenericAlertFmtT(false, Common::MsgType::Warning, MASTER_LOG, format, ##__VA_ARGS__)
|
||||
|
||||
#define PanicYesNoFmtT(format, ...) \
|
||||
GenericAlertFmtT(true, Common::MsgType::Warning, format, ##__VA_ARGS__)
|
||||
GenericAlertFmtT(true, Common::MsgType::Warning, MASTER_LOG, format, ##__VA_ARGS__)
|
||||
|
||||
#define AskYesNoFmtT(format, ...) \
|
||||
GenericAlertFmtT(true, Common::MsgType::Question, format, ##__VA_ARGS__)
|
||||
GenericAlertFmtT(true, Common::MsgType::Question, MASTER_LOG, format, ##__VA_ARGS__)
|
||||
|
||||
#define CriticalAlertFmtT(format, ...) \
|
||||
GenericAlertFmtT(false, Common::MsgType::Critical, format, ##__VA_ARGS__)
|
||||
GenericAlertFmtT(false, Common::MsgType::Critical, MASTER_LOG, format, ##__VA_ARGS__)
|
||||
|
||||
// Variant that takes a log type, used by the assert macros
|
||||
#define PanicYesNoFmtAssert(log_type, format, ...) \
|
||||
GenericAlertFmt(true, Common::MsgType::Warning, log_type, format, ##__VA_ARGS__)
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include "Common/x64Emitter.h"
|
||||
|
||||
#include <cinttypes>
|
||||
#include <cstring>
|
||||
|
||||
#include "Common/CPUDetect.h"
|
||||
@@ -310,7 +309,7 @@ void OpArg::WriteRest(XEmitter* emit, int extraBytes, X64Reg _operandReg,
|
||||
s64 distance = (s64)offset - (s64)ripAddr;
|
||||
ASSERT_MSG(DYNA_REC,
|
||||
(distance < 0x80000000LL && distance >= -0x80000000LL) || !warn_64bit_offset,
|
||||
"WriteRest: op out of range (0x%" PRIx64 " uses 0x%" PRIx64 ")", ripAddr, offset);
|
||||
"WriteRest: op out of range ({:#x} uses {:#x})", ripAddr, offset);
|
||||
s32 offs = (s32)distance;
|
||||
emit->Write32((u32)offs);
|
||||
return;
|
||||
@@ -440,7 +439,7 @@ void XEmitter::JMP(const u8* addr, bool force5Bytes)
|
||||
{
|
||||
s64 distance = (s64)(fn - ((u64)code + 2));
|
||||
ASSERT_MSG(DYNA_REC, distance >= -0x80 && distance < 0x80,
|
||||
"Jump target too far away, needs force5Bytes = true");
|
||||
"Jump target too far away ({}), needs force5Bytes = true", distance);
|
||||
// 8 bits will do
|
||||
Write8(0xEB);
|
||||
Write8((u8)(s8)distance);
|
||||
@@ -450,7 +449,7 @@ void XEmitter::JMP(const u8* addr, bool force5Bytes)
|
||||
s64 distance = (s64)(fn - ((u64)code + 5));
|
||||
|
||||
ASSERT_MSG(DYNA_REC, distance >= -0x80000000LL && distance < 0x80000000LL,
|
||||
"Jump target too far away, needs indirect register");
|
||||
"Jump target too far away ({}), needs indirect register", distance);
|
||||
Write8(0xE9);
|
||||
Write32((u32)(s32)distance);
|
||||
}
|
||||
@@ -489,7 +488,7 @@ void XEmitter::CALL(const void* fnptr)
|
||||
{
|
||||
u64 distance = u64(fnptr) - (u64(code) + 5);
|
||||
ASSERT_MSG(DYNA_REC, distance < 0x0000000080000000ULL || distance >= 0xFFFFFFFF80000000ULL,
|
||||
"CALL out of range (%p calls %p)", code, fnptr);
|
||||
"CALL out of range ({} calls {})", fmt::ptr(code), fmt::ptr(fnptr));
|
||||
Write8(0xE8);
|
||||
Write32(u32(distance));
|
||||
}
|
||||
@@ -572,7 +571,7 @@ void XEmitter::J_CC(CCFlags conditionCode, const u8* addr)
|
||||
{
|
||||
distance = (s64)(fn - ((u64)code + 6));
|
||||
ASSERT_MSG(DYNA_REC, distance >= -0x80000000LL && distance < 0x80000000LL,
|
||||
"Jump target too far away, needs indirect register");
|
||||
"Jump target too far away ({}), needs indirect register", distance);
|
||||
Write8(0x0F);
|
||||
Write8(0x80 + conditionCode);
|
||||
Write32((u32)(s32)distance);
|
||||
@@ -593,14 +592,14 @@ void XEmitter::SetJumpTarget(const FixupBranch& branch)
|
||||
{
|
||||
s64 distance = (s64)(code - branch.ptr);
|
||||
ASSERT_MSG(DYNA_REC, distance >= -0x80 && distance < 0x80,
|
||||
"Jump target too far away, needs force5Bytes = true");
|
||||
"Jump target too far away ({}), needs force5Bytes = true", distance);
|
||||
branch.ptr[-1] = (u8)(s8)distance;
|
||||
}
|
||||
else if (branch.type == FixupBranch::Type::Branch32Bit)
|
||||
{
|
||||
s64 distance = (s64)(code - branch.ptr);
|
||||
ASSERT_MSG(DYNA_REC, distance >= -0x80000000LL && distance < 0x80000000LL,
|
||||
"Jump target too far away, needs indirect register");
|
||||
"Jump target too far away ({}), needs indirect register", distance);
|
||||
|
||||
s32 valid_distance = static_cast<s32>(distance);
|
||||
std::memcpy(&branch.ptr[-4], &valid_distance, sizeof(s32));
|
||||
@@ -1535,7 +1534,7 @@ void OpArg::WriteNormalOp(XEmitter* emit, bool toRM, NormalOp op, const OpArg& o
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_MSG(DYNA_REC, 0, "WriteNormalOp - Unhandled case %d %d", operand.scale, bits);
|
||||
ASSERT_MSG(DYNA_REC, 0, "WriteNormalOp - Unhandled case {} {}", operand.scale, bits);
|
||||
}
|
||||
|
||||
// pass extension in REG of ModRM
|
||||
|
||||
@@ -476,14 +476,15 @@ void DecryptARCode(std::vector<std::string> vCodes, std::vector<AREntry>* ops)
|
||||
else if (!batchdecrypt(uCodes.data(), (u16)vCodes.size() << 1))
|
||||
{
|
||||
// Commented out since we just send the code anyways and hope for the best XD
|
||||
// PanicAlert("Action Replay Code Decryption Error:\nCRC Check Failed\n\n"
|
||||
// "First Code in Block(should be verification code):\n%s", vCodes[0].c_str());
|
||||
// PanicAlertFmt("Action Replay Code Decryption Error:\nCRC Check Failed\n\n"
|
||||
// "First Code in Block (should be verification code):\n{}",
|
||||
// vCodes[0]);
|
||||
|
||||
for (size_t i = 0; i < (vCodes.size() << 1); i += 2)
|
||||
{
|
||||
ops->emplace_back(uCodes[i], uCodes[i + 1]);
|
||||
// PanicAlert("Decrypted AR Code without verification code:\n%08X %08X", uCodes[i],
|
||||
// uCodes[i+1]);
|
||||
// PanicAlertFmt("Decrypted AR Code without verification code:\n{:08X} {:08X}", uCodes[i],
|
||||
// uCodes[i + 1]);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -492,7 +493,7 @@ void DecryptARCode(std::vector<std::string> vCodes, std::vector<AREntry>* ops)
|
||||
for (size_t i = 2; i < (vCodes.size() << 1); i += 2)
|
||||
{
|
||||
ops->emplace_back(uCodes[i], uCodes[i + 1]);
|
||||
// PanicAlert("Decrypted AR Code:\n%08X %08X", uCodes[i], uCodes[i+1]);
|
||||
// PanicAlertFmt("Decrypted AR Code:\n{:08X} {:08X}", uCodes[i], uCodes[i+1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "Core/ConfigManager.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cinttypes>
|
||||
#include <climits>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
@@ -108,9 +108,9 @@ EventType* RegisterEvent(const std::string& name, TimedCallback callback)
|
||||
// check for existing type with same name.
|
||||
// we want event type names to remain unique so that we can use them for serialization.
|
||||
ASSERT_MSG(POWERPC, s_event_types.find(name) == s_event_types.end(),
|
||||
"CoreTiming Event \"%s\" is already registered. Events should only be registered "
|
||||
"CoreTiming Event \"{}\" is already registered. Events should only be registered "
|
||||
"during Init to avoid breaking save states.",
|
||||
name.c_str());
|
||||
name);
|
||||
|
||||
auto info = s_event_types.emplace(name, EventType{callback, nullptr});
|
||||
EventType* event_type = &info.first->second;
|
||||
@@ -257,7 +257,7 @@ void ScheduleEvent(s64 cycles_into_future, EventType* event_type, u64 userdata,
|
||||
{
|
||||
from_cpu_thread = from == FromThread::CPU;
|
||||
ASSERT_MSG(POWERPC, from_cpu_thread == Core::IsCPUThread(),
|
||||
"A \"%s\" event was scheduled from the wrong thread (%s)", event_type->name->c_str(),
|
||||
"A \"{}\" event was scheduled from the wrong thread ({})", *event_type->name,
|
||||
from_cpu_thread ? "CPU" : "non-CPU");
|
||||
}
|
||||
|
||||
|
||||
@@ -300,7 +300,7 @@ u16 SDSP::ReadRegister(size_t reg) const
|
||||
case DSP_REG_ACM1:
|
||||
return r.ac[reg - DSP_REG_ACM0].m;
|
||||
default:
|
||||
ASSERT_MSG(DSP_CORE, 0, "cannot happen");
|
||||
ASSERT_MSG(DSPLLE, 0, "cannot happen");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -687,7 +687,7 @@ u16 Interpreter::OpReadRegister(int reg_)
|
||||
case DSP_REG_ACM1:
|
||||
return state.r.ac[reg - DSP_REG_ACM0].m;
|
||||
default:
|
||||
ASSERT_MSG(DSP_INT, 0, "cannot happen");
|
||||
ASSERT_MSG(DSPLLE, 0, "cannot happen");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ void DSPEmitter::FallBackToInterpreter(UDSPInstruction inst)
|
||||
const auto interpreter_function = Interpreter::GetOp(inst);
|
||||
|
||||
m_gpr.PushRegs();
|
||||
ASSERT_MSG(DSPLLE, interpreter_function != nullptr, "No function for %04x", inst);
|
||||
ASSERT_MSG(DSPLLE, interpreter_function != nullptr, "No function for {:04x}", inst);
|
||||
ABI_CallFunctionPC(FallbackThunk, &m_dsp_core.GetInterpreter(), inst);
|
||||
m_gpr.PopRegs();
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user