Compare commits

...
53 Commits
Author SHA1 Message Date
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
172 changed files with 3695 additions and 3639 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
+22 -3
View File
@@ -20,6 +20,10 @@ on:
cmakeflags:
required: true
type: string
branch:
required: false
type: string
default: "stable"
publish:
required: false
type: boolean
@@ -73,7 +77,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
@@ -84,7 +88,7 @@ jobs:
build-bundle: true
verbose: true
mirror-screenshots-url: https://dl.flathub.org/repo/screenshots
branch: stable
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') }}
@@ -93,4 +97,19 @@ jobs:
run: |
ostree commit --repo=repo --canonical-permissions --branch=screenshots/x86_64 .github/workflows/scripts/linux/flatpak/screenshots
# TODO: Push to flathub
- 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 }}
+1
View File
@@ -28,3 +28,4 @@ jobs:
compiler: clang
cmakeflags: ""
publish: false
secrets: inherit
+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
+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"
@@ -10,6 +10,7 @@ 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)
@@ -17,8 +18,11 @@ 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"
@@ -22,8 +22,11 @@
</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>
+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()
+113 -59
View File
@@ -2025,6 +2025,13 @@ SCED-51262:
SCED-51279:
name: "Official PlayStation 2 Magazine Demo 25"
region: "PAL-M5"
SCED-51305:
name: "WRC II Extreme [Press Kit]"
region: "PAL-E"
gameFixes:
- XGKickHack # Fixes SPS.
gsHWFixes:
halfPixelOffset: 1 # Fixes texture misalignment.
SCED-51319:
name: "Official PlayStation 2 Magazine Demo 27" # German
region: "PAL-E-G"
@@ -2045,6 +2052,12 @@ SCED-51352:
SCED-51359:
name: "Official PlayStation 2 Magazine Demo 27"
region: "PAL-M5"
SCED-51366:
name: "Ape Escape 2 [Demo]"
region: "PAL-M5"
gsHWFixes:
mipmap: 2 # Fixes miptrick texture effects.
trilinearFiltering: 1 # Fixes miptrick blending.
SCED-51376:
name: "Official PlayStation 2 Magazine Demo 28" # German
region: "PAL-E-G"
@@ -2160,6 +2173,13 @@ SCED-51573:
SCED-51575:
name: "Official PlayStation 2 Magazine Demo 40" # German
region: "PAL-E-G"
SCED-51632:
name: "WRC II Extreme [Special Demo]"
region: "PAL-E"
gameFixes:
- XGKickHack # Fixes SPS.
gsHWFixes:
halfPixelOffset: 1 # Fixes texture misalignment.
SCED-51657:
name: "Official PlayStation Magazine Demo 33"
region: "PAL-Unk"
@@ -2275,9 +2295,17 @@ SCED-52092:
SCED-52120:
name: "Official PlayStation 2 Magazine Demo 55" # German
region: "PAL-E-G"
SCED-52137:
name: "WRC 3 [Demo]"
region: "PAL-E"
gameFixes:
- XGKickHack # Fixes SPS.
gsHWFixes:
roundSprite: 2 # Correct misaligned font, better aligns car shadow.
autoFlush: 2 # Fixes sun luminosity.
SCED-52141:
name: "WRC 3 [Demo]"
region: "NTSC-J"
region: "PAL-E"
compat: 5
gameFixes:
- XGKickHack # Fixes SPS.
@@ -2437,16 +2465,8 @@ SCED-52869:
// I wrote a small runtime that moves unpacker higher right after emulator boot.
// Seems little bit extensive, but there is no way to make it smaller.
// Solves TLB miss errors which prevented the game from booting.
patch=0,EE,0040000C,double,3c0500603cc70054
patch=0,EE,00400014,double,24a5001024840010
patch=0,EE,0040001C,double,7ca6000078860000
patch=0,EE,00400024,double,000000001487fffb
patch=0,EE,0040002c,double,000000000817fff5
patch=0,EE,005fffd4,double,3c1c70003c040060
patch=0,EE,005fffdc,double,3c0700003c067000
patch=0,EE,005fffe4,double,279c000024840800
patch=0,EE,005fffec,double,24e7100024c60080
patch=0,EE,005ffff4,double,00c7e8200818000c
patch=0,EE,0040000c,bytes,5400c73c6000053c100084241000a524000086780000a67cfbff871400000000f5ff170800000000
patch=0,EE,005fffd4,bytes,6000043c00701c3c0070063c0000073c0008842400009c278000c6240010e7240c00180820e8c700
gsHWFixes:
autoFlush: 2 # Fixes sun luminosity and car shadows.
roundSprite: 1 # Fixes misaligned text.
@@ -2458,6 +2478,16 @@ SCED-52880:
region: "PAL-E"
gameFixes:
- XGKickHack # Fixes SPS.
patches:
default:
content: |-
author=kozarovv
// Proper patch for WRC 4. CRC independent.
// I wrote a small runtime that moves unpacker higher right after emulator boot.
// Seems little bit extensive, but there is no way to make it smaller.
// Solves TLB miss errors which prevented the game from booting.
patch=0,EE,0040000c,bytes,5400c73c6000053c100084241000a524000086780000a67cfbff871400000000f5ff170800000000
patch=0,EE,005fffd4,bytes,6000043c00701c3c0070063c0000073c0008842400009c278000c6240010e7240c00180820e8c700
gsHWFixes:
autoFlush: 2 # Fixes sun luminosity and car shadows.
roundSprite: 1 # Fixes misaligned text.
@@ -2484,6 +2514,16 @@ SCED-52945:
region: "PAL-E"
gameFixes:
- XGKickHack # Fixes SPS.
patches:
default:
content: |-
author=kozarovv
// Proper patch for WRC 4. CRC independent.
// I wrote a small runtime that moves unpacker higher right after emulator boot.
// Seems little bit extensive, but there is no way to make it smaller.
// Solves TLB miss errors which prevented the game from booting.
patch=0,EE,0040000c,bytes,5400c73c6000053c100084241000a524000086780000a67cfbff871400000000f5ff170800000000
patch=0,EE,005fffd4,bytes,6000043c00701c3c0070063c0000073c0008842400009c278000c6240010e7240c00180820e8c700
gsHWFixes:
autoFlush: 2 # Fixes sun luminosity and car shadows.
roundSprite: 1 # Fixes misaligned text.
@@ -3803,16 +3843,8 @@ SCES-52389:
// I wrote a small runtime that moves unpacker higher right after emulator boot.
// Seems little bit extensive, but there is no way to make it smaller.
// Solves TLB miss errors which prevented the game from booting.
patch=0,EE,0040000C,double,3c0500603cc70054
patch=0,EE,00400014,double,24a5001024840010
patch=0,EE,0040001C,double,7ca6000078860000
patch=0,EE,00400024,double,000000001487fffb
patch=0,EE,0040002c,double,000000000817fff5
patch=0,EE,005fffd4,double,3c1c70003c040060
patch=0,EE,005fffdc,double,3c0700003c067000
patch=0,EE,005fffe4,double,279c000024840800
patch=0,EE,005fffec,double,24e7100024c60080
patch=0,EE,005ffff4,double,00c7e8200818000c
patch=0,EE,0040000c,bytes,5400c73c6000053c100084241000a524000086780000a67cfbff871400000000f5ff170800000000
patch=0,EE,005fffd4,bytes,6000043c00701c3c0070063c0000073c0008842400009c278000c6240010e7240c00180820e8c700
gsHWFixes:
autoFlush: 2 # Fixes sun luminosity and car shadows.
roundSprite: 1 # Fixes misaligned text.
@@ -5115,7 +5147,7 @@ SCKA-20011:
mipmap: 1
partialTargetInvalidation: 1 # Fixes broken pause screen.
SCKA-20012:
name: "Arc the Lad - Jeong Ryeo Hui Hwang Ho"
name: "Arc the Lad - Jeongryeongui Hwanghon"
region: "NTSC-K"
SCKA-20014:
name: "Dark Cloud 2"
@@ -9721,6 +9753,11 @@ SLED-50884:
SLED-50895:
name: "Medal of Honor - Frontline [Demo]"
region: "PAL-E"
SLED-51012:
name: "Stuntman [Demo]"
region: "PAL-E"
gsHWFixes:
cpuSpriteRenderBW: 4 # Fixes textures.
SLED-51062:
name: "Fireblade [Demo]"
region: "PAL-E"
@@ -9750,6 +9787,11 @@ SLED-51342:
vuClampMode: 2 # Missing geometry with microVU.
gsHWFixes:
mipmap: 1 # Fixes broken player textures.
SLED-51380:
name: "Zone of the Enders - The 2nd Runner [Demo]"
region: "PAL"
gsHWFixes:
partialTargetInvalidation: 1 # Fixes cutscene blur effects.
SLED-51676:
name: "Warhammer 40,000 - Fire Warrior [Demo]"
region: "PAL"
@@ -9779,6 +9821,9 @@ SLED-51975:
gsHWFixes:
halfPixelOffset: 2 # Fixes misaligned post-processing.
PCRTCOverscan: 1 # Fixes image alignment.
SLED-52014:
name: "XIII [Demo]"
region: "PAL-E"
SLED-52326:
name: "007 - Everything or Nothing [Demo]"
region: "PAL-E"
@@ -9966,6 +10011,17 @@ SLED-53719:
SLED-53723:
name: "Peter Jackson's King Kong [Demo]"
region: "PAL-E"
SLED-53731:
name: "Battlefield 2 - Modern Combat [Demo]"
region: "PAL-E"
gsHWFixes:
autoFlush: 2 # Post-processing.
halfPixelOffset: 2 # Offset post-processing.
texturePreloading: 1 # Spikes all over the place otherwise.
textureInsideRT: 1 # Fixes light shinging through objects.
cpuCLUTRender: 1 # Fixes light shining through objects.
getSkipCount: "GSC_Battlefield2" # Depth clear.
beforeDraw: "OI_Battlefield2" # Framebuffer copy, fixes rendering for bottom part of screen.
SLED-53732:
name: "Spartan - Total Warrior [Demo]"
region: "PAL"
@@ -24404,7 +24460,7 @@ SLKA-15043:
name: "Super Puzzle Bobble Collection Vol 1"
region: "NTSC-K"
SLKA-15044:
name: "Super Puzzle Bobble 2"
name: "Super Puzzle Bobble Collection Vol 2"
region: "NTSC-K"
SLKA-25002:
name: "Energy Airforce"
@@ -24541,7 +24597,7 @@ SLKA-25049:
gsHWFixes:
gpuPaletteConversion: 2 # Stops excessive VRAM usage with preloading on.
SLKA-25050:
name: "Shin Sangoku Musou 3"
name: "Jin Samguk Mussang 3"
region: "NTSC-K"
SLKA-25051:
name: "Clock Tower 3"
@@ -24645,7 +24701,7 @@ SLKA-25084:
wildArmsHack: 1 # Improves visual clarity whilst upscaling.
roundSprite: 1 # Reduces graphics garbage on UI whilst upscaling.
SLKA-25085:
name: "Shin Sangoku Musou 3 - Mushouden"
name: "Jin Samguk Mussang 3 - Maengjangjeon"
region: "NTSC-K"
SLKA-25086:
name: "NBA Live 2004"
@@ -24807,7 +24863,7 @@ SLKA-25144:
gsHWFixes:
roundSprite: 1 # Fixes font artifacts.
SLKA-25145:
name: "dot hack - Outbreak"
name: "dot hack - Outbreak"
region: "NTSC-K"
SLKA-25146:
name: "Kaido Battle 2 - Chain Reaction"
@@ -24933,7 +24989,7 @@ SLKA-25186:
name: "King of Fighters, The - Maximum Impact [Limited Edition]"
region: "NTSC-K"
SLKA-25187:
name: "Shin Sangoku Musou 3 - Empires"
name: "Jin Samguk Mussang 3 - Empires"
region: "NTSC-K"
SLKA-25196:
name: "Driv3r"
@@ -25263,7 +25319,7 @@ SLKA-25287:
name: "Metal Slug 4&5"
region: "NTSC-K"
SLKA-25289:
name: "Shin Sangoku Musou 4"
name: "Jin Samguk Mussang 4"
region: "NTSC-K"
SLKA-25290:
name: "Super Monkey Ball Deluxe"
@@ -25401,7 +25457,7 @@ SLKA-25328:
- "SLKA-25328"
- "SLKA-25082"
SLKA-25329:
name: "Shin Sangoku Musou 4 - Mushoden"
name: "Jin Samguk Mussang 4 - Maengjangjeon"
region: "NTSC-K"
gsHWFixes:
autoFlush: 2 # Fixes sun luminosity.
@@ -25561,7 +25617,7 @@ SLKA-25389:
clampModes:
eeClampMode: 3 # Otherwise freezes in some spot.
SLKA-25390:
name: "Shin Sangoku Musou 4 - Empires"
name: "Jin Samguk Mussang 4 - Empires"
region: "NTSC-K"
SLKA-25396:
name: "FIFA '07"
@@ -25654,7 +25710,7 @@ SLKA-35004:
gsHWFixes:
getSkipCount: "GSC_SakuraWarsSoLongMyLove"
SLKA-35005:
name: "Shin Sangoku Musou 5 Special"
name: "Jin Samguk Mussang 5 - Special"
region: "NTSC-K"
SLPM-20391:
name: "Saiyuki Gunlock"
@@ -28924,6 +28980,9 @@ SLPM-64544:
SLPM-64549:
name: "Siksin-ui Seong"
region: "NTSC-K"
SLPM-64550:
name: "Super Puzzle Bobble 2"
region: "NTSC-K"
SLPM-64552:
name: "Silent Scope 3"
region: "NTSC-K"
@@ -29948,6 +30007,8 @@ SLPM-65284:
region: "NTSC-J"
gameFixes:
- XGKickHack # Fixes SPS.
gsHWFixes:
halfPixelOffset: 1 # Fixes texture misalignment.
SLPM-65285:
name: "Love Hina Gorgeous [First Limited Edition]"
region: "NTSC-J"
@@ -30889,6 +30950,8 @@ SLPM-65573:
region: "NTSC-J"
gameFixes:
- XGKickHack # Fixes SPS.
gsHWFixes:
halfPixelOffset: 1 # Fixes texture misalignment.
SLPM-65574:
name: "Silent Hill 4 - The Room"
region: "NTSC-J"
@@ -32326,16 +32389,8 @@ SLPM-65975:
// I wrote a small runtime that moves unpacker higher right after emulator boot.
// Seems little bit extensive, but there is no way to make it smaller.
// Solves TLB miss errors which prevented the game from booting.
patch=0,EE,0040000C,double,3c0500603cc70054
patch=0,EE,00400014,double,24a5001024840010
patch=0,EE,0040001C,double,7ca6000078860000
patch=0,EE,00400024,double,000000001487fffb
patch=0,EE,0040002c,double,000000000817fff5
patch=0,EE,005fffd4,double,3c1c70003c040060
patch=0,EE,005fffdc,double,3c0700003c067000
patch=0,EE,005fffe4,double,279c000024840800
patch=0,EE,005fffec,double,24e7100024c60080
patch=0,EE,005ffff4,double,00c7e8200818000c
patch=0,EE,0040000c,bytes,5400c73c6000053c100084241000a524000086780000a67cfbff871400000000f5ff170800000000
patch=0,EE,005fffd4,bytes,6000043c00701c3c0070063c0000073c0008842400009c278000c6240010e7240c00180820e8c700
gsHWFixes:
autoFlush: 2 # Fixes sun luminosity and car shadows.
roundSprite: 1 # Fixes misaligned text.
@@ -32957,8 +33012,10 @@ SLPM-66136:
name: "SuperLite 2000 Vol. 34 - Akai Ito"
region: "NTSC-J"
SLPM-66137:
name: "Clover Heart's Looking for Happiness [The Best]"
name: "Clover Heart's - Looking for Happiness [The Best]"
region: "NTSC-J"
gsHWFixes:
minimumBlendingLevel: 4 # Fixes transparancy.
SLPM-66138:
name: "Desire [Best Version]"
region: "NTSC-J"
@@ -33650,7 +33707,8 @@ SLPM-66302:
name: "Clannad"
region: "NTSC-J"
gsHWFixes:
cpuCLUTRender: 1 # Fixes colours.
gpuTargetCLUT: 1 # Fixes colours.
minimumBlendingLevel: 4 # Fixes transparancy.
SLPM-66307:
name: "Sengoku Musou 2"
region: "NTSC-J"
@@ -33779,16 +33837,8 @@ SLPM-66334:
// I wrote a small runtime that moves unpacker higher right after emulator boot.
// Seems little bit extensive, but there is no way to make it smaller.
// Solves TLB miss errors which prevented the game from booting.
patch=0,EE,0040000C,double,3c0500603cc70054
patch=0,EE,00400014,double,24a5001024840010
patch=0,EE,0040001C,double,7ca6000078860000
patch=0,EE,00400024,double,000000001487fffb
patch=0,EE,0040002c,double,000000000817fff5
patch=0,EE,005fffd4,double,3c1c70003c040060
patch=0,EE,005fffdc,double,3c0700003c067000
patch=0,EE,005fffe4,double,279c000024840800
patch=0,EE,005fffec,double,24e7100024c60080
patch=0,EE,005ffff4,double,00c7e8200818000c
patch=0,EE,0040000c,bytes,5400c73c6000053c100084241000a524000086780000a67cfbff871400000000f5ff170800000000
patch=0,EE,005fffd4,bytes,6000043c00701c3c0070063c0000073c0008842400009c278000c6240010e7240c00180820e8c700
gsHWFixes:
autoFlush: 2 # Fixes sun luminosity and car shadows.
roundSprite: 1 # Fixes misaligned text.
@@ -36415,7 +36465,7 @@ SLPM-67522:
name: "Sangokushi Senki"
region: "NTSC-K"
SLPM-67523:
name: "Shin Sangoku Musou 2"
name: "Jin Samguk Mussang 2"
region: "NTSC-K"
SLPM-67524:
name: "Armored Core 3"
@@ -36463,8 +36513,8 @@ SLPM-67531:
patch=1,EE,00166CD0,word,48438800
patch=1,EE,00166CDC,word,4BE521AC
SLPM-67535:
name: "Memories Of"
region: "NTSC-J-K"
name: "Memories Off"
region: "NTSC-K"
SLPM-67536:
name: "Bongsin Yeonui 2"
region: "NTSC-K"
@@ -36490,7 +36540,7 @@ SLPM-67546:
clampModes:
vuClampMode: 3 # Fix white shiny weapons.
SLPM-67550:
name: "Shin Sangoku Musou 2 - Mushouden"
name: "Jin Samguk Mussang 2 - Maengjangjeon"
region: "NTSC-K"
SLPM-67552:
name: "Tomak - Save the Earth Again [Complete Edition]"
@@ -39816,11 +39866,15 @@ SLPS-25389:
name: "Gundam Seed - Never Ending Tomorrow"
region: "NTSC-J"
SLPS-25390:
name: "Clover's Heart - Looking for Happiness [Limited Edition]"
name: "Clover Heart's - Looking for Happiness [Limited Edition]"
region: "NTSC-J"
gsHWFixes:
minimumBlendingLevel: 4 # Fixes transparancy.
SLPS-25391:
name: "Clover's Heart - Looking for Happiness"
name: "Clover Heart's - Looking for Happiness"
region: "NTSC-J"
gsHWFixes:
minimumBlendingLevel: 4 # Fixes transparancy.
SLPS-25392:
name: "Desire"
region: "NTSC-J"
+20 -5
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,8 +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,
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,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,paddle1:b12,paddle3:b13,paddle2,b14,paddle4:b15,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,paddle1:b12,paddle3:b13,paddle2,b14,paddle4:b15,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,
@@ -1516,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,
@@ -1542,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

