Compare commits

...

24 Commits

Author SHA1 Message Date
TellowKrinkle
7d2d05ff59 GS: Send all frames to capture, including skipped ones
You wanted those frames recorded right?  Also if you skip them you'll desync audio and everything will be sad.
2025-06-18 20:08:16 -04:00
TheLastRar
f7c587c9a8 CI: Restore repository check in Flathub publish action 2025-06-18 09:07:54 -04:00
PCSX2 Bot
9162b30b18 [ci skip] Qt: Update Base Translation. 2025-06-18 07:09:06 +02:00
chaoticgd
14cfe37c8b Debugger: Fix crash when breakpoint is hit before createMenuBar call 2025-06-17 04:39:32 +02:00
PCSX2 Bot
a27a0ab49d [ci skip] PAD: Update to latest controller database. 2025-06-17 04:38:20 +02:00
Ty
0742fe07ec [ci skip] Testing flathub versioning, please ignore 2025-06-15 14:53:55 -04:00
Ty
65a92470d3 CI: Fix flathub versioning on tagless commits 2025-06-15 14:26:08 -04:00
PCSX2 Bot
10dc1a2da2 [ci skip] Qt: Update Base Translation. 2025-06-14 21:50:20 +02:00
JordanTheToaster
aad2128c32 GSRunner: Fix broken compilation 2025-06-14 21:50:08 +02:00
refractionpcsx2
2640678cac GS/HW: Adjust which function gets used for clearing depth on perfect match 2025-06-14 01:30:00 +02:00
KamFretoZ
8b90e2d53d BPM: Fix CTD when exiting BPM in No GUI mode 2025-06-14 01:28:49 +02:00
KamFretoZ
f87175dc7f Host: Move Batch/NoGUI mode check to Host
Moved from QtHost to Host for more accesibility
2025-06-14 01:28:49 +02:00
refractionpcsx2
b30444c0d0 GS/HW: Fix bug and improve inside target tracking on HW moves 2025-06-12 23:01:36 +01:00
refractionpcsx2
c1da0caf15 GS/HW: Fix possible null reference causing a crash 2025-06-12 18:26:15 +01:00
lightningterror
c4a8fc5b71 Qt: Fix Winconsistent-missing-override warning. 2025-06-11 23:17:53 +02:00
GovanifY
8eb46b5a4c IopBios: remove clang deprecated carveout
we use snprintf now, so this isn't useful anymore.
2025-06-10 20:59:25 +02:00
GovanifY
8be16d1039 IopBios: do not overflow snprintf tmp buffer
We could otherwise overflow as snprintf does not return the number of
written bytes but the number of written bytes assuming an infinite
buffer.
2025-06-10 20:59:25 +02:00
refractionpcsx2
76e6208d1b GS/TC: Fix region for tex in rt depth 2025-06-10 20:12:41 +02:00
refractionpcsx2
bc09080ba5 GS/TC: Remove old inside check from source lookup 2025-06-10 20:12:41 +02:00
refractionpcsx2
a6eb257a3a GS/HW: Allow RT in RT offset on Z buffer if FRAME is disabled 2025-06-10 20:11:32 +02:00
PCSX2 Bot
e62450d255 [ci skip] PAD: Update to latest controller database. 2025-06-10 20:10:22 +02:00
GovanifY
1aa922f700 IopBios: allow %u string formatting in IOP kprintf 2025-06-10 14:47:27 +02:00
GovanifY
4c9d2f99b1 IopBios: truncate printf output if bigger than our buffer
I also increased the buffer size while we are at it to avoid breakage,
despite the obvious unintended allowed situations that we allowed up
until now

Reported-By: Michael Lappas
2025-06-10 14:47:27 +02:00
Ty Lamontagne
f6e899b570 Debugger: Update search results when we are _not_ going to remove them 2025-06-08 15:44:56 -04:00
20 changed files with 1287 additions and 1068 deletions

View File

@@ -6,36 +6,45 @@ on:
workflow_dispatch: # As well as manually.
jobs:
check:
if: github.repository == 'PCSX2/pcsx2'
name: "Check if release is needed"
runs-on: ubuntu-latest
timeout-minutes: 180
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}'"
PCSX2_RELEASE=$(echo $PCSX2_RELEASE | sed 's/[^0-9]*//g')
FLATHUB_RELEASE=$(echo $FLATHUB_RELEASE | sed 's/[^0-9]*//g')
echo "PCSX2_RELEASE=${PCSX2_RELEASE}" >> "$GITHUB_OUTPUT"
echo "FLATHUB_RELEASE=${FLATHUB_RELEASE}" >> "$GITHUB_OUTPUT"
# check is disabled as the flathub api does not give us beta repository information
# Alternatively we can "flatpak remote-info or parse the appstream directly for the beta repo"
# Maybe in the future if we don't want to publish the same version twice if we get no commits
# for 24 hours.
# check:
# if: github.repository == 'PCSX2/pcsx2'
# name: "Check if release is needed"
# runs-on: ubuntu-latest
# timeout-minutes: 180
# 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}'"
# PCSX2_RELEASE=$(echo $PCSX2_RELEASE | sed 's/[^0-9]*//g')
# FLATHUB_RELEASE=$(echo $FLATHUB_RELEASE | sed 's/[^0-9]*//g')
# echo "PCSX2_RELEASE=${PCSX2_RELEASE}" >> "$GITHUB_OUTPUT"
# echo "FLATHUB_RELEASE=${FLATHUB_RELEASE}" >> "$GITHUB_OUTPUT"
build:
needs: check
# needs: check
# outputs are automatically compared as strings. This doesn't work in our favour
# Use fromJson() to convert them to proper integers...
# see: https://github.com/github/docs/pull/25870
# and: https://github.com/orgs/community/discussions/57480
#if: fromJson(needs.check.outputs.FLATHUB_RELEASE) < fromJson(needs.check.outputs.PCSX2_RELEASE)
# if: fromJson(needs.check.outputs.FLATHUB_RELEASE) < fromJson(needs.check.outputs.PCSX2_RELEASE)
# As the check step is disabled, perform repository check here
if: github.repository == 'PCSX2/pcsx2'
name: "Build and publish Flatpak"
uses: ./.github/workflows/linux_build_flatpak.yml
with:

