Compare commits

...

15 Commits

Author SHA1 Message Date
chaoticgd
a507964f33 Debugger: Generate a name map for label symbols 2024-11-16 11:50:19 -05:00
chaoticgd
7584a6bb29 Debugger: Allow symbols starting with an underscore in expressions 2024-11-16 11:50:19 -05:00
chaoticgd
ce6103be30 Debugger: Improve function scanner performance for unmapped addresses 2024-11-16 11:50:19 -05:00
chaoticgd
9da4459ab3 Debugger: Run the function scanner on the main symbol database 2024-11-16 11:50:19 -05:00
chaoticgd
3b9b9a84cd Debugger: Use expressions for the function scanner address range 2024-11-16 11:50:19 -05:00
chaoticgd
cce0ae4369 Debugger: Allow loading symbols conditionally and with a base address 2024-11-16 11:50:19 -05:00
chaoticgd
efb43ac7f9 Debugger: Make the expression parser thread safe 2024-11-16 11:50:19 -05:00
lightningterror
8132a8a7f8 USB: Cleanup eyetoy code a bit.
Types, casts, consts.
2024-11-15 15:58:23 +01:00
PCSX2 Bot
9c753cb692 [ci skip] Qt: Update Base Translation. 2024-11-15 14:26:08 +01:00
Berylskid
514e6675c4 GameDB: Fix Enemies Stuck in Armored Core Nine Breaker 2024-11-14 11:22:00 -05:00
Chromaryu
18454fd5d0 GameDB: Add TexInRT on SLPM-62482 2024-11-14 11:20:03 -05:00
chaoticgd
eeb919325e Misc: Minimise the amount of work done when svnrev.h is updated 2024-11-12 09:14:39 -05:00
Julien Reichardt
959be142ed Deps: Update Flatpak dependencies 2024-11-12 08:36:52 -05:00
PCSX2 Bot
42be91d48d PAD: Update to latest controller database. 2024-11-11 14:20:57 -05:00
Bobby Smith
908f916656 GameDB: NBA 2K6 fix hangs on PAL version 2024-11-11 11:52:44 -05:00
49 changed files with 1028 additions and 693 deletions

View File

@@ -8,8 +8,8 @@
{
"type": "git",
"url": "https://github.com/the-tcpdump-group/libpcap.git",
"tag": "libpcap-1.10.4",
"commit": "104271ba4a14de6743e43bcf87536786d8fddea4"
"tag": "libpcap-1.10.5",
"commit": "bbcbc9174df3298a854daee2b3e666a4b6e5383a"
}
],
"cleanup": [

View File

@@ -1,15 +1,15 @@
{
"app-id": "net.pcsx2.PCSX2",
"runtime": "org.kde.Platform",
"runtime-version": "6.7",
"runtime-version": "6.8",
"sdk": "org.kde.Sdk",
"sdk-extensions": [
"org.freedesktop.Sdk.Extension.llvm17"
"org.freedesktop.Sdk.Extension.llvm18"
],
"add-extensions": {
"org.freedesktop.Platform.ffmpeg-full": {
"directory": "lib/ffmpeg",
"version": "23.08",
"version": "24.08",
"add-ld-path": ".",
"autodownload": true
}
@@ -44,8 +44,8 @@
"config-opts": [
"-DCMAKE_BUILD_TYPE=Release",
"-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON",
"-DCMAKE_C_COMPILER=/usr/lib/sdk/llvm17/bin/clang",
"-DCMAKE_CXX_COMPILER=/usr/lib/sdk/llvm17/bin/clang++",
"-DCMAKE_C_COMPILER=/usr/lib/sdk/llvm18/bin/clang",
"-DCMAKE_CXX_COMPILER=/usr/lib/sdk/llvm18/bin/clang++",
"-DCMAKE_EXE_LINKER_FLAGS_INIT=-fuse-ld=lld",
"-DCMAKE_MODULE_LINKER_FLAGS_INIT=-fuse-ld=lld",
"-DCMAKE_SHARED_LINKER_FLAGS_INIT=-fuse-ld=lld",

View File

@@ -93,7 +93,7 @@ const ElfProgramHeader* ElfFile::entry_point_segment() const
return entry_segment;
}
Result<std::span<const u8>> ElfFile::get_virtual(u32 address, u32 size) const
std::optional<std::span<const u8>> ElfFile::get_virtual(u32 address, u32 size) const
{
u32 end_address = address + size;
@@ -109,17 +109,19 @@ Result<std::span<const u8>> ElfFile::get_virtual(u32 address, u32 size) const
}
}
return CCC_FAILURE("No ELF segment for address range 0x%x to 0x%x.", address, end_address);
return std::nullopt;
}
Result<void> ElfFile::copy_virtual(u8* dest, u32 address, u32 size) const
bool ElfFile::copy_virtual(u8* dest, u32 address, u32 size) const
{
Result<std::span<const u8>> block = get_virtual(address, size);
CCC_RETURN_IF_ERROR(block);
std::optional<std::span<const u8>> block = get_virtual(address, size);
if(!block.has_value()) {
return false;
}
memcpy(dest, block->data(), size);
return Result<void>();
return true;
}
}

View File

