Compare commits

...
151 Commits
Author SHA1 Message Date
RedDevilusandrefractionpcsx2 d9dbf2c5e9 Qt: Add Polish flag
Polish were neglected, that ends now. Flag will be used when it sees a Polish entry in the gamelist.

Fixes https://github.com/PCSX2/pcsx2/issues/9137

Bumps the gamelist cache version from 32 to 33
Adds to enumeration
And make it visible in both gamelist and per-game summary view

Update GameList.cpp
2023-07-02 21:14:40 +01:00
RedDevilusandConnor McLaughlin c22f794a20 Qt: Fix wrongly labeled strings Translations
Bahasa Indonesia and Norsk were wrongly labeled, also marked English as the Default language.
2023-07-02 21:15:59 +10:00
Stenzek 972135e184 GS/Vulkan: Use attachment clear for clears when inside render pass 2023-07-02 13:00:16 +10:00
Stenzek 96fad124ac GS/HW: Improve detection of clears
- Detect "normal" target clears and HLE accordingly
 - Rewrite double-half clears to mask Z or FRAME, reducing false target creation.
 - Handle split single-page-wide clears, and attempt to get a real FBW.
 - Propogate clear values between targets, instead of blitting.
2023-07-02 13:00:16 +10:00
Stenzek ce7c466041 GS/HW: Fix mem clear when width != fbw 2023-07-02 13:00:16 +10:00
Berylskidandrefractionpcsx2 db0c7ca907 GameDB: Various fixes for Armored Core games
- Remove unnecessary CPU Sprite Render Size
- Add HPO Normal for fixing blur
2023-07-01 20:57:33 +01:00
Mrlinkwiiandrefractionpcsx2 9f62ecdb33 GameDB: add more missing demos 2023-07-01 20:56:18 +01:00
Sanjay GovindandConnor McLaughlin f91f257a7d USB: Add DJ hero turntable emulation 2023-07-01 20:42:48 +10:00
Bartłomiej PiotrowskiandConnor McLaughlin 28a197b8cd flatpak: Fix the location of mirrored screenshots 2023-07-01 19:55:00 +10:00
Stenzek 9d2d8c0713 CI/Linux: Hopefully fix Flathub release versioning 2023-07-01 14:17:29 +10:00
Stenzek b431f1dc0d Qt: Update base translation 2023-07-01 14:17:29 +10:00
Stenzek 67eb2975f6 Qt: Make achievements login dialog resizeable 2023-07-01 14:17:29 +10:00
Stenzek 4192de7dac USB: Fix some default strings not being translatable 2023-07-01 14:17:29 +10:00
Stenzek 82cecc89e2 Qt: Fix dropdowns in DEV9 not translating 2023-07-01 14:17:29 +10:00
Stenzek 113e264617 Qt: Fix theme names not being translatable 2023-07-01 14:17:29 +10:00
Stenzek a705a69022 Qt: Make memory card convert dialog translatable 2023-07-01 14:17:29 +10:00
Stenzek d757360f4e Qt: Remove some unused Form strings 2023-07-01 14:17:29 +10:00
Stenzek cc978daeef Qt: Disambiguate toolbar and menu bar items 2023-07-01 14:17:29 +10:00
lightningterror d38ad1df94 GS-hw: Change some blend operations in hw blend table.
Change the operations for Cs in table to CONST_ZERO as we want it to be 0.
2023-06-30 20:10:12 +02:00
refractionpcsx2 1fd7bcf9a9 GS: Update draw number on combined EE transfers 2023-06-30 16:31:12 +01:00
refractionpcsx2 06abb70624 GS/HW: Don't use unsigned values when calculating rect 2023-06-30 16:31:12 +01:00
Stenzek 78e20868df GS/OpenGL: Fix potentially-incorrect line width 2023-06-30 23:06:51 +10:00
Stenzek e52766d047 Misc: Fix a few warnings 2023-06-30 21:37:44 +10:00
Stenzek 224460e62d CMake: Remove no-builtin-*cmp, fpmath=sse
The former was for a gcc bug which was long fixed (and we don't use gcc).
The latter is irrelevant with 64-bit builds.
2023-06-30 21:37:44 +10:00
Stenzek 3c408de5c9 Build: Disable exceptions in the compiler 2023-06-30 21:37:44 +10:00
Stenzek ea803ff2d4 Build: Always use bundled soundtouch
Because we're disabling exceptions in it.

Might gain a bit of speed by -Ofast as well.
2023-06-30 21:37:44 +10:00
Stenzek 14a0786982 3rdparty/soundtouch: Add missing overrides 2023-06-30 21:37:44 +10:00
Stenzek 1dbccb5e3d 3rdparty: Remove exception usage 2023-06-30 21:37:44 +10:00
Stenzek adca796d94 Common: Remove SafeArray
And replace with std::vector.
2023-06-30 21:37:44 +10:00
Stenzek 732aa96656 Common: Remove AlignedBuffer
And replace its one use site (texture dumping).
2023-06-30 21:37:44 +10:00
Stenzek 6beaec8ba1 Common: Remove Exceptions
The satisfaction is immeasurable.
2023-06-30 21:37:44 +10:00
Stenzek 2ae78f6e2f Misc: Clean up the last places exceptions were used 2023-06-30 21:37:44 +10:00
Stenzek a889acb332 GS: Remove exceptions 2023-06-30 21:37:44 +10:00
Stenzek 81236209db SaveState: Remove exceptions 2023-06-30 21:37:44 +10:00
Stenzek 52266d7ac0 CDVD: Remove exceptions (completely this time)
The actual reads are still missing error checking...
2023-06-30 21:37:44 +10:00
Stenzek ab4592b8e9 Common: Add Error class 2023-06-30 21:37:44 +10:00
Connor McLaughlinandGitHub 7cda571d72 CI/Linux: Enable daily Flathub builds 2023-06-30 20:00:32 +10:00
Stenzek d0ce4c52b0 GS/Vulkan: Set line width unconditionally on line draw 2023-06-30 14:16:35 +10:00
Stenzekandrefractionpcsx2 64ed6f5572 VMManager: Fix cheats warning showing with per-game HC mode 2023-06-29 20:30:10 +01:00
Stenzekandrefractionpcsx2 987bebffc7 GS/Vulkan: Make line width dynamic 2023-06-29 20:29:59 +01:00
Stenzek e9c3807509 CI/Linux: Publish Flathub builds daily [disabled for now] 2023-06-30 02:41:29 +10:00
Stenzek db642b05c0 CI/Linux: Add manifest to AppStream XML 2023-06-30 02:41:29 +10:00
Stenzek 7da904aa00 CI/Linux: Use add-extensions for ffmpeg in Flatpak 2023-06-30 02:41:29 +10:00
lightningterror 8c09daa22d Revert "Sio: Fix Wunused-variable warning."
This reverts commit 9254403a51.
Apparently there were new changes that made use of the variable.
2023-06-28 23:11:39 +02:00
lightningterror 7ebc04bc34 Interpreter: Cleanup constants, casts, formatting. 2023-06-28 22:59:58 +02:00
lightningterror 9254403a51 Sio: Fix Wunused-variable warning. 2023-06-28 22:59:58 +02:00
Connor McLaughlin b4250965e6 ElfObject: Fix inverted condition 2023-06-29 00:32:06 +10:00
Stenzek 3fbe704e21 Sio: Replace reinsert spam with a single message 2023-06-28 22:44:54 +10:00
Stenzek 4bfbc355a2 R5900: Fully get rid of exceptions 2023-06-28 22:44:54 +10:00
Stenzek 4d22102fd1 Interpreter: Use local variables for action PCs 2023-06-28 22:44:54 +10:00
Mrlinkwiiandrefractionpcsx2 129efbda40 GameDB: general clean up 2023-06-28 13:37:54 +01:00
Stenzek 828fb8972c GS/HW: Use range erase instead of vector swap for draw transfers 2023-06-28 20:59:18 +10:00
Stenzek 29b97209fe GS/HW: Split LookupTarget() and CreateTarget() 2023-06-28 20:59:18 +10:00
BerylskidandConnor McLaughlin 9c71bec4a0 UI: Remove outdated info from descritption 2023-06-28 15:56:51 +10:00
TellowKrinkleandTellowKrinkle 1bc24c8d7c GHActions:MacOS: Update to macOS 13
Newer clang fixes fun compiler bugs
2023-06-27 20:22:11 -05:00
kamfretozandrefractionpcsx2 76ae5f3b12 Qt: Adjust hyperlink color for Cobalt and Pizza theme 2023-06-27 21:13:12 +01:00
kamfretozandrefractionpcsx2 7a6c0c6b4b Qt: Update main PCSX2 icon 2023-06-27 21:13:12 +01:00
Stenzek db42792abf GS/HW: When page aligned, dirty page rects instead of SO
Fixes broken scrolling effects in Onimusha 3.
2023-06-27 17:50:04 +10:00
Stenzekandlightningterror 131f16b731 Qt: Update base translation sources 2023-06-27 09:21:23 +02:00
Stenzekandlightningterror 16e47f1d6b Qt: Move audio backend names to core and allow translation 2023-06-27 09:21:23 +02:00
PCSX2 Botandrefractionpcsx2 79e1fd1ea4 PAD: Update to latest controller database. 2023-06-26 23:06:35 +01:00
Mrlinkwiiandrefractionpcsx2 0c3cc59228 GameDB: fixes for WRC4 demos & update patches 2023-06-26 23:02:11 +01:00
Mrlinkwiiandrefractionpcsx2 15db9e1778 GameDB: add missing demos 2023-06-26 20:13:02 +01:00
Stenzek 19cf29e5cf CI/Linux: Push to Flathub beta 2023-06-27 01:50:15 +10:00
refractionpcsx2 d51d51b3cc Memcard: Stop Folder memcards double reindexing 2023-06-26 14:45:50 +01:00
refractionpcsx2 c40e132284 SIO/MCD: hugely improved memcard swapping + reinsertion 2023-06-26 14:45:50 +01:00
Connor McLaughlin f8f54bd892 Qt: Adjust cache folder help text 2023-06-26 20:40:18 +10:00
Stenzek 5302cdcf2b Qt: Remove renderer title from top group box
Save a little vertical space.
2023-06-26 17:52:39 +10:00
Stenzek 8fe9282bd9 Qt: De-duplicate AppIcon 2023-06-26 17:52:39 +10:00
refractionpcsx2 07ed213b1f GameDB: Add blending for Clannad and Clover Heart's VNs 2023-06-25 17:08:22 +01:00
JordanTheToasterandrefractionpcsx2 8a1b8d2091 GameDB: Add missing WRC 3 serial
God help me.
2023-06-25 15:30:36 +01:00
IlDucciandConnor McLaughlin 034ef5692c Qt: Updating language names
Correcting or expanding language names for both variants of Spanish and Portuguese.
2023-06-25 21:14:46 +10:00
Stenzek b9b9405c35 Qt: Hook up current translations 2023-06-25 16:45:37 +10:00
JordanTheToasterandrefractionpcsx2 ca8d4f9ff0 GameDB: Add missing WRC II Fixes
Adds missing demos and fixes to fix SPS on demos.
2023-06-25 04:09:43 +01:00
Stenzek 0dc39a66d7 GS: Use ResetGS() for CSR resets 2023-06-25 12:54:14 +10:00
Stenzek 55e73bb4b9 MTGS: Convert to namespace 2023-06-25 12:54:14 +10:00
refractionpcsx2 6f9164b986 IPU: Slow down BDEC and IDEC so they don't outstrip DMA data writes 2023-06-25 01:05:42 +01:00
TellowKrinkleandrefractionpcsx2 8d27c32418 Updater:Mac: Delay launch of new application until the old one exits
Prevents duplicate dock icons
2023-06-24 22:28:56 +01:00
refractionpcsx2 a17a7ad1ec UI: Expand Achievement login box height slightly 2023-06-24 20:06:53 +01:00
refractionpcsx2 585868f930 GS/Cleanup: Remove some remaining eewrite references 2023-06-24 18:29:28 +01:00
refractionpcsx2 795d0a6682 GS: Double buffer the EE transfer queue 2023-06-24 18:29:28 +01:00
refractionpcsx2 3c0b7f7724 IPU: Redo FIFO transfers, plus small IPU_TO DMA tweak 2023-06-24 18:11:46 +01:00
Stenzek ff23f87010 FullscreenUI: Add patches/cheats to game settings 2023-06-25 01:52:56 +10:00
Stenzek 989fca99c6 FullscreenUI: Add Disable VS expand option 2023-06-25 01:52:56 +10:00
KamFretoZandConnor McLaughlin b44e10df3c Qt: Removes hyperlink color override from Rcheevos 2023-06-24 22:10:33 +10:00
Stenzek c9e9f92c93 Qt: Add Setup Wizard 2023-06-24 15:18:24 +10:00
refractionpcsx2 bb1a366989 GS/HW: Update drawn area and full valid bits on hardware move 2023-06-24 04:50:21 +01:00
refractionpcsx2 1458511756 Config: Don't apply upscaling fixes from GameDB in native
Also removed some stuff we no longer need
2023-06-24 04:49:44 +01:00
JordanTheToasterandrefractionpcsx2 3ebfc81727 GameDB: Spartan Total Warrior Fixes
Fixes for missing post processing.
2023-06-24 01:48:20 +01:00
refractionpcsx2 8d0d59175d DEV9: Fix typo preventing linux debug builds 2023-06-24 01:42:02 +01:00
Tyler WildingandGitHub a46b3f2ed9 New Crowdin updates (#9030) 2023-06-23 15:08:16 -04:00
TheLastRarandrefractionpcsx2 cb224789e2 DEV9: Deduplicate sparse file assert code 2023-06-23 20:05:50 +01:00
Stenzek cd4d829f9f CI/Linux: Use clang 16 for AppImage 2023-06-24 02:10:35 +10:00
refractionpcsx2 faa25f2a96 GameDB: Add minimum blending level for Snow (SLPS 25342 & 25332) 2023-06-23 14:46:35 +01:00
refractionpcsx2 36e8f49b63 GameDB: Add Partial Target Invalidation to Princess Maker 2 2023-06-23 13:42:04 +01:00
refractionpcsx2 e2a4657777 GS/HW: Improve full dirty rect clears. Remember new EE draws.
Rocky Legends transfers the new frame sometimes just before vsync, and it was getting lost.
2023-06-23 13:42:04 +01:00
refractionpcsx2 261b3f7e5c GS/HW: Remove eewrite from invalidatevideomem, allow age on frame 2023-06-23 13:42:04 +01:00
Stenzekandrefractionpcsx2 d6ba2aa76a CI: Prevent double builds on pushes to pcsx2 repo 2023-06-23 13:20:18 +01:00
refractionpcsx2 fb135a87ab GameDB: Fix CLUT colors for Kazuku Keikaku (SLPM-65889) 2023-06-23 13:17:14 +01:00
Stenzekandrefractionpcsx2 286fabaddc MemoryCardFolder: Fix saved message displaying junk 2023-06-23 11:50:39 +01:00
Stenzekandrefractionpcsx2 a79ad44370 Qt: Fix crash when right clicking volume slider 2023-06-23 11:42:23 +01:00
Stenzek 2046a9b414 GS: Use 32-bit vertex positions for culling
More accurate, stops it passing through vertices which are off-screen
and coordinates overflowed.

Differences versus current have been manually verified to be correct.
2023-06-23 19:54:46 +10:00
lightningterror c77d8b3709 DEV9: Cleanup ATA. 2023-06-23 00:52:15 +02:00
lightningterror 7b428bb6b0 DEV9: Cleanup dev9 base tree. 2023-06-23 00:52:15 +02:00
Tyler WildingandGitHub 6986030cd9 ci: don't build the localization branch on push (#9031) 2023-06-22 17:33:10 -04:00
refractionpcsx2 cc9b9a1935 UI: Fix some typo's and casing in UI 2023-06-22 18:42:03 +01:00
JordanTheToasterandrefractionpcsx2 2b7eeba55c GameDB: Matrix Path Of Neo Fixes
Fixes broken post processing by using autoflush.
2023-06-22 10:13:50 +01:00
Stenzek c87dd99824 GS/HW: Remove targets which lie completely within the invalidate range
Fixes part of Burnout 3's car reflections.
2023-06-22 19:12:22 +10:00
Stenzek fbd837eadb GS/HW: Improve draw rect accuracy 2023-06-22 19:12:22 +10:00
Stenzek 7c9c8e197c Common: Replace MemsetFast routines with C memset
And associated cleanup.

On most compilers these days, it'll either inline the memset with vector
fills or rep stosq, or outline with a call to memset.

I trust the compiler is probably going to make a better decision here,
than manual SSE intrinsics.

Ends up a couple of percent faster in FMV decoding.
2023-06-22 19:11:57 +10:00
Stenzek 0366929231 Flatpak: Add screenshots 2023-06-22 18:32:51 +10:00
KamFretoZandrefractionpcsx2 10d5261153 Updater: Clarify the error message when the program being runs directly 2023-06-21 17:32:24 +01:00
refractionpcsx2 3278856764 GS/HW: Adjust BurnoutGames CRC to allow preloading of undercarriage 2023-06-21 15:11:09 +01:00
refractionpcsx2 ff5a9e0ea1 GS/HW: Add target check safety to FFX and Sonic Unleashed CRC hacks 2023-06-21 15:11:09 +01:00
lightningterror 59b0c09443 GS-hw: Fix Wunused-variable warning. 2023-06-21 00:19:26 +02:00
lightningterror ae772e6a74 Elfheader: Fix Wsign-compare warnings. 2023-06-21 00:19:26 +02:00
RedPanda4552andrefractionpcsx2 0a58783a86 Translations: Fix missing context marker on Manual Hardware Fixes string
Fixes CTD when OSD messages print
2023-06-20 21:19:07 +01:00
refractionpcsx2 6f6de13fd4 GameDB: Add VU Clamping to Motorstorm 2023-06-20 20:30:23 +01:00
refractionpcsx2 89dcb78efa GS/CRC: Fix Ar Tonelico 2 CRC hack to check DS exists 2023-06-20 20:14:13 +01:00
Stenzek 703c02c32c Qt: Update base (en) translation 2023-06-20 22:46:00 +10:00
Stenzek adcfca4db3 Qt: Localization support 2023-06-20 22:46:00 +10:00
Stenzek c359223fd4 ImGuiManager: Localization support 2023-06-20 22:46:00 +10:00
Stenzek c4c7d26bb3 Host: Remove now-unused Add[Keyed]FormattedOSDMessage 2023-06-20 22:46:00 +10:00
Stenzek c06bc16b22 Misc: Mark core strings for translation 2023-06-20 22:46:00 +10:00
Stenzek f7bc05c735 Host: Add message translation functions 2023-06-20 22:46:00 +10:00
Stenzek ff02d41992 USB: Make GetDeviceTypes() return C strings 2023-06-20 22:46:00 +10:00
Stenzek ec180e2771 Hotkeys: Fix adjust target speed 2023-06-20 20:36:47 +10:00
Stenzek dffa9e0b8c VMManager: Fix WS patch not applying auto aspect ratio 2023-06-20 20:36:47 +10:00
Stenzek 497e06bcd9 VMManager: Close memcards on boot failure
And get rid of some double shutdowns.
2023-06-20 20:36:47 +10:00
Stenzek 4c67c165fa GS/HW: Preload uploads even when CPU CLUT is on 2023-06-20 12:52:06 +10:00
Stenzek 2c175c0c7e GS/Skip draw when ZTE=1 and ZTST is NEVER 2023-06-20 12:52:06 +10:00
Stenzek 6babbc1ff9 GS/HW: Cache PrimitiveCoversWithoutGaps() value 2023-06-20 12:52:06 +10:00
Stenzek 8af9aace3c GS/Vulkan: Fix incorrect push/pop with cleared colclip target 2023-06-20 12:52:06 +10:00
Stenzek 601b75b611 GS/HW: Fix some incorrect clear behavior 2023-06-20 12:52:06 +10:00
Stenzek 350037fc75 GS: Store clear colour as RGBA32
And defer clears until draw time for DX11 and OpenGL.
2023-06-20 12:52:06 +10:00
Stenzek f6bcfc3abd GS: Make ClearDepth() take a value 2023-06-20 12:52:06 +10:00
Stenzek a480c972f7 GS/HW: Add ReplaceVerticesWithSprite() helper 2023-06-20 12:52:06 +10:00
Stenzek 581ded2c93 GS/HW: Fix mem clear for Z formats 2023-06-20 12:52:06 +10:00
Stenzek 06176e291a GS/Vulkan: Prevent upload heap being used w/ debug and non Re-BAR GPUs 2023-06-20 12:52:06 +10:00
Stenzek 14ee1b40d0 MTGS: Sync privileged registers before loading state
Fixes display registers not being present for the first frame when
loading GS dumps.
2023-06-20 12:52:06 +10:00
refractionpcsx2 9acb98a2c8 Host/Mcd: Fix boot order so memcard type is set before loading memcards 2023-06-19 22:21:16 +01:00
PCSX2 Botandlightningterror daf50df337 PAD: Update to latest controller database. 2023-06-19 18:23:42 +02:00
Stenzek c4d136383c Qt: Fix size of input profile dropdown 2023-06-19 23:16:37 +10:00
Stenzek 5b5016bfd4 USB: Copy configuration when creating input profile
Also reset configuration when requested.
2023-06-19 23:16:37 +10:00
Stenzek 02352ab231 VMManager: Only reload core settings on ELF load
Game/HW fixes are really the only thing which is going to change, so we
can save ourselves some time by only applying those.
2023-06-19 23:16:37 +10:00
Stenzek a4909d3575 Qt: Fix crash booting with mouse mapping 2023-06-19 23:16:37 +10:00
Stenzek fbb50e2895 VMManager: Fix fast forward boot with GS dumps 2023-06-19 23:16:37 +10:00
Stenzek 0e4bf501f1 VMManager: Fix title updates when switching GS dumps 2023-06-19 23:16:37 +10:00
Stenzek 89b97456b7 VMManager: Fix dump playback adding to play time 2023-06-19 23:16:37 +10:00
Stenzek fc4112c459 GS/HW: Implement FBW-based moves
Used by Metal Gear Solid 2, and Zone of the Enders 2.
2023-06-19 13:42:02 +10:00
Stenzekandrefractionpcsx2 b6923f49b1 GS/HW: Add render fix for MGS3 DoF effect 2023-06-17 20:26:19 +01:00
335 changed files with 370754 additions and 8600 deletions
@@ -0,0 +1,41 @@
name: 📦 Publish Flathub Release
on:
schedule:
- cron: "0 0 * * *" # Every day at 12am UTC.
workflow_dispatch: # As well as manually.
jobs:
check:
if: github.repository == 'PCSX2/pcsx2'
name: "Check if release is needed"
runs-on: ubuntu-latest
outputs:
PCSX2_RELEASE: ${{ steps.getinfo.outputs.PCSX2_RELEASE }}
FLATHUB_RELEASE: ${{ steps.getinfo.outputs.FLATHUB_RELEASE }}
steps:
- name: Get latest tag and Flathub release
id: getinfo
env:
GH_TOKEN: ${{ github.token }}
run: |
PCSX2_RELEASE=$(gh api -H 'Accept: application/vnd.github+json' -H 'X-GitHub-Api-Version: 2022-11-28' /repos/PCSX2/pcsx2/releases | jq -r '.[0].tag_name')
FLATHUB_RELEASE=$(curl -L -s https://flathub.org/api/v2/appstream/net.pcsx2.PCSX2 | jq -r '.releases | max_by(.version) | .version')
echo "Latest PCSX2 release is: '${PCSX2_RELEASE}'"
echo "Latest Flathub release is: '${FLATHUB_RELEASE}'"
echo "PCSX2_RELEASE=${PCSX2_RELEASE}" >> "$GITHUB_OUTPUT"
echo "FLATHUB_RELEASE=${FLATHUB_RELEASE}" >> "$GITHUB_OUTPUT"
build:
needs: check
if: needs.check.outputs.FLATHUB_RELEASE < needs.check.outputs.PCSX2_RELEASE
name: "Build and publish Flatpak"
uses: ./.github/workflows/linux_build_flatpak.yml
with:
jobName: "Qt"
compiler: clang
cmakeflags: ""
publish: true
branch: stable
secrets: inherit
+2 -2
View File
@@ -2,8 +2,8 @@ name: 📝 Validate GameDB
on:
push:
branches:
- master
branches-ignore:
- "l10n_master"
paths:
- '**/GameIndex.yaml'
pull_request:
+34 -2
View File
@@ -20,6 +20,10 @@ on:
cmakeflags:
required: true
type: string
branch:
required: false
type: string
default: "stable"
publish:
required: false
type: boolean
@@ -45,6 +49,13 @@ jobs:
with:
submodules: recursive
# Hackity hack. When running the workflow on a schedule, we don't have the tag,
# it doesn't fetch tags, therefore we don't get a version. So grab them manually.
- name: Fetch tags
if: inputs.publish == true
id: fetch-tags
run: git fetch --tags --no-recurse-submodules
- name: Prepare Artifact Metadata
id: artifact-metadata
shell: bash
@@ -73,7 +84,7 @@ jobs:
run: |
./.github/workflows/scripts/linux/generate-metainfo.sh .github/workflows/scripts/linux/flatpak/net.pcsx2.PCSX2.metainfo.xml
cat .github/workflows/scripts/linux/flatpak/net.pcsx2.PCSX2.metainfo.xml
appstream-util validate .github/workflows/scripts/linux/flatpak/net.pcsx2.PCSX2.metainfo.xml
flatpak run org.freedesktop.appstream-glib validate .github/workflows/scripts/linux/flatpak/net.pcsx2.PCSX2.metainfo.xml
- name: Build Flatpak
uses: flatpak/flatpak-github-actions/flatpak-builder@v6.1
@@ -83,8 +94,29 @@ jobs:
arch: x86_64
build-bundle: true
verbose: true
mirror-screenshots-url: https://dl.flathub.org/repo/screenshots
branch: ${{ inputs.branch }}
cache: true
restore-cache: true
cache-key: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.compiler }} ${{ inputs.detail }} flatpak ${{ hashFiles('.github/workflows/scripts/linux/flatpak/**/*.json') }}
# TODO: Push to flathub
- name: Commit screenshots to OSTree
run: |
ostree commit --repo=repo --canonical-permissions --branch=screenshots/x86_64 flatpak_app/screenshots
- name: Push to Flathub beta
if: inputs.publish == true && inputs.branch == 'beta'
uses: flatpak/flatpak-github-actions/flat-manager@v6.1
with:
flat-manager-url: https://hub.flathub.org/
repository: beta
token: ${{ secrets.FLATHUB_BETA_TOKEN }}
- name: Push to Flathub stable
if: inputs.publish == true && inputs.branch == 'stable'
uses: flatpak/flatpak-github-actions/flat-manager@v6.1
with:
flat-manager-url: https://hub.flathub.org/
repository: stable
token: ${{ secrets.FLATHUB_TOKEN }}
+5 -2
View File
@@ -2,8 +2,8 @@ name: 🐧 Linux Builds
on:
push:
branches:
- '*'
branches-ignore:
- "l10n_master"
pull_request:
branches:
- master
@@ -11,6 +11,7 @@ on:
jobs:
build_linux_qt:
name: "AppImage"
if: github.repository != 'PCSX2/pcsx2' || github.event_name == 'pull_request'
uses: ./.github/workflows/linux_build_qt.yml
with:
jobName: "Qt"
@@ -20,9 +21,11 @@ jobs:
secrets: inherit
build_linux_flatpak:
name: "Flatpak"
if: github.repository != 'PCSX2/pcsx2' || github.event_name == 'pull_request'
uses: ./.github/workflows/linux_build_flatpak.yml
with:
jobName: "Qt"
compiler: clang
cmakeflags: ""
publish: false
secrets: inherit
+2 -2
View File
@@ -102,8 +102,8 @@ jobs:
env:
COMPILER: ${{ inputs.compiler }}
ADDITIONAL_CMAKE_ARGS: ${{ inputs.cmakeflags }}
CLANG_PATH: /usr/bin/clang-12
CLANGXX_PATH: /usr/bin/clang++-12
CLANG_PATH: /usr/bin/clang-16
CLANGXX_PATH: /usr/bin/clang++-16
run: |
DEPS_PREFIX="$HOME/deps" .github/workflows/scripts/linux/generate-cmake-qt.sh
+4 -1
View File
@@ -9,7 +9,7 @@ on:
os:
required: false
type: string
default: macos-11.0
default: macos-13
platform:
required: false
type: string
@@ -42,6 +42,9 @@ jobs:
with:
submodules: recursive
- name: Use Xcode 14.3.1
run: sudo xcode-select -s /Applications/Xcode_14.3.1.app
- name: Prepare Artifact Metadata
id: artifact-metadata
shell: bash
+3 -2
View File
@@ -2,8 +2,8 @@ name: 🍎 MacOS Builds
on:
push:
branches:
- '*'
branches-ignore:
- "l10n_master"
pull_request:
branches:
- master
@@ -11,6 +11,7 @@ on:
jobs:
build_macos_qt:
name: "Defaults"
if: github.repository != 'PCSX2/pcsx2' || github.event_name == 'pull_request'
uses: ./.github/workflows/macos_build.yml
with:
jobName: "Qt"
+2 -1
View File
@@ -26,7 +26,8 @@ jobs:
jobName: "Flatpak"
compiler: clang
cmakeflags: ""
publish: true
branch: "stable"
publish: false
secrets: inherit
# Windows
@@ -61,7 +61,6 @@ declare -a SYSLIBS=(
"libwrap.so.0"
"libharfbuzz.so.0"
"libFLAC.so.8"
"libSoundTouch.so.1"
"libXau.so.6"
"libXcomposite.so.1"
"libXcursor.so.1"
@@ -287,7 +286,7 @@ Plugins = ../lib/plugins
EOF
echo "Copy desktop/icon..."
cp "$PCSX2DIR/pcsx2/Resources/AppIcon64.png" "$OUTDIR/PCSX2.png"
cp "$PCSX2DIR/bin/resources/icons/AppIconLarge.png" "$OUTDIR/PCSX2.png"
cp "$SCRIPTDIR/pcsx2-qt.desktop" "$OUTDIR/PCSX2.desktop"
cp "$SCRIPTDIR/AppRun-qt" "$OUTDIR/AppRun"
@@ -1,25 +0,0 @@
{
"name": "soundtouch",
"buildsystem": "cmake-ninja",
"build-options": {
"strip": true
},
"sources": [
{
"type": "git",
"url": "https://codeberg.org/soundtouch/soundtouch.git",
"tag": "2.3.2",
"commit": "29fba832a7920a04eab956b3990c50e13d8c93f9"
}
],
"cleanup": [
"/bin",
"/include",
"/lib/*.a",
"/lib/*.la",
"/lib/cmake",
"/lib/pkgconfig",
"/share/doc"
]
}
@@ -6,11 +6,12 @@
"sdk-extensions": [
"org.freedesktop.Sdk.Extension.llvm16"
],
"add-build-extensions": {
"add-extensions": {
"org.freedesktop.Platform.ffmpeg-full": {
"directory": "lib/ffmpeg",
"version": "22.08",
"add-ld-path": "."
"add-ld-path": ".",
"autodownload": true
}
},
"command": "pcsx2-qt",
@@ -26,7 +27,6 @@
"modules": [
"modules/10-libpcap.json",
"modules/11-libaio.json",
"modules/12-soundtouch.json",
"modules/20-sdl2.json",
"modules/21-libbacktrace.json",
{
@@ -56,7 +56,7 @@
"cd build && ninja unittests && cd .."
],
"post-install": [
"install -Dm644 bin/resources/icons/AppIconLarge.png ${FLATPAK_DEST}/share/icons/hicolor/256x256/apps/net.pcsx2.PCSX2.png",
"install -Dm644 bin/resources/icons/AppIconLarge.png ${FLATPAK_DEST}/share/icons/hicolor/512x512/apps/net.pcsx2.PCSX2.png",
"install -Dm644 .github/workflows/scripts/linux/pcsx2-qt.desktop ${FLATPAK_DEST}/share/applications/net.pcsx2.PCSX2.desktop",
"desktop-file-edit --set-key=Icon --set-value=net.pcsx2.PCSX2 ${FLATPAK_DEST}/share/applications/net.pcsx2.PCSX2.desktop",
"install -Dm644 .github/workflows/scripts/linux/flatpak/net.pcsx2.PCSX2.metainfo.xml ${FLATPAK_DEST}/share/metainfo/net.pcsx2.PCSX2.metainfo.xml"
Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

@@ -3,22 +3,30 @@
SCRIPTDIR=$(dirname "${BASH_SOURCE[0]}")
if [[ $# -lt 1 ]]; then
echo "Output file must be provided as a parameter"
exit 1
echo "Output file must be provided as a parameter"
exit 1
fi
OUTFILE=$1
GIT_DATE=$(git log -1 --pretty=%cd --date=short)
GIT_VERSION=$(git tag --points-at HEAD)
GIT_HASH=$(git rev-parse HEAD)
if [[ "${GIT_VERSION}" == "" ]]; then
GIT_VERSION=$(git rev-parse HEAD)
# In the odd event that we run this script before the release gets tagged.
GIT_VERSION=$(git describe --tags)
if [[ "${GIT_VERSION}" == "" ]]; then
GIT_VERSION=$(git rev-parse HEAD)
fi
fi
echo "GIT_DATE: ${GIT_DATE}"
echo "GIT_VERSION: ${GIT_VERSION}"
echo "GIT_HASH: ${GIT_HASH}"
cp "${SCRIPTDIR}"/pcsx2-qt.metainfo.xml.in "${OUTFILE}"
sed -i -e "s/@GIT_VERSION@/${GIT_VERSION}/" "${OUTFILE}"
sed -i -e "s/@GIT_DATE@/${GIT_DATE}/" "${OUTFILE}"
sed -i -e "s/@GIT_HASH@/${GIT_HASH}/" "${OUTFILE}"
@@ -8,12 +8,21 @@ set -e
ARCH=x86_64
KDE_BRANCH=6.5
BRANCH=22.08
FLAT_MANAGER_CLIENT_DIR="$HOME/.local/bin"
# Build packages.
# Build packages. Mostly needed for flat-manager-client.
declare -a BUILD_PACKAGES=(
"flatpak"
"flatpak-builder"
"appstream-util"
"python3-aiohttp"
"python3-tenacity"
"python3-gi"
"gobject-introspection"
"libappstream-glib8"
"libappstream-glib-dev"
"libappstream-dev"
"gir1.2-ostree-1.0"
)
# Flatpak runtimes and SDKs.
@@ -22,6 +31,7 @@ declare -a FLATPAK_PACKAGES=(
"org.kde.Sdk/${ARCH}/${KDE_BRANCH}"
"org.freedesktop.Platform.ffmpeg-full/${ARCH}/${BRANCH}"
"org.freedesktop.Sdk.Extension.llvm16/${ARCH}/${BRANCH}"
"org.freedesktop.appstream-glib/${ARCH}/stable"
)
retry_command sudo apt-get -qq update
@@ -36,3 +46,10 @@ sudo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub
echo "Will install the following packages for building - ${FLATPAK_PACKAGES[*]}"
retry_command sudo flatpak -y install "${FLATPAK_PACKAGES[@]}"
echo "Downloading flat-manager-client"
mkdir -p "$FLAT_MANAGER_CLIENT_DIR"
pushd "$FLAT_MANAGER_CLIENT_DIR"
aria2c -Z "https://raw.githubusercontent.com/flatpak/flat-manager/master/flat-manager-client"
chmod +x flat-manager-client
echo "$FLAT_MANAGER_CLIENT_DIR" >> $GITHUB_PATH
popd
@@ -52,7 +52,6 @@ declare -a PCSX2_PACKAGES=(
"libpulse-dev"
"librsvg2-dev"
"libsamplerate0-dev"
"libsoundtouch-dev"
"libudev-dev"
"libx11-xcb-dev"
"libavcodec-dev"
@@ -67,7 +66,13 @@ declare -a PCSX2_PACKAGES=(
if [ "${COMPILER}" = "gcc" ]; then
BUILD_PACKAGES+=("g++-10")
else
BUILD_PACKAGES+=("llvm-12" "lld-12" "clang-12")
BUILD_PACKAGES+=("llvm-16" "lld-16" "clang-16")
# Ubuntu 20.04 doesn't ship with LLVM 16, so we need to pull it from the llvm.org repos.
retry_command wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
sudo apt-add-repository -n 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal-16 main'
retry_command sudo apt-get update
retry_command sudo apt-get install clang-16 lld-16
fi
retry_command sudo apt-get -qq update && break
@@ -13,9 +13,20 @@
</description>
<url type="homepage">https://pcsx2.net/</url>
<url type="bugtracker">https://github.com/PCSX2/pcsx2/issues</url>
<screenshots>
<screenshot type="default">
<image>https://raw.githubusercontent.com/PCSX2/pcsx2/master/.github/workflows/scripts/linux/flatpak/screenshots/screenshot1.png</image>
</screenshot>
<screenshot>
<image>https://raw.githubusercontent.com/PCSX2/pcsx2/master/.github/workflows/scripts/linux/flatpak/screenshots/screenshot2.png</image>
</screenshot>
</screenshots>
<content_rating type="oars-1.1"/>
<update_contact>pcsx2_AT_pcsx2.net</update_contact>
<update_contact>stenzek_AT_gmail.com</update_contact>
<releases>
<release version="@GIT_VERSION@" date="@GIT_DATE@" />
</releases>
<custom>
<value key="flathub::manifest">https://raw.githubusercontent.com/PCSX2/pcsx2/@GIT_HASH@/.github/workflows/scripts/linux/flatpak/net.pcsx2.PCSX2.json</value>
</custom>
</component>
+9 -2
View File
@@ -2,8 +2,8 @@ name: 🖥️ Windows Builds
on:
push:
branches:
- '*'
branches-ignore:
- "l10n_master"
pull_request:
branches:
- master
@@ -12,6 +12,7 @@ jobs:
# MSBUILD
lint_vs_proj_files:
name: Lint VS Project Files
if: github.repository != 'PCSX2/pcsx2' || github.event_name == 'pull_request'
runs-on: windows-2019
steps:
- name: Checkout Repository
@@ -22,6 +23,7 @@ jobs:
build_qt_sse4:
needs: lint_vs_proj_files
name: "SSE4"
if: github.repository != 'PCSX2/pcsx2' || github.event_name == 'pull_request'
uses: ./.github/workflows/windows_build_qt.yml
with:
jobName: Qt
@@ -32,6 +34,7 @@ jobs:
build_qt_avx2:
needs: lint_vs_proj_files
name: "AVX2"
if: github.repository != 'PCSX2/pcsx2' || github.event_name == 'pull_request'
uses: ./.github/workflows/windows_build_qt.yml
with:
jobName: Qt
@@ -40,6 +43,7 @@ jobs:
build_qt_cmake:
name: "CMake"
if: github.repository != 'PCSX2/pcsx2' || github.event_name == 'pull_request'
uses: ./.github/workflows/windows_build_qt.yml
with:
jobName: Qt
@@ -50,6 +54,7 @@ jobs:
build_qt_clang_sse4:
needs: lint_vs_proj_files
name: "SSE4"
if: github.repository != 'PCSX2/pcsx2' || github.event_name == 'pull_request'
uses: ./.github/workflows/windows_build_qt.yml
with:
jobName: Qt Clang
@@ -60,6 +65,7 @@ jobs:
build_qt_clang_avx2:
needs: lint_vs_proj_files
name: "AVX2"
if: github.repository != 'PCSX2/pcsx2' || github.event_name == 'pull_request'
uses: ./.github/workflows/windows_build_qt.yml
with:
jobName: Qt Clang
@@ -68,6 +74,7 @@ jobs:
build_qt_cmake_clang:
name: "CMake"
if: github.repository != 'PCSX2/pcsx2' || github.event_name == 'pull_request'
uses: ./.github/workflows/windows_build_qt.yml
with:
jobName: Qt Clang
+2 -1
View File
@@ -9,9 +9,10 @@
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>__WIN32__;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>__WIN32__;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FunctionLevelLinking>true</FunctionLevelLinking>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<ExceptionHandling>false</ExceptionHandling>
<WarningLevel>TurnOffAllWarnings</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
+3 -17
View File
@@ -4764,23 +4764,9 @@ void cGram::demangleClassName(const std::string& input, cName* retvalue, cGram::
std::string sLength = match[1];
std::string name = match[2];
unsigned long length = 0;
bool ok = true;
try {
length = std::stoul(sLength);
}
catch (const std::invalid_argument&) {
ok = false;
}
catch (const std::out_of_range&) {
ok = false;
}
if (ok) {
if (name.length() == length) {
className = name;
}
unsigned long length = std::stoul(sLength);
if (name.length() == length) {
className = name;
}
}
}
+2 -2
View File
@@ -989,11 +989,11 @@ void RA_Shutdown()
// Call shutdown on toolchain
if (_RA_Shutdown != nullptr)
{
#ifdef __cplusplus
#if defined(__cplusplus) && _HAS_EXCEPTIONS
try {
#endif
_RA_Shutdown();
#ifdef __cplusplus
#if defined(__cplusplus) && _HAS_EXCEPTIONS
}
catch (std::runtime_error&) {
}
+17 -3
View File
@@ -1,4 +1,4 @@
add_library(soundtouch
add_library(pcsx2-soundtouch
source/SoundStretch/WavFile.cpp
source/SoundTouch/AAFilter.cpp
source/SoundTouch/BPMDetect.cpp
@@ -30,5 +30,19 @@ add_library(soundtouch
source/SoundTouch/RateTransposer.h
source/SoundTouch/TDStretch.h
)
target_include_directories(soundtouch PUBLIC soundtouch)
add_library(PkgConfig::SOUNDTOUCH ALIAS soundtouch)
target_include_directories(pcsx2-soundtouch PUBLIC soundtouch)
target_compile_definitions(pcsx2-soundtouch PUBLIC SOUNDTOUCH_FLOAT_SAMPLES ST_NO_EXCEPTION_HANDLING)
set_property(TARGET pcsx2-soundtouch PROPERTY CXX_STANDARD 17)
set_property(TARGET pcsx2-soundtouch PROPERTY CXX_STANDARD_REQUIRED ON)
if(NOT "${CMAKE_BUILD_TYPE}" MATCHES "Debug")
if(MSVC)
target_compile_options(pcsx2-soundtouch PRIVATE /O2 /fp:fast)
else()
target_compile_options(pcsx2-soundtouch PRIVATE -Ofast)
endif()
endif()
add_library(SoundTouch::SoundTouch ALIAS pcsx2-soundtouch)
+1
View File
@@ -31,6 +31,7 @@
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>ST_NO_EXCEPTION_HANDLING;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)soundtouch;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
+9 -9
View File
@@ -91,7 +91,7 @@ public:
);
/// destructor
~FIFOSampleBuffer();
~FIFOSampleBuffer() override;
/// Returns a pointer to the beginning of the output samples.
/// This function is provided for accessing the output samples directly.
@@ -100,7 +100,7 @@ public:
/// When using this function to output samples, also remember to 'remove' the
/// output samples from the buffer by calling the
/// 'receiveSamples(numSamples)' function
virtual SAMPLETYPE *ptrBegin();
virtual SAMPLETYPE *ptrBegin() override;
/// Returns a pointer to the end of the used part of the sample buffer (i.e.
/// where the new samples are to be inserted). This function may be used for
@@ -121,7 +121,7 @@ public:
/// the sample buffer.
virtual void putSamples(const SAMPLETYPE *samples, ///< Pointer to samples.
uint numSamples ///< Number of samples to insert.
);
) override;
/// Adjusts the book-keeping to increase number of samples in the buffer without
/// copying any actual samples.
@@ -139,7 +139,7 @@ public:
/// \return Number of samples returned.
virtual uint receiveSamples(SAMPLETYPE *output, ///< Buffer where to copy output samples.
uint maxSamples ///< How many samples to receive at max.
);
) override;
/// Adjusts book-keeping so that given number of samples are removed from beginning of the
/// sample buffer without copying them anywhere.
@@ -147,10 +147,10 @@ public:
/// Used to reduce the number of samples in the buffer when accessing the sample buffer directly
/// with 'ptrBegin' function.
virtual uint receiveSamples(uint maxSamples ///< Remove this many samples from the beginning of pipe.
);
) override;
/// Returns number of samples currently available.
virtual uint numSamples() const;
virtual uint numSamples() const override;
/// Sets number of channels, 1 = mono, 2 = stereo.
void setChannels(int numChannels);
@@ -162,14 +162,14 @@ public:
}
/// Returns nonzero if there aren't any samples available for outputting.
virtual int isEmpty() const;
virtual int isEmpty() const override;
/// Clears all the samples.
virtual void clear();
virtual void clear() override;
/// allow trimming (downwards) amount of samples in pipeline.
/// Returns adjusted amount of samples
uint adjustAmountOfSamples(uint numSamples);
uint adjustAmountOfSamples(uint numSamples) override;
/// Add silence to end of buffer
void addSilent(uint nSamples);
+7 -7
View File
@@ -164,7 +164,7 @@ protected:
}
/// Destructor.
virtual ~FIFOProcessor()
virtual ~FIFOProcessor() override
{
}
@@ -175,7 +175,7 @@ protected:
/// When using this function to output samples, also remember to 'remove' the
/// output samples from the buffer by calling the
/// 'receiveSamples(numSamples)' function
virtual SAMPLETYPE *ptrBegin()
virtual SAMPLETYPE *ptrBegin() override
{
return output->ptrBegin();
}
@@ -189,7 +189,7 @@ public:
/// \return Number of samples returned.
virtual uint receiveSamples(SAMPLETYPE *outBuffer, ///< Buffer where to copy output samples.
uint maxSamples ///< How many samples to receive at max.
)
) override
{
return output->receiveSamples(outBuffer, maxSamples);
}
@@ -200,26 +200,26 @@ public:
/// Used to reduce the number of samples in the buffer when accessing the sample buffer directly
/// with 'ptrBegin' function.
virtual uint receiveSamples(uint maxSamples ///< Remove this many samples from the beginning of pipe.
)
) override
{
return output->receiveSamples(maxSamples);
}
/// Returns number of samples currently available.
virtual uint numSamples() const
virtual uint numSamples() const override
{
return output->numSamples();
}
/// Returns nonzero if there aren't any samples available for outputting.
virtual int isEmpty() const
virtual int isEmpty() const override
{
return output->isEmpty();
}
/// allow trimming (downwards) amount of samples in pipeline.
/// Returns adjusted amount of samples
virtual uint adjustAmountOfSamples(uint numSamples)
virtual uint adjustAmountOfSamples(uint numSamples) override
{
return output->adjustAmountOfSamples(numSamples);
}
+5 -5
View File
@@ -209,7 +209,7 @@ protected :
public:
SoundTouch();
virtual ~SoundTouch();
virtual ~SoundTouch() override;
/// Get SoundTouch library version string
static const char *getVersionString();
@@ -287,7 +287,7 @@ public:
uint numSamples ///< Number of samples in buffer. Notice
///< that in case of stereo-sound a single sample
///< contains data for both channels.
);
) override;
/// Output samples from beginning of the sample buffer. Copies requested samples to
/// output buffer and removes them from the sample buffer. If there are less than
@@ -296,7 +296,7 @@ public:
/// \return Number of samples returned.
virtual uint receiveSamples(SAMPLETYPE *output, ///< Buffer where to copy output samples.
uint maxSamples ///< How many samples to receive at max.
);
) override;
/// Adjusts book-keeping so that given number of samples are removed from beginning of the
/// sample buffer without copying them anywhere.
@@ -304,11 +304,11 @@ public:
/// Used to reduce the number of samples in the buffer when accessing the sample buffer directly
/// with 'ptrBegin' function.
virtual uint receiveSamples(uint maxSamples ///< Remove this many samples from the beginning of pipe.
);
) override;
/// Clears all the samples in the object's output and internal processing
/// buffers.
virtual void clear();
virtual void clear() override;
/// Changes a setting controlling the processing system behaviour. See the
/// 'SETTING_...' defines for available setting ID's.
+3
View File
@@ -0,0 +1,3 @@
// autotools configuration step replaces this file with a configured version.
// this empty file stub is provided to avoid error about missing include file
// when not using autotools build
+4 -4
View File
@@ -106,12 +106,12 @@ public:
short *filterCoeffsUnalign;
short *filterCoeffsAlign;
virtual uint evaluateFilterStereo(short *dest, const short *src, uint numSamples) const;
virtual uint evaluateFilterStereo(short *dest, const short *src, uint numSamples) const override;
public:
FIRFilterMMX();
~FIRFilterMMX();
virtual void setCoefficients(const short *coeffs, uint newLength, uint uResultDivFactor);
virtual void setCoefficients(const short *coeffs, uint newLength, uint uResultDivFactor) override;
};
#endif // SOUNDTOUCH_ALLOW_MMX
@@ -125,12 +125,12 @@ public:
float *filterCoeffsUnalign;
float *filterCoeffsAlign;
virtual uint evaluateFilterStereo(float *dest, const float *src, uint numSamples) const;
virtual uint evaluateFilterStereo(float *dest, const float *src, uint numSamples) const override;
public:
FIRFilterSSE();
~FIRFilterSSE();
virtual void setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor);
virtual void setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor) override;
};
#endif // SOUNDTOUCH_ALLOW_SSE
+4 -4
View File
@@ -43,20 +43,20 @@ class InterpolateCubic : public TransposerBase
protected:
virtual int transposeMono(SAMPLETYPE *dest,
const SAMPLETYPE *src,
int &srcSamples);
int &srcSamples) override;
virtual int transposeStereo(SAMPLETYPE *dest,
const SAMPLETYPE *src,
int &srcSamples);
int &srcSamples) override;
virtual int transposeMulti(SAMPLETYPE *dest,
const SAMPLETYPE *src,
int &srcSamples);
int &srcSamples) override;
double fract;
public:
InterpolateCubic();
virtual void resetRegisters();
virtual void resetRegisters() override;
int getLatency() const
{
+7 -7
View File
@@ -47,21 +47,21 @@ protected:
virtual int transposeMono(SAMPLETYPE *dest,
const SAMPLETYPE *src,
int &srcSamples);
int &srcSamples) override;
virtual int transposeStereo(SAMPLETYPE *dest,
const SAMPLETYPE *src,
int &srcSamples);
virtual int transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples);
int &srcSamples) override;
virtual int transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples) override;
public:
InterpolateLinearInteger();
/// Sets new target rate. Normal rate = 1.0, smaller values represent slower
/// rate, larger faster rates.
virtual void setRate(double newRate);
virtual void setRate(double newRate) override;
virtual void resetRegisters();
virtual void resetRegisters() override;
int getLatency() const
int getLatency() const override
{
return 0;
}
@@ -87,7 +87,7 @@ public:
virtual void resetRegisters();
int getLatency() const
int getLatency() const override
{
return 0;
}
+4 -4
View File
@@ -48,20 +48,20 @@ class InterpolateShannon : public TransposerBase
protected:
int transposeMono(SAMPLETYPE *dest,
const SAMPLETYPE *src,
int &srcSamples);
int &srcSamples) override;
int transposeStereo(SAMPLETYPE *dest,
const SAMPLETYPE *src,
int &srcSamples);
int &srcSamples) override;
int transposeMulti(SAMPLETYPE *dest,
const SAMPLETYPE *src,
int &srcSamples);
int &srcSamples) override;
double fract;
public:
InterpolateShannon();
void resetRegisters();
void resetRegisters() override;
int getLatency() const
{
+4 -4
View File
@@ -124,7 +124,7 @@ protected:
public:
RateTransposer();
virtual ~RateTransposer();
virtual ~RateTransposer() override;
/// Returns the output buffer object
FIFOSamplePipe *getOutput() { return &outputBuffer; };
@@ -147,13 +147,13 @@ public:
/// Adds 'numSamples' pcs of samples from the 'samples' memory position into
/// the input of the object.
void putSamples(const SAMPLETYPE *samples, uint numSamples);
void putSamples(const SAMPLETYPE *samples, uint numSamples) override;
/// Clears all the samples in the object
void clear();
void clear() override;
/// Returns nonzero if there aren't any samples available for outputting.
int isEmpty() const;
int isEmpty() const override;
/// Return approximate initial input-output latency
int getLatency() const;
+9 -9
View File
@@ -165,7 +165,7 @@ protected:
public:
TDStretch();
virtual ~TDStretch();
virtual ~TDStretch() override;
/// Operator 'new' is overloaded so that it automatically creates a suitable instance
/// depending on if we've a MMX/SSE/etc-capable CPU available or not.
@@ -187,7 +187,7 @@ public:
void setTempo(double newTempo);
/// Returns nonzero if there aren't any samples available for outputting.
virtual void clear();
virtual void clear() override;
/// Clears the input buffer
void clearInput();
@@ -227,7 +227,7 @@ public:
const SAMPLETYPE *samples, ///< Input sample data
uint numSamples ///< Number of samples in 'samples' so that one sample
///< contains both channels if stereo
);
) override;
/// return nominal input sample requirement for triggering a processing batch
int getInputSampleReq() const
@@ -256,10 +256,10 @@ public:
class TDStretchMMX : public TDStretch
{
protected:
double calcCrossCorr(const short *mixingPos, const short *compare, double &norm);
double calcCrossCorrAccumulate(const short *mixingPos, const short *compare, double &norm);
virtual void overlapStereo(short *output, const short *input) const;
virtual void clearCrossCorrState();
double calcCrossCorr(const short *mixingPos, const short *compare, double &norm) override;
double calcCrossCorrAccumulate(const short *mixingPos, const short *compare, double &norm) override;
virtual void overlapStereo(short *output, const short *input) const override;
virtual void clearCrossCorrState() override;
};
#endif /// SOUNDTOUCH_ALLOW_MMX
@@ -269,8 +269,8 @@ public:
class TDStretchSSE : public TDStretch
{
protected:
double calcCrossCorr(const float *mixingPos, const float *compare, double &norm);
double calcCrossCorrAccumulate(const float *mixingPos, const float *compare, double &norm);
double calcCrossCorr(const float *mixingPos, const float *compare, double &norm) override;
double calcCrossCorrAccumulate(const float *mixingPos, const float *compare, double &norm) override;
};
#endif /// SOUNDTOUCH_ALLOW_SSE
-2
View File
@@ -62,8 +62,6 @@ endif()
# tests
if(ACTUALLY_ENABLE_TESTS)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
add_subdirectory(3rdparty/gtest EXCLUDE_FROM_ALL)
add_subdirectory(tests/ctest)
endif()
File diff suppressed because it is too large Load Diff
+21 -4
View File
@@ -35,6 +35,7 @@
03000000c82d00006528000000000000,8BitDo N30 Pro 2,a:b1,b:b0,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:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00000290000000000000,8BitDo N64,+rightx:b9,+righty:b3,-rightx:b4,-righty:b8,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,platform:Windows,
03000000c82d00003038000000000000,8BitDo N64,+rightx:b9,+righty:b3,-rightx:b4,-righty:b8,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,platform:Windows,
03000000c82d00006928000000000000,8BitDo N64,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a4,start:b11,platform:Windows,
030000003512000012ab000000000000,8BitDo NES30,a:b2,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Windows,
03000000c82d000012ab000000000000,8BitDo NES30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
03000000022000000090000000000000,8BitDo NES30 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:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
@@ -68,8 +69,11 @@
03000000c82d00000161000000000000,8BitDo SN30 Pro,a:b1,b:b0,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:b4,y:b3,platform:Windows,
03000000c82d00000260000000000000,8BitDo SN30 Pro Plus,a:b1,b:b0,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:b4,y:b3,platform:Windows,
03000000c82d00000261000000000000,8BitDo SN30 Pro Plus,a:b1,b:b0,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:b4,y:b3,platform:Windows,
03000000c82d00001230000000000000,8BitDo Ultimate,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,paddle1:b2,paddle2:b5,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000c82d00001530000000000000,8BitDo Ultimate C,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,
03000000c82d00001630000000000000,8BitDo Ultimate C,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,
03000000c82d00001730000000000000,8BitDo Ultimate C,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,
03000000c82d00001130000000000000,8BitDo Ultimate Wired,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:b26,paddle1:b24,paddle2:b25,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000c82d00001230000000000000,8BitDo Ultimate Wireless,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,
03000000c82d00001330000000000000,8BitDo Ultimate Wireless,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,misc1:b26,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,
03000000c82d00000121000000000000,8BitDo Xbox One SN30 Pro,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,
03000000a00500003232000000000000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,
@@ -386,6 +390,7 @@
03000000242f00007300000000000000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,
0300000079000000d218000000000000,Mayflash Magic NS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000d620000010a7000000000000,Mayflash Magic NS,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,
03000000242f0000f400000000000000,Mayflash N64 Controller 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:a5,start:b9,platform:Windows,
03000000790000007918000000000000,Mayflash N64 Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,righttrigger:b7,rightx:a3,righty:a2,start:b8,platform:Windows,
030000008f0e00001030000000000000,Mayflash Saturn Adapter,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:b7,rightshoulder:b6,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,
0300000025090000e803000000000000,Mayflash Wii Classic Adapter,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:a5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,
@@ -784,6 +789,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000c82d00000451000000010000,8BitDo N30,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:Mac OS X,
03000000c82d00001590000001000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,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:Mac OS X,
03000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00006928000000010000,8BitDo N64,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,platform:Mac OS X,
030000003512000012ab000001000000,8BitDo NES30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d000012ab000001000000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000c82d00002028000000010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,
@@ -807,6 +813,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,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:a5,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00000260000001000000,8BitDo SN30 Pro Plus,a:b1,b:b0,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:b4,y:b3,platform:Mac OS X,
03000000c82d00000261000000010000,8BitDo SN30 Pro Plus,a:b1,b:b0,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:b4,y:b3,platform:Mac OS X,
03000000c82d00001230000000010000,8BitDo Ultimate,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,paddle1:b2,paddle2:b5,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000c82d00001530000001000000,8BitDo Ultimate C,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:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000c82d00001630000001000000,8BitDo Ultimate C,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,
03000000c82d00001730000001000000,8BitDo Ultimate C,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:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000c82d00001130000000020000,8BitDo Ultimate Wired,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,misc1:b26,paddle1:b24,paddle2:b25,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000c82d00001330000001000000,8BitDo Ultimate Wireless,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,misc1:b26,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000c82d00001330000000020000,8BitDo Ultimate 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,misc1:b26,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
@@ -1045,6 +1055,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000c82d00000451000000010000,8BitDo N30,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,
03000000c82d00001590000011010000,8BitDo N30 Pro 2,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,
05000000c82d00006528000000010000,8BitDo N30 Pro 2,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,
05000000c82d00006928000000010000,8BitDo N64,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,platform:Linux,
03000000008000000210000011010000,8BitDo NES30,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
03000000c82d00000310000011010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux,
05000000c82d00008010000000010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux,
@@ -1082,6 +1093,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000c82d00000260000011010000,8BitDo SN30 Pro Plus,a:b1,b:b0,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:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
05000000c82d00000261000000010000,8BitDo SN30 Pro Plus,a:b1,b:b0,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:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
05000000202800000900000000010000,8BitDo SNES30,a:b1,b:b0,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
05000000c82d00001230000000010000,8BitDo Ultimate,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,
03000000c82d00001730000011010000,8BitDo Ultimate 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,
03000000c82d00001530000011010000,8BitDo Ultimate C,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,
03000000c82d00001630000011010000,8BitDo Ultimate C,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,
03000000c82d00001130000011010000,8BitDo Ultimate Wired,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,misc1:b26,paddle1:b24,paddle2:b25,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000c82d00000760000011010000,8BitDo Ultimate Wireless,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
03000000c82d00001230000011010000,8BitDo Ultimate Wireless,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,
@@ -1294,7 +1309,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000005e040000ea02000008040000,Microsoft Xbox One,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,
060000005e040000120b000009050000,Microsoft Xbox One,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,
030000005e040000e302000003020000,Microsoft Xbox One Elite,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,
030000005e040000000b000008040000,Microsoft Xbox One Elite 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,
030000005e040000000b000007040000,Microsoft Xbox One Elite 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,paddle1:b12,paddle2:b14,paddle3:b13,paddle4:b15,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000000b000008040000,Microsoft Xbox One Elite 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,paddle1:b12,paddle2:b14,paddle3:b13,paddle4:b15,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
050000005e040000050b000003090000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
030000005e040000120b00000b050000,Microsoft 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,
03000000030000000300000002000000,Miroof,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,
@@ -1368,6 +1384,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006f0e0000a802000023020000,PDP Xbox One Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,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,
030000006f0e0000a702000023020000,PDP Xbox One Raven Black,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,
030000006f0e0000d802000006640000,PDP 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,
030000006f0e0000ef02000007640000,PDP Xbox Series Kinetic Wired 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,
03000000666600006706000000010000,PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux,
030000004c050000da0c000011010000,PlayStation Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
03000000d9040000160f000000010000,PlayStation Controller Adapter,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:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
@@ -1514,7 +1531,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000ba2200000701000001010000,Technology Innovation PS2 Adapter,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:a5,righty:a2,start:b9,x:b3,y:b2,platform:Linux,
03000000790000001c18000011010000,TGZ Controller,a:b0,b:b1,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:b3,y:b4,platform:Linux,
03000000591c00002400000010010000,THEC64 Joystick,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,
03000000591c00002600000010010000,THEGamepad,a:b2,b:b1,back:b6,leftx:a0,lefty:a1,leftshoulder:b4,rightshoulder:b5,x:b3,y:b0,start:b7,platform:Linux,
03000000591c00002600000010010000,THEGamepad,a:b2,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Linux,
030000004f04000015b3000001010000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
030000004f04000020b3000010010000,Thrustmaster Dual Trigger,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
@@ -1540,7 +1557,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000e00d00000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux,
03000000f00600000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux,
030000005f140000c501000010010000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
06000000f51000000870000003010000,Turtle Beach Recon,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,
06000000f51000000870000003010000,Turtle Beach Recon,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,
03000000100800000100000010010000,Twin PS2 Adapter,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:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
03000000151900005678000010010000,Uniplay U6,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
03000000100800000300000010010000,USB Gamepad,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:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 B

