Compare commits

...
61 Commits
Author SHA1 Message Date
Gd7andGitHub b95eb5cd74 GameDB: Final Fantasy X Optimal FPU config. (#11958)
Fixes the vast majority of FFX's FPU glitches as well as fixing a major cutscene bug without breaking anything more than what the current config already breaks.

EE clamping fixes reverse controls and characters and enemies facing the wrong way during battles, everything else is affected by EE rounding and EE division rounding.

VU0 clamping affects nothing.
2024-11-04 12:40:16 +01:00
KamFretoZandlightningterror b865bbb0d3 CI: Add ci skip to base translation update workflow 2024-11-04 12:39:04 +01:00
KamFretoZandlightningterror ca6e1c9a46 Qt: Cleanup Unused InputRec Menu 2024-11-04 12:39:04 +01:00
KamFretoZandlightningterror ea8a2deae6 Qt: Icon Tweaks 2024-11-04 12:39:04 +01:00
KamFretoZandlightningterror c67237672c Qt/Savestate: Add option to disable savestate selector UI 2024-11-04 12:39:04 +01:00
Ty Lamontagne 2d5faa627f CI: Default to flatpak beta branch 2024-10-31 09:22:11 -04:00
Tyler WildingandGitHub 1562ba4ca0 translations: Syncing Crowdin translations (#11970) 2024-10-31 09:21:06 -04:00
Ty Lamontagne a5d94ac454 Patches: Fix a regression that broke gamedb dynpatches 2024-10-30 17:07:07 -04:00
Ty Lamontagne 943fbd8719 Dis5900asm: Fix an out of bounds access on invalid pmfhl formats 2024-10-30 09:15:17 -04:00
Ty Lamontagne eea1d57e7e PAD: Fix negon and jogcon BPM crash 2024-10-29 18:52:44 -04:00
PCSX2 Botandlightningterror 74645aa1b7 PAD: Update to latest controller database. 2024-10-28 17:56:47 +01:00
PCSX2 BotandTy dfd23d9a25 Qt: Update Base Translation 2024-10-27 20:07:36 -04:00
KamFretoZandTy 27cf16a09c CI: Fix Translation Workflow Scripts Order of Operation
[ci skip]
2024-10-27 10:20:02 -04:00
PCSX2 BotandTy 0dee9e3ff1 Qt: Update Base Translation 2024-10-26 21:06:14 -04:00
KamFretoZandTy 9b47dc0ee3 OSD: Fix Input Overlay Clipping 2024-10-26 11:20:49 -04:00
KamFretoZandTy c7b9ee92b7 Qt: Properly Grey Out Checkboxes When Perf OSD is Disabled 2024-10-26 11:20:49 -04:00
KamFretoZandTy ac32e6ca92 FSUI: Fix and Tweak BPM Buttons and Legends 2024-10-26 11:20:49 -04:00
TheLastRarandTy 0c204c3ebb Qt: Hackfix settings icon stretching on Windows themes 2024-10-24 12:23:36 -04:00
PCSX2 BotandTy 016b871734 Qt: Update Base Translation 2024-10-23 20:04:03 -04:00
lightningterrorandTy 22413b8e7f GS/OGL: Only paste all available extensions in dev/debug build. 2024-10-23 10:11:06 -04:00
lightningterrorandTy 1b50057764 GS/Qt: Adjust how we handle Default adapter.
Try to resolve it again since it annoys me.

Treat is as empty.

Also do NOT translate Default adapter,
it messes with the ini config.
2024-10-23 10:11:06 -04:00
lightningterrorandTy 9e15058634 GS/D3D12: Disable DX12 if feature level is not detected.
Intel Haswell doesn't actually support DX12 even tho the device is created which results in a crash,
to get around this check if device can be created using feature level 12 (skylake+).
2024-10-23 10:11:06 -04:00
lightningterrorandTy 2a81a7af9e GS: Check feature level 12 as a requirement when selecting auto renderer on intel.
Just to be on the safe side when selecting OpenGL.
2024-10-23 10:11:06 -04:00
chaoticgdandTy 6d3d5ebdc5 Qt: Fix symbol sources list in per-game settings dialog 2024-10-23 09:58:59 -04:00
chaoticgdandTy 7d63a9e51c Debugger: Avoid resetting symbol trees while single stepping 2024-10-23 09:58:02 -04:00
JordanTheToasterandTy 56a2b3b5ad VMManager: Add renderer selection warning 2024-10-23 09:55:36 -04:00
badfontkemingandTy f46f788d80 USB: Fix FFB quality and dropouts for most wheels, make workaround optional
The original workaround for FFB issues simply restarted the constant force
each time it was updated. Turns out that a lot of wheels don't behave
perfectly during this. A better fix was found, which is to set the effect
duration to infinite. However, some wheels are so bugged that they don't even
respect THAT, so the workaround needs to stick around in some capacity.
2024-10-23 08:40:47 -04:00
TheLastRarandGitHub a044b7cf6e DEV9: Set/Clear SEEK bit in all relevent commands (#11931)
* DEV9: Set SEEK on all successful seeks

* DEV9: Complete HDD_Flush immediately when write queue is empty

Also set SEEK when write queue isn't empty

* DEV9: Lock reported value of SEEK when errored
2024-10-23 08:36:16 -04:00
Rares-Alexandru FodorandTy 8afd29e1a2 Qt: Add search bar for cheats 2024-10-23 08:34:47 -04:00
Rares-Alexandru FodorandTy d89b051e6d Qt: Replace QTreeWidget with QTreeView for cheat list 2024-10-23 08:34:47 -04:00
Ty Lamontagne 47cf69d2b3 TraceLogging: Fix SIF trace logging 2024-10-23 08:30:37 -04:00
PCSX2 BotandTy 35c3c912e7 PAD: Update to latest controller database. 2024-10-21 12:02:59 -04:00
ZiemasandTy 67c5f0229b EE: vtlb handler for writes to IOP mem 2024-10-21 11:14:29 -04:00
5dcc79555d Qt: Update Base Translation (#11932)
Co-authored-by: PCSX2 Bot <PCSX2Bot@users.noreply.github.com>
2024-10-20 20:04:11 -04:00
TheLastRarandGitHub 82f741e1dc DEV9: Add ATA commands used by PS2 Linux (#11925) 2024-10-19 20:05:34 -04:00
Ty Lamontagne ab21d22514 Misc: wire up and refactor trace logging 2024-10-19 20:04:02 -04:00
PCSX2 BotandTy 0a599e7337 Qt: Update Base Translation 2024-10-18 20:26:49 -04:00
chaoticgdandTy f77bf1ec6b Debugger: Be smarter about deciding when functions should be hashed 2024-10-18 13:57:05 -04:00
chaoticgdandTy ed4fbb4f5a Debugger: Hash functions scanned in by the MIPS analyst 2024-10-18 13:57:05 -04:00
chaoticgdandTy f963291970 Debugger: Cache hash match results on symbol tree nodes 2024-10-18 13:57:05 -04:00
chaoticgdandTy 2c3abe33d5 Debugger: Add settings to control the analysis passes 2024-10-18 13:57:05 -04:00
chaoticgdandTy 0fd7e1d7c2 Debugger: Split out SymbolImporter into its own class 2024-10-18 13:57:05 -04:00
TheLastRarandTy 1e23e7efc4 DEV9: Add note regarding IF_CTRL bit 3 2024-10-17 16:10:38 -04:00
TheLastRarandTy 46d5d24fcd DEV9: Correct SPD_XFR_DMAEN define 2024-10-17 16:10:38 -04:00
TheLastRarandTy 3276c0db9c DEV9: Correct implementation of SPD_R_DBUF_STAT reset 2024-10-17 16:10:38 -04:00
TheLastRarandTy 1bdd53a6c5 DEV9: Don't fake the FIFO 2024-10-17 16:10:38 -04:00
TheLastRarandTy 1f2d9ab4e5 IOP: Seperate completing DMA8 to a seperate function 2024-10-17 16:10:38 -04:00
TheLastRarandTy 0806ca442a DEV9: Use ReceivedPayload more in TCP_Session
Instead of shuffling a unique_ptr around
Fixes handling of connection failure in ConnectTCPComplete()
2024-10-15 08:51:09 -04:00
TheLastRarandTy e3a666bfe4 DEV9: Move adapter detection hack 2024-10-15 08:37:21 -04:00
TheLastRarandTy 6b2dc7a68c DEV9: Move call to network backend reset
SMAP_R_EMAC3_TxMODE1_L is unrelated to resetting the adapter
2024-10-15 08:37:21 -04:00
PCSX2 Botandlightningterror 18c492d9da Qt: Update Base Translation 2024-10-15 12:28:13 +02:00
TheLastRarandlightningterror 6065caaf19 DEV9: Allow writes to ATA_R_CONTROL while busy 2024-10-15 12:22:03 +02:00
TheLastRarandlightningterror bb4c456f35 DEV9: Disable interrupts on reset 2024-10-15 12:22:03 +02:00
TheLastRarandlightningterror 078a10dcdb DEV9: Implement ATA pending interrupts 2024-10-15 12:22:03 +02:00
TheLastRarandlightningterror a8a0c5c0bf DEV9: Rewrite suppression of diagnostics IRQ during reset 2024-10-15 12:22:03 +02:00
TheLastRarandlightningterror 1a95bd3088 DEV9: Support 8bit reads/writes for most ATA regs 2024-10-15 12:22:03 +02:00
PCSX2 Botandlightningterror cf157fd2d7 PAD: Update to latest controller database. 2024-10-14 18:12:02 +02:00
ZiemasandTy 35ada362d4 IOP/EE: Add SBUS interrupts
Lets the CPUs trigger an interrupt on the other.
2024-10-14 09:15:42 -04:00
KamFretoZandlightningterror 444b110411 GSDevice11: Don't try to get the adapter name twice 2024-10-14 14:42:01 +02:00
KamFretoZandlightningterror 1b82fac70e OSD: Clarify Min/Avg/Max label to Frametime counter 2024-10-14 14:42:01 +02:00
badfontkemingandTy dafca1e264 USB: Work around FFB dropouts with modern wheels
Certain modern direct-drive wheels such as the Moza R5, R9, etc. implement
timeouts for FFB constant forces, and expect the forces to be re-run
rather than updated in order to refresh these timeouts.
2024-10-13 17:58:52 -04:00
161 changed files with 103689 additions and 63099 deletions
+1 -1
View File
@@ -43,7 +43,7 @@ jobs:
compiler: clang
cmakeflags: ""
publish: true
branch: stable
fetchTags: true
stableBuild: false
secrets: inherit
@@ -20,7 +20,7 @@ jobs:
uses: peter-evans/create-pull-request@v7
with:
title: "Qt: Update Base Translation"
commit-message: "Qt: Update Base Translation"
commit-message: "[ci skip]"
committer: "PCSX2 Bot <PCSX2Bot@users.noreply.github.com>"
author: "PCSX2 Bot <PCSX2Bot@users.noreply.github.com>"
body: "Daily update of base translation sources."
+23 -10
View File
@@ -23,10 +23,6 @@ on:
cmakeflags:
required: true
type: string
branch:
required: false
type: string
default: "stable"
publish:
required: false
type: boolean
@@ -98,7 +94,8 @@ jobs:
run: |
flatpak-builder-lint manifest .github/workflows/scripts/linux/flatpak/net.pcsx2.PCSX2.json
- name: Build Flatpak
- name: Build Flatpak (beta)
if: ${{ inputs.stableBuild == false || inputs.stableBuild == 'false' }}
uses: flathub-infra/flatpak-github-actions/flatpak-builder@23796715b3dfa4c86ddf50cf29c3cc8b3c82dca8
with:
bundle: ${{ steps.artifact-metadata.outputs.artifact-name }}.flatpak
@@ -108,17 +105,33 @@ jobs:
build-bundle: true
verbose: true
mirror-screenshots-url: https://dl.flathub.org/media
branch: ${{ inputs.branch }}
branch: beta
cache: true
restore-cache: true
cache-key: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.compiler }} flatpak ${{ hashFiles('.github/workflows/scripts/linux/flatpak/**/*.json') }}
- name: Build Flatpak (stable)
if: ${{ inputs.stableBuild == true || inputs.stableBuild == 'true' }}
uses: flathub-infra/flatpak-github-actions/flatpak-builder@23796715b3dfa4c86ddf50cf29c3cc8b3c82dca8
with:
bundle: ${{ steps.artifact-metadata.outputs.artifact-name }}.flatpak
upload-artifact: false
manifest-path: .github/workflows/scripts/linux/flatpak/net.pcsx2.PCSX2.json
arch: x86_64
build-bundle: true
verbose: true
mirror-screenshots-url: https://dl.flathub.org/media
branch: stable
cache: true
restore-cache: true
cache-key: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.compiler }} flatpak ${{ hashFiles('.github/workflows/scripts/linux/flatpak/**/*.json') }}
#- name: Validate build
# run: |
# flatpak-builder-lint repo repo
- name: Push to Flathub beta
if: inputs.publish == true && inputs.branch == 'beta'
- name: Push to Flathub (beta)
if: ${{ inputs.publish == true && (inputs.stableBuild == false || inputs.stableBuild == 'false') }}
uses: flathub-infra/flatpak-github-actions/flat-manager@23796715b3dfa4c86ddf50cf29c3cc8b3c82dca8
with:
flat-manager-url: https://hub.flathub.org/
@@ -126,8 +139,8 @@ jobs:
token: ${{ secrets.FLATHUB_BETA_TOKEN }}
build-log-url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
- name: Push to Flathub stable
if: inputs.publish == true && inputs.branch == 'stable'
- name: Push to Flathub (stable)
if: ${{ inputs.publish == true && (inputs.stableBuild == true || inputs.stableBuild == 'true') }}
uses: flathub-infra/flatpak-github-actions/flat-manager@23796715b3dfa4c86ddf50cf29c3cc8b3c82dca8
with:
flat-manager-url: https://hub.flathub.org/
-1
View File
@@ -114,7 +114,6 @@ jobs:
artifactPrefixName: "PCSX2-linux-Qt-x64-flatpak"
compiler: clang
cmakeflags: ""
branch: "stable"
publish: false
fetchTags: true
stableBuild: ${{ github.event_name == 'workflow_dispatch' && inputs.is_prelease == 'false' }}
@@ -6,9 +6,9 @@ set -e
# While we use custom Qt builds for our releases, the Qt6 package will be good enough
# for just updating translations. Saves building it for this action alone.
"$SCRIPTDIR/../../../../tools/retry.sh" sudo apt-get -y install qt6-l10n-tools python3
"$SCRIPTDIR/../../../../tools/retry.sh" sudo apt-get -y install qt6-l10n-tools python3
"$SCRIPTDIR/../../../../tools/generate_fullscreen_ui_translation_strings.py"
"$SCRIPTDIR/../../../../pcsx2-qt/Translations/update_glyph_ranges.py"
"$SCRIPTDIR/../../../../tools/generate_update_fa_glyph_ranges.py"
PATH=/usr/lib/qt6/bin:$PATH "$SCRIPTDIR/../../../../pcsx2-qt/Translations/update_base_translation.sh"
PATH=/usr/bin/python3:$PATH "$SCRIPTDIR/../../../../pcsx2-qt/Translations/update_glyph_ranges.py"
PATH=/usr/bin/python3:$PATH "$SCRIPTDIR/../../../../tools/generate_fullscreen_ui_translation_strings.py"
PATH=/usr/bin/python3:$PATH "$SCRIPTDIR/../../../../tools/generate_update_fa_glyph_ranges.py"
@@ -195,6 +195,9 @@ cd "qtbase-everywhere-src-%QT%" || goto error
rem Disable the PCRE2 JIT, it doesn't properly verify AVX2 support.
%PATCH% -p1 < "%SCRIPTDIR%\qtbase-disable-pcre2-jit.patch" || goto error
rem Hackfix settings icon stretching
%PATCH% -p1 < "%SCRIPTDIR%\qtbase-fix-icon-stretch.patch" || goto error
cmake -B build -DFEATURE_sql=OFF -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" %FORCEPDB% -DINPUT_gui=yes -DINPUT_widgets=yes -DINPUT_ssl=yes -DINPUT_openssl=no -DINPUT_schannel=yes -DFEATURE_system_png=ON -DFEATURE_system_jpeg=ON -DFEATURE_system_zlib=ON -DFEATURE_system_freetype=ON -DFEATURE_system_harfbuzz=ON %QTBUILDSPEC% || goto error
cmake --build build --parallel || goto error
ninja -C build install || goto error
@@ -0,0 +1,13 @@
diff --git a/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp b/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp
index 208420d7e8..26ef6f31ef 100644
--- a/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp
+++ b/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp
@@ -4232,8 +4232,6 @@ QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption
case SE_ItemViewItemDecoration:
rect = QWindowsStyle::subElementRect(element, option, widget);
- if (qstyleoption_cast<const QStyleOptionViewItem *>(option))
- rect.adjust(-2, 0, 2, 0);
break;
case SE_ItemViewItemFocusRect:
+1 -1
View File
@@ -753,7 +753,7 @@ void SourceFile::check_functions_match(const SymbolDatabase& database)
u32 modified = 0;
for(FunctionHandle function_handle : functions()) {
const ccc::Function* function = database.functions.symbol_from_handle(function_handle);
if(!function || function->original_hash() == 0) {
if(!function || function->current_hash() == 0 || function->original_hash() == 0) {
continue;
}
+21 -21
View File
@@ -2615,7 +2615,7 @@ SCED-50642:
gameFixes:
- SoftwareRendererFMVHack # Fixes interlacing.
roundModes:
eeRoundMode: 1 # Fixes reverse control and boss in some places.
eeRoundMode: 2 # Fixes reverse control and boss in some places.
clampModes:
eeClampMode: 3 # Fixes animations.
gsHWFixes:
@@ -2742,7 +2742,7 @@ SCED-50907:
gameFixes:
- SoftwareRendererFMVHack # Fixes interlacing.
roundModes:
eeRoundMode: 1 # Fixes reverse control and boss in some places.
eeRoundMode: 2 # Fixes reverse control and boss in some places.
clampModes:
eeClampMode: 3 # Fixes animations.
gsHWFixes:
@@ -4451,7 +4451,7 @@ SCES-50490:
gameFixes:
- SoftwareRendererFMVHack # Fixes interlacing.
roundModes:
eeRoundMode: 1 # Fixes reverse control and boss in some places.
eeRoundMode: 2 # Fixes reverse control and boss in some places.
clampModes:
eeClampMode: 3 # Fixes animations.
gsHWFixes:
@@ -4463,7 +4463,7 @@ SCES-50491:
gameFixes:
- SoftwareRendererFMVHack # Fixes interlacing.
roundModes:
eeRoundMode: 1 # Fixes reverse control and boss in some places.
eeRoundMode: 2 # Fixes reverse control and boss in some places.
clampModes:
eeClampMode: 3 # Fixes animations.
gsHWFixes:
@@ -4476,7 +4476,7 @@ SCES-50492:
gameFixes:
- SoftwareRendererFMVHack # Fixes interlacing.
roundModes:
eeRoundMode: 1 # Fixes reverse control and boss in some places.
eeRoundMode: 2 # Fixes reverse control and boss in some places.
clampModes:
eeClampMode: 3 # Fixes animations.
gsHWFixes:
@@ -4488,7 +4488,7 @@ SCES-50493:
gameFixes:
- SoftwareRendererFMVHack # Fixes interlacing.
roundModes:
eeRoundMode: 1 # Fixes reverse control and boss in some places.
eeRoundMode: 2 # Fixes reverse control and boss in some places.
clampModes:
eeClampMode: 3 # Fixes animations.
gsHWFixes:
@@ -4500,7 +4500,7 @@ SCES-50494:
gameFixes:
- SoftwareRendererFMVHack # Fixes interlacing.
roundModes:
eeRoundMode: 1 # Fixes reverse control and boss in some places.
eeRoundMode: 2 # Fixes reverse control and boss in some places.
clampModes:
eeClampMode: 3 # Fixes animations.
gsHWFixes:
@@ -29780,12 +29780,12 @@ SLKA-25214:
name: "Final Fantasy X - International [PlayStation 2 - Big Hit Series]"
region: "NTSC-K"
roundModes:
eeRoundMode: 1 # Fixes reverse control and boss in some places.
eeRoundMode: 2 # Fixes reverse control and boss in some places.
clampModes:
eeClampMode: 3 # Fixes animations.
vu0ClampMode: 3 # Fixes character flickering caused by EE clamp full.
gsHWFixes:
roundSprite: 2 # Fixes font artifacts.
autoFlush: 1 # Fixes blur effect on attacks.
SLKA-25215:
name: "Shining Wind"
region: "NTSC-K"
@@ -37641,12 +37641,12 @@ SLPM-65115:
name-en: "Final Fantasy X International"
region: "NTSC-J"
roundModes:
eeRoundMode: 1 # Fixes reverse control and boss in some places.
eeRoundMode: 2 # Fixes reverse control and boss in some places.
clampModes:
eeClampMode: 3 # Fixes animations.
vu0ClampMode: 3 # Fixes character flickering caused by EE clamp full.
gsHWFixes:
roundSprite: 2 # Fixes font artifacts.
autoFlush: 1 # Fixes blur effect on attacks.
SLPM-65116:
name: "リリーのアトリエ プラス 〜ザールブルグの錬金術士3〜"
name-sort: "りりーのあとりえ ぷらす 〜ざーるぶるぐのれんきんじゅつし3〜"
@@ -43332,7 +43332,7 @@ SLPM-66124:
gameFixes:
- SoftwareRendererFMVHack # Fixes interlacing.
roundModes:
eeRoundMode: 1 # Fixes reverse control and boss in some places.
eeRoundMode: 2 # Fixes reverse control and boss in some places.
clampModes:
eeClampMode: 3 # Fixes animations.
gsHWFixes:
@@ -46745,12 +46745,12 @@ SLPM-66677:
name-en: "Final Fantasy X - International [Ultimate Hits]"
region: "NTSC-J"
roundModes:
eeRoundMode: 1 # Fixes reverse control and boss in some places.
eeRoundMode: 2 # Fixes reverse control and boss in some places.
clampModes:
eeClampMode: 3 # Fixes animations.
vu0ClampMode: 3 # Fixes character flickering caused by EE clamp full.
gsHWFixes:
roundSprite: 2 # Fixes font artifacts.
autoFlush: 1 # Fixes blur effect on attacks.
SLPM-66678:
name: "ファイナルファンタジーX-2 インターナショナル+ラストミッション [アルティメットヒッツ]"
name-sort: "ふぁいなるふぁんたじー10-2 いんたーなしょなる+らすとみっしょん [あるてぃめっとひっつ]"
@@ -48710,12 +48710,12 @@ SLPM-67513:
name: "Final Fantasy X International"
region: "NTSC-K"
roundModes:
eeRoundMode: 1 # Fixes reverse control and boss in some places.
eeRoundMode: 2 # Fixes reverse control and boss in some places.
clampModes:
eeClampMode: 3 # Fixes animations.
vu0ClampMode: 3 # Fixes character flickering caused by EE clamp full.
gsHWFixes:
roundSprite: 2 # Fixes font artifacts.
autoFlush: 1 # Fixes blur effect on attacks.
SLPM-67514:
name: "Kessen"
region: "NTSC-K"
@@ -52241,7 +52241,7 @@ SLPS-25050:
gameFixes:
- SoftwareRendererFMVHack # Fixes interlacing.
roundModes:
eeRoundMode: 1 # Fixes reverse control and boss in some places.
eeRoundMode: 2 # Fixes reverse control and boss in some places.
clampModes:
eeClampMode: 3 # Fixes animations.
gsHWFixes:
@@ -52448,12 +52448,12 @@ SLPS-25088:
region: "NTSC-J"
compat: 5
roundModes:
eeRoundMode: 1 # Fixes reverse control and boss in some places.
eeRoundMode: 2 # Fixes reverse control and boss in some places.
clampModes:
eeClampMode: 3 # Fixes animations.
vu0ClampMode: 3 # Fixes character flickering caused by EE clamp full.
gsHWFixes:
roundSprite: 2 # Fixes font artifacts.
autoFlush: 1 # Fixes blur effect on attacks.
SLPS-25089:
name: "Salt Lake 2002"
region: "NTSC-J"
@@ -57535,7 +57535,7 @@ SLPS-72501:
gameFixes:
- SoftwareRendererFMVHack # Fixes interlacing.
roundModes:
eeRoundMode: 1 # Fixes reverse control and boss in some places.
eeRoundMode: 2 # Fixes reverse control and boss in some places.
clampModes:
eeClampMode: 3 # Fixes animations.
gsHWFixes:
@@ -59686,7 +59686,7 @@ SLUS-20312:
gameFixes:
- SoftwareRendererFMVHack # Fixes interlacing.
roundModes:
eeRoundMode: 1 # Fixes reverse control and boss in some places.
eeRoundMode: 2 # Fixes reverse control and boss in some places.
clampModes:
eeClampMode: 3 # Fixes animations.
gsHWFixes:
+11 -2
View File
@@ -323,6 +323,7 @@
030000000d0f0000c100000000000000,Horipad 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,
030000000d0f0000f600000000000000,Horipad Nintendo Switch Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
030000000d0f00006700000000000000,Horipad One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
030000000d0f00009601000000000000,Horipad Steam,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,misc1:b2,paddle1:b15,paddle2:b5,paddle3:b19,paddle4:b18,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
030000000d0f0000dc00000000000000,Horipad Switch,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000242e00000b20000000000000,Hyperkin Admiral N64 Controller,+rightx:b11,+righty:b13,-rightx:b8,-righty:b12,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,platform:Windows,
03000000242e0000ff0b000000000000,Hyperkin N64 Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,platform:Windows,
@@ -748,6 +749,7 @@
03000000bd12000012d0000000000000,USB Controller,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,
03000000ff1100004133000000000000,USB Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
03000000632500002305000000000000,USB Vibration Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000882800000305000000000000,V5 Game Pad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,x:b2,y:b3,platform:Windows,
03000000790000001a18000000000000,Venom,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,
03000000790000001b18000000000000,Venom Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
030000006f0e00000302000000000000,Victrix PS4 Pro Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
@@ -812,7 +814,6 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000790000004f18000000000000,ZDT Android 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,
03000000120c00000500000000000000,Zeroplus Adapter,a:b2,b:b1,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b0,righttrigger:b5,rightx:a3,righty:a2,start:b8,x:b3,y:b0,platform:Windows,
03000000120c0000101e000000000000,Zeroplus P4 Gamepad,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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000882800000305000000000000,V5 GAME PAD,a:b0,b:b1,x:b2,y:b3,guide:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows
# Mac OS X
030000008f0e00000300000009010000,2 In 1 Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
@@ -1103,14 +1104,15 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000005e040000130b000015050000,Xbox Series 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:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
030000005e040000130b000007050000,Xbox 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:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
030000005e040000130b000017050000,Xbox 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:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
030000005e040000130b000022050000,Xbox 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:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
030000005e040000220b000017050000,Xbox 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:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
030000005e040000130b000022050000,Xbox Wireless Controller,a:b0,b:b1,x:b3,y:b4,back:b10,guide:b12,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4,platform:Mac OS X,
03000000172700004431000029010000,XiaoMi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000120c0000100e000000010000,Zeroplus P4,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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000120c0000101e000000010000,Zeroplus P4,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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
# Linux
03000000c82d00000031000011010000,8BitDo Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000c82d00000631000000010000,8BitDo Adapter 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000c82d00000951000000010000,8BitDo Dogbone,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Linux,
03000000021000000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
@@ -1239,6 +1241,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000000b0400003365000000010000,Competition Pro,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Linux,
03000000260900008888000000010000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Linux,
03000000a306000022f6000011010000,Cyborg V3 Rumble,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:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
030000005e0400008e02000002010000,Data Frog S80,a:b1,b:b0,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux,
03000000791d00000103000010010000,Dual Box Wii Classic Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
030000006f0e00003001000001010000,EA Sports PS3 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,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000c11100000191000011010000,EasySMX,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
@@ -1420,10 +1423,13 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
05000000c62400001a89000000010000,MOGA XP5X Plus,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:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000250900006688000000010000,MP8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,
030000005e0400008e02000010020000,MSI GC20 V2,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000f70600000100000000010000,N64 Adaptoid,+rightx:b2,+righty:b1,-rightx:b4,-righty:b5,a:b0,b:b3,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,platform:Linux,
030000006f0e00001311000011010000,N64 Controller,+rightx:b10,+righty:b3,-rightx:b0,-righty:b11,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,platform:Linux,
030000006b1400000906000014010000,Nacon Asymmetric Wireless PS4 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006b140000010c000010010000,Nacon GC 400ES,a:b0,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:b2,y:b3,platform:Linux,
03000000853200000706000012010000,Nacon GC-100,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
0300000085320000170d000011010000,Nacon Revolution 5 Pro,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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
0300000085320000190d000011010000,Nacon Revolution 5 Pro,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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
030000000d0f00000900000010010000,Natec Genesis P44,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:Linux,
030000004f1f00000800000011010000,NeoGeo PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
0300000092120000474e000000010000,NeoGeo X Arcade Stick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b3,y:b2,platform:Linux,
@@ -1570,6 +1576,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
050000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
0300000032150000030a000001010000,Razer Wildcat,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000321500000b10000011010000,Razer Wolverine PS5 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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
030000000d0f0000c100000010010000,Retro Bit Legacy16,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b12,leftshoulder:b4,lefttrigger:b6,misc1:b13,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f0000c100000072056800,Retro Bit Legacy16,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b5,leftshoulder:b9,lefttrigger:+a4,misc1:b11,rightshoulder:b10,righttrigger:+a5,start:b6,x:b3,y:b2,platform:Linux,
03000000790000001100000010010000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Linux,
0300000003040000c197000011010000,Retrode Adapter,a:b0,b:b4,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux,
190000004b4800000111000000010000,RetroGame Joypad,a:b1,b:b0,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
@@ -1713,6 +1721,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000005e040000ea02000011050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
060000005e040000ea0200000b050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
060000005e040000ea0200000d050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
060000005e040000ea02000016050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000120b000001050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000120b000005050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000120b000007050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-1
View File
@@ -77,7 +77,6 @@ target_sources(common PRIVATE
Timer.h
TextureDecompress.h
Threading.h
TraceLog.h
VectorIntrin.h
WAVWriter.h
WindowInfo.h
+1
View File
@@ -364,6 +364,7 @@ bool Log::SetFileOutputLevel(LOGLEVEL level, std::string path)
}
s_file_level = s_file_handle ? level : LOGLEVEL_NONE;
UpdateMaxLevel();
return IsFileOutputEnabled();
}
-197
View File
@@ -1,197 +0,0 @@
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
#pragma once
#include "common/Assertions.h"
#include "common/Console.h"
#include "common/StringUtil.h"
// --------------------------------------------------------------------------------------
// TraceLogDescriptor
// --------------------------------------------------------------------------------------
// Provides textual information for use by UIs; to give the end user a selection screen for
// enabling/disabling logs, and also for saving the log settings to INI.
//
struct TraceLogDescriptor
{
// short name, alphanumerics only: used for saving/loading options.
const char* ShortName;
// Standard UI name for this log source. Used in menus, options dialogs.
const char* Name;
// Length description for use as a tooltip or menu item description.
const char* Description;
const char* GetShortName() const
{
pxAssumeMsg(Name, "Tracelog descriptors require a valid name!");
return ShortName ? ShortName : Name;
}
};
// --------------------------------------------------------------------------------------
// BaseTraceLogSource
// --------------------------------------------------------------------------------------
// This class houses the base attributes for any trace log (to file or to console), which
// only includes the logfile's name, description, and enabled bit (for UIs and ini files),
// and an IsActive() method for determining if the log should be written or not.
//
// Derived classes then provide their own Write/DoWrite functions that format and write
// the log to the intended target(s).
//
// All individual calls to log write functions should be responsible for checking the
// status of the log via the IsActive() method manually (typically done via macro). This
// is done in favor of internal checks because most logs include detailed/formatted
// information, which itself can take a lot of cpu power to prepare. If the IsActive()
// check is done top-level, the parameters' calculations can be skipped. If the IsActive()
// check is done internally as part of the Write/Format calls, all parameters have to be
// resolved regardless of if the log is actually active.
//
class BaseTraceLogSource
{
protected:
const TraceLogDescriptor* m_Descriptor;
public:
// Indicates if the user has enabled this specific log. This boolean only represents
// the configured status of this log, and does *NOT* actually mean the log is active
// even when TRUE. Because many tracelogs have master enablers that act on a group
// of logs, logging checks should always use IsActive() instead to determine if a log
// should be processed or not.
bool Enabled;
protected:
BaseTraceLogSource()
: m_Descriptor(NULL)
, Enabled(false)
{
}
public:
BaseTraceLogSource(const TraceLogDescriptor* desc)
{
pxAssumeMsg(desc, "Trace logs must have a valid (non-NULL) descriptor.");
Enabled = false;
m_Descriptor = desc;
}
// Provides a categorical identifier, typically in "group.subgroup.subgroup" form.
// (use periods in favor of colons, since they do not require escape characters when
// written to ini/config files).
virtual std::string GetCategory() const { return std::string(); }
// This method should be used to determine if a log should be generated or not.
// See the class overview comments for details on how and why this method should
// be used.
virtual bool IsActive() const { return Enabled; }
virtual const char* GetShortName() const { return m_Descriptor->GetShortName(); }
virtual const char* GetName() const { return m_Descriptor->Name; }
virtual const char* GetDescription() const
{
return (m_Descriptor->Description != NULL) ? m_Descriptor->Description : "";
}
virtual bool HasDescription() const { return m_Descriptor->Description != NULL; }
};
// --------------------------------------------------------------------------------------
// TextFileTraceLog
// --------------------------------------------------------------------------------------
// This class is tailored for performance logging to file. It does not support console
// colors or wide/unicode text conversion.
//
class TextFileTraceLog : public BaseTraceLogSource
{
public:
TextFileTraceLog(const TraceLogDescriptor* desc)
: BaseTraceLogSource(desc)
{
}
bool Write(const char* fmt, ...) const
{
va_list list;
va_start(list, fmt);
WriteV(fmt, list);
va_end(list);
return false;
}
bool WriteV(const char* fmt, va_list list) const
{
std::string ascii;
ApplyPrefix(ascii);
ascii += StringUtil::StdStringFromFormatV(fmt, list);
DoWrite(ascii.c_str());
return false;
}
virtual void ApplyPrefix(std::string& ascii) const {}
virtual void DoWrite(const char* fmt) const = 0;
};
// --------------------------------------------------------------------------------------
// ConsoleLogSource
// --------------------------------------------------------------------------------------
// This class is tailored for logging to console. It applies default console color attributes
// to all writes, and supports both char and wxChar (Ascii and UF8/16) formatting.
//
class ConsoleLogSource : public BaseTraceLogSource
{
public:
ConsoleColors DefaultColor;
protected:
ConsoleLogSource()
: DefaultColor(Color_Gray)
{
}
public:
ConsoleLogSource(const TraceLogDescriptor* desc, ConsoleColors defaultColor = Color_Gray)
: BaseTraceLogSource(desc)
{
DefaultColor = defaultColor;
}
// Writes to the console using the source's default color. Note that the source's default
// color will always be used, thus ConsoleColorScope() will not be effectual unless the
// console's default color is Color_Default.
bool Write(const char* fmt, ...) const
{
va_list list;
va_start(list, fmt);
WriteV(fmt, list);
va_end(list);
return false;
}
// Writes to the console using the specified color. This overrides the default color setting
// for this log.
bool Write(ConsoleColors color, const char* fmt, ...) const
{
va_list list;
va_start(list, fmt);
WriteV(color, fmt, list);
va_end(list);
return false;
}
bool WriteV(const char* fmt, va_list list) const
{
Console.FormatV(fmt, list);
return false;
}
bool WriteV(ConsoleColors color, const char* fmt, va_list list) const
{
Console.FormatV(color, fmt, list);
return false;
}
};
+6
View File
@@ -83,6 +83,9 @@ target_sources(pcsx2-qt PRIVATE
Settings/ControllerSettingsWindow.h
Settings/ControllerSettingsWindow.ui
Settings/ControllerSettingWidgetBinder.h
Settings/DebugAnalysisSettingsWidget.cpp
Settings/DebugAnalysisSettingsWidget.h
Settings/DebugAnalysisSettingsWidget.ui
Settings/DebugSettingsWidget.cpp
Settings/DebugSettingsWidget.h
Settings/DebugSettingsWidget.ui
@@ -152,6 +155,9 @@ target_sources(pcsx2-qt PRIVATE
Settings/USBBindingWidget_GunCon2.ui
Settings/USBBindingWidget_RyojouhenCon.ui
Settings/USBBindingWidget_ShinkansenCon.ui
Debugger/AnalysisOptionsDialog.cpp
Debugger/AnalysisOptionsDialog.h
Debugger/AnalysisOptionsDialog.ui
Debugger/CpuWidget.cpp
Debugger/CpuWidget.h
Debugger/CpuWidget.ui
@@ -0,0 +1,35 @@
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
#include "AnalysisOptionsDialog.h"
#include "Host.h"
#include "DebugTools/SymbolImporter.h"
AnalysisOptionsDialog::AnalysisOptionsDialog(QWidget* parent)
: QDialog(parent)
{
m_ui.setupUi(this);
m_analysis_settings = new DebugAnalysisSettingsWidget();
m_ui.analysisSettings->setLayout(new QVBoxLayout());
m_ui.analysisSettings->layout()->setContentsMargins(0, 0, 0, 0);
m_ui.analysisSettings->layout()->addWidget(m_analysis_settings);
connect(m_ui.analyseButton, &QPushButton::clicked, this, &AnalysisOptionsDialog::analyse);
connect(m_ui.closeButton, &QPushButton::clicked, this, &QDialog::reject);
}
void AnalysisOptionsDialog::analyse()
{
Pcsx2Config::DebugAnalysisOptions options;
m_analysis_settings->parseSettingsFromWidgets(options);
Host::RunOnCPUThread([options]() {
R5900SymbolImporter.LoadAndAnalyseElf(options);
});
if (m_ui.closeCheckBox->isChecked())
accept();
}
+25
View File
@@ -0,0 +1,25 @@
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
#pragma once
#include "Settings/DebugAnalysisSettingsWidget.h"
#include <QtWidgets/QDialog>
#include "ui_AnalysisOptionsDialog.h"
class AnalysisOptionsDialog : public QDialog
{
Q_OBJECT
public:
AnalysisOptionsDialog(QWidget* parent = nullptr);
protected:
void analyse();
DebugAnalysisSettingsWidget* m_analysis_settings;
Ui::AnalysisOptionsDialog m_ui;
};
+113
View File
@@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AnalysisOptionsDialog</class>
<widget class="QDialog" name="AnalysisOptionsDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>500</width>
<height>750</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>500</width>
<height>650</height>
</size>
</property>
<property name="windowTitle">
<string>Analysis Options</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Changes made here won't be saved. Edit these settings from the global or per-game settings dialogs to have your changes take effect for future analysis runs.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="analysisSettings">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>488</width>
<height>636</height>
</rect>
</property>
</widget>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="buttons">
<item>
<widget class="QCheckBox" name="closeCheckBox">
<property name="text">
<string>Close dialog after analysis has started</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="analyseButton">
<property name="text">
<string>Analyze</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="closeButton">
<property name="text">
<string>Close</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+4 -6
View File
@@ -164,10 +164,6 @@ void CpuWidget::setupSymbolTrees()
m_ui.tabLocalVariables->layout()->addWidget(m_local_variable_tree);
m_ui.tabParameterVariables->layout()->addWidget(m_parameter_variable_tree);
connect(m_ui.tabWidgetRegFunc, &QTabWidget::currentChanged, m_function_tree, &SymbolTreeWidget::updateModel);
connect(m_ui.tabWidget, &QTabWidget::currentChanged, m_global_variable_tree, &SymbolTreeWidget::updateModel);
connect(m_ui.tabWidget, &QTabWidget::currentChanged, m_local_variable_tree, &SymbolTreeWidget::updateModel);
connect(m_function_tree, &SymbolTreeWidget::goToInDisassembly, m_ui.disassemblyWidget, &DisassemblyWidget::gotoAddressAndSetFocus);
connect(m_global_variable_tree, &SymbolTreeWidget::goToInDisassembly, m_ui.disassemblyWidget, &DisassemblyWidget::gotoAddressAndSetFocus);
connect(m_local_variable_tree, &SymbolTreeWidget::goToInDisassembly, m_ui.disassemblyWidget, &DisassemblyWidget::gotoAddressAndSetFocus);
@@ -207,8 +203,10 @@ void CpuWidget::reloadCPUWidgets()
m_ui.disassemblyWidget->update();
m_ui.memoryviewWidget->update();
m_local_variable_tree->reset();
m_parameter_variable_tree->reset();
m_function_tree->updateModel();
m_global_variable_tree->updateModel();
m_local_variable_tree->updateModel();
m_parameter_variable_tree->updateModel();
}
void CpuWidget::paintEvent(QPaintEvent* event)
+26 -1
View File
@@ -5,9 +5,11 @@
#include "DebugTools/DebugInterface.h"
#include "DebugTools/Breakpoints.h"
#include "DebugTools/SymbolImporter.h"
#include "VMManager.h"
#include "QtHost.h"
#include "MainWindow.h"
#include "AnalysisOptionsDialog.h"
DebuggerWindow::DebuggerWindow(QWidget* parent)
: QMainWindow(parent)
@@ -28,6 +30,7 @@ DebuggerWindow::DebuggerWindow(QWidget* parent)
connect(m_ui.actionStepInto, &QAction::triggered, this, &DebuggerWindow::onStepInto);
connect(m_ui.actionStepOver, &QAction::triggered, this, &DebuggerWindow::onStepOver);
connect(m_ui.actionStepOut, &QAction::triggered, this, &DebuggerWindow::onStepOut);
connect(m_ui.actionAnalyse, &QAction::triggered, this, &DebuggerWindow::onAnalyse);
connect(m_ui.actionOnTop, &QAction::triggered, [this] { this->setWindowFlags(this->windowFlags() ^ Qt::WindowStaysOnTopHint); this->show(); });
connect(g_emu_thread, &EmuThread::onVMPaused, this, &DebuggerWindow::onVMStateChanged);
@@ -38,7 +41,7 @@ DebuggerWindow::DebuggerWindow(QWidget* parent)
// We can't do this in the designer, but we want to right align the actionOnTop action in the toolbar
QWidget* spacer = new QWidget(this);
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_ui.toolBar->insertWidget(m_ui.actionOnTop, spacer);
m_ui.toolBar->insertWidget(m_ui.actionAnalyse, spacer);
m_cpuWidget_r5900 = new CpuWidget(this, r5900Debug);
m_cpuWidget_r3000 = new CpuWidget(this, r3000Debug);
@@ -127,3 +130,25 @@ void DebuggerWindow::onStepOut()
CpuWidget* currentCpu = static_cast<CpuWidget*>(m_ui.cpuTabs->currentWidget());
currentCpu->onStepOut();
}
void DebuggerWindow::onAnalyse()
{
AnalysisOptionsDialog* dialog = new AnalysisOptionsDialog(this);
dialog->show();
}
void DebuggerWindow::showEvent(QShowEvent* event)
{
Host::RunOnCPUThread([]() {
R5900SymbolImporter.OnDebuggerOpened();
});
QMainWindow::showEvent(event);
}
void DebuggerWindow::hideEvent(QHideEvent* event)
{
Host::RunOnCPUThread([]() {
R5900SymbolImporter.OnDebuggerClosed();
});
QMainWindow::hideEvent(event);
}
+5
View File
@@ -21,6 +21,11 @@ public slots:
void onStepInto();
void onStepOver();
void onStepOut();
void onAnalyse();
protected:
void showEvent(QShowEvent* event);
void hideEvent(QHideEvent *event);
private:
Ui::DebuggerWindow m_ui;
+28 -13
View File
@@ -29,12 +29,6 @@
<property name="contextMenuPolicy">
<enum>Qt::PreventContextMenu</enum>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="floatable">
<bool>false</bool>
</property>
<property name="movable">
<bool>false</bool>
</property>
@@ -44,6 +38,12 @@
<height>16</height>
</size>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="floatable">
<bool>false</bool>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
@@ -54,11 +54,13 @@
<addaction name="actionStepInto"/>
<addaction name="actionStepOver"/>
<addaction name="actionStepOut"/>
<addaction name="actionAnalyse"/>
<addaction name="actionOnTop"/>
</widget>
<action name="actionRun">
<property name="icon">
<iconset theme="play-line"/>
<iconset theme="play-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Run</string>
@@ -66,7 +68,8 @@
</action>
<action name="actionStepInto">
<property name="icon">
<iconset theme="debug-step-into-line"/>
<iconset theme="debug-step-into-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Step Into</string>
@@ -77,7 +80,8 @@
</action>
<action name="actionStepOver">
<property name="icon">
<iconset theme="debug-step-over-line"/>
<iconset theme="debug-step-over-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Step Over</string>
@@ -88,7 +92,8 @@
</action>
<action name="actionStepOut">
<property name="icon">
<iconset theme="debug-step-out-line"/>
<iconset theme="debug-step-out-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Step Out</string>
@@ -98,12 +103,13 @@
</property>
</action>
<action name="actionOnTop">
<property name="icon">
<iconset theme="pin-filled"/>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset theme="pin-filled">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Always On Top</string>
</property>
@@ -111,6 +117,15 @@
<string>Show this window on top</string>
</property>
</action>
<action name="actionAnalyse">
<property name="icon">
<iconset theme="restart-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Analyze</string>
</property>
</action>
</widget>
<resources/>
<connections/>
@@ -337,7 +337,7 @@ void NewFunctionDialog::createSymbol()
QString error_message;
m_cpu.GetSymbolGuardian().ReadWrite([&](ccc::SymbolDatabase& database) {
ccc::Result<ccc::SymbolSourceHandle> source = database.get_symbol_source("User-defined");
ccc::Result<ccc::SymbolSourceHandle> source = database.get_symbol_source("User-Defined");
if (!source.success())
{
error_message = tr("Cannot create symbol source.");
@@ -398,7 +398,7 @@ void NewGlobalVariableDialog::createSymbol()
QString error_message;
m_cpu.GetSymbolGuardian().ReadWrite([&](ccc::SymbolDatabase& database) {
ccc::Result<ccc::SymbolSourceHandle> source = database.get_symbol_source("User-defined");
ccc::Result<ccc::SymbolSourceHandle> source = database.get_symbol_source("User-Defined");
if (!source.success())
{
error_message = tr("Cannot create symbol source.");
@@ -508,7 +508,7 @@ void NewLocalVariableDialog::createSymbol()
return;
}
ccc::Result<ccc::SymbolSourceHandle> source = database.get_symbol_source("User-defined");
ccc::Result<ccc::SymbolSourceHandle> source = database.get_symbol_source("User-Defined");
if (!source.success())
{
error_message = tr("Cannot create symbol source.");
@@ -622,7 +622,7 @@ void NewParameterVariableDialog::createSymbol()
return;
}
ccc::Result<ccc::SymbolSourceHandle> source = database.get_symbol_source("User-defined");
ccc::Result<ccc::SymbolSourceHandle> source = database.get_symbol_source("User-Defined");
if (!source.success())
{
error_message = tr("Cannot create symbol source.");
@@ -50,14 +50,14 @@ protected:
protected slots:
virtual bool parseUserInput() = 0;
protected:
virtual void createSymbol() = 0;
void setupRegisterField();
void setupSizeField();
void setupFunctionField();
void connectInputWidgets();
void updateErrorMessage(QString error_message);
@@ -75,14 +75,14 @@ protected:
u32 storageType() const;
void onStorageTabChanged(int index);
std::string parseName(QString& error_message);
u32 parseAddress(QString& error_message);
DebugInterface& m_cpu;
Ui::NewSymbolDialog m_ui;
u32 m_alignment;
u32 m_alignment;
std::vector<ccc::FunctionHandle> m_functions;
};
@@ -96,7 +96,7 @@ public:
protected:
bool parseUserInput() override;
void createSymbol() override;
std::string m_name;
u32 m_address = 0;
u32 m_size = 0;
@@ -114,7 +114,7 @@ public:
protected:
bool parseUserInput() override;
void createSymbol() override;
std::string m_name;
u32 m_address;
std::unique_ptr<ccc::ast::Node> m_type;
@@ -130,7 +130,7 @@ public:
protected:
bool parseUserInput() override;
void createSymbol() override;
std::string m_name;
std::variant<ccc::GlobalStorage, ccc::RegisterStorage, ccc::StackStorage> m_storage;
u32 m_address = 0;
@@ -148,7 +148,7 @@ public:
protected:
bool parseUserInput() override;
void createSymbol() override;
std::string m_name;
std::variant<ccc::RegisterStorage, ccc::StackStorage> m_storage;
std::unique_ptr<ccc::ast::Node> m_type;
@@ -5,6 +5,7 @@
#include <QtWidgets/QStyledItemDelegate>
#include "DebugTools/DebugInterface.h"
#include "DebugTools/SymbolGuardian.h"
class SymbolTreeValueDelegate : public QStyledItemDelegate
@@ -106,8 +106,8 @@ QVariant SymbolTreeModel::data(const QModelIndex& index, int role) const
bool active = true;
// Gray out the names of symbols that have been overwritten in memory.
if (index.column() == NAME && node->symbol.valid())
active = symbolMatchesMemory(node->symbol);
if (index.column() == NAME)
active = node->matchesMemory();
// Gray out the values of variables that are dead.
if (index.column() == VALUE && node->liveness().has_value())
@@ -521,80 +521,3 @@ bool SymbolTreeModel::nodeHasChildren(const ccc::ast::Node& logical_type, const
return result;
}
bool SymbolTreeModel::symbolMatchesMemory(ccc::MultiSymbolHandle& symbol) const
{
bool matching = true;
switch (symbol.descriptor())
{
case ccc::SymbolDescriptor::FUNCTION:
{
m_cpu.GetSymbolGuardian().Read([&](const ccc::SymbolDatabase& database) -> void {
const ccc::Function* function = database.functions.symbol_from_handle(symbol.handle());
if (!function || function->original_hash() == 0)
return;
matching = function->current_hash() == function->original_hash();
});
break;
}
case ccc::SymbolDescriptor::GLOBAL_VARIABLE:
{
m_cpu.GetSymbolGuardian().Read([&](const ccc::SymbolDatabase& database) -> void {
const ccc::GlobalVariable* global_variable = database.global_variables.symbol_from_handle(symbol.handle());
if (!global_variable)
return;
const ccc::SourceFile* source_file = database.source_files.symbol_from_handle(global_variable->source_file());
if (!source_file)
return;
matching = source_file->functions_match();
});
break;
}
case ccc::SymbolDescriptor::LOCAL_VARIABLE:
{
m_cpu.GetSymbolGuardian().Read([&](const ccc::SymbolDatabase& database) -> void {
const ccc::LocalVariable* local_variable = database.local_variables.symbol_from_handle(symbol.handle());
if (!local_variable)
return;
const ccc::Function* function = database.functions.symbol_from_handle(local_variable->function());
if (!function)
return;
const ccc::SourceFile* source_file = database.source_files.symbol_from_handle(function->source_file());
if (!source_file)
return;
matching = source_file->functions_match();
});
break;
}
case ccc::SymbolDescriptor::PARAMETER_VARIABLE:
{
m_cpu.GetSymbolGuardian().Read([&](const ccc::SymbolDatabase& database) -> void {
const ccc::ParameterVariable* parameter_variable = database.parameter_variables.symbol_from_handle(symbol.handle());
if (!parameter_variable)
return;
const ccc::Function* function = database.functions.symbol_from_handle(parameter_variable->function());
if (!function)
return;
const ccc::SourceFile* source_file = database.source_files.symbol_from_handle(function->source_file());
if (!source_file)
return;
matching = source_file->functions_match();
});
break;
}
default:
{
}
}
return matching;
}
@@ -76,8 +76,6 @@ protected:
static bool nodeHasChildren(const ccc::ast::Node& logical_type, const ccc::SymbolDatabase& database);
bool symbolMatchesMemory(ccc::MultiSymbolHandle& symbol) const;
std::unique_ptr<SymbolTreeNode> m_root;
QString m_filter;
DebugInterface& m_cpu;
@@ -41,6 +41,7 @@ bool SymbolTreeNode::readFromVM(DebugInterface& cpu, const ccc::SymbolDatabase&
data_changed |= updateDisplayString(cpu, database);
data_changed |= updateLiveness(cpu);
data_changed |= updateMatchesMemory(cpu, database);
return data_changed;
}
@@ -478,6 +479,161 @@ bool SymbolTreeNode::updateLiveness(DebugInterface& cpu)
return true;
}
bool SymbolTreeNode::updateMatchesMemory(DebugInterface& cpu, const ccc::SymbolDatabase& database)
{
bool matching = true;
switch (symbol.descriptor())
{
case ccc::SymbolDescriptor::FUNCTION:
{
const ccc::Function* function = database.functions.symbol_from_handle(symbol.handle());
if (!function || function->current_hash() == 0 || function->original_hash() == 0)
return false;
matching = function->current_hash() == function->original_hash();
break;
}
case ccc::SymbolDescriptor::GLOBAL_VARIABLE:
{
const ccc::GlobalVariable* global_variable = database.global_variables.symbol_from_handle(symbol.handle());
if (!global_variable)
return false;
const ccc::SourceFile* source_file = database.source_files.symbol_from_handle(global_variable->source_file());
if (!source_file)
return false;
matching = source_file->functions_match();
break;
}
case ccc::SymbolDescriptor::LOCAL_VARIABLE:
{
const ccc::LocalVariable* local_variable = database.local_variables.symbol_from_handle(symbol.handle());
if (!local_variable)
return false;
const ccc::Function* function = database.functions.symbol_from_handle(local_variable->function());
if (!function || function->current_hash() == 0 || function->original_hash() == 0)
return false;
matching = function->current_hash() == function->original_hash();
break;
}
case ccc::SymbolDescriptor::PARAMETER_VARIABLE:
{
const ccc::ParameterVariable* parameter_variable = database.parameter_variables.symbol_from_handle(symbol.handle());
if (!parameter_variable)
return false;
const ccc::Function* function = database.functions.symbol_from_handle(parameter_variable->function());
if (!function || function->current_hash() == 0 || function->original_hash() == 0)
return false;
matching = function->current_hash() == function->original_hash();
break;
}
default:
{
}
}
if (matching == m_matches_memory)
return false;
m_matches_memory = matching;
return true;
}
bool SymbolTreeNode::matchesMemory() const
{
return m_matches_memory;
}
void SymbolTreeNode::updateSymbolHashes(std::span<const SymbolTreeNode*> nodes, DebugInterface& cpu, ccc::SymbolDatabase& database)
{
std::set<ccc::FunctionHandle> functions;
std::set<ccc::SourceFile*> source_files;
// Determine which functions we need to hash again, and in the case of
// global variables, which source files are associated with those functions
// so that we can check if they still match.
for (const SymbolTreeNode* node : nodes)
{
switch (node->symbol.descriptor())
{
case ccc::SymbolDescriptor::FUNCTION:
{
functions.emplace(node->symbol.handle());
break;
}
case ccc::SymbolDescriptor::GLOBAL_VARIABLE:
{
const ccc::GlobalVariable* global_variable = database.global_variables.symbol_from_handle(node->symbol.handle());
if (!global_variable)
continue;
ccc::SourceFile* source_file = database.source_files.symbol_from_handle(global_variable->source_file());
if (!source_file)
continue;
for (ccc::FunctionHandle function : source_file->functions())
functions.emplace(function);
source_files.emplace(source_file);
break;
}
case ccc::SymbolDescriptor::LOCAL_VARIABLE:
{
const ccc::LocalVariable* local_variable = database.local_variables.symbol_from_handle(node->symbol.handle());
if (!local_variable)
continue;
functions.emplace(local_variable->function());
break;
}
case ccc::SymbolDescriptor::PARAMETER_VARIABLE:
{
const ccc::ParameterVariable* parameter_variable = database.parameter_variables.symbol_from_handle(node->symbol.handle());
if (!parameter_variable)
continue;
functions.emplace(parameter_variable->function());
break;
}
default:
{
}
}
}
// Update the hashes for the enumerated functions.
for (ccc::FunctionHandle function_handle : functions)
{
ccc::Function* function = database.functions.symbol_from_handle(function_handle);
if (!function || function->original_hash() == 0)
continue;
std::optional<ccc::FunctionHash> hash = SymbolGuardian::HashFunction(*function, cpu);
if (!hash.has_value())
continue;
function->set_current_hash(*hash);
}
// Check that the enumerated source files still have matching functions.
for (ccc::SourceFile* source_file : source_files)
source_file->check_functions_match(database);
}
bool SymbolTreeNode::anySymbolsValid(const ccc::SymbolDatabase& database) const
{
if (symbol.lookup_symbol(database))
@@ -62,6 +62,11 @@ public:
bool updateLiveness(DebugInterface& cpu);
bool updateMatchesMemory(DebugInterface& cpu, const ccc::SymbolDatabase& database);
bool matchesMemory() const;
static void updateSymbolHashes(std::span<const SymbolTreeNode*> nodes, DebugInterface& cpu, ccc::SymbolDatabase& database);
bool anySymbolsValid(const ccc::SymbolDatabase& database) const;
const SymbolTreeNode* parent() const;
@@ -79,6 +84,7 @@ protected:
QVariant m_value;
QString m_display_value;
std::optional<bool> m_liveness;
bool m_matches_memory = true;
SymbolTreeNode* m_parent = nullptr;
std::vector<std::unique_ptr<SymbolTreeNode>> m_children;
@@ -24,17 +24,29 @@ SymbolTreeWidget::SymbolTreeWidget(u32 flags, s32 symbol_address_alignment, Debu
setupMenu();
connect(m_ui.refreshButton, &QPushButton::clicked, this, &SymbolTreeWidget::reset);
connect(m_ui.refreshButton, &QPushButton::clicked, this, [&]() {
m_cpu.GetSymbolGuardian().ReadWrite([&](ccc::SymbolDatabase& database) {
m_cpu.GetSymbolGuardian().UpdateFunctionHashes(database, m_cpu);
});
reset();
});
connect(m_ui.filterBox, &QLineEdit::textEdited, this, &SymbolTreeWidget::reset);
connect(m_ui.newButton, &QPushButton::clicked, this, &SymbolTreeWidget::onNewButtonPressed);
connect(m_ui.deleteButton, &QPushButton::clicked, this, &SymbolTreeWidget::onDeleteButtonPressed);
connect(m_ui.treeView->verticalScrollBar(), &QScrollBar::valueChanged, this, &SymbolTreeWidget::updateVisibleNodes);
connect(m_ui.treeView->verticalScrollBar(), &QScrollBar::valueChanged, this, [&]() {
updateVisibleNodes(false);
});
m_ui.treeView->setContextMenuPolicy(Qt::CustomContextMenu);
connect(m_ui.treeView, &QTreeView::customContextMenuRequested, this, &SymbolTreeWidget::openMenu);
connect(m_ui.treeView, &QTreeView::expanded, this, &SymbolTreeWidget::updateVisibleNodes);
connect(m_ui.treeView, &QTreeView::expanded, this, [&]() {
updateVisibleNodes(true);
});
}
SymbolTreeWidget::~SymbolTreeWidget() = default;
@@ -43,15 +55,15 @@ void SymbolTreeWidget::resizeEvent(QResizeEvent* event)
{
QWidget::resizeEvent(event);
updateVisibleNodes();
updateVisibleNodes(false);
}
void SymbolTreeWidget::updateModel()
{
if (!m_model || m_model->needsReset())
if (needsReset())
reset();
updateVisibleNodes();
else
updateVisibleNodes(true);
}
void SymbolTreeWidget::reset()
@@ -61,8 +73,6 @@ void SymbolTreeWidget::reset()
m_ui.treeView->setColumnHidden(SymbolTreeModel::SIZE, !m_show_size_column || !m_show_size_column->isChecked());
m_cpu.GetSymbolGuardian().UpdateFunctionHashes(m_cpu);
SymbolFilters filters;
std::unique_ptr<SymbolTreeNode> root;
m_cpu.GetSymbolGuardian().Read([&](const ccc::SymbolDatabase& database) -> void {
@@ -80,25 +90,39 @@ void SymbolTreeWidget::reset()
m_model->reset(std::move(root));
// Read the initial values for visible nodes.
updateVisibleNodes();
updateVisibleNodes(true);
if (!filters.string.isEmpty())
expandGroups(QModelIndex());
}
}
void SymbolTreeWidget::updateVisibleNodes()
void SymbolTreeWidget::updateVisibleNodes(bool update_hashes)
{
if (!m_model)
return;
// Enumerate visible symbol nodes.
std::vector<const SymbolTreeNode*> nodes;
QModelIndex index = m_ui.treeView->indexAt(m_ui.treeView->rect().topLeft());
while (m_ui.treeView->visualRect(index).intersects(m_ui.treeView->viewport()->rect()))
{
m_model->setData(index, QVariant(), SymbolTreeModel::UPDATE_FROM_MEMORY_ROLE);
nodes.emplace_back(m_model->nodeFromIndex(index));
index = m_ui.treeView->indexBelow(index);
}
// Hash functions for symbols with visible nodes.
if (update_hashes)
{
m_cpu.GetSymbolGuardian().ReadWrite([&](ccc::SymbolDatabase& database) {
SymbolTreeNode::updateSymbolHashes(nodes, m_cpu, database);
});
}
// Update the values of visible nodes from memory.
for (const SymbolTreeNode* node : nodes)
m_model->setData(m_model->indexFromNode(*node), QVariant(), SymbolTreeModel::UPDATE_FROM_MEMORY_ROLE);
m_ui.treeView->update();
}
@@ -465,6 +489,11 @@ void SymbolTreeWidget::openMenu(QPoint pos)
m_context_menu->exec(m_ui.treeView->viewport()->mapToGlobal(pos));
}
bool SymbolTreeWidget::needsReset() const
{
return !m_model || m_model->needsReset();
}
void SymbolTreeWidget::onDeleteButtonPressed()
{
SymbolTreeNode* node = currentNode();
@@ -861,14 +890,43 @@ LocalVariableTreeWidget::LocalVariableTreeWidget(DebugInterface& cpu, QWidget* p
LocalVariableTreeWidget::~LocalVariableTreeWidget() = default;
bool LocalVariableTreeWidget::needsReset() const
{
if (!m_function.valid())
return true;
u32 program_counter = m_cpu.getPC();
bool left_function = true;
m_cpu.GetSymbolGuardian().Read([&](const ccc::SymbolDatabase& database) {
const ccc::Function* function = database.functions.symbol_from_handle(m_function);
if (!function || !function->address().valid())
return;
u32 begin = function->address().value;
u32 end = function->address().value + function->size();
left_function = program_counter < begin || program_counter >= end;
});
if (left_function)
return true;
return SymbolTreeWidget::needsReset();
}
std::vector<SymbolTreeWidget::SymbolWork> LocalVariableTreeWidget::getSymbols(
const QString& filter, const ccc::SymbolDatabase& database)
{
u32 program_counter = m_cpu.getPC();
const ccc::Function* function = database.functions.symbol_overlapping_address(program_counter);
if (!function || !function->local_variables().has_value())
{
m_function = ccc::FunctionHandle();
return std::vector<SymbolWork>();
}
m_function = function->handle();
m_caller_stack_pointer = m_cpu.getCallerStackPointer(*function);
std::vector<SymbolTreeWidget::SymbolWork> symbols;
@@ -957,6 +1015,31 @@ ParameterVariableTreeWidget::ParameterVariableTreeWidget(DebugInterface& cpu, QW
ParameterVariableTreeWidget::~ParameterVariableTreeWidget() = default;
bool ParameterVariableTreeWidget::needsReset() const
{
if (!m_function.valid())
return true;
u32 program_counter = m_cpu.getPC();
bool left_function = true;
m_cpu.GetSymbolGuardian().Read([&](const ccc::SymbolDatabase& database) {
const ccc::Function* function = database.functions.symbol_from_handle(m_function);
if (!function || !function->address().valid())
return;
u32 begin = function->address().value;
u32 end = function->address().value + function->size();
left_function = program_counter < begin || program_counter >= end;
});
if (left_function)
return true;
return SymbolTreeWidget::needsReset();
}
std::vector<SymbolTreeWidget::SymbolWork> ParameterVariableTreeWidget::getSymbols(
const QString& filter, const ccc::SymbolDatabase& database)
{
@@ -965,8 +1048,12 @@ std::vector<SymbolTreeWidget::SymbolWork> ParameterVariableTreeWidget::getSymbol
u32 program_counter = m_cpu.getPC();
const ccc::Function* function = database.functions.symbol_overlapping_address(program_counter);
if (!function || !function->parameter_variables().has_value())
{
m_function = ccc::FunctionHandle();
return std::vector<SymbolWork>();
}
m_function = function->handle();
m_caller_stack_pointer = m_cpu.getCallerStackPointer(*function);
for (const ccc::ParameterVariableHandle parameter_variable_handle : *function->parameter_variables())
@@ -21,7 +21,7 @@ public:
void updateModel();
void reset();
void updateVisibleNodes();
void updateVisibleNodes(bool update_hashes);
void expandGroups(QModelIndex index);
signals:
@@ -41,7 +41,7 @@ protected:
const ccc::SourceFile* source_file = nullptr;
};
explicit SymbolTreeWidget(u32 flags, s32 symbol_address_alignment, DebugInterface& cpu, QWidget* parent = nullptr);
SymbolTreeWidget(u32 flags, s32 symbol_address_alignment, DebugInterface& cpu, QWidget* parent = nullptr);
void resizeEvent(QResizeEvent* event) override;
@@ -72,6 +72,8 @@ protected:
void setupMenu();
void openMenu(QPoint pos);
virtual bool needsReset() const;
virtual std::vector<SymbolWork> getSymbols(
const QString& filter, const ccc::SymbolDatabase& database) = 0;
@@ -172,6 +174,8 @@ public:
virtual ~LocalVariableTreeWidget();
protected:
bool needsReset() const override;
std::vector<SymbolWork> getSymbols(
const QString& filter, const ccc::SymbolDatabase& database) override;
@@ -182,6 +186,7 @@ protected:
void onNewButtonPressed() override;
ccc::FunctionHandle m_function;
std::optional<u32> m_caller_stack_pointer;
};
@@ -193,6 +198,8 @@ public:
virtual ~ParameterVariableTreeWidget();
protected:
bool needsReset() const override;
std::vector<SymbolWork> getSymbols(
const QString& filter, const ccc::SymbolDatabase& database) override;
@@ -203,6 +210,7 @@ protected:
void onNewButtonPressed() override;
ccc::FunctionHandle m_function;
std::optional<u32> m_caller_stack_pointer;
};
-5
View File
@@ -1911,11 +1911,6 @@ void MainWindow::onInputRecStopActionTriggered()
}
}
void MainWindow::onInputRecOpenSettingsTriggered()
{
// TODO - Vaser - Implement
}
InputRecordingViewer* MainWindow::getInputRecordingViewer()
{
if (!m_input_recording_viewer)
-1
View File
@@ -179,7 +179,6 @@ private Q_SLOTS:
void onInputRecNewActionTriggered();
void onInputRecPlayActionTriggered();
void onInputRecStopActionTriggered();
void onInputRecOpenSettingsTriggered();
void onInputRecOpenViewer();
void onVMStarting();
-9
View File
@@ -196,7 +196,6 @@
<addaction name="actionInputRecStop"/>
<addaction name="separator"/>
<addaction name="actionInputRecOpenViewer"/>
<addaction name="actionInputRecOpenSettings"/>
<addaction name="separator"/>
<addaction name="actionInputRecConsoleLogs"/>
<addaction name="actionInputRecControllerLogs"/>
@@ -981,14 +980,6 @@
<string extracomment="This section refers to the Input Recording submenu.">Stop</string>
</property>
</action>
<action name="actionInputRecOpenSettings">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string extracomment="This section refers to the Input Recording submenu.">Settings</string>
</property>
</action>
<action name="actionRecording_Console_Logs">
<property name="text">
<string>Input Recording Logs</string>
@@ -56,6 +56,9 @@ AdvancedSettingsWidget::AdvancedSettingsWidget(SettingsWindow* dialog, QWidget*
SettingWidgetBinder::BindWidgetToFloatSetting(sif, m_ui.ntscFrameRate, "EmuCore/GS", "FramerateNTSC", 59.94f);
SettingWidgetBinder::BindWidgetToFloatSetting(sif, m_ui.palFrameRate, "EmuCore/GS", "FrameratePAL", 50.00f);
dialog->registerWidgetHelp(m_ui.savestateSelector, tr("Use Save State Selector"), tr("Checked"),
tr("Show a save state selector UI when switching slots instead of showing a notification bubble."));
SettingWidgetBinder::BindWidgetToIntSetting(
sif, m_ui.savestateCompressionMethod, "EmuCore", "SavestateCompressionType", static_cast<int>(SavestateCompressionMethod::Zstandard));
@@ -67,6 +70,7 @@ AdvancedSettingsWidget::AdvancedSettingsWidget(SettingsWindow* dialog, QWidget*
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.backupSaveStates, "EmuCore", "BackupSavestate", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.saveStateOnShutdown, "EmuCore", "SaveStateOnShutdown", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.savestateSelector, "EmuCore", "UseSavestateSelector", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pineEnable, "EmuCore", "EnablePINE", false);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.pineSlot, "EmuCore", "PINESlot", 28011);
+15 -8
View File
@@ -32,9 +32,9 @@
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<y>-447</y>
<width>790</width>
<height>1023</height>
<height>1049</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
@@ -422,10 +422,10 @@
<string>Savestate Settings</string>
</property>
<layout class="QGridLayout" name="savestateSettingsLayout">
<item row="0" column="0">
<widget class="QLabel" name="savestateCompressionLabel">
<item row="3" column="1">
<widget class="QCheckBox" name="saveStateOnShutdown">
<property name="text">
<string>Compression Method:</string>
<string>Save State On Shutdown</string>
</property>
</widget>
</item>
@@ -491,10 +491,17 @@
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="saveStateOnShutdown">
<item row="0" column="0">
<widget class="QLabel" name="savestateCompressionLabel">
<property name="text">
<string>Save State On Shutdown</string>
<string>Compression Method:</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="savestateSelector">
<property name="text">
<string>Use Save State Selector</string>
</property>
</widget>
</item>
@@ -0,0 +1,427 @@
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
#include "DebugAnalysisSettingsWidget.h"
#include "SettingsWindow.h"
#include "SettingWidgetBinder.h"
#include "DebugTools/SymbolImporter.h"
#include <QtWidgets/QFileDialog>
DebugAnalysisSettingsWidget::DebugAnalysisSettingsWidget(QWidget* parent)
: QWidget(parent)
{
m_ui.setupUi(this);
m_ui.automaticallyClearSymbols->setChecked(Host::GetBoolSettingValue("Debugger/Analysis", "AutomaticallySelectSymbolsToClear", true));
setupSymbolSourceGrid();
m_ui.importFromElf->setChecked(Host::GetBoolSettingValue("Debugger/Analysis", "ImportSymbolsFromELF", true));
m_ui.importSymFileFromDefaultLocation->setChecked(Host::GetBoolSettingValue("Debugger/Analysis", "ImportSymFileFromDefaultLocation", true));
m_ui.demangleSymbols->setChecked(Host::GetBoolSettingValue("Debugger/Analysis", "DemangleSymbols", true));
m_ui.demangleParameters->setChecked(Host::GetBoolSettingValue("Debugger/Analysis", "DemangleParameters", true));
setupSymbolFileList();
std::string function_scan_mode = Host::GetStringSettingValue("Debugger/Analysis", "FunctionScanMode");
for (int i = 0;; i++)
{
if (Pcsx2Config::DebugAnalysisOptions::FunctionScanModeNames[i] == nullptr)
break;
if (function_scan_mode == Pcsx2Config::DebugAnalysisOptions::FunctionScanModeNames[i])
m_ui.functionScanMode->setCurrentIndex(i);
}
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.grayOutOverwrittenFunctions->setChecked(Host::GetBoolSettingValue("Debugger/Analysis", "GenerateFunctionHashes", true));
connect(m_ui.automaticallyClearSymbols, &QCheckBox::checkStateChanged, this, &DebugAnalysisSettingsWidget::updateEnabledStates);
connect(m_ui.demangleSymbols, &QCheckBox::checkStateChanged, this, &DebugAnalysisSettingsWidget::updateEnabledStates);
connect(m_ui.customAddressRange, &QCheckBox::checkStateChanged, this, &DebugAnalysisSettingsWidget::updateEnabledStates);
updateEnabledStates();
}
DebugAnalysisSettingsWidget::DebugAnalysisSettingsWidget(SettingsWindow* dialog, QWidget* parent)
: QWidget(parent)
, m_dialog(dialog)
{
SettingsInterface* sif = dialog->getSettingsInterface();
m_ui.setupUi(this);
// Make sure the user doesn't select symbol sources from both the global
// settings and the per-game settings, as these settings will conflict with
// each other. It only really makes sense to modify these settings on a
// per-game basis anyway.
if (dialog->isPerGameSettings())
{
SettingWidgetBinder::BindWidgetToBoolSetting(
sif, m_ui.automaticallyClearSymbols, "Debugger/Analysis", "AutomaticallySelectSymbolsToClear", true);
m_dialog->registerWidgetHelp(m_ui.automaticallyClearSymbols, tr("Automatically Select Symbols To Clear"), tr("Checked"),
tr("Automatically delete symbols that were generated by any previous analysis runs."));
setupSymbolSourceGrid();
}
else
{
m_ui.clearExistingSymbolsGroup->hide();
}
SettingWidgetBinder::BindWidgetToBoolSetting(
sif, m_ui.importFromElf, "Debugger/Analysis", "ImportSymbolsFromELF", true);
SettingWidgetBinder::BindWidgetToBoolSetting(
sif, m_ui.importSymFileFromDefaultLocation, "Debugger/Analysis", "ImportSymFileFromDefaultLocation", true);
SettingWidgetBinder::BindWidgetToBoolSetting(
sif, m_ui.demangleSymbols, "Debugger/Analysis", "DemangleSymbols", true);
SettingWidgetBinder::BindWidgetToBoolSetting(
sif, m_ui.demangleParameters, "Debugger/Analysis", "DemangleParameters", true);
m_dialog->registerWidgetHelp(m_ui.importFromElf, tr("Import From ELF"), tr("Checked"),
tr("Import symbol tables stored in the game's boot ELF."));
m_dialog->registerWidgetHelp(m_ui.importSymFileFromDefaultLocation, tr("Import Default .sym File"), tr("Checked"),
tr("Import symbols from a .sym file with the same name as the loaded ISO file on disk if such a file exists."));
m_dialog->registerWidgetHelp(m_ui.demangleSymbols, tr("Demangle Symbols"), tr("Checked"),
tr("Demangle C++ symbols during the import process so that the function and global variable names shown in the "
"debugger are more readable."));
m_dialog->registerWidgetHelp(m_ui.demangleParameters, tr("Demangle Parameters"), tr("Checked"),
tr("Include parameter lists in demangled function names."));
// Same as above. It only makes sense to load extra symbol files on a
// per-game basis.
if (dialog->isPerGameSettings())
{
setupSymbolFileList();
}
else
{
m_ui.symbolFileLabel->hide();
m_ui.symbolFileList->hide();
m_ui.importSymbolFileButtons->hide();
}
SettingWidgetBinder::BindWidgetToEnumSetting(
sif, m_ui.functionScanMode, "Debugger/Analysis", "FunctionScanMode",
Pcsx2Config::DebugAnalysisOptions::FunctionScanModeNames, DebugFunctionScanMode::SCAN_ELF);
m_dialog->registerWidgetHelp(m_ui.functionScanMode, tr("Scan Mode"), tr("Scan ELF"),
tr("Choose where the function scanner looks to find functions. This option can be useful if the application "
"loads additional code at runtime."));
// Same as above. It only makes sense to set a custom memory range on a
// per-game basis.
if (dialog->isPerGameSettings())
{
SettingWidgetBinder::BindWidgetToBoolSetting(
sif, m_ui.customAddressRange, "Debugger/Analysis", "CustomFunctionScanRange", false);
connect(m_ui.addressRangeStart, &QLineEdit::textChanged, this, &DebugAnalysisSettingsWidget::functionScanRangeChanged);
connect(m_ui.addressRangeEnd, &QLineEdit::textChanged, this, &DebugAnalysisSettingsWidget::functionScanRangeChanged);
m_dialog->registerWidgetHelp(m_ui.customAddressRange, tr("Custom Address Range"), tr("Unchecked"),
tr("Whether to look for functions from the address range specified (Checked), or from the ELF segment "
"containing the entry point (Unchecked)."));
}
else
{
m_ui.customAddressRange->hide();
m_ui.customAddressRangeLineEdits->hide();
}
SettingWidgetBinder::BindWidgetToBoolSetting(
sif, m_ui.grayOutOverwrittenFunctions, "Debugger/Analysis", "GenerateFunctionHashes", true);
m_dialog->registerWidgetHelp(m_ui.grayOutOverwrittenFunctions, tr("Gray Out Symbols For Overwritten Functions"), tr("Checked"),
tr("Generate hashes for all the detected functions, and gray out the symbols displayed in the debugger for "
"functions that no longer match."));
connect(m_ui.automaticallyClearSymbols, &QCheckBox::checkStateChanged, this, &DebugAnalysisSettingsWidget::updateEnabledStates);
connect(m_ui.demangleSymbols, &QCheckBox::checkStateChanged, this, &DebugAnalysisSettingsWidget::updateEnabledStates);
connect(m_ui.customAddressRange, &QCheckBox::checkStateChanged, this, &DebugAnalysisSettingsWidget::updateEnabledStates);
updateEnabledStates();
}
void DebugAnalysisSettingsWidget::parseSettingsFromWidgets(Pcsx2Config::DebugAnalysisOptions& output)
{
output.AutomaticallySelectSymbolsToClear = m_ui.automaticallyClearSymbols->isChecked();
for (const auto& [name, temp] : m_symbol_sources)
{
DebugSymbolSource& source = output.SymbolSources.emplace_back();
source.Name = name;
source.ClearDuringAnalysis = temp.check_box->isChecked();
}
output.ImportSymbolsFromELF = m_ui.importFromElf->isChecked();
output.ImportSymFileFromDefaultLocation = m_ui.importSymFileFromDefaultLocation->isChecked();
output.DemangleSymbols = m_ui.demangleSymbols->isChecked();
output.DemangleParameters = m_ui.demangleParameters->isChecked();
for (int i = 0; i < m_ui.symbolFileList->count(); i++)
{
DebugExtraSymbolFile& file = output.ExtraSymbolFiles.emplace_back();
file.Path = m_ui.symbolFileList->item(i)->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()
{
QGridLayout* layout = new QGridLayout(m_ui.symbolSourceGrid);
if (!m_dialog || m_dialog->getSerial() == QtHost::GetCurrentGameSerial().toStdString())
{
// 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);
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);
SymbolSourceTemp& source = m_symbol_sources[name];
source.previous_value = value;
source.modified_by_user = true;
}
// Add any more symbol sources for which the user hasn't made a
// selection. These are separate since we don't want to have to store
// configuration data for them.
R5900SymbolGuardian.Read([&](const ccc::SymbolDatabase& database) {
for (const ccc::SymbolSource& symbol_source : database.symbol_sources)
{
if (m_symbol_sources.find(symbol_source.name()) == m_symbol_sources.end() && symbol_source.name() != "Built-In")
{
SymbolSourceTemp& source = m_symbol_sources[symbol_source.name()];
source.previous_value = SymbolImporter::ShouldClearSymbolsFromSourceByDefault(symbol_source.name());
source.modified_by_user = false;
}
}
});
if (m_symbol_sources.empty())
{
m_ui.symbolSourceErrorMessage->setText(tr("<i>No symbol sources in database.</i>"));
m_ui.symbolSourceScrollArea->hide();
return;
}
// Create the check boxes.
int i = 0;
for (auto& [name, temp] : m_symbol_sources)
{
temp.check_box = new QCheckBox(QString::fromStdString(name));
temp.check_box->setChecked(temp.previous_value);
layout->addWidget(temp.check_box, i / 2, i % 2);
connect(temp.check_box, &QCheckBox::checkStateChanged, this, &DebugAnalysisSettingsWidget::symbolSourceCheckStateChanged);
i++;
}
}
else
{
m_ui.symbolSourceErrorMessage->setText(tr("<i>Start this game to modify the symbol sources list.</i>"));
m_ui.symbolSourceScrollArea->hide();
return;
}
m_ui.symbolSourceErrorMessage->hide();
}
void DebugAnalysisSettingsWidget::symbolSourceCheckStateChanged()
{
QCheckBox* check_box = qobject_cast<QCheckBox*>(sender());
if (!check_box)
return;
auto temp = m_symbol_sources.find(check_box->text().toStdString());
if (temp == m_symbol_sources.end())
return;
temp->second.modified_by_user = true;
saveSymbolSources();
}
void DebugAnalysisSettingsWidget::saveSymbolSources()
{
if (!m_dialog)
return;
SettingsInterface* sif = m_dialog->getSettingsInterface();
if (!sif)
return;
// Clean up old configuration entries.
int old_count = sif->GetIntValue("Debugger/Analysis/SymbolSources", "Count");
for (int i = 0; i < old_count; i++)
{
std::string section = "Debugger/Analysis/SymbolSources/" + std::to_string(i);
sif->RemoveSection(section.c_str());
}
sif->RemoveSection("Debugger/Analysis/SymbolSources");
int symbol_sources_to_save = 0;
for (auto& [name, temp] : m_symbol_sources)
if (temp.modified_by_user)
symbol_sources_to_save++;
if (symbol_sources_to_save == 0)
return;
// Make new configuration entries.
sif->SetIntValue("Debugger/Analysis/SymbolSources", "Count", symbol_sources_to_save);
int i = 0;
for (auto& [name, temp] : m_symbol_sources)
{
if (!temp.modified_by_user)
continue;
std::string section = "Debugger/Analysis/SymbolSources/" + std::to_string(i);
sif->SetStringValue(section.c_str(), "Name", name.c_str());
sif->SetBoolValue(section.c_str(), "ClearDuringAnalysis", temp.check_box->isChecked());
i++;
}
}
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);
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));
}
connect(m_ui.addSymbolFile, &QPushButton::clicked, this, &DebugAnalysisSettingsWidget::addSymbolFile);
connect(m_ui.removeSymbolFile, &QPushButton::clicked, this, &DebugAnalysisSettingsWidget::removeSymbolFile);
}
void DebugAnalysisSettingsWidget::addSymbolFile()
{
QString path = QFileDialog::getOpenFileName(this, tr("Add Symbol File"));
if (path.isEmpty())
return;
m_ui.symbolFileList->addItem(path);
saveSymbolFiles();
}
void DebugAnalysisSettingsWidget::removeSymbolFile()
{
for (QListWidgetItem* item : m_ui.symbolFileList->selectedItems())
delete item;
saveSymbolFiles();
}
void DebugAnalysisSettingsWidget::saveSymbolFiles()
{
if (!m_dialog)
return;
SettingsInterface* sif = m_dialog->getSettingsInterface();
if (!sif)
return;
// Clean up old configuration entries.
int old_count = sif->GetIntValue("Debugger/Analysis/ExtraSymbolFiles", "Count");
for (int i = 0; i < old_count; i++)
{
std::string section = "Debugger/Analysis/ExtraSymbolFiles/" + std::to_string(i);
sif->RemoveSection(section.c_str());
}
sif->RemoveSection("Debugger/Analysis/ExtraSymbolFiles");
if (m_ui.symbolFileList->count() == 0)
return;
// Make new configuration entries.
sif->SetIntValue("Debugger/Analysis/ExtraSymbolFiles", "Count", m_ui.symbolFileList->count());
for (int i = 0; i < m_ui.symbolFileList->count(); 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());
}
QtHost::SaveGameSettings(sif, true);
g_emu_thread->reloadGameSettings();
}
void DebugAnalysisSettingsWidget::functionScanRangeChanged()
{
if (!m_dialog)
return;
SettingsInterface* sif = m_dialog->getSettingsInterface();
if (!sif)
return;
QString start_address = m_ui.addressRangeStart->text();
QString end_address = m_ui.addressRangeEnd->text();
bool ok;
if (start_address.toUInt(&ok, 16), ok)
sif->SetStringValue("Debugger/Analysis", "FunctionScanStartAddress", start_address.toStdString().c_str());
if (end_address.toUInt(&ok, 16), ok)
sif->SetStringValue("Debugger/Analysis", "FunctionScanEndAddress", end_address.toStdString().c_str());
}
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.customAddressRangeLineEdits->setEnabled(m_ui.customAddressRange->isChecked());
}
@@ -0,0 +1,56 @@
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
#pragma once
#include "ui_DebugAnalysisSettingsWidget.h"
#include "Config.h"
#include <QtWidgets/QDialog>
class SettingsWindow;
class DebugAnalysisSettingsWidget : public QWidget
{
Q_OBJECT
public:
// Create a widget that will discard any settings changed after it is
// closed, for use in the dialog opened by the "Reanalyze" button.
DebugAnalysisSettingsWidget(QWidget* parent = nullptr);
// Create a widget that will write back any settings changed to the config
// system, for use in the settings dialog.
DebugAnalysisSettingsWidget(SettingsWindow* dialog, QWidget* parent = nullptr);
// Read all the analysis settings from the widget tree and store them in the
// output object. This is used by the analysis options dialog to start an
// analysis run manually.
void parseSettingsFromWidgets(Pcsx2Config::DebugAnalysisOptions& output);
protected:
void setupSymbolSourceGrid();
void symbolSourceCheckStateChanged();
void saveSymbolSources();
void setupSymbolFileList();
void addSymbolFile();
void removeSymbolFile();
void saveSymbolFiles();
void functionScanRangeChanged();
void updateEnabledStates();
struct SymbolSourceTemp
{
QCheckBox* check_box = nullptr;
bool previous_value = false;
bool modified_by_user = false;
};
SettingsWindow* m_dialog = nullptr;
std::map<std::string, SymbolSourceTemp> m_symbol_sources;
Ui::DebugAnalysisSettingsWidget m_ui;
};
@@ -0,0 +1,407 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DebugAnalysisSettingsWidget</class>
<widget class="QWidget" name="DebugAnalysisSettingsWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>500</width>
<height>750</height>
</rect>
</property>
<property name="windowTitle">
<string/>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="clearExistingSymbolsGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Clear Existing Symbols</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QCheckBox" name="automaticallyClearSymbols">
<property name="text">
<string>Automatically Select Symbols To Clear</string>
</property>
</widget>
</item>
<item>
<widget class="QScrollArea" name="symbolSourceScrollArea">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>150</height>
</size>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="symbolSourceGrid">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>480</width>
<height>83</height>
</rect>
</property>
</widget>
</widget>
</item>
<item>
<widget class="QLabel" name="symbolSourceErrorMessage">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="importSymbolTablesGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Import Symbols</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QWidget" name="importSymbolTableCheckBoxes" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QGridLayout" name="importSymbolTableCheckBoxesLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QCheckBox" name="importFromElf">
<property name="text">
<string>Import From ELF</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="demangleSymbols">
<property name="text">
<string>Demangle Symbols</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="demangleParameters">
<property name="text">
<string>Demangle Parameters</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="importSymFileFromDefaultLocation">
<property name="text">
<string>Import Default .sym File</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="symbolFileLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Import from file (.elf, .sym, etc):</string>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="symbolFileList">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>100</height>
</size>
</property>
<property name="sortingEnabled">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="importSymbolFileButtons" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QHBoxLayout" name="importSymbolFileButtonsLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="importSymbolFileSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="addSymbolFile">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removeSymbolFile">
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="scanForFunctionsGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Scan For Functions</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QFormLayout" name="functionScanForm">
<item row="0" column="0">
<widget class="QLabel" name="functionScanLabel">
<property name="text">
<string>Scan Mode:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="functionScanMode">
<item>
<property name="text">
<string>Scan ELF</string>
</property>
</item>
<item>
<property name="text">
<string>Scan Memory</string>
</property>
</item>
<item>
<property name="text">
<string>Skip</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="customAddressRange">
<property name="text">
<string>Custom Address Range:</string>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="customAddressRangeLineEdits" native="true">
<layout class="QHBoxLayout" name="memoryRangeLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="startSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Maximum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="addressRangeStartLabel">
<property name="text">
<string>Start:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="addressRangeStart"/>
</item>
<item>
<widget class="QLabel" name="addressRangeEndLabel">
<property name="text">
<string>End:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="addressRangeEnd"/>
</item>
<item>
<spacer name="endSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Maximum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Hash Functions</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QCheckBox" name="grayOutOverwrittenFunctions">
<property name="text">
<string>Gray Out Symbols For Overwritten Functions</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+149
View File
@@ -2,6 +2,8 @@
// SPDX-License-Identifier: GPL-3.0+
#include "DebugSettingsWidget.h"
#include "DebugAnalysisSettingsWidget.h"
#include "QtUtils.h"
#include "SettingWidgetBinder.h"
#include "SettingsWindow.h"
@@ -18,6 +20,27 @@ DebugSettingsWidget::DebugSettingsWidget(SettingsWindow* dialog, QWidget* parent
m_ui.setupUi(this);
//////////////////////////////////////////////////////////////////////////
// Analysis Settings
//////////////////////////////////////////////////////////////////////////
SettingWidgetBinder::BindWidgetToEnumSetting(
sif, m_ui.analysisCondition, "Debugger/Analysis", "RunCondition",
Pcsx2Config::DebugAnalysisOptions::RunConditionNames, DebugAnalysisCondition::IF_DEBUGGER_IS_OPEN);
SettingWidgetBinder::BindWidgetToBoolSetting(
sif, m_ui.generateSymbolsForIRXExportTables, "Debugger/Analysis", "GenerateSymbolsForIRXExports", true);
dialog->registerWidgetHelp(m_ui.analysisCondition, tr("Analyze Program"), tr("If Debugger Is Open"),
tr("Choose when the analysis passes should be run: Always (to save time when opening the debugger), If "
"Debugger Is Open (to save memory if you never open the debugger), or Never."));
dialog->registerWidgetHelp(m_ui.generateSymbolsForIRXExportTables, tr("Generate Symbols for IRX Export Tables"), tr("Checked"),
tr("Hook IRX module loading/unloading and generate symbols for exported functions on the fly."));
m_analysis_settings = new DebugAnalysisSettingsWidget(dialog);
m_ui.analysisSettings->setLayout(new QVBoxLayout());
m_ui.analysisSettings->layout()->setContentsMargins(0, 0, 0, 0);
m_ui.analysisSettings->layout()->addWidget(m_analysis_settings);
//////////////////////////////////////////////////////////////////////////
// GS Settings
//////////////////////////////////////////////////////////////////////////
@@ -35,6 +58,88 @@ DebugSettingsWidget::DebugSettingsWidget(SettingsWindow* dialog, QWidget* parent
connect(m_ui.dumpGSDraws, &QCheckBox::checkStateChanged, this, &DebugSettingsWidget::onDrawDumpingChanged);
onDrawDumpingChanged();
#ifdef PCSX2_DEVBUILD
//////////////////////////////////////////////////////////////////////////
// Trace Logging Settings
//////////////////////////////////////////////////////////////////////////
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkEnable, "EmuCore/TraceLog", "Enabled", false);
dialog->registerWidgetHelp(m_ui.chkEnable, tr("Enable Trace Logging"), tr("Unchecked"), tr("Globally enable / disable trace logging."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkEEBIOS, "EmuCore/TraceLog", "EE.bios", false);
dialog->registerWidgetHelp(m_ui.chkEEBIOS, tr("EE BIOS"), tr("Unchecked"), tr("Log SYSCALL and DECI2 activity."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkEEMemory, "EmuCore/TraceLog", "EE.memory", false);
dialog->registerWidgetHelp(m_ui.chkEEMemory, tr("EE Memory"), tr("Unchecked"), tr("Log memory access to unknown or unmapped EE memory."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkEER5900, "EmuCore/TraceLog", "EE.r5900", false);
dialog->registerWidgetHelp(m_ui.chkEER5900, tr("EE R5900"), tr("Unchecked"), tr("Log R5900 core instructions (excluding COPs). Requires modifying the PCSX2 source and enabling the interpreter."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkEECOP0, "EmuCore/TraceLog", "EE.cop0", false);
dialog->registerWidgetHelp(m_ui.chkEECOP0, tr("EE COP0"), tr("Unchecked"), tr("Log COP0 (MMU, CPU status, etc) instructions."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkEECOP1, "EmuCore/TraceLog", "EE.cop1", false);
dialog->registerWidgetHelp(m_ui.chkEECOP1, tr("EE COP1"), tr("Unchecked"), tr("Log COP1 (FPU) instructions."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkEECOP2, "EmuCore/TraceLog", "EE.cop2", false);
dialog->registerWidgetHelp(m_ui.chkEECOP2, tr("EE COP2"), tr("Unchecked"), tr("Log COP2 (VU0 Macro mode) instructions."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkEECache, "EmuCore/TraceLog", "EE.cache", false);
dialog->registerWidgetHelp(m_ui.chkEECache, tr("EE Cache"), tr("Unchecked"), tr("Log EE cache activity."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkEEMMIO, "EmuCore/TraceLog", "EE.knownhw", false);
dialog->registerWidgetHelp(m_ui.chkEEMMIO, tr("EE Known MMIO"), tr("Unchecked"), tr("Log known MMIO accesses."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkEEUNKNWNMMIO, "EmuCore/TraceLog", "EE.unknownhw", false);
dialog->registerWidgetHelp(m_ui.chkEEUNKNWNMMIO, tr("EE Unknown MMIO"), tr("Unchecked"), tr("Log unknown or unimplemented MMIO accesses."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkEEDMARegs, "EmuCore/TraceLog", "EE.dmahw", false);
dialog->registerWidgetHelp(m_ui.chkEEDMARegs, tr("EE DMA Registers"), tr("Unchecked"), tr("Log DMA-related MMIO accesses."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkEEIPU, "EmuCore/TraceLog", "EE.ipu", false);
dialog->registerWidgetHelp(m_ui.chkEEIPU, tr("EE IPU"), tr("Unchecked"), tr("Log IPU activity; MMIO, decoding operations, DMA status, etc."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkEEGIFTags, "EmuCore/TraceLog", "EE.giftag", false);
dialog->registerWidgetHelp(m_ui.chkEEGIFTags, tr("EE GIF Tags"), tr("Unchecked"), tr("Log GIFtag parsing activity."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkEEVIFCodes, "EmuCore/TraceLog", "EE.vifcode", false);
dialog->registerWidgetHelp(m_ui.chkEEVIFCodes, tr("EE VIF Codes"), tr("Unchecked"), tr("Log VIFcode processing; command, tag style, interrupts."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkEEMSKPATH3, "EmuCore/TraceLog", "EE.mskpath3", false);
dialog->registerWidgetHelp(m_ui.chkEEMSKPATH3, tr("EE MSKPATH3"), tr("Unchecked"), tr("Log Path3 Masking processing."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkEEMFIFO, "EmuCore/TraceLog", "EE.spr", false);
dialog->registerWidgetHelp(m_ui.chkEEMFIFO, tr("EE MFIFO"), tr("Unchecked"), tr("Log Scratchpad MFIFO activity."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkEEDMACTRL, "EmuCore/TraceLog", "EE.dmac", false);
dialog->registerWidgetHelp(m_ui.chkEEDMACTRL, tr("EE DMA Controller"), tr("Unchecked"), tr("Log DMA transfer activity. Stalls, bus right arbitration, etc."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkEECounters, "EmuCore/TraceLog", "EE.counters", false);
dialog->registerWidgetHelp(m_ui.chkEECounters, tr("EE Counters"), tr("Unchecked"), tr("Log all EE counters events and some counter register activity."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkEEVIF, "EmuCore/TraceLog", "EE.vif", false);
dialog->registerWidgetHelp(m_ui.chkEEVIF, tr("EE VIF"), tr("Unchecked"), tr("Log various VIF and VIFcode processing data."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkEEGIF, "EmuCore/TraceLog", "EE.gif", false);
dialog->registerWidgetHelp(m_ui.chkEEGIF, tr("EE GIF"), tr("Unchecked"), tr("Log various GIF and GIFtag parsing data."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkIOPBIOS, "EmuCore/TraceLog", "IOP.Bios", false);
dialog->registerWidgetHelp(m_ui.chkIOPBIOS, tr("IOP BIOS"), tr("Unchecked"), tr("Log SYSCALL and IRX activity."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkIOPMemcards, "EmuCore/TraceLog", "IOP.memcards", false);
dialog->registerWidgetHelp(m_ui.chkIOPMemcards, tr("IOP Memcards"), tr("Unchecked"), tr("Log memory card activity. Reads, Writes, erases, etc."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkIOPR3000A, "EmuCore/TraceLog", "IOP.r3000a", false);
dialog->registerWidgetHelp(m_ui.chkIOPR3000A, tr("IOP R3000A"), tr("Unchecked"), tr("Log R3000A core instructions (excluding COPs)."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkIOPCOP2, "EmuCore/TraceLog", "IOP.cop2", false);
dialog->registerWidgetHelp(m_ui.chkIOPCOP2, tr("IOP COP2"), tr("Unchecked"), tr("Log IOP GPU co-processor instructions."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkIOPMMIO, "EmuCore/TraceLog", "IOP.knownhw", false);
dialog->registerWidgetHelp(m_ui.chkIOPMMIO, tr("IOP Known MMIO"), tr("Unchecked"), tr("Log known MMIO accesses."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkIOPUNKNWNMMIO, "EmuCore/TraceLog", "IOP.unknownhw", false);
dialog->registerWidgetHelp(m_ui.chkIOPUNKNWNMMIO, tr("IOP Unknown MMIO"), tr("Unchecked"), tr("Log unknown or unimplemented MMIO accesses."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkIOPDMARegs, "EmuCore/TraceLog", "IOP.dmahw", false);
dialog->registerWidgetHelp(m_ui.chkIOPDMARegs, tr("IOP DMA Registers"), tr("Unchecked"), tr("Log DMA-related MMIO accesses."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkIOPPad, "EmuCore/TraceLog", "IOP.pad", false);
dialog->registerWidgetHelp(m_ui.chkIOPPad, tr("IOP PAD"), tr("Unchecked"), tr("Log PAD activity."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkIOPDMACTRL, "EmuCore/TraceLog", "IOP.dmac", false);
dialog->registerWidgetHelp(m_ui.chkIOPDMACTRL, tr("IOP DMA Controller"), tr("Unchecked"), tr("Log DMA transfer activity. Stalls, bus right arbitration, etc."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkIOPCounters, "EmuCore/TraceLog", "IOP.counters", false);
dialog->registerWidgetHelp(m_ui.chkIOPCounters, tr("IOP Counters"), tr("Unchecked"), tr("Log all IOP counters events and some counter register activity."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkIOPCDVD, "EmuCore/TraceLog", "IOP.cdvd", false);
dialog->registerWidgetHelp(m_ui.chkIOPCDVD, tr("IOP CDVD"), tr("Unchecked"), tr("Log CDVD hardware activity."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkIOPMDEC, "EmuCore/TraceLog", "IOP.mdec", false);
dialog->registerWidgetHelp(m_ui.chkIOPMDEC, tr("IOP MDEC"), tr("Unchecked"), tr("Log Motion (FMV) Decoder hardware unit activity."));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chkEESIF, "EmuCore/TraceLog", "MISC.sif", false);
dialog->registerWidgetHelp(m_ui.chkEESIF, tr("EE SIF"), tr("Unchecked"), tr("Log SIF (EE <-> IOP) activity."));
connect(m_ui.chkEnable, &QCheckBox::checkStateChanged, this, &DebugSettingsWidget::onLoggingEnableChanged);
onLoggingEnableChanged();
#else
m_ui.debugTabs->removeTab(m_ui.debugTabs->indexOf(m_ui.traceLogTabWidget));
#endif
}
DebugSettingsWidget::~DebugSettingsWidget() = default;
@@ -47,3 +152,47 @@ void DebugSettingsWidget::onDrawDumpingChanged()
m_ui.saveTexture->setEnabled(enabled);
m_ui.saveDepth->setEnabled(enabled);
}
#ifdef PCSX2_DEVBUILD
void DebugSettingsWidget::onLoggingEnableChanged()
{
const bool enabled = m_dialog->getEffectiveBoolValue("EmuCore/TraceLog", "Enabled", false);
m_ui.chkEEBIOS->setEnabled(enabled);
m_ui.chkEEMemory->setEnabled(enabled);
m_ui.chkEER5900->setEnabled(enabled);
m_ui.chkEECOP0->setEnabled(enabled);
m_ui.chkEECOP1->setEnabled(enabled);
m_ui.chkEECOP2->setEnabled(enabled);
m_ui.chkEECache->setEnabled(enabled);
m_ui.chkEEMMIO->setEnabled(enabled);
m_ui.chkEEUNKNWNMMIO->setEnabled(enabled);
m_ui.chkEEDMARegs->setEnabled(enabled);
m_ui.chkEEIPU->setEnabled(enabled);
m_ui.chkEEGIFTags->setEnabled(enabled);
m_ui.chkEEVIFCodes->setEnabled(enabled);
m_ui.chkEEMSKPATH3->setEnabled(enabled);
m_ui.chkEEMFIFO->setEnabled(enabled);
m_ui.chkEEDMACTRL->setEnabled(enabled);
m_ui.chkEECounters->setEnabled(enabled);
m_ui.chkEEVIF->setEnabled(enabled);
m_ui.chkEEGIF->setEnabled(enabled);
m_ui.chkEESIF->setEnabled(enabled);
m_ui.chkIOPBIOS->setEnabled(enabled);
m_ui.chkIOPMemcards->setEnabled(enabled);
m_ui.chkIOPR3000A->setEnabled(enabled);
m_ui.chkIOPCOP2->setEnabled(enabled);
m_ui.chkIOPMMIO->setEnabled(enabled);
m_ui.chkIOPUNKNWNMMIO->setEnabled(enabled);
m_ui.chkIOPDMARegs->setEnabled(enabled);
m_ui.chkIOPMemcards->setEnabled(enabled);
m_ui.chkIOPPad->setEnabled(enabled);
m_ui.chkIOPDMACTRL->setEnabled(enabled);
m_ui.chkIOPCounters->setEnabled(enabled);
m_ui.chkIOPCDVD->setEnabled(enabled);
m_ui.chkIOPMDEC->setEnabled(enabled);
g_emu_thread->applySettings();
}
#endif
+5
View File
@@ -8,6 +8,7 @@
#include "ui_DebugSettingsWidget.h"
class SettingsWindow;
class DebugAnalysisSettingsWidget;
class DebugSettingsWidget : public QWidget
{
@@ -19,9 +20,13 @@ public:
private Q_SLOTS:
void onDrawDumpingChanged();
#ifdef PCSX2_DEVBUILD
void onLoggingEnableChanged();
#endif
private:
SettingsWindow* m_dialog;
DebugAnalysisSettingsWidget* m_analysis_settings;
Ui::DebugSettingsWidget m_ui;
};
+413 -16
View File
@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>861</width>
<width>527</width>
<height>501</height>
</rect>
</property>
@@ -24,20 +24,136 @@
<number>0</number>
</property>
<item>
<widget class="QTabWidget" name="gsTab">
<widget class="QTabWidget" name="debugTabs">
<property name="currentIndex">
<number>0</number>
</property>
<property name="documentMode">
<bool>true</bool>
</property>
<widget class="QWidget" name="analysisTabWidget">
<attribute name="title">
<string>Analysis</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_6">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QScrollArea" name="analysisScrollArea">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="analysisScrollAreaContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>523</width>
<height>464</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="analysisLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>These settings control what and when analysis passes should be performed on the program running in the virtual machine so that the resultant information can be shown in the debugger.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="analysisGroupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Analysis</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QFormLayout" name="analysisForm">
<item row="0" column="0">
<widget class="QLabel" name="analysisConditionLabel">
<property name="text">
<string>Automatically Analyze Program:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="analysisCondition">
<item>
<property name="text">
<string>Always</string>
</property>
</item>
<item>
<property name="text">
<string>If Debugger Is Open</string>
</property>
</item>
<item>
<property name="text">
<string>Never</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="generateSymbolsForIRXExportTables">
<property name="text">
<string>Generate Symbols For IRX Exports</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="analysisSettings" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="gsTabWidget">
<attribute name="title">
<string>GS</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox">
<widget class="QGroupBox" name="drawDumpingGroupBox">
<property name="title">
<string>Draw Dumping</string>
</property>
@@ -173,21 +289,302 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="traceLogTabWidget">
<attribute name="title">
<string>Trace Logging</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="QCheckBox" name="chkEnable">
<property name="text">
<string>Enable</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="traceLogHorizontalLayout">
<item>
<widget class="QGroupBox" name="grpEELogging">
<property name="title">
<string>EE</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QGridLayout" name="grpEELoggingGrid">
<item row="4" column="1">
<widget class="QCheckBox" name="chkEEDMACTRL">
<property name="text">
<string>DMA Control</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QCheckBox" name="chkEEMFIFO">
<property name="text">
<string>SPR / MFIFO</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QCheckBox" name="chkEEVIF">
<property name="text">
<string>VIF</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="chkEECOP1">
<property name="text">
<string>COP1 (FPU)</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="chkEEMSKPATH3">
<property name="text">
<string>MSKPATH3</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="chkEECache">
<property name="text">
<string>Cache</string>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QCheckBox" name="chkEEGIF">
<property name="text">
<string>GIF</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="chkEER5900">
<property name="text">
<string>R5900</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="chkEECOP0">
<property name="text">
<string>COP0</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="chkEEMMIO">
<property name="text">
<string>HW Regs (MMIO)</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QCheckBox" name="chkEECounters">
<property name="text">
<string>Counters</string>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QCheckBox" name="chkEESIF">
<property name="text">
<string>SIF</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="chkEECOP2">
<property name="text">
<string>COP2 (VU0 Macro)</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QCheckBox" name="chkEEVIFCodes">
<property name="text">
<string>VIFCodes</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="chkEEMemory">
<property name="text">
<string>Memory</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="chkEEUNKNWNMMIO">
<property name="text">
<string>Unknown MMIO</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QCheckBox" name="chkEEIPU">
<property name="text">
<string>IPU</string>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QCheckBox" name="chkEEBIOS">
<property name="text">
<string>BIOS</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="chkEEDMARegs">
<property name="text">
<string>DMA Registers</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QCheckBox" name="chkEEGIFTags">
<property name="text">
<string>GIFTags</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="eeLoggingSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="grpIOPLogging">
<property name="title">
<string>IOP</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<layout class="QGridLayout" name="grpIOPLoggingGrid">
<item row="4" column="0">
<widget class="QCheckBox" name="chkIOPCounters">
<property name="text">
<string>Counters</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="chkIOPUNKNWNMMIO">
<property name="text">
<string>Unknown MMIO</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="chkIOPMMIO">
<property name="text">
<string>HW Regs (MMIO)</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="chkIOPCDVD">
<property name="text">
<string>CDVD</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="chkIOPR3000A">
<property name="text">
<string>R3000A</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="chkIOPMemcards">
<property name="text">
<string>Memcards</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="chkIOPDMARegs">
<property name="text">
<string>DMA Registers</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="chkIOPPad">
<property name="text">
<string>Pad</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="chkIOPBIOS">
<property name="text">
<string>BIOS</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="chkIOPMDEC">
<property name="text">
<string>MDEC</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="chkIOPDMACTRL">
<property name="text">
<string>DMA Control</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="chkIOPCOP2">
<property name="text">
<string>COP2 (GPU)</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="iopLoggingSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>60</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
+94 -43
View File
@@ -13,25 +13,49 @@
#include "common/HeterogeneousContainers.h"
#include <QtCore/QSortFilterProxyModel>
#include <QtGui/QStandardItemModel>
GameCheatSettingsWidget::GameCheatSettingsWidget(SettingsWindow* dialog, QWidget* parent)
: m_dialog(dialog)
{
m_ui.setupUi(this);
m_model = new QStandardItemModel(this);
QStringList headers;
headers.push_back(tr("Name"));
headers.push_back(tr("Author"));
headers.push_back(tr("Description"));
m_model->setHorizontalHeaderLabels(headers);
m_model_proxy = new QSortFilterProxyModel(this);
m_model_proxy->setSourceModel(m_model);
m_model_proxy->setRecursiveFilteringEnabled(true);
m_model_proxy->setAutoAcceptChildRows(true);
m_model_proxy->setFilterCaseSensitivity(Qt::CaseInsensitive);
m_ui.cheatList->setModel(m_model_proxy);
reloadList();
m_ui.cheatList->expandAll();
SettingsInterface* sif = m_dialog->getSettingsInterface();
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableCheats, "EmuCore", "EnableCheats", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.allCRCsCheckbox, "EmuCore", "ShowCheatsForAllCRCs", false);
updateListEnabled();
connect(m_ui.enableCheats, &QCheckBox::checkStateChanged, this, &GameCheatSettingsWidget::updateListEnabled);
connect(m_ui.cheatList, &QTreeWidget::itemDoubleClicked, this, &GameCheatSettingsWidget::onCheatListItemDoubleClicked);
connect(m_ui.cheatList, &QTreeWidget::itemChanged, this, &GameCheatSettingsWidget::onCheatListItemChanged);
connect(m_ui.cheatList, &QTreeView::doubleClicked, this, &GameCheatSettingsWidget::onCheatListItemDoubleClicked);
connect(m_model, &QStandardItemModel::itemChanged, this, &GameCheatSettingsWidget::onCheatListItemChanged);
connect(m_ui.reloadCheats, &QPushButton::clicked, this, &GameCheatSettingsWidget::onReloadClicked);
connect(m_ui.enableAll, &QPushButton::clicked, this, [this]() { setStateForAll(true); });
connect(m_ui.disableAll, &QPushButton::clicked, this, [this]() { setStateForAll(false); });
connect(m_ui.allCRCsCheckbox, &QCheckBox::checkStateChanged, this, &GameCheatSettingsWidget::onReloadClicked);
connect(m_ui.searchText, &QLineEdit::textChanged, this, [this](const QString& text) {
m_model_proxy->setFilterFixedString(text);
m_ui.cheatList->expandAll();
});
dialog->registerWidgetHelp(m_ui.allCRCsCheckbox, tr("Show Cheats For All CRCs"), tr("Checked"),
tr("Toggles scanning patch files for all CRCs of the game. With this enabled available patches for the game serial with different CRCs will also be loaded."));
@@ -39,28 +63,45 @@ GameCheatSettingsWidget::GameCheatSettingsWidget(SettingsWindow* dialog, QWidget
GameCheatSettingsWidget::~GameCheatSettingsWidget() = default;
void GameCheatSettingsWidget::onCheatListItemDoubleClicked(QTreeWidgetItem* item, int column)
void GameCheatSettingsWidget::onCheatListItemDoubleClicked(const QModelIndex& index)
{
QVariant data = item->data(0, Qt::UserRole);
const QModelIndex source_index = m_model_proxy->mapToSource(index);
const QModelIndex sibling_index = source_index.sibling(source_index.row(), 0);
QStandardItem* item = m_model->itemFromIndex(sibling_index);
if (!item)
return;
if (item->hasChildren() && index.column() != 0)
{
const QModelIndex view_sibling_index = index.sibling(index.row(), 0);
const bool isExpanded = m_ui.cheatList->isExpanded(view_sibling_index);
if (isExpanded)
m_ui.cheatList->collapse(view_sibling_index);
else
m_ui.cheatList->expand(view_sibling_index);
return;
}
QVariant data = item->data(Qt::UserRole);
if (!data.isValid())
return;
std::string cheat_name = data.toString().toStdString();
const bool new_state = !(item->checkState(0) == Qt::Checked);
item->setCheckState(0, new_state ? Qt::Checked : Qt::Unchecked);
const bool new_state = !(item->checkState() == Qt::Checked);
item->setCheckState(new_state ? Qt::Checked : Qt::Unchecked);
setCheatEnabled(std::move(cheat_name), new_state, true);
}
void GameCheatSettingsWidget::onCheatListItemChanged(QTreeWidgetItem* item, int column)
void GameCheatSettingsWidget::onCheatListItemChanged(QStandardItem* item)
{
QVariant data = item->data(0, Qt::UserRole);
QVariant data = item->data(Qt::UserRole);
if (!data.isValid())
return;
std::string cheat_name = data.toString().toStdString();
const bool current_enabled =
(std::find(m_enabled_patches.begin(), m_enabled_patches.end(), cheat_name) != m_enabled_patches.end());
const bool current_checked = (item->checkState(0) == Qt::Checked);
const bool current_checked = (item->checkState() == Qt::Checked);
if (current_enabled == current_checked)
return;
@@ -70,6 +111,7 @@ void GameCheatSettingsWidget::onCheatListItemChanged(QTreeWidgetItem* item, int
void GameCheatSettingsWidget::onReloadClicked()
{
reloadList();
m_ui.cheatList->expandAll();
// reload it on the emu thread too, so it picks up any changes
g_emu_thread->reloadPatches();
@@ -83,6 +125,7 @@ void GameCheatSettingsWidget::updateListEnabled()
m_ui.disableAll->setEnabled(cheats_enabled);
m_ui.reloadCheats->setEnabled(cheats_enabled);
m_ui.allCRCsCheckbox->setEnabled(cheats_enabled);
m_ui.searchText->setEnabled(cheats_enabled);
}
void GameCheatSettingsWidget::disableAllCheats()
@@ -125,24 +168,28 @@ void GameCheatSettingsWidget::setCheatEnabled(std::string name, bool enabled, bo
void GameCheatSettingsWidget::setStateForAll(bool enabled)
{
QSignalBlocker sb(m_ui.cheatList);
// Temporarily disconnect from itemChanged to prevent redundant saves
disconnect(m_model, &QStandardItemModel::itemChanged, this, &GameCheatSettingsWidget::onCheatListItemChanged);
setStateRecursively(nullptr, enabled);
m_dialog->getSettingsInterface()->Save();
g_emu_thread->reloadGameSettings();
connect(m_model, &QStandardItemModel::itemChanged, this, &GameCheatSettingsWidget::onCheatListItemChanged);
}
void GameCheatSettingsWidget::setStateRecursively(QTreeWidgetItem* parent, bool enabled)
void GameCheatSettingsWidget::setStateRecursively(QStandardItem* parent, bool enabled)
{
const int count = parent ? parent->childCount() : m_ui.cheatList->topLevelItemCount();
const int count = parent ? parent->rowCount() : m_model->rowCount();
for (int i = 0; i < count; i++)
{
QTreeWidgetItem* item = parent ? parent->child(i) : m_ui.cheatList->topLevelItem(i);
QVariant data = item->data(0, Qt::UserRole);
QStandardItem* item = parent ? parent->child(i, 0) : m_model->item(i, 0);
QVariant data = item->data(Qt::UserRole);
if (data.isValid())
{
if ((item->checkState(0) == Qt::Checked) != enabled)
if ((item->checkState() == Qt::Checked) != enabled)
{
item->setCheckState(0, enabled ? Qt::Checked : Qt::Unchecked);
item->setCheckState(enabled ? Qt::Checked : Qt::Unchecked);
setCheatEnabled(data.toString().toStdString(), enabled, false);
}
}
@@ -162,8 +209,7 @@ void GameCheatSettingsWidget::reloadList()
m_dialog->getSettingsInterface()->GetStringList(Patch::CHEATS_CONFIG_SECTION, Patch::PATCH_ENABLE_CONFIG_KEY);
m_parent_map.clear();
while (m_ui.cheatList->topLevelItemCount() > 0)
delete m_ui.cheatList->takeTopLevelItem(0);
m_model->removeRows(0, m_model->rowCount());
for (const Patch::PatchInfo& pi : m_patches)
{
@@ -171,14 +217,12 @@ void GameCheatSettingsWidget::reloadList()
(std::find(m_enabled_patches.begin(), m_enabled_patches.end(), pi.name) != m_enabled_patches.end());
const std::string_view parent_part = pi.GetNameParentPart();
QTreeWidgetItem* parent = getTreeWidgetParent(parent_part);
QTreeWidgetItem* item = new QTreeWidgetItem();
populateTreeWidgetItem(item, pi, enabled);
QStandardItem* parent = getTreeViewParent(parent_part);
QList<QStandardItem*> items = populateTreeViewRow(pi, enabled);
if (parent)
parent->addChild(item);
parent->appendRow(items);
else
m_ui.cheatList->addTopLevelItem(item);
m_model->appendRow(items);
}
// Hide root indicator when there's no groups, frees up some whitespace.
@@ -186,13 +230,13 @@ void GameCheatSettingsWidget::reloadList()
if (num_unlabelled_codes > 0)
{
QTreeWidgetItem* item = new QTreeWidgetItem();
item->setText(0, tr("%1 unlabelled patch codes will automatically activate.").arg(num_unlabelled_codes));
m_ui.cheatList->addTopLevelItem(item);
QStandardItem* item = new QStandardItem();
item->setText(tr("%1 unlabelled patch codes will automatically activate.").arg(num_unlabelled_codes));
m_model->appendRow(item);
}
}
QTreeWidgetItem* GameCheatSettingsWidget::getTreeWidgetParent(const std::string_view parent)
QStandardItem* GameCheatSettingsWidget::getTreeViewParent(const std::string_view parent)
{
if (parent.empty())
return nullptr;
@@ -202,37 +246,44 @@ QTreeWidgetItem* GameCheatSettingsWidget::getTreeWidgetParent(const std::string_
return it->second;
std::string_view this_part = parent;
QTreeWidgetItem* parent_to_this = nullptr;
QStandardItem* parent_to_this = nullptr;
const std::string_view::size_type pos = parent.rfind('\\');
if (pos != std::string::npos && pos != (parent.size() - 1))
{
// go up the chain until we find the real parent, then back down
parent_to_this = getTreeWidgetParent(parent.substr(0, pos));
parent_to_this = getTreeViewParent(parent.substr(0, pos));
this_part = parent.substr(pos + 1);
}
QTreeWidgetItem* item = new QTreeWidgetItem();
item->setText(0, QString::fromUtf8(this_part.data(), this_part.length()));
QStandardItem* item = new QStandardItem();
item->setText(QString::fromUtf8(this_part.data(), this_part.length()));
if (parent_to_this)
parent_to_this->addChild(item);
parent_to_this->appendRow(item);
else
m_ui.cheatList->addTopLevelItem(item);
m_model->appendRow(item);
// Must be called after adding.
item->setExpanded(true);
m_parent_map.emplace(parent, item);
return item;
}
void GameCheatSettingsWidget::populateTreeWidgetItem(QTreeWidgetItem* item, const Patch::PatchInfo& pi, bool enabled)
QList<QStandardItem*> GameCheatSettingsWidget::populateTreeViewRow(const Patch::PatchInfo& pi, bool enabled)
{
QList<QStandardItem*> items;
QStandardItem* nameItem = new QStandardItem();
const std::string_view name_part = pi.GetNamePart();
item->setFlags(item->flags() | Qt::ItemIsUserCheckable | Qt::ItemNeverHasChildren);
item->setCheckState(0, enabled ? Qt::Checked : Qt::Unchecked);
item->setData(0, Qt::UserRole, QString::fromStdString(pi.name));
nameItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemNeverHasChildren | Qt::ItemIsEnabled);
nameItem->setCheckState(enabled ? Qt::Checked : Qt::Unchecked);
nameItem->setData(QString::fromStdString(pi.name), Qt::UserRole);
if (!name_part.empty())
item->setText(0, QString::fromUtf8(name_part.data(), name_part.length()));
item->setText(1, QString::fromStdString(pi.author));
item->setText(2, QString::fromStdString(pi.description));
nameItem->setText(QString::fromUtf8(name_part.data(), name_part.length()));
QStandardItem* authorItem = new QStandardItem(QString::fromStdString(pi.author));
QStandardItem* descriptionItem = new QStandardItem(QString::fromStdString(pi.description));
items.push_back(nameItem);
items.push_back(authorItem);
items.push_back(descriptionItem);
return items;
}
+10 -7
View File
@@ -3,7 +3,8 @@
#pragma once
#include <QtWidgets/QWidget>
#include <QtGui/QStandardItemModel>
#include <QtCore/QSortFilterProxyModel>
#include "ui_GameCheatSettingsWidget.h"
@@ -36,23 +37,25 @@ protected:
void resizeEvent(QResizeEvent* event) override;
private Q_SLOTS:
void onCheatListItemDoubleClicked(QTreeWidgetItem* item, int column);
void onCheatListItemChanged(QTreeWidgetItem* item, int column);
void onCheatListItemDoubleClicked(const QModelIndex& index);
void onCheatListItemChanged(QStandardItem* item);
void onReloadClicked();
void updateListEnabled();
void reloadList();
private:
QTreeWidgetItem* getTreeWidgetParent(const std::string_view parent);
void populateTreeWidgetItem(QTreeWidgetItem* item, const Patch::PatchInfo& pi, bool enabled);
QStandardItem* getTreeViewParent(const std::string_view parent);
QList<QStandardItem*> populateTreeViewRow(const Patch::PatchInfo& pi, bool enabled);
void setCheatEnabled(std::string name, bool enabled, bool save_and_reload_settings);
void setStateForAll(bool enabled);
void setStateRecursively(QTreeWidgetItem* parent, bool enabled);
void setStateRecursively(QStandardItem* parent, bool enabled);
Ui::GameCheatSettingsWidget m_ui;
SettingsWindow* m_dialog;
QStandardItemModel* m_model = nullptr;
QSortFilterProxyModel* m_model_proxy = nullptr;
UnorderedStringMap<QTreeWidgetItem*> m_parent_map;
UnorderedStringMap<QStandardItem*> m_parent_map;
std::vector<Patch::PatchInfo> m_patches;
std::vector<std::string> m_enabled_patches;
};
+17 -21
View File
@@ -34,14 +34,25 @@
</widget>
</item>
<item>
<widget class="QCheckBox" name="enableCheats">
<property name="text">
<string>Enable Cheats</string>
</property>
</widget>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QCheckBox" name="enableCheats">
<property name="text">
<string>Enable Cheats</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="searchText">
<property name="placeholderText">
<string>Search...</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTreeWidget" name="cheatList">
<widget class="QTreeView" name="cheatList">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
@@ -51,21 +62,6 @@
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectItems</enum>
</property>
<column>
<property name="text">
<string>Name</string>
</property>
</column>
<column>
<property name="text">
<string>Author</string>
</property>
</column>
<column>
<property name="text">
<string>Description</string>
</property>
</column>
</widget>
</item>
<item>
+4 -2
View File
@@ -931,12 +931,14 @@ void GraphicsSettingsWidget::onPerformancePosChanged()
{
const bool enabled = m_ui.osdPerformancePos->currentIndex() != (m_dialog->isPerGameSettings() ? 1 : 0);
m_ui.osdShowVPS->setEnabled(enabled);
m_ui.osdShowSpeed->setEnabled(enabled);
m_ui.osdShowFPS->setEnabled(enabled);
m_ui.osdShowCPU->setEnabled(enabled);
m_ui.osdShowGPU->setEnabled(enabled);
m_ui.osdShowResolution->setEnabled(enabled);
m_ui.osdShowGSStats->setEnabled(enabled);
m_ui.osdShowHardwareInfo->setEnabled(enabled);
m_ui.osdShowIndicators->setEnabled(enabled);
m_ui.osdShowFrameTimes->setEnabled(enabled);
m_ui.osdShowVersion->setEnabled(enabled);
@@ -1137,13 +1139,13 @@ void GraphicsSettingsWidget::updateRendererDependentOptions()
std::string current_adapter = Host::GetBaseStringSettingValue("EmuCore/GS", "Adapter", "");
m_ui.adapterDropdown->clear();
m_ui.adapterDropdown->setEnabled(!adapters.empty());
m_ui.adapterDropdown->addItem(tr("(Default)"));
m_ui.adapterDropdown->addItem(GetDefaultAdapter().c_str());
m_ui.adapterDropdown->setCurrentIndex(0);
if (m_dialog->isPerGameSettings())
{
m_ui.adapterDropdown->insertItem(
0, tr("Use Global Setting [%1]").arg(current_adapter.empty() ? tr("(Default)") : QString::fromStdString(current_adapter)));
0, tr("Use Global Setting [%1]").arg(current_adapter.empty() ? GetDefaultAdapter().c_str() : QString::fromStdString(current_adapter)));
if (!m_dialog->getSettingsInterface()->GetStringValue("EmuCore/GS", "Adapter", &current_adapter))
{
// clear the adapter so we don't set it to the global value
+70 -70
View File
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>720</width>
<height>562</height>
<height>594</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
@@ -1632,6 +1632,13 @@
</item>
<item row="3" column="0" colspan="2">
<layout class="QGridLayout" name="osdOptionLayout">
<item row="2" column="1">
<widget class="QCheckBox" name="osdShowSpeed">
<property name="text">
<string>Show Speed Percentages</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QCheckBox" name="osdShowVideoCapture">
<property name="text">
@@ -1639,13 +1646,6 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="osdShowGPU">
<property name="text">
<string>Show GPU Usage</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="osdShowInputRec">
<property name="text">
@@ -1653,48 +1653,6 @@
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="osdShowInputs">
<property name="text">
<string>Show Inputs</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="osdShowSpeed">
<property name="text">
<string>Show Speed Percentages</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="osdShowHardwareInfo">
<property name="text">
<string>Show Hardware Info</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="osdShowFrameTimes">
<property name="text">
<string>Show Frame Times</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="osdShowSettings">
<property name="text">
<string>Show Settings</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QCheckBox" name="warnAboutUnsafeSettings">
<property name="text">
<string>Warn About Unsafe Settings</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="osdShowIndicators">
<property name="text">
@@ -1702,20 +1660,6 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="osdShowCPU">
<property name="text">
<string>Show CPU Usage</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="osdShowGSStats">
<property name="text">
<string>Show Statistics</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="osdShowFPS">
<property name="text">
@@ -1723,10 +1667,52 @@
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QCheckBox" name="osdShowVersion">
<item row="0" column="0">
<widget class="QCheckBox" name="osdShowVPS">
<property name="text">
<string>Show PCSX2 Version</string>
<string>Show VPS</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="osdShowInputs">
<property name="text">
<string>Show Inputs</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="osdShowHardwareInfo">
<property name="text">
<string>Show Hardware Info</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="osdShowGPU">
<property name="text">
<string>Show GPU Usage</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="osdShowCPU">
<property name="text">
<string>Show CPU Usage</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="osdShowSettings">
<property name="text">
<string>Show Settings</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="osdShowFrameTimes">
<property name="text">
<string>Show Frame Times</string>
</property>
</widget>
</item>
@@ -1737,10 +1723,24 @@
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="osdShowVPS">
<item row="4" column="0">
<widget class="QCheckBox" name="osdShowGSStats">
<property name="text">
<string>Show VPS</string>
<string>Show Statistics</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QCheckBox" name="osdShowVersion">
<property name="text">
<string>Show PCSX2 Version</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QCheckBox" name="warnAboutUnsafeSettings">
<property name="text">
<string>Warn About Unsafe Settings</string>
</property>
</widget>
</item>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+12
View File
@@ -97,6 +97,7 @@
<ClCompile Include="EarlyHardwareCheck.cpp" />
<ClCompile Include="LogWindow.cpp" />
<ClCompile Include="QtProgressCallback.cpp" />
<ClCompile Include="Settings\DebugAnalysisSettingsWidget.cpp" />
<ClCompile Include="Settings\DebugSettingsWidget.cpp" />
<ClCompile Include="Settings\FolderSettingsWidget.cpp" />
<ClCompile Include="Settings\GameCheatSettingsWidget.cpp" />
@@ -106,6 +107,7 @@
<ClCompile Include="Themes.cpp" />
<ClCompile Include="Tools\InputRecording\InputRecordingViewer.cpp" />
<ClCompile Include="Tools\InputRecording\NewInputRecordingDlg.cpp" />
<ClCompile Include="Debugger\AnalysisOptionsDialog.cpp" />
<ClCompile Include="Debugger\CpuWidget.cpp" />
<ClCompile Include="Debugger\DebuggerWindow.cpp" />
<ClCompile Include="Debugger\DisassemblyWidget.cpp" />
@@ -192,6 +194,7 @@
<QtMoc Include="Debugger\SymbolTree\TypeString.h" />
<ClInclude Include="Settings\ControllerSettingWidgetBinder.h" />
<QtMoc Include="Settings\FolderSettingsWidget.h" />
<QtMoc Include="Settings\DebugAnalysisSettingsWidget.h" />
<QtMoc Include="Settings\DebugSettingsWidget.h" />
<QtMoc Include="Settings\GameCheatSettingsWidget.h" />
<QtMoc Include="Settings\GamePatchSettingsWidget.h" />
@@ -206,6 +209,7 @@
<QtMoc Include="Tools\InputRecording\NewInputRecordingDlg.h" />
<QtMoc Include="Tools\InputRecording\InputRecordingViewer.h" />
<ClInclude Include="QtUtils.h" />
<QtMoc Include="Debugger\AnalysisOptionsDialog.h" />
<QtMoc Include="Debugger\CpuWidget.h" />
<QtMoc Include="Debugger\DebuggerWindow.h" />
<QtMoc Include="Debugger\DisassemblyWidget.h" />
@@ -263,7 +267,9 @@
<ClCompile Include="$(IntDir)Settings\moc_GameSummaryWidget.cpp" />
<ClCompile Include="$(IntDir)Settings\moc_AchievementLoginDialog.cpp" />
<ClCompile Include="$(IntDir)Settings\moc_AchievementSettingsWidget.cpp" />
<ClCompile Include="$(IntDir)Settings\moc_DebugAnalysisSettingsWidget.cpp" />
<ClCompile Include="$(IntDir)Settings\moc_DebugSettingsWidget.cpp" />
<ClCompile Include="$(IntDir)Debugger\moc_AnalysisOptionsDialog.cpp" />
<ClCompile Include="$(IntDir)Debugger\moc_DebuggerWindow.cpp" />
<ClCompile Include="$(IntDir)Debugger\moc_CpuWidget.cpp" />
<ClCompile Include="$(IntDir)Debugger\moc_DisassemblyWidget.cpp" />
@@ -392,6 +398,9 @@
<QtUi Include="Tools\InputRecording\InputRecordingViewer.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Debugger\AnalysisOptionsDialog.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Debugger\DebuggerWindow.ui">
<FileType>Document</FileType>
</QtUi>
@@ -421,6 +430,9 @@
<QtTs Include="Translations\pcsx2-qt_en.ts">
<FileType>Document</FileType>
</QtTs>
<QtUi Include="Settings\DebugAnalysisSettingsWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\DebugSettingsWidget.ui">
<FileType>Document</FileType>
</QtUi>
+24
View File
@@ -257,12 +257,21 @@
<ClCompile Include="Tools\InputRecording\InputRecordingViewer.cpp">
<Filter>Tools\Input Recording</Filter>
</ClCompile>
<ClCompile Include="Settings\DebugAnalysisSettingsWidget.cpp">
<Filter>Settings</Filter>
</ClCompile>
<ClCompile Include="$(IntDir)Settings\moc_DebugAnalysisSettingsWidget.cpp">
<Filter>moc</Filter>
</ClCompile>
<ClCompile Include="Settings\DebugSettingsWidget.cpp">
<Filter>Settings</Filter>
</ClCompile>
<ClCompile Include="$(IntDir)Settings\moc_DebugSettingsWidget.cpp">
<Filter>moc</Filter>
</ClCompile>
<ClCompile Include="Debugger\AnalysisOptionsDialog.cpp">
<Filter>Debugger</Filter>
</ClCompile>
<ClCompile Include="Debugger\DebuggerWindow.cpp">
<Filter>Debugger</Filter>
</ClCompile>
@@ -296,6 +305,9 @@
<ClCompile Include="Debugger\Models\SavedAddressesModel.cpp">
<Filter>Debugger\Models</Filter>
</ClCompile>
<ClCompile Include="$(IntDir)Debugger\moc_AnalysisOptionsDialog.cpp">
<Filter>moc</Filter>
</ClCompile>
<ClCompile Include="$(IntDir)Debugger\moc_CpuWidget.cpp">
<Filter>moc</Filter>
</ClCompile>
@@ -520,9 +532,15 @@
<Filter>Settings</Filter>
</QtMoc>
<QtMoc Include="Tools\InputRecording\InputRecordingViewer.h" />
<QtMoc Include="Settings\DebugAnalysisSettingsWidget.h">
<Filter>Settings</Filter>
</QtMoc>
<QtMoc Include="Settings\DebugSettingsWidget.h">
<Filter>Settings</Filter>
</QtMoc>
<QtMoc Include="Debugger\AnalysisOptionsDialog.h">
<Filter>Debugger</Filter>
</QtMoc>
<QtMoc Include="Debugger\DebuggerWindow.h">
<Filter>Debugger</Filter>
</QtMoc>
@@ -665,9 +683,15 @@
<QtUi Include="Settings\USBDeviceWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\DebugAnalysisSettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Settings\DebugSettingsWidget.ui">
<Filter>Settings</Filter>
</QtUi>
<QtUi Include="Debugger\AnalysisOptionsDialog.ui">
<Filter>Debugger</Filter>
</QtUi>
<QtUi Include="Debugger\DebuggerWindow.ui">
<Filter>Debugger</Filter>
</QtUi>
@@ -1,7 +1,17 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
<svg width="256px" height="256px" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="#000000" class="bi bi-camera-video">
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
<g id="SVGRepo_iconCarrier"> <path fill-rule="evenodd" d="M0 5a2 2 0 0 1 2-2h7.5a2 2 0 0 1 1.983 1.738l3.11-1.382A1 1 0 0 1 16 4.269v7.462a1 1 0 0 1-1.406.913l-3.111-1.382A2 2 0 0 1 9.5 13H2a2 2 0 0 1-2-2V5zm11.5 5.175 3.5 1.556V4.269l-3.5 1.556v4.35zM2 4a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h7.5a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H2z"/> </g>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg id="camera_video_-_PCSX2" data-name="camera video - PCSX2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 150">
<defs>
<style>
.cls-1 {
fill: none;
stroke: #000;
stroke-miterlimit: 10;
stroke-width: 12px;
}
</style>
</defs>
<g id="By_Maxihplay" data-name="By Maxihplay">
<rect class="cls-1" x="9.4" y="33.49" width="90.95" height="83.02" rx="12.96" ry="12.96"/>
<path class="cls-1" d="m138.43,105.09l-37.81-15.05v-30.07l37.81-15.05c1.03-.41,2.16.3,2.16,1.35v57.48c0,1.05-1.14,1.76-2.16,1.35Z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 782 B

After

Width:  |  Height:  |  Size: 623 B

@@ -1,20 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="PCSX2_-_Namco" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 150 150" style="enable-background:new 0 0 150 150;" xml:space="preserve">
<path id="By_Maxihplay" d="M130.4,64.3c3.3-4.2,5.2-9.4,5.2-15.1c0-13.5-11-24.4-24.4-24.4c-4.7,0-9.1,1.4-12.9,3.7
c-5.4-8-14.7-12.8-24.4-12.2c-8.5,0.6-16.1,5.3-20.7,12.3c-3.8-2.4-8.3-3.9-13.2-3.9c-13.5,0-24.4,11-24.4,24.4c0,5.2,1.6,10,4.4,14
c-2.6,6.9-8.8,25.5-7.3,37.9c2,15.9,10.9,22.2,11.9,22.8c0.6,0.4,1.3,0.7,2.1,0.8c4.8,0.9,9.5,0.4,13.4-1.5c3.6-1.8,6.4-4.8,8.5-9.1
c3.1-6.5,2.8-15.8,1.6-24.7c0.2,0.1,0.8-0.1,1.4-0.2c4.2,8.6,13.1,14.6,23.4,14.6c10.2,0,19.1-5.9,23.3-14.5c0.5,0.1,0.9,0.2,1,0.1
c-0.9,7-1.2,17.8,2.1,24.7c2.1,4.3,4.8,7.3,8.5,9.1c2.6,1.3,5.7,2,8.9,2c1.5,0,3-0.1,4.5-0.4c0.8-0.2,1.5-0.4,2.1-0.9
c1-0.7,9.9-6.9,11.9-22.8C138.8,89.4,133.1,71.9,130.4,64.3z M111.2,36.8c6.8,0,12.4,5.6,12.4,12.4c0,6.8-5.6,12.4-12.4,12.4
s-12.4-5.6-12.4-12.4C98.8,42.4,104.3,36.8,111.2,36.8z M74.7,28.3c6.3-0.4,12.3,3.3,15,9.3c-1.9,3.5-2.9,7.4-2.9,11.6
c0,2,0.2,3.9,0.7,5.7c-3.7-2-7.9-3.2-12.5-3.2c-4,0-7.8,0.9-11.1,2.5c0.3-1.6,0.5-3.3,0.5-5.1c0-4-1-7.8-2.7-11.1
C63.9,32.6,68.9,28.7,74.7,28.3z M40,36.8c6.8,0,12.4,5.6,12.4,12.4c0,6.8-5.6,12.4-12.4,12.4s-12.4-5.6-12.4-12.4
C27.6,42.4,33.1,36.8,40,36.8z M45.8,78l-1.8,0.5c-3.9,1.1-6.3,4.5-5.7,8.1l0,0.1c0.7,4.8,2.7,17.4-0.2,23.4c-1.5,3.2-3,4-3.5,4.2
c0,0,0,0,0,0c-2.2,1.1-4.8,0.2-6.2-1.7c-1.7-2.5-3.8-6.5-4.5-12.6c-1-7.9,2.3-20.4,5.2-28.9c3.3,1.6,7,2.6,10.9,2.6
c3.5,0,6.7-0.7,9.7-2c-0.5,1.8-0.7,3.7-0.7,5.7C47.8,77.5,46.6,77.8,45.8,78z M75,91.9c-7.7,0-14-6.3-14-14s6.3-14,14-14
c7.7,0,14,6.3,14,14S82.7,91.9,75,91.9z M126.1,100c-0.8,6.1-2.8,10.1-4.5,12.6c-1.4,2-4,2.8-6.2,1.8c0,0,0,0,0,0
c-0.5-0.3-2-1-3.5-4.2c-2.9-6-1.8-19.2-1.2-23.5l0-0.2c0.5-3.2-1.3-6.2-4.4-7.7l-1.1-0.5c-1-0.5-2.6-0.8-4.1-0.9
c-0.1-2.1-0.4-4.2-0.9-6.2c3.3,1.7,7.1,2.7,11.1,2.7c3.5,0,6.9-0.8,9.9-2.1C123.9,80.1,127,92.3,126.1,100z"/>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Jogcon_-_PCSX2" data-name="Jogcon - PCSX2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 150">
<defs>
<style>
.cls-1 {
fill: none;
stroke: #000;
stroke-linecap: round;
stroke-linejoin: round;
stroke-width: 12px;
}
</style>
</defs>
<g id="By_maxihplay" data-name="By @maxihplay">
<g>
<path class="cls-1" d="m126.03,63.22c3.43-3.42,5.55-8.15,5.55-13.38,0-10.44-8.47-18.91-18.91-18.91-6.44,0-12.12,3.22-15.54,8.13"/>
<path class="cls-1" d="m24.65,63.22c-3.43-3.42-4.52-8.15-4.52-13.38,0-10.44,8.47-18.91,18.91-18.91,6.44,0,12.12,3.22,15.54,8.13"/>
<g>
<path d="m130.41,61.42c-1.1-2.72-4.43-4.12-7.43-3.12-3.01.99-4.55,4-3.46,6.72,2.66,6.58,9.26,26.04,7.91,36.9-.78,6.27-2.83,10.41-4.61,12.93-1.43,2.03-4.12,2.88-6.35,1.79-.01,0-.03-.01-.04-.02-.56-.28-2.05-1.02-3.65-4.34-2.98-6.2-1.89-19.72-1.2-24.16l.04-.26c.51-3.24-1.32-6.4-4.54-7.86l-1.15-.53c-1.81-.83-5.55-1.26-7.4-.87.23,1.26,0,3.43,0,4.75,0,3.3-.69,4.83-2.04,7.68,1.01-.44,3.25.21,3.51.11-.92,7.22-1.22,18.32,2.14,25.31,2.13,4.44,4.98,7.5,8.69,9.35,2.71,1.35,5.83,2.04,9.1,2.04,1.52,0,3.06-.15,4.61-.45.78-.15,1.52-.45,2.17-.88,1.04-.68,10.2-7.1,12.23-23.43,1.93-15.54-8.12-40.61-8.55-41.67Z"/>
<path d="m52.83,90.71c-1.19-2.71-2.94-5.14-2.94-8.24,0-1.21.68-2.7.87-3.87-1.34-.25-4.31.36-5.68.74l-1.82.51c-3.97,1.1-6.44,4.6-5.87,8.32l.02.15c.75,4.88,2.74,17.84-.2,23.97-1.6,3.32-3.09,4.06-3.65,4.34-.01,0-.03.01-.04.02-2.23,1.09-4.91.24-6.33-1.79-1.77-2.52-3.85-6.69-4.62-12.93-1.35-10.86,5.26-30.32,7.91-36.9,1.1-2.72-.45-5.73-3.45-6.72-3.01-1-6.33.4-7.43,3.12-.43,1.06-10.47,26.13-8.55,41.67,2.02,16.33,11.19,22.75,12.23,23.43.65.42,1.39.72,2.17.88,4.88.95,9.74.39,13.7-1.59,3.71-1.85,6.56-4.91,8.69-9.35,3.23-6.71,2.84-16.24,1.66-25.32.38.12,2.88-.55,3.33-.43Z"/>
</g>
<circle class="cls-1" cx="75" cy="79.2" r="20.58"/>
<path class="cls-1" d="m55.23,37.19c2.88-8.45,10.44-14.38,19.06-14.98,9.65-.68,18.83,5.45,22.14,14.98"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

@@ -1,30 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Duckstation_-_Negcon_00000104687465272175918400000016919813319004934028_"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 150 150"
style="enable-background:new 0 0 150 150;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;}
.st1{fill:none;stroke:#000000;stroke-width:12;stroke-miterlimit:10;}
.st2{fill:none;stroke:#000000;stroke-width:12;stroke-linecap:round;stroke-miterlimit:10;}
</style>
<g id="tela">
<rect id="tela_00000129895939108887223950000017508827257489233583_" class="st0" width="150" height="150"/>
</g>
<g id="By_Maxihplay_00000152974811067316581070000007946929605663458202_">
<g id="control">
<g id="B">
<path class="st1" d="M91.9,87.8h14l20.2,21.1c3.6,2.5,8.5-0.2,8.4-4.6l-3.9-35.4c0-10.3-8.3-18.6-18.6-18.6H91.9V87.8L91.9,87.8z
"/>
<line class="st1" x1="83.7" y1="40.1" x2="83.5" y2="99.1"/>
<polyline class="st2" points="101.6,46.2 116.7,46.2 126.1,52 "/>
</g>
<g id="A">
<path class="st1" d="M58.1,87.8h-14l-20.2,21.1c-3.6,2.5-8.5-0.2-8.4-4.6l3.9-35.4c0-10.3,8.3-18.6,18.6-18.6h20.1V87.8
L58.1,87.8z"/>
<line class="st1" x1="66.3" y1="40.1" x2="66.5" y2="99.1"/>
<polyline class="st2" points="48.1,46.2 33,46.2 23.6,52 "/>
</g>
</g>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Negcon_-_PCSX2" data-name="Negcon - PCSX2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 150">
<defs>
<style>
.cls-1 {
fill: none;
stroke: #000;
stroke-linecap: round;
stroke-miterlimit: 10;
stroke-width: 12px;
}
</style>
</defs>
<g id="By_maxihplay" data-name="By @maxihplay">
<path d="m130.96,116.52c-2.29,0-4.57-.69-6.54-2.06l-.5-.34-19.54-20.41h-17.92v-50.78h26.79c13.8,0,25.04,11.13,25.23,24.88l4.03,36.82c.1,4.4-2.24,8.42-6.11,10.5-1.72.92-3.59,1.38-5.46,1.38Zm-32.49-34.81h11.04l20.83,21.76-3.85-34.98v-.33c0-7.3-5.94-13.23-13.23-13.23h-14.79v26.78Z"/>
<line class="cls-1" x1="84" y1="39.48" x2="83.79" y2="97.31"/>
<path d="m19.04,116.52c-1.86,0-3.74-.46-5.46-1.38-3.87-2.08-6.21-6.1-6.11-10.5l.03-.52,4-36.3c.19-13.75,11.44-24.88,25.23-24.88h26.79v50.78h-17.92l-19.53,20.41-.5.34c-1.97,1.37-4.25,2.06-6.54,2.06Zm17.7-61.59c-7.3,0-13.23,5.94-13.23,13.23l-.04.66-3.82,34.65,20.83-21.76h11.04v-26.78h-14.79Z"/>
<line class="cls-1" x1="66" y1="39.48" x2="66.21" y2="97.31"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -1,7 +1,15 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
<svg width="256px" height="256px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
<g id="SVGRepo_iconCarrier"> <circle cx="12" cy="12" r="10" stroke="#000000" stroke-width="1.5"/> <circle cx="12" cy="7" r="1.5" transform="rotate(-90 12 7)" stroke="#000000" stroke-width="1.5"/> <circle cx="12" cy="12" r="1.5" transform="rotate(-90 12 12)" stroke="#000000" stroke-width="1.5"/> <path d="M8 8C8.82843 8 9.5 8.67157 9.5 9.5C9.5 10.3284 8.82843 11 8 11C7.17157 11 6.5 10.3284 6.5 9.5C6.5 8.67157 7.17157 8 8 8Z" stroke="#000000" stroke-width="1.5"/> </g>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Ball_-_PCSX2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 150 150" style="enable-background:new 0 0 150 150;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;stroke:#000000;stroke-width:12;stroke-miterlimit:42.67;}
.st1{stroke:#000000;stroke-width:7;stroke-miterlimit:42.67;}
</style>
<g id="Kam_-_ball">
<circle class="st0" cx="75" cy="75" r="55.7"/>
<circle class="st1" cx="82.1" cy="44.4" r="8.4"/>
<circle class="st1" cx="79.2" cy="77.8" r="8.3"/>
<path class="st1" d="M52.7,52.7c4.6,0,8.4,3.7,8.4,8.4s-3.7,8.3-8.3,8.3s-8.3-3.7-8.3-8.3S48.1,52.7,52.7,52.7z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 891 B

After

Width:  |  Height:  |  Size: 817 B

@@ -1,19 +1,27 @@
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 -10 100 110" >
<g>
<path
fill="none"
stroke="black"
stroke-width="8"
stroke-miterlimit="5"
d="m 0 50
l 20,0
l 7.5,20
l 15,-45
l 15,55
l 15,-65
l 7.5,35
l 20,0" />
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Vibration_-_PCSX2" data-name="Vibration - PCSX2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 150">
<defs>
<style>
.cls-1 {
stroke-linecap: round;
stroke-linejoin: round;
}
.cls-1, .cls-2 {
fill: none;
stroke: #000;
stroke-width: 12px;
}
.cls-2 {
stroke-miterlimit: 5;
}
</style>
</defs>
<g id="By_maxihplay" data-name="By @maxihplay">
<rect class="cls-2" x="51.59" y="20.59" width="46.81" height="87.78" rx="17.19" ry="17.19"/>
<path class="cls-1" d="m75,113.37v7.22c0,4.85,3.97,8.82,8.82,8.82h18.88"/>
<polyline class="cls-1" points="130.09 33.5 116.93 58.56 132.07 75.26 118.88 95.92 130.8 116.5"/>
<polyline class="cls-1" points="19.91 33.5 33.07 58.56 17.93 75.26 31.12 95.92 19.2 116.5"/>
</g>
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 332 B

After

Width:  |  Height:  |  Size: 879 B

@@ -1,7 +1,17 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
<svg width="256px" height="256px" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="#ffffff" class="bi bi-camera-video">
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
<g id="SVGRepo_iconCarrier"> <path fill-rule="evenodd" d="M0 5a2 2 0 0 1 2-2h7.5a2 2 0 0 1 1.983 1.738l3.11-1.382A1 1 0 0 1 16 4.269v7.462a1 1 0 0 1-1.406.913l-3.111-1.382A2 2 0 0 1 9.5 13H2a2 2 0 0 1-2-2V5zm11.5 5.175 3.5 1.556V4.269l-3.5 1.556v4.35zM2 4a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h7.5a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H2z"/> </g>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg id="camera_video_-_PCSX2" data-name="camera video - PCSX2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 150">
<defs>
<style>
.cls-1 {
fill: none;
stroke: #fff;
stroke-miterlimit: 10;
stroke-width: 12px;
}
</style>
</defs>
<g id="By_Maxihplay" data-name="By Maxihplay">
<rect class="cls-1" x="9.4" y="33.49" width="90.95" height="83.02" rx="12.96" ry="12.96"/>
<path class="cls-1" d="m138.43,105.09l-37.81-15.05v-30.07l37.81-15.05c1.03-.41,2.16.3,2.16,1.35v57.48c0,1.05-1.14,1.76-2.16,1.35Z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 782 B

After

Width:  |  Height:  |  Size: 623 B

@@ -1,23 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="PCSX2_-_Namco" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 150 150" style="enable-background:new 0 0 150 150;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<path id="By_Maxihplay" class="st0" d="M130.4,64.3c3.3-4.2,5.2-9.4,5.2-15.1c0-13.5-11-24.4-24.4-24.4c-4.7,0-9.1,1.4-12.9,3.7
c-5.4-8-14.7-12.8-24.4-12.2c-8.5,0.6-16.1,5.3-20.7,12.3c-3.8-2.4-8.3-3.9-13.2-3.9c-13.5,0-24.4,11-24.4,24.4c0,5.2,1.6,10,4.4,14
c-2.6,6.9-8.8,25.5-7.3,37.9c2,15.9,10.9,22.2,11.9,22.8c0.6,0.4,1.3,0.7,2.1,0.8c4.8,0.9,9.5,0.4,13.4-1.5c3.6-1.8,6.4-4.8,8.5-9.1
c3.1-6.5,2.8-15.8,1.6-24.7c0.2,0.1,0.8-0.1,1.4-0.2c4.2,8.6,13.1,14.6,23.4,14.6c10.2,0,19.1-5.9,23.3-14.5c0.5,0.1,0.9,0.2,1,0.1
c-0.9,7-1.2,17.8,2.1,24.7c2.1,4.3,4.8,7.3,8.5,9.1c2.6,1.3,5.7,2,8.9,2c1.5,0,3-0.1,4.5-0.4c0.8-0.2,1.5-0.4,2.1-0.9
c1-0.7,9.9-6.9,11.9-22.8C138.8,89.4,133.1,71.9,130.4,64.3z M111.2,36.8c6.8,0,12.4,5.6,12.4,12.4c0,6.8-5.6,12.4-12.4,12.4
s-12.4-5.6-12.4-12.4C98.8,42.4,104.3,36.8,111.2,36.8z M74.7,28.3c6.3-0.4,12.3,3.3,15,9.3c-1.9,3.5-2.9,7.4-2.9,11.6
c0,2,0.2,3.9,0.7,5.7c-3.7-2-7.9-3.2-12.5-3.2c-4,0-7.8,0.9-11.1,2.5c0.3-1.6,0.5-3.3,0.5-5.1c0-4-1-7.8-2.7-11.1
C63.9,32.6,68.9,28.7,74.7,28.3z M40,36.8c6.8,0,12.4,5.6,12.4,12.4c0,6.8-5.6,12.4-12.4,12.4s-12.4-5.6-12.4-12.4
C27.6,42.4,33.1,36.8,40,36.8z M45.8,78l-1.8,0.5c-3.9,1.1-6.3,4.5-5.7,8.1l0,0.1c0.7,4.8,2.7,17.4-0.2,23.4c-1.5,3.2-3,4-3.5,4.2
c0,0,0,0,0,0c-2.2,1.1-4.8,0.2-6.2-1.7c-1.7-2.5-3.8-6.5-4.5-12.6c-1-7.9,2.3-20.4,5.2-28.9c3.3,1.6,7,2.6,10.9,2.6
c3.5,0,6.7-0.7,9.7-2c-0.5,1.8-0.7,3.7-0.7,5.7C47.8,77.5,46.6,77.8,45.8,78z M75,91.9c-7.7,0-14-6.3-14-14s6.3-14,14-14
c7.7,0,14,6.3,14,14S82.7,91.9,75,91.9z M126.1,100c-0.8,6.1-2.8,10.1-4.5,12.6c-1.4,2-4,2.8-6.2,1.8c0,0,0,0,0,0
c-0.5-0.3-2-1-3.5-4.2c-2.9-6-1.8-19.2-1.2-23.5l0-0.2c0.5-3.2-1.3-6.2-4.4-7.7l-1.1-0.5c-1-0.5-2.6-0.8-4.1-0.9
c-0.1-2.1-0.4-4.2-0.9-6.2c3.3,1.7,7.1,2.7,11.1,2.7c3.5,0,6.9-0.8,9.9-2.1C123.9,80.1,127,92.3,126.1,100z"/>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Jogcon_-_PCSX2" data-name="Jogcon - PCSX2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 150">
<defs>
<style>
.cls-1 {
fill: #fff;
}
.cls-2 {
fill: none;
stroke: #fff;
stroke-linecap: round;
stroke-linejoin: round;
stroke-width: 12px;
}
</style>
</defs>
<g id="By_maxihplay" data-name="By @maxihplay">
<g>
<path class="cls-2" d="m126.03,63.22c3.43-3.42,5.55-8.15,5.55-13.38,0-10.44-8.47-18.91-18.91-18.91-6.44,0-12.12,3.22-15.54,8.13"/>
<path class="cls-2" d="m24.65,63.22c-3.43-3.42-4.52-8.15-4.52-13.38,0-10.44,8.47-18.91,18.91-18.91,6.44,0,12.12,3.22,15.54,8.13"/>
<g>
<path class="cls-1" d="m130.41,61.42c-1.1-2.72-4.43-4.12-7.43-3.12-3.01.99-4.55,4-3.46,6.72,2.66,6.58,9.26,26.04,7.91,36.9-.78,6.27-2.83,10.41-4.61,12.93-1.43,2.03-4.12,2.88-6.35,1.79-.01,0-.03-.01-.04-.02-.56-.28-2.05-1.02-3.65-4.34-2.98-6.2-1.89-19.72-1.2-24.16l.04-.26c.51-3.24-1.32-6.4-4.54-7.86l-1.15-.53c-1.81-.83-5.55-1.26-7.4-.87.23,1.26,0,3.43,0,4.75,0,3.3-.69,4.83-2.04,7.68,1.01-.44,3.25.21,3.51.11-.92,7.22-1.22,18.32,2.14,25.31,2.13,4.44,4.98,7.5,8.69,9.35,2.71,1.35,5.83,2.04,9.1,2.04,1.52,0,3.06-.15,4.61-.45.78-.15,1.52-.45,2.17-.88,1.04-.68,10.2-7.1,12.23-23.43,1.93-15.54-8.12-40.61-8.55-41.67Z"/>
<path class="cls-1" d="m52.83,90.71c-1.19-2.71-2.94-5.14-2.94-8.24,0-1.21.68-2.7.87-3.87-1.34-.25-4.31.36-5.68.74l-1.82.51c-3.97,1.1-6.44,4.6-5.87,8.32l.02.15c.75,4.88,2.74,17.84-.2,23.97-1.6,3.32-3.09,4.06-3.65,4.34-.01,0-.03.01-.04.02-2.23,1.09-4.91.24-6.33-1.79-1.77-2.52-3.85-6.69-4.62-12.93-1.35-10.86,5.26-30.32,7.91-36.9,1.1-2.72-.45-5.73-3.45-6.72-3.01-1-6.33.4-7.43,3.12-.43,1.06-10.47,26.13-8.55,41.67,2.02,16.33,11.19,22.75,12.23,23.43.65.42,1.39.72,2.17.88,4.88.95,9.74.39,13.7-1.59,3.71-1.85,6.56-4.91,8.69-9.35,3.23-6.71,2.84-16.24,1.66-25.32.38.12,2.88-.55,3.33-.43Z"/>
</g>
<circle class="cls-2" cx="75" cy="79.2" r="20.58"/>
<path class="cls-2" d="m55.23,37.19c2.88-8.45,10.44-14.38,19.06-14.98,9.65-.68,18.83,5.45,22.14,14.98"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

@@ -1 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="Duckstation_-_Negcon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 150"><defs><style>.cls-1{stroke-linecap:round;}.cls-1,.cls-2,.cls-3{fill:none;}.cls-1,.cls-3{stroke:#fff;stroke-miterlimit:10;stroke-width:12px;}</style></defs><g id="tela"><rect id="tela-2" class="cls-2" width="150" height="150"/></g><g id="By_Maxihplay"><g id="control"><g id="B"><path class="cls-3" d="M91.9,87.8h14l20.2,21.1c3.6,2.5,8.5-.2,8.4-4.6l-3.9-35.4c0-10.3-8.3-18.6-18.6-18.6h-20.1v37.5h0Z"/><line class="cls-3" x1="83.7" y1="40.1" x2="83.5" y2="99.1"/><polyline class="cls-1" points="101.6 46.2 116.7 46.2 126.1 52"/></g><g id="A"><path class="cls-3" d="M58.1,87.8h-14l-20.2,21.1c-3.6,2.5-8.5-.2-8.4-4.6l3.9-35.4c0-10.3,8.3-18.6,18.6-18.6h20.1v37.5h0Z"/><line class="cls-3" x1="66.3" y1="40.1" x2="66.5" y2="99.1"/><polyline class="cls-1" points="48.1 46.2 33 46.2 23.6 52"/></g></g></g></svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Negcon_-_PCSX2" data-name="Negcon - PCSX2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 150">
<defs>
<style>
.cls-1 {
fill: #fff;
}
.cls-2 {
fill: none;
stroke: #fff;
stroke-linecap: round;
stroke-miterlimit: 10;
stroke-width: 12px;
}
</style>
</defs>
<g id="By_maxihplay" data-name="By @maxihplay">
<path class="cls-1" d="m130.96,116.52c-2.29,0-4.57-.69-6.54-2.06l-.5-.34-19.54-20.41h-17.92v-50.78h26.79c13.8,0,25.04,11.13,25.23,24.88l4.03,36.82c.1,4.4-2.24,8.42-6.11,10.5-1.72.92-3.59,1.38-5.46,1.38Zm-32.49-34.81h11.04l20.83,21.76-3.85-34.98v-.33c0-7.3-5.94-13.23-13.24-13.23h-14.79v26.78Z"/>
<line class="cls-2" x1="84" y1="39.48" x2="83.79" y2="97.31"/>
<path class="cls-1" d="m19.04,116.52c-1.86,0-3.74-.46-5.46-1.38-3.87-2.08-6.21-6.1-6.11-10.5l.03-.52,4-36.3c.19-13.75,11.44-24.88,25.23-24.88h26.79v50.78h-17.92l-19.54,20.41-.5.34c-1.97,1.37-4.25,2.06-6.54,2.06Zm17.7-61.59c-7.3,0-13.23,5.94-13.23,13.23l-.04.66-3.82,34.65,20.83-21.76h11.04v-26.78h-14.79Z"/>
<line class="cls-2" x1="66" y1="39.48" x2="66.21" y2="97.31"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 927 B

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -1,7 +1,15 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
<svg width="256px" height="256px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
<g id="SVGRepo_iconCarrier"> <circle cx="12" cy="12" r="10" stroke="#ffffff" stroke-width="1.5"/> <circle cx="12" cy="7" r="1.5" transform="rotate(-90 12 7)" stroke="#ffffff" stroke-width="1.5"/> <circle cx="12" cy="12" r="1.5" transform="rotate(-90 12 12)" stroke="#ffffff" stroke-width="1.5"/> <path d="M8 8C8.82843 8 9.5 8.67157 9.5 9.5C9.5 10.3284 8.82843 11 8 11C7.17157 11 6.5 10.3284 6.5 9.5C6.5 8.67157 7.17157 8 8 8Z" stroke="#ffffff" stroke-width="1.5"/> </g>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Ball_-_PCSX2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 150 150" style="enable-background:new 0 0 150 150;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;stroke:#FFFFFF;stroke-width:12;stroke-miterlimit:42.67;}
.st1{fill:#FFFFFF;stroke:#FFFFFF;stroke-width:7;stroke-miterlimit:42.67;}
</style>
<g id="Kam_-_ball">
<circle class="st0" cx="75" cy="75" r="55.7"/>
<circle class="st1" cx="82.1" cy="44.4" r="8.4"/>
<circle class="st1" cx="79.2" cy="77.8" r="8.3"/>
<path class="st1" d="M52.7,52.7c4.6,0,8.4,3.7,8.4,8.4s-3.7,8.3-8.3,8.3s-8.3-3.7-8.3-8.3S48.1,52.7,52.7,52.7z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 891 B

After

Width:  |  Height:  |  Size: 830 B

@@ -1,19 +1,27 @@
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 -10 100 110" >
<g>
<path
fill="none"
stroke="white"
stroke-width="8"
stroke-miterlimit="5"
d="m 0 50
l 20,0
l 7.5,20
l 15,-45
l 15,55
l 15,-65
l 7.5,35
l 20,0" />
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Vibration_-_PCSX2" data-name="Vibration - PCSX2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 150">
<defs>
<style>
.cls-1 {
stroke-miterlimit: 5;
}
.cls-1, .cls-2 {
fill: none;
stroke: #fff;
stroke-width: 12px;
}
.cls-2 {
stroke-linecap: round;
stroke-linejoin: round;
}
</style>
</defs>
<g id="By_maxihplay" data-name="By @maxihplay">
<rect class="cls-1" x="51.59" y="20.59" width="46.81" height="87.78" rx="17.19" ry="17.19"/>
<path class="cls-2" d="m75,113.37v7.22c0,4.85,3.97,8.82,8.82,8.82h18.88"/>
<polyline class="cls-2" points="130.09 33.5 116.93 58.56 132.07 75.26 118.88 95.92 130.8 116.5"/>
<polyline class="cls-2" points="19.91 33.5 33.07 58.56 17.93 75.26 31.12 95.92 19.2 116.5"/>
</g>
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 332 B

After

Width:  |  Height:  |  Size: 879 B

+2
View File
@@ -789,6 +789,7 @@ set(pcsx2DebugToolsSources
DebugTools/MipsStackWalk.cpp
DebugTools/Breakpoints.cpp
DebugTools/SymbolGuardian.cpp
DebugTools/SymbolImporter.cpp
DebugTools/DisR3000A.cpp
DebugTools/DisR5900asm.cpp
DebugTools/DisVU0Micro.cpp
@@ -806,6 +807,7 @@ set(pcsx2DebugToolsHeaders
DebugTools/MipsStackWalk.h
DebugTools/Breakpoints.h
DebugTools/SymbolGuardian.h
DebugTools/SymbolImporter.h
DebugTools/Debug.h
DebugTools/DisASM.h
DebugTools/DisVUmicro.h
+133 -32
View File
@@ -35,13 +35,13 @@ enum class CDVD_SourceType : uint8_t;
namespace Pad
{
enum class ControllerType : u8;
enum class ControllerType : u8;
}
/// Generic setting information which can be reused in multiple components.
struct SettingInfo
{
using GetOptionsCallback = std::vector<std::pair<std::string, std::string>>(*)();
using GetOptionsCallback = std::vector<std::pair<std::string, std::string>> (*)();
enum class Type
{
@@ -190,6 +190,35 @@ enum class SpeedHack
MaxCount,
};
enum class DebugAnalysisCondition
{
ALWAYS,
IF_DEBUGGER_IS_OPEN,
NEVER
};
struct DebugSymbolSource
{
std::string Name;
bool ClearDuringAnalysis = false;
friend auto operator<=>(const DebugSymbolSource& lhs, const DebugSymbolSource& rhs) = default;
};
struct DebugExtraSymbolFile
{
std::string Path;
friend auto operator<=>(const DebugExtraSymbolFile& lhs, const DebugExtraSymbolFile& rhs) = default;
};
enum class DebugFunctionScanMode
{
SCAN_ELF,
SCAN_MEMORY,
SKIP
};
enum class AspectRatioType : u8
{
Stretch,
@@ -421,41 +450,82 @@ enum class GSNativeScaling : u8
};
// --------------------------------------------------------------------------------------
// TraceFiltersEE
// TraceLogsEE
// --------------------------------------------------------------------------------------
struct TraceFiltersEE
struct TraceLogsEE
{
// EE
BITFIELD32()
bool
m_EnableAll : 1, // Master Enable switch (if false, no logs at all)
m_EnableDisasm : 1,
m_EnableRegisters : 1,
m_EnableEvents : 1; // Enables logging of event-driven activity -- counters, DMAs, etc.
bios : 1,
memory : 1,
giftag : 1,
vifcode : 1,
mskpath3 : 1,
r5900 : 1,
cop0 : 1,
cop1 : 1,
cop2 : 1,
cache : 1,
knownhw : 1,
unknownhw : 1,
dmahw : 1,
ipu : 1,
dmac : 1,
counters : 1,
spr : 1,
vif : 1,
gif : 1;
BITFIELD_END
TraceFiltersEE();
TraceLogsEE();
bool operator==(const TraceFiltersEE& right) const;
bool operator!=(const TraceFiltersEE& right) const;
bool operator==(const TraceLogsEE& right) const;
bool operator!=(const TraceLogsEE& right) const;
};
// --------------------------------------------------------------------------------------
// TraceFiltersIOP
// TraceLogsIOP
// --------------------------------------------------------------------------------------
struct TraceFiltersIOP
struct TraceLogsIOP
{
BITFIELD32()
bool
m_EnableAll : 1, // Master Enable switch (if false, no logs at all)
m_EnableDisasm : 1,
m_EnableRegisters : 1,
m_EnableEvents : 1; // Enables logging of event-driven activity -- counters, DMAs, etc.
bios : 1,
memcards : 1,
pad : 1,
r3000a : 1,
cop2 : 1,
memory : 1,
knownhw : 1,
unknownhw : 1,
dmahw : 1,
dmac : 1,
counters : 1,
cdvd : 1,
mdec : 1;
BITFIELD_END
TraceFiltersIOP();
TraceLogsIOP();
bool operator==(const TraceFiltersIOP& right) const;
bool operator!=(const TraceFiltersIOP& right) const;
bool operator==(const TraceLogsIOP& right) const;
bool operator!=(const TraceLogsIOP& right) const;
};
// --------------------------------------------------------------------------------------
// TraceLogsMISC
// --------------------------------------------------------------------------------------
struct TraceLogsMISC
{
BITFIELD32()
bool
sif : 1;
BITFIELD_END
TraceLogsMISC();
bool operator==(const TraceLogsMISC& right) const;
bool operator!=(const TraceLogsMISC& right) const;
};
// --------------------------------------------------------------------------------------
@@ -463,21 +533,18 @@ struct TraceFiltersIOP
// --------------------------------------------------------------------------------------
struct TraceLogFilters
{
// Enabled - global toggle for high volume logging. This is effectively the equivalent to
// (EE.Enabled() || IOP.Enabled() || SIF) -- it's cached so that we can use the macros
// below to inline the conditional check. This is desirable because these logs are
// *very* high volume, and debug builds get noticably slower if they have to invoke
// methods/accessors to test the log enable bits. Debug builds are slow enough already,
// so I prefer this to help keep them usable.
bool Enabled;
TraceFiltersEE EE;
TraceFiltersIOP IOP;
TraceLogsEE EE;
TraceLogsIOP IOP;
TraceLogsMISC MISC;
TraceLogFilters();
void LoadSave(SettingsWrapper& ini);
// When logging, the tracelogpack is checked, not was in the config.
// Call this to sync the tracelogpack values with the config values.
void SyncToConfig() const;
bool operator==(const TraceLogFilters& right) const;
bool operator!=(const TraceLogFilters& right) const;
};
@@ -647,7 +714,7 @@ struct Pcsx2Config
OsdShowInputs : 1,
OsdShowFrameTimes : 1,
OsdShowVersion : 1,
OsdShowVideoCapture: 1,
OsdShowVideoCapture : 1,
OsdShowInputRec : 1,
OsdShowHardwareInfo : 1,
HWSpinGPUForReadbacks : 1,
@@ -1007,6 +1074,7 @@ struct Pcsx2Config
u32 WindowHeight;
u32 MemoryViewBytesPerRow;
DebugOptions();
void LoadSave(SettingsWrapper& wrap);
@@ -1014,6 +1082,37 @@ struct Pcsx2Config
bool operator!=(const DebugOptions& right) const;
};
// ------------------------------------------------------------------------
struct DebugAnalysisOptions
{
static const char* RunConditionNames[];
static const char* FunctionScanModeNames[];
DebugAnalysisCondition RunCondition = DebugAnalysisCondition::IF_DEBUGGER_IS_OPEN;
bool GenerateSymbolsForIRXExports = true;
bool AutomaticallySelectSymbolsToClear = true;
std::vector<DebugSymbolSource> SymbolSources;
bool ImportSymbolsFromELF = true;
bool ImportSymFileFromDefaultLocation = true;
bool DemangleSymbols = true;
bool DemangleParameters = true;
std::vector<DebugExtraSymbolFile> ExtraSymbolFiles;
DebugFunctionScanMode FunctionScanMode = DebugFunctionScanMode::SCAN_ELF;
bool CustomFunctionScanRange = false;
std::string FunctionScanStartAddress = "0";
std::string FunctionScanEndAddress = "0";
bool GenerateFunctionHashes = true;
void LoadSave(SettingsWrapper& wrap);
friend auto operator<=>(const DebugAnalysisOptions& lhs, const DebugAnalysisOptions& rhs) = default;
};
// ------------------------------------------------------------------------
struct EmulationSpeedOptions
{
@@ -1149,10 +1248,10 @@ struct Pcsx2Config
{
SavestateOptions();
void LoadSave(SettingsWrapper& wrap);
SavestateCompressionMethod CompressionType = SavestateCompressionMethod::Zstandard;
SavestateCompressionLevel CompressionRatio = SavestateCompressionLevel::Medium;
bool operator==(const SavestateOptions& right) const;
bool operator!=(const SavestateOptions& right) const;
};
@@ -1177,6 +1276,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,
InhibitScreensaver : 1,
BackupSavestate : 1,
McdFolderAutoManage : 1,
@@ -1192,6 +1292,7 @@ struct Pcsx2Config
GamefixOptions Gamefixes;
ProfilerOptions Profiler;
DebugOptions Debugger;
DebugAnalysisOptions DebuggerAnalysis;
EmulationSpeedOptions EmulationSpeed;
SavestateOptions Savestate;
SPU2Options SPU2;
+2 -4
View File
@@ -499,8 +499,7 @@ static __fi void VSyncStart(u32 sCycle)
// Poll input after MTGS frame push, just in case it has to stall to catch up.
VMManager::Internal::PollInputOnCPUThread();
if (EmuConfig.Trace.Enabled && EmuConfig.Trace.EE.m_EnableAll)
SysTrace.EE.Counters.Write(" ================ EE COUNTER VSYNC START (frame: %d) ================", g_FrameCount);
EECNT_LOG(" ================ EE COUNTER VSYNC START (frame: %d) ================", g_FrameCount);
// Memcard auto ejection - Uses a tick system timed off of real time, decrementing one tick per frame.
AutoEject::CountDownTicks();
@@ -564,8 +563,7 @@ static __fi void GSVSync()
static __fi void VSyncEnd(u32 sCycle)
{
if (EmuConfig.Trace.Enabled && EmuConfig.Trace.EE.m_EnableAll)
SysTrace.EE.Counters.Write(" ================ EE COUNTER VSYNC END (frame: %d) ================", g_FrameCount);
EECNT_LOG(" ================ EE COUNTER VSYNC END (frame: %d) ================", g_FrameCount);
g_FrameCount++;
if (!GSSMODE1reg.SINT)

Some files were not shown because too many files have changed in this diff Show More