View File

@@ -54,19 +54,16 @@ jobs:
uses: actions/checkout@v4
with:
set-safe-directory: ${{ env.GITHUB_WORKSPACE }}
# 10 here, since the odds of having 10 untagged commits in a row should be slim to none
# This is required for the tagging logic in generate-metainfo.sh
fetch-depth: 10
fetch-tags: true
# Work around container ownership issue
- name: Set Safe Directory
shell: bash
run: git config --global --add safe.directory "*"
# 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.
# actions/checkout elides tags, fetch them primarily for releases
- name: Fetch tags
if: ${{ inputs.fetchTags }}
run: git fetch --tags --no-recurse-submodules
- name: Add stable release identifier file
if: ${{ inputs.stableBuild == true || inputs.stableBuild == 'true' }}
shell: bash
@@ -125,7 +122,7 @@ jobs:
cache: true
restore-cache: true
cache-key: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.compiler }} flatpak ${{ hashFiles('.github/workflows/scripts/linux/flatpak/**/*.json') }}
#- name: Validate build
# run: |
# flatpak-builder-lint repo repo

View File

@@ -12,12 +12,24 @@ GIT_DATE=$(git log -1 --pretty=%cd --date=iso8601)
GIT_VERSION=$(git tag --points-at HEAD)
GIT_HASH=$(git rev-parse HEAD)
if [[ "${GIT_VERSION}" == "" ]]; then
# 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
if [[ -z "${GIT_VERSION}" ]]; then
if git branch -r --contains HEAD | grep -q 'origin/master'; then
# Our master doesn't have a tagged commit
# This happens when the commit is "ci skip"
# abbrev so we have just the latest tag
# ie v2.3.420 (Yes, that's the current master at the time of writing)
GIT_VERSION=$(git describe --tags --abbrev=0)
else
# We are probably building a PR
# Keep the short SHA in the version
# ie v2.3.420-1-g10dc1a2da
GIT_VERSION=$(git describe --tags)
fi
if [[ -z "${GIT_VERSION}" ]]; then
# Fallback to raw commit hash
GIT_VERSION=$(git rev-parse HEAD)
fi
fi
echo "GIT_DATE: ${GIT_DATE}"

View File