+16 -5
View File
@@ -134,8 +134,6 @@ add_compile_options("${ARCH_FLAG_LIST}")
option(USE_PGO_GENERATE "Enable PGO optimization (generate profile)")
option(USE_PGO_OPTIMIZE "Enable PGO optimization (use profile)")
# Note1: Builtin strcmp/memcmp was proved to be slower on Mesa than stdlib version.
# Note2: float operation SSE is impacted by the PCSX2 SSE configuration. In particular, flush to zero denormal.
if(MSVC AND NOT USE_CLANG_CL)
add_compile_options(
"$<$<COMPILE_LANGUAGE:CXX>:/Zc:externConstexpr>"
@@ -144,8 +142,20 @@ if(MSVC AND NOT USE_CLANG_CL)
"/Zo"
"/utf-8"
)
elseif(NOT MSVC)
add_compile_options(-pipe -fvisibility=hidden -pthread -fno-builtin-strcmp -fno-builtin-memcmp -mfpmath=sse)
endif()
if(MSVC)
# Disable RTTI
string(REPLACE "/GR" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
# Disable Exceptions
string(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
else()
add_compile_options(-pipe -fvisibility=hidden -pthread)
add_compile_options(
"$<$<COMPILE_LANGUAGE:CXX>:-fno-rtti>"
"$<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions>"
)
endif()
set(CONFIG_REL_NO_DEB $<OR:$<CONFIG:Release>,$<CONFIG:MinSizeRel>>)
@@ -156,8 +166,9 @@ if(WIN32)
$<$<CONFIG:Debug>:_ITERATOR_DEBUG_LEVEL=2>
$<$<CONFIG:Devel>:_ITERATOR_DEBUG_LEVEL=1>
$<${CONFIG_ANY_REL}:_ITERATOR_DEBUG_LEVEL=0>
_HAS_EXCEPTIONS=0
)
list(APPEND PCSX2_DEFS TIXML_USE_STL _SCL_SECURE_NO_WARNINGS _UNICODE UNICODE)
list(APPEND PCSX2_DEFS _SCL_SECURE_NO_WARNINGS _UNICODE UNICODE)
endif()
# Enable debug information in release builds for Linux.
+1 -3
View File
@@ -9,7 +9,6 @@ if (WIN32)
add_subdirectory(3rdparty/zlib EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/libpng EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/libjpeg EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/soundtouch EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/wil EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/xz EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/D3D12MemAlloc EXCLUDE_FROM_ALL)
@@ -74,8 +73,6 @@ else()
endif()
endif()
check_lib(SOUNDTOUCH SoundTouch SoundTouch.h PATH_SUFFIXES soundtouch)
if(NOT QT_BUILD)
find_optional_system_library(SDL2 3rdparty/sdl2 2.0.12)
endif()
@@ -165,6 +162,7 @@ endif()
add_subdirectory(3rdparty/lzma EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/libchdr EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/soundtouch EXCLUDE_FROM_ALL)
# rapidyaml includes fast_float as a submodule, saves us pulling it in directly.
# Normally, we'd just pull in the cmake project, and link to it, but... it seems to enable
-113
View File
@@ -42,116 +42,3 @@ extern void _aligned_free(void* pmem);
#define pcsx2_aligned_realloc(handle, new_size, align, old_size) \
_aligned_realloc(handle, new_size, align)
#endif
// --------------------------------------------------------------------------------------
// AlignedBuffer
// --------------------------------------------------------------------------------------
// A simple container class for an aligned allocation. By default, no bounds checking is
// performed, and there is no option for enabling bounds checking. If bounds checking and
// other features are needed, use the more robust SafeArray<> instead.
//
template <typename T, uint align>
class AlignedBuffer
{
static_assert(std::is_pod<T>::value, "Must use a POD type");
struct Deleter
{
void operator()(T* ptr)
{
_aligned_free(ptr);
}
};
std::unique_ptr<T[], Deleter> m_buffer;
std::size_t m_size;
public:
AlignedBuffer(size_t size = 0)
{
Alloc(size);
}
AlignedBuffer(const AlignedBuffer& copy)
{
Alloc(copy.m_size);
if (copy.m_size > 0)
std::memcpy(m_buffer.get(), copy.m_buffer.get(), copy.m_size);
}
AlignedBuffer(AlignedBuffer&& move)
: m_buffer(std::move(move.m_buffer))
, m_size(move.m_size)
{
move.m_size = 0;
}
size_t GetSize() const { return m_size; }
size_t GetLength() const { return m_size; }
void Alloc(size_t newsize)
{
m_size = newsize;
m_buffer.reset();
if (!m_size)
return;
m_buffer.reset(reinterpret_cast<T*>(_aligned_malloc(this->m_size * sizeof(T), align)));
if (!m_buffer)
throw std::bad_alloc();
}
void Resize(size_t newsize)
{
m_buffer.reset(reinterpret_cast<T*>(pcsx2_aligned_realloc(m_buffer.release(), newsize * sizeof(T), align, m_size * sizeof(T))));
m_size = newsize;
if (!m_buffer)
throw std::bad_alloc();
}
void Free()
{
Alloc(0);
}
// Makes enough room for the requested size. Existing data in the array is retained.
void MakeRoomFor(uint size)
{
if (size <= m_size)
return;
Resize(size);
}
AlignedBuffer& operator=(const AlignedBuffer& copy)
{
Alloc(copy.m_size);
if (copy.m_size > 0)
std::memcpy(m_buffer.get(), copy.m_buffer.get(), copy.m_size);
return *this;
}
AlignedBuffer& operator=(AlignedBuffer&& move)
{
m_buffer = std::move(move.m_buffer);
m_size = move.m_size;
move.m_size = 0;
return *this;
}
T* GetPtr(uint idx = 0) const
{
return &m_buffer[idx];
}
T& operator[](uint idx)
{
return m_buffer[idx];
}
const T& operator[](uint idx) const
{
return m_buffer[idx];
}
};
+133
View File
@@ -0,0 +1,133 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2010 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "Threading.h"
#include "General.h"
#include "Assertions.h"
#include "CrashHandler.h"
#include <mutex>
#include "fmt/core.h"
#ifdef _WIN32
#include "RedtapeWindows.h"
#include <intrin.h>
#include <tlhelp32.h>
#endif
#ifdef __UNIX__
#include <signal.h>
#endif
static std::mutex s_assertion_failed_mutex;
static inline void FreezeThreads(void** handle)
{
#if defined(_WIN32)
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (snapshot != INVALID_HANDLE_VALUE)
{
THREADENTRY32 threadEntry;
if (Thread32First(snapshot, &threadEntry))
{
do
{
if (threadEntry.th32ThreadID == GetCurrentThreadId())
continue;
HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE, threadEntry.th32ThreadID);
if (hThread != nullptr)
{
SuspendThread(hThread);
CloseHandle(hThread);
}
} while (Thread32Next(snapshot, &threadEntry));
}
}
*handle = static_cast<void*>(snapshot);
#else
* handle = nullptr;
#endif
}
static inline void ResumeThreads(void* handle)
{
#if defined(_WIN32)
if (handle != INVALID_HANDLE_VALUE)
{
THREADENTRY32 threadEntry;
if (Thread32First(reinterpret_cast<HANDLE>(handle), &threadEntry))
{
do
{
if (threadEntry.th32ThreadID == GetCurrentThreadId())
continue;
HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE, threadEntry.th32ThreadID);
if (hThread != nullptr)
{
ResumeThread(hThread);
CloseHandle(hThread);
}
} while (Thread32Next(reinterpret_cast<HANDLE>(handle), &threadEntry));
}
CloseHandle(reinterpret_cast<HANDLE>(handle));
}
#else
#endif
}
void pxOnAssertFail(const char* file, int line, const char* func, const char* msg)
{
std::unique_lock guard(s_assertion_failed_mutex);
void* handle;
FreezeThreads(&handle);
char full_msg[512];
std::snprintf(full_msg, sizeof(full_msg), "%s:%d: assertion failed in function %s: %s\n", file, line, func, msg);
#if defined(_WIN32)
HANDLE error_handle = GetStdHandle(STD_ERROR_HANDLE);
if (error_handle != INVALID_HANDLE_VALUE)
WriteConsoleA(GetStdHandle(STD_ERROR_HANDLE), full_msg, static_cast<DWORD>(std::strlen(full_msg)), NULL, NULL);
OutputDebugStringA(full_msg);
std::snprintf(
full_msg, sizeof(full_msg),
"Assertion failed in function %s (%s:%d):\n\n%s\n\nPress Abort to exit, Retry to break to debugger, or Ignore to attempt to continue.",
func, file, line, msg);
int result = MessageBoxA(NULL, full_msg, NULL, MB_ABORTRETRYIGNORE | MB_ICONERROR);
if (result == IDRETRY)
{
__debugbreak();
}
else if (result != IDIGNORE)
{
// try to save a crash dump before exiting
CrashHandler::WriteDumpForCaller();
TerminateProcess(GetCurrentProcess(), 0xBAADC0DE);
}
#else
fputs(full_msg, stderr);
fputs("\nAborting application.\n", stderr);
fflush(stderr);
AbortWithMessage(full_msg);
#endif
ResumeThreads(handle);
}
+4 -5
View File
@@ -10,11 +10,11 @@ add_library(common)
# x86emitter sources
target_sources(common PRIVATE
AlignedMalloc.cpp
SafeArray.inl
Assertions.cpp
Console.cpp
CrashHandler.cpp
DynamicLibrary.cpp
Exceptions.cpp
Error.cpp
FastJmp.cpp
FileSystem.cpp
General.cpp
@@ -70,7 +70,7 @@ target_sources(common PRIVATE
DynamicLibrary.h
Easing.h
EnumOps.h
Exceptions.h
Error.h
FastJmp.h
FileSystem.h
General.h
@@ -81,7 +81,6 @@ target_sources(common PRIVATE
HeapArray.h
HTTPDownloader.h
MemorySettingsInterface.h
MemsetFast.inl
MD5Digest.h
MRCHelpers.h
Path.h
@@ -90,7 +89,6 @@ target_sources(common PRIVATE
ReadbackSpinManager.h
RedtapeWilCom.h
RedtapeWindows.h
SafeArray.h
ScopedGuard.h
SettingsInterface.h
SettingsWrapper.h
@@ -101,6 +99,7 @@ target_sources(common PRIVATE
TraceLog.h
WAVWriter.h
WindowInfo.h
WrappedMemCopy.h
emitter/implement/dwshift.h
emitter/implement/group1.h
emitter/implement/group2.h
+2 -2
View File
@@ -33,8 +33,8 @@ namespace CocoaTools
std::optional<std::string> GetNonTranslocatedBundlePath();
/// Move the given file to the trash, and return the path to its new location
std::optional<std::string> MoveToTrash(std::string_view file);
/// Launch the given application
bool LaunchApplication(std::string_view file);
/// Launch the given application once this one quits
bool DelayedLaunch(std::string_view file);
}
#endif // __APPLE__
+9 -20
View File
@@ -175,27 +175,16 @@ std::optional<std::string> CocoaTools::MoveToTrash(std::string_view file)
return std::string([new_url fileSystemRepresentation]);
}
bool CocoaTools::LaunchApplication(std::string_view file)
bool CocoaTools::DelayedLaunch(std::string_view file)
{
NSURL* url = [NSURL fileURLWithPath:[[NSString alloc] initWithBytes:file.data() length:file.size() encoding:NSUTF8StringEncoding]];
if (@available(macOS 10.15, *))
{
// replacement api is async which isn't great for us
std::mutex done;
bool output;
done.lock();
NSWorkspaceOpenConfiguration* config = [NSWorkspaceOpenConfiguration new];
[config setCreatesNewApplicationInstance:YES];
[[NSWorkspace sharedWorkspace] openApplicationAtURL:url configuration:config completionHandler:[&](NSRunningApplication*_Nullable app, NSError*_Nullable error) {
output = app != nullptr;
done.unlock();
@autoreleasepool {
NSTask* task = [NSTask new];
[task setExecutableURL:[NSURL fileURLWithPath:@"/bin/sh"]];
[task setEnvironment:@{
@"WAITPID": [NSString stringWithFormat:@"%d", [[NSProcessInfo processInfo] processIdentifier]],
@"LAUNCHAPP": [[NSString alloc] initWithBytes:file.data() length:file.size() encoding:NSUTF8StringEncoding],
}];
done.lock();
done.unlock();
return output;
}
else
{
return [[NSWorkspace sharedWorkspace] launchApplicationAtURL:url options:NSWorkspaceLaunchNewInstance configuration:@{} error:nil];
[task setArguments:@[@"-c", @"while /bin/ps -p $WAITPID > /dev/null; do /bin/sleep 0.1; done; exec /usr/bin/open \"$LAUNCHAPP\";"]];
return [task launchAndReturnError:nil];
}
}
+192
View File
@@ -0,0 +1,192 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "Error.h"
#include <cstdlib>
#include <cstring>
#include <type_traits>
#include "fmt/format.h"
// Platform-specific includes
#if defined(_WIN32)
#include "RedtapeWindows.h"
static_assert(std::is_same<DWORD, unsigned long>::value, "DWORD is unsigned long");
static_assert(std::is_same<HRESULT, long>::value, "HRESULT is long");
#endif
Error::Error() = default;
Error::Error(const Error& c) = default;
Error::Error(Error&& e) = default;
Error::~Error() = default;
void Error::Clear()
{
m_description = {};
}
void Error::SetErrno(int err)
{
m_type = Type::Errno;
#ifdef _MSC_VER
char buf[128];
if (strerror_s(buf, sizeof(buf), err) != 0)
m_description = fmt::format("errno {}: {}", err, buf);
else
m_description = fmt::format("errno {}: <Could not get error message>", err);
#else
const char* buf = std::strerror(err);
if (buf)
m_description = fmt::format("errno {}: {}", err, buf);
else
m_description = fmt::format("errno {}: <Could not get error message>", err);
#endif
}
void Error::SetErrno(Error* errptr, int err)
{
if (errptr)
errptr->SetErrno(err);
}
void Error::SetString(std::string description)
{
m_type = Type::User;
m_description = std::move(description);
}
void Error::SetString(Error* errptr, std::string description)
{
if (errptr)
errptr->SetString(std::move(description));
}
#ifdef _WIN32
void Error::SetWin32(unsigned long err)
{
m_type = Type::Win32;
char buf[128];
const DWORD r = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, err, 0, buf, sizeof(buf), nullptr);
if (r > 0)
m_description = fmt::format("Win32 Error {}: {}", err, std::string_view(buf, r));
else
m_description = fmt::format("Win32 Error {}: <Could not resolve system error ID>");
}
void Error::SetWin32(Error* errptr, unsigned long err)
{
if (errptr)
errptr->SetWin32(err);
}
void Error::SetHResult(long err)
{
m_type = Type::HResult;
char buf[128];
const DWORD r = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, err, 0, buf, sizeof(buf), nullptr);
if (r > 0)
m_description = fmt::format("HRESULT {:08X}: {}", err, std::string_view(buf, r));
else
m_description = fmt::format("HRESULT {:08X}: <Could not resolve system error ID>");
}
void Error::SetHResult(Error* errptr, long err)
{
if (errptr)
errptr->SetHResult(err);
}
#endif
void Error::SetSocket(int err)
{
// Socket errors are win32 errors on windows
#ifdef _WIN32
SetWin32(err);
#else
SetErrno(err);
#endif
m_type = Type::Socket;
}
void Error::SetSocket(Error* errptr, int err)
{
if (errptr)
errptr->SetSocket(err);
}
Error Error::CreateNone()
{
return Error();
}
Error Error::CreateErrno(int err)
{
Error ret;
ret.SetErrno(err);
return ret;
}
Error Error::CreateSocket(int err)
{
Error ret;
ret.SetSocket(err);
return ret;
}
Error Error::CreateString(std::string description)
{
Error ret;
ret.SetString(std::move(description));
return ret;
}
#ifdef _WIN32
Error Error::CreateWin32(unsigned long err)
{
Error ret;
ret.SetWin32(err);
return ret;
}
Error Error::CreateHResult(long err)
{
Error ret;
ret.SetHResult(err);
return ret;
}
#endif
Error& Error::operator=(const Error& e) = default;
Error& Error::operator=(Error&& e) = default;
bool Error::operator==(const Error& e) const
{
return (m_type == e.m_type && m_description == e.m_description);
}
bool Error::operator!=(const Error& e) const
{
return (m_type != e.m_type || m_description != e.m_description);
}
+84
View File
@@ -0,0 +1,84 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "Pcsx2Defs.h"
#include <string>
class Error
{
public:
Error();
Error(const Error& e);
Error(Error&& e);
~Error();
enum class Type
{
None = 0,
Errno = 1,
Socket = 2,
User = 3,
Win32 = 4,
HResult = 5,
};
__fi Type GetType() const { return m_type; }
__fi const std::string& GetDescription() const { return m_description; }
void Clear();
/// Error that is set by system functions, such as open().
void SetErrno(int err);
/// Error that is set by socket functions, such as socket(). On Unix this is the same as errno.
void SetSocket(int err);
/// Set both description and message.
void SetString(std::string description);
#ifdef _WIN32
/// Error that is returned by some Win32 functions, such as RegOpenKeyEx. Also used by other APIs through GetLastError().
void SetWin32(unsigned long err);
/// Error that is returned by Win32 COM methods, e.g. S_OK.
void SetHResult(long err);
#endif
static Error CreateNone();
static Error CreateErrno(int err);
static Error CreateSocket(int err);
static Error CreateString(std::string description);
#ifdef _WIN32
static Error CreateWin32(unsigned long err);
static Error CreateHResult(long err);
#endif
// helpers for setting
static void SetErrno(Error* errptr, int err);
static void SetSocket(Error* errptr, int err);
static void SetString(Error* errptr, std::string description);
static void SetWin32(Error* errptr, unsigned long err);
static void SetHResult(Error* errptr, long err);
Error& operator=(const Error& e);
Error& operator=(Error&& e);
bool operator==(const Error& e) const;
bool operator!=(const Error& e) const;
private:
Type m_type = Type::None;
std::string m_description;
};
-346
View File
@@ -1,346 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2010 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "Threading.h"
#include "General.h"
#include "Exceptions.h"
#include "CrashHandler.h"
#include <mutex>
#include "fmt/core.h"
#ifdef _WIN32
#include "RedtapeWindows.h"
#include <intrin.h>
#include <tlhelp32.h>
#endif
#ifdef __UNIX__
#include <signal.h>
#endif
static std::mutex s_assertion_failed_mutex;
static inline void FreezeThreads(void** handle)
{
#if defined(_WIN32)
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (snapshot != INVALID_HANDLE_VALUE)
{
THREADENTRY32 threadEntry;
if (Thread32First(snapshot, &threadEntry))
{
do
{
if (threadEntry.th32ThreadID == GetCurrentThreadId())
continue;
HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE, threadEntry.th32ThreadID);
if (hThread != nullptr)
{
SuspendThread(hThread);
CloseHandle(hThread);
}
} while (Thread32Next(snapshot, &threadEntry));
}
}
*handle = static_cast<void*>(snapshot);
#else
* handle = nullptr;
#endif
}
static inline void ResumeThreads(void* handle)
{
#if defined(_WIN32)
if (handle != INVALID_HANDLE_VALUE)
{
THREADENTRY32 threadEntry;
if (Thread32First(reinterpret_cast<HANDLE>(handle), &threadEntry))
{
do
{
if (threadEntry.th32ThreadID == GetCurrentThreadId())
continue;
HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE, threadEntry.th32ThreadID);
if (hThread != nullptr)
{
ResumeThread(hThread);
CloseHandle(hThread);
}
} while (Thread32Next(reinterpret_cast<HANDLE>(handle), &threadEntry));
}
CloseHandle(reinterpret_cast<HANDLE>(handle));
}
#else
#endif
}
void pxOnAssertFail(const char* file, int line, const char* func, const char* msg)
{
std::unique_lock guard(s_assertion_failed_mutex);
void* handle;
FreezeThreads(&handle);
char full_msg[512];
std::snprintf(full_msg, sizeof(full_msg), "%s:%d: assertion failed in function %s: %s\n", file, line, func, msg);
#if defined(_WIN32)
HANDLE error_handle = GetStdHandle(STD_ERROR_HANDLE);
if (error_handle != INVALID_HANDLE_VALUE)
WriteConsoleA(GetStdHandle(STD_ERROR_HANDLE), full_msg, static_cast<DWORD>(std::strlen(full_msg)), NULL, NULL);
OutputDebugStringA(full_msg);
std::snprintf(
full_msg, sizeof(full_msg),
"Assertion failed in function %s (%s:%d):\n\n%s\n\nPress Abort to exit, Retry to break to debugger, or Ignore to attempt to continue.",
func, file, line, msg);
int result = MessageBoxA(NULL, full_msg, NULL, MB_ABORTRETRYIGNORE | MB_ICONERROR);
if (result == IDRETRY)
{
__debugbreak();
}
else if (result != IDIGNORE)
{
// try to save a crash dump before exiting
CrashHandler::WriteDumpForCaller();
TerminateProcess(GetCurrentProcess(), 0xBAADC0DE);
}
#else
fputs(full_msg, stderr);
fputs("\nAborting application.\n", stderr);
fflush(stderr);
AbortWithMessage(full_msg);
#endif
ResumeThreads(handle);
}
// --------------------------------------------------------------------------------------
// BaseException (implementations)
// --------------------------------------------------------------------------------------
BaseException& BaseException::SetBothMsgs(const char* msg_diag)
{
m_message_user = msg_diag ? std::string(msg_diag) : std::string();
return SetDiagMsg(msg_diag);
}
BaseException& BaseException::SetDiagMsg(std::string msg_diag)
{
m_message_diag = std::move(msg_diag);
return *this;
}
BaseException& BaseException::SetUserMsg(std::string msg_user)
{
m_message_user = std::move(msg_user);
return *this;
}
std::string BaseException::FormatDiagnosticMessage() const
{
return m_message_diag;
}
std::string BaseException::FormatDisplayMessage() const
{
return m_message_user.empty() ? m_message_diag : m_message_user;
}
// --------------------------------------------------------------------------------------
// Exception::RuntimeError (implementations)
// --------------------------------------------------------------------------------------
Exception::RuntimeError::RuntimeError(const std::runtime_error& ex, const char* prefix /* = nullptr */)
{
IsSilent = false;
const bool has_prefix = prefix && prefix[0] != 0;
SetDiagMsg(fmt::format("STL Runtime Error{}{}{}: {}",
has_prefix ? " (" : "", prefix ? prefix : "", has_prefix ? ")" : "",
ex.what()));
}
Exception::RuntimeError::RuntimeError(const std::exception& ex, const char* prefix /* = nullptr */)
{
IsSilent = false;
const bool has_prefix = prefix && prefix[0] != 0;
SetDiagMsg(fmt::format("STL Exception{}{}{}: {}",
has_prefix ? " (" : "", prefix ? prefix : "", has_prefix ? ")" : "",
ex.what()));
}
// --------------------------------------------------------------------------------------
// Exception::BadStream (implementations)
// --------------------------------------------------------------------------------------
std::string Exception::BadStream::FormatDiagnosticMessage() const
{
std::string retval;
_formatDiagMsg(retval);
return retval;
}
std::string Exception::BadStream::FormatDisplayMessage() const
{
std::string retval;
_formatUserMsg(retval);
return retval;
}
void Exception::BadStream::_formatDiagMsg(std::string& dest) const
{
fmt::format_to(std::back_inserter(dest), "Path: ");
if (!StreamName.empty())
fmt::format_to(std::back_inserter(dest), "{}", StreamName);
else
dest += "[Unnamed or unknown]";
if (!m_message_diag.empty())
fmt::format_to(std::back_inserter(dest), "\n{}", m_message_diag);
}
void Exception::BadStream::_formatUserMsg(std::string& dest) const
{
fmt::format_to(std::back_inserter(dest), "Path: ");
if (!StreamName.empty())
fmt::format_to(std::back_inserter(dest), "{}", StreamName);
else
dest += "[Unnamed or unknown]";
if (!m_message_user.empty())
fmt::format_to(std::back_inserter(dest), "\n{}", m_message_user);
}
// --------------------------------------------------------------------------------------
// Exception::CannotCreateStream (implementations)
// --------------------------------------------------------------------------------------
std::string Exception::CannotCreateStream::FormatDiagnosticMessage() const
{
std::string retval;
retval = "File could not be created.";
_formatDiagMsg(retval);
return retval;
}
std::string Exception::CannotCreateStream::FormatDisplayMessage() const
{
std::string retval;
retval = "A file could not be created.\n";
_formatUserMsg(retval);
return retval;
}
// --------------------------------------------------------------------------------------
// Exception::FileNotFound (implementations)
// --------------------------------------------------------------------------------------
std::string Exception::FileNotFound::FormatDiagnosticMessage() const
{
std::string retval;
retval = "File not found.\n";
_formatDiagMsg(retval);
return retval;
}
std::string Exception::FileNotFound::FormatDisplayMessage() const
{
std::string retval;
retval = "File not found.\n";
_formatUserMsg(retval);
return retval;
}
// --------------------------------------------------------------------------------------
// Exception::AccessDenied (implementations)
// --------------------------------------------------------------------------------------
std::string Exception::AccessDenied::FormatDiagnosticMessage() const
{
std::string retval;
retval = "Permission denied to file.\n";
_formatDiagMsg(retval);
return retval;
}
std::string Exception::AccessDenied::FormatDisplayMessage() const
{
std::string retval;
retval = "Permission denied while trying to open file, likely due to insufficient user account rights.\n";
_formatUserMsg(retval);
return retval;
}
// --------------------------------------------------------------------------------------
// Exception::EndOfStream (implementations)
// --------------------------------------------------------------------------------------
std::string Exception::EndOfStream::FormatDiagnosticMessage() const
{
std::string retval;
retval = "Unexpected end of file or stream.\n";
_formatDiagMsg(retval);
return retval;
}
std::string Exception::EndOfStream::FormatDisplayMessage() const
{
std::string retval;
retval = "Unexpected end of file or stream encountered. File is probably truncated or corrupted.\n";
_formatUserMsg(retval);
return retval;
}
// --------------------------------------------------------------------------------------
// Exceptions from Errno (POSIX)
// --------------------------------------------------------------------------------------
// Translates an Errno code into an exception.
// Throws an exception based on the given error code (usually taken from ANSI C's errno)
std::unique_ptr<BaseException> Exception::FromErrno(std::string streamname, int errcode)
{
pxAssumeDev(errcode != 0, "Invalid NULL error code? (errno)");
switch (errcode)
{
case EINVAL:
pxFailDev("Invalid argument");
return std::unique_ptr<BaseException>(&(new Exception::BadStream(streamname))->SetDiagMsg("Invalid argument? (likely caused by an unforgivable programmer error!)"));
case EACCES: // Access denied!
return std::unique_ptr<BaseException>(new Exception::AccessDenied(streamname));
case EMFILE: // Too many open files!
return std::unique_ptr<BaseException>(&(new Exception::CannotCreateStream(streamname))->SetDiagMsg("Too many open files")); // File handle allocation failure
case EEXIST:
return std::unique_ptr<BaseException>(&(new Exception::CannotCreateStream(streamname))->SetDiagMsg("File already exists"));
case ENOENT: // File not found!
return std::unique_ptr<BaseException>(new Exception::FileNotFound(streamname));
case EPIPE:
return std::unique_ptr<BaseException>(&(new Exception::BadStream(streamname))->SetDiagMsg("Broken pipe"));
case EBADF:
return std::unique_ptr<BaseException>(&(new Exception::BadStream(streamname))->SetDiagMsg("Bad file number"));
default:
return std::unique_ptr<BaseException>(&(new Exception::BadStream(streamname))->SetDiagMsg(fmt::format("General file/stream error [errno: {}]", errcode)));
}
}
-255
View File
@@ -1,255 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2010 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <memory>
#include <stdexcept>
#include "common/Assertions.h"
#include "common/Pcsx2Defs.h"
namespace Exception
{
class BaseException;
std::unique_ptr<BaseException> FromErrno(std::string streamname, int errcode);
// --------------------------------------------------------------------------------------
// BaseException
// --------------------------------------------------------------------------------------
// std::exception sucks, and isn't entirely cross-platform reliable in its implementation,
// so I made a replacement. The internal messages are non-const, which means that a
// catch clause can optionally modify them and then re-throw to a top-level handler.
//
// Note, this class is "abstract" which means you shouldn't use it directly like, ever.
// Use Exception::RuntimeError instead for generic exceptions.
//
// Because exceptions are the (only!) really useful example of multiple inheritance,
// this class has only a trivial constructor, and must be manually initialized using
// InitBaseEx() or by individual member assignments. This is because C++ multiple inheritence
// is, by design, a lot of fail, especially when class initializers are mixed in.
//
// [TODO] : Add an InnerException component, and Clone() facility.
//
class BaseException
{
protected:
std::string m_message_diag; // (untranslated) a "detailed" message of what disastrous thing has occurred!
std::string m_message_user; // (translated) a "detailed" message of what disastrous thing has occurred!
public:
virtual ~BaseException() = default;
const std::string& DiagMsg() const { return m_message_diag; }
const std::string& UserMsg() const { return m_message_user; }
std::string& DiagMsg() { return m_message_diag; }
std::string& UserMsg() { return m_message_user; }
BaseException& SetBothMsgs(const char* msg_diag);
BaseException& SetDiagMsg(std::string msg_diag);
BaseException& SetUserMsg(std::string msg_user);
// Returns a message suitable for diagnostic / logging purposes.
// This message is always in English, and includes a full stack trace.
virtual std::string FormatDiagnosticMessage() const;
// Returns a message suitable for end-user display.
// This message is usually meant for display in a user popup or such.
virtual std::string FormatDisplayMessage() const;
virtual void Rethrow() const = 0;
virtual BaseException* Clone() const = 0;
};
// Some helper macros for defining the standard constructors of internationalized constructors
// Parameters:
// classname - Yeah, the name of this class being defined. :)
//
// defmsg - default message (in english), which will be used for both english and i18n messages.
// The text string will be passed through the translator, so if it's int he gettext database
// it will be optionally translated.
//
// BUGZ?? I'd rather use 'classname' on the Clone() prototype, but for some reason it generates
// ambiguity errors on virtual inheritance (it really shouldn't!). So I have to force it to the
// BaseException base class. Not sure if this is Stupid Standard Tricks or Stupid MSVC Tricks. --air
//
// (update: web searches indicate it's MSVC specific -- happens in 2008, not sure about 2010).
//
#define DEFINE_EXCEPTION_COPYTORS(classname, parent) \
private: \
typedef parent _parent; \
\
public: \
virtual ~classname() = default; \
\
virtual void Rethrow() const override \
{ \
throw *this; \
} \
\
virtual classname* Clone() const override \
{ \
return new classname(*this); \
}
#define DEFINE_EXCEPTION_MESSAGES(classname) \
public: \
classname& SetBothMsgs(const char* msg_diag) \
{ \
BaseException::SetBothMsgs(msg_diag); \
return *this; \
} \
\
classname& SetDiagMsg(std::string msg_diag) \
{ \
m_message_diag = msg_diag; \
return *this; \
} \
\
classname& SetUserMsg(std::string msg_user) \
{ \
m_message_user = std::move(msg_user); \
return *this; \
}
#define DEFINE_RUNTIME_EXCEPTION(classname, parent, message) \
DEFINE_EXCEPTION_COPYTORS(classname, parent) \
classname() \
{ \
SetDiagMsg(message); \
} \
DEFINE_EXCEPTION_MESSAGES(classname)
// ---------------------------------------------------------------------------------------
// RuntimeError - Generalized Exceptions with Recoverable Traits!
// ---------------------------------------------------------------------------------------
class RuntimeError : public BaseException
{
DEFINE_EXCEPTION_COPYTORS(RuntimeError, BaseException)
DEFINE_EXCEPTION_MESSAGES(RuntimeError)
public:
bool IsSilent;
RuntimeError() { IsSilent = false; }
RuntimeError(const std::runtime_error& ex, const char* prefix = nullptr);
RuntimeError(const std::exception& ex, const char* prefix = nullptr);
};
// ---------------------------------------------------------------------------------------
// Streaming (file) Exceptions:
// Stream / BadStream / CannotCreateStream / FileNotFound / AccessDenied / EndOfStream
// ---------------------------------------------------------------------------------------
#define DEFINE_STREAM_EXCEPTION(classname, parent) \
DEFINE_RUNTIME_EXCEPTION(classname, parent, "") \
classname(std::string filename) \
{ \
StreamName = filename; \
} \
virtual classname& SetStreamName(std::string name) override \
{ \
StreamName = std::move(name); \
return *this; \
} \
\
virtual classname& SetStreamName(const char* name) override \
{ \
StreamName = name; \
return *this; \
}
// A generic base error class for bad streams -- corrupted data, sudden closures, loss of
// connection, or anything else that would indicate a failure to open a stream or read the
// data after the stream was successfully opened.
//
class BadStream : public RuntimeError
{
DEFINE_RUNTIME_EXCEPTION(BadStream, RuntimeError, "")
public:
BadStream(std::string filename)
: StreamName(std::move(filename))
{
}
virtual BadStream& SetStreamName(std::string name)
{
StreamName = std::move(name);
return *this;
}
virtual BadStream& SetStreamName(const char* name)
{
StreamName = name;
return *this;
}
std::string StreamName; // name of the stream (if applicable)
virtual std::string FormatDiagnosticMessage() const override;
virtual std::string FormatDisplayMessage() const override;
protected:
void _formatDiagMsg(std::string& dest) const;
void _formatUserMsg(std::string& dest) const;
};
// A generic exception for odd-ball stream creation errors.
//
class CannotCreateStream : public BadStream
{
DEFINE_STREAM_EXCEPTION(CannotCreateStream, BadStream)
virtual std::string FormatDiagnosticMessage() const override;
virtual std::string FormatDisplayMessage() const override;
};
// Exception thrown when an attempt to open a non-existent file is made.
// (this exception can also mean file permissions are invalid)
//
class FileNotFound : public CannotCreateStream
{
public:
DEFINE_STREAM_EXCEPTION(FileNotFound, CannotCreateStream)
virtual std::string FormatDiagnosticMessage() const override;
virtual std::string FormatDisplayMessage() const override;
};
class AccessDenied : public CannotCreateStream
{
public:
DEFINE_STREAM_EXCEPTION(AccessDenied, CannotCreateStream)
virtual std::string FormatDiagnosticMessage() const override;
virtual std::string FormatDisplayMessage() const override;
};
// EndOfStream can be used either as an error, or used just as a shortcut for manual
// feof checks.
//
class EndOfStream : public BadStream
{
public:
DEFINE_STREAM_EXCEPTION(EndOfStream, BadStream)
virtual std::string FormatDiagnosticMessage() const override;
virtual std::string FormatDisplayMessage() const override;
};
} // namespace Exception
using Exception::BaseException;
+32 -12
View File
@@ -14,12 +14,14 @@
*/
#include "FileSystem.h"
#include "Error.h"
#include "Path.h"
#include "Assertions.h"
#include "Console.h"
#include "StringUtil.h"
#include "Path.h"
#include <algorithm>
#include <cerrno>
#include <cstdlib>
#include <cstring>
#include <limits>
@@ -596,7 +598,7 @@ std::string Path::Combine(const std::string_view& base, const std::string_view&
return ret;
}
std::FILE* FileSystem::OpenCFile(const char* filename, const char* mode)
std::FILE* FileSystem::OpenCFile(const char* filename, const char* mode, Error* error)
{
#ifdef _WIN32
const std::wstring wfilename(StringUtil::UTF8StringToWideString(filename));
@@ -604,23 +606,34 @@ std::FILE* FileSystem::OpenCFile(const char* filename, const char* mode)
if (!wfilename.empty() && !wmode.empty())
{
std::FILE* fp;
if (_wfopen_s(&fp, wfilename.c_str(), wmode.c_str()) != 0)
const errno_t err = _wfopen_s(&fp, wfilename.c_str(), wmode.c_str());
if (err != 0)
{
Error::SetErrno(error, err);
return nullptr;
}
return fp;
}
std::FILE* fp;
if (fopen_s(&fp, filename, mode) != 0)
const errno_t err = fopen_s(&fp, filename, mode);
if (err != 0)
{
Error::SetErrno(error, err);
return nullptr;
}
return fp;
#else
return std::fopen(filename, mode);
std::FILE* fp = std::fopen(filename, mode);
if (!fp)
Error::SetErrno(error, errno);
return fp;
#endif
}
int FileSystem::OpenFDFile(const char* filename, int flags, int mode)
int FileSystem::OpenFDFile(const char* filename, int flags, int mode, Error* error)
{
#ifdef _WIN32
const std::wstring wfilename(StringUtil::UTF8StringToWideString(filename));
@@ -629,16 +642,19 @@ int FileSystem::OpenFDFile(const char* filename, int flags, int mode)
return -1;
#else
return open(filename, flags, mode);
const int fd = open(filename, flags, mode);
if (fd < 0)
Error::SetErrno(error, errno);
return fd;
#endif
}
FileSystem::ManagedCFilePtr FileSystem::OpenManagedCFile(const char* filename, const char* mode)
FileSystem::ManagedCFilePtr FileSystem::OpenManagedCFile(const char* filename, const char* mode, Error* error)
{
return ManagedCFilePtr(OpenCFile(filename, mode), [](std::FILE* fp) { std::fclose(fp); });
return ManagedCFilePtr(OpenCFile(filename, mode, error), [](std::FILE* fp) { std::fclose(fp); });
}
std::FILE* FileSystem::OpenSharedCFile(const char* filename, const char* mode, FileShareMode share_mode)
std::FILE* FileSystem::OpenSharedCFile(const char* filename, const char* mode, FileShareMode share_mode, Error* error)
{
#ifdef _WIN32
const std::wstring wfilename(StringUtil::UTF8StringToWideString(filename));
@@ -668,15 +684,19 @@ std::FILE* FileSystem::OpenSharedCFile(const char* filename, const char* mode, F
if (fp)
return fp;
Error::SetErrno(error, errno);
return nullptr;
#else
return std::fopen(filename, mode);
std::FILE* fp = std::fopen(filename, mode);
if (!fp)
Error::SetErrno(error, errno);
return fp;
#endif
}
FileSystem::ManagedCFilePtr FileSystem::OpenManagedSharedCFile(const char* filename, const char* mode, FileShareMode share_mode)
FileSystem::ManagedCFilePtr FileSystem::OpenManagedSharedCFile(const char* filename, const char* mode, FileShareMode share_mode, Error* error)
{
return ManagedCFilePtr(OpenSharedCFile(filename, mode, share_mode), [](std::FILE* fp) { std::fclose(fp); });
return ManagedCFilePtr(OpenSharedCFile(filename, mode, share_mode, error), [](std::FILE* fp) { std::fclose(fp); });
}
int FileSystem::FSeek64(std::FILE* fp, s64 offset, int whence)
+7 -5
View File
@@ -23,6 +23,8 @@
#include <vector>
#include <sys/stat.h>
class Error;
#ifdef _WIN32
#define FS_OSPATH_SEPARATOR_CHARACTER '\\'
#define FS_OSPATH_SEPARATOR_STR "\\"
@@ -102,13 +104,13 @@ namespace FileSystem
/// open files
using ManagedCFilePtr = std::unique_ptr<std::FILE, void (*)(std::FILE*)>;
ManagedCFilePtr OpenManagedCFile(const char* filename, const char* mode);
std::FILE* OpenCFile(const char* filename, const char* mode);
ManagedCFilePtr OpenManagedCFile(const char* filename, const char* mode, Error* error = nullptr);
std::FILE* OpenCFile(const char* filename, const char* mode, Error* error = nullptr);
int FSeek64(std::FILE* fp, s64 offset, int whence);
s64 FTell64(std::FILE* fp);
s64 FSize64(std::FILE* fp);
int OpenFDFile(const char* filename, int flags, int mode);
int OpenFDFile(const char* filename, int flags, int mode, Error* error = nullptr);
/// Sharing modes for OpenSharedCFile().
enum class FileShareMode
@@ -121,8 +123,8 @@ namespace FileSystem
/// Opens a file in shareable mode (where other processes can access it concurrently).
/// Only has an effect on Windows systems.
ManagedCFilePtr OpenManagedSharedCFile(const char* filename, const char* mode, FileShareMode share_mode);
std::FILE* OpenSharedCFile(const char* filename, const char* mode, FileShareMode share_mode);
ManagedCFilePtr OpenManagedSharedCFile(const char* filename, const char* mode, FileShareMode share_mode, Error* error = nullptr);
std::FILE* OpenSharedCFile(const char* filename, const char* mode, FileShareMode share_mode, Error* error = nullptr);
std::optional<std::vector<u8>> ReadBinaryFile(const char* filename);
std::optional<std::vector<u8>> ReadBinaryFile(std::FILE* fp);
-18
View File
@@ -198,24 +198,6 @@ private:
#define SafeSysMunmap(ptr, size) \
((void)(HostSys::Munmap(ptr, size), (ptr) = 0))
// This method can clear any object-like entity -- which is anything that is not a pointer.
// Structures, static arrays, etc. No need to include sizeof() crap, this does it automatically
// for you!
template <typename T>
static __fi void memzero(T& object)
{
static_assert(std::is_trivially_copyable_v<T>);
std::memset(&object, 0, sizeof(T));
}
// This method clears an object with the given 8 bit value.
template <u8 data, typename T>
static __fi void memset8(T& object)
{
static_assert(std::is_trivially_copyable_v<T>);
std::memset(&object, data, sizeof(T));
}
extern u64 GetTickFrequency();
extern u64 GetCPUTicks();
extern u64 GetPhysicalMemory();
-1
View File
@@ -28,7 +28,6 @@
#include "common/Align.h"
#include "common/Assertions.h"
#include "common/Console.h"
#include "common/Exceptions.h"
#include "common/General.h"
// Apple uses the MAP_ANON define instead of MAP_ANONYMOUS, but they mean
-95
View File
@@ -1,95 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2010 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <xmmintrin.h>
template <u8 data>
__noinline void memset_sse_a(void* dest, const size_t size)
{
const uint MZFqwc = size / 16;
pxAssert((size & 0xf) == 0);
__m128 srcreg;
if (data != 0)
{
alignas(16) static const u8 loadval[8] = {data, data, data, data, data, data, data, data};
srcreg = _mm_loadh_pi(_mm_load_ps((float*)loadval), (__m64*)loadval);
}
else
srcreg = _mm_setzero_ps();
float(*destxmm)[4] = (float(*)[4])dest;
switch (MZFqwc & 0x07)
{
case 0x07:
_mm_store_ps(&destxmm[0x07 - 1][0], srcreg);
// Fall through
case 0x06:
_mm_store_ps(&destxmm[0x06 - 1][0], srcreg);
// Fall through
case 0x05:
_mm_store_ps(&destxmm[0x05 - 1][0], srcreg);
// Fall through
case 0x04:
_mm_store_ps(&destxmm[0x04 - 1][0], srcreg);
// Fall through
case 0x03:
_mm_store_ps(&destxmm[0x03 - 1][0], srcreg);
// Fall through
case 0x02:
_mm_store_ps(&destxmm[0x02 - 1][0], srcreg);
// Fall through
case 0x01:
_mm_store_ps(&destxmm[0x01 - 1][0], srcreg);
// Fall through
}
destxmm += (MZFqwc & 0x07);
for (uint i = 0; i < MZFqwc / 8; ++i, destxmm += 8)
{
_mm_store_ps(&destxmm[0][0], srcreg);
_mm_store_ps(&destxmm[1][0], srcreg);
_mm_store_ps(&destxmm[2][0], srcreg);
_mm_store_ps(&destxmm[3][0], srcreg);
_mm_store_ps(&destxmm[4][0], srcreg);
_mm_store_ps(&destxmm[5][0], srcreg);
_mm_store_ps(&destxmm[6][0], srcreg);
_mm_store_ps(&destxmm[7][0], srcreg);
}
};
static __fi void memzero_sse_a(void* dest, const size_t size)
{
memset_sse_a<0>(dest, size);
}
template <u8 data, typename T>
__noinline void memset_sse_a(T& dest)
{
static_assert((sizeof(dest) & 0xf) == 0, "Bad size for SSE memset");
memset_sse_a<data>(&dest, sizeof(dest));
}
template <typename T>
void memzero_sse_a(T& dest)
{
static_assert((sizeof(dest) & 0xf) == 0, "Bad size for SSE memset");
memset_sse_a<0>(&dest, sizeof(dest));
}
-99
View File
@@ -1,99 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2010 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "common/Pcsx2Defs.h"
// Microsoft Windows only macro, useful for freeing out COM objects:
#define safe_release(ptr) \
((void)((((ptr) != NULL) && ((ptr)->Release(), !!0)), (ptr) = NULL))
// --------------------------------------------------------------------------------------
// SafeArray
// --------------------------------------------------------------------------------------
// Handy little class for allocating a resizable memory block, complete with exception
// error handling and automatic cleanup. A lightweight alternative to std::vector.
//
template <typename T>
class SafeArray
{
DeclareNoncopyableObject(SafeArray);
public:
static const int DefaultChunkSize = 0x1000 * sizeof(T);
public:
std::string Name; // user-assigned block name
int ChunkSize;
protected:
T* m_ptr;
int m_size; // size of the allocation of memory
protected:
SafeArray(std::string name, T* allocated_mem, int initSize);
virtual T* _virtual_realloc(int newsize);
// A safe array index fetcher. Asserts if the index is out of bounds (dev and debug
// builds only -- no bounds checking is done in release builds).
T* _getPtr(uint i) const;
public:
virtual ~SafeArray();
explicit SafeArray(std::string name = "Unnamed");
explicit SafeArray(int initialSize, std::string name = "Unnamed");
void Dispose();
void ExactAlloc(int newsize);
void MakeRoomFor(int newsize)
{
if (newsize > m_size)
ExactAlloc(newsize);
}
bool IsDisposed() const { return (m_ptr == NULL); }
// Returns the size of the memory allocation, as according to the array type.
int GetLength() const { return m_size; }
// Returns the size of the memory allocation in bytes.
int GetSizeInBytes() const { return m_size * sizeof(T); }
// Extends the containment area of the array. Extensions are performed
// in chunks.
void GrowBy(int items)
{
MakeRoomFor(m_size + ChunkSize + items + 1);
}
// Gets a pointer to the requested allocation index.
// DevBuilds : Generates assertion if the index is invalid.
T* GetPtr(uint idx = 0) { return _getPtr(idx); }
const T* GetPtr(uint idx = 0) const { return _getPtr(idx); }
// Gets a pointer to the element directly after the last element in the array.
// This is equivalent to doing GetPtr(GetLength()), except that this call *avoids*
// the out-of-bounds assertion check that typically occurs when you do that. :)
T* GetPtrEnd() { return &m_ptr[m_size]; }
const T* GetPtrEnd() const { return &m_ptr[m_size]; }
// Gets an element of this memory allocation much as if it were an array.
// DevBuilds : Generates assertion if the index is invalid.
T& operator[](int idx) { return *_getPtr((uint)idx); }
const T& operator[](int idx) const { return *_getPtr((uint)idx); }
virtual SafeArray<T>* Clone() const;
};
-121
View File
@@ -1,121 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2010 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "common/Assertions.h"
#include "common/SafeArray.h"
// Internal constructor for use by derived classes. This allows a derived class to
// use its own memory allocation (with an aligned memory, for example).
// Throws:
// Exception::OutOfMemory if the allocated_mem pointer is NULL.
template <typename T>
SafeArray<T>::SafeArray(std::string name, T* allocated_mem, int initSize)
: Name(std::move(name))
{
ChunkSize = DefaultChunkSize;
m_ptr = allocated_mem;
m_size = initSize;
if (m_ptr == NULL)
pxFailRel("SafeArray memory assignment failed");
}
template <typename T>
T* SafeArray<T>::_virtual_realloc(int newsize)
{
T* retval = (T*)((m_ptr == NULL) ?
malloc(newsize * sizeof(T)) :
realloc(m_ptr, newsize * sizeof(T)));
if (IsDebugBuild && (retval != NULL))
{
// Zero everything out to 0xbaadf00d, so that its obviously uncleared
// to a debuggee
u32* fill = (u32*)&retval[m_size];
const u32* end = (u32*)((((uptr)&retval[newsize - 1]) - 3) & ~0x3);
for (; fill < end; ++fill)
*fill = 0xbaadf00d;
}
return retval;
}
template <typename T>
SafeArray<T>::~SafeArray()
{
safe_free(m_ptr);
}
template <typename T>
SafeArray<T>::SafeArray(std::string name)
: Name(std::move(name))
{
ChunkSize = DefaultChunkSize;
m_ptr = NULL;
m_size = 0;
}
template <typename T>
SafeArray<T>::SafeArray(int initialSize, std::string name)
: Name(std::move(name))
{
ChunkSize = DefaultChunkSize;
m_ptr = (initialSize == 0) ? NULL : (T*)malloc(initialSize * sizeof(T));
m_size = initialSize;
if ((initialSize != 0) && (m_ptr == NULL))
pxFailRel("SafeArray memory allocation failed");
}
// Clears the contents of the array to zero, and frees all memory allocations.
template <typename T>
void SafeArray<T>::Dispose()
{
m_size = 0;
safe_free(m_ptr);
}
template <typename T>
T* SafeArray<T>::_getPtr(uint i) const
{
pxAssumeDev(i < static_cast<uint>(m_size), "Array index in bounds");
return &m_ptr[i];
}
// reallocates the array to the explicit size. Can be used to shrink or grow an
// array, and bypasses the internal threshold growth indicators.
template <typename T>
void SafeArray<T>::ExactAlloc(int newsize)
{
if (newsize == m_size)
return;
m_ptr = _virtual_realloc(newsize);
if (m_ptr == NULL)
pxFailRel("SafeArray exact alloc failed");
m_size = newsize;
}
template <typename T>
SafeArray<T>* SafeArray<T>::Clone() const
{
SafeArray<T>* retval = new SafeArray<T>(m_size);
memcpy(retval->GetPtr(), m_ptr, sizeof(T) * m_size);
return retval;
}
-1
View File
@@ -19,7 +19,6 @@
#include "common/RedtapeWindows.h"
#include "common/Console.h"
#include "common/General.h"
#include "common/Exceptions.h"
#include "common/StringUtil.h"
#include "common/AlignedMalloc.h"
#include "common/Assertions.h"
-1
View File
@@ -17,7 +17,6 @@
#include "common/Pcsx2Defs.h"
#include "common/RedtapeWindows.h"
#include "common/Exceptions.h"
#include "common/StringUtil.h"
#include "common/Threading.h"
#include "common/General.h"
+50
View File
@@ -0,0 +1,50 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "common/Pcsx2Defs.h"
__ri static void MemCopy_WrappedDest(const u128* src, u128* destBase, uint& destStart, uint destSize, uint len)
{
uint endpos = destStart + len;
if (endpos < destSize)
{
memcpy(&destBase[destStart], src, len * 16);
destStart += len;
}
else
{
uint firstcopylen = destSize - destStart;
memcpy(&destBase[destStart], src, firstcopylen * 16);
destStart = endpos % destSize;
memcpy(destBase, src + firstcopylen, destStart * 16);
}
}
__ri static void MemCopy_WrappedSrc(const u128* srcBase, uint& srcStart, uint srcSize, u128* dest, uint len)
{
uint endpos = srcStart + len;
if (endpos < srcSize)
{
memcpy(dest, &srcBase[srcStart], len * 16);
srcStart += len;
}
else
{
uint firstcopylen = srcSize - srcStart;
memcpy(dest, &srcBase[srcStart], firstcopylen * 16);
srcStart = endpos % srcSize;
memcpy(dest + firstcopylen, srcBase, srcStart * 16);
}
}
+5 -3
View File
@@ -46,10 +46,11 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="AlignedMalloc.cpp" />
<ClCompile Include="Assertions.cpp" />
<ClCompile Include="Console.cpp" />
<ClCompile Include="CrashHandler.cpp" />
<ClCompile Include="DynamicLibrary.cpp" />
<ClCompile Include="Exceptions.cpp" />
<ClCompile Include="Error.cpp" />
<ClCompile Include="FastJmp.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
@@ -109,6 +110,7 @@
<ClInclude Include="DynamicLibrary.h" />
<ClInclude Include="Easing.h" />
<ClInclude Include="boost_spsc_queue.hpp" />
<ClInclude Include="Error.h" />
<ClInclude Include="FastJmp.h" />
<ClInclude Include="FileSystem.h" />
<ClInclude Include="HashCombine.h" />
@@ -131,7 +133,6 @@
<ClInclude Include="SettingsWrapper.h" />
<ClInclude Include="Assertions.h" />
<ClInclude Include="Console.h" />
<ClInclude Include="Exceptions.h" />
<ClInclude Include="General.h" />
<ClInclude Include="MathUtils.h" />
<ClInclude Include="Path.h" />
@@ -169,6 +170,7 @@
<ClInclude Include="emitter\implement\simd_helpers.h" />
<ClInclude Include="emitter\implement\simd_moremovs.h" />
<ClInclude Include="emitter\implement\simd_shufflepack.h" />
<ClInclude Include="WrappedMemCopy.h" />
<ClInclude Include="ZipHelpers.h" />
</ItemGroup>
<ItemGroup>
@@ -180,4 +182,4 @@
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
</Project>
</Project>
+13 -7
View File
@@ -13,9 +13,6 @@
<ClCompile Include="emitter\cpudetect.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Exceptions.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="emitter\fpu.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@@ -139,6 +136,12 @@
<ClCompile Include="General.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Error.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Assertions.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="AlignedMalloc.h">
@@ -159,9 +162,6 @@
<ClInclude Include="emitter\implement\dwshift.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Exceptions.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="General.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -348,6 +348,12 @@
<ClInclude Include="ByteSwap.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="WrappedMemCopy.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Error.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Source Files">
@@ -362,4 +368,4 @@
<Filter>Source Files</Filter>
</MASM>
</ItemGroup>
</Project>
</Project>
-4
View File
@@ -66,8 +66,6 @@ x86capabilities::x86capabilities()
, PhysicalCores(0)
, LogicalCores(0)
{
memzero(VendorName);
memzero(FamilyName);
}
#if defined(_MSC_VER)
#pragma optimize("", on)
@@ -148,7 +146,6 @@ void x86capabilities::Identify()
s32 regs[4];
u32 cmds;
memzero(VendorName);
cpuid(regs, 0);
cmds = regs[0];
@@ -201,7 +198,6 @@ void x86capabilities::Identify()
EFlags = regs[3];
}
memzero(FamilyName);
cpuid((int*)FamilyName, 0x80000002);
cpuid((int*)(FamilyName + 16), 0x80000003);
cpuid((int*)(FamilyName + 32), 0x80000004);
+6 -6
View File
@@ -46,8 +46,8 @@ public:
u32 EFlags2; // Extended Feature Flags pg2
u32 SEFlag; // Structured Extended Feature Flags Enumeration
char VendorName[16]; // Vendor/Creator ID
char FamilyName[50]; // the original cpu name
char VendorName[16] = {}; // Vendor/Creator ID
char FamilyName[50] = {}; // the original cpu name
// ----------------------------------------------------------------------------
// x86 CPU Capabilities Section (all boolean flags!)
@@ -55,6 +55,8 @@ public:
union
{
u64 AllCapabilities = 0;
struct
{
u32 hasFloatingPointUnit : 1;
@@ -101,13 +103,11 @@ public:
u32 hasAMD64BitArchitecture : 1;
u32 hasStreamingSIMD4ExtensionsA : 1;
};
u64 AllCapabilities;
};
// Core Counts!
u32 PhysicalCores;
u32 LogicalCores;
u32 PhysicalCores = 0;
u32 LogicalCores = 0;
public:
x86capabilities();
+12 -7
View File
@@ -167,20 +167,25 @@
/>
</Target>
<!--Copies base translation files-->
<!--Copies base translation files, need to rename them from qtbase_ to qt_ -->
<ItemGroup>
<BaseTsFiles Include="$(QtTranslationsDir)\*.qm" />
</ItemGroup>
<Target Name="QtCopyBaseTranslations"
AfterTargets="Build"
Inputs="@(BaseTsFiles)"
Outputs="@(BaseTsFiles -> '$(QtTsOutDir)%(RecursiveDir)%(Filename)%(Extension)')">
Outputs="@(BaseTsFiles -> '$(QtTsOutDir)%(RecursiveDir)%(Filename.Replace('qtbase_', 'qt_'))%(Extension)')">
<!-- https://stackoverflow.com/a/15379344 -->
<ItemGroup>
<TempItems Include="@(BaseTsFiles->'%(Filename)%(Extension)'->Replace('qtbase_', 'qt_'))">
<OriginalPath>%(Identity)</OriginalPath>
<SavedRecursiveDir>%(RecursiveDir)</SavedRecursiveDir>
</TempItems>
</ItemGroup>
<Message Text="Copying base translation files" Importance="High" />
<Copy
SourceFiles="@(BaseTsFiles)"
DestinationFolder="$(QtTsOutDir)"
SkipUnchangedFiles="true"
/>
<Copy SourceFiles="@(TempItems->'%(OriginalPath)')"
DestinationFiles="@(TempItems->'$(QtTsOutDir)%(SavedRecursiveDir)%(Identity)')"
SkipUnchangedFiles="true" />
</Target>
<!--Compiles all translation files-->
+2 -2
View File
@@ -19,19 +19,19 @@
<ClCompile>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(SolutionDir);$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>__WIN32__;WIN32;_WINDOWS;WIN32_LEAN_AND_MEAN;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;WINVER=0x0A00;_WIN32_WINNT=0x0A00;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>__WIN32__;WIN32;_WINDOWS;WIN32_LEAN_AND_MEAN;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_HAS_EXCEPTIONS=0;WINVER=0x0A00;_WIN32_WINNT=0x0A00;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="$(Configuration.Contains(Debug))">PCSX2_DEBUG;PCSX2_DEVBUILD;_SECURE_SCL_=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="$(Configuration.Contains(Devel))">PCSX2_DEVEL;PCSX2_DEVBUILD;NDEBUG;_SECURE_SCL_=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="$(Configuration.Contains(Release))">NDEBUG;_SECURE_SCL_=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FunctionLevelLinking>true</FunctionLevelLinking>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<ExceptionHandling>false</ExceptionHandling>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4063;4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<LanguageStandard>stdcpp17</LanguageStandard>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<ExceptionHandling>Async</ExceptionHandling>
<MinimalRebuild>false</MinimalRebuild>
<ConformanceMode>true</ConformanceMode>
<ObjectFileName>$(IntDir)%(RelativeDir)</ObjectFileName>
+3 -1
View File
@@ -1,3 +1,5 @@
pull_request_title: "[ci skip] Syncing Crowdin translations"
commit_message: "[ci skip]"
files:
- source: pcsx2-qt/Translations/pcsx2-qt_en.ts
translation: '/pcsx2-qt/Translations/pcsx2-qt_%two_letters_code%.ts'
translation: '/pcsx2-qt/Translations/pcsx2-qt_%locale%.ts'
+15 -14
View File
@@ -28,7 +28,6 @@
#include "common/Assertions.h"
#include "common/Console.h"
#include "common/Exceptions.h"
#include "common/FileSystem.h"
#include "common/MemorySettingsInterface.h"
#include "common/Path.h"
@@ -40,13 +39,13 @@
#include "pcsx2/Achievements.h"
#include "pcsx2/CDVD/CDVD.h"
#include "pcsx2/GS.h"
#include "pcsx2/GS/GS.h"
#include "pcsx2/GSDumpReplayer.h"
#include "pcsx2/Host.h"
#include "pcsx2/INISettingsInterface.h"
#include "pcsx2/ImGui/ImGuiManager.h"
#include "pcsx2/Input/InputManager.h"
#include "pcsx2/LogSink.h"
#include "pcsx2/MTGS.h"
#include "pcsx2/PAD/Host/PAD.h"
#include "pcsx2/PerformanceMetrics.h"
#include "pcsx2/VMManager.h"
@@ -69,7 +68,6 @@ static constexpr u32 WINDOW_WIDTH = 640;
static constexpr u32 WINDOW_HEIGHT = 480;
static MemorySettingsInterface s_settings_interface;
alignas(16) static SysMtgsThread s_mtgs_thread;
static std::string s_output_prefix;
static s32 s_loop_count = 1;
@@ -362,15 +360,6 @@ std::optional<std::string> InputManager::ConvertHostKeyboardCodeToString(u32 cod
return std::nullopt;
}
SysMtgsThread& GetMTGS()
{
return s_mtgs_thread;
}
//////////////////////////////////////////////////////////////////////////
// Interface Stuff
//////////////////////////////////////////////////////////////////////////
BEGIN_HOTKEY_LIST(g_host_hotkeys)
END_HOTKEY_LIST()
@@ -651,13 +640,25 @@ int main(int argc, char* argv[])
void Host::VSyncOnCPUThread()
{
// update GS thread copy of frame number
GetMTGS().RunOnGSThread([frame_number = GSDumpReplayer::GetFrameNumber()]() { s_dump_frame_number = frame_number; });
GetMTGS().RunOnGSThread([loop_number = GSDumpReplayer::GetLoopCount()]() { s_loop_number = loop_number; });
MTGS::RunOnGSThread([frame_number = GSDumpReplayer::GetFrameNumber()]() { s_dump_frame_number = frame_number; });
MTGS::RunOnGSThread([loop_number = GSDumpReplayer::GetLoopCount()]() { s_loop_number = loop_number; });
// process any window messages (but we shouldn't really have any)
GSRunner::PumpPlatformMessages();
}
s32 Host::Internal::GetTranslatedStringImpl(
const std::string_view& context, const std::string_view& msg, char* tbuf, size_t tbuf_space)
{
if (msg.size() > tbuf_space)
return -1;
else if (msg.empty())
return 0;
std::memcpy(tbuf, msg.data(), msg.size());
return static_cast<s32>(msg.size());
}
//////////////////////////////////////////////////////////////////////////
// Platform specific code
//////////////////////////////////////////////////////////////////////////
+2 -1
View File
@@ -804,7 +804,8 @@ bool AutoUpdaterDialog::processUpdate(const QByteArray& update_data, QProgressDi
}
QDir(QString::fromStdString(*trashed_path)).removeRecursively();
}
if (!CocoaTools::LaunchApplication(open_path.toStdString()))
// For some reason if I use QProcess the shell gets killed immediately with SIGKILL, but NSTask is fine...
if (!CocoaTools::DelayedLaunch(open_path.toStdString()))
{
reportError("Failed to start new application");
return false;
+27
View File
@@ -25,7 +25,11 @@ target_sources(pcsx2-qt PRIVATE
PrecompiledHeader.cpp
PrecompiledHeader.h
SettingWidgetBinder.h
SetupWizardDialog.cpp
SetupWizardDialog.h
SetupWizardDialog.ui
Themes.cpp
Translations.cpp
QtHost.cpp
QtHost.h
QtKeyCodes.cpp
@@ -173,6 +177,8 @@ if(USE_ACHIEVEMENTS)
)
endif()
file(GLOB TS_FILES ${CMAKE_CURRENT_SOURCE_DIR}/Translations/*.ts)
target_precompile_headers(pcsx2-qt PRIVATE PrecompiledHeader.h)
target_include_directories(pcsx2-qt PRIVATE
@@ -191,6 +197,27 @@ target_link_libraries(pcsx2-qt PRIVATE
Qt6::Network
)
# Our Qt builds may have exceptions on, so force them off.
target_compile_definitions(pcsx2-qt PRIVATE QT_NO_EXCEPTIONS)
if(WIN32)
set_source_files_properties(${TS_FILES} PROPERTIES OUTPUT_LOCATION "${CMAKE_SOURCE_DIR}/bin/translations")
qt_add_lrelease(pcsx2-qt TS_FILES ${TS_FILES})
elseif(APPLE)
# Hopefully macdeployqt will pick these up.
qt_add_lrelease(pcsx2-qt TS_FILES ${TS_FILES})
else()
# TODO: Copy base translations.
qt_add_lrelease(pcsx2-qt TS_FILES ${TS_FILES} QM_FILES_OUTPUT_VARIABLE QM_FILES)
set(QM_OUTPUT_DIR "$<TARGET_FILE_DIR:pcsx2-qt>/translations")
add_custom_command(TARGET pcsx2-qt POST_BUILD COMMAND "${CMAKE_COMMAND}" -E make_directory "${QM_OUTPUT_DIR}")
foreach (QM_FILE IN LISTS QM_FILES)
get_filename_component(QM_FILE_NAME ${QM_FILE} NAME)
add_custom_command(TARGET pcsx2-qt POST_BUILD COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${QM_FILE}" "${QM_OUTPUT_DIR}/${QM_FILE_NAME}")
endforeach()
endif()
# Currently, 7z is only needed for the Windows updater.
if(WIN32)
target_link_libraries(pcsx2-qt PRIVATE
+72 -31
View File
@@ -41,6 +41,7 @@
#include "pcsx2/GameList.h"
#include "pcsx2/Host.h"
#include "pcsx2/LogSink.h"
#include "pcsx2/MTGS.h"
#include "pcsx2/PerformanceMetrics.h"
#include "pcsx2/Recording/InputRecording.h"
#include "pcsx2/Recording/InputRecordingControls.h"
@@ -182,7 +183,6 @@ void MainWindow::setupAdditionalUi()
{
const bool show_advanced_settings = QtHost::ShouldShowAdvancedSettings();
setWindowIcon(QIcon(QStringLiteral("%1/icons/AppIconLarge.png").arg(QtHost::GetResourcesBasePath())));
makeIconsMasks(menuBar());
m_ui.menuDebug->menuAction()->setVisible(show_advanced_settings);
@@ -293,7 +293,6 @@ void MainWindow::connectSignals()
connect(m_ui.actionStartFile, &QAction::triggered, this, &MainWindow::onStartFileActionTriggered);
connect(m_ui.actionStartDisc, &QAction::triggered, this, &MainWindow::onStartDiscActionTriggered);
connect(m_ui.actionStartBios, &QAction::triggered, this, &MainWindow::onStartBIOSActionTriggered);
connect(m_ui.actionChangeDisc, &QAction::triggered, [this] { m_ui.menuChangeDisc->exec(QCursor::pos()); });
connect(m_ui.actionChangeDiscFromFile, &QAction::triggered, this, &MainWindow::onChangeDiscFromFileActionTriggered);
connect(m_ui.actionChangeDiscFromDevice, &QAction::triggered, this, &MainWindow::onChangeDiscFromDeviceActionTriggered);
connect(m_ui.actionChangeDiscFromGameList, &QAction::triggered, this, &MainWindow::onChangeDiscFromGameListActionTriggered);
@@ -302,14 +301,22 @@ void MainWindow::connectSignals()
connect(m_ui.menuChangeDisc, &QMenu::aboutToHide, this, &MainWindow::onChangeDiscMenuAboutToHide);
connect(m_ui.actionPowerOff, &QAction::triggered, this, [this]() { requestShutdown(true, true, EmuConfig.SaveStateOnShutdown); });
connect(m_ui.actionPowerOffWithoutSaving, &QAction::triggered, this, [this]() { requestShutdown(false, false, false); });
connect(m_ui.actionLoadState, &QAction::triggered, this, [this]() { m_ui.menuLoadState->exec(QCursor::pos()); });
connect(m_ui.actionSaveState, &QAction::triggered, this, [this]() { m_ui.menuSaveState->exec(QCursor::pos()); });
connect(m_ui.actionToolbarStartFile, &QAction::triggered, this, &MainWindow::onStartFileActionTriggered);
connect(m_ui.actionToolbarStartDisc, &QAction::triggered, this, &MainWindow::onStartDiscActionTriggered);
connect(m_ui.actionToolbarStartBios, &QAction::triggered, this, &MainWindow::onStartBIOSActionTriggered);
connect(m_ui.actionToolbarChangeDisc, &QAction::triggered, [this] { m_ui.menuChangeDisc->exec(QCursor::pos()); });
connect(m_ui.actionToolbarPowerOff, &QAction::triggered, this, [this]() { requestShutdown(true, true, EmuConfig.SaveStateOnShutdown); });
connect(m_ui.actionToolbarLoadState, &QAction::triggered, this, [this]() { m_ui.menuLoadState->exec(QCursor::pos()); });
connect(m_ui.actionToolbarSaveState, &QAction::triggered, this, [this]() { m_ui.menuSaveState->exec(QCursor::pos()); });
connect(m_ui.actionToolbarSettings, &QAction::triggered, this, &MainWindow::onSettingsTriggeredFromToolbar);
connect(m_ui.actionToolbarControllerSettings, &QAction::triggered,
[this]() { doControllerSettings(ControllerSettingsDialog::Category::GlobalSettings); });
connect(m_ui.actionToolbarScreenshot, &QAction::triggered, this, &MainWindow::onScreenshotActionTriggered);
connect(m_ui.actionExit, &QAction::triggered, this, &MainWindow::close);
connect(m_ui.actionScreenshot, &QAction::triggered, this, &MainWindow::onScreenshotActionTriggered);
connect(m_ui.menuLoadState, &QMenu::aboutToShow, this, &MainWindow::onLoadStateMenuAboutToShow);
connect(m_ui.menuSaveState, &QMenu::aboutToShow, this, &MainWindow::onSaveStateMenuAboutToShow);
connect(m_ui.actionSettings, &QAction::triggered, [this]() { doSettings(); });
connect(m_ui.actionSettings2, &QAction::triggered, this, &MainWindow::onSettingsTriggeredFromToolbar);
connect(m_ui.actionInterfaceSettings, &QAction::triggered, [this]() { doSettings("Interface"); });
connect(m_ui.actionGameListSettings, &QAction::triggered, [this]() { doSettings("Game List"); });
connect(m_ui.actionEmulationSettings, &QAction::triggered, [this]() { doSettings("Emulation"); });
@@ -402,7 +409,7 @@ void MainWindow::connectSignals()
void MainWindow::connectVMThreadSignals(EmuThread* thread)
{
connect(m_ui.actionStartFullscreenUI, &QAction::triggered, thread, &EmuThread::startFullscreenUI);
connect(m_ui.actionStartFullscreenUI2, &QAction::triggered, thread, &EmuThread::startFullscreenUI);
connect(m_ui.actionToolbarStartFullscreenUI, &QAction::triggered, thread, &EmuThread::startFullscreenUI);
connect(thread, &EmuThread::messageConfirmed, this, &MainWindow::confirmMessage, Qt::BlockingQueuedConnection);
connect(thread, &EmuThread::onAcquireRenderWindowRequested, this, &MainWindow::acquireRenderWindow, Qt::BlockingQueuedConnection);
connect(thread, &EmuThread::onReleaseRenderWindowRequested, this, &MainWindow::releaseRenderWindow, Qt::BlockingQueuedConnection);
@@ -418,6 +425,9 @@ void MainWindow::connectVMThreadSignals(EmuThread* thread)
connect(m_ui.actionReset, &QAction::triggered, thread, &EmuThread::resetVM);
connect(m_ui.actionPause, &QAction::toggled, thread, &EmuThread::setVMPaused);
connect(m_ui.actionFullscreen, &QAction::triggered, thread, &EmuThread::toggleFullscreen);
connect(m_ui.actionToolbarReset, &QAction::triggered, thread, &EmuThread::resetVM);
connect(m_ui.actionToolbarPause, &QAction::toggled, thread, &EmuThread::setVMPaused);
connect(m_ui.actionToolbarFullscreen, &QAction::triggered, thread, &EmuThread::toggleFullscreen);
connect(m_ui.actionToggleSoftwareRendering, &QAction::triggered, thread, &EmuThread::toggleSoftwareRendering);
connect(m_ui.actionDebugger, &QAction::triggered, this, &MainWindow::openDebugger);
connect(m_ui.actionReloadPatches, &QAction::triggered, thread, &EmuThread::reloadPatches);
@@ -672,18 +682,25 @@ void MainWindow::updateEmulationActions(bool starting, bool running, bool stoppi
m_ui.actionStartFile->setDisabled(starting_or_running || stopping);
m_ui.actionStartDisc->setDisabled(starting_or_running || stopping);
m_ui.actionStartBios->setDisabled(starting_or_running || stopping);
m_ui.actionToolbarStartFile->setDisabled(starting_or_running || stopping);
m_ui.actionToolbarStartDisc->setDisabled(starting_or_running || stopping);
m_ui.actionToolbarStartBios->setDisabled(starting_or_running || stopping);
m_ui.actionPowerOff->setEnabled(running);
m_ui.actionPowerOffWithoutSaving->setEnabled(running);
m_ui.actionReset->setEnabled(running);
m_ui.actionPause->setEnabled(running);
m_ui.actionChangeDisc->setEnabled(running);
m_ui.actionScreenshot->setEnabled(running);
m_ui.menuChangeDisc->setEnabled(running);
m_ui.actionSaveState->setEnabled(running);
m_ui.menuSaveState->setEnabled(running);
m_ui.actionToolbarPowerOff->setEnabled(running);
m_ui.actionToolbarReset->setEnabled(running);
m_ui.actionToolbarPause->setEnabled(running);
m_ui.actionToolbarScreenshot->setEnabled(running);
m_ui.actionToolbarChangeDisc->setEnabled(running);
m_ui.actionToolbarSaveState->setEnabled(running);
m_ui.actionViewGameProperties->setEnabled(running);
m_ui.actionToolsVideoCapture->setEnabled(running);
@@ -697,8 +714,15 @@ void MainWindow::updateEmulationActions(bool starting, bool running, bool stoppi
if (!starting && !running)
{
QSignalBlocker sb(m_ui.actionPause);
m_ui.actionPause->setChecked(false);
{
QSignalBlocker sb(m_ui.actionPause);
m_ui.actionPause->setChecked(false);
}
{
QSignalBlocker sb(m_ui.actionToolbarPause);
m_ui.actionToolbarPause->setChecked(false);
}
}
// scanning needs to be disabled while running
@@ -709,14 +733,20 @@ void MainWindow::updateEmulationActions(bool starting, bool running, bool stoppi
void MainWindow::updateDisplayRelatedActions(bool has_surface, bool render_to_main, bool fullscreen)
{
// rendering to main, or switched to gamelist/grid
m_ui.actionViewSystemDisplay->setEnabled((has_surface && render_to_main) || (!has_surface && GetMTGS().IsOpen()));
m_ui.actionViewSystemDisplay->setEnabled((has_surface && render_to_main) || (!has_surface && MTGS::IsOpen()));
m_ui.menuWindowSize->setEnabled(has_surface && !fullscreen);
m_ui.actionFullscreen->setEnabled(has_surface);
m_ui.actionToolbarFullscreen->setEnabled(has_surface);
{
QSignalBlocker blocker(m_ui.actionFullscreen);
m_ui.actionFullscreen->setChecked(fullscreen);
}
{
QSignalBlocker blocker(m_ui.actionToolbarFullscreen);
m_ui.actionToolbarFullscreen->setChecked(fullscreen);
}
}
void MainWindow::updateStatusBarWidgetVisibility()
@@ -821,7 +851,7 @@ bool MainWindow::isShowingGameList() const
bool MainWindow::isRenderingFullscreen() const
{
if (!GetMTGS().IsOpen() || !m_display_widget)
if (!MTGS::IsOpen() || !m_display_widget)
return false;
return getDisplayContainer()->isFullScreen();
@@ -1394,6 +1424,12 @@ void MainWindow::updateTheme()
m_game_list_widget->refreshImages();
}
void MainWindow::updateLanguage()
{
QtHost::InstallTranslator();
recreate();
}
void MainWindow::onInputRecNewActionTriggered()
{
const bool wasPaused = s_vm_paused;
@@ -1417,6 +1453,7 @@ void MainWindow::onInputRecNewActionTriggered()
m_ui.actionInputRecNew->setEnabled(false);
m_ui.actionInputRecStop->setEnabled(true);
m_ui.actionReset->setEnabled(!g_InputRecording.isTypeSavestate());
m_ui.actionToolbarReset->setEnabled(!g_InputRecording.isTypeSavestate());
});
}
});
@@ -1469,6 +1506,7 @@ void MainWindow::onInputRecPlayActionTriggered()
m_ui.actionInputRecNew->setEnabled(false);
m_ui.actionInputRecStop->setEnabled(true);
m_ui.actionReset->setEnabled(!g_InputRecording.isTypeSavestate());
m_ui.actionToolbarReset->setEnabled(!g_InputRecording.isTypeSavestate());
});
}
});
@@ -1485,6 +1523,7 @@ void MainWindow::onInputRecStopActionTriggered()
m_ui.actionInputRecNew->setEnabled(true);
m_ui.actionInputRecStop->setEnabled(false);
m_ui.actionReset->setEnabled(true);
m_ui.actionToolbarReset->setEnabled(true);
});
});
}
@@ -1548,6 +1587,10 @@ void MainWindow::onVMPaused()
QSignalBlocker sb(m_ui.actionPause);
m_ui.actionPause->setChecked(true);
}
{
QSignalBlocker sb(m_ui.actionToolbarPause);
m_ui.actionToolbarPause->setChecked(true);
}
s_vm_paused = true;
updateWindowTitle();
@@ -1565,6 +1608,10 @@ void MainWindow::onVMResumed()
QSignalBlocker sb(m_ui.actionPause);
m_ui.actionPause->setChecked(false);
}
{
QSignalBlocker sb(m_ui.actionToolbarPause);
m_ui.actionToolbarPause->setChecked(false);
}
s_vm_paused = false;
m_was_disc_change_request = false;
@@ -1826,7 +1873,7 @@ std::optional<WindowInfo> MainWindow::acquireRenderWindow(bool recreate_window,
updateWindowState();
m_ui.actionStartFullscreenUI->setEnabled(false);
m_ui.actionStartFullscreenUI2->setEnabled(false);
m_ui.actionToolbarStartFullscreenUI->setEnabled(false);
updateDisplayWidgetCursor();
m_display_widget->setFocus();
@@ -1933,7 +1980,7 @@ void MainWindow::relativeMouseModeRequested(bool enabled)
return;
m_relative_mouse_mode = enabled;
if (s_vm_valid && !s_vm_paused)
if (m_display_widget && !s_vm_paused)
updateDisplayWidgetCursor();
}
@@ -1946,7 +1993,7 @@ void MainWindow::releaseRenderWindow()
m_ui.actionViewSystemDisplay->setEnabled(false);
m_ui.actionFullscreen->setEnabled(false);
m_ui.actionStartFullscreenUI->setEnabled(true);
m_ui.actionStartFullscreenUI2->setEnabled(true);
m_ui.actionToolbarStartFullscreenUI->setEnabled(true);
}
void MainWindow::destroyDisplayWidget(bool show_game_list)
@@ -2002,6 +2049,7 @@ void MainWindow::destroyDisplayWidget(bool show_game_list)
void MainWindow::updateDisplayWidgetCursor()
{
pxAssertRel(m_display_widget, "Should have a display widget");
m_display_widget->updateRelativeMode(s_vm_valid && !s_vm_paused && m_relative_mouse_mode);
m_display_widget->updateCursor(s_vm_valid && !s_vm_paused && shouldHideMouseCursor());
}
@@ -2063,6 +2111,11 @@ SettingsDialog* MainWindow::getSettingsDialog()
{
m_settings_dialog = new SettingsDialog(this);
connect(m_settings_dialog->getInterfaceSettingsWidget(), &InterfaceSettingsWidget::themeChanged, this, &MainWindow::updateTheme);
connect(m_settings_dialog->getInterfaceSettingsWidget(), &InterfaceSettingsWidget::languageChanged, this, [this]() {
// reopen settings dialog after it applies
updateLanguage();
g_main_window->doSettings("Interface");
});
}
return m_settings_dialog;
@@ -2420,9 +2473,9 @@ void MainWindow::updateSaveStateMenusEnableState(bool enable)
const bool load_enabled = enable;
const bool save_enabled = enable && s_vm_valid;
m_ui.menuLoadState->setEnabled(load_enabled);
m_ui.actionLoadState->setEnabled(load_enabled);
m_ui.actionToolbarLoadState->setEnabled(load_enabled);
m_ui.menuSaveState->setEnabled(save_enabled);
m_ui.actionSaveState->setEnabled(save_enabled);
m_ui.actionToolbarSaveState->setEnabled(save_enabled);
}
void MainWindow::doStartFile(std::optional<CDVD_SourceType> source, const QString& path)
@@ -2452,20 +2505,8 @@ void MainWindow::doStartFile(std::optional<CDVD_SourceType> source, const QStrin
void MainWindow::doDiscChange(CDVD_SourceType source, const QString& path)
{
const bool is_gs_dump = VMManager::IsGSDumpFileName(path.toStdString());
if (is_gs_dump != GSDumpReplayer::IsReplayingDump())
{
QMessageBox::critical(this, tr("Error"), tr("Cannot switch from game to GS dump or vice versa."));
return;
}
else if (is_gs_dump)
{
Host::RunOnCPUThread([path = path.toStdString()]() { GSDumpReplayer::ChangeDump(path.c_str()); });
return;
}
bool reset_system = false;
if (!m_was_disc_change_request)
if (!m_was_disc_change_request && !GSDumpReplayer::IsReplayingDump())
{
QMessageBox message(QMessageBox::Question, tr("Confirm Disc Change"),
tr("Do you want to swap discs or boot the new image (via system reset)?"), QMessageBox::NoButton, this);
+1
View File
@@ -159,6 +159,7 @@ private Q_SLOTS:
void onToolsOpenDataDirectoryTriggered();
void onToolsCoverDownloaderTriggered();
void updateTheme();
void updateLanguage();
void onScreenshotActionTriggered();
void onSaveGSDumpActionTriggered();
void onBlockDumpActionToggled(bool checked);
+153 -64
View File
@@ -16,6 +16,11 @@
<property name="windowTitle">
<string>PCSX2</string>
</property>
<property name="windowIcon">
<iconset>
<normalon>:/icons/AppIcon64.png</normalon>
</iconset>
</property>
<widget class="QStackedWidget" name="mainContainer"/>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
@@ -126,10 +131,10 @@
<property name="title">
<string>Switch Renderer</string>
</property>
<property name="icon">
<iconset theme="brush-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="icon">
<iconset theme="brush-line">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
<addaction name="menuDebugSwitchRenderer"/>
<addaction name="separator"/>
@@ -234,24 +239,24 @@
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionStartFile"/>
<addaction name="actionStartDisc"/>
<addaction name="actionStartBios"/>
<addaction name="actionStartFullscreenUI2"/>
<addaction name="actionToolbarStartFile"/>
<addaction name="actionToolbarStartDisc"/>
<addaction name="actionToolbarStartBios"/>
<addaction name="actionToolbarStartFullscreenUI"/>
<addaction name="separator"/>
<addaction name="actionPowerOff"/>
<addaction name="actionReset"/>
<addaction name="actionPause"/>
<addaction name="actionChangeDisc"/>
<addaction name="actionScreenshot"/>
<addaction name="actionToolbarPowerOff"/>
<addaction name="actionToolbarReset"/>
<addaction name="actionToolbarPause"/>
<addaction name="actionToolbarChangeDisc"/>
<addaction name="actionToolbarScreenshot"/>
<addaction name="separator"/>
<addaction name="actionLoadState"/>
<addaction name="actionSaveState"/>
<addaction name="actionToolbarLoadState"/>
<addaction name="actionToolbarSaveState"/>
<addaction name="separator"/>
<addaction name="actionFullscreen"/>
<addaction name="actionToolbarFullscreen"/>
<addaction name="separator"/>
<addaction name="actionSettings2"/>
<addaction name="actionControllerSettings"/>
<addaction name="actionToolbarSettings"/>
<addaction name="actionToolbarControllerSettings"/>
</widget>
<widget class="QStatusBar" name="statusBar"/>
<action name="actionStartFile">
@@ -263,6 +268,15 @@
<string>Start &amp;File...</string>
</property>
</action>
<action name="actionToolbarStartFile">
<property name="icon">
<iconset theme="file-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string comment="In Toolbar">Start &amp;File...</string>
</property>
</action>
<action name="actionStartDisc">
<property name="icon">
<iconset theme="disc-2-line">
@@ -272,6 +286,15 @@
<string>Start &amp;Disc...</string>
</property>
</action>
<action name="actionToolbarStartDisc">
<property name="icon">
<iconset theme="disc-2-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string comment="In Toolbar">Start &amp;Disc...</string>
</property>
</action>
<action name="actionStartBios">
<property name="icon">
<iconset theme="chip-line">
@@ -281,6 +304,15 @@
<string>Start &amp;BIOS</string>
</property>
</action>
<action name="actionToolbarStartBios">
<property name="icon">
<iconset theme="chip-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string comment="In Toolbar">Start &amp;BIOS</string>
</property>
</action>
<action name="actionScanForNewGames">
<property name="icon">
<iconset theme="file-search-line">
@@ -308,6 +340,15 @@
<string>Shut &amp;Down</string>
</property>
</action>
<action name="actionToolbarPowerOff">
<property name="icon">
<iconset theme="shut-down-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string comment="In Toolbar">Shut &amp;Down</string>
</property>
</action>
<action name="actionPowerOffWithoutSaving">
<property name="icon">
<iconset theme="close-line">
@@ -326,6 +367,15 @@
<string>&amp;Reset</string>
</property>
</action>
<action name="actionToolbarReset">
<property name="icon">
<iconset theme="restart-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string comment="In Toolbar">&amp;Reset</string>
</property>
</action>
<action name="actionPause">
<property name="checkable">
<bool>true</bool>
@@ -338,22 +388,34 @@
<string>&amp;Pause</string>
</property>
</action>
<action name="actionLoadState">
<action name="actionToolbarPause">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset theme="pause-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string comment="In Toolbar">&amp;Pause</string>
</property>
</action>
<action name="actionToolbarLoadState">
<property name="icon">
<iconset theme="floppy-out-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Load State</string>
<string comment="In Toolbar">&amp;Load State</string>
</property>
</action>
<action name="actionSaveState">
<action name="actionToolbarSaveState">
<property name="icon">
<iconset theme="floppy-in-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Save State</string>
<string comment="In Toolbar">&amp;Save State</string>
</property>
</action>
<action name="actionExit">
@@ -392,6 +454,15 @@
<string>&amp;Controllers</string>
</property>
</action>
<action name="actionToolbarControllerSettings">
<property name="icon">
<iconset theme="controller-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string comment="In Toolbar">&amp;Controllers</string>
</property>
</action>
<action name="actionHotkeySettings">
<property name="icon">
<iconset theme="keyboard-line">
@@ -433,37 +504,46 @@
<string>Fullscreen</string>
</property>
</action>
<action name="actionToolbarFullscreen">
<property name="icon">
<iconset theme="fullscreen-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string comment="In Toolbar">Fullscreen</string>
</property>
</action>
<action name="actionResolution_Scale">
<property name="text">
<string>Resolution Scale</string>
</property>
</action>
<action name="actionGitHubRepository">
<property name="text">
<string>&amp;GitHub Repository...</string>
</property>
<property name="icon">
<iconset theme="github">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;GitHub Repository...</string>
</property>
</action>
<action name="actionSupportForums">
<property name="text">
<string>Support &amp;Forums...</string>
</property>
<property name="icon">
<iconset theme="at">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Support &amp;Forums...</string>
</property>
</action>
<action name="actionDiscordServer">
<property name="text">
<string>&amp;Discord Server...</string>
</property>
<property name="icon">
<iconset theme="discord">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Discord Server...</string>
</property>
</action>
<action name="actionCheckForUpdates">
<property name="icon">
@@ -484,21 +564,21 @@
</property>
</action>
<action name="actionAbout">
<property name="icon">
<iconset resource="resources/resources.qrc">
<normaloff>:/icons/AppIcon64.png</normaloff>:/icons/AppIcon64.png</iconset>
</property>
<property name="text">
<string>&amp;About PCSX2...</string>
</property>
<property name="icon">
<iconset resource="resources/resources.qrc">
<normaloff>:/icons/AppIcon.png</normaloff>:/icons/AppIcon.png</iconset>
</property>
</action>
<action name="actionChangeDisc">
<action name="actionToolbarChangeDisc">
<property name="icon">
<iconset theme="disc-eject-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Change Disc...</string>
<string comment="In Toolbar">Change Disc...</string>
</property>
</action>
<action name="actionAudioSettings">
@@ -549,13 +629,13 @@
<enum>QAction::PreferencesRole</enum>
</property>
</action>
<action name="actionSettings2">
<action name="actionToolbarSettings">
<property name="icon">
<iconset theme="settings-3-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Settings</string>
<string comment="In Toolbar">&amp;Settings</string>
</property>
<property name="menuRole">
<enum>QAction::PreferencesRole</enum>
@@ -595,6 +675,15 @@
<string>&amp;Screenshot</string>
</property>
</action>
<action name="actionToolbarScreenshot">
<property name="icon">
<iconset theme="screenshot-2-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string comment="In Toolbar">&amp;Screenshot</string>
</property>
</action>
<action name="actionMemoryCardSettings">
<property name="icon">
<iconset theme="memcard-line">
@@ -720,55 +809,55 @@
</property>
</action>
<action name="actionGridViewZoomIn">
<property name="icon">
<iconset theme="zoom-in-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Zoom &amp;In (Grid View)</string>
</property>
<property name="shortcut">
<string>Ctrl++</string>
</property>
<property name="icon">
<iconset theme="zoom-in-line">
<normaloff>.</normaloff>.</iconset>
</property>
</action>
<action name="actionGridViewZoomOut">
<property name="icon">
<iconset theme="zoom-out-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Zoom &amp;Out (Grid View)</string>
</property>
<property name="shortcut">
<string>Ctrl+-</string>
</property>
<property name="icon">
<iconset theme="zoom-out-line">
<normaloff>.</normaloff>.</iconset>
</property>
</action>
<action name="actionGridViewRefreshCovers">
<property name="text">
<string>Refresh &amp;Covers (Grid View)</string>
</property>
<property name="icon">
<iconset theme="refresh-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Refresh &amp;Covers (Grid View)</string>
</property>
</action>
<action name="actionOpen_Memory_Card_Directory">
<property name="text">
<string>Open Memory Card Directory...</string>
</property>
<property name="icon">
<iconset theme="memcard-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Open Memory Card Directory...</string>
</property>
</action>
<action name="actionOpenDataDirectory">
<property name="text">
<string>Open Data Directory...</string>
</property>
<property name="icon">
<iconset theme="folder-open-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Open Data Directory...</string>
</property>
</action>
<action name="actionToggleSoftwareRendering">
<property name="text">
@@ -776,13 +865,13 @@
</property>
</action>
<action name="actionDebugger">
<property name="text">
<string>Open Debugger</string>
</property>
<property name="icon">
<iconset theme="heart-circle-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Open Debugger</string>
</property>
</action>
<action name="actionReloadPatches">
<property name="text">
@@ -920,23 +1009,23 @@
<string>Start Big Picture Mode</string>
</property>
</action>
<action name="actionStartFullscreenUI2">
<action name="actionToolbarStartFullscreenUI">
<property name="icon">
<iconset theme="tv-2-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Big Picture</string>
<string comment="In Toolbar">Big Picture</string>
</property>
</action>
<action name="actionCoverDownloader">
<property name="text">
<string>Cover Downloader...</string>
</property>
<property name="icon">
<iconset theme="artboard-2-line">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Cover Downloader...</string>
</property>
</action>
<action name="actionShowAdvancedSettings">
<property name="checkable">
+85 -45
View File
@@ -21,6 +21,7 @@
#include "MainWindow.h"
#include "QtHost.h"
#include "QtUtils.h"
#include "SetupWizardDialog.h"
#include "svnrev.h"
#include "pcsx2/CDVD/CDVDcommon.h"
@@ -38,14 +39,15 @@
#include "pcsx2/ImGui/ImGuiManager.h"
#include "pcsx2/Input/InputManager.h"
#include "pcsx2/LogSink.h"
#include "pcsx2/MTGS.h"
#include "pcsx2/PAD/Host/PAD.h"
#include "pcsx2/PerformanceMetrics.h"
#include "pcsx2/SysForwardDefs.h"
#include "pcsx2/VMManager.h"
#include "common/Assertions.h"
#include "common/Console.h"
#include "common/CrashHandler.h"
#include "common/Exceptions.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/SettingsWrapper.h"
@@ -79,6 +81,8 @@ namespace QtHost
static bool InitializeConfig();
static void SaveSettings();
static void HookSignals();
static void RegisterTypes();
static bool RunSetupWizard();
} // namespace QtHost
//////////////////////////////////////////////////////////////////////////
@@ -91,6 +95,7 @@ static bool s_nogui_mode = false;
static bool s_start_fullscreen_ui = false;
static bool s_start_fullscreen_ui_fullscreen = false;
static bool s_test_config_and_exit = false;
static bool s_run_setup_wizard = false;
static bool s_boot_and_debug = false;
//////////////////////////////////////////////////////////////////////////
@@ -186,7 +191,7 @@ void EmuThread::startFullscreenUI(bool fullscreen)
return;
}
if (VMManager::HasValidVM() || GetMTGS().IsOpen())
if (VMManager::HasValidVM() || MTGS::IsOpen())
return;
// this should just set the flag so it gets automatically started
@@ -195,7 +200,7 @@ void EmuThread::startFullscreenUI(bool fullscreen)
m_is_rendering_to_main = shouldRenderToMain();
m_is_fullscreen = fullscreen;
if (!GetMTGS().WaitForOpen())
if (!MTGS::WaitForOpen())
{
m_run_fullscreen_ui = false;
return;
@@ -213,18 +218,18 @@ void EmuThread::stopFullscreenUI()
QMetaObject::invokeMethod(this, &EmuThread::stopFullscreenUI, Qt::QueuedConnection);
// wait until the host display is gone
while (GetMTGS().IsOpen())
while (MTGS::IsOpen())
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 1);
return;
}
if (!GetMTGS().IsOpen())
if (!MTGS::IsOpen())
return;
pxAssertRel(!VMManager::HasValidVM(), "VM is not valid at FSUI shutdown time");
m_run_fullscreen_ui = false;
GetMTGS().WaitForClose();
MTGS::WaitForClose();
}
void EmuThread::startVM(std::shared_ptr<VMBootParameters> boot_params)
@@ -505,14 +510,14 @@ void EmuThread::setFullscreen(bool fullscreen, bool allow_render_to_main)
return;
}
if (!GetMTGS().IsOpen() || m_is_fullscreen == fullscreen)
if (!MTGS::IsOpen() || m_is_fullscreen == fullscreen)
return;
// This will call back to us on the MTGS thread.
m_is_fullscreen = fullscreen;
m_is_rendering_to_main = allow_render_to_main && shouldRenderToMain();
GetMTGS().UpdateDisplayWindow();
GetMTGS().WaitGS();
MTGS::UpdateDisplayWindow();
MTGS::WaitGS();
// If we're using exclusive fullscreen, the refresh rate may have changed.
UpdateVSyncRate(true);
@@ -526,17 +531,17 @@ void EmuThread::setSurfaceless(bool surfaceless)
return;
}
if (!GetMTGS().IsOpen() || m_is_surfaceless == surfaceless)
if (!MTGS::IsOpen() || m_is_surfaceless == surfaceless)
return;
// If we went surfaceless and were running the fullscreen UI, stop MTGS running idle.
// Otherwise, we'll keep trying to present to nothing.
GetMTGS().SetRunIdle(!surfaceless && m_run_fullscreen_ui);
MTGS::SetRunIdle(!surfaceless && m_run_fullscreen_ui);
// This will call back to us on the MTGS thread.
m_is_surfaceless = surfaceless;
GetMTGS().UpdateDisplayWindow();
GetMTGS().WaitGS();
MTGS::UpdateDisplayWindow();
MTGS::WaitGS();
}
void EmuThread::applySettings()
@@ -591,20 +596,22 @@ void Host::LoadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& loc
void EmuThread::checkForSettingChanges(const Pcsx2Config& old_config)
{
QMetaObject::invokeMethod(g_main_window, &MainWindow::checkForSettingChanges, Qt::QueuedConnection);
if (g_main_window)
{
QMetaObject::invokeMethod(g_main_window, &MainWindow::checkForSettingChanges, Qt::QueuedConnection);
updatePerformanceMetrics(true);
}
if (GetMTGS().IsOpen())
if (MTGS::IsOpen())
{
const bool render_to_main = shouldRenderToMain();
if (!m_is_fullscreen && m_is_rendering_to_main != render_to_main)
{
m_is_rendering_to_main = render_to_main;
GetMTGS().UpdateDisplayWindow();
GetMTGS().WaitGS();
MTGS::UpdateDisplayWindow();
MTGS::WaitGS();
}
}
updatePerformanceMetrics(true);
}
void Host::CheckForSettingsChanges(const Pcsx2Config& old_config)
@@ -628,7 +635,7 @@ void EmuThread::toggleSoftwareRendering()
if (!VMManager::HasValidVM())
return;
GetMTGS().ToggleSoftwareRendering();
MTGS::ToggleSoftwareRendering();
}
void EmuThread::switchRenderer(GSRendererType renderer)
@@ -642,7 +649,7 @@ void EmuThread::switchRenderer(GSRendererType renderer)
if (!VMManager::HasValidVM())
return;
GetMTGS().SwitchRenderer(renderer);
MTGS::SwitchRenderer(renderer);
}
void EmuThread::changeDisc(CDVD_SourceType source, const QString& path)
@@ -786,10 +793,10 @@ void EmuThread::connectDisplaySignals(DisplayWidget* widget)
void EmuThread::onDisplayWindowResized(int width, int height, float scale)
{
if (!GetMTGS().IsOpen())
if (!MTGS::IsOpen())
return;
GetMTGS().ResizeDisplayWindow(width, height, scale);
MTGS::ResizeDisplayWindow(width, height, scale);
}
void EmuThread::onApplicationStateChanged(Qt::ApplicationState state)
@@ -835,7 +842,7 @@ void EmuThread::redrawDisplayWindow()
if (!VMManager::HasValidVM() || VMManager::GetState() == VMState::Running)
return;
GetMTGS().PresentCurrentFrame();
MTGS::PresentCurrentFrame();
}
void EmuThread::runOnCPUThread(const std::function<void()>& func)
@@ -854,7 +861,7 @@ void EmuThread::queueSnapshot(quint32 gsdump_frames)
if (!VMManager::HasValidVM())
return;
GetMTGS().RunOnGSThread([gsdump_frames]() { GSQueueSnapshot(std::string(), gsdump_frames); });
MTGS::RunOnGSThread([gsdump_frames]() { GSQueueSnapshot(std::string(), gsdump_frames); });
}
void EmuThread::beginCapture(const QString& path)
@@ -868,13 +875,13 @@ void EmuThread::beginCapture(const QString& path)
if (!VMManager::HasValidVM())
return;
GetMTGS().RunOnGSThread([path = path.toStdString()]() {
MTGS::RunOnGSThread([path = path.toStdString()]() {
GSBeginCapture(std::move(path));
});
// Sync GS thread. We want to start adding audio at the same time as video.
// TODO: This could be up to 64 frames behind... use the pts to adjust it.
GetMTGS().WaitGS(false, false, false);
MTGS::WaitGS(false, false, false);
}
void EmuThread::endCapture()
@@ -888,7 +895,7 @@ void EmuThread::endCapture()
if (!VMManager::HasValidVM())
return;
GetMTGS().RunOnGSThread(&GSEndCapture);
MTGS::RunOnGSThread(&GSEndCapture);
}
std::optional<WindowInfo> EmuThread::acquireRenderWindow(bool recreate_window)
@@ -1179,13 +1186,6 @@ void Host::SetFullscreen(bool enabled)
g_emu_thread->setFullscreen(enabled, true);
}
alignas(16) static SysMtgsThread s_mtgs_thread;
SysMtgsThread& GetMTGS()
{
return s_mtgs_thread;
}
bool QtHost::InitializeConfig()
{
if (!EmuFolders::InitializeCriticalFolders())
@@ -1199,6 +1199,7 @@ bool QtHost::InitializeConfig()
CrashHandler::SetWriteDirectory(EmuFolders::DataRoot);
const std::string path(Path::Combine(EmuFolders::Settings, "PCSX2.ini"));
s_run_setup_wizard = s_run_setup_wizard || !FileSystem::FileExists(path.c_str());
Console.WriteLn("Loading config from %s.", path.c_str());
s_base_settings_interface = std::make_unique<INISettingsInterface>(std::move(path));
@@ -1215,11 +1216,19 @@ bool QtHost::InitializeConfig()
}
VMManager::SetDefaultSettings(*s_base_settings_interface, true, true, true, true, true);
SaveSettings();
// Don't save if we're running the setup wizard. We want to run it next time if they don't finish it.
if (!s_run_setup_wizard)
SaveSettings();
}
// Setup wizard was incomplete last time?
s_run_setup_wizard =
s_run_setup_wizard || s_base_settings_interface->GetBoolValue("UI", "SetupWizardIncomplete", false);
LogSink::SetBlockSystemConsole(QtHost::InNoGUIMode());
VMManager::Internal::LoadStartupSettings();
InstallTranslator();
return true;
}
@@ -1535,6 +1544,7 @@ void QtHost::PrintCommandLineHelp(const std::string_view& progname)
std::fprintf(stderr, " -bigpicture: Forces PCSX2 to use the Big Picture mode (useful for controller-only and couch play).\n");
std::fprintf(stderr, " -earlyconsolelog: Forces logging of early console messages to console.\n");
std::fprintf(stderr, " -testconfig: Initializes configuration and checks version, then exits.\n");
std::fprintf(stderr, " -setupwizard: Forces initial setup wizard to run.\n");
std::fprintf(stderr, " -debugger: Open debugger and break on entry point.\n");
#ifdef ENABLE_RAINTEGRATION
std::fprintf(stderr, " -raintegration: Use RAIntegration instead of built-in achievement support.\n");
@@ -1658,6 +1668,11 @@ bool QtHost::ParseCommandLineOptions(const QStringList& args, std::shared_ptr<VM
s_test_config_and_exit = true;
continue;
}
else if (CHECK_ARG(QStringLiteral("-setupwizard")))
{
s_run_setup_wizard = true;
continue;
}
else if (CHECK_ARG(QStringLiteral("-debugger")))
{
s_boot_and_debug = true;
@@ -1737,7 +1752,7 @@ static bool PerformEarlyHardwareChecks()
#endif
static void RegisterTypes()
void QtHost::RegisterTypes()
{
qRegisterMetaType<std::optional<bool>>();
qRegisterMetaType<std::optional<WindowInfo>>("std::optional<WindowInfo>()");
@@ -1756,12 +1771,28 @@ static void RegisterTypes()
qRegisterMetaType<const GameList::Entry*>();
}
bool QtHost::RunSetupWizard()
{
// Set a flag in the config so that even though we created the ini, we'll run the wizard next time.
Host::SetBaseBoolSettingValue("UI", "SetupWizardIncomplete", true);
Host::CommitBaseSettingChanges();
SetupWizardDialog dialog;
if (dialog.exec() == QDialog::Rejected)
return false;
// Remove the flag.
Host::SetBaseBoolSettingValue("UI", "SetupWizardIncomplete", false);
Host::CommitBaseSettingChanges();
return true;
}
int main(int argc, char* argv[])
{
CrashHandler::Install();
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
RegisterTypes();
QtHost::RegisterTypes();
QApplication app(argc, argv);
@@ -1784,24 +1815,32 @@ int main(int argc, char* argv[])
// Set theme before creating any windows.
QtHost::UpdateApplicationTheme();
MainWindow* main_window = new MainWindow();
// Start up the CPU thread.
QtHost::HookSignals();
EmuThread::start();
// Optionally run setup wizard.
int result;
if (s_run_setup_wizard && !QtHost::RunSetupWizard())
{
result = EXIT_FAILURE;
goto shutdown_and_exit;
}
// Create all window objects, the emuthread might still be starting up at this point.
main_window->initialize();
g_main_window = new MainWindow();
g_main_window->initialize();
// When running in batch mode, ensure game list is loaded, but don't scan for any new files.
if (!s_batch_mode)
main_window->refreshGameList(false);
g_main_window->refreshGameList(false);
else
GameList::Refresh(false, true);
// Don't bother showing the window in no-gui mode.
if (!s_nogui_mode)
main_window->show();
g_main_window->show();
// Initialize big picture mode if requested.
if (s_start_fullscreen_ui)
@@ -1810,18 +1849,19 @@ int main(int argc, char* argv[])
if (s_boot_and_debug)
{
DebugInterface::setPauseOnEntry(true);
main_window->openDebugger();
g_main_window->openDebugger();
}
// Skip the update check if we're booting a game directly.
if (autoboot)
g_emu_thread->startVM(std::move(autoboot));
else if (!s_nogui_mode)
main_window->startupUpdateCheck();
g_main_window->startupUpdateCheck();
// This doesn't return until we exit.
const int result = app.exec();
result = app.exec();
shutdown_and_exit:
// Shutting down.
EmuThread::stop();
if (g_main_window)
+9
View File
@@ -216,6 +216,9 @@ namespace QtHost
/// Default theme name for the platform.
const char* GetDefaultThemeName();
/// Default language for the platform.
const char* GetDefaultLanguage();
/// Sets application theme according to settings.
void UpdateApplicationTheme();
@@ -234,6 +237,12 @@ namespace QtHost
/// Executes a function on the UI thread.
void RunOnUIThread(const std::function<void()>& func, bool block = false);
/// Returns a list of supported languages and codes (suffixes for translation files).
std::vector<std::pair<QString, QString>> GetAvailableLanguageList();
/// Call when the language changes.
void InstallTranslator();
/// Returns the application name and version, optionally including debug/devel config indicator.
QString GetAppNameAndVersion();
+6 -2
View File
@@ -931,14 +931,18 @@ namespace SettingWidgetBinder
template <typename WidgetType>
static inline void BindWidgetToEnumSetting(SettingsInterface* sif, WidgetType* widget, std::string section, std::string key,
const char** enum_names, const char** enum_values, const char* default_value)
const char** enum_names, const char** enum_values, const char* default_value, const char* translation_ctx = nullptr)
{
using Accessor = SettingAccessor<WidgetType>;
const std::string value = Host::GetBaseStringSettingValue(section.c_str(), key.c_str(), default_value);
for (int i = 0; enum_names[i] != nullptr; i++)
widget->addItem(QString::fromUtf8(enum_names[i]));
{
widget->addItem(translation_ctx ?
qApp->translate(translation_ctx, enum_names[i]) :
QString::fromUtf8(enum_names[i]));
}
int enum_index = -1;
for (int i = 0; enum_values[i] != nullptr; i++)
+2 -14
View File
@@ -9,22 +9,10 @@
<rect>
<x>0</x>
<y>0</y>
<width>410</width>
<height>190</height>
<width>447</width>
<height>196</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>410</width>
<height>190</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>410</width>
<height>190</height>
</size>
</property>
<property name="windowTitle">
<string comment="Window title">RetroAchievements Login</string>
</property>
@@ -157,7 +157,7 @@
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;PCSX2 uses RetroAchievements as an achievement database and for tracking progress. To use achievements, please sign up for an account at &lt;a href=&quot;https://retroachievements.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#4169e1;&quot;&gt;retroachievements.org&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p align=&quot;justify&quot;&gt;To view the achievement list in-game, press the hotkey for &lt;span style=&quot; font-weight:600;&quot;&gt;Open Pause Menu&lt;/span&gt; and select &lt;span style=&quot; font-weight:600;&quot;&gt;Achievements&lt;/span&gt; from the menu.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;PCSX2 uses RetroAchievements as an achievement database and for tracking progress. To use achievements, please sign up for an account at &lt;a href=&quot;https://retroachievements.org/&quot;&gt;retroachievements.org&lt;/a&gt;.&lt;/p&gt;&lt;p align=&quot;justify&quot;&gt;To view the achievement list in-game, press the hotkey for &lt;span style=&quot; font-weight:600;&quot;&gt;Open Pause Menu&lt;/span&gt; and select &lt;span style=&quot; font-weight:600;&quot;&gt;Achievements&lt;/span&gt; from the menu.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
+18 -23
View File
@@ -39,20 +39,6 @@ static constexpr s32 DEFAULT_SOUNDTOUCH_SEQUENCE_LENGTH = 30;
static constexpr s32 DEFAULT_SOUNDTOUCH_SEEK_WINDOW = 20;
static constexpr s32 DEFAULT_SOUNDTOUCH_OVERLAP = 10;
static const char* s_output_module_entries[] = {QT_TRANSLATE_NOOP("AudioSettingsWidget", "No Sound (Emulate SPU2 only)"),
//: Cubeb is an audio engine name. Leave as-is.
QT_TRANSLATE_NOOP("AudioSettingsWidget", "Cubeb (Cross-platform)"),
#ifdef _WIN32
//: XAudio2 is an audio engine name. Leave as-is.
QT_TRANSLATE_NOOP("AudioSettingsWidget", "XAudio2"),
#endif
nullptr};
static const char* s_output_module_values[] = {"nullout", "cubeb",
#ifdef _WIN32
"xaudio2",
#endif
nullptr};
AudioSettingsWidget::AudioSettingsWidget(SettingsDialog* dialog, QWidget* parent)
: QWidget(parent)
, m_dialog(dialog)
@@ -60,6 +46,7 @@ AudioSettingsWidget::AudioSettingsWidget(SettingsDialog* dialog, QWidget* parent
SettingsInterface* sif = dialog->getSettingsInterface();
m_ui.setupUi(this);
populateOutputModules();
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.syncMode, "SPU2/Output", "SynchMode", DEFAULT_SYNCHRONIZATION_MODE);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.expansionMode, "SPU2/Output", "SpeakerConfiguration", DEFAULT_EXPANSION_MODE);
@@ -69,8 +56,7 @@ AudioSettingsWidget::AudioSettingsWidget(SettingsDialog* dialog, QWidget* parent
updateTargetLatencyRange();
expansionModeChanged();
SettingWidgetBinder::BindWidgetToEnumSetting(
sif, m_ui.outputModule, "SPU2/Output", "OutputModule", s_output_module_entries, s_output_module_values, DEFAULT_OUTPUT_MODULE);
SettingWidgetBinder::BindWidgetToStringSetting(sif, m_ui.outputModule, "SPU2/Output", "OutputModule", DEFAULT_OUTPUT_MODULE);
SettingWidgetBinder::BindSliderToIntSetting(
//: Measuring unit that will appear after the number selected in its option. Adapt the space depending on your language's rules.
sif, m_ui.targetLatency, m_ui.targetLatencyLabel, tr(" ms"), "SPU2/Output", "Latency", DEFAULT_TARGET_LATENCY);
@@ -86,15 +72,18 @@ AudioSettingsWidget::AudioSettingsWidget(SettingsDialog* dialog, QWidget* parent
outputModuleChanged();
m_ui.volume->setValue(m_dialog->getEffectiveIntValue("SPU2/Mixing", "FinalVolume", DEFAULT_VOLUME));
m_ui.volume->setContextMenuPolicy(Qt::CustomContextMenu);
connect(m_ui.volume, &QSlider::valueChanged, this, &AudioSettingsWidget::volumeChanged);
connect(m_ui.volume, &QSlider::customContextMenuRequested, this, &AudioSettingsWidget::volumeContextMenuRequested);
updateVolumeLabel();
if (sif && sif->ContainsValue("SPU2/Mixing", "FinalVolume"))
if (dialog->isPerGameSettings())
{
QFont bold_font(m_ui.volume->font());
bold_font.setBold(true);
m_ui.volumeLabel->setFont(bold_font);
connect(m_ui.volume, &QSlider::customContextMenuRequested, this, &AudioSettingsWidget::volumeContextMenuRequested);
m_ui.volume->setContextMenuPolicy(Qt::CustomContextMenu);
if (sif->ContainsValue("SPU2/Mixing", "FinalVolume"))
{
QFont bold_font(m_ui.volume->font());
bold_font.setBold(true);
m_ui.volumeLabel->setFont(bold_font);
}
}
SettingWidgetBinder::BindSliderToIntSetting(sif, m_ui.sequenceLength, m_ui.sequenceLengthLabel, tr(" ms"), "Soundtouch",
@@ -153,6 +142,12 @@ void AudioSettingsWidget::expansionModeChanged()
m_ui.dplLevel->setDisabled(!expansion51);
}
void AudioSettingsWidget::populateOutputModules()
{
for (const SndOutModule* mod : GetSndOutModules())
m_ui.outputModule->addItem(qApp->translate("SPU2", mod->GetDisplayName()), QString::fromUtf8(mod->GetIdent()));
}
void AudioSettingsWidget::outputModuleChanged()
{
const std::string module_name(m_dialog->getEffectiveStringValue("SPU2/Output", "OutputModule", DEFAULT_OUTPUT_MODULE));
@@ -284,7 +279,7 @@ void AudioSettingsWidget::volumeContextMenuRequested(const QPoint& pt)
m_ui.volume->connect(menu.addAction(qApp->translate("SettingWidgetBinder", "Reset")), &QAction::triggered, this, [this]() {
const s32 global_value = Host::GetBaseIntSettingValue("SPU2/Mixing", "FinalVolume", DEFAULT_VOLUME);
{
QSignalBlocker sb(m_ui.volumeLabel);
QSignalBlocker sb(m_ui.volume);
m_ui.volume->setValue(global_value);
updateVolumeLabel();
}
+1
View File
@@ -42,6 +42,7 @@ private Q_SLOTS:
void resetTimestretchDefaults();
private:
void populateOutputModules();
void updateVolumeLabel();
SettingsDialog* m_dialog;
+13 -6
View File
@@ -78,11 +78,17 @@ void BIOSSettingsWidget::refreshList()
}
void BIOSSettingsWidget::listRefreshed(const QVector<BIOSInfo>& items)
{
QSignalBlocker sb(m_ui.fileList);
populateList(m_ui.fileList, items);
m_ui.fileList->setEnabled(true);
}
void BIOSSettingsWidget::populateList(QTreeWidget* list, const QVector<BIOSInfo>& items)
{
const std::string selected_bios(Host::GetBaseStringSettingValue("Filenames", "BIOS"));
const QString res_path(QtHost::GetResourcesBasePath());
QSignalBlocker sb(m_ui.fileList);
for (const BIOSInfo& bi : items)
{
QTreeWidgetItem* item = new QTreeWidgetItem();
@@ -129,12 +135,14 @@ void BIOSSettingsWidget::listRefreshed(const QVector<BIOSInfo>& items)
break;
}
m_ui.fileList->addTopLevelItem(item);
list->addTopLevelItem(item);
if (bi.filename == selected_bios)
{
list->selectionModel()->setCurrentIndex(list->indexFromItem(item), QItemSelectionModel::Select);
item->setSelected(true);
}
}
m_ui.fileList->setEnabled(true);
}
void BIOSSettingsWidget::listItemChanged(const QTreeWidgetItem* current, const QTreeWidgetItem* previous)
@@ -151,9 +159,8 @@ void BIOSSettingsWidget::fastBootChanged()
m_ui.fastBootFastForward->setEnabled(enabled);
}
BIOSSettingsWidget::RefreshThread::RefreshThread(BIOSSettingsWidget* parent, const QString& directory)
BIOSSettingsWidget::RefreshThread::RefreshThread(QWidget* parent, const QString& directory)
: QThread(parent)
, m_parent(parent)
, m_directory(directory)
{
}
@@ -179,5 +186,5 @@ void BIOSSettingsWidget::RefreshThread::run()
}
}
QMetaObject::invokeMethod(m_parent, "listRefreshed", Qt::QueuedConnection, Q_ARG(const QVector<BIOSInfo>&, items));
QMetaObject::invokeMethod(parent(), "listRefreshed", Qt::QueuedConnection, Q_ARG(const QVector<BIOSInfo>&, items));
}
+15 -14
View File
@@ -46,6 +46,21 @@ public:
BIOSSettingsWidget(SettingsDialog* dialog, QWidget* parent);
~BIOSSettingsWidget();
class RefreshThread final : public QThread
{
public:
RefreshThread(QWidget* parent, const QString& directory);
~RefreshThread();
protected:
void run() override;
private:
QString m_directory;
};
static void populateList(QTreeWidget* list, const QVector<BIOSInfo>& items);
private Q_SLOTS:
void refreshList();
@@ -58,19 +73,5 @@ private:
Ui::BIOSSettingsWidget m_ui;
SettingsDialog* m_dialog;
class RefreshThread final : public QThread
{
public:
RefreshThread(BIOSSettingsWidget* parent, const QString& directory);
~RefreshThread();
protected:
void run() override;
private:
BIOSSettingsWidget* m_parent;
QString m_directory;
};
RefreshThread* m_refresh_thread = nullptr;
};
@@ -72,7 +72,7 @@ QIcon ControllerBindingWidget::getIcon() const
void ControllerBindingWidget::populateControllerTypes()
{
for (const auto& [name, display_name] : PAD::GetControllerTypeNames())
m_ui.controllerType->addItem(QString::fromStdString(display_name), QString::fromStdString(name));
m_ui.controllerType->addItem(qApp->translate("Pad", display_name), QString::fromStdString(name));
}
void ControllerBindingWidget::onTypeChanged()
@@ -116,8 +116,8 @@ void ControllerBindingWidget::onTypeChanged()
if (has_settings)
{
const gsl::span<const SettingInfo> settings(cinfo->settings, cinfo->num_settings);
m_settings_widget =
new ControllerCustomSettingsWidget(settings, m_config_section, std::string(), cinfo->name, getDialog(), m_ui.stackedWidget);
m_settings_widget = new ControllerCustomSettingsWidget(
settings, m_config_section, std::string(), "Pad", getDialog(), m_ui.stackedWidget);
m_ui.stackedWidget->addWidget(m_settings_widget);
}
@@ -343,7 +343,7 @@ ControllerMacroEditWidget::ControllerMacroEditWidget(ControllerMacroWidget* pare
continue;
QListWidgetItem* item = new QListWidgetItem();
item->setText(QString::fromUtf8(bi.display_name));
item->setText(qApp->translate("Pad", bi.display_name));
item->setCheckState((std::find(m_binds.begin(), m_binds.end(), &bi) != m_binds.end()) ? Qt::Checked : Qt::Unchecked);
m_ui.bindList->addItem(item);
}
@@ -374,7 +374,7 @@ QString ControllerMacroEditWidget::getSummary() const
{
if (!str.isEmpty())
str += static_cast<QChar>('/');
str += QString::fromUtf8(bi->name);
str += qApp->translate("Pad", bi->display_name);
}
return str.isEmpty() ? tr("Not Configured") : str;
}
@@ -902,7 +902,7 @@ QIcon USBDeviceWidget::getIcon() const
void USBDeviceWidget::populateDeviceTypes()
{
for (const auto& [name, display_name] : USB::GetDeviceTypes())
m_ui.deviceType->addItem(QString::fromStdString(display_name), QString::fromStdString(name));
m_ui.deviceType->addItem(qApp->translate("USB", display_name), QString::fromUtf8(name));
}
void USBDeviceWidget::populatePages()
@@ -950,7 +950,7 @@ void USBDeviceWidget::populatePages()
if (!settings.empty())
{
m_settings_widget = new ControllerCustomSettingsWidget(
settings, m_config_section, m_device_type + "_", m_device_type.c_str(), m_dialog, m_ui.stackedWidget);
settings, m_config_section, m_device_type + "_", "USB", m_dialog, m_ui.stackedWidget);
m_ui.stackedWidget->addWidget(m_settings_widget);
}
@@ -1027,7 +1027,7 @@ void USBDeviceWidget::onAutomaticBindingClicked()
void USBDeviceWidget::onClearBindingsClicked()
{
if (QMessageBox::question(QtUtils::GetRootWidget(this), tr("Clear Bindings"),
tr("Are you sure you want to clear all bindings for this controller? This action cannot be undone.")) != QMessageBox::Yes)
tr("Are you sure you want to clear all bindings for this device? This action cannot be undone.")) != QMessageBox::Yes)
{
return;
}
@@ -128,6 +128,7 @@ void ControllerSettingsDialog::onNewProfileClicked()
// from global
auto lock = Host::GetSettingsLock();
PAD::CopyConfiguration(&temp_si, *Host::Internal::GetBaseSettingsLayer(), true, true, false);
USB::CopyConfiguration(&temp_si, *Host::Internal::GetBaseSettingsLayer(), true, true);
}
else
{
@@ -135,6 +136,7 @@ void ControllerSettingsDialog::onNewProfileClicked()
const bool copy_hotkey_bindings = m_profile_interface->GetBoolValue("Pad", "UseProfileHotkeyBindings", false);
temp_si.SetBoolValue("Pad", "UseProfileHotkeyBindings", copy_hotkey_bindings);
PAD::CopyConfiguration(&temp_si, *m_profile_interface, true, true, copy_hotkey_bindings);
USB::CopyConfiguration(&temp_si, *m_profile_interface, true, true);
}
}
@@ -163,6 +165,7 @@ void ControllerSettingsDialog::onLoadProfileClicked()
{
auto lock = Host::GetSettingsLock();
PAD::CopyConfiguration(Host::Internal::GetBaseSettingsLayer(), *m_profile_interface, true, true, false);
USB::CopyConfiguration(Host::Internal::GetBaseSettingsLayer(), *m_profile_interface, true, true);
}
Host::CommitBaseSettingChanges();
@@ -398,7 +401,7 @@ void ControllerSettingsDialog::createWidgets()
m_ui.settingsContainer->addWidget(m_port_bindings[global_slot]);
const PAD::ControllerInfo* ci = PAD::GetControllerInfo(m_port_bindings[global_slot]->getControllerType());
const QString display_name(ci ? QString::fromUtf8(ci->display_name) : QStringLiteral("Unknown"));
const QString display_name(ci ? qApp->translate("Pad", ci->display_name) : QStringLiteral("Unknown"));
QListWidgetItem* item = new QListWidgetItem();
//: Controller Port is an official term from Sony. Find the official translation for your language inside the console's manual.
@@ -454,7 +457,7 @@ void ControllerSettingsDialog::updateListDescription(u32 global_slot, Controller
const bool mtap_enabled = getBoolValue("Pad", (port == 0) ? "MultitapPort1" : "MultitapPort2", false);
const PAD::ControllerInfo* ci = PAD::GetControllerInfo(widget->getControllerType());
const QString display_name(ci ? QString::fromUtf8(ci->display_name) : QStringLiteral("Unknown"));
const QString display_name(ci ? qApp->translate("Pad", ci->display_name) : QStringLiteral("Unknown"));
//: Controller Port is an official term from Sony. Find the official translation for your language inside the console's manual.
item->setText(mtap_enabled ? (tr("Controller Port %1%2\n%3").arg(port + 1).arg(s_mtap_slot_names[slot]).arg(display_name)) :
+14 -1
View File
@@ -73,7 +73,20 @@
</widget>
</item>
<item>
<widget class="QComboBox" name="currentProfile"/>
<widget class="QComboBox" name="currentProfile">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>220</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="newProfile">
+1 -1
View File
@@ -166,7 +166,7 @@
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>Low compatiblity warning: yes, it's very big, but may not work with many games.</string>
<string>Low compatibility warning: yes, it's very big, but may not work with many games.</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+4 -4
View File
@@ -136,10 +136,10 @@ DEV9SettingsWidget::DEV9SettingsWidget(SettingsDialog* dialog, QWidget* parent)
if (m_dialog->isPerGameSettings())
m_ui.ethDevType->addItem(tr("Use Global Setting [%1]").arg(QString::fromUtf8(Pcsx2Config::DEV9Options::NetApiNames[static_cast<u32>(m_global_api)])));
else
m_ui.ethDevType->addItem(QString::fromUtf8(m_api_namelist[0]));
m_ui.ethDevType->addItem(qApp->translate("DEV9SettingsWidget", m_api_namelist[0]));
for (int i = 1; m_api_namelist[i] != nullptr; i++)
m_ui.ethDevType->addItem(QString::fromUtf8(m_api_namelist[i]));
m_ui.ethDevType->addItem(qApp->translate("DEV9SettingsWidget", m_api_namelist[i]));
const std::string value = m_dialog->getStringValue("DEV9/Eth", "EthApi", Pcsx2Config::DEV9Options::NetApiNames[static_cast<int>(Pcsx2Config::DEV9Options::NetApi::Unset)]).value();
@@ -212,12 +212,12 @@ DEV9SettingsWidget::DEV9SettingsWidget(SettingsDialog* dialog, QWidget* parent)
connect(m_ui.ethGatewayAuto, QOverload<int>::of(&QCheckBox::stateChanged), this, [&](int state) { onEthAutoChanged(m_ui.ethGatewayAuto, state, m_ui.ethGatewayAddr, "DEV9/Eth", "AutoGateway"); });
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.ethDNS1Mode, "DEV9/Eth", "ModeDNS1",
s_dns_name, Pcsx2Config::DEV9Options::DnsModeNames, Pcsx2Config::DEV9Options::DnsModeNames[static_cast<int>(Pcsx2Config::DEV9Options::DnsMode::Auto)]);
s_dns_name, Pcsx2Config::DEV9Options::DnsModeNames, Pcsx2Config::DEV9Options::DnsModeNames[static_cast<int>(Pcsx2Config::DEV9Options::DnsMode::Auto)], "DEV9SettingsWidget");
onEthDNSModeChanged(m_ui.ethDNS1Mode, m_ui.ethDNS1Mode->currentIndex(), m_ui.ethDNS1Addr, "DEV9/Eth", "ModeDNS1");
connect(m_ui.ethDNS1Mode, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [&](int index) { onEthDNSModeChanged(m_ui.ethDNS1Mode, index, m_ui.ethDNS1Addr, "DEV9/Eth", "ModeDNS1"); });
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.ethDNS2Mode, "DEV9/Eth", "ModeDNS2",
s_dns_name, Pcsx2Config::DEV9Options::DnsModeNames, Pcsx2Config::DEV9Options::DnsModeNames[static_cast<int>(Pcsx2Config::DEV9Options::DnsMode::Auto)]);
s_dns_name, Pcsx2Config::DEV9Options::DnsModeNames, Pcsx2Config::DEV9Options::DnsModeNames[static_cast<int>(Pcsx2Config::DEV9Options::DnsMode::Auto)], "DEV9SettingsWidget");
onEthDNSModeChanged(m_ui.ethDNS2Mode, m_ui.ethDNS2Mode->currentIndex(), m_ui.ethDNS2Addr, "DEV9/Eth", "ModeDNS2");
connect(m_ui.ethDNS2Mode, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [&](int index) { onEthDNSModeChanged(m_ui.ethDNS2Mode, index, m_ui.ethDNS2Addr, "DEV9/Eth", "ModeDNS2"); });
+1 -1
View File
@@ -59,7 +59,7 @@
<item row="0" column="0" colspan="4">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Used for storing shaders, gzip indices, and game list data.</string>
<string>Used for storing shaders, game list, and achievement data.</string>
</property>
</widget>
</item>
@@ -10,9 +10,6 @@
<height>361</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
@@ -16,9 +16,6 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
@@ -10,9 +10,6 @@
<height>392</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
+5
View File
@@ -268,6 +268,11 @@
<string extracomment="Leave the code as-is, translate the country's name.">PAL-P (Portugal)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-PL (Poland)</string>
</property>
</item>
<item>
<property name="text">
<string extracomment="Leave the code as-is, translate the country's name.">PAL-R (Russia)</string>
+2 -3
View File
@@ -554,8 +554,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
"Helps Harry Potter and Stuntman games. It has a big impact on performance."));
dialog->registerWidgetHelp(m_ui.preloadFrameData, tr("Preload Frame Data"), tr("Unchecked"),
tr("Uploads GS data when rendering a new frame to reproduce some effects accurately. "
"Fixes black screen issues in games like Armored Core: Last Raven."));
tr("Uploads GS data when rendering a new frame to reproduce some effects accurately. "));
dialog->registerWidgetHelp(m_ui.textureInsideRt, tr("Texture Inside RT"), tr("Disabled"),
tr("Allows the texture cache to reuse as an input texture the inner portion of a previous framebuffer."));
@@ -678,7 +677,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
tr("Displays various settings and the current values of those settings, useful for debugging."));
dialog->registerWidgetHelp(m_ui.osdShowInputs, tr("Show Inputs"), tr("Unchecked"),
tr("Shows the current controler state of the system in the bottom left corner of the display."));
tr("Shows the current controller state of the system in the bottom left corner of the display."));
dialog->registerWidgetHelp(
m_ui.osdShowFrameTimes, tr("Show Frame Times"), tr("Unchecked"), tr("Displays a graph showing the average frametimes."));
+3 -3
View File
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>720</width>
<height>492</height>
<height>463</height>
</rect>
</property>
<property name="windowTitle">
@@ -29,7 +29,7 @@
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Renderer</string>
<string/>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
@@ -237,7 +237,7 @@
<item row="6" column="1">
<widget class="QSpinBox" name="stretchY">
<property name="suffix">
<string extracomment="Percentage sign that shows next to a value. You might want to add a space before if you language requires it.">%</string>
<string extracomment="Percentage sign that shows next to a value. You might want to add a space before if your language requires it.">%</string>
</property>
<property name="minimum">
<number>1</number>
+13 -6
View File
@@ -22,7 +22,7 @@
#include "SettingsDialog.h"
#include "QtHost.h"
static const char* THEME_NAMES[] = {
const char* InterfaceSettingsWidget::THEME_NAMES[] = {
QT_TRANSLATE_NOOP("InterfaceSettingsWidget", "Native"),
//: Ignore what Crowdin says in this string about "[Light]/[Dark]" being untouchable here, these are not variables in this case and must be translated.
QT_TRANSLATE_NOOP("InterfaceSettingsWidget", "Fusion [Light/Dark]"),
@@ -52,7 +52,7 @@ static const char* THEME_NAMES[] = {
QT_TRANSLATE_NOOP("InterfaceSettingsWidget", "Custom.qss [Drop in PCSX2 Folder]"),
nullptr};
static const char* THEME_VALUES[] = {
const char* InterfaceSettingsWidget::THEME_VALUES[] = {
"",
"fusion",
"darkfusion",
@@ -92,9 +92,13 @@ InterfaceSettingsWidget::InterfaceSettingsWidget(SettingsDialog* dialog, QWidget
connect(m_ui.renderToSeparateWindow, &QCheckBox::stateChanged, this, &InterfaceSettingsWidget::onRenderToSeparateWindowChanged);
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.theme, "UI", "Theme", THEME_NAMES, THEME_VALUES,
QtHost::GetDefaultThemeName());
QtHost::GetDefaultThemeName(), "InterfaceSettingsWidget");
connect(m_ui.theme, QOverload<int>::of(&QComboBox::currentIndexChanged), [this]() { emit themeChanged(); });
populateLanguages();
SettingWidgetBinder::BindWidgetToStringSetting(sif, m_ui.language, "UI", "Language", QtHost::GetDefaultLanguage());
connect(m_ui.language, QOverload<int>::of(&QComboBox::currentIndexChanged), [this]() { emit languageChanged(); });
// Per-game settings is special, we don't want to bind it if we're editing per-game settings.
m_ui.perGameSettings->setEnabled(!dialog->isPerGameSettings());
if (!dialog->isPerGameSettings())
@@ -181,9 +185,6 @@ InterfaceSettingsWidget::InterfaceSettingsWidget(SettingsDialog* dialog, QWidget
m_ui.disableWindowResizing, tr("Disable Window Resizing"), tr("Unchecked"),
tr("Prevents the main window from being resized."));
// Not yet used, disable the options
m_ui.language->setDisabled(true);
onRenderToSeparateWindowChanged();
}
@@ -193,3 +194,9 @@ void InterfaceSettingsWidget::onRenderToSeparateWindowChanged()
{
m_ui.hideMainWindow->setEnabled(m_ui.renderToSeparateWindow->isChecked());
}
void InterfaceSettingsWidget::populateLanguages()
{
for (const std::pair<QString, QString>& it : QtHost::GetAvailableLanguageList())
m_ui.language->addItem(it.first, it.second);
}
@@ -31,10 +31,17 @@ public:
Q_SIGNALS:
void themeChanged();
void languageChanged();
private Q_SLOTS:
void onRenderToSeparateWindowChanged();
private:
void populateLanguages();
Ui::InterfaceSettingsWidget m_ui;
public:
static const char* THEME_NAMES[];
static const char* THEME_VALUES[];
};
+23 -16
View File
@@ -30,6 +30,13 @@ MemoryCardConvertDialog::MemoryCardConvertDialog(QWidget* parent, QString select
: QDialog(parent)
{
m_ui.setupUi(this);
// For some reason, setting these in the .ui doesn't work..
m_ui.conversionTypeDescription->setFrameStyle(QFrame::Sunken);
m_ui.conversionTypeDescription->setFrameShape(QFrame::WinPanel);
m_ui.note->setFrameStyle(QFrame::Sunken);
m_ui.note->setFrameShape(QFrame::WinPanel);
m_selectedCard = selectedCard;
std::optional<AvailableMcdInfo> srcCardInfo = FileMcd_GetCardInfo(m_selectedCard.toStdString());
@@ -49,22 +56,22 @@ MemoryCardConvertDialog::MemoryCardConvertDialog(QWidget* parent, QString select
switch (m_srcCardInfo.type)
{
case MemoryCardType::File:
SetType(MemoryCardType::Folder, MemoryCardFileType::Unknown, "Uses a folder on your PC filesystem, instead of a file. Infinite capacity, while keeping the same compatibility as an 8 MB Memory Card.");
SetType(MemoryCardType::Folder, MemoryCardFileType::Unknown, tr("Uses a folder on your PC filesystem, instead of a file. Infinite capacity, while keeping the same compatibility as an 8 MB Memory Card."));
break;
case MemoryCardType::Folder:
switch (m_ui.conversionTypeSelect->currentData().toInt())
{
case 8:
SetType(MemoryCardType::File, MemoryCardFileType::PS2_8MB, "A standard, 8 MB Memory Card. Most compatible, but smallest capacity.");
SetType(MemoryCardType::File, MemoryCardFileType::PS2_8MB, tr("A standard, 8 MB Memory Card. Most compatible, but smallest capacity."));
break;
case 16:
SetType(MemoryCardType::File, MemoryCardFileType::PS2_16MB, "2x larger than a standard Memory Card. May have some compatibility issues.");
SetType(MemoryCardType::File, MemoryCardFileType::PS2_16MB, tr("2x larger than a standard Memory Card. May have some compatibility issues."));
break;
case 32:
SetType(MemoryCardType::File, MemoryCardFileType::PS2_32MB, "4x larger than a standard Memory Card. Likely to have compatibility issues.");
SetType(MemoryCardType::File, MemoryCardFileType::PS2_32MB, tr("4x larger than a standard Memory Card. Likely to have compatibility issues."));
break;
case 64:
SetType(MemoryCardType::File, MemoryCardFileType::PS2_64MB, "8x larger than a standard Memory Card. Likely to have compatibility issues.");
SetType(MemoryCardType::File, MemoryCardFileType::PS2_64MB, tr("8x larger than a standard Memory Card. Likely to have compatibility issues."));
break;
default:
//: MemoryCardType should be left as-is.
@@ -153,7 +160,7 @@ bool MemoryCardConvertDialog::SetupPicklist()
{
case MemoryCardType::File:
m_ui.conversionTypeSelect->addItems({"Folder"});
SetType(MemoryCardType::Folder, MemoryCardFileType::Unknown, "Uses a folder on your PC filesystem, instead of a file. Infinite capacity, while keeping the same compatibility as an 8 MB Memory Card.");
SetType(MemoryCardType::Folder, MemoryCardFileType::Unknown, tr("Uses a folder on your PC filesystem, instead of a file. Infinite capacity, while keeping the same compatibility as an 8 MB Memory Card."));
break;
case MemoryCardType::Folder:
// Compute which file types should be allowed.
@@ -183,7 +190,7 @@ bool MemoryCardConvertDialog::SetupPicklist()
if (sizeBytes < CardCapacity::_8_MB)
{
m_ui.conversionTypeSelect->addItem("8 MB File", 8);
m_ui.conversionTypeSelect->addItem(tr("8 MB File"), 8);
if (!typeSet)
{
@@ -194,7 +201,7 @@ bool MemoryCardConvertDialog::SetupPicklist()
if (sizeBytes < CardCapacity::_16_MB)
{
m_ui.conversionTypeSelect->addItem("16 MB File", 16);
m_ui.conversionTypeSelect->addItem(tr("16 MB File"), 16);
if (!typeSet)
{
@@ -205,7 +212,7 @@ bool MemoryCardConvertDialog::SetupPicklist()
if (sizeBytes < CardCapacity::_32_MB)
{
m_ui.conversionTypeSelect->addItem("32 MB File", 32);
m_ui.conversionTypeSelect->addItem(tr("32 MB File"), 32);
if (!typeSet)
{
@@ -216,7 +223,7 @@ bool MemoryCardConvertDialog::SetupPicklist()
if (sizeBytes < CardCapacity::_64_MB)
{
m_ui.conversionTypeSelect->addItem("64 MB File", 64);
m_ui.conversionTypeSelect->addItem(tr("64 MB File"), 64);
if (!typeSet)
{
@@ -284,30 +291,30 @@ void MemoryCardConvertDialog::SetType(MemoryCardType type, MemoryCardFileType fi
{
m_type = type;
m_fileType = fileType;
m_ui.conversionTypeDescription->setPlainText(description);
m_ui.conversionTypeDescription->setText(QStringLiteral("<center>%1</center>").arg(description));
}
void MemoryCardConvertDialog::SetType_8()
{
SetType(MemoryCardType::File, MemoryCardFileType::PS2_8MB, "A standard, 8 MB Memory Card. Most compatible, but smallest capacity.");
SetType(MemoryCardType::File, MemoryCardFileType::PS2_8MB, tr("A standard, 8 MB Memory Card. Most compatible, but smallest capacity."));
}
void MemoryCardConvertDialog::SetType_16()
{
SetType(MemoryCardType::File, MemoryCardFileType::PS2_16MB, "2x larger as a standard Memory Card. May have some compatibility issues.");
SetType(MemoryCardType::File, MemoryCardFileType::PS2_16MB, tr("2x larger as a standard Memory Card. May have some compatibility issues."));
}
void MemoryCardConvertDialog::SetType_32()
{
SetType(MemoryCardType::File, MemoryCardFileType::PS2_32MB, "4x larger than a standard Memory Card. Likely to have compatibility issues.");
SetType(MemoryCardType::File, MemoryCardFileType::PS2_32MB, tr("4x larger than a standard Memory Card. Likely to have compatibility issues."));
}
void MemoryCardConvertDialog::SetType_64()
{
SetType(MemoryCardType::File, MemoryCardFileType::PS2_64MB, "8x larger than a standard Memory Card. Likely to have compatibility issues.");
SetType(MemoryCardType::File, MemoryCardFileType::PS2_64MB, tr("8x larger than a standard Memory Card. Likely to have compatibility issues."));
}
void MemoryCardConvertDialog::SetType_Folder()
{
SetType(MemoryCardType::Folder, MemoryCardFileType::Unknown, "Uses a folder on your PC filesystem, instead of a file. Infinite capacity, while keeping the same compatibility as an 8 MB Memory Card.");
SetType(MemoryCardType::Folder, MemoryCardFileType::Unknown, tr("Uses a folder on your PC filesystem, instead of a file. Infinite capacity, while keeping the same compatibility as an 8 MB Memory Card."));
}
+105 -147
View File
@@ -10,27 +10,9 @@
<x>0</x>
<y>0</y>
<width>440</width>
<height>320</height>
<height>282</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>440</width>
<height>320</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>440</width>
<height>320</height>
</size>
</property>
<property name="windowTitle">
<string>Convert Memory Card</string>
</property>
@@ -40,141 +22,117 @@
<property name="modal">
<bool>false</bool>
</property>
<widget class="QGroupBox" name="conversionTypeGroup">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>421</width>
<height>61</height>
</rect>
</property>
<property name="title">
<string>Conversion Type</string>
</property>
<widget class="QComboBox" name="conversionTypeSelect">
<property name="geometry">
<rect>
<x>10</x>
<y>30</y>
<width>401</width>
<height>22</height>
</rect>
</property>
<item>
<property name="text">
<string>8 MB File</string>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="conversionTypeGroup">
<property name="title">
<string>Conversion Type</string>
</property>
</item>
<item>
<property name="text">
<string>16 MB File</string>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QComboBox" name="conversionTypeSelect">
<item>
<property name="text">
<string>8 MB File</string>
</property>
</item>
<item>
<property name="text">
<string>16 MB File</string>
</property>
</item>
<item>
<property name="text">
<string>32 MB File</string>
</property>
</item>
<item>
<property name="text">
<string>64 MB File</string>
</property>
</item>
<item>
<property name="text">
<string>Folder</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="conversionTypeDescription">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
</item>
<item>
<property name="text">
<string>32 MB File</string>
<string/>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="note">
<property name="minimumSize">
<size>
<width>0</width>
<height>35</height>
</size>
</property>
</item>
<item>
<property name="text">
<string>64 MB File</string>
<string>&lt;center&gt;&lt;strong&gt;Note:&lt;/strong&gt; Converting a Memory Card creates a &lt;strong&gt;COPY&lt;/strong&gt; of your existing Memory Card. It does &lt;strong&quot;&gt;NOT delete, modify, or replace&lt;/strong&gt; your existing Memory Card.&lt;/center&gt;</string>
</property>
</item>
<item>
<property name="text">
<string>Folder</string>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</item>
</widget>
</widget>
<widget class="QTextBrowser" name="note">
<property name="geometry">
<rect>
<x>10</x>
<y>150</y>
<width>421</width>
<height>61</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;meta charset=&quot;utf-8&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
hr { height: 1px; border-width: 0; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Segoe UI'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Note: Converting a Memory Card creates a COPY of your existing Memory Card. It does NOT delete, modify, or replace your existing Memory Card.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
<widget class="QTextBrowser" name="conversionTypeDescription">
<property name="geometry">
<rect>
<x>10</x>
<y>80</y>
<width>421</width>
<height>61</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;meta charset=&quot;utf-8&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
hr { height: 1px; border-width: 0; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Segoe UI'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p align=&quot;center&quot; style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>270</x>
<y>290</y>
<width>156</width>
<height>24</height>
</rect>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<widget class="QGroupBox" name="progressGroup">
<property name="geometry">
<rect>
<x>10</x>
<y>220</y>
<width>421</width>
<height>61</height>
</rect>
</property>
<property name="title">
<string>Progress</string>
</property>
<widget class="QProgressBar" name="progressBar">
<property name="geometry">
<rect>
<x>10</x>
<y>30</y>
<width>401</width>
<height>23</height>
</rect>
</property>
<property name="value">
<number>24</number>
</property>
</widget>
</widget>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="progressGroup">
<property name="title">
<string>Progress</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QProgressBar" name="progressBar">
<property name="value">
<number>24</number>
</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>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
-3
View File
@@ -10,9 +10,6 @@
<height>112</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
+506
View File
@@ -0,0 +1,506 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "PAD/Host/PAD.h"
#include "QtHost.h"
#include "QtUtils.h"
#include "SettingWidgetBinder.h"
#include "Settings/ControllerSettingWidgetBinder.h"
#include "Settings/InterfaceSettingsWidget.h"
#include "SetupWizardDialog.h"
#include <QtWidgets/QMessageBox>
SetupWizardDialog::SetupWizardDialog()
{
setupUi();
updatePageLabels(-1);
updatePageButtons();
}
SetupWizardDialog::~SetupWizardDialog()
{
if (m_bios_refresh_thread)
{
m_bios_refresh_thread->wait();
delete m_bios_refresh_thread;
}
}
void SetupWizardDialog::resizeEvent(QResizeEvent* event)
{
QDialog::resizeEvent(event);
resizeDirectoryListColumns();
}
bool SetupWizardDialog::canShowNextPage()
{
const int current_page = m_ui.pages->currentIndex();
switch (current_page)
{
case Page_BIOS:
{
if (!m_ui.biosList->currentItem())
{
if (QMessageBox::question(this, tr("Warning"),
tr("A BIOS image has not been selected. PCSX2 <strong>will not</strong> be able to run games "
"without a BIOS image.<br><br>Are you sure you wish to continue without selecting a BIOS "
"image?")) != QMessageBox::Yes)
{
return false;
}
}
}
break;
case Page_GameList:
{
if (m_ui.searchDirectoryList->rowCount() == 0)
{
if (QMessageBox::question(this, tr("Warning"),
tr("No game directories have been selected. You will have to manually open any game dumps you "
"want to play, PCSX2's list will be empty.\n\nAre you sure you want to continue?")) !=
QMessageBox::Yes)
{
return false;
}
}
}
break;
default:
break;
}
return true;
}
void SetupWizardDialog::previousPage()
{
const int current_page = m_ui.pages->currentIndex();
if (current_page == 0)
return;
m_ui.pages->setCurrentIndex(current_page - 1);
updatePageLabels(current_page);
updatePageButtons();
}
void SetupWizardDialog::nextPage()
{
const int current_page = m_ui.pages->currentIndex();
if (current_page == Page_Complete)
{
accept();
return;
}
if (!canShowNextPage())
return;
const int new_page = current_page + 1;
m_ui.pages->setCurrentIndex(new_page);
updatePageLabels(current_page);
updatePageButtons();
pageChangedTo(new_page);
}
void SetupWizardDialog::pageChangedTo(int page)
{
switch (page)
{
case Page_GameList:
resizeDirectoryListColumns();
break;
default:
break;
}
}
void SetupWizardDialog::updatePageLabels(int prev_page)
{
if (prev_page >= 0)
{
QFont prev_font = m_page_labels[prev_page]->font();
prev_font.setBold(false);
m_page_labels[prev_page]->setFont(prev_font);
}
const int page = m_ui.pages->currentIndex();
QFont font = m_page_labels[page]->font();
font.setBold(true);
m_page_labels[page]->setFont(font);
}
void SetupWizardDialog::updatePageButtons()
{
const int page = m_ui.pages->currentIndex();
m_ui.next->setText((page == Page_Complete) ? "&Finish" : "&Next");
m_ui.back->setEnabled(page > 0);
}
void SetupWizardDialog::confirmCancel()
{
if (QMessageBox::question(this, tr("Cancel Setup"),
tr("Are you sure you want to cancel PCSX2 setup?\n\nAny changes have been saved, and the wizard will run "
"again next time you start PCSX2.")) != QMessageBox::Yes)
{
return;
}
reject();
}
void SetupWizardDialog::setupUi()
{
m_ui.setupUi(this);
m_ui.logo->setPixmap(QPixmap(QStringLiteral("%1/icons/AppIconLarge.png").arg(QtHost::GetResourcesBasePath())));
m_ui.pages->setCurrentIndex(0);
m_page_labels[Page_Language] = m_ui.labelLanguage;
m_page_labels[Page_BIOS] = m_ui.labelBIOS;
m_page_labels[Page_GameList] = m_ui.labelGameList;
m_page_labels[Page_Controller] = m_ui.labelController;
m_page_labels[Page_Complete] = m_ui.labelComplete;
connect(m_ui.back, &QPushButton::clicked, this, &SetupWizardDialog::previousPage);
connect(m_ui.next, &QPushButton::clicked, this, &SetupWizardDialog::nextPage);
connect(m_ui.cancel, &QPushButton::clicked, this, &SetupWizardDialog::confirmCancel);
setupLanguagePage();
setupBIOSPage();
setupGameListPage();
setupControllerPage();
}
void SetupWizardDialog::setupLanguagePage()
{
SettingWidgetBinder::BindWidgetToEnumSetting(nullptr, m_ui.theme, "UI", "Theme",
InterfaceSettingsWidget::THEME_NAMES, InterfaceSettingsWidget::THEME_VALUES, QtHost::GetDefaultThemeName(), "InterfaceSettingsWidget");
connect(m_ui.theme, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &SetupWizardDialog::themeChanged);
for (const std::pair<QString, QString>& it : QtHost::GetAvailableLanguageList())
m_ui.language->addItem(it.first, it.second);
SettingWidgetBinder::BindWidgetToStringSetting(
nullptr, m_ui.language, "UI", "Language", QtHost::GetDefaultLanguage());
connect(
m_ui.language, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &SetupWizardDialog::languageChanged);
SettingWidgetBinder::BindWidgetToBoolSetting(
nullptr, m_ui.autoUpdateEnabled, "AutoUpdater", "CheckAtStartup", true);
}
void SetupWizardDialog::themeChanged()
{
// Main window gets recreated at the end here anyway, so it's fine to just yolo it.
QtHost::UpdateApplicationTheme();
}
void SetupWizardDialog::languageChanged()
{
// Skip the recreation, since we don't have many dynamic UI elements.
QtHost::InstallTranslator();
m_ui.retranslateUi(this);
}
void SetupWizardDialog::setupBIOSPage()
{
SettingWidgetBinder::BindWidgetToFolderSetting(nullptr, m_ui.biosSearchDirectory, m_ui.browseBiosSearchDirectory,
m_ui.openBiosSearchDirectory, m_ui.resetBiosSearchDirectory, "Folders", "Bios",
Path::Combine(EmuFolders::DataRoot, "bios"));
refreshBiosList();
connect(m_ui.biosSearchDirectory, &QLineEdit::textChanged, this, &SetupWizardDialog::refreshBiosList);
connect(m_ui.refreshBiosList, &QPushButton::clicked, this, &SetupWizardDialog::refreshBiosList);
connect(m_ui.biosList, &QTreeWidget::currentItemChanged, this, &SetupWizardDialog::biosListItemChanged);
}
void SetupWizardDialog::refreshBiosList()
{
if (m_bios_refresh_thread)
{
m_bios_refresh_thread->wait();
delete m_bios_refresh_thread;
}
QSignalBlocker blocker(m_ui.biosList);
m_ui.biosList->clear();
m_ui.biosList->setEnabled(false);
m_bios_refresh_thread = new BIOSSettingsWidget::RefreshThread(this, m_ui.biosSearchDirectory->text());
m_bios_refresh_thread->start();
}
void SetupWizardDialog::biosListItemChanged(const QTreeWidgetItem* current, const QTreeWidgetItem* previous)
{
Host::SetBaseStringSettingValue("Filenames", "BIOS", current->text(0).toUtf8().constData());
Host::CommitBaseSettingChanges();
g_emu_thread->applySettings();
}
void SetupWizardDialog::listRefreshed(const QVector<BIOSInfo>& items)
{
QSignalBlocker sb(m_ui.biosList);
BIOSSettingsWidget::populateList(m_ui.biosList, items);
m_ui.biosList->setEnabled(true);
}
void SetupWizardDialog::setupGameListPage()
{
m_ui.searchDirectoryList->setSelectionMode(QAbstractItemView::SingleSelection);
m_ui.searchDirectoryList->setSelectionBehavior(QAbstractItemView::SelectRows);
m_ui.searchDirectoryList->setAlternatingRowColors(true);
m_ui.searchDirectoryList->setShowGrid(false);
m_ui.searchDirectoryList->horizontalHeader()->setHighlightSections(false);
m_ui.searchDirectoryList->verticalHeader()->hide();
m_ui.searchDirectoryList->setCurrentIndex({});
m_ui.searchDirectoryList->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
connect(m_ui.searchDirectoryList, &QTableWidget::customContextMenuRequested, this,
&SetupWizardDialog::onDirectoryListContextMenuRequested);
connect(m_ui.addSearchDirectoryButton, &QPushButton::clicked, this,
&SetupWizardDialog::onAddSearchDirectoryButtonClicked);
connect(m_ui.removeSearchDirectoryButton, &QPushButton::clicked, this,
&SetupWizardDialog::onRemoveSearchDirectoryButtonClicked);
refreshDirectoryList();
}
void SetupWizardDialog::onDirectoryListContextMenuRequested(const QPoint& point)
{
QModelIndexList selection = m_ui.searchDirectoryList->selectionModel()->selectedIndexes();
if (selection.size() < 1)
return;
const int row = selection[0].row();
QMenu menu;
menu.addAction(tr("Remove"), [this]() { onRemoveSearchDirectoryButtonClicked(); });
menu.addSeparator();
menu.addAction(tr("Open Directory..."),
[this, row]() { QtUtils::OpenURL(this, QUrl::fromLocalFile(m_ui.searchDirectoryList->item(row, 0)->text())); });
menu.exec(m_ui.searchDirectoryList->mapToGlobal(point));
}
void SetupWizardDialog::onAddSearchDirectoryButtonClicked()
{
QString dir = QDir::toNativeSeparators(QFileDialog::getExistingDirectory(this, tr("Select Search Directory")));
if (dir.isEmpty())
return;
QMessageBox::StandardButton selection = QMessageBox::question(this, tr("Scan Recursively?"),
tr("Would you like to scan the directory \"%1\" recursively?\n\nScanning recursively takes "
"more time, but will identify files in subdirectories.")
.arg(dir),
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
if (selection == QMessageBox::Cancel)
return;
const bool recursive = (selection == QMessageBox::Yes);
const std::string spath = dir.toStdString();
Host::RemoveBaseValueFromStringList("GameList", recursive ? "Paths" : "RecursivePaths", spath.c_str());
Host::AddBaseValueToStringList("GameList", recursive ? "RecursivePaths" : "Paths", spath.c_str());
Host::CommitBaseSettingChanges();
refreshDirectoryList();
}
void SetupWizardDialog::onRemoveSearchDirectoryButtonClicked()
{
const int row = m_ui.searchDirectoryList->currentRow();
std::unique_ptr<QTableWidgetItem> item((row >= 0) ? m_ui.searchDirectoryList->takeItem(row, 0) : nullptr);
if (!item)
return;
const std::string spath = item->text().toStdString();
if (!Host::RemoveBaseValueFromStringList("GameList", "Paths", spath.c_str()) &&
!Host::RemoveBaseValueFromStringList("GameList", "RecursivePaths", spath.c_str()))
{
return;
}
Host::CommitBaseSettingChanges();
refreshDirectoryList();
}
void SetupWizardDialog::addPathToTable(const std::string& path, bool recursive)
{
const int row = m_ui.searchDirectoryList->rowCount();
m_ui.searchDirectoryList->insertRow(row);
QTableWidgetItem* item = new QTableWidgetItem();
item->setText(QString::fromStdString(path));
item->setFlags(item->flags() & ~(Qt::ItemIsEditable));
m_ui.searchDirectoryList->setItem(row, 0, item);
QCheckBox* cb = new QCheckBox(m_ui.searchDirectoryList);
m_ui.searchDirectoryList->setCellWidget(row, 1, cb);
cb->setChecked(recursive);
connect(cb, &QCheckBox::stateChanged, [item](int state) {
const std::string path(item->text().toStdString());
if (state == Qt::Checked)
{
Host::RemoveBaseValueFromStringList("GameList", "Paths", path.c_str());
Host::AddBaseValueToStringList("GameList", "RecursivePaths", path.c_str());
}
else
{
Host::RemoveBaseValueFromStringList("GameList", "RecursivePaths", path.c_str());
Host::AddBaseValueToStringList("GameList", "Paths", path.c_str());
}
Host::CommitBaseSettingChanges();
});
}
void SetupWizardDialog::refreshDirectoryList()
{
QSignalBlocker sb(m_ui.searchDirectoryList);
while (m_ui.searchDirectoryList->rowCount() > 0)
m_ui.searchDirectoryList->removeRow(0);
std::vector<std::string> path_list = Host::GetBaseStringListSetting("GameList", "Paths");
for (const std::string& entry : path_list)
addPathToTable(entry, false);
path_list = Host::GetBaseStringListSetting("GameList", "RecursivePaths");
for (const std::string& entry : path_list)
addPathToTable(entry, true);
m_ui.searchDirectoryList->sortByColumn(0, Qt::AscendingOrder);
}
void SetupWizardDialog::resizeDirectoryListColumns()
{
QtUtils::ResizeColumnsForTableView(m_ui.searchDirectoryList, {-1, 100});
}
void SetupWizardDialog::setupControllerPage()
{
static constexpr u32 NUM_PADS = 2;
struct PadWidgets
{
QComboBox* type_combo;
QLabel* mapping_result;
QToolButton* mapping_button;
};
const PadWidgets pad_widgets[NUM_PADS] = {
{m_ui.controller1Type, m_ui.controller1Mapping, m_ui.controller1AutomaticMapping},
{m_ui.controller2Type, m_ui.controller2Mapping, m_ui.controller2AutomaticMapping},
};
for (u32 port = 0; port < NUM_PADS; port++)
{
const std::string section = fmt::format("Pad{}", port + 1);
const PadWidgets& w = pad_widgets[port];
for (const auto& [name, display_name] : PAD::GetControllerTypeNames())
w.type_combo->addItem(qApp->translate("Pad", display_name), QString::fromStdString(name));
ControllerSettingWidgetBinder::BindWidgetToInputProfileString(
nullptr, w.type_combo, section, "Type", PAD::GetDefaultPadType(port));
w.mapping_result->setText((port == 0) ? tr("Default (Keyboard)") : tr("Default (None)"));
connect(w.mapping_button, &QAbstractButton::clicked, this,
[this, port, label = w.mapping_result]() { openAutomaticMappingMenu(port, label); });
}
// Trigger enumeration to populate the device list.
connect(g_emu_thread, &EmuThread::onInputDevicesEnumerated, this, &SetupWizardDialog::onInputDevicesEnumerated);
connect(g_emu_thread, &EmuThread::onInputDeviceConnected, this, &SetupWizardDialog::onInputDeviceConnected);
connect(g_emu_thread, &EmuThread::onInputDeviceDisconnected, this, &SetupWizardDialog::onInputDeviceDisconnected);
g_emu_thread->enumerateInputDevices();
}
void SetupWizardDialog::openAutomaticMappingMenu(u32 port, QLabel* update_label)
{
QMenu menu(this);
bool added = false;
for (const QPair<QString, QString>& dev : m_device_list)
{
// we set it as data, because the device list could get invalidated while the menu is up
QAction* action = menu.addAction(QStringLiteral("%1 (%2)").arg(dev.first).arg(dev.second));
action->setData(dev.first);
connect(action, &QAction::triggered, this, [this, port, update_label, action]() {
doDeviceAutomaticBinding(port, update_label, action->data().toString());
});
added = true;
}
if (!added)
{
QAction* action = menu.addAction(tr("No devices available"));
action->setEnabled(false);
}
menu.exec(QCursor::pos());
}
void SetupWizardDialog::doDeviceAutomaticBinding(u32 port, QLabel* update_label, const QString& device)
{
std::vector<std::pair<GenericInputBinding, std::string>> mapping =
InputManager::GetGenericBindingMapping(device.toStdString());
if (mapping.empty())
{
QMessageBox::critical(this, tr("Automatic Binding"),
tr("No generic bindings were generated for device '%1'. The controller/source may not support automatic "
"mapping.")
.arg(device));
return;
}
bool result;
{
auto lock = Host::GetSettingsLock();
result = PAD::MapController(*Host::Internal::GetBaseSettingsLayer(), port, mapping);
}
if (!result)
return;
Host::CommitBaseSettingChanges();
update_label->setText(device);
}
void SetupWizardDialog::onInputDevicesEnumerated(const QList<QPair<QString, QString>>& devices)
{
m_device_list = devices;
}
void SetupWizardDialog::onInputDeviceConnected(const QString& identifier, const QString& device_name)
{
m_device_list.emplace_back(identifier, device_name);
}
void SetupWizardDialog::onInputDeviceDisconnected(const QString& identifier)
{
for (auto iter = m_device_list.begin(); iter != m_device_list.end(); ++iter)
{
if (iter->first == identifier)
{
m_device_list.erase(iter);
break;
}
}
}
+96
View File
@@ -0,0 +1,96 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "Settings/BIOSSettingsWidget.h"
#include "ui_SetupWizardDialog.h"
#include <QtCore/QList>
#include <QtCore/QString>
#include <QtCore/QVector>
#include <QtWidgets/QDialog>
#include "common/Pcsx2Defs.h"
class SetupWizardDialog final : public QDialog
{
Q_OBJECT
public:
SetupWizardDialog();
~SetupWizardDialog();
private Q_SLOTS:
bool canShowNextPage();
void previousPage();
void nextPage();
void confirmCancel();
void themeChanged();
void languageChanged();
void refreshBiosList();
void biosListItemChanged(const QTreeWidgetItem* current, const QTreeWidgetItem* previous);
void listRefreshed(const QVector<BIOSInfo>& items);
void onDirectoryListContextMenuRequested(const QPoint& point);
void onAddSearchDirectoryButtonClicked();
void onRemoveSearchDirectoryButtonClicked();
void refreshDirectoryList();
void resizeDirectoryListColumns();
void onInputDevicesEnumerated(const QList<QPair<QString, QString>>& devices);
void onInputDeviceConnected(const QString& identifier, const QString& device_name);
void onInputDeviceDisconnected(const QString& identifier);
protected:
void resizeEvent(QResizeEvent* event);
private:
enum Page : u32
{
Page_Language,
Page_BIOS,
Page_GameList,
Page_Controller,
Page_Complete,
Page_Count,
};
void setupUi();
void setupLanguagePage();
void setupBIOSPage();
void setupGameListPage();
void setupControllerPage();
void pageChangedTo(int page);
void updatePageLabels(int prev_page);
void updatePageButtons();
void addPathToTable(const std::string& path, bool recursive);
void openAutomaticMappingMenu(u32 port, QLabel* update_label);
void doDeviceAutomaticBinding(u32 port, QLabel* update_label, const QString& device);
Ui::SetupWizardDialog m_ui;
std::array<QLabel*, Page_Count> m_page_labels;
BIOSSettingsWidget::RefreshThread* m_bios_refresh_thread = nullptr;
QList<QPair<QString, QString>> m_device_list;
};

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