mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-01-31 01:15:24 +01:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9858aa1aa5 | ||
|
|
256a946f96 | ||
|
|
a507964f33 | ||
|
|
7584a6bb29 | ||
|
|
ce6103be30 | ||
|
|
9da4459ab3 | ||
|
|
3b9b9a84cd | ||
|
|
cce0ae4369 | ||
|
|
efb43ac7f9 | ||
|
|
8132a8a7f8 | ||
|
|
9c753cb692 | ||
|
|
514e6675c4 | ||
|
|
18454fd5d0 | ||
|
|
eeb919325e | ||
|
|
959be142ed | ||
|
|
42be91d48d | ||
|
|
908f916656 |
@@ -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": [
|
||||
|
||||
@@ -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",
|
||||
|
||||
14
3rdparty/ccc/src/ccc/elf.cpp
vendored
14
3rdparty/ccc/src/ccc/elf.cpp
vendored
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
20
3rdparty/ccc/src/ccc/elf.h
vendored
20
3rdparty/ccc/src/ccc/elf.h
vendored
@@ -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()));
|
||||
}
|
||||
|
||||
2
3rdparty/ccc/src/ccc/symbol_database.h
vendored
2
3rdparty/ccc/src/ccc/symbol_database.h
vendored
@@ -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; }
|
||||
|
||||
|
||||
6
3rdparty/ccc/src/ccc/symbol_table.cpp
vendored
6
3rdparty/ccc/src/ccc/symbol_table.cpp
vendored
@@ -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();
|
||||
|
||||
3
3rdparty/ccc/src/ccc/symbol_table.h
vendored
3
3rdparty/ccc/src/ccc/symbol_table.h
vendored
@@ -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);
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -287,3 +287,58 @@ int main() {
|
||||
set(HOST_CACHE_LINE_SIZE ${detect_cache_line_size_output} CACHE STRING "Reported host cache line size")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(get_recursive_include_directories output target inc_prop link_prop)
|
||||
get_target_property(dirs ${target} ${inc_prop})
|
||||
if(NOT dirs)
|
||||
set(dirs)
|
||||
endif()
|
||||
get_target_property(deps ${target} ${link_prop})
|
||||
if(deps)
|
||||
foreach(dep IN LISTS deps)
|
||||
if(TARGET ${dep})
|
||||
get_recursive_include_directories(depdirs ${dep} INTERFACE_INCLUDE_DIRECTORIES INTERFACE_LINK_LIBRARIES)
|
||||
foreach(depdir IN LISTS depdirs)
|
||||
# Only match absolute paths
|
||||
# We'll hope any non-absolute paths will not get set as system directories
|
||||
if(depdir MATCHES "^/")
|
||||
list(APPEND dirs ${depdir})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES dirs)
|
||||
endif()
|
||||
set(${output} "${dirs}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(force_include_last_impl target include inc_prop link_prop)
|
||||
get_recursive_include_directories(dirs ${target} ${inc_prop} ${link_prop})
|
||||
set(remove)
|
||||
foreach(dir IN LISTS dirs)
|
||||
if("${dir}" MATCHES "${include}")
|
||||
list(APPEND remove ${dir})
|
||||
endif()
|
||||
endforeach()
|
||||
if(NOT "${remove}" STREQUAL "")
|
||||
get_target_property(sysdirs ${target} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES)
|
||||
if(NOT sysdirs)
|
||||
set(sysdirs)
|
||||
endif()
|
||||
# Move matching items to the end
|
||||
list(REMOVE_ITEM dirs ${remove})
|
||||
list(APPEND dirs ${remove})
|
||||
# Set them as system include directories
|
||||
list(APPEND sysdirs ${remove})
|
||||
list(REMOVE_DUPLICATES sysdirs)
|
||||
set_target_properties(${target} PROPERTIES
|
||||
${inc_prop} "${dirs}"
|
||||
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${sysdirs}"
|
||||
)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(force_include_last target include)
|
||||
force_include_last_impl(${target} "${include}" INTERFACE_INCLUDE_DIRECTORIES INTERFACE_LINK_LIBRARIES)
|
||||
force_include_last_impl(${target} "${include}" INCLUDE_DIRECTORIES LINK_LIBRARIES)
|
||||
endfunction()
|
||||
|
||||
@@ -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')
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
16
pcsx2/BuildVersion.cpp
Normal 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
18
pcsx2/BuildVersion.h
Normal 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
|
||||
@@ -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
|
||||
@@ -1225,6 +1227,10 @@ if (NOT APPLE)
|
||||
endif()
|
||||
|
||||
fixup_file_properties(PCSX2)
|
||||
# Directories like /usr/local/include, /opt/local/include, etc tend to include lots of headers from lots of libraries.
|
||||
# Possibly including libraries that we compiled versions of with the dependency build script.
|
||||
# To ensure the dependency build script's headers are preferred, push any directories that look like */local/include to the end.
|
||||
force_include_last(PCSX2_FLAGS "/(usr|local)/include/?$")
|
||||
|
||||
if (APPLE)
|
||||
find_library(METAL_LIBRARY Metal)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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 = {};
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user