@@ -469,8 +469,10 @@
030000001008000001e5000000000000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Windows,
03000000050b00000045000000000000,Nexus,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Windows,
03000000152000000182000000000000,NGDS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows,
030000007e0500006920000000000000,Nintendo Switch 2 Pro Controller,a:b0,b:b1,back:b14,dpdown:b8,dpleft:b10,dpright:b9,dpup:b11,guide:b16,leftshoulder:b12,leftstick:b15,lefttrigger:b13,leftx:a0,lefty:a1~,misc1:b17,misc2:b20,paddle1:b18,paddle2:b19,rightshoulder:b4,rightstick:b7,righttrigger:b5,rightx:a2,righty:a3~,start:b6,x:b2,y:b3,platform:Windows,
030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
030000000d0500000308000000000000,Nostromo N45,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Windows,
030000007e0500007320000000000000,NSO GameCube Controller,a:b1,b:b3,dpdown:b8,dpleft:b10,dpright:b9,dpup:b11,guide:b16,leftshoulder:b13,lefttrigger:b12,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b4,rightx:a2,righty:a3~,start:b6,x:b0,y:b2,platform:Windows,
030000007e0500001920000000000000,NSO N64 Controller,+rightx:b8,+righty:b2,-rightx:b3,-righty:b7,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Windows,
030000007e0500001720000000000000,NSO SNES Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b15,start:b9,x:b2,y:b3,platform:Windows,
03000000550900001472000000000000,NVIDIA Controller,a:b11,b:b10,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b5,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b4,righttrigger:a5,rightx:a3,righty:a6,start:b3,x:b9,y:b8,platform:Windows,
@@ -1000,13 +1002,16 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000d62000007162000001000000,Moga Pro 2,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Mac OS X,
03000000c62400002a89000000010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,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,
03000000c62400002b89000000010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000853200008906000000010000,Nacon Revolution X Unlimited,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,
03000000632500007505000000020000,NeoGeo mini PAD Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b2,y:b3,platform:Mac OS X,
03000000921200004b46000003020000,NES 2-port Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b11,platform:Mac OS X,
030000001008000001e5000006010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Mac OS X,
030000007e0500006920000001010000,Nintendo Switch 2 Pro Controller,a:b0,b:b1,back:b14,dpdown:b8,dpleft:b10,dpright:b9,dpup:b11,guide:b16,leftshoulder:b12,leftstick:b15,lefttrigger:b13,leftx:a0,lefty:a1~,misc1:b17,misc2:b20,paddle1:b18,paddle2:b19,rightshoulder:b4,rightstick:b7,righttrigger:b5,rightx:a2,righty:a3~,start:b6,x:b2,y:b3,platform:Mac OS X,
030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
030000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
030000007e0500000920000010020000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:Mac OS X,
050000007e05000009200000ff070000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:Mac OS X,
030000007e0500007320000001010000,NSO GameCube Controller,a:b1,b:b3,dpdown:b8,dpleft:b10,dpright:b9,dpup:b11,guide:b16,leftshoulder:b13,lefttrigger:b12,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b4,rightx:a2,righty:a3~,start:b6,x:b0,y:b2,platform:Mac OS X,
030000007e0500001920000001000000,NSO N64 Controller,+rightx:b8,+righty:b7,-rightx:b3,-righty:b2,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Mac OS X,
030000007e0500001720000001000000,NSO SNES Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b15,start:b9,x:b2,y:b3,platform:Mac OS X,
03000000550900001472000025050000,NVIDIA Controller,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Mac OS X,
@@ -1481,6 +1486,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
060000007e0500003713000000000000,Nintendo 3DS,a:b0,b:b1,back:b8,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,
030000007e0500003703000000016800,Nintendo GameCube Controller,a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,platform:Linux,
03000000790000004618000010010000,Nintendo GameCube Controller Adapter,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5~,righty:a2~,start:b9,x:b2,y:b3,platform:Linux,
030000007e0500006920000011010000,Nintendo Switch 2 Pro Controller,a:b0,b:b1,back:b14,dpdown:b8,dpleft:b10,dpright:b9,dpup:b11,guide:b16,leftshoulder:b12,leftstick:b15,lefttrigger:b13,leftx:a0,lefty:a1~,misc1:b17,misc2:b20,paddle1:b18,paddle2:b19,rightshoulder:b4,rightstick:b7,righttrigger:b5,rightx:a2,righty:a3~,start:b6,x:b2,y:b3,platform:Linux,
060000004e696e74656e646f20537700,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
060000007e0500000620000000000000,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
060000007e0500000820000000000000,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
@@ -1495,6 +1501,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
050000007e0500003003000001000000,Nintendo Wii U Pro Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,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:b3,y:b2,platform:Linux,
050000005a1d00000218000003000000,Nokia GC 5000,a:b9,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,
030000000d0500000308000010010000,Nostromo n45 Dual Analog,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Linux,
030000007e0500007320000011010000,NSO GameCube Controller,a:b1,b:b3,dpdown:b8,dpleft:b10,dpright:b9,dpup:b11,guide:b16,leftshoulder:b13,lefttrigger:b12,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b4,rightx:a2,righty:a3~,start:b6,x:b0,y:b2,platform:Linux,
030000007e0500001920000011810000,NSO N64 Controller,+rightx:b2,+righty:b3,-rightx:b4,-righty:b10,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,misc1:b5,rightshoulder:b7,righttrigger:b9,start:b11,platform:Linux,
050000007e0500001920000001000000,NSO N64 Controller,+rightx:b8,+righty:b7,-rightx:b3,-righty:b2,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Linux,
050000007e0500001920000001800000,NSO N64 Controller,+rightx:b2,+righty:b3,-rightx:b4,-righty:b10,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,misc1:b5,rightshoulder:b7,righttrigger:b9,start:b11,platform:Linux,
@@ -1607,6 +1614,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000009b2800003200000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
030000009b2800006000000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
030000009b2800006100000001010000,Raphnet N64 Adapter,+rightx:b9,+righty:b7,-rightx:b8,-righty:b6,a:b0,b:b1,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Linux,
030000009b2800006400000001010000,Raphnet N64 Adapter,+rightx:b9,+righty:b7,-rightx:b8,-righty:b6,a:b0,b:b1,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Linux,
030000009b2800008000000020020000,Raphnet Wii Classic Adapter,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Linux,
030000009b2800008000000001010000,Raphnet Wii Classic Adapter V3,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Linux,
03000000f8270000bf0b000011010000,Razer Kishi,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,

View File