@@ -125,18 +125,20 @@ struct ElfFile {
const ElfProgramHeader* entry_point_segment() const;
// Retrieve a block of data in an ELF file given its address and size.
Result<std::span<const u8>> get_virtual(u32 address, u32 size) const;
std::optional<std::span<const u8>> get_virtual(u32 address, u32 size) const;
// Copy a block of data in an ELF file to the destination buffer given its
// address and size.
Result<void> copy_virtual(u8* dest, u32 address, u32 size) const;
bool copy_virtual(u8* dest, u32 address, u32 size) const;
// Retrieve an object of type T from an ELF file given its address.
template <typename T>
Result<T> get_object_virtual(u32 address) const
std::optional<T> get_object_virtual(u32 address) const
{
Result<std::span<const u8>> result = get_virtual(address, sizeof(T));
CCC_RETURN_IF_ERROR(result);
std::optional<std::span<const u8>> result = get_virtual(address, sizeof(T));
if(!result.has_value()) {
return std::nullopt;
}
return *(T*) result->data();
}
@@ -144,10 +146,12 @@ struct ElfFile {
// Retrieve an array of objects of type T from an ELF file given its
// address and element count.
template <typename T>
Result<std::span<const T>> get_array_virtual(u32 address, u32 element_count) const
std::optional<std::span<const T>> get_array_virtual(u32 address, u32 element_count) const
{
Result<std::span<const u8>> result = get_virtual(address, element_count * sizeof(T));
CCC_RETURN_IF_ERROR(result);
std::optional<std::span<const u8>> result = get_virtual(address, element_count * sizeof(T));
if(!result.has_value()) {
return std::nullopt;
}
return std::span<const T>((T*) result->data(), (T*) (result->data() + result->size()));
}

View File

@@ -435,7 +435,7 @@ class Label : public Symbol {
public:
static constexpr const SymbolDescriptor DESCRIPTOR = LABEL;
static constexpr const char* NAME = "Label";
static constexpr u32 FLAGS = WITH_ADDRESS_MAP;
static constexpr u32 FLAGS = WITH_ADDRESS_MAP | WITH_NAME_MAP;
LabelHandle handle() const { return m_handle; }

View File

@@ -100,8 +100,9 @@ Result<std::unique_ptr<SymbolTable>> create_elf_symbol_table(
Result<ModuleHandle> import_symbol_tables(
SymbolDatabase& database,
std::string module_name,
const std::vector<std::unique_ptr<SymbolTable>>& symbol_tables,
std::string module_name,
Address base_address,
u32 importer_flags,
DemanglerFunctions demangler,
const std::atomic_bool* interrupt)
@@ -109,7 +110,8 @@ Result<ModuleHandle> import_symbol_tables(
Result<SymbolSourceHandle> module_source = database.get_symbol_source("Symbol Table Importer");
CCC_RETURN_IF_ERROR(module_source);
Result<Module*> module_symbol = database.modules.create_symbol(std::move(module_name), *module_source, nullptr);
Result<Module*> module_symbol = database.modules.create_symbol(
std::move(module_name), base_address, *module_source, nullptr);
CCC_RETURN_IF_ERROR(module_symbol);
ModuleHandle module_handle = (*module_symbol)->handle();

View File

@@ -71,8 +71,9 @@ Result<std::unique_ptr<SymbolTable>> create_elf_symbol_table(
// and to generate a module handle.
Result<ModuleHandle> import_symbol_tables(
SymbolDatabase& database,
std::string module_name,
const std::vector<std::unique_ptr<SymbolTable>>& symbol_tables,
std::string module_name,
Address base_address,
u32 importer_flags,
DemanglerFunctions demangler,
const std::atomic_bool* interrupt);

View File

@@ -1588,6 +1588,14 @@ SCAJ-20105:
recommendedBlendingLevel: 3 # Fixes level brightness.
cpuSpriteRenderBW: 2 # Fixes broken water on "Upper Sea" level.
cpuSpriteRenderLevel: 2 # Needed for above.
dynaPatches:
- pattern:
- { offset: 0x0, value: 0x3C023E4C }
- { offset: 0x4, value: 0x3442CCCD }
- { offset: 0x8, value: 0xE7A300D0 }
- { offset: 0xC, value: 0xE7A200D4 }
replacement:
- { offset: 0x4, value: 0x3442CCE0 }
SCAJ-20107:
name: "Bakufuu Slash! Kizna Arashi"
region: "NTSC-Unk"
@@ -6914,6 +6922,14 @@ SCKA-20047:
- "SCKA-20047"
- "SLKA-25201"
- "SLKA-25202"
dynaPatches:
- pattern:
- { offset: 0x0, value: 0x3C023E4C }
- { offset: 0x4, value: 0x3442CCCD }
- { offset: 0x8, value: 0xE7A300D0 }
- { offset: 0xC, value: 0xE7A200D4 }
replacement:
- { offset: 0x4, value: 0x3442CCE0 }
SCKA-20048:
name: "Killzone"
region: "NTSC-K"
@@ -22781,11 +22797,27 @@ SLES-53687:
name: "NBA 2K6"
region: "PAL-M5"
patches:
04808D11:
4047DB34: # English
content: |-
author=Prafull
comment=fixes hang at start
patch=1,EE,00441ff8,word,00000000
B91D81A3: # French
content: |-
comment=fixes hang at start
patch=1,EE,00441fa0,word,00000000
C96E2007: # German
content: |-
comment=fixes hang at start
patch=1,EE,00441e48,word,00000000
79A6C879: # Italian
content: |-
comment=fixes hang at start
patch=1,EE,00441de8,word,00000000
08349AAF: # Spanish
content: |-
comment=fixes hang at start
patch=1,EE,00441ec8,word,00000000
SLES-53689:
name: "World Poker Tour 2K6"
region: "PAL-M3"
@@ -23229,6 +23261,14 @@ SLES-53819:
- "SLES-53819"
- "SLES-82036"
- "SLES-82037"
dynaPatches:
- pattern:
- { offset: 0x0, value: 0x3C023E4C }
- { offset: 0x4, value: 0x3442CCCD }
- { offset: 0x8, value: 0xE7A300D0 }
- { offset: 0xC, value: 0xE7A200D4 }
replacement:
- { offset: 0x4, value: 0x3442CCE0 }
SLES-53820:
name: "Armored Core - Last Raven"
region: "PAL-E"
@@ -35406,6 +35446,8 @@ SLPM-62482:
name-sort: "ぱちすろとうこんでんしょう いのきまつり あんとにおいのきというなのぱちすろき あんとにおいのきじしんがぱちすろき"
name-en: "Pachinko Slot Tokodensho - Inoki Festival"
region: "NTSC-J"
gsHWFixes:
textureInsideRT: 1 # Fixes on screen garbage.
SLPM-62483:
name: "SIMPLE2000シリーズ Vol.48 THE タクシー 〜運転手は君だ〜"
name-sort: "しんぷる2000しりーず Vol.48 THE たくしー うんてんしゅはきみだ"
@@ -54257,6 +54299,14 @@ SLPS-25408:
- "SLPS-25339"
- "SLPS-73202"
- "SLPS-73203"
dynaPatches:
- pattern:
- { offset: 0x0, value: 0x3C023E4C }
- { offset: 0x4, value: 0x3442CCCD }
- { offset: 0x8, value: 0xE7A300D0 }
- { offset: 0xC, value: 0xE7A200D4 }
replacement:
- { offset: 0x4, value: 0x3442CCE0 }
SLPS-25409:
name: "双恋—フタコイ— 初回限定版"
name-sort: "ふたこい しょかいげんていばん"
@@ -64574,6 +64624,14 @@ SLUS-21200:
- "SLUS-21200"
- "SLUS-20986"
- "SLUS-21079"
dynaPatches:
- pattern:
- { offset: 0x0, value: 0x3C023E4C }
- { offset: 0x4, value: 0x3442CCCD }
- { offset: 0x8, value: 0xE7A300D0 }
- { offset: 0xC, value: 0xE7A200D4 }
replacement:
- { offset: 0x4, value: 0x3442CCE0 }
SLUS-21201:
name: "Tales of Legendia"
region: "NTSC-U"

View File

@@ -498,6 +498,8 @@
03000000d620000012a7000000000000,PowerA Fusion Nintendo Switch Fight Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000dd62000016a7000000000000,PowerA Fusion Pro Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000d620000013a7000000000000,PowerA Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000d62000002640000000000000,PowerA OPS Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000d62000003340000000000000,PowerA OPS Pro Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000d62000006dca000000000000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
0300000062060000d570000000000000,PowerA PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000d620000014a7000000000000,PowerA Spectra Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,

View File

@@ -7,8 +7,8 @@
#include "QtProgressCallback.h"
#include "QtUtils.h"
#include "pcsx2/BuildVersion.h"
#include "pcsx2/Host.h"
#include "svnrev.h"
#include "updater/UpdaterExtractor.h"
@@ -47,12 +47,6 @@
// Interval at which HTTP requests are polled.
static constexpr u32 HTTP_POLL_INTERVAL = 10;
// Logic to detect whether we can use the auto updater.
// We use tagged commit, because this gets set on nightly builds.
#if (defined(_WIN32) || defined(__linux__) || defined(__APPLE__)) && GIT_TAGGED_COMMIT
#define AUTO_UPDATER_SUPPORTED 1
#if defined(_WIN32)
#define UPDATE_PLATFORM_STR "Windows"
#elif defined(__linux__)
@@ -69,10 +63,6 @@ static constexpr u32 HTTP_POLL_INTERVAL = 10;
#define UPDATE_ADDITIONAL_TAGS "SSE4"
#endif
#endif
#ifdef AUTO_UPDATER_SUPPORTED
#define LATEST_RELEASE_URL "https://api.pcsx2.net/v1/%1Releases?pageSize=1"
#define CHANGES_URL "https://api.github.com/repos/PCSX2/pcsx2/compare/%1...%2"
@@ -87,8 +77,6 @@ static const char* UPDATE_TAGS[] = {"stable", "nightly"};
#define DEFAULT_UPDATER_CHANNEL "nightly"
#endif
#endif
AutoUpdaterDialog::AutoUpdaterDialog(QWidget* parent /* = nullptr */)
: QDialog(parent)
{
@@ -109,7 +97,11 @@ AutoUpdaterDialog::~AutoUpdaterDialog() = default;
bool AutoUpdaterDialog::isSupported()
{
#ifdef AUTO_UPDATER_SUPPORTED
// Logic to detect whether we can use the auto updater.
// We use tagged commit, because this gets set on nightly builds.
if (!BuildVersion::GitTaggedCommit)
return false;
#ifdef __linux__
// For Linux, we need to check whether we're running from the appimage.
if (!std::getenv("APPIMAGE"))
@@ -119,10 +111,9 @@ bool AutoUpdaterDialog::isSupported()
}
return true;
#else
#elif defined(_WIN32) || defined(__APPLE__)
// Windows, MacOS - always supported.
return true;
#endif
#else
return false;
#endif
@@ -130,39 +121,36 @@ bool AutoUpdaterDialog::isSupported()
QStringList AutoUpdaterDialog::getTagList()
{
#ifdef AUTO_UPDATER_SUPPORTED
if (!isSupported())
return QStringList();
return QStringList(std::begin(UPDATE_TAGS), std::end(UPDATE_TAGS));
#else
return QStringList();
#endif
}
std::string AutoUpdaterDialog::getDefaultTag()
{
#ifdef AUTO_UPDATER_SUPPORTED
if (!isSupported())
return {};
return DEFAULT_UPDATER_CHANNEL;
#else
return {};
#endif
}
QString AutoUpdaterDialog::getCurrentVersion()
{
return QStringLiteral(GIT_TAG);
return QString(BuildVersion::GitTag);
}
QString AutoUpdaterDialog::getCurrentVersionDate()
{
return QStringLiteral(GIT_DATE);
return QString(BuildVersion::GitDate);
}
QString AutoUpdaterDialog::getCurrentUpdateTag() const
{
#ifdef AUTO_UPDATER_SUPPORTED
if (!isSupported())
return QString();
return QString::fromStdString(Host::GetBaseStringSettingValue("AutoUpdater", "UpdateTag", DEFAULT_UPDATER_CHANNEL));
#else
return QString();
#endif
}
void AutoUpdaterDialog::reportError(const char* msg, ...)
@@ -215,18 +203,21 @@ void AutoUpdaterDialog::queueUpdateCheck(bool display_message)
{
m_display_messages = display_message;
#ifdef AUTO_UPDATER_SUPPORTED
if (!ensureHttpReady())
if (isSupported())
{
if (!ensureHttpReady())
{
emit updateCheckCompleted();
return;
}
m_http->CreateRequest(QStringLiteral(LATEST_RELEASE_URL).arg(getCurrentUpdateTag()).toStdString(),
std::bind(&AutoUpdaterDialog::getLatestReleaseComplete, this, std::placeholders::_1, std::placeholders::_3));
}
else
{
emit updateCheckCompleted();
return;
}
m_http->CreateRequest(QStringLiteral(LATEST_RELEASE_URL).arg(getCurrentUpdateTag()).toStdString(),
std::bind(&AutoUpdaterDialog::getLatestReleaseComplete, this, std::placeholders::_1, std::placeholders::_3));
#else
emit updateCheckCompleted();
#endif
}
void AutoUpdaterDialog::getLatestReleaseComplete(s32 status_code, std::vector<u8> data)
@@ -236,7 +227,9 @@ void AutoUpdaterDialog::getLatestReleaseComplete(s32 status_code, std::vector<u8
cpuinfo_initialize();
#endif
#ifdef AUTO_UPDATER_SUPPORTED
if (!isSupported())
return;
bool found_update_info = false;
if (status_code == HTTPDownloader::HTTP_STATUS_OK)
@@ -373,23 +366,25 @@ void AutoUpdaterDialog::getLatestReleaseComplete(s32 status_code, std::vector<u8
checkIfUpdateNeeded();
emit updateCheckCompleted();
#endif
}
void AutoUpdaterDialog::queueGetChanges()
{
#ifdef AUTO_UPDATER_SUPPORTED
if (!ensureHttpReady())
if (!isSupported() || !ensureHttpReady())
return;
m_http->CreateRequest(QStringLiteral(CHANGES_URL).arg(GIT_HASH).arg(m_latest_version).toStdString(),
m_http->CreateRequest(QStringLiteral(CHANGES_URL).arg(BuildVersion::GitHash).arg(m_latest_version).toStdString(),
std::bind(&AutoUpdaterDialog::getChangesComplete, this, std::placeholders::_1, std::placeholders::_3));
#endif
}
void AutoUpdaterDialog::getChangesComplete(s32 status_code, std::vector<u8> data)
{
#ifdef AUTO_UPDATER_SUPPORTED
if (!isSupported())
{
m_ui.downloadAndInstall->setEnabled(true);
return;
}
if (status_code == HTTPDownloader::HTTP_STATUS_OK)
{
QJsonParseError parse_error;
@@ -456,7 +451,6 @@ void AutoUpdaterDialog::getChangesComplete(s32 status_code, std::vector<u8> data
{
reportError("Failed to download change list: %d", status_code);
}
#endif
m_ui.downloadAndInstall->setEnabled(true);
}
@@ -542,10 +536,10 @@ void AutoUpdaterDialog::checkIfUpdateNeeded()
const QString last_checked_version(
QString::fromStdString(Host::GetBaseStringSettingValue("AutoUpdater", "LastVersion")));
Console.WriteLn(Color_StrongGreen, "Current version: %s", GIT_TAG);
Console.WriteLn(Color_StrongGreen, "Current version: %s", BuildVersion::GitTag);
Console.WriteLn(Color_StrongYellow, "Latest version: %s", m_latest_version.toUtf8().constData());
Console.WriteLn(Color_StrongOrange, "Last checked version: %s", last_checked_version.toUtf8().constData());
if (m_latest_version == GIT_TAG || m_latest_version == last_checked_version)
if (m_latest_version == BuildVersion::GitTag || m_latest_version == last_checked_version)
{
Console.WriteLn(Color_StrongGreen, "No update needed.");
@@ -787,7 +781,7 @@ void AutoUpdaterDialog::cleanupAfterUpdate()
static QString UpdateVersionNumberInName(QString name, QStringView new_version)
{
QString current_version_string = QStringLiteral(GIT_TAG);
QString current_version_string(BuildVersion::GitTag);
QStringView current_version = current_version_string;
if (!current_version.empty() && !new_version.empty() && current_version[0] == 'v' && new_version[0] == 'v')
{

View File

@@ -80,6 +80,8 @@ void BreakpointDialog::onRdoButtonToggled()
void BreakpointDialog::accept()
{
std::string error;
if (m_purpose == PURPOSE::CREATE)
{
if (m_ui.rdoExecute->isChecked())
@@ -93,9 +95,9 @@ void BreakpointDialog::accept()
PostfixExpression expr;
u64 address;
if (!m_cpu->evaluateExpression(m_ui.txtAddress->text().toStdString().c_str(), address))
if (!m_cpu->evaluateExpression(m_ui.txtAddress->text().toStdString().c_str(), address, error))
{
QMessageBox::warning(this, tr("Invalid Address"), getExpressionError());
QMessageBox::warning(this, tr("Invalid Address"), QString::fromStdString(error));
return;
}
@@ -108,9 +110,9 @@ void BreakpointDialog::accept()
bp->hasCond = true;
bp->cond.debug = m_cpu;
if (!m_cpu->initExpression(m_ui.txtCondition->text().toStdString().c_str(), expr))
if (!m_cpu->initExpression(m_ui.txtCondition->text().toStdString().c_str(), expr, error))
{
QMessageBox::warning(this, tr("Invalid Condition"), getExpressionError());
QMessageBox::warning(this, tr("Invalid Condition"), QString::fromStdString(error));
return;
}
@@ -121,16 +123,16 @@ void BreakpointDialog::accept()
if (auto* mc = std::get_if<MemCheck>(&m_bp_mc))
{
u64 startAddress;
if (!m_cpu->evaluateExpression(m_ui.txtAddress->text().toStdString().c_str(), startAddress))
if (!m_cpu->evaluateExpression(m_ui.txtAddress->text().toStdString().c_str(), startAddress, error))
{
QMessageBox::warning(this, tr("Invalid Address"), getExpressionError());
QMessageBox::warning(this, tr("Invalid Address"), QString::fromStdString(error));
return;
}
u64 size;
if (!m_cpu->evaluateExpression(m_ui.txtSize->text().toStdString().c_str(), size) || !size)
if (!m_cpu->evaluateExpression(m_ui.txtSize->text().toStdString().c_str(), size, error) || !size)
{
QMessageBox::warning(this, tr("Invalid Size"), getExpressionError());
QMessageBox::warning(this, tr("Invalid Size"), QString::fromStdString(error));
return;
}
@@ -143,9 +145,9 @@ void BreakpointDialog::accept()
mc->cond.debug = m_cpu;
PostfixExpression expr;
if (!m_cpu->initExpression(m_ui.txtCondition->text().toStdString().c_str(), expr))
if (!m_cpu->initExpression(m_ui.txtCondition->text().toStdString().c_str(), expr, error))
{
QMessageBox::warning(this, tr("Invalid Condition"), getExpressionError());
QMessageBox::warning(this, tr("Invalid Condition"), QString::fromStdString(error));
return;
}

View File

@@ -170,9 +170,10 @@ void DisassemblyWidget::contextGoToAddress()
return;
u64 address = 0;
if (!m_cpu->evaluateExpression(targetString.toStdString().c_str(), address))
std::string error;
if (!m_cpu->evaluateExpression(targetString.toStdString().c_str(), address, error))
{
QMessageBox::warning(this, tr("Cannot Go To"), getExpressionError());
QMessageBox::warning(this, tr("Cannot Go To"), QString::fromStdString(error));
return;
}

View File

@@ -599,9 +599,10 @@ void MemoryViewWidget::contextGoToAddress()
return;
u64 address = 0;
if (!m_cpu->evaluateExpression(targetString.toStdString().c_str(), address))
std::string error;
if (!m_cpu->evaluateExpression(targetString.toStdString().c_str(), address, error))
{
QMessageBox::warning(this, tr("Cannot Go To"), getExpressionError());
QMessageBox::warning(this, tr("Cannot Go To"), QString::fromStdString(error));
return;
}

View File

@@ -273,6 +273,8 @@ Qt::ItemFlags BreakpointModel::flags(const QModelIndex& index) const
bool BreakpointModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
std::string error;
if (role == Qt::CheckStateRole && index.column() == BreakpointColumns::ENABLED)
{
auto bp_mc = m_breakpoints.at(index.row());
@@ -314,9 +316,9 @@ bool BreakpointModel::setData(const QModelIndex& index, const QVariant& value, i
{
PostfixExpression expr;
if (!m_cpu.initExpression(condValue.toLocal8Bit().constData(), expr))
if (!m_cpu.initExpression(condValue.toLocal8Bit().constData(), expr, error))
{
QMessageBox::warning(nullptr, "Condition Error", QString(getExpressionError()));
QMessageBox::warning(nullptr, "Condition Error", QString::fromStdString(error));
return false;
}
@@ -347,9 +349,9 @@ bool BreakpointModel::setData(const QModelIndex& index, const QVariant& value, i
{
PostfixExpression expr;
if (!m_cpu.initExpression(condValue.toLocal8Bit().constData(), expr))
if (!m_cpu.initExpression(condValue.toLocal8Bit().constData(), expr, error))
{
QMessageBox::warning(nullptr, "Condition Error", QString(getExpressionError()));
QMessageBox::warning(nullptr, "Condition Error", QString::fromStdString(error));
return false;
}
@@ -456,17 +458,20 @@ void BreakpointModel::refreshData()
void BreakpointModel::loadBreakpointFromFieldList(QStringList fields)
{
std::string error;
bool ok;
if (fields.size() != BreakpointModel::BreakpointColumns::COLUMN_COUNT)
if (fields.size() != BreakpointColumns::COLUMN_COUNT)
{
Console.WriteLn("Debugger Breakpoint Model: Invalid number of columns, skipping");
return;
}
const int type = fields[BreakpointModel::BreakpointColumns::TYPE].toUInt(&ok);
const int type = fields[BreakpointColumns::TYPE].toUInt(&ok);
if (!ok)
{
Console.WriteLn("Debugger Breakpoint Model: Failed to parse type '%s', skipping", fields[BreakpointModel::BreakpointColumns::TYPE].toUtf8().constData());
Console.WriteLn("Debugger Breakpoint Model: Failed to parse type '%s', skipping",
fields[BreakpointColumns::TYPE].toUtf8().constData());
return;
}
@@ -476,34 +481,37 @@ void BreakpointModel::loadBreakpointFromFieldList(QStringList fields)
BreakPoint bp;
// Address
bp.addr = fields[BreakpointModel::BreakpointColumns::OFFSET].toUInt(&ok, 16);
bp.addr = fields[BreakpointColumns::OFFSET].toUInt(&ok, 16);
if (!ok)
{
Console.WriteLn("Debugger Breakpoint Model: Failed to parse address '%s', skipping", fields[BreakpointModel::BreakpointColumns::OFFSET].toUtf8().constData());
Console.WriteLn("Debugger Breakpoint Model: Failed to parse address '%s', skipping",
fields[BreakpointColumns::OFFSET].toUtf8().constData());
return;
}
// Condition
if (!fields[BreakpointModel::BreakpointColumns::CONDITION].isEmpty())
if (!fields[BreakpointColumns::CONDITION].isEmpty())
{
PostfixExpression expr;
bp.hasCond = true;
bp.cond.debug = &m_cpu;
if (!m_cpu.initExpression(fields[BreakpointModel::BreakpointColumns::CONDITION].toUtf8().constData(), expr))
if (!m_cpu.initExpression(fields[BreakpointColumns::CONDITION].toUtf8().constData(), expr, error))
{
Console.WriteLn("Debugger Breakpoint Model: Failed to parse cond '%s', skipping", fields[BreakpointModel::BreakpointColumns::CONDITION].toUtf8().constData());
Console.WriteLn("Debugger Breakpoint Model: Failed to parse cond '%s', skipping",
fields[BreakpointModel::CONDITION].toUtf8().constData());
return;
}
bp.cond.expression = expr;
bp.cond.expressionString = fields[BreakpointModel::BreakpointColumns::CONDITION].toStdString();
bp.cond.expressionString = fields[BreakpointColumns::CONDITION].toStdString();
}
// Enabled
bp.enabled = fields[BreakpointModel::BreakpointColumns::ENABLED].toUInt(&ok);
bp.enabled = fields[BreakpointColumns::ENABLED].toUInt(&ok);
if (!ok)
{
Console.WriteLn("Debugger Breakpoint Model: Failed to parse enable flag '%s', skipping", fields[BreakpointModel::BreakpointColumns::ENABLED].toUtf8().constData());
Console.WriteLn("Debugger Breakpoint Model: Failed to parse enable flag '%s', skipping",
fields[BreakpointColumns::ENABLED].toUtf8().constData());
return;
}
@@ -515,49 +523,54 @@ void BreakpointModel::loadBreakpointFromFieldList(QStringList fields)
// Mode
if (type >= MEMCHECK_INVALID)
{
Console.WriteLn("Debugger Breakpoint Model: Failed to parse cond type '%s', skipping", fields[BreakpointModel::BreakpointColumns::TYPE].toUtf8().constData());
Console.WriteLn("Debugger Breakpoint Model: Failed to parse cond type '%s', skipping",
fields[BreakpointColumns::TYPE].toUtf8().constData());
return;
}
mc.memCond = static_cast<MemCheckCondition>(type);
// Address
QString test = fields[BreakpointModel::BreakpointColumns::OFFSET];
mc.start = fields[BreakpointModel::BreakpointColumns::OFFSET].toUInt(&ok, 16);
QString test = fields[BreakpointColumns::OFFSET];
mc.start = fields[BreakpointColumns::OFFSET].toUInt(&ok, 16);
if (!ok)
{
Console.WriteLn("Debugger Breakpoint Model: Failed to parse address '%s', skipping", fields[BreakpointModel::BreakpointColumns::OFFSET].toUtf8().constData());
Console.WriteLn("Debugger Breakpoint Model: Failed to parse address '%s', skipping",
fields[BreakpointColumns::OFFSET].toUtf8().constData());
return;
}
// Size
mc.end = fields[BreakpointModel::BreakpointColumns::SIZE_LABEL].toUInt(&ok) + mc.start;
mc.end = fields[BreakpointColumns::SIZE_LABEL].toUInt(&ok) + mc.start;
if (!ok)
{
Console.WriteLn("Debugger Breakpoint Model: Failed to parse length '%s', skipping", fields[BreakpointModel::BreakpointColumns::SIZE_LABEL].toUtf8().constData());
Console.WriteLn("Debugger Breakpoint Model: Failed to parse length '%s', skipping",
fields[BreakpointColumns::SIZE_LABEL].toUtf8().constData());
return;
}
// Condition
if (!fields[BreakpointModel::BreakpointColumns::CONDITION].isEmpty())
if (!fields[BreakpointColumns::CONDITION].isEmpty())
{
PostfixExpression expr;
mc.hasCond = true;
mc.cond.debug = &m_cpu;
if (!m_cpu.initExpression(fields[BreakpointModel::BreakpointColumns::CONDITION].toUtf8().constData(), expr))
if (!m_cpu.initExpression(fields[BreakpointColumns::CONDITION].toUtf8().constData(), expr, error))
{
Console.WriteLn("Debugger Breakpoint Model: Failed to parse cond '%s', skipping", fields[BreakpointModel::BreakpointColumns::CONDITION].toUtf8().constData());
Console.WriteLn("Debugger Breakpoint Model: Failed to parse cond '%s', skipping",
fields[BreakpointColumns::CONDITION].toUtf8().constData());
return;
}
mc.cond.expression = expr;
mc.cond.expressionString = fields[BreakpointModel::BreakpointColumns::CONDITION].toStdString();
mc.cond.expressionString = fields[BreakpointColumns::CONDITION].toStdString();
}
// Result
const int result = fields[BreakpointModel::BreakpointColumns::ENABLED].toUInt(&ok);
const int result = fields[BreakpointColumns::ENABLED].toUInt(&ok);
if (!ok)
{
Console.WriteLn("Debugger Breakpoint Model: Failed to parse result flag '%s', skipping", fields[BreakpointModel::BreakpointColumns::ENABLED].toUtf8().constData());
Console.WriteLn("Debugger Breakpoint Model: Failed to parse result flag '%s', skipping",
fields[BreakpointColumns::ENABLED].toUtf8().constData());
return;
}
mc.result = static_cast<MemCheckResult>(result);

View File

@@ -19,7 +19,6 @@
#include "Settings/MemoryCardCreateDialog.h"
#include "Tools/InputRecording/InputRecordingViewer.h"
#include "Tools/InputRecording/NewInputRecordingDlg.h"
#include "svnrev.h"
#include "pcsx2/Achievements.h"
#include "pcsx2/CDVD/CDVDcommon.h"

View File

@@ -10,10 +10,10 @@
#include "QtProgressCallback.h"
#include "QtUtils.h"
#include "SetupWizardDialog.h"
#include "svnrev.h"
#include "pcsx2/CDVD/CDVDcommon.h"
#include "pcsx2/Achievements.h"
#include "pcsx2/BuildVersion.h"
#include "pcsx2/CDVD/CDVD.h"
#include "pcsx2/Counters.h"
#include "pcsx2/DebugTools/Debug.h"
@@ -1468,7 +1468,7 @@ bool Host::RequestResetSettings(bool folders, bool core, bool controllers, bool
QString QtHost::GetAppNameAndVersion()
{
return QStringLiteral("PCSX2 " GIT_REV);
return QString("PCSX2 %1").arg(BuildVersion::GitRev);
}
QString QtHost::GetAppConfigSuffix()

View File

@@ -37,8 +37,8 @@ DebugAnalysisSettingsWidget::DebugAnalysisSettingsWidget(QWidget* parent)
}
m_ui.customAddressRange->setChecked(Host::GetBoolSettingValue("Debugger/Analysis", "CustomFunctionScanRange", false));
m_ui.addressRangeStart->setText(QString::fromStdString(Host::GetStringSettingValue("Debugger/Analysis", "FunctionScanStartAddress", "0")));
m_ui.addressRangeEnd->setText(QString::fromStdString(Host::GetStringSettingValue("Debugger/Analysis", "FunctionScanEndAddress", "0")));
m_ui.addressRangeStart->setText(QString::fromStdString(Host::GetStringSettingValue("Debugger/Analysis", "FunctionScanStartAddress", "")));
m_ui.addressRangeEnd->setText(QString::fromStdString(Host::GetStringSettingValue("Debugger/Analysis", "FunctionScanEndAddress", "")));
m_ui.grayOutOverwrittenFunctions->setChecked(Host::GetBoolSettingValue("Debugger/Analysis", "GenerateFunctionHashes", true));
@@ -104,7 +104,7 @@ DebugAnalysisSettingsWidget::DebugAnalysisSettingsWidget(SettingsWindow* dialog,
else
{
m_ui.symbolFileLabel->hide();
m_ui.symbolFileList->hide();
m_ui.symbolFileTable->hide();
m_ui.importSymbolFileButtons->hide();
}
@@ -165,18 +165,19 @@ void DebugAnalysisSettingsWidget::parseSettingsFromWidgets(Pcsx2Config::DebugAna
output.DemangleSymbols = m_ui.demangleSymbols->isChecked();
output.DemangleParameters = m_ui.demangleParameters->isChecked();
for (int i = 0; i < m_ui.symbolFileList->count(); i++)
for (int i = 0; i < m_symbol_file_model->rowCount(); i++)
{
DebugExtraSymbolFile& file = output.ExtraSymbolFiles.emplace_back();
file.Path = m_ui.symbolFileList->item(i)->text().toStdString();
file.Path = m_symbol_file_model->item(i, PATH_COLUMN)->text().toStdString();
file.BaseAddress = m_symbol_file_model->item(i, BASE_ADDRESS_COLUMN)->text().toStdString();
file.Condition = m_symbol_file_model->item(i, CONDITION_COLUMN)->text().toStdString();
}
output.FunctionScanMode = static_cast<DebugFunctionScanMode>(m_ui.functionScanMode->currentIndex());
output.CustomFunctionScanRange = m_ui.customAddressRange->isChecked();
output.FunctionScanStartAddress = m_ui.addressRangeStart->text().toStdString();
output.FunctionScanEndAddress = m_ui.addressRangeEnd->text().toStdString();
output.GenerateFunctionHashes = m_ui.grayOutOverwrittenFunctions->isChecked();
}
void DebugAnalysisSettingsWidget::setupSymbolSourceGrid()
@@ -187,27 +188,12 @@ void DebugAnalysisSettingsWidget::setupSymbolSourceGrid()
{
// Add symbol sources for which the user has already selected whether or
// not they should be cleared.
int existing_symbol_source_count;
if (m_dialog)
existing_symbol_source_count = m_dialog->getEffectiveIntValue("Debugger/Analysis/SymbolSources", "Count", 0);
else
existing_symbol_source_count = Host::GetIntSettingValue("Debugger/Analysis/SymbolSources", "Count", 0);
int existing_symbol_source_count = getIntSettingValue("Debugger/Analysis/SymbolSources", "Count", 0);
for (int i = 0; i < existing_symbol_source_count; i++)
{
std::string section = "Debugger/Analysis/SymbolSources/" + std::to_string(i);
std::string name;
if (m_dialog)
name = m_dialog->getEffectiveStringValue(section.c_str(), "Name", "");
else
name = Host::GetStringSettingValue(section.c_str(), "Name", "");
bool value;
if (m_dialog)
value = m_dialog->getEffectiveBoolValue(section.c_str(), "ClearDuringAnalysis", false);
else
value = Host::GetBoolSettingValue(section.c_str(), "ClearDuringAnalysis", false);
std::string name = getStringSettingValue(section.c_str(), "Name", "");
bool value = getBoolSettingValue(section.c_str(), "ClearDuringAnalysis", false);
SymbolSourceTemp& source = m_symbol_sources[name];
source.previous_value = value;
@@ -320,45 +306,100 @@ void DebugAnalysisSettingsWidget::saveSymbolSources()
void DebugAnalysisSettingsWidget::setupSymbolFileList()
{
int extra_symbol_file_count;
if (m_dialog)
extra_symbol_file_count = m_dialog->getEffectiveIntValue("Debugger/Analysis/ExtraSymbolFiles", "Count", 0);
else
extra_symbol_file_count = Host::GetIntSettingValue("Debugger/Analysis/ExtraSymbolFiles", "Count", 0);
m_symbol_file_model = new QStandardItemModel(0, SYMBOL_FILE_COLUMN_COUNT, m_ui.symbolFileTable);
QStringList headers;
headers.emplace_back(tr("Path"));
headers.emplace_back(tr("Base Address"));
headers.emplace_back(tr("Condition"));
m_symbol_file_model->setHorizontalHeaderLabels(headers);
m_ui.symbolFileTable->setModel(m_symbol_file_model);
m_ui.symbolFileTable->horizontalHeader()->setSectionResizeMode(PATH_COLUMN, QHeaderView::Stretch);
m_ui.symbolFileTable->horizontalHeader()->setSectionResizeMode(BASE_ADDRESS_COLUMN, QHeaderView::Fixed);
m_ui.symbolFileTable->horizontalHeader()->setSectionResizeMode(CONDITION_COLUMN, QHeaderView::Fixed);
m_ui.symbolFileTable->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
int extra_symbol_file_count = getIntSettingValue("Debugger/Analysis/ExtraSymbolFiles", "Count", 0);
for (int i = 0; i < extra_symbol_file_count; i++)
{
std::string section = "Debugger/Analysis/ExtraSymbolFiles/" + std::to_string(i);
std::string path;
if (m_dialog)
path = m_dialog->getEffectiveStringValue(section.c_str(), "Path", "");
else
path = Host::GetStringSettingValue(section.c_str(), "Path", "");
m_ui.symbolFileList->addItem(QString::fromStdString(path));
int row = m_symbol_file_model->rowCount();
if (!m_symbol_file_model->insertRow(row))
continue;
QStandardItem* path_item = new QStandardItem();
path_item->setText(QString::fromStdString(getStringSettingValue(section.c_str(), "Path", "")));
m_symbol_file_model->setItem(row, PATH_COLUMN, path_item);
QStandardItem* base_address_item = new QStandardItem();
base_address_item->setText(QString::fromStdString(getStringSettingValue(section.c_str(), "BaseAddress")));
m_symbol_file_model->setItem(row, BASE_ADDRESS_COLUMN, base_address_item);
QStandardItem* condition_item = new QStandardItem();
condition_item->setText(QString::fromStdString(getStringSettingValue(section.c_str(), "Condition")));
m_symbol_file_model->setItem(row, CONDITION_COLUMN, condition_item);
}
connect(m_ui.addSymbolFile, &QPushButton::clicked, this, &DebugAnalysisSettingsWidget::addSymbolFile);
connect(m_ui.removeSymbolFile, &QPushButton::clicked, this, &DebugAnalysisSettingsWidget::removeSymbolFile);
connect(m_ui.symbolFileTable->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &DebugAnalysisSettingsWidget::updateEnabledStates);
connect(m_symbol_file_model, &QStandardItemModel::dataChanged,
this, &DebugAnalysisSettingsWidget::saveSymbolFiles);
connect(m_symbol_file_model, &QStandardItemModel::dataChanged,
this, &DebugAnalysisSettingsWidget::updateEnabledStates);
}
void DebugAnalysisSettingsWidget::addSymbolFile()
{
QString path = QDir::toNativeSeparators(QFileDialog::getOpenFileName(this, tr("Add Symbol File")));
if (path.isEmpty())
std::string path = Path::ToNativePath(QFileDialog::getOpenFileName(this, tr("Add Symbol File")).toStdString());
if (path.empty())
return;
m_ui.symbolFileList->addItem(path);
std::string relative_path = Path::MakeRelative(path, EmuFolders::GameSettings);
if (!relative_path.starts_with(".."))
path = std::move(relative_path);
int row = m_symbol_file_model->rowCount();
if (!m_symbol_file_model->insertRow(row))
return;
QStandardItem* path_item = new QStandardItem();
path_item->setText(QString::fromStdString(path));
m_symbol_file_model->setItem(row, PATH_COLUMN, path_item);
QStandardItem* base_address_item = new QStandardItem();
base_address_item->setText("");
m_symbol_file_model->setItem(row, BASE_ADDRESS_COLUMN, base_address_item);
QStandardItem* condition_item = new QStandardItem();
condition_item->setText("");
m_symbol_file_model->setItem(row, CONDITION_COLUMN, condition_item);
saveSymbolFiles();
updateEnabledStates();
}
void DebugAnalysisSettingsWidget::removeSymbolFile()
{
for (QListWidgetItem* item : m_ui.symbolFileList->selectedItems())
delete item;
QItemSelectionModel* selection_model = m_ui.symbolFileTable->selectionModel();
if (!selection_model)
return;
while (!selection_model->selectedIndexes().isEmpty())
{
QModelIndex index = selection_model->selectedIndexes().first();
m_symbol_file_model->removeRow(index.row(), index.parent());
}
saveSymbolFiles();
updateEnabledStates();
}
void DebugAnalysisSettingsWidget::saveSymbolFiles()
@@ -380,17 +421,24 @@ void DebugAnalysisSettingsWidget::saveSymbolFiles()
sif->RemoveSection("Debugger/Analysis/ExtraSymbolFiles");
if (m_ui.symbolFileList->count() == 0)
if (m_symbol_file_model->rowCount() == 0)
return;
// Make new configuration entries.
sif->SetIntValue("Debugger/Analysis/ExtraSymbolFiles", "Count", m_ui.symbolFileList->count());
sif->SetIntValue("Debugger/Analysis/ExtraSymbolFiles", "Count", m_symbol_file_model->rowCount());
for (int i = 0; i < m_ui.symbolFileList->count(); i++)
for (int i = 0; i < m_symbol_file_model->rowCount(); i++)
{
std::string section = "Debugger/Analysis/ExtraSymbolFiles/" + std::to_string(i);
std::string path = m_ui.symbolFileList->item(i)->text().toStdString();
sif->SetStringValue(section.c_str(), "Path", path.c_str());
if (QStandardItem* path_item = m_symbol_file_model->item(i, PATH_COLUMN))
sif->SetStringValue(section.c_str(), "Path", path_item->text().toStdString().c_str());
if (QStandardItem* base_address_item = m_symbol_file_model->item(i, BASE_ADDRESS_COLUMN))
sif->SetStringValue(section.c_str(), "BaseAddress", base_address_item->text().toStdString().c_str());
if (QStandardItem* condition_item = m_symbol_file_model->item(i, CONDITION_COLUMN))
sif->SetStringValue(section.c_str(), "Condition", condition_item->text().toStdString().c_str());
}
QtHost::SaveGameSettings(sif, true);
@@ -423,5 +471,34 @@ void DebugAnalysisSettingsWidget::updateEnabledStates()
m_ui.symbolSourceScrollArea->setEnabled(!m_ui.automaticallyClearSymbols->isChecked());
m_ui.symbolSourceErrorMessage->setEnabled(!m_ui.automaticallyClearSymbols->isChecked());
m_ui.demangleParameters->setEnabled(m_ui.demangleSymbols->isChecked());
m_ui.removeSymbolFile->setEnabled(
m_ui.symbolFileTable->selectionModel() && m_ui.symbolFileTable->selectionModel()->hasSelection());
m_ui.customAddressRangeLineEdits->setEnabled(m_ui.customAddressRange->isChecked());
}
std::string DebugAnalysisSettingsWidget::getStringSettingValue(
const char* section, const char* key, const char* default_value)
{
if (m_dialog)
return m_dialog->getEffectiveStringValue(section, key, default_value);
return Host::GetStringSettingValue(section, key, default_value);
}
bool DebugAnalysisSettingsWidget::getBoolSettingValue(
const char* section, const char* key, bool default_value)
{
if (m_dialog)
return m_dialog->getEffectiveBoolValue(section, key, default_value);
return Host::GetBoolSettingValue(section, key, default_value);
}
int DebugAnalysisSettingsWidget::getIntSettingValue(
const char* section, const char* key, int default_value)
{
if (m_dialog)
return m_dialog->getEffectiveIntValue(section, key, default_value);
return Host::GetIntSettingValue(section, key, default_value);
}

View File

@@ -6,6 +6,7 @@
#include "Config.h"
#include <QtGui/QStandardItemModel>
#include <QtWidgets/QDialog>
class SettingsWindow;
@@ -16,7 +17,7 @@ class DebugAnalysisSettingsWidget : public QWidget
public:
// Create a widget that will discard any settings changed after it is
// closed, for use in the dialog opened by the "Reanalyze" button.
// closed, for use in the dialog opened by the "Analyze" button.
DebugAnalysisSettingsWidget(QWidget* parent = nullptr);
// Create a widget that will write back any settings changed to the config
@@ -42,6 +43,10 @@ protected:
void updateEnabledStates();
std::string getStringSettingValue(const char* section, const char* key, const char* default_value = "");
bool getBoolSettingValue(const char* section, const char* key, bool default_value = false);
int getIntSettingValue(const char* section, const char* key, int default_value = 0);
struct SymbolSourceTemp
{
QCheckBox* check_box = nullptr;
@@ -49,8 +54,18 @@ protected:
bool modified_by_user = false;
};
enum SymbolFileColumn
{
PATH_COLUMN = 0,
BASE_ADDRESS_COLUMN = 1,
CONDITION_COLUMN = 2,
SYMBOL_FILE_COLUMN_COUNT = 3
};
SettingsWindow* m_dialog = nullptr;
std::map<std::string, SymbolSourceTemp> m_symbol_sources;
QStandardItemModel* m_symbol_file_model;
Ui::DebugAnalysisSettingsWidget m_ui;
};

View File

@@ -171,7 +171,7 @@
</widget>
</item>
<item>
<widget class="QListWidget" name="symbolFileList">
<widget class="QTableView" name="symbolFileTable">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
@@ -184,9 +184,27 @@
<height>100</height>
</size>
</property>
<property name="sortingEnabled">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="textElideMode">
<enum>Qt::ElideLeft</enum>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
<attribute name="horizontalHeaderHighlightSections">
<bool>false</bool>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
<item>

View File

@@ -1870,8 +1870,8 @@ Leaderboard Position: {1} of {2}</source>
<name>AutoUpdaterDialog</name>
<message>
<location filename="../AutoUpdaterDialog.ui" line="17"/>
<location filename="../AutoUpdaterDialog.cpp" line="489"/>
<location filename="../AutoUpdaterDialog.cpp" line="554"/>
<location filename="../AutoUpdaterDialog.cpp" line="483"/>
<location filename="../AutoUpdaterDialog.cpp" line="548"/>
<source>Automatic Updater</source>
<translation type="unfinished"></translation>
</message>
@@ -1911,68 +1911,68 @@ Leaderboard Position: {1} of {2}</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../AutoUpdaterDialog.cpp" line="178"/>
<location filename="../AutoUpdaterDialog.cpp" line="683"/>
<location filename="../AutoUpdaterDialog.cpp" line="166"/>
<location filename="../AutoUpdaterDialog.cpp" line="677"/>
<source>Updater Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../AutoUpdaterDialog.cpp" line="401"/>
<location filename="../AutoUpdaterDialog.cpp" line="396"/>
<source>&lt;h2&gt;Changes:&lt;/h2&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../AutoUpdaterDialog.cpp" line="435"/>
<location filename="../AutoUpdaterDialog.cpp" line="430"/>
<source>&lt;h2&gt;Save State Warning&lt;/h2&gt;&lt;p&gt;Installing this update will make your save states &lt;b&gt;incompatible&lt;/b&gt;. Please ensure you have saved your games to a Memory Card before installing this update or you will lose progress.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../AutoUpdaterDialog.cpp" line="445"/>
<location filename="../AutoUpdaterDialog.cpp" line="440"/>
<source>&lt;h2&gt;Settings Warning&lt;/h2&gt;&lt;p&gt;Installing this update will reset your program configuration. Please note that you will have to reconfigure your settings after this update.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../AutoUpdaterDialog.cpp" line="472"/>
<location filename="../AutoUpdaterDialog.cpp" line="466"/>
<source>Savestate Warning</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../AutoUpdaterDialog.cpp" line="473"/>
<location filename="../AutoUpdaterDialog.cpp" line="467"/>
<source>&lt;h1&gt;WARNING&lt;/h1&gt;&lt;p style=&apos;font-size:12pt;&apos;&gt;Installing this update will make your &lt;b&gt;save states incompatible&lt;/b&gt;, &lt;i&gt;be sure to save any progress to your memory cards before proceeding&lt;/i&gt;.&lt;/p&gt;&lt;p&gt;Do you wish to continue?&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../AutoUpdaterDialog.cpp" line="490"/>
<location filename="../AutoUpdaterDialog.cpp" line="484"/>
<source>Downloading %1...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../AutoUpdaterDialog.cpp" line="555"/>
<location filename="../AutoUpdaterDialog.cpp" line="549"/>
<source>No updates are currently available. Please try again later.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../AutoUpdaterDialog.cpp" line="573"/>
<location filename="../AutoUpdaterDialog.cpp" line="567"/>
<source>Current Version: %1 (%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../AutoUpdaterDialog.cpp" line="574"/>
<location filename="../AutoUpdaterDialog.cpp" line="568"/>
<source>New Version: %1 (%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../AutoUpdaterDialog.cpp" line="575"/>
<location filename="../AutoUpdaterDialog.cpp" line="569"/>
<source>Download Size: %1 MB</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../AutoUpdaterDialog.cpp" line="576"/>
<location filename="../AutoUpdaterDialog.cpp" line="570"/>
<source>Loading...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../AutoUpdaterDialog.cpp" line="683"/>
<location filename="../AutoUpdaterDialog.cpp" line="677"/>
<source>Failed to remove updater exe after update.</source>
<translation type="unfinished"></translation>
</message>
@@ -15413,14 +15413,14 @@ Right click to clear binding</source>
</message>
<message>
<location filename="../MainWindow.ui" line="43"/>
<location filename="../MainWindow.cpp" line="1407"/>
<location filename="../MainWindow.cpp" line="1468"/>
<location filename="../MainWindow.cpp" line="1406"/>
<location filename="../MainWindow.cpp" line="1467"/>
<source>Change Disc</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="58"/>
<location filename="../MainWindow.cpp" line="2786"/>
<location filename="../MainWindow.cpp" line="2785"/>
<source>Load State</source>
<translation type="unfinished"></translation>
</message>
@@ -15929,13 +15929,13 @@ Right click to clear binding</source>
</message>
<message>
<location filename="../MainWindow.ui" line="1042"/>
<location filename="../MainWindow.cpp" line="1511"/>
<location filename="../MainWindow.cpp" line="1510"/>
<source>Start Big Picture Mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="1051"/>
<location filename="../MainWindow.cpp" line="1512"/>
<location filename="../MainWindow.cpp" line="1511"/>
<source>Big Picture</source>
<comment>In Toolbar</comment>
<translation type="unfinished"></translation>
@@ -15947,7 +15947,7 @@ Right click to clear binding</source>
</message>
<message>
<location filename="../MainWindow.ui" line="1068"/>
<location filename="../MainWindow.cpp" line="674"/>
<location filename="../MainWindow.cpp" line="673"/>
<source>Show Advanced Settings</source>
<translation type="unfinished"></translation>
</message>
@@ -15958,7 +15958,7 @@ Right click to clear binding</source>
</message>
<message>
<location filename="../MainWindow.ui" line="1081"/>
<location filename="../MainWindow.cpp" line="743"/>
<location filename="../MainWindow.cpp" line="742"/>
<source>Video Capture</source>
<translation type="unfinished"></translation>
</message>
@@ -15973,27 +15973,27 @@ Right click to clear binding</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="252"/>
<location filename="../MainWindow.cpp" line="251"/>
<source>Internal Resolution</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="252"/>
<location filename="../MainWindow.cpp" line="251"/>
<source>%1x Scale</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="652"/>
<location filename="../MainWindow.cpp" line="651"/>
<source>Select location to save block dump:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="670"/>
<location filename="../MainWindow.cpp" line="669"/>
<source>Do not show again</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="675"/>
<location filename="../MainWindow.cpp" line="674"/>
<source>Changing advanced settings can have unpredictable effects on games, including graphical glitches, lock-ups, and even corrupted save files. We do not recommend changing advanced settings unless you know what you are doing, and the implications of changing each setting.
The PCSX2 team will not provide any support for configurations that modify these settings, you are on your own.
@@ -16002,309 +16002,309 @@ Are you sure you want to continue?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="740"/>
<location filename="../MainWindow.cpp" line="739"/>
<source>%1 Files (*.%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1079"/>
<location filename="../MainWindow.cpp" line="1078"/>
<source>WARNING: Memory Card Busy</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1200"/>
<location filename="../MainWindow.cpp" line="1199"/>
<source>Confirm Shutdown</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1203"/>
<location filename="../MainWindow.cpp" line="1202"/>
<source>Are you sure you want to shut down the virtual machine?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1205"/>
<location filename="../MainWindow.cpp" line="1204"/>
<source>Save State For Resume</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1313"/>
<location filename="../MainWindow.cpp" line="1708"/>
<location filename="../MainWindow.cpp" line="2195"/>
<location filename="../MainWindow.cpp" line="2330"/>
<location filename="../MainWindow.cpp" line="2691"/>
<location filename="../MainWindow.cpp" line="2805"/>
<location filename="../MainWindow.cpp" line="1312"/>
<location filename="../MainWindow.cpp" line="1707"/>
<location filename="../MainWindow.cpp" line="2194"/>
<location filename="../MainWindow.cpp" line="2329"/>
<location filename="../MainWindow.cpp" line="2690"/>
<location filename="../MainWindow.cpp" line="2804"/>
<source>Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1313"/>
<location filename="../MainWindow.cpp" line="1312"/>
<source>You must select a disc to change discs.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1345"/>
<location filename="../MainWindow.cpp" line="1344"/>
<source>Properties...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1362"/>
<location filename="../MainWindow.cpp" line="1361"/>
<source>Set Cover Image...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1365"/>
<location filename="../MainWindow.cpp" line="1364"/>
<source>Exclude From List</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1368"/>
<location filename="../MainWindow.cpp" line="1367"/>
<source>Reset Play Time</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1372"/>
<location filename="../MainWindow.cpp" line="1371"/>
<source>Check Wiki Page</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1379"/>
<location filename="../MainWindow.cpp" line="1378"/>
<source>Default Boot</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1386"/>
<location filename="../MainWindow.cpp" line="1385"/>
<source>Fast Boot</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1389"/>
<location filename="../MainWindow.cpp" line="1388"/>
<source>Full Boot</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1394"/>
<location filename="../MainWindow.cpp" line="1393"/>
<source>Boot and Debug</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1418"/>
<location filename="../MainWindow.cpp" line="1417"/>
<source>Add Search Directory...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1427"/>
<location filename="../MainWindow.cpp" line="1426"/>
<source>Start File</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1436"/>
<location filename="../MainWindow.cpp" line="1435"/>
<source>Start Disc</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1453"/>
<location filename="../MainWindow.cpp" line="1452"/>
<source>Select Disc Image</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1621"/>
<location filename="../MainWindow.cpp" line="1620"/>
<source>Updater Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1627"/>
<location filename="../MainWindow.cpp" line="1626"/>
<source>&lt;p&gt;Sorry, you are trying to update a PCSX2 version which is not an official GitHub release. To prevent incompatibilities, the auto-updater is only enabled on official builds.&lt;/p&gt;&lt;p&gt;To obtain an official build, please download from the link below:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://pcsx2.net/downloads/&quot;&gt;https://pcsx2.net/downloads/&lt;/a&gt;&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1632"/>
<location filename="../MainWindow.cpp" line="1631"/>
<source>Automatic updating is not supported on the current platform.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1698"/>
<location filename="../MainWindow.cpp" line="1697"/>
<source>Confirm File Creation</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1699"/>
<location filename="../MainWindow.cpp" line="1698"/>
<source>The pnach file &apos;%1&apos; does not currently exist. Do you want to create it?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1708"/>
<location filename="../MainWindow.cpp" line="1707"/>
<source>Failed to create &apos;%1&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1733"/>
<location filename="../MainWindow.cpp" line="1732"/>
<source>Theme Change</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1734"/>
<location filename="../MainWindow.cpp" line="1733"/>
<source>Changing the theme will close the debugger window. Any unsaved data will be lost. Do you want to continue?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1832"/>
<location filename="../MainWindow.cpp" line="1831"/>
<source>Input Recording Failed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1833"/>
<location filename="../MainWindow.cpp" line="1832"/>
<source>Failed to create file: {}</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1856"/>
<location filename="../MainWindow.cpp" line="1855"/>
<source>Input Recording Files (*.p2m2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1891"/>
<location filename="../MainWindow.cpp" line="1890"/>
<source>Input Playback Failed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1892"/>
<location filename="../MainWindow.cpp" line="1891"/>
<source>Failed to open file: {}</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1973"/>
<location filename="../MainWindow.cpp" line="1972"/>
<source>Paused</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2152"/>
<location filename="../MainWindow.cpp" line="2151"/>
<source>Load State Failed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2152"/>
<location filename="../MainWindow.cpp" line="2151"/>
<source>Cannot load a save state without a running VM.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2180"/>
<location filename="../MainWindow.cpp" line="2179"/>
<source>The new ELF cannot be loaded without resetting the virtual machine. Do you want to reset the virtual machine now?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2195"/>
<location filename="../MainWindow.cpp" line="2194"/>
<source>Cannot change from game to GS dump without shutting down first.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2330"/>
<location filename="../MainWindow.cpp" line="2329"/>
<source>Failed to get window info from widget</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1511"/>
<location filename="../MainWindow.cpp" line="1510"/>
<source>Stop Big Picture Mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1512"/>
<location filename="../MainWindow.cpp" line="1511"/>
<source>Exit Big Picture</source>
<comment>In Toolbar</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1576"/>
<location filename="../MainWindow.cpp" line="1575"/>
<source>Game Properties</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1576"/>
<location filename="../MainWindow.cpp" line="1575"/>
<source>Game properties is unavailable for the current game.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2649"/>
<location filename="../MainWindow.cpp" line="2648"/>
<source>Could not find any CD/DVD-ROM devices. Please ensure you have a drive connected and sufficient permissions to access it.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2667"/>
<location filename="../MainWindow.cpp" line="2666"/>
<source>Select disc drive:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2691"/>
<location filename="../MainWindow.cpp" line="2690"/>
<source>This save state does not exist.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2704"/>
<location filename="../MainWindow.cpp" line="2703"/>
<source>Select Cover Image</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2721"/>
<location filename="../MainWindow.cpp" line="2720"/>
<source>Cover Already Exists</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2722"/>
<location filename="../MainWindow.cpp" line="2721"/>
<source>A cover image for this game already exists, do you wish to replace it?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2717"/>
<location filename="../MainWindow.cpp" line="2731"/>
<location filename="../MainWindow.cpp" line="2737"/>
<location filename="../MainWindow.cpp" line="2743"/>
<location filename="../MainWindow.cpp" line="2716"/>
<location filename="../MainWindow.cpp" line="2730"/>
<location filename="../MainWindow.cpp" line="2736"/>
<location filename="../MainWindow.cpp" line="2742"/>
<source>Copy Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2731"/>
<location filename="../MainWindow.cpp" line="2730"/>
<source>Failed to remove existing cover &apos;%1&apos;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2737"/>
<location filename="../MainWindow.cpp" line="2736"/>
<source>Failed to copy &apos;%1&apos; to &apos;%2&apos;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2743"/>
<location filename="../MainWindow.cpp" line="2742"/>
<source>Failed to remove &apos;%1&apos;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2179"/>
<location filename="../MainWindow.cpp" line="2752"/>
<location filename="../MainWindow.cpp" line="2178"/>
<location filename="../MainWindow.cpp" line="2751"/>
<source>Confirm Reset</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2704"/>
<location filename="../MainWindow.cpp" line="2703"/>
<source>All Cover Image Types (*.jpg *.jpeg *.png *.webp)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2717"/>
<location filename="../MainWindow.cpp" line="2716"/>
<source>You must select a different file to the current cover image.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2753"/>
<location filename="../MainWindow.cpp" line="2752"/>
<source>Are you sure you want to reset the play time for &apos;%1&apos;?
This action cannot be undone.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2780"/>
<location filename="../MainWindow.cpp" line="2779"/>
<source>Load Resume State</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2783"/>
<location filename="../MainWindow.cpp" line="2782"/>
<source>A resume save state was found for this game, saved at:
%1.
@@ -16313,131 +16313,131 @@ Do you want to load this state, or start from a fresh boot?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2787"/>
<location filename="../MainWindow.cpp" line="2786"/>
<source>Fresh Boot</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2788"/>
<location filename="../MainWindow.cpp" line="2787"/>
<source>Delete And Boot</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2805"/>
<location filename="../MainWindow.cpp" line="2804"/>
<source>Failed to delete save state file &apos;%1&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2863"/>
<location filename="../MainWindow.cpp" line="2862"/>
<source>Load State File...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2863"/>
<location filename="../MainWindow.cpp" line="2862"/>
<source>Load From File...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2866"/>
<location filename="../MainWindow.cpp" line="2937"/>
<location filename="../MainWindow.cpp" line="2865"/>
<location filename="../MainWindow.cpp" line="2936"/>
<source>Select Save State File</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2937"/>
<location filename="../MainWindow.cpp" line="2936"/>
<source>Save States (*.p2s)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2873"/>
<location filename="../MainWindow.cpp" line="2872"/>
<source>Delete Save States...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="58"/>
<location filename="../MainWindow.cpp" line="57"/>
<source>All File Types (*.bin *.iso *.cue *.mdf *.chd *.cso *.zso *.gz *.elf *.irx *.gs *.gs.xz *.gs.zst *.dump);;Single-Track Raw Images (*.bin *.iso);;Cue Sheets (*.cue);;Media Descriptor File (*.mdf);;MAME CHD Images (*.chd);;CSO Images (*.cso);;ZSO Images (*.zso);;GZ Images (*.gz);;ELF Executables (*.elf);;IRX Executables (*.irx);;GS Dumps (*.gs *.gs.xz *.gs.zst);;Block Dumps (*.dump)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="71"/>
<location filename="../MainWindow.cpp" line="70"/>
<source>All File Types (*.bin *.iso *.cue *.mdf *.chd *.cso *.zso *.gz *.dump);;Single-Track Raw Images (*.bin *.iso);;Cue Sheets (*.cue);;Media Descriptor File (*.mdf);;MAME CHD Images (*.chd);;CSO Images (*.cso);;ZSO Images (*.zso);;GZ Images (*.gz);;Block Dumps (*.dump)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1080"/>
<location filename="../MainWindow.cpp" line="1079"/>
<source>WARNING: Your memory card is still writing data. Shutting down now &lt;b&gt;WILL IRREVERSIBLY DESTROY YOUR MEMORY CARD.&lt;/b&gt; It is strongly recommended to resume your game and let it finish writing to your memory card.&lt;br&gt;&lt;br&gt;Do you wish to shutdown anyways and &lt;b&gt;IRREVERSIBLY DESTROY YOUR MEMORY CARD?&lt;/b&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2866"/>
<location filename="../MainWindow.cpp" line="2865"/>
<source>Save States (*.p2s *.p2s.backup)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2878"/>
<location filename="../MainWindow.cpp" line="2877"/>
<source>Undo Load State</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2892"/>
<location filename="../MainWindow.cpp" line="2891"/>
<source>Resume (%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2908"/>
<location filename="../MainWindow.cpp" line="2907"/>
<source>Load Slot %1 (%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2917"/>
<location filename="../MainWindow.cpp" line="2925"/>
<location filename="../MainWindow.cpp" line="2916"/>
<location filename="../MainWindow.cpp" line="2924"/>
<source>Delete Save States</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2918"/>
<location filename="../MainWindow.cpp" line="2917"/>
<source>Are you sure you want to delete all save states for %1?
The saves will not be recoverable.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2925"/>
<location filename="../MainWindow.cpp" line="2924"/>
<source>%1 save states deleted.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2935"/>
<location filename="../MainWindow.cpp" line="2934"/>
<source>Save To File...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2955"/>
<location filename="../MainWindow.cpp" line="2954"/>
<source>Empty</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2957"/>
<location filename="../MainWindow.cpp" line="2956"/>
<source>Save Slot %1 (%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="3008"/>
<location filename="../MainWindow.cpp" line="3007"/>
<source>Confirm Disc Change</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="3009"/>
<location filename="../MainWindow.cpp" line="3008"/>
<source>Do you want to swap discs or boot the new image (via system reset)?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="3010"/>
<location filename="../MainWindow.cpp" line="3009"/>
<source>Swap Disc</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="3011"/>
<location filename="../MainWindow.cpp" line="3010"/>
<source>Reset</source>
<translation type="unfinished"></translation>
</message>
@@ -16460,24 +16460,24 @@ The saves will not be recoverable.</source>
<context>
<name>MemoryCard</name>
<message>
<location filename="../../pcsx2/SIO/Memcard/MemoryCardFile.cpp" line="284"/>
<location filename="../../pcsx2/SIO/Memcard/MemoryCardFile.cpp" line="969"/>
<location filename="../../pcsx2/SIO/Memcard/MemoryCardFile.cpp" line="282"/>
<location filename="../../pcsx2/SIO/Memcard/MemoryCardFile.cpp" line="967"/>
<source>Memory Card Creation Failed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../pcsx2/SIO/Memcard/MemoryCardFile.cpp" line="285"/>
<location filename="../../pcsx2/SIO/Memcard/MemoryCardFile.cpp" line="283"/>
<source>Could not create the memory card:
{}</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../pcsx2/SIO/Memcard/MemoryCardFile.cpp" line="310"/>
<location filename="../../pcsx2/SIO/Memcard/MemoryCardFile.cpp" line="308"/>
<source>Memory Card Read Failed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../pcsx2/SIO/Memcard/MemoryCardFile.cpp" line="311"/>
<location filename="../../pcsx2/SIO/Memcard/MemoryCardFile.cpp" line="309"/>
<source>Unable to access memory card:
{}
@@ -16488,13 +16488,13 @@ Close any other instances of PCSX2, or restart your computer.
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../pcsx2/SIO/Memcard/MemoryCardFile.cpp" line="506"/>
<location filename="../../pcsx2/SIO/Memcard/MemoryCardFolder.cpp" line="2346"/>
<location filename="../../pcsx2/SIO/Memcard/MemoryCardFile.cpp" line="504"/>
<location filename="../../pcsx2/SIO/Memcard/MemoryCardFolder.cpp" line="2344"/>
<source>Memory Card &apos;{}&apos; was saved to storage.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../pcsx2/SIO/Memcard/MemoryCardFile.cpp" line="970"/>
<location filename="../../pcsx2/SIO/Memcard/MemoryCardFile.cpp" line="968"/>
<source>Failed to create memory card. The error was:
{}</source>
<translation type="unfinished"></translation>
@@ -18440,7 +18440,7 @@ Ejecting {3} and replacing it with {2}.</source>
<context>
<name>SaveState</name>
<message>
<location filename="../../pcsx2/SaveState.cpp" line="1092"/>
<location filename="../../pcsx2/SaveState.cpp" line="1095"/>
<source>This save state is outdated and is no longer compatible with the current version of PCSX2.
If you have any unsaved progress on this save state, you can download the compatible version (PCSX2 {}) from pcsx2.net, load the save state, and save your progress to the memory card.</source>

View File

@@ -4,6 +4,7 @@
#define IMGUI_DEFINE_MATH_OPERATORS
#include "Achievements.h"
#include "BuildVersion.h"
#include "CDVD/CDVD.h"
#include "Elfheader.h"
#include "Host.h"
@@ -16,7 +17,6 @@
#include "Memory.h"
#include "SaveState.h"
#include "VMManager.h"
#include "svnrev.h"
#include "vtlb.h"
#include "common/Assertions.h"
@@ -3039,7 +3039,7 @@ void Achievements::SwitchToRAIntegration()
void Achievements::RAIntegration::InitializeRAIntegration(void* main_window_handle)
{
RA_InitClient((HWND)main_window_handle, "PCSX2", GIT_TAG);
RA_InitClient((HWND)main_window_handle, "PCSX2", BuildVersion::GitTag);
RA_SetUserAgentDetail(Host::GetHTTPUserAgent().c_str());
RA_InstallSharedFunctions(RACallbackIsActive, RACallbackCauseUnpause, RACallbackCausePause, RACallbackRebuildMenu,

16
pcsx2/BuildVersion.cpp Normal file
View File

@@ -0,0 +1,16 @@
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
#include "svnrev.h"
namespace BuildVersion
{
const char* GitTag = GIT_TAG;
bool GitTaggedCommit = GIT_TAGGED_COMMIT;
int GitTagHi = GIT_TAG_HI;
int GitTagMid = GIT_TAG_MID;
int GitTagLo = GIT_TAG_LO;
const char* GitRev = GIT_REV;
const char* GitHash = GIT_HASH;
const char* GitDate = GIT_DATE;
} // namespace BuildVersion

18
pcsx2/BuildVersion.h Normal file
View File

@@ -0,0 +1,18 @@
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
#pragma once
// This file provides the same information as svnrev.h except you don't need to
// recompile each object file using it when said information is updated.
namespace BuildVersion
{
extern const char* GitTag;
extern bool GitTaggedCommit;
extern int GitTagHi;
extern int GitTagMid;
extern int GitTagLo;
extern const char* GitRev;
extern const char* GitHash;
extern const char* GitDate;
} // namespace BuildVersion

View File

@@ -54,6 +54,7 @@ endif(WIN32)
# Main pcsx2 source
set(pcsx2Sources
Achievements.cpp
BuildVersion.cpp
Cache.cpp
COP0.cpp
COP2.cpp
@@ -140,6 +141,7 @@ set(pcsx2Sources
# Main pcsx2 header
set(pcsx2Headers
Achievements.h
BuildVersion.h
Cache.h
Common.h
Config.h

View File

@@ -208,6 +208,8 @@ struct DebugSymbolSource
struct DebugExtraSymbolFile
{
std::string Path;
std::string BaseAddress;
std::string Condition;
friend auto operator<=>(const DebugExtraSymbolFile& lhs, const DebugExtraSymbolFile& rhs) = default;
};
@@ -1103,8 +1105,8 @@ struct Pcsx2Config
DebugFunctionScanMode FunctionScanMode = DebugFunctionScanMode::SCAN_ELF;
bool CustomFunctionScanRange = false;
std::string FunctionScanStartAddress = "0";
std::string FunctionScanEndAddress = "0";
std::string FunctionScanStartAddress;
std::string FunctionScanEndAddress;
bool GenerateFunctionHashes = true;
@@ -1276,7 +1278,7 @@ struct Pcsx2Config
EnableGameFixes : 1, // enables automatic game fixes
SaveStateOnShutdown : 1, // default value for saving state on shutdown
EnableDiscordPresence : 1, // enables discord rich presence integration
UseSavestateSelector: 1,
UseSavestateSelector : 1,
InhibitScreensaver : 1,
BackupSavestate : 1,
McdFolderAutoManage : 1,

View File

@@ -24,7 +24,8 @@ struct BreakPointCond
u32 Evaluate()
{
u64 result;
if (!debug->parseExpression(expression, result) || result == 0)
std::string error;
if (!debug->parseExpression(expression, result, error) || result == 0)
return 0;
return 1;
}

View File

@@ -34,227 +34,6 @@ enum ReferenceIndexType
REF_INDEX_VFPU = 0x10000,
REF_INDEX_VFPU_INT = 0x20000,
REF_INDEX_IS_FLOAT = REF_INDEX_FPU | REF_INDEX_VFPU,
};
class MipsExpressionFunctions : public IExpressionFunctions
{
public:
explicit MipsExpressionFunctions(DebugInterface* cpu, bool enumerateSymbols)
: m_cpu(cpu)
{
if (!enumerateSymbols)
return;
m_cpu->GetSymbolGuardian().Read([&](const ccc::SymbolDatabase& database) {
for (const ccc::Function& function : database.functions)
m_mangled_function_names_to_handles.emplace(function.mangled_name(), function.handle());
for (const ccc::GlobalVariable& global : database.global_variables)
m_mangled_global_names_to_handles.emplace(global.mangled_name(), global.handle());
});
}
virtual bool parseReference(char* str, u64& referenceIndex)
{
for (int i = 0; i < 32; i++)
{
char reg[8];
std::snprintf(reg, std::size(reg), "r%d", i);
if (StringUtil::Strcasecmp(str, reg) == 0 || StringUtil::Strcasecmp(str, m_cpu->getRegisterName(0, i)) == 0)
{
referenceIndex = i;
return true;
}
std::snprintf(reg, std::size(reg), "f%d", i);
if (StringUtil::Strcasecmp(str, reg) == 0)
{
referenceIndex = i | REF_INDEX_FPU;
return true;
}
}
if (StringUtil::Strcasecmp(str, "pc") == 0)
{
referenceIndex = REF_INDEX_PC;
return true;
}
if (StringUtil::Strcasecmp(str, "hi") == 0)
{
referenceIndex = REF_INDEX_HI;
return true;
}
if (StringUtil::Strcasecmp(str, "lo") == 0)
{
referenceIndex = REF_INDEX_LO;
return true;
}
if (StringUtil::Strcasecmp(str, "target") == 0)
{
referenceIndex = REF_INDEX_OPTARGET;
return true;
}
if (StringUtil::Strcasecmp(str, "load") == 0)
{
referenceIndex = REF_INDEX_OPLOAD;
return true;
}
if (StringUtil::Strcasecmp(str, "store") == 0)
{
referenceIndex = REF_INDEX_OPSTORE;
return true;
}
return false;
}
virtual bool parseSymbol(char* str, u64& symbolValue)
{
bool success = false;
m_cpu->GetSymbolGuardian().Read([&](const ccc::SymbolDatabase& database) {
std::string name = str;
// Check for mangled function names.
auto function_iterator = m_mangled_function_names_to_handles.find(name);
if (function_iterator != m_mangled_function_names_to_handles.end())
{
const ccc::Function* function = database.functions.symbol_from_handle(function_iterator->second);
if (function && function->address().valid())
{
symbolValue = function->address().value;
success = true;
return;
}
}
// Check for mangled global variable names.
auto global_iterator = m_mangled_global_names_to_handles.find(name);
if (global_iterator != m_mangled_global_names_to_handles.end())
{
const ccc::GlobalVariable* global = database.global_variables.symbol_from_handle(global_iterator->second);
if (global && global->address().valid())
{
symbolValue = global->address().value;
success = true;
return;
}
}
// Check for regular unmangled names.
const ccc::Symbol* symbol = database.symbol_with_name(name);
if (symbol && symbol->address().valid())
{
symbolValue = symbol->address().value;
success = true;
return;
}
});
return success;
}
virtual u64 getReferenceValue(u64 referenceIndex)
{
if (referenceIndex < 32)
return m_cpu->getRegister(0, referenceIndex)._u64[0];
if (referenceIndex == REF_INDEX_PC)
return m_cpu->getPC();
if (referenceIndex == REF_INDEX_HI)
return m_cpu->getHI()._u64[0];
if (referenceIndex == REF_INDEX_LO)
return m_cpu->getLO()._u64[0];
if (referenceIndex & REF_INDEX_IS_OPSL)
{
const u32 OP = m_cpu->read32(m_cpu->getPC());
const R5900::OPCODE& opcode = R5900::GetInstruction(OP);
if (opcode.flags & IS_MEMORY)
{
// Fetch the address in the base register
u32 target = cpuRegs.GPR.r[(OP >> 21) & 0x1F].UD[0];
// Add the offset (lower 16 bits)
target += static_cast<u16>(OP);
if (referenceIndex & REF_INDEX_OPTARGET)
{
return target;
}
else if (referenceIndex & REF_INDEX_OPLOAD)
{
return (opcode.flags & IS_LOAD) ? target : 0;
}
else if (referenceIndex & REF_INDEX_OPSTORE)
{
return (opcode.flags & IS_STORE) ? target : 0;
}
}
return 0;
}
if (referenceIndex & REF_INDEX_FPU)
{
return m_cpu->getRegister(EECAT_FPR, referenceIndex & 0x1F)._u64[0];
}
return -1;
}
virtual ExpressionType getReferenceType(u64 referenceIndex)
{
if (referenceIndex & REF_INDEX_IS_FLOAT)
{
return EXPR_TYPE_FLOAT;
}
return EXPR_TYPE_UINT;
}
virtual bool getMemoryValue(u32 address, int size, u64& dest, std::string& error)
{
switch (size)
{
case 1:
case 2:
case 4:
case 8:
break;
default:
error = StringUtil::StdStringFromFormat(
TRANSLATE("ExpressionParser", "Invalid memory access size %d."), size);
return false;
}
if (address % size)
{
error = TRANSLATE("ExpressionParser", "Invalid memory access (unaligned).");
return false;
}
switch (size)
{
case 1:
dest = m_cpu->read8(address);
break;
case 2:
dest = m_cpu->read16(address);
break;
case 4:
dest = m_cpu->read32(address);
break;
case 8:
dest = m_cpu->read64(address);
break;
}
return true;
}
protected:
DebugInterface* m_cpu;
std::map<std::string, ccc::FunctionHandle> m_mangled_function_names_to_handles;
std::map<std::string, ccc::GlobalVariableHandle> m_mangled_global_names_to_handles;
};
//
@@ -340,7 +119,7 @@ std::optional<u32> DebugInterface::getStackFrameSize(const ccc::Function& functi
// The stack frame size isn't stored in the symbol table, so we try
// to extract it from the code by checking for an instruction at the
// start of the current function that is in the form of
// "addui $sp, $sp, frame_size" instead.
// "addiu $sp, $sp, frame_size" instead.
u32 instruction = read32(function.address().value);
@@ -354,29 +133,29 @@ std::optional<u32> DebugInterface::getStackFrameSize(const ccc::Function& functi
return static_cast<u32>(stack_frame_size);
}
bool DebugInterface::evaluateExpression(const char* expression, u64& dest)
bool DebugInterface::evaluateExpression(const char* expression, u64& dest, std::string& error)
{
PostfixExpression postfix;
if (!initExpression(expression, postfix))
if (!initExpression(expression, postfix, error))
return false;
if (!parseExpression(postfix, dest))
if (!parseExpression(postfix, dest, error))
return false;
return true;
}
bool DebugInterface::initExpression(const char* exp, PostfixExpression& dest)
bool DebugInterface::initExpression(const char* exp, PostfixExpression& dest, std::string& error)
{
MipsExpressionFunctions funcs(this, true);
return initPostfixExpression(exp, &funcs, dest);
MipsExpressionFunctions funcs(this, nullptr, true);
return initPostfixExpression(exp, &funcs, dest, error);
}
bool DebugInterface::parseExpression(PostfixExpression& exp, u64& dest)
bool DebugInterface::parseExpression(PostfixExpression& exp, u64& dest, std::string& error)
{
MipsExpressionFunctions funcs(this, false);
return parsePostfixExpression(exp, &funcs, dest);
MipsExpressionFunctions funcs(this, nullptr, false);
return parsePostfixExpression(exp, &funcs, dest, error);
}
//
@@ -904,12 +683,10 @@ std::vector<std::unique_ptr<BiosThread>> R5900DebugInterface::GetThreadList() co
return getEEThreads();
}
//
// R3000DebugInterface
//
BreakPointCpu R3000DebugInterface::getCpuType()
{
return BREAKPOINT_IOP;
@@ -1235,8 +1012,8 @@ ElfMemoryReader::ElfMemoryReader(const ccc::ElfFile& elf)
u32 ElfMemoryReader::read8(u32 address)
{
ccc::Result<u8> result = m_elf.get_object_virtual<u8>(address);
if (!result.success())
std::optional<u8> result = m_elf.get_object_virtual<u8>(address);
if (!result.has_value())
return 0;
return *result;
@@ -1244,8 +1021,8 @@ u32 ElfMemoryReader::read8(u32 address)
u32 ElfMemoryReader::read8(u32 address, bool& valid)
{
ccc::Result<u8> result = m_elf.get_object_virtual<u8>(address);
valid = result.success();
std::optional<u8> result = m_elf.get_object_virtual<u8>(address);
valid = result.has_value();
if (!valid)
return 0;
@@ -1254,8 +1031,8 @@ u32 ElfMemoryReader::read8(u32 address, bool& valid)
u32 ElfMemoryReader::read16(u32 address)
{
ccc::Result<u16> result = m_elf.get_object_virtual<u16>(address);
if (!result.success())
std::optional<u16> result = m_elf.get_object_virtual<u16>(address);
if (!result.has_value())
return 0;
return *result;
@@ -1263,8 +1040,8 @@ u32 ElfMemoryReader::read16(u32 address)
u32 ElfMemoryReader::read16(u32 address, bool& valid)
{
ccc::Result<u16> result = m_elf.get_object_virtual<u16>(address);
valid = result.success();
std::optional<u16> result = m_elf.get_object_virtual<u16>(address);
valid = result.has_value();
if (!valid)
return 0;
@@ -1273,8 +1050,8 @@ u32 ElfMemoryReader::read16(u32 address, bool& valid)
u32 ElfMemoryReader::read32(u32 address)
{
ccc::Result<u32> result = m_elf.get_object_virtual<u32>(address);
if (!result.success())
std::optional<u32> result = m_elf.get_object_virtual<u32>(address);
if (!result.has_value())
return 0;
return *result;
@@ -1282,8 +1059,8 @@ u32 ElfMemoryReader::read32(u32 address)
u32 ElfMemoryReader::read32(u32 address, bool& valid)
{
ccc::Result<u32> result = m_elf.get_object_virtual<u32>(address);
valid = result.success();
std::optional<u32> result = m_elf.get_object_virtual<u32>(address);
valid = result.has_value();
if (!valid)
return 0;
@@ -1292,8 +1069,8 @@ u32 ElfMemoryReader::read32(u32 address, bool& valid)
u64 ElfMemoryReader::read64(u32 address)
{
ccc::Result<u64> result = m_elf.get_object_virtual<u64>(address);
if (!result.success())
std::optional<u64> result = m_elf.get_object_virtual<u64>(address);
if (!result.has_value())
return 0;
return *result;
@@ -1301,10 +1078,246 @@ u64 ElfMemoryReader::read64(u32 address)
u64 ElfMemoryReader::read64(u32 address, bool& valid)
{
ccc::Result<u64> result = m_elf.get_object_virtual<u64>(address);
valid = result.success();
std::optional<u64> result = m_elf.get_object_virtual<u64>(address);
valid = result.has_value();
if (!valid)
return 0;
return *result;
}
//
// MipsExpressionFunctions
//
MipsExpressionFunctions::MipsExpressionFunctions(
DebugInterface* cpu, const ccc::SymbolDatabase* symbolDatabase, bool shouldEnumerateSymbols)
: m_cpu(cpu)
, m_database(symbolDatabase)
{
if (!shouldEnumerateSymbols)
return;
if (symbolDatabase)
{
enumerateSymbols(*symbolDatabase);
}
else
{
m_cpu->GetSymbolGuardian().Read([&](const ccc::SymbolDatabase& database) {
enumerateSymbols(database);
});
}
}
void MipsExpressionFunctions::enumerateSymbols(const ccc::SymbolDatabase& database)
{
// TODO: Add mangled symbol name maps to CCC and remove this.
for (const ccc::Function& function : database.functions)
m_mangled_function_names_to_handles.emplace(function.mangled_name(), function.handle());
for (const ccc::GlobalVariable& global : database.global_variables)
m_mangled_global_names_to_handles.emplace(global.mangled_name(), global.handle());
}
bool MipsExpressionFunctions::parseReference(char* str, u64& referenceIndex)
{
for (int i = 0; i < 32; i++)
{
char reg[8];
std::snprintf(reg, std::size(reg), "r%d", i);
if (StringUtil::Strcasecmp(str, reg) == 0 || StringUtil::Strcasecmp(str, m_cpu->getRegisterName(0, i)) == 0)
{
referenceIndex = i;
return true;
}
std::snprintf(reg, std::size(reg), "f%d", i);
if (StringUtil::Strcasecmp(str, reg) == 0)
{
referenceIndex = i | REF_INDEX_FPU;
return true;
}
}
if (StringUtil::Strcasecmp(str, "pc") == 0)
{
referenceIndex = REF_INDEX_PC;
return true;
}
if (StringUtil::Strcasecmp(str, "hi") == 0)
{
referenceIndex = REF_INDEX_HI;
return true;
}
if (StringUtil::Strcasecmp(str, "lo") == 0)
{
referenceIndex = REF_INDEX_LO;
return true;
}
if (StringUtil::Strcasecmp(str, "target") == 0)
{
referenceIndex = REF_INDEX_OPTARGET;
return true;
}
if (StringUtil::Strcasecmp(str, "load") == 0)
{
referenceIndex = REF_INDEX_OPLOAD;
return true;
}
if (StringUtil::Strcasecmp(str, "store") == 0)
{
referenceIndex = REF_INDEX_OPSTORE;
return true;
}
return false;
}
bool MipsExpressionFunctions::parseSymbol(char* str, u64& symbolValue)
{
if (m_database)
return parseSymbol(str, symbolValue, *m_database);
bool success = false;
m_cpu->GetSymbolGuardian().Read([&](const ccc::SymbolDatabase& database) {
success = parseSymbol(str, symbolValue, database);
});
return success;
}
bool MipsExpressionFunctions::parseSymbol(char* str, u64& symbolValue, const ccc::SymbolDatabase& database)
{
std::string name = str;
// Check for mangled function names.
auto function_iterator = m_mangled_function_names_to_handles.find(name);
if (function_iterator != m_mangled_function_names_to_handles.end())
{
const ccc::Function* function = database.functions.symbol_from_handle(function_iterator->second);
if (function && function->address().valid())
{
symbolValue = function->address().value;
return true;
}
}
// Check for mangled global variable names.
auto global_iterator = m_mangled_global_names_to_handles.find(name);
if (global_iterator != m_mangled_global_names_to_handles.end())
{
const ccc::GlobalVariable* global = database.global_variables.symbol_from_handle(global_iterator->second);
if (global && global->address().valid())
{
symbolValue = global->address().value;
return true;
}
}
// Check for regular unmangled names.
const ccc::Symbol* symbol = database.symbol_with_name(name);
if (symbol && symbol->address().valid())
{
symbolValue = symbol->address().value;
return true;
}
return false;
}
u64 MipsExpressionFunctions::getReferenceValue(u64 referenceIndex)
{
if (referenceIndex < 32)
return m_cpu->getRegister(0, referenceIndex)._u64[0];
if (referenceIndex == REF_INDEX_PC)
return m_cpu->getPC();
if (referenceIndex == REF_INDEX_HI)
return m_cpu->getHI()._u64[0];
if (referenceIndex == REF_INDEX_LO)
return m_cpu->getLO()._u64[0];
if (referenceIndex & REF_INDEX_IS_OPSL)
{
const u32 OP = m_cpu->read32(m_cpu->getPC());
const R5900::OPCODE& opcode = R5900::GetInstruction(OP);
if (opcode.flags & IS_MEMORY)
{
// Fetch the address in the base register
u32 target = cpuRegs.GPR.r[(OP >> 21) & 0x1F].UD[0];
// Add the offset (lower 16 bits)
target += static_cast<u16>(OP);
if (referenceIndex & REF_INDEX_OPTARGET)
{
return target;
}
else if (referenceIndex & REF_INDEX_OPLOAD)
{
return (opcode.flags & IS_LOAD) ? target : 0;
}
else if (referenceIndex & REF_INDEX_OPSTORE)
{
return (opcode.flags & IS_STORE) ? target : 0;
}
}
return 0;
}
if (referenceIndex & REF_INDEX_FPU)
{
return m_cpu->getRegister(EECAT_FPR, referenceIndex & 0x1F)._u64[0];
}
return -1;
}
ExpressionType MipsExpressionFunctions::getReferenceType(u64 referenceIndex)
{
if (referenceIndex & REF_INDEX_IS_FLOAT)
{
return EXPR_TYPE_FLOAT;
}
return EXPR_TYPE_UINT;
}
bool MipsExpressionFunctions::getMemoryValue(u32 address, int size, u64& dest, std::string& error)
{
switch (size)
{
case 1:
case 2:
case 4:
case 8:
break;
default:
error = StringUtil::StdStringFromFormat(
TRANSLATE("ExpressionParser", "Invalid memory access size %d."), size);
return false;
}
if (address % size)
{
error = TRANSLATE("ExpressionParser", "Invalid memory access (unaligned).");
return false;
}
switch (size)
{
case 1:
dest = m_cpu->read8(address);
break;
case 2:
dest = m_cpu->read16(address);
break;
case 4:
dest = m_cpu->read32(address);
break;
case 8:
dest = m_cpu->read64(address);
break;
}
return true;
}

View File

@@ -2,8 +2,8 @@
// SPDX-License-Identifier: GPL-3.0+
#pragma once
#include "DebugTools/BiosDebugData.h"
#include "MemoryTypes.h"
#include "BiosDebugData.h"
#include "ExpressionParser.h"
#include "SymbolGuardian.h"
#include "SymbolImporter.h"
@@ -86,9 +86,9 @@ public:
virtual SymbolImporter* GetSymbolImporter() const = 0;
virtual std::vector<std::unique_ptr<BiosThread>> GetThreadList() const = 0;
bool evaluateExpression(const char* expression, u64& dest);
bool initExpression(const char* exp, PostfixExpression& dest);
bool parseExpression(PostfixExpression& exp, u64& dest);
bool evaluateExpression(const char* expression, u64& dest, std::string& error);
bool initExpression(const char* exp, PostfixExpression& dest, std::string& error);
bool parseExpression(PostfixExpression& exp, u64& dest, std::string& error);
bool isAlive();
bool isCpuPaused();
void pauseCpu();
@@ -210,5 +210,26 @@ protected:
const ccc::ElfFile& m_elf;
};
class MipsExpressionFunctions : public IExpressionFunctions
{
public:
MipsExpressionFunctions(
DebugInterface* cpu, const ccc::SymbolDatabase* symbolDatabase, bool shouldEnumerateSymbols);
bool parseReference(char* str, u64& referenceIndex) override;
bool parseSymbol(char* str, u64& symbolValue) override;
u64 getReferenceValue(u64 referenceIndex) override;
ExpressionType getReferenceType(u64 referenceIndex) override;
bool getMemoryValue(u32 address, int size, u64& dest, std::string& error) override;
protected:
void enumerateSymbols(const ccc::SymbolDatabase& database);
bool parseSymbol(char* str, u64& symbolValue, const ccc::SymbolDatabase& database);
DebugInterface* m_cpu;
const ccc::SymbolDatabase* m_database;
std::map<std::string, ccc::FunctionHandle> m_mangled_function_names_to_handles;
std::map<std::string, ccc::GlobalVariableHandle> m_mangled_global_names_to_handles;
};
extern R5900DebugInterface r5900Debug;
extern R3000DebugInterface r3000Debug;

View File

@@ -21,8 +21,6 @@ typedef enum {
typedef enum { EXCOMM_CONST, EXCOMM_CONST_FLOAT, EXCOMM_REF, EXCOMM_OP } ExpressionCommand;
static std::string expressionError;
typedef struct {
char Name[4];
unsigned char Priority;
@@ -209,10 +207,8 @@ bool isAlphaNum(char c)
c == '@' || c == '_' || c == '$' || c == '.');
}
bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, PostfixExpression& dest)
bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, PostfixExpression& dest, std::string& error)
{
expressionError.clear();
int infixPos = 0;
int infixLen = (int)strlen(infix);
ExpressionOpcodeType lastOpcode = EXOP_NONE;
@@ -241,7 +237,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
if(subPos == sizeof(subStr) - 1)
{
expressionError = TRANSLATE("ExpressionParser", "Token too long.");
error = TRANSLATE("ExpressionParser", "Token too long.");
return false;
}
@@ -251,14 +247,14 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
isFloat = true;
else if (!parseNumber(subStr,16,subPos,value))
{
expressionError = StringUtil::StdStringFromFormat(
error = StringUtil::StdStringFromFormat(
TRANSLATE("ExpressionParser", "Invalid number \"%s\"."), subStr);
return false;
}
dest.push_back(ExpressionPair(isFloat?EXCOMM_CONST_FLOAT:EXCOMM_CONST,value));
lastOpcode = EXOP_NUMBER;
} else if ((first >= 'a' && first <= 'z') || first == '@')
} else if ((first >= 'a' && first <= 'z') || first == '@' || first == '_')
{
while (isAlphaNum(infix[infixPos]) && subPos < static_cast<int>(sizeof(subStr)) - 1)
{
@@ -268,7 +264,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
if(subPos == sizeof(subStr) - 1)
{
expressionError = TRANSLATE("ExpressionParser", "Token too long.");
error = TRANSLATE("ExpressionParser", "Token too long.");
return false;
}
@@ -294,7 +290,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
continue;
}
expressionError = StringUtil::StdStringFromFormat(
error = StringUtil::StdStringFromFormat(
TRANSLATE("ExpressionParser", "Invalid symbol \"%s\"."), subStr);
return false;
} else {
@@ -302,7 +298,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
ExpressionOpcodeType type = getExpressionOpcode(&infix[infixPos],len,lastOpcode);
if (type == EXOP_NONE)
{
expressionError = StringUtil::StdStringFromFormat(
error = StringUtil::StdStringFromFormat(
TRANSLATE("ExpressionParser", "Invalid operator at \"%s\"."), &infix[infixPos]);
return false;
}
@@ -318,7 +314,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
{
if (opcodeStack.empty())
{
expressionError = TRANSLATE("ExpressionParser", "Closing parenthesis without opening one.");
error = TRANSLATE("ExpressionParser", "Closing parenthesis without opening one.");
return false;
}
ExpressionOpcodeType t = opcodeStack[opcodeStack.size()-1];
@@ -332,7 +328,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
{
if (opcodeStack.empty())
{
expressionError = TRANSLATE("ExpressionParser", "Closing bracket without opening one.");
error = TRANSLATE("ExpressionParser", "Closing bracket without opening one.");
return false;
}
ExpressionOpcodeType t = opcodeStack[opcodeStack.size()-1];
@@ -385,7 +381,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
if (t == EXOP_BRACKETL) // opening bracket without closing one
{
expressionError = TRANSLATE("ExpressionParser", "Parenthesis not closed.");
error = TRANSLATE("ExpressionParser", "Parenthesis not closed.");
return false;
}
dest.push_back(ExpressionPair(EXCOMM_OP,t));
@@ -415,7 +411,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
return true;
}
bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, u64& dest)
bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, u64& dest, std::string& error)
{
size_t num = 0;
u64 opcode;
@@ -444,7 +440,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
opcode = exp[num++].second;
if (valueStack.size() < ExpressionOpcodes[opcode].args)
{
expressionError = TRANSLATE("ExpressionParser", "Not enough arguments.");
error = TRANSLATE("ExpressionParser", "Not enough arguments.");
return false;
}
for (int l = 0; l < ExpressionOpcodes[opcode].args; l++)
@@ -459,12 +455,12 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
case EXOP_MEMSIZE: // must be followed by EXOP_MEM
if (exp[num++].second != EXOP_MEM)
{
expressionError = TRANSLATE("ExpressionParser", "Invalid memsize operator.");
error = TRANSLATE("ExpressionParser", "Invalid memsize operator.");
return false;
}
u64 val;
if(!funcs->getMemoryValue(arg[1],arg[0],val,expressionError))
if(!funcs->getMemoryValue(arg[1],arg[0],val,error))
{
return false;
}
@@ -473,7 +469,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
case EXOP_MEM:
{
u64 val;
if (!funcs->getMemoryValue(arg[0],4,val,expressionError))
if (!funcs->getMemoryValue(arg[0],4,val,error))
{
return false;
}
@@ -503,7 +499,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
case EXOP_DIV: // a/b
if (arg[0] == 0)
{
expressionError = TRANSLATE("ExpressionParser", "Division by zero.");
error = TRANSLATE("ExpressionParser", "Division by zero.");
return false;
}
if (useFloat)
@@ -514,7 +510,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
case EXOP_MOD: // a%b
if (arg[0] == 0)
{
expressionError = TRANSLATE("ExpressionParser", "Modulo by zero.");
error = TRANSLATE("ExpressionParser", "Modulo by zero.");
return false;
}
valueStack.push_back(arg[1]%arg[0]);
@@ -593,7 +589,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
case EXOP_TERTELSE: // exp ? exp : exp, else muss zuerst kommen!
if (exp[num++].second != EXOP_TERTIF)
{
expressionError = TRANSLATE("ExpressionParser", "Invalid tertiary operator.");
error = TRANSLATE("ExpressionParser", "Invalid tertiary operator.");
return false;
}
valueStack.push_back(arg[2]?arg[1]:arg[0]);
@@ -608,17 +604,9 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
return true;
}
bool parseExpression(char* exp, IExpressionFunctions* funcs, u64& dest)
bool parseExpression(const char* exp, IExpressionFunctions* funcs, u64& dest, std::string& error)
{
PostfixExpression postfix;
if (!initPostfixExpression(exp,funcs,postfix)) return false;
return parsePostfixExpression(postfix,funcs,dest);
}
const char* getExpressionError()
{
if (expressionError.empty())
return TRANSLATE("ExpressionParser", "Invalid expression.");
return expressionError.c_str();
if (!initPostfixExpression(exp,funcs,postfix,error)) return false;
return parsePostfixExpression(postfix,funcs,dest,error);
}

View File

@@ -26,7 +26,6 @@ public:
virtual bool getMemoryValue(u32 address, int size, u64& dest, std::string& error) = 0;
};
bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, PostfixExpression& dest);
bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, u64& dest);
bool parseExpression(const char* exp, IExpressionFunctions* funcs, u64& dest);
const char* getExpressionError();
bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, PostfixExpression& dest, std::string& error);
bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, u64& dest, std::string& error);
bool parseExpression(const char* exp, IExpressionFunctions* funcs, u64& dest, std::string& error);

View File

@@ -355,11 +355,12 @@ bool MipsCheckImmediate(const char* Source, DebugInterface* cpu, int& dest, int&
RetLen = SourceLen;
PostfixExpression postfix;
if (!cpu->initExpression(Buffer,postfix))
std::string error;
if (!cpu->initExpression(Buffer,postfix,error))
return false;
u64 value;
if (!cpu->parseExpression(postfix,value))
if (!cpu->parseExpression(postfix,value,error))
return false;
dest = (int) value;

View File

@@ -212,11 +212,6 @@ void SymbolImporter::AnalyseElf(
SymbolGuardian::GenerateFunctionHashes(temp_database, reader);
}
if (m_interrupt_import_thread)
return;
ScanForFunctions(temp_database, worker_symbol_file, options);
if (m_interrupt_import_thread)
return;
@@ -227,6 +222,14 @@ void SymbolImporter::AnalyseElf(
return;
database.merge_from(temp_database);
if (m_interrupt_import_thread)
return;
// The function scanner has to be run on the main database so that
// functions created before the importer was run are still
// considered. Otherwise, duplicate functions will be created.
ScanForFunctions(database, worker_symbol_file, options);
});
});
}
@@ -276,13 +279,6 @@ void SymbolImporter::ImportSymbols(
const std::map<std::string, ccc::DataTypeHandle>& builtin_types,
const std::atomic_bool* interrupt)
{
ccc::DemanglerFunctions demangler;
if (options.DemangleSymbols)
{
demangler.cplus_demangle = cplus_demangle;
demangler.cplus_demangle_opname = cplus_demangle_opname;
}
u32 importer_flags =
ccc::NO_MEMBER_FUNCTIONS |
ccc::NO_OPTIMIZED_OUT_FUNCTIONS |
@@ -291,6 +287,13 @@ void SymbolImporter::ImportSymbols(
if (options.DemangleParameters)
importer_flags |= ccc::DEMANGLE_PARAMETERS;
ccc::DemanglerFunctions demangler;
if (options.DemangleSymbols)
{
demangler.cplus_demangle = cplus_demangle;
demangler.cplus_demangle_opname = cplus_demangle_opname;
}
if (options.ImportSymbolsFromELF)
{
ccc::Result<std::vector<std::unique_ptr<ccc::SymbolTable>>> symbol_tables = elf.get_all_symbol_tables();
@@ -301,7 +304,7 @@ void SymbolImporter::ImportSymbols(
else
{
ccc::Result<ccc::ModuleHandle> module_handle = ccc::import_symbol_tables(
database, elf.name(), *symbol_tables, importer_flags, demangler, interrupt);
database, *symbol_tables, elf.name(), ccc::Address(), importer_flags, demangler, interrupt);
if (!module_handle.success())
{
ccc::report_error(module_handle.error());
@@ -311,7 +314,7 @@ void SymbolImporter::ImportSymbols(
if (!nocash_path.empty() && options.ImportSymFileFromDefaultLocation)
{
ccc::Result<bool> nocash_result = ImportNocashSymbols(database, nocash_path, builtin_types);
ccc::Result<bool> nocash_result = ImportNocashSymbols(database, nocash_path, 0, builtin_types);
if (!nocash_result.success())
{
Console.Error("Failed to import symbol file '%s': %s",
@@ -319,14 +322,64 @@ void SymbolImporter::ImportSymbols(
}
}
ImportExtraSymbols(database, options, builtin_types, importer_flags, demangler, interrupt);
Console.WriteLn("Imported %d symbols.", database.symbol_count());
return;
}
void SymbolImporter::ImportExtraSymbols(
ccc::SymbolDatabase& database,
const Pcsx2Config::DebugAnalysisOptions& options,
const std::map<std::string, ccc::DataTypeHandle>& builtin_types,
u32 importer_flags,
const ccc::DemanglerFunctions& demangler,
const std::atomic_bool* interrupt)
{
MipsExpressionFunctions expression_functions(&r5900Debug, &database, true);
for (const DebugExtraSymbolFile& extra_symbol_file : options.ExtraSymbolFiles)
{
if (*interrupt)
return;
if (StringUtil::EndsWithNoCase(extra_symbol_file.Path, ".sym"))
std::string path = Path::ToNativePath(extra_symbol_file.Path);
if (!Path::IsAbsolute(path))
path = Path::Combine(EmuFolders::GameSettings, path);
if (!extra_symbol_file.Condition.empty())
{
ccc::Result<bool> nocash_result = ImportNocashSymbols(database, extra_symbol_file.Path, builtin_types);
u64 expression_result = 0;
std::string error;
if (!parseExpression(extra_symbol_file.Condition.c_str(), &expression_functions, expression_result, error))
{
Console.Error("Failed to evaluate condition expression '%s' while importing extra symbol file '%s': %s",
extra_symbol_file.Condition.c_str(), path.c_str(), error.c_str());
}
if (!expression_result)
continue;
}
ccc::Address base_address;
if (!extra_symbol_file.BaseAddress.empty())
{
u64 expression_result = 0;
std::string error;
if (!parseExpression(extra_symbol_file.BaseAddress.c_str(), &expression_functions, expression_result, error))
{
Console.Error("Failed to evaluate base address expression '%s' while importing extra symbol file '%s': %s",
extra_symbol_file.BaseAddress.c_str(), path.c_str(), error.c_str());
}
base_address = static_cast<u32>(expression_result);
}
if (StringUtil::EndsWithNoCase(path, ".sym"))
{
ccc::Result<bool> nocash_result = ImportNocashSymbols(
database, path, base_address.get_or_zero(), builtin_types);
if (!nocash_result.success())
{
Console.Error("Failed to import symbol file '%s': %s",
@@ -334,29 +387,30 @@ void SymbolImporter::ImportSymbols(
}
if (!*nocash_result)
Console.Error("Cannot open symbol file '%s'.", extra_symbol_file.Path.c_str());
Console.Error("Cannot open symbol file '%s'.", path.c_str());
continue;
}
Error error;
std::optional<std::vector<u8>> image = FileSystem::ReadBinaryFile(extra_symbol_file.Path.c_str());
std::optional<std::vector<u8>> image = FileSystem::ReadBinaryFile(path.c_str());
if (!image.has_value())
{
Console.Error("Failed to read extra symbol file '%s'.", extra_symbol_file.Path.c_str());
Console.Error("Failed to read extra symbol file '%s'.", path.c_str());
continue;
}
std::string file_name(Path::GetFileName(extra_symbol_file.Path));
std::string file_name(Path::GetFileName(path));
ccc::Result<std::unique_ptr<ccc::SymbolFile>> symbol_file = ccc::parse_symbol_file(std::move(*image), file_name.c_str());
ccc::Result<std::unique_ptr<ccc::SymbolFile>> symbol_file = ccc::parse_symbol_file(
std::move(*image), file_name.c_str());
if (!symbol_file.success())
{
ccc::report_error(symbol_file.error());
continue;
}
ccc::Result<std::vector<std::unique_ptr<ccc::SymbolTable>>> symbol_tables = (*symbol_file)->get_all_symbol_tables();
ccc::Result<std::vector<std::unique_ptr<ccc::SymbolTable>>> symbol_tables =
(*symbol_file)->get_all_symbol_tables();
if (!symbol_tables.success())
{
ccc::report_error(symbol_tables.error());
@@ -364,22 +418,19 @@ void SymbolImporter::ImportSymbols(
}
ccc::Result<ccc::ModuleHandle> module_handle = ccc::import_symbol_tables(
database, elf.name(), *symbol_tables, importer_flags, demangler, interrupt);
database, *symbol_tables, (*symbol_file)->name(), base_address, importer_flags, demangler, interrupt);
if (!module_handle.success())
{
ccc::report_error(module_handle.error());
continue;
}
}
Console.WriteLn("Imported %d symbols.", database.symbol_count());
return;
}
ccc::Result<bool> SymbolImporter::ImportNocashSymbols(
ccc::SymbolDatabase& database,
const std::string& file_path,
u32 base_address,
const std::map<std::string, ccc::DataTypeHandle>& builtin_types)
{
auto file = FileSystem::OpenManagedCFile(file_path.c_str(), "r");
@@ -405,6 +456,8 @@ ccc::Result<bool> SymbolImporter::ImportNocashSymbols(
if (address == 0 && strcmp(value, "0") == 0)
continue;
address += base_address;
if (value[0] == '.')
{
// data directives
@@ -498,12 +551,32 @@ std::unique_ptr<ccc::ast::Node> SymbolImporter::GetBuiltInType(
void SymbolImporter::ScanForFunctions(
ccc::SymbolDatabase& database, const ccc::ElfSymbolFile& elf, const Pcsx2Config::DebugAnalysisOptions& options)
{
MipsExpressionFunctions expression_functions(&r5900Debug, &database, true);
u32 start_address = 0;
u32 end_address = 0;
if (options.CustomFunctionScanRange)
{
start_address = static_cast<u32>(std::stoull(options.FunctionScanStartAddress.c_str(), nullptr, 16));
end_address = static_cast<u32>(std::stoull(options.FunctionScanEndAddress.c_str(), nullptr, 16));
u64 expression_result = 0;
std::string error;
if (!parseExpression(options.FunctionScanStartAddress.c_str(), &expression_functions, expression_result, error))
{
Console.Error("Failed to evaluate start address expression '%s' while scanning for functions: %s",
options.FunctionScanStartAddress.c_str(), error.c_str());
return;
}
start_address = static_cast<u32>(expression_result);
if (!parseExpression(options.FunctionScanEndAddress.c_str(), &expression_functions, expression_result, error))
{
Console.Error("Failed to evaluate end address expression '%s' while scanning for functions: %s",
options.FunctionScanEndAddress.c_str(), error.c_str());
return;
}
end_address = static_cast<u32>(expression_result);
}
else
{

View File

@@ -46,9 +46,18 @@ public:
const std::map<std::string, ccc::DataTypeHandle>& builtin_types,
const std::atomic_bool* interrupt);
static void ImportExtraSymbols(
ccc::SymbolDatabase& database,
const Pcsx2Config::DebugAnalysisOptions& options,
const std::map<std::string, ccc::DataTypeHandle>& builtin_types,
u32 importer_flags,
const ccc::DemanglerFunctions& demangler,
const std::atomic_bool* interrupt);
static ccc::Result<bool> ImportNocashSymbols(
ccc::SymbolDatabase& database,
const std::string& file_path,
u32 base_address,
const std::map<std::string, ccc::DataTypeHandle>& builtin_types);
static std::unique_ptr<ccc::ast::Node> GetBuiltInType(

View File

@@ -10,6 +10,7 @@
#include "GS/Renderers/Vulkan/VKShaderCache.h"
#include "GS/Renderers/Vulkan/VKSwapChain.h"
#include "BuildVersion.h"
#include "Host.h"
#include "common/Console.h"
@@ -103,16 +104,15 @@ VkInstance GSDeviceVK::CreateVulkanInstance(const WindowInfo& wi, OptionalExtens
if (!SelectInstanceExtensions(&enabled_extensions, wi, oe, enable_debug_utils))
return VK_NULL_HANDLE;
// Remember to manually update this every release. We don't pull in svnrev.h here, because
// it's only the major/minor version, and rebuilding the file every time something else changes
// is unnecessary.
VkApplicationInfo app_info = {};
app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
app_info.pNext = nullptr;
app_info.pApplicationName = "PCSX2";
app_info.applicationVersion = VK_MAKE_VERSION(1, 7, 0);
app_info.applicationVersion = VK_MAKE_VERSION(
BuildVersion::GitTagHi, BuildVersion::GitTagMid, BuildVersion::GitTagLo);
app_info.pEngineName = "PCSX2";
app_info.engineVersion = VK_MAKE_VERSION(1, 7, 0);
app_info.engineVersion = VK_MAKE_VERSION(
BuildVersion::GitTagHi, BuildVersion::GitTagMid, BuildVersion::GitTagLo);
app_info.apiVersion = VK_API_VERSION_1_1;
VkInstanceCreateInfo instance_create_info = {};

View File

@@ -1,12 +1,12 @@
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
#include "BuildVersion.h"
#include "GS.h"
#include "GS/Renderers/HW/GSTextureReplacements.h"
#include "Host.h"
#include "LayeredSettingsInterface.h"
#include "VMManager.h"
#include "svnrev.h"
#include "common/Assertions.h"
#include "common/CrashHandler.h"
@@ -159,7 +159,7 @@ bool Host::ConfirmFormattedMessage(const std::string_view title, const char* for
std::string Host::GetHTTPUserAgent()
{
return fmt::format("PCSX2 " GIT_REV " ({})", GetOSVersionString());
return fmt::format("PCSX2 {} ({})", BuildVersion::GitRev, GetOSVersionString());
}
std::unique_lock<std::mutex> Host::GetSettingsLock()

View File

@@ -3,6 +3,7 @@
#define IMGUI_DEFINE_MATH_OPERATORS
#include "BuildVersion.h"
#include "CDVD/CDVDcommon.h"
#include "GS/Renderers/Common/GSDevice.h"
#include "GS/Renderers/Common/GSTexture.h"
@@ -23,7 +24,6 @@
#include "USB/USB.h"
#include "VMManager.h"
#include "ps2/BiosTools.h"
#include "svnrev.h"
#include "common/Console.h"
#include "common/Error.h"
@@ -6633,7 +6633,7 @@ void FullscreenUI::DrawAboutWindow()
"This allows you to play PS2 games on your PC, with many additional features and benefits."));
ImGui::NewLine();
ImGui::TextWrapped(FSUI_CSTR("Version: %s"), GIT_REV);
ImGui::TextWrapped(FSUI_CSTR("Version: %s"), BuildVersion::GitRev);
ImGui::NewLine();
ImGui::TextWrapped("%s",

View File

@@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
#include "BuildVersion.h"
#include "Config.h"
#include "Counters.h"
#include "GS.h"
@@ -24,7 +25,6 @@
#include "SIO/Pad/PadBase.h"
#include "USB/USB.h"
#include "VMManager.h"
#include "svnrev.h"
#include "cpuinfo.h"
#include "common/BitUtils.h"
@@ -170,7 +170,7 @@ __ri void ImGuiManager::DrawPerformanceOverlay(float& position_y, float scale, f
if (GSConfig.OsdShowVersion)
{
text.append_format("{}PCSX2 {}", first ? "" : " | ", GIT_REV);
text.append_format("{}PCSX2 {}", first ? "" : " | ", BuildVersion::GitRev);
}
if (!text.empty())

View File

@@ -1,13 +1,13 @@
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
#include "BuildVersion.h"
#include "Common.h"
#include "Host.h"
#include "Memory.h"
#include "Elfheader.h"
#include "PINE.h"
#include "VMManager.h"
#include "svnrev.h"
#include <atomic>
#include <cstdio>
@@ -607,14 +607,12 @@ PINEServer::IPCBuffer PINEServer::ParseCommand(std::span<u8> buf, std::vector<u8
{
if (!VMManager::HasValidVM())
goto error;
static constexpr const char* version = "PCSX2 " GIT_REV;
static constexpr u32 size = sizeof(version) + 1;
u32 size = strlen(BuildVersion::GitRev) + 7;
if (!SafetyChecks(buf_cnt, 0, ret_cnt, size + 4, buf_size)) [[unlikely]]
goto error;
ToResultVector(ret_buffer, size, ret_cnt);
ret_cnt += 4;
memcpy(&ret_buffer[ret_cnt], version, size);
snprintf(reinterpret_cast<char*>(&ret_buffer[ret_cnt]), size, "PCSX2 %s", BuildVersion::GitRev);
ret_cnt += size;
break;
}

View File

@@ -1625,6 +1625,8 @@ void Pcsx2Config::DebugAnalysisOptions::LoadSave(SettingsWrapper& wrap)
file = ExtraSymbolFiles[i];
SettingsWrapEntryEx(file.Path, "Path");
SettingsWrapEntryEx(file.BaseAddress, "BaseAddress");
SettingsWrapEntryEx(file.Condition, "Condition");
if (wrap.IsLoading())
ExtraSymbolFiles.emplace_back(std::move(file));

View File

@@ -3,13 +3,10 @@
#include "InputRecordingFile.h"
#include "BuildVersion.h"
#include "Utilities/InputRecordingLogger.h"
#include "common/FileSystem.h"
#include "common/StringUtil.h"
#include "DebugTools/Debug.h"
#include "MemoryTypes.h"
#include "svnrev.h"
#include <fmt/format.h>
@@ -23,7 +20,7 @@ void InputRecordingFile::InputRecordingFileHeader::init() noexcept
void InputRecordingFile::setEmulatorVersion()
{
StringUtil::Strlcpy(m_header.m_emulatorVersion, "PCSX2-" GIT_REV, sizeof(m_header.m_emulatorVersion));
snprintf(m_header.m_emulatorVersion, sizeof(m_header.m_emulatorVersion), "PCSX2-%s", BuildVersion::GitRev);
}
void InputRecordingFile::setAuthor(const std::string& _author)

View File

@@ -20,8 +20,6 @@
#include "Host.h"
#include "IconsPromptFont.h"
#include "svnrev.h"
#include "fmt/core.h"
#include <map>
@@ -1075,4 +1073,4 @@ bool FileMcd_DeleteCard(const std::string_view name)
}
return true;
}
}

View File

@@ -21,8 +21,6 @@
#include "ryml_std.hpp"
#include "ryml.hpp"
#include "svnrev.h"
#include <sstream>
#include <mutex>
#include <optional>
@@ -2380,4 +2378,4 @@ bool FolderMemoryCardAggregator::ReIndex(uint slot, const bool enableFiltering,
SetFiltering(enableFiltering);
m_lastKnownFilter = filter;
return false;
}
}

View File

@@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-3.0+
#include "Achievements.h"
#include "BuildVersion.h"
#include "CDVD/CDVD.h"
#include "COP0.h"
#include "Cache.h"
@@ -27,7 +28,6 @@
#include "VMManager.h"
#include "VUmicro.h"
#include "ps2/BiosTools.h"
#include "svnrev.h"
#include "common/Error.h"
#include "common/FileSystem.h"
@@ -972,11 +972,14 @@ static bool SaveState_AddToZip(zip_t* zf, ArchiveEntryList* srclist, SaveStateSc
VersionIndicator* vi = static_cast<VersionIndicator*>(std::malloc(sizeof(VersionIndicator)));
vi->save_version = g_SaveVersion;
#if GIT_TAGGED_COMMIT
StringUtil::Strlcpy(vi->version, GIT_TAG, std::size(vi->version));
#else
StringUtil::Strlcpy(vi->version, "Unknown", std::size(vi->version));
#endif
if (BuildVersion::GitTaggedCommit)
{
StringUtil::Strlcpy(vi->version, BuildVersion::GitTag, std::size(vi->version));
}
else
{
StringUtil::Strlcpy(vi->version, "Unknown", std::size(vi->version));
}
zip_source_t* const zs = zip_source_buffer(zf, vi, sizeof(*vi), 1);
if (!zs)

View File

@@ -34,10 +34,9 @@ namespace usb_eyetoy
HRESULT DirectShow::CallbackHandler::SampleCB(double time, IMediaSample* sample)
{
HRESULT hr;
unsigned char* buffer;
hr = sample->GetPointer((BYTE**)&buffer);
const HRESULT hr = sample->GetPointer((BYTE**)&buffer);
if (hr != S_OK)
return S_OK;
@@ -588,7 +587,7 @@ namespace usb_eyetoy
{
mpeg_mutex.lock();
int len2 = mpeg_buffer.length;
if ((unsigned int)len < mpeg_buffer.length)
if (static_cast<size_t>(len) < mpeg_buffer.length)
len2 = len;
memcpy(buf, mpeg_buffer.start, len2);
mpeg_buffer.length = 0;

View File

@@ -26,8 +26,8 @@ namespace usb_eyetoy
std::unique_ptr<VideoDevice> videodev;
USBDevice* mic;
uint8_t regs[0xFF]; //OV519
uint8_t i2c_regs[0xFF]; //OV764x
u8 regs[0xFF]; //OV519
u8 i2c_regs[0xFF]; //OV764x
int hw_camera_running;
int frame_step;
@@ -81,10 +81,10 @@ namespace usb_eyetoy
}
else if (s->hw_camera_running && s->subtype == TYPE_OV511P)
{
const int width = 320;
const int height = 240;
constexpr int width = 320;
constexpr int height = 240;
const FrameFormat format = format_yuv400;
const int mirror = 0;
constexpr int mirror = 0;
Console.WriteLn(
"EyeToy : eyetoy_open(); hw=%d, w=%d, h=%d, fmt=%d, mirr=%d", s->hw_camera_running, width, height, format, mirror);
if (s->videodev->Open(width, height, format, mirror) != 0)
@@ -111,7 +111,7 @@ namespace usb_eyetoy
s->mic->klass.handle_reset(s->mic);
}
static void webcam_handle_control_eyetoy(USBDevice* dev, USBPacket* p, int request, int value, int index, int length, uint8_t* data)
static void webcam_handle_control_eyetoy(USBDevice* dev, USBPacket* p, int request, int value, int index, int length, u8* data)
{
EYETOYState* s = USB_CONTAINER_OF(dev, EYETOYState, dev);
int ret = 0;
@@ -172,9 +172,9 @@ namespace usb_eyetoy
case R518_I2C_CTL:
if (data[0] == 1) // Commit I2C write
{
//uint8_t reg = s->regs[s->regs[R51x_I2C_W_SID]];
uint8_t reg = s->regs[R51x_I2C_SADDR_3];
uint8_t val = s->regs[R51x_I2C_DATA];
//u8 reg = s->regs[s->regs[R51x_I2C_W_SID]];
const u8 reg = s->regs[R51x_I2C_SADDR_3];
const u8 val = s->regs[R51x_I2C_DATA];
if ((reg == 0x12) && (val & 0x80))
{
s->i2c_regs[0x12] = val & ~0x80; //or skip?
@@ -194,7 +194,7 @@ namespace usb_eyetoy
else if (s->regs[R518_I2C_CTL] == 0x03 && data[0] == 0x05)
{
//s->regs[s->regs[R51x_I2C_R_SID]] but seems to default to 0x43 (R51x_I2C_SADDR_2)
uint8_t i2c_reg = s->regs[R51x_I2C_SADDR_2];
const u8 i2c_reg = s->regs[R51x_I2C_SADDR_2];
s->regs[R51x_I2C_DATA] = 0;
if (i2c_reg < sizeof(s->i2c_regs))
@@ -218,7 +218,7 @@ namespace usb_eyetoy
}
}
static void webcam_handle_control_ov511p(USBDevice* dev, USBPacket* p, int request, int value, int index, int length, uint8_t* data)
static void webcam_handle_control_ov511p(USBDevice* dev, USBPacket* p, int request, int value, int index, int length, u8* data)
{
EYETOYState* s = USB_CONTAINER_OF(dev, EYETOYState, dev);
int ret = 0;
@@ -242,8 +242,8 @@ namespace usb_eyetoy
case R511_I2C_CTL:
if (data[0] == 1)
{
uint8_t reg = s->regs[R51x_I2C_SADDR_3];
uint8_t val = s->regs[R51x_I2C_DATA];
u8 reg = s->regs[R51x_I2C_SADDR_3];
const u8 val = s->regs[R51x_I2C_DATA];
if (reg < sizeof(s->i2c_regs))
{
s->i2c_regs[reg] = val;
@@ -251,7 +251,7 @@ namespace usb_eyetoy
}
else if (s->regs[R511_I2C_CTL] == 0x03 && data[0] == 0x05)
{
uint8_t i2c_reg = s->regs[R51x_I2C_SADDR_2];
const u8 i2c_reg = s->regs[R51x_I2C_SADDR_2];
s->regs[R51x_I2C_DATA] = 0;
if (i2c_reg < sizeof(s->i2c_regs))
@@ -277,8 +277,8 @@ namespace usb_eyetoy
static void webcam_handle_data_eyetoy(USBDevice* dev, USBPacket* p)
{
EYETOYState* s = USB_CONTAINER_OF(dev, EYETOYState, dev);
static const unsigned int max_ep_size = 896;
uint8_t devep = p->ep->nr;
static constexpr unsigned int max_ep_size = 896;
const u8 devep = p->ep->nr;
if (!s->hw_camera_running)
{
@@ -346,7 +346,7 @@ namespace usb_eyetoy
static void webcam_handle_data_ov511p(USBDevice* dev, USBPacket* p)
{
EYETOYState* s = USB_CONTAINER_OF(dev, EYETOYState, dev);
uint8_t devep = p->ep->nr;
const u8 devep = p->ep->nr;
if (!s->hw_camera_running)
{

View File

@@ -11,7 +11,7 @@
namespace usb_eyetoy
{
static const uint8_t eyetoy_dev_descriptor[] = {
static const u8 eyetoy_dev_descriptor[] = {
0x12, /* bLength */
0x01, /* bDescriptorType */
WBVAL(0x0110), /* bcdUSB */
@@ -28,7 +28,7 @@ namespace usb_eyetoy
0x01, /* bNumConfigurations */
};
static const uint8_t eyetoy_config_descriptor[] = {
static const u8 eyetoy_config_descriptor[] = {
0x09, // bLength
0x02, // bDescriptorType (Configuration)
0xB4, 0x00, // wTotalLength 180
@@ -215,7 +215,7 @@ namespace usb_eyetoy
0x00, 0x00, // wLockDelay 0
};
static const uint8_t ov511p_dev_descriptor[] = {
static const u8 ov511p_dev_descriptor[] = {
0x12, // bLength
0x01, // bDescriptorType (Device)
0x00, 0x01, // bcdUSB 1.00
@@ -232,7 +232,7 @@ namespace usb_eyetoy
0x01, // bNumConfigurations 1
};
static const uint8_t ov511p_config_descriptor[] = {
static const u8 ov511p_config_descriptor[] = {
0x09, // bLength
0x02, // bDescriptorType (Configuration)
0x89, 0x00, // wTotalLength 137
@@ -379,7 +379,7 @@ namespace usb_eyetoy
0x01, // bInterval 1 (unit depends on device speed)
};
static const uint8_t ov519_defaults[] = {
static const u8 ov519_defaults[] = {
0xc0, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x14, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00,
0x00, 0x08, 0x98, 0xff, 0x00, 0x03, 0x00, 0x00, 0x1e, 0x01, 0xf1, 0x00, 0x01, 0x00, 0x00, 0x00,
@@ -398,7 +398,7 @@ namespace usb_eyetoy
0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static const uint8_t ov7648_defaults[] = {
static const u8 ov7648_defaults[] = {
0x00, 0x84, 0x84, 0x84, 0x34, 0x3e, 0x80, 0x8c, 0x00, 0x00, 0x76, 0x48, 0x7b, 0x5b, 0x00, 0x98,
0x57, 0x00, 0x14, 0xa3, 0x04, 0x00, 0x00, 0x1a, 0xba, 0x03, 0xf3, 0x00, 0x7f, 0xa2, 0x00, 0x01,
0xc0, 0x80, 0x80, 0xde, 0x10, 0x8a, 0xa2, 0xe2, 0x20, 0x00, 0x00, 0x00, 0x88, 0x81, 0x00, 0x94,
@@ -417,7 +417,7 @@ namespace usb_eyetoy
0x75, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static const uint8_t ov511p_defaults[] = {
static const u8 ov511p_defaults[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x27, 0x1d, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x4f, 0x1d, 0x00, 0x01, 0x01, 0x04,
0x01, 0x01, 0x01, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -436,7 +436,7 @@ namespace usb_eyetoy
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static const uint8_t ov7620_defaults[] = {
static const u8 ov7620_defaults[] = {
0x00, 0x84, 0x84, 0x84, 0x34, 0x3e, 0x80, 0x8c, 0x00, 0x00, 0x76, 0x48, 0x7b, 0x5b, 0x00, 0x98,
0x57, 0x00, 0x14, 0xa3, 0x04, 0x00, 0x00, 0x1a, 0xba, 0x03, 0xf3, 0x00, 0x7f, 0xa2, 0x00, 0x01,
0xc0, 0x80, 0x80, 0xde, 0x10, 0x8a, 0xa2, 0xe2, 0x20, 0x00, 0x00, 0x00, 0x88, 0x81, 0x00, 0x94,

View File

@@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-3.0+
#include "Achievements.h"
#include "BuildVersion.h"
#include "CDVD/CDVD.h"
#include "CDVD/IsoReader.h"
#include "Counters.h"
@@ -40,7 +41,6 @@
#include "Vif_Dynarec.h"
#include "VMManager.h"
#include "ps2/BiosTools.h"
#include "svnrev.h"
#include "common/Console.h"
#include "common/Error.h"
@@ -2490,7 +2490,7 @@ void LogGPUCapabilities()
void VMManager::LogCPUCapabilities()
{
Console.WriteLn(Color_StrongGreen, "PCSX2 " GIT_REV);
Console.WriteLn(Color_StrongGreen, "PCSX2 %s", BuildVersion::GitRev);
Console.WriteLnFmt("Savestate version: 0x{:x}\n", g_SaveVersion);
Console.WriteLn();

View File

@@ -419,6 +419,7 @@
<ExcludedFromBuild Condition="'$(Platform)'!='x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="ps2\BiosTools.cpp" />
<ClCompile Include="BuildVersion.cpp" />
<ClCompile Include="Counters.cpp" />
<ClCompile Include="FiFo.cpp" />
<ClCompile Include="Hw.cpp" />
@@ -865,6 +866,7 @@
<ClInclude Include="Elfheader.h" />
<ClInclude Include="CDVD\IsoFileFormats.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="BuildVersion.h" />
<ClInclude Include="Common.h" />
<ClInclude Include="Config.h" />
<ClInclude Include="SaveState.h" />

View File

@@ -1292,6 +1292,9 @@
<ClCompile Include="Pcsx2Config.cpp">
<Filter>Misc</Filter>
</ClCompile>
<ClCompile Include="BuildVersion.cpp">
<Filter>Misc</Filter>
</ClCompile>
<ClCompile Include="Counters.cpp">
<Filter>System\Ps2\EmotionEngine\Hardware</Filter>
</ClCompile>
@@ -2244,6 +2247,9 @@
<ClInclude Include="ps2\pgif.h">
<Filter>System\Ps2\Iop</Filter>
</ClInclude>
<ClInclude Include="BuildVersion.h">
<Filter>Misc</Filter>
</ClInclude>
<ClInclude Include="Counters.h">
<Filter>System\Ps2\EmotionEngine\Hardware</Filter>
</ClInclude>