+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);
}
+3 -4
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
@@ -89,7 +89,6 @@ target_sources(common PRIVATE
ReadbackSpinManager.h
RedtapeWilCom.h
RedtapeWindows.h
SafeArray.h
ScopedGuard.h
SettingsInterface.h
SettingsWrapper.h
+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);
-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
-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"
+3 -2
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" />
+10 -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>
@@ -351,6 +351,9 @@
<ClInclude Include="WrappedMemCopy.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Error.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Source Files">
@@ -365,4 +368,4 @@
<Filter>Source Files</Filter>
</MASM>
</ItemGroup>
</Project>
</Project>
+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>
-1
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"
+4 -3
View File
@@ -177,9 +177,7 @@ if(USE_ACHIEVEMENTS)
)
endif()
set(TS_FILES
Translations/pcsx2-qt_en.ts
)
file(GLOB TS_FILES ${CMAKE_CURRENT_SOURCE_DIR}/Translations/*.ts)
target_precompile_headers(pcsx2-qt PRIVATE PrecompiledHeader.h)
@@ -199,6 +197,9 @@ 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})
-1
View File
@@ -183,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);
+13 -8
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"/>
@@ -484,12 +489,12 @@
</property>
</action>
<action name="actionAbout">
<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>
<normaloff>:/icons/AppIcon64.png</normaloff>:/icons/AppIcon64.png</iconset>
</property>
<property name="text">
<string>&amp;About PCSX2...</string>
</property>
</action>
<action name="actionChangeDisc">
+1 -1
View File
@@ -42,12 +42,12 @@
#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"
+8 -16
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);
@@ -156,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));
+1
View File
@@ -42,6 +42,7 @@ private Q_SLOTS:
void resetTimestretchDefaults();
private:
void populateOutputModules();
void updateVolumeLabel();
SettingsDialog* m_dialog;
+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>
+1 -2
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."));
+2 -2
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">
+2 -2
View File
@@ -169,10 +169,10 @@ void SetupWizardDialog::confirmCancel()
void SetupWizardDialog::setupUi()
{
setWindowIcon(QIcon(QStringLiteral("%1/icons/AppIconLarge.png").arg(QtHost::GetResourcesBasePath())));
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;
+12 -4
View File
@@ -13,6 +13,11 @@
<property name="windowTitle">
<string>PCSX2 Setup Wizard</string>
</property>
<property name="windowIcon">
<iconset>
<normalon>:/icons/AppIcon64.png</normalon>
</iconset>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="horizontalSpacing">
<number>10</number>
@@ -20,7 +25,7 @@
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label">
<widget class="QLabel" name="logo">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
@@ -33,12 +38,15 @@
<height>128</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>128</width>
<height>128</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="resources/resources.qrc">:/icons/AppIcon.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
+3 -2
View File
@@ -238,7 +238,7 @@ void QtHost::SetStyleFromSettings()
standardPalette.setColor(QPalette::Text, Qt::black);
standardPalette.setColor(QPalette::Button, extr);
standardPalette.setColor(QPalette::ButtonText, Qt::black);
standardPalette.setColor(QPalette::Link, Qt::black);
standardPalette.setColor(QPalette::Link, highlight.darker());
standardPalette.setColor(QPalette::Highlight, highlight);
standardPalette.setColor(QPalette::HighlightedText, Qt::white);
standardPalette.setColor(QPalette::Active, QPalette::Button, extr);
@@ -332,6 +332,7 @@ void QtHost::SetStyleFromSettings()
const QColor royalBlue(29, 41, 81);
const QColor darkishBlue(17, 30, 108);
const QColor highlight(36, 93, 218);
const QColor link(0, 202, 255);
QPalette darkPalette;
darkPalette.setColor(QPalette::Window, royalBlue);
@@ -343,7 +344,7 @@ void QtHost::SetStyleFromSettings()
darkPalette.setColor(QPalette::Text, Qt::white);
darkPalette.setColor(QPalette::Button, darkishBlue);
darkPalette.setColor(QPalette::ButtonText, Qt::white);
darkPalette.setColor(QPalette::Link, Qt::white);
darkPalette.setColor(QPalette::Link, link);
darkPalette.setColor(QPalette::Highlight, highlight);
darkPalette.setColor(QPalette::HighlightedText, Qt::white);
+180 -78
View File
@@ -17,6 +17,7 @@
#include "QtHost.h"
#include "common/Assertions.h"
#include "common/Console.h"
#include "common/StringUtil.h"
@@ -40,9 +41,20 @@
namespace QtHost
{
static const ImWchar* GetGlyphRangesJapanese();
static const ImWchar* GetGlyphRangesChinese();
static std::string GetFontPath(const char* name);
struct GlyphInfo
{
const char* language;
const char* windows_font_name;
const char* linux_font_name;
const char* mac_font_name;
const char16_t* used_glyphs;
};
static std::string GetFontPath(const GlyphInfo* gi);
static void UpdateGlyphRanges(const std::string_view& language);
static const GlyphInfo* GetGlyphInfo(const std::string_view& language);
static std::vector<ImWchar> s_glyph_ranges;
} // namespace QtHost
static std::vector<QTranslator*> s_translators;
@@ -60,7 +72,7 @@ void QtHost::InstallTranslator()
QString::fromStdString(Host::GetBaseStringSettingValue("UI", "Language", GetDefaultLanguage()));
// Install the base qt translation first.
const QString base_dir = QStringLiteral("%1/translations").arg(qApp->applicationDirPath());
const QString base_dir = QStringLiteral("%1/translations").arg(qApp->applicationDirPath());
QString base_path = QStringLiteral("%1/qt_%2.qm").arg(base_dir).arg(language);
bool has_base_ts = QFile::exists(base_path);
if (!has_base_ts)
@@ -90,65 +102,67 @@ void QtHost::InstallTranslator()
}
const QString path = QStringLiteral("%1/pcsx2-qt_%3.qm").arg(base_dir).arg(language);
if (!QFile::exists(path))
QTranslator* translator = nullptr;
if (QFile::exists(path))
{
translator = new QTranslator(qApp);
if (translator->load(path))
{
Console.WriteLn(
Color_StrongYellow, "Loaded translation file for language %s", language.toUtf8().constData());
}
else
{
QMessageBox::warning(nullptr, QStringLiteral("Translation Error"),
QStringLiteral("Failed to load translation file for language '%1':\n%2").arg(language).arg(path));
delete translator;
translator = nullptr;
}
}
else
{
#ifdef PCSX2_DEVBUILD
// For now, until we're sure this works on all platforms, we won't block users from starting if they're missing.
QMessageBox::warning(nullptr, QStringLiteral("Translation Error"),
QStringLiteral("Failed to find translation file for language '%1':\n%2").arg(language).arg(path));
#endif
return;
}
QTranslator* translator = new QTranslator(qApp);
if (!translator->load(path))
if (translator)
{
QMessageBox::warning(nullptr, QStringLiteral("Translation Error"),
QStringLiteral("Failed to load translation file for language '%1':\n%2").arg(language).arg(path));
delete translator;
return;
qApp->installTranslator(translator);
s_translators.push_back(translator);
}
Console.WriteLn(Color_StrongYellow, "Loaded translation file for language %s", language.toUtf8().constData());
qApp->installTranslator(translator);
s_translators.push_back(translator);
UpdateGlyphRanges(language.toStdString());
#ifdef _WIN32
if (language == QStringLiteral("ja"))
{
ImGuiManager::SetFontPath(GetFontPath("msgothic.ttc"));
ImGuiManager::SetFontRange(GetGlyphRangesJapanese());
}
else if (language == QStringLiteral("zh-cn"))
{
ImGuiManager::SetFontPath(GetFontPath("msyh.ttc"));
ImGuiManager::SetFontRange(GetGlyphRangesChinese());
}
#endif
// Clear translation cache after installing translators, to prevent races.
Host::ClearTranslationCache();
}
static std::string QtHost::GetFontPath(const char* name)
static std::string QtHost::GetFontPath(const GlyphInfo* gi)
{
std::string font_path;
#ifdef _WIN32
PWSTR folder_path;
if (FAILED(SHGetKnownFolderPath(FOLDERID_Fonts, 0, nullptr, &folder_path)))
return fmt::format("C:\\Windows\\Fonts\\%s", name);
if (gi->windows_font_name)
{
PWSTR folder_path;
if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_Fonts, 0, nullptr, &folder_path)))
{
font_path = StringUtil::WideStringToUTF8String(folder_path);
CoTaskMemFree(folder_path);
font_path += "\\";
font_path += gi->windows_font_name;
}
else
{
font_path = fmt::format("C:\\Windows\\Fonts\\%s", gi->windows_font_name);
}
}
#endif
std::string font_path(StringUtil::WideStringToUTF8String(folder_path));
CoTaskMemFree(folder_path);
font_path += "\\";
font_path += name;
return font_path;
#else
return name;
#endif
}
std::vector<std::pair<QString, QString>> QtHost::GetAvailableLanguageList()
{
return {
{QStringLiteral("English"), QStringLiteral("en")},
};
}
const char* QtHost::GetDefaultLanguage()
@@ -173,46 +187,134 @@ s32 Host::Internal::GetTranslatedStringImpl(
return static_cast<s32>(translated_size);
}
static const ImWchar* QtHost::GetGlyphRangesJapanese()
std::vector<std::pair<QString, QString>> QtHost::GetAvailableLanguageList()
{
// clang-format off
// auto update by generate_update_glyph_ranges.py with pcsx2-qt_ja.ts
static const char16_t chars[] = u"、。あいかがきこさしすずせたってでとなにのはべまみらりるれをんァィイェエカキクグゲシジスセタダチッデトドバパフブプボポミムメモャュョラリルレロンー一中了今件体使信入出制効動取口可変始定実度強後得態択挿易更有本検無状獲用画的索終績能自行覧解設読起送速選開除難面高";
const int chars_length = sizeof(chars) / sizeof(chars[0]);
// clang-format on
static ImWchar base_ranges[] = {
0x0020, 0x007E, // Basic Latin
return {
{QStringLiteral("Afrikaans (af-ZA)"), QStringLiteral("af-ZA")},
{QStringLiteral("عربي (ar-SA)"), QStringLiteral("ar-SA")},
{QStringLiteral("Català (ca-ES)"), QStringLiteral("ca-ES")},
{QStringLiteral("Čeština (cs-CZ)"), QStringLiteral("cs-CZ")},
{QStringLiteral("Dansk (da-DK)"), QStringLiteral("da-DK")},
{QStringLiteral("Deutsch (de-DE)"), QStringLiteral("de-DE")},
{QStringLiteral("Ελληνικά (el-GR)"), QStringLiteral("el-GR")},
{QStringLiteral("English (en)"), QStringLiteral("en")},
{QStringLiteral("Español (Hispanoamérica) (es-419)"), QStringLiteral("es-419")},
{QStringLiteral("Español (España) (es-ES)"), QStringLiteral("es-ES")},
{QStringLiteral("فارسی (fa-IR)"), QStringLiteral("fa-IR")},
{QStringLiteral("Suomi (fi-FI)"), QStringLiteral("fi-FI")},
{QStringLiteral("Français (fr-FR)"), QStringLiteral("fr-FR")},
{QStringLiteral("עִבְרִית (he-IL)"), QStringLiteral("he-IL")},
{QStringLiteral("Magyar (hu-HU)"), QStringLiteral("hu-HU")},
{QStringLiteral("Bahasa Indonesia (in-ID)"), QStringLiteral("id-ID")},
{QStringLiteral("Italiano (it-IT)"), QStringLiteral("it-IT")},
{QStringLiteral("日本語 (ja-JP)"), QStringLiteral("ja-JP")},
{QStringLiteral("한국어 (ko-KR)"), QStringLiteral("ko-KR")},
{QStringLiteral("Nederlands (nl-NL)"), QStringLiteral("nl-NL")},
{QStringLiteral("Norsk (nl-NL)"), QStringLiteral("no-NO")},
{QStringLiteral("Polski (pl-PL)"), QStringLiteral("pl-PL")},
{QStringLiteral("Português (Brasil) (pt-BR)"), QStringLiteral("pt-BR")},
{QStringLiteral("Português (Portugal) (pt-PT)"), QStringLiteral("pt-PT")},
{QStringLiteral("Limba română (ro-RO)"), QStringLiteral("ro-RO")},
{QStringLiteral("Русский (ru-RU)"), QStringLiteral("ru-RU")},
{QStringLiteral("Српски језик (sr-SP)"), QStringLiteral("sr-SP")},
{QStringLiteral("Svenska (sv-SE)"), QStringLiteral("sv-SE")},
{QStringLiteral("Türkçe (tr-TR)"), QStringLiteral("tr-TR")},
{QStringLiteral("Українська мова (uk-UA)"), QStringLiteral("uk-UA")},
{QStringLiteral("Tiếng Việt (vi-VN)"), QStringLiteral("vi-VN")},
{QStringLiteral("简体中文 (zh-CN)"), QStringLiteral("zh-CN")},
{QStringLiteral("繁體中文 (zh-TW)"), QStringLiteral("zh-TW")},
};
const int base_length = sizeof(base_ranges) / sizeof(base_ranges[0]);
static ImWchar full_ranges[base_length + chars_length * 2 + 1] = {0};
memcpy(full_ranges, base_ranges, sizeof(base_ranges));
for (int i = 0; i < chars_length; i++)
{
full_ranges[base_length + i * 2] = full_ranges[base_length + i * 2 + 1] = chars[i];
}
return full_ranges;
}
static const ImWchar* QtHost::GetGlyphRangesChinese()
static constexpr const ImWchar s_base_latin_range[] = {
0x0020, 0x00FF, // Basic Latin + Latin Supplement
};
static constexpr const ImWchar s_central_european_ranges[] = {
0x0100, 0x017F, // Central European diacritics
};
void QtHost::UpdateGlyphRanges(const std::string_view& language)
{
// clang-format off
// auto update by generate_update_glyph_ranges.py with pcsx2-qt_zh-cn.ts
static const char16_t chars[] = u"";
const int chars_length = sizeof(chars) / sizeof(chars[0]);
// clang-format on
const GlyphInfo* gi = GetGlyphInfo(language);
static ImWchar base_ranges[] = {
0x0020, 0x007E, // Basic Latin
};
const int base_length = sizeof(base_ranges) / sizeof(base_ranges[0]);
std::string font_path;
s_glyph_ranges.clear();
static ImWchar full_ranges[base_length + chars_length * 2 + 1] = {0};
memcpy(full_ranges, base_ranges, sizeof(base_ranges));
for (int i = 0; i < chars_length; i++)
// Base Latin range is always included.
s_glyph_ranges.insert(s_glyph_ranges.begin(), std::begin(s_base_latin_range), std::end(s_base_latin_range));
if (gi)
{
full_ranges[base_length + i * 2] = full_ranges[base_length + i * 2 + 1] = chars[i];
if (gi->used_glyphs)
{
const char16_t* ptr = gi->used_glyphs;
while (*ptr != 0)
{
// Always should be in pairs.
pxAssert(ptr[0] != 0 && ptr[1] != 0);
s_glyph_ranges.push_back(*(ptr++));
s_glyph_ranges.push_back(*(ptr++));
}
}
font_path = GetFontPath(gi);
}
return full_ranges;
// If we don't have any specific glyph range, assume Central European, except if English, then keep the size down.
if ((!gi || !gi->used_glyphs) && language != "en")
{
s_glyph_ranges.insert(
s_glyph_ranges.begin(), std::begin(s_central_european_ranges), std::end(s_central_european_ranges));
}
// List terminator.
s_glyph_ranges.push_back(0);
s_glyph_ranges.push_back(0);
ImGuiManager::SetFontPath(std::move(font_path));
ImGuiManager::SetFontRange(s_glyph_ranges.data());
}
// clang-format off
static constexpr const char16_t s_cyrillic_ranges[] = {
/* Cyrillic + Cyrillic Supplement */ 0x0400, 0x052F, /* Extended-A */ 0x2DE0, 0x2DFF, /* Extended-B */ 0xA640, 0xA69F, 0, 0
};
static constexpr const QtHost::GlyphInfo s_glyph_info[] = {
// Cyrillic languages
{ "ru-RU", nullptr, nullptr, nullptr, s_cyrillic_ranges },
{ "sr-SP", nullptr, nullptr, nullptr, s_cyrillic_ranges },
{ "uk-UA", nullptr, nullptr, nullptr, s_cyrillic_ranges },
{
"ja-JP", "msgothic.ttc", nullptr, nullptr,
// auto update by update_glyph_ranges.py with pcsx2-qt_ja-JP.ts
u"​​□□△△◯◯✕✕、。〜〜ああいいううええおきくぐここささしすせせそそただっつてにのはびびへべほほまみめもややよれわわをんァイウコサソタチッツテニネパビロワワンンーー一一上下不不中中丸丸了了互互今今他他代代仮仮作作使使保保信信修修倍倍値値停停備備像像入入全全公公内内再再出出切切別別利利制制削削副副割割力力加加効効動動勧勧化化十十南南参参反収取取古古可台右右合合同名向向回回固固国国在在報報場場境境壊壊変変外外大大失失奨奨始始字存完完定定実実左左帰帰常常幅幅度度式式張張形形待待後後御御性性情情想想意意感感態態成成投投択択拡拡推推提提換換敗敗数数整整新新方方既既日日明明時時更更書書替最有有期期本本果果検検標標橙橙機機止正毎毎比比況況注注消消港港湾湾準準無無照照状状率率現現璧璧環環生生用用画画異異的的直直知知確確示示種種稿稿空空索索終終緑緑編編績績能能自自般般行行表表製製複複視視覧覧解解言言設設認認語語読読赤赤起起跡跡転転軸軸込込近近追追送送通通速速進進遅遅遊遊適適選選部部長長閉閉開開関関防防限限除除隅隅集集青青非非面面韓韓音音類類香香高高黄黄++??"
},
{
"ko-KR", "malgun.ttf", nullptr, nullptr,
// auto update by update_glyph_ranges.py with pcsx2-qt_ko-KR.ts
u""
},
{
"zh-CN", "msyh.ttc", nullptr, nullptr,
// auto update by update_glyph_ranges.py with pcsx2-qt_zh-CN.ts
u"‘’□□△△○○、。一丁三下不与且且世世丢丢两两个个中中丰丰串串为主么义之之乎乎乐乐乘乘也也了了事二于于互互亚些交交产产享享亮亮亲亲人人什什仅仅介介仍从他他代以们们件价任任份份伍伍休休优优会会传传估估伸伸似似但但位住佑佑体体何何余余作作佣佣佳佳使使例例供供侧侧便便俄俄保保信信修修倍倍值值倾倾假假偏偏做做停停储储像像儿儿允允元元充充先光克克免免入入全全六六兰共关关兵典兼兼内内册再写写冲决况况净净准准减减几几出击函函刀刀刃刃分切列列则则创创删删利利别别到到制刷刹刹前前剪剪副副力力功务动助势势勿勿包包化化匹区十十升升半半协协单单南南占卡卫卫印印即即压压原原去去参参及及双反发发取变叠叠口古另另只只可台右右号号各各合吉同后向向吗吗否否含含启启呈呈告告员员味味命命和和哈哈响响哪哪唤唤商商善善器器四四回回因因团团围围国图圈圈在在地地场场址址均均坏坐块块坛坛垂垂型型域域基基堆堆堪堪塔塔填填增增士士声声处处备备复复外外多多够够大大天太失失头头夹夹奇奇奏奏套套奥奥奶奶好好如如始始威威娱娱婴婴媒媒子子字存它它安安完完宏宏官官定定宝实害害家家容容宽宽宿宿寄寄密密富富寸对导导封封射射将将小小少少尔尔尚尚尝尝就就尺尺尼尾局局层层屏屏展展属属崩崩工左巨巨差差己已巴巴希希带帧帮帮常常幅幅幕幕平平并并幸幸序序库底度度延延建建开开异弃弊弊式式引引张张弹强归当录录形形彩彩影影径待很很得得循循微微德德心心必忆志志忙忙快快忽忽态态性性怪怪恢恢息息您您悬悬情情惑惑惯惯意意感感慢慢戏我或或战战截截戳戳户户所扁手手打打托托执执扩扩扫扬扳扳找找技技抑抑抖抗护护拆拆拉拉拍拍拒拒拟拟拦拦择择括括拳拳持持指指按按挑挑挡挡挪挪振振捕捕损损换换据据掌掌排排接接控掩描提插插握握搜搜摇摇撕撕撤撤播播操擎支支收收改改放放故故效效敏敏散散数数整整文文断断斯新方方旋旋无无日日旧旧时时明明易易星映是是显显晕晕普普晰晰暂暂暗暗曲曲更更替最有有服服期期未未本本机机权权杆杆束束条条来来板板极极果果柄柄某某染染查查栅栅标栈栏栏校校样根格格框框案案档档桥桥检检棕棕榜榜模模橙橙次次欧欧止步死死殊殊段段每每比比毫毫水水求求汇汇没没油油法法波波注注泻泻洲洲活活流流浅浅测测浏浏浪浪浮浮海海消消深深混混添添清清港港渲渲游游湖湖湾湾溃溃源源溢溢滑滑满满滤滤演演澳澳激激灰灰灵灵点点烈烈热热焦焦然然煞煞照照片版牌牌牙牙特特状状狂狂独独狼狼猎猎猩猩率率王王玩玩环现班班理理瑞瑞甚甚生生用用由甲电电画画畅畅界界留留略略疤疤登登白百的的皇皇盖盘目目直直相相省省看看真眠着着知知短短石石码码破破础础硬硬确确碌碌磁磁示示神神禁禁离离种种秒秒积称移移程程稍稍稳稳空空突突窗窗立立站站端端符符第第等等筛筛签签简简算算管管类类粉粉粘粘精精糊糊系系素素索索紫紫纠纠红红级级纯纯纳纳纹纹线线组组细终经经绑绑结结绕绕绘给络绝统统继继绪绪续续维维绿缀缓缓编编缩缩网网罗罗置置美美翻翻考考者者而而耗耗耳耳联联肩肩胖胖能能腊腊自自至致舍舍良良色色节节芬芬英英范范荐荐荷荷莱莱获获菜菜萄萄著著葡葡蓝蓝藏藏虑虑虚虚融融行行衡衡补补表表被被裁裂装装西西要要覆覆观观规规视视览觉角角解解触触言言警警计计认认让让议议记记许许论论设访证证诊诊译译试试询询该详语语误误说说请诸读读调调谍谍豹豹负负败账质质贴贴费费赛赛起起超超越越足足跟跟跨跨路路跳跳踏踏踪踪身身车车轨轨转转轮软轴轴轻轻载载较较辅辅辑辑输输辨辨边边达达过过运近还这进进连迟述述追追退适选选逐逐递递通通速造遇遇道道避避那那部部都都配配醒醒采采释释里重量量针针钮钮铁铁铺铺链链销锁锐锐错错键锯镜镜长长门门闭问闲闲间间队队防防阴阴附附陆陆降降限限除除险险随隐隔隔隙隙障障雄雄集集零零雾雾需需震震静静非非靠靠面面韩韩音音顶顶项须顿顿预预频频题题颜额风风饱饱馈馈首首香香马马驱驱验验高高鬼鬼魂魂魔魔麦麦黄黄黑黑默默鼓鼓鼠鼠齐齐齿齿,,??"
},
{
"zh-TW", "msyh.ttc", nullptr, nullptr,
// auto update by update_glyph_ranges.py with pcsx2-qt_zh-TW.ts
u""
},
};
// clang-format on
const QtHost::GlyphInfo* QtHost::GetGlyphInfo(const std::string_view& language)
{
for (const GlyphInfo& it : s_glyph_info)
{
if (language == it.language)
return &it;
}
return nullptr;
}
@@ -1,44 +0,0 @@
#!/usr/bin/env python3
import sys
import os
import re
import xml.etree.ElementTree as ET
src_path = os.path.join(os.path.dirname(__file__), "..", "Translations.cpp")
def parse_xml(path):
translations = ""
tree = ET.parse(path)
root = tree.getroot()
for node in root.findall("context/message/translation"):
if node.text:
translations += node.text
chars = list(set([ord(ch) for ch in translations if ord(ch) >= 0x2000]))
chars.sort()
chars = "".join([chr(ch) for ch in chars])
return chars
def update_src_file(ts_file, chars):
ts_name = os.path.basename(ts_file)
pattern = re.compile('(// auto update.*' + ts_name + '.*\n[^"]+")[^"]*(".*)')
with open(src_path, "r", encoding="utf-8") as f:
original = f.read()
update = pattern.sub("\\1" + chars + "\\2", original)
if original != update:
with open(src_path, "w", encoding="utf-8") as f:
f.write(update)
print("Updated character list.")
else:
print("Character list is unchanged.")
if __name__ == "__main__":
if len(sys.argv) < 2:
print(f"usage: {sys.argv[0]} <pcsx2-qt_*.ts path>")
sys.exit(1)
chars = parse_xml(sys.argv[1])
#print(chars)
print(f"{len(chars)} character(s) detected.")
update_src_file(sys.argv[1], chars)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,69 @@
#!/usr/bin/env python3
import os
import re
import xml.etree.ElementTree as ET
languages_to_update = [
"ja-JP",
"ko-KR",
"zh-CN",
"zh-TW"
]
src_path = os.path.join(os.path.dirname(__file__), "..", "Translations.cpp")
ts_dir = os.path.join(os.path.dirname(__file__))
def parse_xml(path):
tree = ET.parse(path)
root = tree.getroot()
translations = ""
for node in root.findall("context/message/translation"):
if node.text:
translations += node.text
ords = list(set([ord(ch) for ch in translations if ord(ch) >= 0x2000]))
if len(ords) == 0:
return ""
# Try to organize it into ranges
ords.sort()
ord_pairs = []
start_ord = None
last_ord = None
for nord in ords:
if start_ord is not None and nord == (last_ord + 1):
last_ord = nord
continue
if start_ord is not None:
ord_pairs.append(start_ord)
ord_pairs.append(last_ord)
start_ord = nord
last_ord = nord
if start_ord is not None:
ord_pairs.append(start_ord)
ord_pairs.append(last_ord)
chars = "".join([chr(ch) for ch in ord_pairs])
return chars
def update_src_file(ts_file, chars):
ts_name = os.path.basename(ts_file)
pattern = re.compile('(// auto update.*' + ts_name + '.*\n[^"]+")[^"]*(".*)')
with open(src_path, "r", encoding="utf-8") as f:
original = f.read()
update = pattern.sub("\\1" + chars + "\\2", original)
if original != update:
with open(src_path, "w", encoding="utf-8") as f:
f.write(update)
print(f"Updated character list for {ts_file}.")
else:
print(f"Character list is unchanged for {ts_file}.")
if __name__ == "__main__":
for language in languages_to_update:
ts_file = os.path.join(ts_dir, f"pcsx2-qt_{language}.ts")
chars = parse_xml(ts_file)
print(f"{language}: {len(chars)} character(s) detected.")
update_src_file(ts_file, chars)
+1
View File
@@ -49,6 +49,7 @@
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>PrecompiledHeader.h</PrecompiledHeaderFile>
<PreprocessorDefinitions>LZMA_API_STATIC;BUILD_DX=1;ENABLE_RAINTEGRATION;ENABLE_ACHIEVEMENTS;ENABLE_DISCORD_PRESENCE;ENABLE_OPENGL;ENABLE_VULKAN;SDL_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>QT_NO_EXCEPTIONS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<!-- Current Qt debug builds assert on RTTI. Remove this once we next build Qt. -->
<RuntimeTypeInfo Condition="$(Configuration.Contains(Clang)) And $(Configuration.Contains(Debug))">true</RuntimeTypeInfo>
</ClCompile>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