@@ -419,6 +419,16 @@ void Host::OnCreateMemoryCardOpenRequested()
// noop
}
bool Host::InBatchMode()
{
return false;
}
bool Host::InNoGUIMode()
{
return false;
}
bool Host::ShouldPreferHostFileSelector()
{
return false;

View File

@@ -142,12 +142,12 @@ void DockManager::switchToLayout(DockLayout::Index layout_index, bool blink_tab)
layout.thaw();
int tab_index = static_cast<int>(layout_index);
if (m_menu_bar && tab_index >= 0)
if (tab_index >= 0 && m_menu_bar)
m_menu_bar->onCurrentLayoutChanged(layout_index);
}
}
if (blink_tab)
if (blink_tab && m_menu_bar)
m_menu_bar->startBlink(m_current_layout);
}
@@ -512,7 +512,8 @@ void DockManager::newLayoutClicked()
{
// The plus button has just been made the current tab, so set it back to the
// one corresponding to the current layout again.
m_menu_bar->onCurrentLayoutChanged(m_current_layout);
if (m_menu_bar)
m_menu_bar->onCurrentLayoutChanged(m_current_layout);
auto name_validator = [this](const QString& name) {
return !hasNameConflict(name, DockLayout::INVALID_INDEX);

View File

@@ -311,7 +311,7 @@ void searchWorker(DebugInterface* cpu, std::vector<SearchResult>& searchResults,
const auto readValue = readValueAtAddress<T>(cpu, addr);
const bool doesMatch = handleSearchComparison(searchComparison, addr, &searchResult, searchValue, readValue);
if (!doesMatch)
if (doesMatch)
searchResult = MemorySearchView::SearchResult(addr, QVariant::fromValue(readValue), searchType);
return !doesMatch;

View File

@@ -92,7 +92,7 @@ public Q_SLOTS:
void refreshGridCovers();
protected:
void resizeEvent(QResizeEvent* event);
void resizeEvent(QResizeEvent* event) override;
bool event(QEvent* event) override;
private:

View File

@@ -43,7 +43,7 @@ void LogWindow::updateSettings()
{
std::unique_lock lock(s_log_mutex);
const bool new_enabled = Host::GetBaseBoolSettingValue("Logging", "EnableLogWindow", false) && !QtHost::InNoGUIMode();
const bool new_enabled = Host::GetBaseBoolSettingValue("Logging", "EnableLogWindow", false) && !Host::InNoGUIMode();
const bool attach_to_main = Host::GetBaseBoolSettingValue("Logging", "AttachLogWindowToMainWindow", true);
const bool curr_enabled = Log::IsHostOutputEnabled();

View File

@@ -1130,7 +1130,7 @@ bool MainWindow::shouldHideMainWindow() const
// NOTE: We can't use isRenderingToMain() here, because this happens post-fullscreen-switch.
return (Host::GetBoolSettingValue("UI", "HideMainWindowWhenRunning", false) && !g_emu_thread->shouldRenderToMain()) ||
(g_emu_thread->shouldRenderToMain() && (isRenderingFullscreen() || m_is_temporarily_windowed)) ||
QtHost::InNoGUIMode();
Host::InNoGUIMode();
}
bool MainWindow::shouldMouseLock() const
@@ -1306,7 +1306,7 @@ bool MainWindow::requestShutdown(bool allow_confirm, bool allow_save_to_state, b
// reshow the main window during display updates, because otherwise fullscreen transitions and renderer switches
// would briefly show and then hide the main window. So instead, we do it on shutdown, here. Except if we're in
// batch mode, when we're going to exit anyway.
if (!isRenderingToMain() && isHidden() && !QtHost::InBatchMode() && !g_emu_thread->isRunningFullscreenUI())
if (!isRenderingToMain() && isHidden() && !Host::InBatchMode() && !g_emu_thread->isRunningFullscreenUI())
updateWindowState(true);
// Clear the VM valid state early. That way we can't do anything in the UI if we take a while to shut down.
@@ -2060,7 +2060,7 @@ void MainWindow::onVMStopped()
updateInputRecordingActions(false);
// If we're closing or in batch mode, quit the whole application now.
if (m_is_closing || QtHost::InBatchMode())
if (m_is_closing || Host::InBatchMode())
{
quit();
return;

View File

@@ -602,7 +602,7 @@ void Host::CheckForSettingsChanges(const Pcsx2Config& old_config)
bool EmuThread::shouldRenderToMain() const
{
return !Host::GetBoolSettingValue("UI", "RenderToSeparateWindow", false) && !QtHost::InNoGUIMode();
return !Host::GetBoolSettingValue("UI", "RenderToSeparateWindow", false) && !Host::InNoGUIMode();
}
void EmuThread::toggleSoftwareRendering()
@@ -1268,7 +1268,7 @@ void Host::RequestVMShutdown(bool allow_confirm, bool allow_save_state, bool def
// This will probably call shutdownVM() again, but by the time it runs, we'll have already shut down
// and it'll be a noop.
if (QtHost::InBatchMode())
if (Host::InBatchMode())
QMetaObject::invokeMethod(g_main_window, "requestExit", Qt::QueuedConnection, Q_ARG(bool, false));
}
}
@@ -1437,12 +1437,12 @@ void Host::CommitBaseSettingChanges()
}
}
bool QtHost::InBatchMode()
bool Host::InBatchMode()
{
return s_batch_mode;
}
bool QtHost::InNoGUIMode()
bool Host::InNoGUIMode()
{
return s_nogui_mode;
}

View File

@@ -245,12 +245,6 @@ namespace QtHost
/// Sets the icon theme, based on the current style (light/dark).
void SetIconThemeFromStyle();
/// Sets batch mode (exit after game shutdown).
bool InBatchMode();
/// Sets NoGUI mode (implys batch mode, does not display main window, exits on shutdown).
bool InNoGUIMode();
/// Returns true if the calling thread is the UI thread.
bool IsOnUIThread();

File diff suppressed because it is too large Load Diff

View File

@@ -617,72 +617,71 @@ void GSRenderer::VSync(u32 field, bool registers_written, bool idle_frame)
EndPresentFrame();
PerformanceMetrics::Update(registers_written, fb_sprite_frame, skip_frame);
return;
}
if (!idle_frame)
g_gs_device->AgePool();
g_perfmon.EndFrame(idle_frame);
if ((g_perfmon.GetFrame() & 0x1f) == 0)
g_perfmon.Update();
// Little bit ugly, but we can't do CAS inside the render pass.
GSVector4i src_rect;
GSVector4 src_uv, draw_rect;
GSTexture* current = g_gs_device->GetCurrent();
if (current && !blank_frame)
else
{
src_rect = CalculateDrawSrcRect(current, m_real_size);
src_uv = GSVector4(src_rect) / GSVector4(current->GetSize()).xyxy();
draw_rect = CalculateDrawDstRect(g_gs_device->GetWindowWidth(), g_gs_device->GetWindowHeight(),
src_rect, current->GetSize(), s_display_alignment, g_gs_device->UsesLowerLeftOrigin(),
GetVideoMode() == GSVideoMode::SDTV_480P);
s_last_draw_rect = draw_rect;
if (!idle_frame)
g_gs_device->AgePool();
if (GSConfig.CASMode != GSCASMode::Disabled)
{
static bool cas_log_once = false;
if (g_gs_device->Features().cas_sharpening)
{
// sharpen only if the IR is higher than the display resolution
const bool sharpen_only = (GSConfig.CASMode == GSCASMode::SharpenOnly ||
(current->GetWidth() > g_gs_device->GetWindowWidth() &&
current->GetHeight() > g_gs_device->GetWindowHeight()));
g_gs_device->CAS(current, src_rect, src_uv, draw_rect, sharpen_only);
}
else if (!cas_log_once)
{
Host::AddIconOSDMessage("CASUnsupported", ICON_FA_EXCLAMATION_TRIANGLE,
TRANSLATE_SV("GS",
"CAS is not available, your graphics driver does not support the required functionality."),
10.0f);
cas_log_once = true;
}
}
}
g_perfmon.EndFrame(idle_frame);
if (BeginPresentFrame(false))
{
if ((g_perfmon.GetFrame() & 0x1f) == 0)
g_perfmon.Update();
// Little bit ugly, but we can't do CAS inside the render pass.
GSVector4i src_rect;
GSVector4 src_uv, draw_rect;
GSTexture* current = g_gs_device->GetCurrent();
if (current && !blank_frame)
{
const u64 current_time = Common::Timer::GetCurrentValue();
const float shader_time = static_cast<float>(Common::Timer::ConvertValueToSeconds(current_time - m_shader_time_start));
src_rect = CalculateDrawSrcRect(current, m_real_size);
src_uv = GSVector4(src_rect) / GSVector4(current->GetSize()).xyxy();
draw_rect = CalculateDrawDstRect(g_gs_device->GetWindowWidth(), g_gs_device->GetWindowHeight(),
src_rect, current->GetSize(), s_display_alignment, g_gs_device->UsesLowerLeftOrigin(),
GetVideoMode() == GSVideoMode::SDTV_480P);
s_last_draw_rect = draw_rect;
g_gs_device->PresentRect(current, src_uv, nullptr, draw_rect,
s_tv_shader_indices[GSConfig.TVShader], shader_time, GSConfig.LinearPresent != GSPostBilinearMode::Off);
if (GSConfig.CASMode != GSCASMode::Disabled)
{
static bool cas_log_once = false;
if (g_gs_device->Features().cas_sharpening)
{
// sharpen only if the IR is higher than the display resolution
const bool sharpen_only = (GSConfig.CASMode == GSCASMode::SharpenOnly ||
(current->GetWidth() > g_gs_device->GetWindowWidth() &&
current->GetHeight() > g_gs_device->GetWindowHeight()));
g_gs_device->CAS(current, src_rect, src_uv, draw_rect, sharpen_only);
}
else if (!cas_log_once)
{
Host::AddIconOSDMessage("CASUnsupported", ICON_FA_EXCLAMATION_TRIANGLE,
TRANSLATE_SV("GS", "CAS is not available, your graphics driver does not support the required functionality."),
10.0f);
cas_log_once = true;
}
}
}
EndPresentFrame();
if (BeginPresentFrame(false))
{
if (current && !blank_frame)
{
const u64 current_time = Common::Timer::GetCurrentValue();
const float shader_time = static_cast<float>(Common::Timer::ConvertValueToSeconds(current_time - m_shader_time_start));
if (GSConfig.OsdShowGPU)
PerformanceMetrics::OnGPUPresent(g_gs_device->GetAndResetAccumulatedGPUTime());
g_gs_device->PresentRect(current, src_uv, nullptr, draw_rect,
s_tv_shader_indices[GSConfig.TVShader], shader_time, GSConfig.LinearPresent != GSPostBilinearMode::Off);
}
EndPresentFrame();
if (GSConfig.OsdShowGPU)
PerformanceMetrics::OnGPUPresent(g_gs_device->GetAndResetAccumulatedGPUTime());
}
PerformanceMetrics::Update(registers_written, fb_sprite_frame, false);
}
PerformanceMetrics::Update(registers_written, fb_sprite_frame, false);
// snapshot
if (!m_snapshot.empty())
{

View File

@@ -3166,6 +3166,144 @@ void GSRendererHW::Draw()
}
}
}
if (no_rt && ds && ds->m_TEX0.TBP0 != m_cached_ctx.ZBUF.Block())
{
const GSLocalMemory::psm_t& zbuf_psm = GSLocalMemory::m_psm[m_cached_ctx.ZBUF.PSM];
int vertical_offset = ((static_cast<int>(m_cached_ctx.ZBUF.Block() - ds->m_TEX0.TBP0) / 32) / std::max(static_cast<int>(ds->m_TEX0.TBW), 1)) * zbuf_psm.pgs.y; // I know I could just not shift it..
int texture_offset = 0;
int horizontal_offset = ((static_cast<int>((m_cached_ctx.ZBUF.Block() - ds->m_TEX0.TBP0)) / 32) % static_cast<int>(std::max(ds->m_TEX0.TBW, 1U))) * zbuf_psm.pgs.x;
// Used to reduce the offset made later in channel shuffles
m_target_offset = std::abs(static_cast<int>((m_cached_ctx.ZBUF.Block() - ds->m_TEX0.TBP0)) >> 5);
if (vertical_offset < 0)
{
ds->m_TEX0.TBP0 = m_cached_ctx.ZBUF.Block();
GSVector2i new_size = ds->m_unscaled_size;
// Make sure to use the original format for the offset.
const int new_offset = std::abs((vertical_offset / zbuf_psm.pgs.y) * GSLocalMemory::m_psm[ds->m_TEX0.PSM].pgs.y);
texture_offset = new_offset;
new_size.y += new_offset;
const GSVector4i new_drect = GSVector4i(0, new_offset * ds->m_scale, new_size.x * ds->m_scale, new_size.y * ds->m_scale);
ds->ResizeTexture(new_size.x, new_size.y, true, true, new_drect);
if (src && src->m_from_target && src->m_from_target == ds && src->m_target_direct)
{
src->m_texture = ds->m_texture;
// If we've moved it and the source is expecting to be inside this target, we need to update the region to point to it.
int max_region_y = src->m_region.GetMaxY() + new_offset;
if (max_region_y == new_offset)
max_region_y = new_size.y;
src->m_region.SetY(src->m_region.GetMinY() + new_offset, max_region_y);
}
ds->m_valid.y += new_offset;
ds->m_valid.w += new_offset;
ds->m_drawn_since_read.y += new_offset;
ds->m_drawn_since_read.w += new_offset;
g_texture_cache->CombineAlignedInsideTargets(ds, src);
if (ds->m_dirty.size())
{
for (int i = 0; i < static_cast<int>(ds->m_dirty.size()); i++)
{
ds->m_dirty[i].r.y += new_offset;
ds->m_dirty[i].r.w += new_offset;
}
}
t_size.y += std::abs(vertical_offset);
vertical_offset = 0;
}
if (horizontal_offset < 0)
{
// Thankfully this doesn't really happen, but catwoman moves the framebuffer backwards 1 page with a channel shuffle, which is really messy and not easy to deal with.
// Hopefully the quick channel shuffle will just guess this and run with it.
ds->m_TEX0.TBP0 += horizontal_offset;
horizontal_offset = 0;
}
if (vertical_offset || horizontal_offset)
{
GSVertex* v = &m_vertex.buff[0];
for (u32 i = 0; i < m_vertex.tail; i++)
{
v[i].XYZ.X += horizontal_offset << 4;
v[i].XYZ.Y += vertical_offset << 4;
}
if (texture_offset && src && src->m_from_target && src->m_target_direct && src->m_from_target == ds)
{
GSVector4i src_region = src->GetRegionRect();
if (src_region.rempty())
{
src_region = GSVector4i::loadh(ds->m_unscaled_size);
src_region.y += texture_offset;
}
else
{
src_region.y += texture_offset;
src_region.w += texture_offset;
}
src->m_region.SetX(src_region.x, src_region.z);
src->m_region.SetY(src_region.y, src_region.w);
}
m_context->scissor.in.x += horizontal_offset;
m_context->scissor.in.z += horizontal_offset;
m_context->scissor.in.y += vertical_offset;
m_context->scissor.in.w += vertical_offset;
m_r.y += vertical_offset;
m_r.w += vertical_offset;
m_r.x += horizontal_offset;
m_r.z += horizontal_offset;
m_in_target_draw = ds->m_TEX0.TBP0 != m_cached_ctx.ZBUF.Block();
m_vt.m_min.p.x += horizontal_offset;
m_vt.m_max.p.x += horizontal_offset;
m_vt.m_min.p.y += vertical_offset;
m_vt.m_max.p.y += vertical_offset;
t_size.y = ds->m_unscaled_size.y - vertical_offset;
t_size.x = ds->m_unscaled_size.x - horizontal_offset;
}
// Don't resize if the BPP don't match.
GSVector2i new_size = GetValidSize(src, possible_shuffle);
if (new_size.x > ds->m_unscaled_size.x || new_size.y > ds->m_unscaled_size.y)
{
const u32 new_width = std::max(new_size.x, ds->m_unscaled_size.x);
const u32 new_height = std::max(new_size.y, ds->m_unscaled_size.y);
//DevCon.Warning("HW: Resizing texture %d x %d draw %d", ds->m_unscaled_size.x, new_height, s_n);
ds->ResizeTexture(new_width, new_height);
}
else if ((IsPageCopy() || is_possible_mem_clear) && m_r.width() <= zbuf_psm.pgs.x && m_r.height() <= zbuf_psm.pgs.y)
{
const int get_next_ctx = m_env.PRIM.CTXT;
const GSDrawingContext& next_ctx = m_env.CTXT[get_next_ctx];
GSVector4i update_valid = GSVector4i::loadh(GSVector2i(horizontal_offset + GSLocalMemory::m_psm[m_cached_ctx.ZBUF.PSM].pgs.x, GSLocalMemory::m_psm[m_cached_ctx.ZBUF.PSM].pgs.y + vertical_offset));
ds->UpdateValidity(update_valid, true);
if (is_possible_mem_clear)
{
if ((horizontal_offset + GSLocalMemory::m_psm[m_cached_ctx.ZBUF.PSM].pgs.x) >= static_cast<int>(ds->m_TEX0.TBW * 64) && next_ctx.ZBUF.Block() == (m_cached_ctx.ZBUF.Block() + 0x20))
{
update_valid.x = 0;
update_valid.z = GSLocalMemory::m_psm[m_cached_ctx.ZBUF.PSM].pgs.x;
update_valid.y += GSLocalMemory::m_psm[m_cached_ctx.ZBUF.PSM].pgs.y;
update_valid.w += GSLocalMemory::m_psm[m_cached_ctx.ZBUF.PSM].pgs.y;
ds->UpdateValidity(update_valid, true);
}
}
}
}
}
if (!no_rt)

View File

@@ -629,6 +629,8 @@ void GSTextureCache::DirtyRectByPage(u32 sbp, u32 spsm, u32 sbw, Target* t, GSVe
{
RGBAMask rgba;
rgba._u32 = GSUtil::GetChannelMask(spsm);
// FIXME: This could be a problem if used when the valid area is smaller than dirty area and it needs the data during expansion on a later draw.
// This happens on Kamen Rider - Seigi no Keifu if the invalidatevideomem function was to use this function for depth clearing.
AddDirtyRectTarget(t, t->m_valid, t->m_TEX0.PSM, t->m_TEX0.TBW, rgba);
return;
}
@@ -1192,8 +1194,8 @@ GSTextureCache::Source* GSTextureCache::LookupDepthSource(const bool is_depth, c
if (inside_target)
{
// Need to set it up as a region target.
src->m_region.SetX(block_boundary_rect.x, src->m_from_target->m_valid.z);
src->m_region.SetY(block_boundary_rect.y, src->m_from_target->m_valid.w);
src->m_region.SetX(block_boundary_rect.x, std::max(src->m_from_target->m_valid.z, block_boundary_rect.z));
src->m_region.SetY(block_boundary_rect.y, std::max(src->m_from_target->m_valid.w, block_boundary_rect.w));
}
if (GSRendererHW::GetInstance()->IsTBPFrameOrZ(dst->m_TEX0.TBP0))
@@ -1800,10 +1802,6 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
if (!t->HasValidBitsForFormat(psm, req_color, req_alpha, rt_tbw == TEX0.TBW) && !(possible_shuffle && GSLocalMemory::m_psm[psm].bpp == 16 && GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp == 32))
continue;
// Be careful of shuffles where it can shuffle the width of the target, even though it may not have all been drawn to.
if (!possible_shuffle && frame.Block() != TEX0.TBP0 && !t->Inside(bp, bw, psm, block_boundary_rect))
continue;
x_offset = rect.x;
y_offset = rect.y;
dst = t;
@@ -4367,7 +4365,9 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
InvalidateTemporaryZ();
}
if (GSLocalMemory::m_psm[psm].depth)
// If we're dealing with quadrant draws, we need to position them correctly (Final Fantasy X).
if (GSLocalMemory::m_psm[psm].depth &&
r.width() <= (GSLocalMemory::m_psm[psm].pgs.x >> 1) && r.height() <= (GSLocalMemory::m_psm[psm].pgs.y >> 1))
DirtyRectByPage(bp, psm, bw, t, r);
else
AddDirtyRectTarget(t, r, psm, bw, rgba);
@@ -4778,6 +4778,11 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u
}
bool req_resize = false;
// Save for later in case of page copy.
const u32 start_SBP = SBP;
const u32 start_DBP = DBP;
if (m_expected_src_bp == static_cast<int>(SBP) && m_expected_dst_bp == static_cast<int>(DBP))
{
// Get the new position so we can work out the offset.
@@ -4793,12 +4798,13 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u
SBP = m_remembered_src_bp;
DBP = m_remembered_dst_bp;
m_expected_src_bp = -1;
m_remembered_src_bp = -1;
m_expected_dst_bp = -1;
m_remembered_dst_bp = -1;
}
m_expected_src_bp = -1;
m_remembered_src_bp = -1;
m_expected_dst_bp = -1;
m_remembered_dst_bp = -1;
// Look for an exact match on the targets.
GSTextureCache::Target* src = GetExactTarget(SBP, SBW, spsm_s.depth ? DepthStencil : RenderTarget, SBP);
GSTextureCache::Target* dst = GetExactTarget(DBP, DBW, dpsm_s.depth ? DepthStencil : RenderTarget, DBP);
@@ -4862,7 +4868,7 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u
// If we have an offset, adjust the base positions
if (src->m_TEX0.TBP0 != SBP)
{
GSVector4i offset = TranslateAlignedRectByPage(dst, SBP, SPSM, SBW, GSVector4i(0, 1).xxyy(), false);
const GSVector4i offset = TranslateAlignedRectByPage(src, SBP, SPSM, SBW, GSVector4i(0, 1).xxyy(), false);
sx += offset.x;
sy += offset.y;
@@ -4870,7 +4876,7 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u
if (dst->m_TEX0.TBP0 != DBP)
{
GSVector4i offset = TranslateAlignedRectByPage(dst, DBP, DPSM, DBW, GSVector4i(0, 1).xxyy(), false);
const GSVector4i offset = TranslateAlignedRectByPage(dst, DBP, DPSM, DBW, GSVector4i(0, 1).xxyy(), false);
dx += offset.x;
dy += offset.y;
@@ -5048,18 +5054,26 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u
u32 page_mask = GSLocalMemory::IsPageAlignedMasked(src->m_TEX0.PSM, GSVector4i(sx, sy, sx + w, sy + h));
if (((page_mask & 0x0f0f) == 0x0f0f || (page_mask & 0xf0f0) == 0xf0f0) && (w == GSLocalMemory::m_psm[src->m_TEX0.PSM].pgs.x || h == GSLocalMemory::m_psm[src->m_TEX0.PSM].pgs.y))
{
// Vertical Strips
if (w == GSLocalMemory::m_psm[src->m_TEX0.PSM].pgs.x)
// Page copy
if (w == GSLocalMemory::m_psm[src->m_TEX0.PSM].pgs.x && h == GSLocalMemory::m_psm[src->m_TEX0.PSM].pgs.y)
{
m_expected_src_bp = start_SBP + BLOCKS_PER_PAGE;
m_expected_dst_bp = start_DBP + BLOCKS_PER_PAGE;
}
// Vertical Strips.
else if (w == GSLocalMemory::m_psm[src->m_TEX0.PSM].pgs.x)
{
m_expected_src_bp = GSLocalMemory::GetStartBlockAddress(src->m_TEX0.TBP0, src->m_TEX0.TBW, src->m_TEX0.PSM, GSVector4i(sx + w, 0, sx + w + w, h));
m_expected_dst_bp = GSLocalMemory::GetStartBlockAddress(dst->m_TEX0.TBP0, dst->m_TEX0.TBW, dst->m_TEX0.PSM, GSVector4i(dx + w, 0, dx + w + w, h));
}
// Horizontal Strips.
else
{
m_expected_src_bp = GSLocalMemory::GetStartBlockAddress(src->m_TEX0.TBP0, src->m_TEX0.TBW, src->m_TEX0.PSM, GSVector4i(0, sy + h, w, sy + h + h));
m_expected_dst_bp = GSLocalMemory::GetStartBlockAddress(dst->m_TEX0.TBP0, dst->m_TEX0.TBW, dst->m_TEX0.PSM, GSVector4i(0, dy + h, w, dy + h + h));
}
// Only check the source, the destination might need expanding.
if (static_cast<u32>(m_expected_src_bp) < src->UnwrappedEndBlock() && static_cast<u32>(m_expected_src_bp) >= src->m_TEX0.TBP0)
{
m_remembered_src_bp = src->m_TEX0.TBP0;

View File

@@ -67,6 +67,12 @@ namespace Host
bool ConfirmMessage(const std::string_view title, const std::string_view message);
bool ConfirmFormattedMessage(const std::string_view title, const char* format, ...);
/// Sets batch mode (exit after game shutdown).
bool InBatchMode();
/// Sets NoGUI mode (implys batch mode, does not display main window, exits on shutdown).
bool InNoGUIMode();
/// Opens a URL, using the default application.
void OpenURL(const std::string_view url);

View File

@@ -1602,7 +1602,7 @@ void FullscreenUI::DrawExitWindow()
ImGui::PushStyleColor(ImGuiCol_Text, UIBackgroundTextColor);
if (BeginHorizontalMenu("exit_window", menu_pos, menu_size, 3))
if (BeginHorizontalMenu("exit_window", menu_pos, menu_size, (Host::InNoGUIMode()) ? 2 : 3))
{
ResetFocusHere();
@@ -1621,10 +1621,13 @@ void FullscreenUI::DrawExitWindow()
DoRequestExit();
}
if (HorizontalMenuItem(GetCachedTexture("fullscreenui/desktop-mode.png"), FSUI_CSTR("Desktop Mode"),
FSUI_CSTR("Exits Big Picture mode, returning to the desktop interface.")))
if (!Host::InNoGUIMode())
{
DoDesktopMode();
if (HorizontalMenuItem(GetCachedTexture("fullscreenui/desktop-mode.png"), FSUI_CSTR("Desktop Mode"),
FSUI_CSTR("Exits Big Picture mode, returning to the desktop interface.")))
{
DoDesktopMode();
}
}
}
EndHorizontalMenu();

View File

@@ -21,6 +21,7 @@
#include <cstring>
#include <fmt/format.h>
#include <sys/stat.h>
#include <algorithm>
#include <fcntl.h>
@@ -641,7 +642,7 @@ namespace R3000A
for (size_t i = 0; i < handles.size(); i++)
{
if (handles[i].fd_index == (u32) fd - firstfd)
if (handles[i].fd_index == (u32)fd - firstfd)
{
handles.erase(handles.begin() + i);
break;
@@ -928,12 +929,6 @@ namespace R3000A
{
int Kprintf_HLE()
{
// Using sprintf here is a bit nasty, but it has a large buffer..
// Don't feel like rewriting it.
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif
// Emulate the expected Kprintf functionality:
iopMemWrite32(sp, a0);
@@ -951,8 +946,12 @@ namespace R3000A
if (!ConsoleLogging.iopConsole.IsActive())
return 1;
char tmp[1024], tmp2[1024];
// maximum allowed size for our buffer before we truncate
const unsigned int max_len = 4096;
char tmp[max_len], tmp2[max_len];
char* ptmp = tmp;
unsigned int printed_bytes = 0;
int remaining_buf = max_len - 1;
int n = 1, i = 0, j = 0;
while (fmt[i])
@@ -963,21 +962,32 @@ namespace R3000A
j = 0;
tmp2[j++] = '%';
_start:
switch (fmt[++i])
// let's check whether this is our null terminator
// before allowing the parser to proceed
if (fmt[i + 1])
{
case '.':
case 'l':
tmp2[j++] = fmt[i];
goto _start;
default:
if (fmt[i] >= '0' && fmt[i] <= '9')
{
switch (fmt[++i])
{
case '.':
case 'l':
if (j >= max_len)
break;
tmp2[j++] = fmt[i];
goto _start;
}
break;
default:
if (fmt[i] >= '0' && fmt[i] <= '9')
{
if (j >= max_len)
break;
tmp2[j++] = fmt[i];
goto _start;
}
break;
}
}
if (j >= max_len)
break;
tmp2[j++] = fmt[i];
tmp2[j] = 0;
@@ -985,7 +995,9 @@ namespace R3000A
{
case 'f':
case 'F':
ptmp += sprintf(ptmp, tmp2, (float)iopMemRead32(sp + n * 4));
printed_bytes = std::min(remaining_buf, snprintf(ptmp, remaining_buf, tmp2, (float)iopMemRead32(sp + n * 4)));
remaining_buf -= printed_bytes;
ptmp += printed_bytes;
n++;
break;
@@ -995,7 +1007,9 @@ namespace R3000A
case 'E':
case 'g':
case 'G':
ptmp += sprintf(ptmp, tmp2, (double)iopMemRead32(sp + n * 4));
printed_bytes = std::min(remaining_buf, snprintf(ptmp, remaining_buf, tmp2, (double)iopMemRead32(sp + n * 4)));
remaining_buf -= printed_bytes;
ptmp += printed_bytes;
n++;
break;
@@ -1007,19 +1021,27 @@ namespace R3000A
case 'O':
case 'x':
case 'X':
ptmp += sprintf(ptmp, tmp2, (u32)iopMemRead32(sp + n * 4));
case 'u':
case 'U':
printed_bytes = std::min(remaining_buf, snprintf(ptmp, remaining_buf, tmp2, (u32)iopMemRead32(sp + n * 4)));
remaining_buf -= printed_bytes;
ptmp += printed_bytes;
n++;
break;
case 'c':
ptmp += sprintf(ptmp, tmp2, (u8)iopMemRead32(sp + n * 4));
printed_bytes = std::min(remaining_buf, snprintf(ptmp, remaining_buf, tmp2, (u8)iopMemRead32(sp + n * 4)));
remaining_buf -= printed_bytes;
ptmp += printed_bytes;
n++;
break;
case 's':
{
std::string s = iopMemReadString(iopMemRead32(sp + n * 4));
ptmp += sprintf(ptmp, tmp2, s.data());
printed_bytes = std::min(remaining_buf, snprintf(ptmp, remaining_buf, tmp2, s.data()));
remaining_buf -= printed_bytes;
ptmp += printed_bytes;
n++;
}
break;
@@ -1043,10 +1065,6 @@ namespace R3000A
iopConLog(ShiftJIS_ConvertString(tmp, 1023));
return 1;
#ifdef __clang__
#pragma clang diagnostic pop
#endif
}
} // namespace sysmem

View File

@@ -56,6 +56,16 @@ void Host::OpenURL(const std::string_view url)
{
}
bool Host::InBatchMode()
{
return false;
}
bool Host::InNoGUIMode()
{
return false;
}
bool Host::CopyTextToClipboard(const std::string_view text)
{
return false;