+1 -1
View File
@@ -1,6 +1,6 @@
<RCC>
<qresource>
<file>icons/AppIcon.png</file>
<file>icons/AppIcon64.png</file>
<file>icons/applications-system-24.png</file>
<file>icons/black/index.theme</file>
<file>icons/black/svg/arrow-left-right-line.svg</file>
+31 -32
View File
@@ -30,6 +30,7 @@
#include "MTGS.h"
#include "VMManager.h"
#include "svnrev.h"
#include "SysForwardDefs.h"
#include "vtlb.h"
#include "common/Assertions.h"
@@ -1357,42 +1358,40 @@ std::string_view Achievements::GetELFNameForHash(const std::string& elf_path)
std::optional<std::vector<u8>> Achievements::ReadELFFromCurrentDisc(const std::string& elf_path)
{
// This CDVD stuff is super nasty and full of exceptions..
std::optional<std::vector<u8>> ret;
try
// ELF suffix hack. Taken from CDVD::loadElf
// MLB2k6 has an elf whose suffix is actually ;2
std::string filepath(elf_path);
const std::string::size_type semi_pos = filepath.rfind(';');
if (semi_pos != std::string::npos && std::string_view(filepath).substr(semi_pos) != ";1")
{
// ELF suffix hack. Taken from CDVD::loadElf
// MLB2k6 has an elf whose suffix is actually ;2
std::string filepath(elf_path);
const std::string::size_type semi_pos = filepath.rfind(';');
if (semi_pos != std::string::npos && std::string_view(filepath).substr(semi_pos) != ";1")
{
Console.Warning("(Achievements) Non-conforming version suffix (%s) detected and replaced.", elf_path.c_str());
filepath.erase(semi_pos);
filepath += ";1";
}
IsoFSCDVD isofs;
IsoFile file(isofs, filepath);
const u32 size = file.getLength();
ret = std::vector<u8>();
ret->resize(size);
if (size > 0)
{
const s32 bytes_read = file.read(ret->data(), static_cast<s32>(size));
if (bytes_read != static_cast<s32>(size))
{
Console.Error("(Achievements) Only read %d of %u bytes of ELF '%s'", bytes_read, size, elf_path.c_str());
ret.reset();
}
}
Console.Warning(fmt::format("(Achievements) Non-conforming version suffix ({}) detected and replaced.", elf_path));
filepath.erase(semi_pos);
filepath += ";1";
}
catch (...)
IsoFSCDVD isofs;
IsoFile file(isofs);
Error error;
if (!file.open(filepath, &error))
{
Console.Error("(Achievements) Caught exception while trying to read ELF '%s'.", elf_path.c_str());
ret.reset();
Console.Error(fmt::format("(Achievements) Failed to open ELF '{}' on disc: {}", elf_path, error.GetDescription()));
return ret;
}
const u32 size = file.getLength();
ret = std::vector<u8>();
ret->resize(size);
if (size > 0)
{
const s32 bytes_read = file.read(ret->data(), static_cast<s32>(size));
if (bytes_read != static_cast<s32>(size))
{
Console.Error(fmt::format("(Achievements) Only read {} of {} bytes of ELF '{}'", bytes_read, size, elf_path));
ret.reset();
}
}
return ret;
+104 -126
View File
@@ -19,6 +19,7 @@
#include "IopHw.h"
#include "IopDma.h"
#include "VMManager.h"
#include "Sio.h"
#include <cctype>
#include <ctime>
@@ -382,140 +383,118 @@ s32 cdvdWriteConfig(const u8* config)
return 0;
}
// Sets ElfCRC to the CRC of the game bound to the CDVD source.
std::unique_ptr<ElfObject> cdvdLoadElf(std::string filename, bool isPSXElf)
bool cdvdLoadElf(ElfObject* elfo, std::string elfpath, bool isPSXElf, Error* error)
{
if (StringUtil::StartsWith(filename, "host:"))
if (StringUtil::StartsWith(elfpath, "host:"))
{
std::string host_filename(filename.substr(5));
s64 host_size = FileSystem::GetPathFileSize(host_filename.c_str());
return std::make_unique<ElfObject>(std::move(host_filename), static_cast<u32>(std::max<s64>(host_size, 0)), isPSXElf);
std::string host_filename(elfpath.substr(5));
if (!elfo->OpenFile(host_filename, isPSXElf, error))
return false;
}
else
{
// Mimic PS2 behavior!
// Much trial-and-error with changing the ISOFS and BOOT2 contents of an image have shown that
// the PS2 BIOS performs the peculiar task of *ignoring* the version info from the parsed BOOT2
// filename *and* the ISOFS, when loading the game's ELF image. What this means is:
//
// 1. a valid PS2 ELF can have any version (ISOFS), and the version need not match the one in SYSTEM.CNF.
// 2. the version info on the file in the BOOT2 parameter of SYSTEM.CNF can be missing, 10 chars long,
// or anything else. Its all ignored.
// 3. Games loading their own files do *not* exhibit this behavior; likely due to using newer IOP modules
// or lower level filesystem APIs (fortunately that doesn't affect us).
//
// FIXME: Properly mimicing this behavior is troublesome since we need to add support for "ignoring"
// version information when doing file searches. I'll add this later. For now, assuming a ;1 should
// be sufficient (no known games have their ELF binary as anything but version ;1)
const std::string::size_type semi_pos = elfpath.rfind(';');
if (semi_pos != std::string::npos && std::string_view(elfpath).substr(semi_pos) != ";1")
{
Console.WriteLn(Color_Blue, "(LoadELF) Non-conforming version suffix (%s) detected and replaced.", elfpath.c_str());
elfpath.erase(semi_pos);
elfpath += ";1";
}
// Fix cdrom:path, the iso reader doesn't like it.
if (StringUtil::StartsWith(elfpath, "cdrom:") && elfpath[6] != '\\' && elfpath[6] != '/')
elfpath.insert(6, 1, '\\');
IsoFSCDVD isofs;
IsoFile file(isofs);
if (!file.open(elfpath, error) || !elfo->OpenIsoFile(elfpath, file, isPSXElf, error))
return false;
}
// Mimic PS2 behavior!
// Much trial-and-error with changing the ISOFS and BOOT2 contents of an image have shown that
// the PS2 BIOS performs the peculiar task of *ignoring* the version info from the parsed BOOT2
// filename *and* the ISOFS, when loading the game's ELF image. What this means is:
//
// 1. a valid PS2 ELF can have any version (ISOFS), and the version need not match the one in SYSTEM.CNF.
// 2. the version info on the file in the BOOT2 parameter of SYSTEM.CNF can be missing, 10 chars long,
// or anything else. Its all ignored.
// 3. Games loading their own files do *not* exhibit this behavior; likely due to using newer IOP modules
// or lower level filesystem APIs (fortunately that doesn't affect us).
//
// FIXME: Properly mimicing this behavior is troublesome since we need to add support for "ignoring"
// version information when doing file searches. I'll add this later. For now, assuming a ;1 should
// be sufficient (no known games have their ELF binary as anything but version ;1)
const std::string::size_type semi_pos = filename.rfind(';');
if (semi_pos != std::string::npos && std::string_view(filename).substr(semi_pos) != ";1")
{
Console.WriteLn(Color_Blue, "(LoadELF) Non-conforming version suffix (%s) detected and replaced.", filename.c_str());
filename.erase(semi_pos);
filename += ";1";
}
// Fix cdrom:path, the iso reader doesn't like it.
if (StringUtil::StartsWith(filename, "cdrom:") && filename[6] != '\\' && filename[6] != '/')
filename.insert(6, 1, '\\');
IsoFSCDVD isofs;
IsoFile file(isofs, filename);
return std::make_unique<ElfObject>(std::move(filename), file, isPSXElf);
return true;
}
u32 cdvdGetElfCRC(const std::string& path)
{
try
{
// Yay for write-after-read here. Isn't our ELF parser great....
const s64 host_size = FileSystem::GetPathFileSize(path.c_str());
if (host_size <= 0)
return 0;
std::unique_ptr<ElfObject> elfptr(std::make_unique<ElfObject>(path, static_cast<u32>(std::max<s64>(host_size, 0)), false));
elfptr->loadHeaders();
return elfptr->getCRC();
}
catch ([[maybe_unused]] Exception::FileNotFound& e)
{
ElfObject elfo;
if (!elfo.OpenFile(path, false, nullptr))
return 0;
}
return elfo.GetCRC();
}
// return value:
// 0 - Invalid or unknown disc.
// 1 - PS1 CD
// 2 - PS2 CD
static CDVDDiscType GetPS2ElfName(std::string* name, std::string* version)
{
CDVDDiscType retype = CDVDDiscType::Other;
name->clear();
version->clear();
try {
IsoFSCDVD isofs;
IsoFile file( isofs, "SYSTEM.CNF;1");
Error error;
IsoFSCDVD isofs;
IsoFile file(isofs);
if (!file.open("SYSTEM.CNF;1", &error))
{
Console.Error(fmt::format("(GetElfName) Failed to open SYSTEM.CNF: {}", error.GetDescription()));
return CDVDDiscType::Other;
}
int size = file.getLength();
if( size == 0 ) return CDVDDiscType::Other;
const int size = file.getLength();
if (size == 0)
return CDVDDiscType::Other;
while( !file.eof() )
{
const std::string line(file.readLine());
std::string_view key, value;
if (!StringUtil::ParseAssignmentString(line, &key, &value))
continue;
while (!file.eof())
{
const std::string line(file.readLine());
std::string_view key, value;
if (!StringUtil::ParseAssignmentString(line, &key, &value))
continue;
if( value.empty() && file.getLength() != file.getSeekPos() )
{ // Some games have a character on the last line of the file, don't print the error in those cases.
Console.Warning( "(SYSTEM.CNF) Unusual or malformed entry in SYSTEM.CNF ignored:" );
Console.Indent().WriteLn(line);
continue;
}
if( key == "BOOT2" )
{
Console.WriteLn( Color_StrongBlue, "(SYSTEM.CNF) Detected PS2 Disc = %.*s",
static_cast<int>(value.size()), value.data());
*name = value;
retype = CDVDDiscType::PS2Disc;
}
else if( key == "BOOT" )
{
Console.WriteLn( Color_StrongBlue, "(SYSTEM.CNF) Detected PSX/PSone Disc = %.*s",
static_cast<int>(value.size()), value.data());
*name = value;
retype = CDVDDiscType::PS1Disc;
}
else if( key == "VMODE" )
{
Console.WriteLn( Color_Blue, "(SYSTEM.CNF) Disc region type = %.*s",
static_cast<int>(value.size()), value.data());
}
else if( key == "VER" )
{
Console.WriteLn( Color_Blue, "(SYSTEM.CNF) Software version = %.*s",
static_cast<int>(value.size()), value.data());
*version = value;
}
if (value.empty() && file.getLength() != file.getSeekPos())
{ // Some games have a character on the last line of the file, don't print the error in those cases.
Console.Warning("(SYSTEM.CNF) Unusual or malformed entry in SYSTEM.CNF ignored:");
Console.Indent().WriteLn(line);
continue;
}
if( retype == CDVDDiscType::Other )
if (key == "BOOT2")
{
Console.Error("(GetElfName) Disc image is *not* a PlayStation or PS2 game!");
return CDVDDiscType::Other;
Console.WriteLn(Color_StrongBlue, fmt::format("(SYSTEM.CNF) Detected PS2 Disc = {}", value));
*name = value;
retype = CDVDDiscType::PS2Disc;
}
else if (key == "BOOT")
{
Console.WriteLn(Color_StrongBlue, fmt::format("(SYSTEM.CNF) Detected PSX/PSone Disc = {}", value));
*name = value;
retype = CDVDDiscType::PS1Disc;
}
else if (key == "VMODE")
{
Console.WriteLn(Color_Blue, fmt::format("(SYSTEM.CNF) Disc region type = {}", value));
}
else if (key == "VER")
{
Console.WriteLn(Color_Blue, fmt::format("(SYSTEM.CNF) Software version = {}", value));
*version = value;
}
}
catch( Exception::FileNotFound& )
{
//Console.Warning(ex.FormatDiagnosticMessage());
return CDVDDiscType::Other; // no SYSTEM.CNF, not a PS1/PS2 disc.
}
catch (Exception::BadStream& ex)
{
Console.Error(ex.FormatDiagnosticMessage());
return CDVDDiscType::Other; // ISO error
}
if (retype == CDVDDiscType::Other)
Console.Error("(GetElfName) Disc image is *not* a PlayStation or PS2 game!");
return retype;
}
@@ -585,21 +564,13 @@ void cdvdGetDiscInfo(std::string* out_serial, std::string* out_elf_path, std::st
if (disc_type == CDVDDiscType::PS2Disc || disc_type == CDVDDiscType::PS1Disc)
{
try
{
const bool isPSXElf = (disc_type == CDVDDiscType::PS1Disc);
std::unique_ptr<ElfObject> elfptr(cdvdLoadElf(elfpath, isPSXElf));
elfptr->loadHeaders();
crc = elfptr->getCRC();
}
catch ([[maybe_unused]] Exception::FileNotFound& e)
{
Console.Error(fmt::format("Failed to load ELF info for {}", elfpath));
}
catch (Exception::BadStream& ex)
{
Console.Error(ex.FormatDiagnosticMessage());
}
Error error;
ElfObject elfo;
const bool isPSXElf = (disc_type == CDVDDiscType::PS1Disc);
if (!cdvdLoadElf(&elfo, elfpath, isPSXElf, &error))
Console.Error(fmt::format("Failed to load ELF info for {}: {}", elfpath, error.GetDescription()));
else
crc = elfo.GetCRC();
}
*out_crc = crc;
@@ -963,10 +934,14 @@ void cdvdReset()
cdvdCtrlTrayClose();
}
void SaveStateBase::cdvdFreeze()
bool SaveStateBase::cdvdFreeze()
{
FreezeTag("cdvd");
if (!FreezeTag("cdvd"))
return false;
Freeze(cdvd);
if (!IsOkay())
return false;
if (IsLoading())
{
@@ -977,6 +952,8 @@ void SaveStateBase::cdvdFreeze()
if (cdvd.Reading)
cdvd.RErr = DoCDVDreadTrack(cdvd.Readed ? cdvd.Sector : cdvd.SeekToSector, cdvd.ReadMode);
}
return true;
}
void cdvdNewDiskCB()
@@ -1528,6 +1505,7 @@ void cdvdVsync()
cdvd.RTCcount = 0;
cdvdUpdateTrayState();
AutoEject::CountDownTicks();
cdvd.RTC.second++;
if (cdvd.RTC.second < 60)
+2 -1
View File
@@ -21,6 +21,7 @@
#include <string>
#include <string_view>
class Error;
class ElfObject;
#define btoi(b) ((b) / 16 * 10 + (b) % 16) /* BCD to u_char */
@@ -189,7 +190,7 @@ extern void cdvdWrite(u8 key, u8 rt);
extern void cdvdGetDiscInfo(std::string* out_serial, std::string* out_elf_path, std::string* out_version, u32* out_crc,
CDVDDiscType* out_disc_type);
extern u32 cdvdGetElfCRC(const std::string& path);
extern std::unique_ptr<ElfObject> cdvdLoadElf(std::string filename, bool isPSXElf);
extern bool cdvdLoadElf(ElfObject* elfo, std::string filename, bool isPSXElf, Error* error);
extern s32 cdvdCtrlTrayOpen();
extern s32 cdvdCtrlTrayClose();
+6 -34
View File
@@ -30,7 +30,6 @@
#include "IsoFileFormats.h"
#include "common/Assertions.h"
#include "common/Exceptions.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/StringUtil.h"
@@ -73,14 +72,11 @@ static void CheckNullCDVD()
static int CheckDiskTypeFS(int baseType)
{
IsoFSCDVD isofs;
try
IsoDirectory rootdir(isofs);
if (rootdir.OpenRootDirectory())
{
IsoDirectory rootdir(isofs);
try
if (IsoFile file(isofs); file.open(rootdir, "SYSTEM.CNF;1"))
{
IsoFile file(rootdir, "SYSTEM.CNF;1");
const int size = file.getLength();
const std::unique_ptr<char[]> buffer = std::make_unique<char[]>(size + 1);
file.read(buffer.get(), size);
@@ -97,40 +93,16 @@ static int CheckDiskTypeFS(int baseType)
return (baseType == CDVD_TYPE_DETCTCD) ? CDVD_TYPE_PS2CD : CDVD_TYPE_PS2DVD;
}
catch (Exception::FileNotFound&)
{
}
// PS2 Linux disc 2, doesn't have a System.CNF or a normal ELF
try
{
IsoFile file(rootdir, "P2L_0100.02;1");
if (rootdir.Exists("P2L_0100.02;1"))
return CDVD_TYPE_PS2DVD;
}
catch (Exception::FileNotFound&)
{
}
try
{
IsoFile file(rootdir, "PSX.EXE;1");
if (rootdir.Exists("PSX.EXE;1"))
return CDVD_TYPE_PSCD;
}
catch (Exception::FileNotFound&)
{
}
try
{
IsoFile file(rootdir, "VIDEO_TS/VIDEO_TS.IFO;1");
if (rootdir.Exists("VIDEO_TS/VIDEO_TS.IFO;1"))
return CDVD_TYPE_DVDV;
}
catch (Exception::FileNotFound&)
{
}
}
catch (Exception::FileNotFound&)
{
}
#ifdef PCSX2_DEVBUILD
+10 -29
View File
@@ -156,14 +156,7 @@ bool StartKeepAliveThread()
if (s_keepalive_is_open == false)
{
s_keepalive_is_open = true;
try
{
s_keepalive_thread = std::thread(keepAliveThread);
}
catch (std::system_error&)
{
s_keepalive_is_open = false;
}
s_keepalive_thread = std::thread(keepAliveThread);
}
return s_keepalive_is_open;
@@ -190,21 +183,15 @@ s32 CALLBACK DISCopen(const char* pTitle)
return -1;
// open device file
try
{
src = std::unique_ptr<IOCtlSrc>(new IOCtlSrc(drive));
}
catch (std::runtime_error&)
{
return -1;
}
//setup threading manager
if (!cdvdStartThread())
src = std::make_unique<IOCtlSrc>(std::move(drive));
if (!src->Reopen())
{
src.reset();
return -1;
}
//setup threading manager
cdvdStartThread();
StartKeepAliveThread();
return cdvdRefreshData();
@@ -312,16 +299,10 @@ s32 CALLBACK DISCgetTD(u8 Track, cdvdTD* Buffer)
{
if (src == nullptr)
return -1;
try
{
Buffer->lsn = src->GetSectorCount();
Buffer->type = 0;
return 0;
}
catch (...)
{
return -1;
}
Buffer->lsn = src->GetSectorCount();
Buffer->type = 0;
return 0;
}
if (Track < strack)
+3 -2
View File
@@ -64,12 +64,13 @@ class IOCtlSrc
bool ReadDVDInfo();
bool ReadCDInfo();
bool Reopen();
public:
IOCtlSrc(std::string filename);
~IOCtlSrc();
bool Reopen();
u32 GetSectorCount() const;
const std::vector<toc_entry>& ReadTOC() const;
bool ReadSectors2048(u32 sector, u32 count, u8* buffer) const;
@@ -90,7 +91,7 @@ extern bool weAreInNewDiskCB;
extern void (*newDiscCB)();
bool cdvdStartThread();
void cdvdStartThread();
void cdvdStopThread();
void cdvdRequestSector(u32 sector, s32 mode);
u8* cdvdGetSector(u32 sector, s32 mode);
+3 -20
View File
@@ -261,25 +261,15 @@ void cdvdThread()
printf(" * CDVD: IO thread finished.\n");
}
bool cdvdStartThread()
void cdvdStartThread()
{
if (cdvd_is_open == false)
{
cdvd_is_open = true;
try
{
s_thread = std::thread(cdvdThread);
}
catch (std::system_error&)
{
cdvd_is_open = false;
return false;
}
s_thread = std::thread(cdvdThread);
}
cdvdCacheReset();
return true;
}
void cdvdStopThread()
@@ -349,15 +339,8 @@ s32 cdvdDirectReadSector(u32 sector, s32 mode, u8* buffer)
if (src == nullptr)
return -1;
try
{
if (sector >= src->GetSectorCount())
return -1;
}
catch (...)
{
if (sector >= src->GetSectorCount())
return -1;
}
// Align to cache block
u32 sector_block = sector & ~(sectors_per_read - 1);
+2 -1
View File
@@ -24,7 +24,8 @@
#include "IsoFileFormats.h"
#include "AsyncFileReader.h"
#include "CDVD/CDVD.h"
#include "common/Exceptions.h"
#include "common/Assertions.h"
#include <cstring>
#include <array>
+2 -4
View File
@@ -29,11 +29,9 @@
#include <cerrno>
#include <cstring>
IOCtlSrc::IOCtlSrc(decltype(m_filename) filename)
: m_filename(filename)
IOCtlSrc::IOCtlSrc(std::string filename)
: m_filename(std::move(filename))
{
if (!Reopen())
throw std::runtime_error(" * CDVD: Error opening source.\n");
}
IOCtlSrc::~IOCtlSrc()
+11 -8
View File
@@ -16,26 +16,31 @@
#pragma once
#include "common/Pcsx2Defs.h"
#include <optional>
#include <string_view>
#include <vector>
class Error;
enum IsoFS_Type
{
FStype_ISO9660 = 1,
FStype_Joliet = 2,
};
class IsoDirectory
class IsoDirectory final
{
public:
SectorSource& internalReader;
std::vector<IsoFileDescriptor> files;
IsoFS_Type m_fstype;
IsoFS_Type m_fstype = FStype_ISO9660;
public:
IsoDirectory(SectorSource& r);
IsoDirectory(SectorSource& r, const IsoFileDescriptor& directoryEntry);
virtual ~IsoDirectory() = default;
~IsoDirectory();
bool OpenRootDirectory(Error* error = nullptr);
bool Open(const IsoFileDescriptor& directoryEntry, Error* error = nullptr);
std::string FStype_ToString() const;
SectorSource& GetReader() const { return internalReader; }
@@ -46,12 +51,10 @@ public:
u32 GetFileSize(const std::string_view& filePath) const;
IsoFileDescriptor FindFile(const std::string_view& filePath) const;
std::optional<IsoFileDescriptor> FindFile(const std::string_view& filePath) const;
protected:
const IsoFileDescriptor& GetEntry(const std::string_view& fileName) const;
const IsoFileDescriptor& GetEntry(int index) const;
const IsoFileDescriptor& GetEntry(size_t index) const;
void Init(const IsoFileDescriptor& directoryEntry);
int GetIndexOf(const std::string_view& fileName) const;
};
+61 -33
View File
@@ -20,7 +20,7 @@
#include "IsoFile.h"
#include "common/Assertions.h"
#include "common/Exceptions.h"
#include "common/Error.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/StringUtil.h"
@@ -51,6 +51,12 @@ std::string IsoDirectory::FStype_ToString() const
// Used to load the Root directory from an image
IsoDirectory::IsoDirectory(SectorSource& r)
: internalReader(r)
{
}
IsoDirectory::~IsoDirectory() = default;
bool IsoDirectory::OpenRootDirectory(Error* error /* = nullptr */)
{
IsoFileDescriptor rootDirEntry;
bool isValid = false;
@@ -107,22 +113,17 @@ IsoDirectory::IsoDirectory(SectorSource& r)
}
if (!isValid)
throw Exception::FileNotFound("IsoFileSystem") // FIXME: Should report the name of the ISO here...
.SetDiagMsg("IsoFS could not find the root directory on the ISO image.");
{
Error::SetString(error, "IsoFS could not find the root directory on the ISO image.");
return false;
}
DevCon.WriteLn("(IsoFS) Filesystem is %s", FStype_ToString().c_str());
Init(rootDirEntry);
return Open(rootDirEntry);
}
// Used to load a specific directory from a file descriptor
IsoDirectory::IsoDirectory(SectorSource& r, const IsoFileDescriptor& directoryEntry)
: internalReader(r)
{
m_fstype = FStype_ISO9660;
Init(directoryEntry);
}
void IsoDirectory::Init(const IsoFileDescriptor& directoryEntry)
bool IsoDirectory::Open(const IsoFileDescriptor& directoryEntry, Error* error /* = nullptr */)
{
// parse directory sector
IsoFile dataStream(internalReader, directoryEntry);
@@ -163,9 +164,10 @@ void IsoDirectory::Init(const IsoFileDescriptor& directoryEntry)
}
b[0] = 0;
return true;
}
const IsoFileDescriptor& IsoDirectory::GetEntry(int index) const
const IsoFileDescriptor& IsoDirectory::GetEntry(size_t index) const
{
return files[index];
}
@@ -178,25 +180,19 @@ int IsoDirectory::GetIndexOf(const std::string_view& fileName) const
return i;
}
throw Exception::FileNotFound(std::string(fileName));
return -1;
}
const IsoFileDescriptor& IsoDirectory::GetEntry(const std::string_view& fileName) const
{
return GetEntry(GetIndexOf(fileName));
}
IsoFileDescriptor IsoDirectory::FindFile(const std::string_view& filePath) const
std::optional<IsoFileDescriptor> IsoDirectory::FindFile(const std::string_view& filePath) const
{
if (filePath.empty())
throw Exception::FileNotFound();
return std::nullopt;
// DOS-style parser should work fine for ISO 9660 path names. Only practical difference
// is case sensitivity, and that won't matter for path splitting.
std::vector<std::string_view> parts(Path::SplitWindowsPath(filePath));
IsoFileDescriptor info;
const IsoDirectory* dir = this;
std::unique_ptr<IsoDirectory> deleteme;
IsoDirectory subdir(internalReader);
// walk through path ("." and ".." entries are in the directories themselves, so even if the
// path included . and/or .., it still works)
@@ -206,35 +202,67 @@ IsoFileDescriptor IsoDirectory::FindFile(const std::string_view& filePath) const
for (size_t index = has_device ? 1 : 0; index < (parts.size() - 1); index++)
{
info = dir->GetEntry(parts[index]);
if (info.IsFile())
throw Exception::FileNotFound(std::string(filePath));
const int subdir_index = GetIndexOf(parts[index]);
if (subdir_index < 0)
return std::nullopt;
deleteme.reset(new IsoDirectory(internalReader, info));
dir = deleteme.get();
const IsoFileDescriptor& subdir_entry = GetEntry(static_cast<size_t>(index));
if (subdir_entry.IsFile() || !subdir.Open(subdir_entry, nullptr))
return std::nullopt;
dir = &subdir;
}
info = dir->GetEntry(parts.back());
return info;
const int file_index = dir->GetIndexOf(parts.back());
if (file_index < 0)
return std::nullopt;
return GetEntry(static_cast<size_t>(file_index));
}
bool IsoDirectory::Exists(const std::string_view& filePath) const
{
if (filePath.empty())
return false;
const std::optional<IsoFileDescriptor> fd(FindFile(filePath));
return fd.has_value();
}
bool IsoDirectory::IsFile(const std::string_view& filePath) const
{
if (filePath.empty())
return false;
return (FindFile(filePath).flags & 2) != 2;
const std::optional<IsoFileDescriptor> fd(FindFile(filePath));
if (fd.has_value())
return false;
return ((fd->flags & 2) != 2);
}
bool IsoDirectory::IsDir(const std::string_view& filePath) const
{
if (filePath.empty())
return false;
return (FindFile(filePath).flags & 2) == 2;
const std::optional<IsoFileDescriptor> fd(FindFile(filePath));
if (fd.has_value())
return false;
return ((fd->flags & 2) == 2);
}
u32 IsoDirectory::GetFileSize(const std::string_view& filePath) const
{
return FindFile(filePath).size;
if (filePath.empty())
return 0;
const std::optional<IsoFileDescriptor> fd(FindFile(filePath));
if (fd.has_value())
return 0;
return fd->size;
}
IsoFileDescriptor::IsoFileDescriptor()
+1 -1
View File
@@ -17,7 +17,7 @@
class IsoFile;
class IsoDirectory;
struct ISoFileDescriptor;
struct IsoFileDescriptor;
#include "SectorSource.h"
#include "IsoFileDescriptor.h"
+1 -1
View File
@@ -19,7 +19,7 @@
#include "SectorSource.h"
class IsoFSCDVD : public SectorSource
class IsoFSCDVD final : public SectorSource
{
public:
IsoFSCDVD();
+28 -12
View File
@@ -16,26 +16,19 @@
#include "PrecompiledHeader.h"
#include "common/Assertions.h"
#include "common/Exceptions.h"
#include "common/Error.h"
#include "IsoFS.h"
#include "IsoFile.h"
#include <cstdio>
IsoFile::IsoFile(SectorSource& reader, const std::string_view& filename)
IsoFile::IsoFile(SectorSource& reader)
: internalReader(reader)
, fileEntry(IsoDirectory(reader).FindFile(filename))
{
Init();
}
IsoFile::IsoFile(const IsoDirectory& dir, const std::string_view& filename)
: internalReader(dir.GetReader())
, fileEntry(dir.FindFile(filename))
{
Init();
}
IsoFile::~IsoFile() = default;
IsoFile::IsoFile(SectorSource& reader, const IsoFileDescriptor& fileEntry)
: internalReader(reader)
@@ -51,12 +44,35 @@ void IsoFile::Init()
currentSectorNumber = fileEntry.lba;
currentOffset = 0;
sectorOffset = 0;
maxOffset = std::max<u32>(0, fileEntry.size);
maxOffset = fileEntry.size;
if (maxOffset > 0)
internalReader.readSector(currentSector, currentSectorNumber);
}
bool IsoFile::open(const IsoDirectory& dir, const std::string_view& filename, Error* error /*= nullptr*/)
{
const std::optional<IsoFileDescriptor> fd(dir.FindFile(filename));
if (!fd.has_value())
{
Error::SetString(error, fmt::format("Failed to find file '{}'", filename));
return false;
}
fileEntry = std::move(fd.value());
Init();
return true;
}
bool IsoFile::open(const std::string_view& filename, Error* error /*= nullptr*/)
{
IsoDirectory dir(internalReader);
if (!dir.OpenRootDirectory(error))
return false;
return open(dir, filename, error);
}
u32 IsoFile::seek(u32 absoffset)
{
u32 endOffset = absoffset;
@@ -142,7 +158,7 @@ void IsoFile::makeDataAvailable()
u8 IsoFile::readByte()
{
if (currentOffset >= maxOffset)
throw Exception::EndOfStream();
return 0;
makeDataAvailable();
+13 -9
View File
@@ -21,27 +21,31 @@
#include "common/Pcsx2Defs.h"
#include <string_view>
class IsoFile
class Error;
class IsoFile final
{
public:
static const int sectorLength = 2048;
protected:
SectorSource& internalReader;
IsoFileDescriptor fileEntry;
IsoFileDescriptor fileEntry = {};
u32 currentOffset;
u32 maxOffset;
u32 currentOffset = 0;
u32 maxOffset = 0;
int currentSectorNumber;
int currentSectorNumber = 0;
int sectorOffset = 0;
u8 currentSector[sectorLength];
int sectorOffset;
public:
IsoFile(const IsoDirectory& dir, const std::string_view& filename);
IsoFile(SectorSource& reader, const std::string_view& filename);
IsoFile(SectorSource& reader);
IsoFile(SectorSource& reader, const IsoFileDescriptor& fileEntry);
virtual ~IsoFile() = default;
~IsoFile();
bool open(const IsoDirectory& dir, const std::string_view& filename, Error* error = nullptr);
bool open(const std::string_view& filename, Error* error = nullptr);
u32 seek(u32 absoffset);
u32 seek(s64 offset, int mode);
+2 -4
View File
@@ -26,11 +26,9 @@
#include <climits>
#include <cstring>
IOCtlSrc::IOCtlSrc(decltype(m_filename) filename)
: m_filename(filename)
IOCtlSrc::IOCtlSrc(std::string filename)
: m_filename(std::move(filename))
{
if (!Reopen())
throw std::runtime_error(" * CDVD: Error opening source.\n");
}
IOCtlSrc::~IOCtlSrc()
-1
View File
@@ -18,7 +18,6 @@
#include "CDVD/IsoFileFormats.h"
#include "Host.h"
#include "common/Exceptions.h"
#include "common/FileSystem.h"
#include "common/StringUtil.h"
+7 -2
View File
@@ -22,6 +22,8 @@
#include "IopHw.h"
#include "IopDma.h"
#include "common/Threading.h"
//THIS ALL IS FOR THE CDROM REGISTERS HANDLING
enum cdrom_registers
@@ -1114,8 +1116,11 @@ void cdrReset()
cdReadTime = (PSXCLK / 1757) * BIAS;
}
void SaveStateBase::cdrFreeze()
bool SaveStateBase::cdrFreeze()
{
FreezeTag("cdrom");
if (!FreezeTag("cdrom"))
return false;
Freeze(cdr);
return IsOkay();
}
-2
View File
@@ -36,8 +36,6 @@
IOCtlSrc::IOCtlSrc(std::string filename)
: m_filename(std::move(filename))
{
if (!Reopen())
throw std::runtime_error(" * CDVD: Error opening source.\n");
}
IOCtlSrc::~IOCtlSrc()
+4 -1
View File
@@ -1179,7 +1179,7 @@ target_link_libraries(PCSX2_FLAGS INTERFACE
cpuinfo
zydis
ZLIB::ZLIB
PkgConfig::SOUNDTOUCH
SoundTouch::SoundTouch
PNG::PNG
LibLZMA::LibLZMA
Zstd::Zstd
@@ -1233,6 +1233,9 @@ target_include_directories(PCSX2_FLAGS INTERFACE
"${CMAKE_SOURCE_DIR}/3rdparty/xbyak"
"${FFMPEG_INCLUDE_DIRS}"
)
target_compile_definitions(PCSX2_FLAGS INTERFACE
XBYAK_NO_EXCEPTION
)
if(COMMAND target_precompile_headers)
message("Using precompiled headers.")
+1 -4
View File
@@ -1170,10 +1170,7 @@ struct Pcsx2Config
// ------------------------------------------------------------------------
struct USBOptions
{
enum : u32
{
NUM_PORTS = 2
};
static constexpr u32 NUM_PORTS = 2;
struct Port
{
+3 -1
View File
@@ -1156,7 +1156,7 @@ template u16 rcntRead32<0x01>( u32 mem );
template bool rcntWrite32<0x00>( u32 mem, mem32_t& value );
template bool rcntWrite32<0x01>( u32 mem, mem32_t& value );
void SaveStateBase::rcntFreeze()
bool SaveStateBase::rcntFreeze()
{
Freeze( counters );
Freeze( hsyncCounter );
@@ -1170,4 +1170,6 @@ void SaveStateBase::rcntFreeze()
if( IsLoading() )
cpuRcntSet();
return IsOkay();
}
+120 -94
View File
@@ -43,50 +43,79 @@ struct PSXEXEHeader
static_assert(sizeof(PSXEXEHeader) == 0x800);
#pragma pack(pop)
// All of ElfObjects functions.
ElfObject::ElfObject(std::string srcfile, IsoFile& isofile, bool isPSXElf_)
: data(isofile.getLength(), "ELF headers")
, header(*(ELF_HEADER*)data.GetPtr())
, filename(std::move(srcfile))
, isPSXElf(isPSXElf_)
ElfObject::ElfObject() = default;
ElfObject::~ElfObject() = default;
bool ElfObject::OpenIsoFile(std::string srcfile, IsoFile& isofile, bool isPSXElf_, Error* error)
{
checkElfSize(data.GetSizeInBytes());
readIso(isofile);
initElfHeaders();
const u32 length = isofile.getLength();
if (!CheckElfSize(length, error))
return false;
data.resize(length);
const s32 rsize = isofile.read(data.data(), static_cast<s32>(length));
if (rsize < static_cast<s32>(length))
{
Error::SetString(error, "Failed to read ELF from ISO");
return false;
}
filename = std::move(srcfile);
isPSXElf = isPSXElf_;
InitElfHeaders();
return true;
}
ElfObject::ElfObject(std::string srcfile, u32 hdrsize, bool isPSXElf_)
: data(hdrsize, "ELF headers")
, header(*(ELF_HEADER*)data.GetPtr())
, filename(std::move(srcfile))
, isPSXElf(isPSXElf_)
bool ElfObject::OpenFile(std::string srcfile, bool isPSXElf_, Error* error)
{
checkElfSize(data.GetSizeInBytes());
readFile();
initElfHeaders();
auto fp = FileSystem::OpenManagedCFile(srcfile.c_str(), "rb", error);
FILESYSTEM_STAT_DATA sd;
if (!fp || !FileSystem::StatFile(fp.get(), &sd))
{
Error::SetString(error, fmt::format("Failed to read ELF from '{}'", srcfile));
return false;
}
if (!isPSXElf_ && !CheckElfSize(sd.Size, error))
return false;
data.resize(static_cast<size_t>(sd.Size));
if (std::fread(data.data(), data.size(), 1, fp.get()) != 1)
{
Error::SetString(error, fmt::format("Failed to read ELF from '{}'", srcfile));
return false;
}
filename = std::move(srcfile);
isPSXElf = isPSXElf_;
InitElfHeaders();
return true;
}
void ElfObject::initElfHeaders()
void ElfObject::InitElfHeaders()
{
if (isPSXElf)
return;
DevCon.WriteLn("Initializing Elf: %d bytes", data.GetSizeInBytes());
DevCon.WriteLn("Initializing Elf: %zu bytes", data.size());
const ELF_HEADER& header = GetHeader();
if (header.e_phnum > 0)
{
if ((header.e_phoff + sizeof(ELF_PHR)) <= static_cast<u32>(data.GetSizeInBytes()))
if ((header.e_phoff + sizeof(ELF_PHR)) <= data.size())
proghead = reinterpret_cast<ELF_PHR*>(&data[header.e_phoff]);
else
Console.Error("(ELF) Program header offset %u is larger than file size %u", header.e_phoff, data.GetSizeInBytes());
Console.Error("(ELF) Program header offset %u is larger than file size %zu", header.e_phoff, data.size());
}
if (header.e_shnum > 0)
{
if ((header.e_shoff + sizeof(ELF_SHR)) <= static_cast<u32>(data.GetSizeInBytes()))
if ((header.e_shoff + sizeof(ELF_SHR)) <= data.size())
secthead = reinterpret_cast<ELF_SHR*>(&data[header.e_shoff]);
else
Console.Error("(ELF) Section header offset %u is larger than file size %u", header.e_shoff, data.GetSizeInBytes());
Console.Error("(ELF) Section header offset %u is larger than file size %zu", header.e_shoff, data.size());
}
if ((header.e_shnum > 0) && (header.e_shentsize != sizeof(ELF_SHR)))
@@ -147,49 +176,61 @@ void ElfObject::initElfHeaders()
//applyPatches();
}
bool ElfObject::hasValidPSXHeader()
bool ElfObject::HasValidPSXHeader() const
{
if (data.GetSizeInBytes() < static_cast<s64>(sizeof(PSXEXEHeader)))
if (data.size() < sizeof(PSXEXEHeader))
return false;
const PSXEXEHeader* header = reinterpret_cast<const PSXEXEHeader*>(data.GetPtr());
const PSXEXEHeader* header = reinterpret_cast<const PSXEXEHeader*>(data.data());
static constexpr char expected_id[] = {'P', 'S', '-', 'X', ' ', 'E', 'X', 'E'};
if (std::memcmp(header->id, expected_id, sizeof(expected_id)) != 0)
return false;
if (static_cast<s64>(header->file_size + sizeof(PSXEXEHeader)) > data.GetSizeInBytes())
if ((header->file_size + sizeof(PSXEXEHeader)) > data.size())
{
Console.Warning("Incorrect file size in PS-EXE header: %u bytes should not be greater than %u bytes",
header->file_size, static_cast<unsigned>(data.GetSizeInBytes() - sizeof(PSXEXEHeader)));
header->file_size, static_cast<unsigned>(data.size() - sizeof(PSXEXEHeader)));
}
return true;
}
bool ElfObject::hasProgramHeaders() { return (proghead != NULL); }
bool ElfObject::hasSectionHeaders() { return (secthead != NULL); }
bool ElfObject::hasHeaders() { return (hasProgramHeaders() && hasSectionHeaders()); }
bool ElfObject::HasProgramHeaders() const
{
return (proghead != nullptr);
}
u32 ElfObject::getEntryPoint()
bool ElfObject::HasSectionHeaders() const
{
return (secthead != nullptr);
}
bool ElfObject::HasHeaders() const
{
return (HasProgramHeaders() && HasSectionHeaders());
}
u32 ElfObject::GetEntryPoint() const
{
if (isPSXElf)
{
if (hasValidPSXHeader())
return reinterpret_cast<const PSXEXEHeader*>(data.GetPtr())->initial_pc;
if (HasValidPSXHeader())
return reinterpret_cast<const PSXEXEHeader*>(data.data())->initial_pc;
else
return 0xFFFFFFFFu;
}
else
{
return header.e_entry;
return GetHeader().e_entry;
}
}
std::pair<u32,u32> ElfObject::getTextRange()
std::pair<u32,u32> ElfObject::GetTextRange() const
{
if (isPSXElf && hasProgramHeaders())
if (!isPSXElf && HasProgramHeaders())
{
const ELF_HEADER& header = GetHeader();
for (int i = 0; i < header.e_phnum; i++)
{
const u32 start = proghead[i].p_vaddr;
@@ -203,62 +244,36 @@ std::pair<u32,u32> ElfObject::getTextRange()
return std::make_pair(0,0);
}
void ElfObject::readIso(IsoFile& file)
bool ElfObject::CheckElfSize(s64 size, Error* error)
{
int rsize = file.read(data.GetPtr(), data.GetSizeInBytes());
if (rsize < data.GetSizeInBytes()) throw Exception::EndOfStream(filename);
if (size > 0xfffffff)
Error::SetString(error, "Illegal ELF file size over 2GB!");
else if (size == -1)
Error::SetString(error, "ELF file does not exist!");
else if (size <= static_cast<s64>(sizeof(ELF_HEADER)))
Error::SetString(error, "Unexpected end of ELF file.");
else
return true;
return false;
}
void ElfObject::readFile()
{
int rsize = 0;
FILE *f = FileSystem::OpenCFile( filename.c_str(), "rb");
if (f == NULL) throw Exception::FileNotFound(filename);
fseek(f, 0, SEEK_SET);
rsize = fread(data.GetPtr(), 1, data.GetSizeInBytes(), f);
fclose( f );
if (rsize < data.GetSizeInBytes()) throw Exception::EndOfStream(filename);
}
static std::string GetMsg_InvalidELF()
{
return
"Cannot load ELF binary image. The file may be corrupt or incomplete."
"\n\n"
"If loading from an ISO image, this error may be caused by an unsupported ISO image type or a bug in PCSX2 ISO image support.";
}
void ElfObject::checkElfSize(s64 elfsize)
{
const char* diagMsg = NULL;
if (elfsize > 0xfffffff) diagMsg = "Illegal ELF file size over 2GB!";
else if (elfsize == -1) diagMsg = "ELF file does not exist!";
else if (elfsize == 0) diagMsg = "Unexpected end of ELF file.";
if (diagMsg)
throw Exception::BadStream(filename)
.SetDiagMsg(diagMsg)
.SetUserMsg(GetMsg_InvalidELF());
}
u32 ElfObject::getCRC()
u32 ElfObject::GetCRC() const
{
u32 CRC = 0;
const u32* srcdata = (u32*)data.GetPtr();
for(u32 i=data.GetSizeInBytes()/4; i; --i, ++srcdata)
const u32* srcdata = reinterpret_cast<const u32*>(data.data());
for (u32 i = static_cast<u32>(data.size()) / 4; i; --i, ++srcdata)
CRC ^= *srcdata;
return CRC;
}
void ElfObject::loadProgramHeaders()
void ElfObject::LoadProgramHeaders()
{
if (proghead == NULL) return;
const ELF_HEADER& header = GetHeader();
for( int i = 0 ; i < header.e_phnum ; i++ )
{
ELF_LOG( "Elf32 Program Header" );
@@ -289,11 +304,17 @@ void ElfObject::loadProgramHeaders()
}
}
void ElfObject::loadSectionHeaders()
void ElfObject::LoadSectionHeaders()
{
if (secthead == NULL || header.e_shoff > (u32)data.GetLength()) return;
const ELF_HEADER& header = GetHeader();
if (!secthead || header.e_shoff > data.size())
return;
const u8* sections_names = data.GetPtr( secthead[ (header.e_shstrndx == 0xffff ? 0 : header.e_shstrndx) ].sh_offset );
// This function scares me a lot. There's a lot of potential for buffer overreads.
// All the accesses should be wrapped in bounds checked read() calls.
const u32 section_names_offset = secthead[(header.e_shstrndx == 0xffff ? 0 : header.e_shstrndx)].sh_offset;
const u8* sections_names = data.data() + section_names_offset;
int i_st = -1, i_dt = -1;
@@ -343,28 +364,33 @@ void ElfObject::loadSectionHeaders()
if ((i_st >= 0) && (i_dt >= 0))
{
const char * SymNames;
Elf32_Sym * eS;
const char* SymNames;
Elf32_Sym* eS;
SymNames = (char*)data.GetPtr(secthead[i_dt].sh_offset);
eS = (Elf32_Sym*)data.GetPtr(secthead[i_st].sh_offset);
Console.WriteLn("found %d symbols", secthead[i_st].sh_size / sizeof(Elf32_Sym));
if (secthead[i_dt].sh_offset < data.size() &&
secthead[i_st].sh_offset < data.size())
{
SymNames = (char*)(data.data() + secthead[i_dt].sh_offset);
eS = (Elf32_Sym*)(data.data() + secthead[i_st].sh_offset);
Console.WriteLn("found %d symbols", secthead[i_st].sh_size / sizeof(Elf32_Sym));
R5900SymbolMap.Clear();
for(uint i = 1; i < (secthead[i_st].sh_size / sizeof(Elf32_Sym)); i++) {
if ((eS[i].st_value != 0) && (ELF32_ST_TYPE(eS[i].st_info) == 2))
R5900SymbolMap.Clear();
for (uint i = 1; i < (secthead[i_st].sh_size / sizeof(Elf32_Sym)); i++)
{
R5900SymbolMap.AddLabel(&SymNames[eS[i].st_name],eS[i].st_value);
if ((eS[i].st_value != 0) && (ELF32_ST_TYPE(eS[i].st_info) == 2))
{
R5900SymbolMap.AddLabel(&SymNames[eS[i].st_name], eS[i].st_value);
}
}
}
}
}
void ElfObject::loadHeaders()
void ElfObject::LoadHeaders()
{
if (isPSXElf)
return;
loadProgramHeaders();
loadSectionHeaders();
LoadProgramHeaders();
LoadSectionHeaders();
}
+33 -29
View File
@@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2010 PCSX2 Dev Team
* 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-
@@ -15,10 +15,10 @@
#pragma once
#include "common/SafeArray.h"
#include "common/SafeArray.inl"
#include "common/Error.h"
#include "CDVD/IsoFS/IsoFSCDVD.h"
#include "CDVD/IsoFS/IsoFS.h"
#include <vector>
struct ELF_HEADER {
u8 e_ident[16]; //0x7f,"ELF" (ELF file identifier)
@@ -118,39 +118,43 @@ struct Elf32_Rel {
u32 r_info;
};
class ElfObject
class ElfObject final
{
private:
SafeArray<u8> data;
ELF_HEADER& header;
ELF_PHR* proghead = nullptr;
ELF_SHR* secthead = nullptr;
std::string filename;
bool isPSXElf;
public:
ElfObject();
ElfObject(const ElfObject&) = delete;
~ElfObject();
void initElfHeaders();
bool hasValidPSXHeader();
void readIso(IsoFile& file);
void readFile();
void checkElfSize(s64 elfsize);
__fi const ELF_HEADER& GetHeader() const { return *reinterpret_cast<const ELF_HEADER*>(data.data()); }
__fi u32 GetSize() const { return static_cast<u32>(data.size()); }
public:
ElfObject(std::string srcfile, IsoFile& isofile, bool isPSXElf_);
ElfObject(std::string srcfile, u32 hdrsize, bool isPSXElf_);
bool OpenFile(std::string srcfile, bool isPSXElf_, Error* error);
bool OpenIsoFile(std::string srcfile, IsoFile& isofile, bool isPSXElf_, Error* error);
bool IsPSXElf() const { return isPSXElf; }
void LoadHeaders();
void loadProgramHeaders();
void loadSectionHeaders();
void loadHeaders();
bool HasProgramHeaders() const;
bool HasSectionHeaders() const;
bool HasHeaders() const;
bool hasProgramHeaders();
bool hasSectionHeaders();
bool hasHeaders();
std::pair<u32, u32> GetTextRange() const;
u32 GetEntryPoint() const;
u32 GetCRC() const;
std::pair<u32,u32> getTextRange();
u32 getEntryPoint();
u32 getCRC();
private:
std::vector<u8> data;
ELF_PHR* proghead = nullptr;
ELF_SHR* secthead = nullptr;
std::string filename;
bool isPSXElf;
bool CheckElfSize(s64 size, Error* error);
void InitElfHeaders();
void LoadProgramHeaders();
void LoadSectionHeaders();
bool HasValidPSXHeader() const;
};
//-------------------
+2 -1
View File
@@ -372,9 +372,10 @@ void gsPostVsyncStart()
MTGS::PostVsyncStart(registers_written);
}
void SaveStateBase::gsFreeze()
bool SaveStateBase::gsFreeze()
{
FreezeMem(PS2MEM_GS, 0x2000);
Freeze(gsVideoMode);
return IsOkay();
}
+22 -92
View File
@@ -342,52 +342,24 @@ void GSclose()
void GSreset(bool hardware_reset)
{
try
{
g_gs_renderer->Reset(hardware_reset);
}
catch (GSRecoverableError)
{
}
g_gs_renderer->Reset(hardware_reset);
}
void GSgifSoftReset(u32 mask)
{
try
{
g_gs_renderer->SoftReset(mask);
}
catch (GSRecoverableError)
{
}
g_gs_renderer->SoftReset(mask);
}
void GSwriteCSR(u32 csr)
{
try
{
g_gs_renderer->WriteCSR(csr);
}
catch (GSRecoverableError)
{
}
g_gs_renderer->WriteCSR(csr);
}
void GSInitAndReadFIFO(u8* mem, u32 size)
{
GL_PERF("Init and read FIFO %u qwc", size);
try
{
g_gs_renderer->InitReadFIFO(mem, size);
g_gs_renderer->ReadFIFO(mem, size);
}
catch (GSRecoverableError)
{
}
catch (const std::bad_alloc&)
{
fprintf(stderr, "GS: Memory allocation error\n");
}
g_gs_renderer->InitReadFIFO(mem, size);
g_gs_renderer->ReadFIFO(mem, size);
}
void GSReadLocalMemoryUnsync(u8* mem, u32 qwc, u64 BITBLITBUF, u64 TRXPOS, u64 TRXREG)
@@ -397,89 +369,47 @@ void GSReadLocalMemoryUnsync(u8* mem, u32 qwc, u64 BITBLITBUF, u64 TRXPOS, u64 T
void GSgifTransfer(const u8* mem, u32 size)
{
try
{
g_gs_renderer->Transfer<3>(mem, size);
}
catch (GSRecoverableError)
{
}
g_gs_renderer->Transfer<3>(mem, size);
}
void GSgifTransfer1(u8* mem, u32 addr)
{
try
{
g_gs_renderer->Transfer<0>(const_cast<u8*>(mem) + addr, (0x4000 - addr) / 16);
}
catch (GSRecoverableError)
{
}
g_gs_renderer->Transfer<0>(const_cast<u8*>(mem) + addr, (0x4000 - addr) / 16);
}
void GSgifTransfer2(u8* mem, u32 size)
{
try
{
g_gs_renderer->Transfer<1>(const_cast<u8*>(mem), size);
}
catch (GSRecoverableError)
{
}
g_gs_renderer->Transfer<1>(const_cast<u8*>(mem), size);
}
void GSgifTransfer3(u8* mem, u32 size)
{
try
{
g_gs_renderer->Transfer<2>(const_cast<u8*>(mem), size);
}
catch (GSRecoverableError)
{
}
g_gs_renderer->Transfer<2>(const_cast<u8*>(mem), size);
}
void GSvsync(u32 field, bool registers_written)
{
try
{
g_gs_renderer->VSync(field, registers_written, g_gs_renderer->IsIdleFrame());
}
catch (GSRecoverableError)
{
}
catch (const std::bad_alloc&)
{
fprintf(stderr, "GS: Memory allocation error\n");
}
g_gs_renderer->VSync(field, registers_written, g_gs_renderer->IsIdleFrame());
}
int GSfreeze(FreezeAction mode, freezeData* data)
{
try
if (mode == FreezeAction::Save)
{
if (mode == FreezeAction::Save)
{
return g_gs_renderer->Freeze(data, false);
}
else if (mode == FreezeAction::Size)
{
return g_gs_renderer->Freeze(data, true);
}
else if (mode == FreezeAction::Load)
{
// Since Defrost doesn't do a hardware reset (since it would be clearing
// local memory just before it's overwritten), we have to manually wipe
// out the current textures.
g_gs_device->ClearCurrent();
return g_gs_renderer->Defrost(data);
}
return g_gs_renderer->Freeze(data, false);
}
catch (GSRecoverableError)
else if (mode == FreezeAction::Size)
{
return g_gs_renderer->Freeze(data, true);
}
else // if (mode == FreezeAction::Load)
{
// Since Defrost doesn't do a hardware reset (since it would be clearing
// local memory just before it's overwritten), we have to manually wipe
// out the current textures.
g_gs_device->ClearCurrent();
return g_gs_renderer->Defrost(data);
}
return 0;
}
void GSQueueSnapshot(const std::string& path, u32 gsdump_frames)
-7
View File
@@ -119,13 +119,6 @@ bool GSSaveSnapshotToMemory(u32 window_width, u32 window_height, bool apply_aspe
u32* width, u32* height, std::vector<u32>* pixels);
void GSJoinSnapshotThreads();
struct GSError
{
};
struct GSRecoverableError : GSError
{
};
namespace Host
{
/// Called when the GS is creating a render device.
+1 -1
View File
@@ -30,7 +30,7 @@ GSClut::GSClut(GSLocalMemory* mem)
// 1k + 1k for mirrored area simulating wrapping memory
m_clut = static_cast<u16*>(_aligned_malloc(CLUT_ALLOC_SIZE, VECTOR_ALIGNMENT));
if (!m_clut)
throw std::bad_alloc();
pxFailRel("Failed to allocate CLUT storage.");
m_buff32 = reinterpret_cast<u32*>(reinterpret_cast<u8*>(m_clut) + 2048); // 1k
m_buff64 = reinterpret_cast<u64*>(reinterpret_cast<u8*>(m_clut) + 4096); // 2k
+11 -1
View File
@@ -65,7 +65,7 @@ GSLocalMemory::GSLocalMemory()
{
m_vm8 = (u8*)GSAllocateWrappedMemory(m_vmsize, 4);
if (!m_vm8)
throw std::bad_alloc();
pxFailRel("Failed to allocate GS memory storage.");
memset(m_vm8, 0, m_vmsize);
@@ -485,6 +485,16 @@ u32 GSLocalMemory::GetEndBlockAddress(u32 bp, u32 bw, u32 psm, GSVector4i rect)
return result;
}
GSVector4i GSLocalMemory::GetRectForPageOffset(u32 base_bp, u32 offset_bp, u32 bw, u32 psm)
{
pxAssert((base_bp % BLOCKS_PER_PAGE) == 0 && (offset_bp % BLOCKS_PER_PAGE) == 0);
const u32 page_offset = (offset_bp - base_bp) >> 5;
const GSVector2i& pgs = m_psm[psm].pgs;
const GSVector2i page_offset_xy = GSVector2i(page_offset % bw, page_offset / bw);
return GSVector4i(pgs * page_offset_xy).xyxy() + GSVector4i::loadh(pgs);
}
///////////////////
void GSLocalMemory::ReadTexture(const GSOffset& off, const GSVector4i& r, u8* dst, int dstpitch, const GIFRegTEXA& TEXA)

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