mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-08-24 22:54:37 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fac171fa95 | ||
|
|
fa1b6493da | ||
|
|
e58766745c | ||
|
|
d8a9c5b479 | ||
|
|
9a4d8ba934 | ||
|
|
ab816543c8 | ||
|
|
37ccd81985 | ||
|
|
42dad4ade8 | ||
|
|
b2ac035862 | ||
|
|
f42d7eec74 | ||
|
|
e4ef41f86a | ||
|
|
103dd3954a | ||
|
|
2f9577a28e | ||
|
|
33ec4d9430 | ||
|
|
209f09ca7a | ||
|
|
2e6af75f1d | ||
|
|
f68122a380 | ||
|
|
d51bdccf7f | ||
|
|
7d8377b133 | ||
|
|
80d3a8a757 | ||
|
|
2e6c5cde29 | ||
|
|
0f2768dca4 | ||
|
|
d5be095482 | ||
|
|
b315625a94 | ||
|
|
6b51462fa0 | ||
|
|
373e698545 | ||
|
|
3b309c6d4e | ||
|
|
8e93e9f516 | ||
|
|
ac8582eca7 | ||
|
|
e6f72fdde7 | ||
|
|
9166218d07 | ||
|
|
c0b1bde94b | ||
|
|
756a679262 | ||
|
|
13b19b35c0 | ||
|
|
cadb70d1e4 | ||
|
|
4cb4844e8d | ||
|
|
556c7ca080 | ||
|
|
962db4bfc4 | ||
|
|
da651cabe4 | ||
|
|
e03076c6ff | ||
|
|
122968e63a | ||
|
|
6beac26727 | ||
|
|
3073281d13 | ||
|
|
0e0e23eefb | ||
|
|
bcec38bd97 | ||
|
|
bd706f99b2 | ||
|
|
501af632f7 | ||
|
|
a143122804 | ||
|
|
92aa426bba | ||
|
|
96a1ce2fb2 | ||
|
|
c203a09435 | ||
|
|
c4084b4162 | ||
|
|
2a7c948a57 | ||
|
|
46912595ea | ||
|
|
120ee6c673 | ||
|
|
112238fbd7 | ||
|
|
38e288ef6a | ||
|
|
35322cf49b | ||
|
|
8d44e1af0e | ||
|
|
16af078b3b | ||
|
|
3e968b4390 | ||
|
|
0029dac32d | ||
|
|
a083343c6e | ||
|
|
c277ee1d34 | ||
|
|
ebe8592a8d | ||
|
|
6c3e357d9e | ||
|
|
64455620e8 | ||
|
|
fc799778de | ||
|
|
e04e0e38d1 | ||
|
|
8d6569be95 | ||
|
|
8b086a3898 | ||
|
|
a4b8c33cf3 | ||
|
|
1d37ba47f4 | ||
|
|
8d480c28ce | ||
|
|
6e38f40f96 | ||
|
|
017c37f212 | ||
|
|
6eee4cb38a | ||
|
|
1f6a14261c | ||
|
|
14e8d840ff | ||
|
|
125b9ea1e1 | ||
|
|
e6b1e1948e | ||
|
|
ba1072f470 | ||
|
|
1fb29de082 | ||
|
|
f79e5ab559 | ||
|
|
c3a9fd469e | ||
|
|
c8abc909fa | ||
|
|
401a9f4c62 | ||
|
|
f1edb0c960 | ||
|
|
d73335e4d3 | ||
|
|
7a554be7a7 | ||
|
|
31b6ff6046 | ||
|
|
38ab0630e6 | ||
|
|
b5fa9deb30 | ||
|
|
4e8bae1703 | ||
|
|
464ce1c3cd | ||
|
|
bb55c320c1 | ||
|
|
af585bffa9 | ||
|
|
bde4868b67 | ||
|
|
3835fc5ad1 | ||
|
|
7b815b5f07 | ||
|
|
754c6126b1 | ||
|
|
2dc2a32e45 | ||
|
|
7a579303b9 | ||
|
|
03401e377b | ||
|
|
ff4ec6d843 | ||
|
|
0dc3dcd9ed | ||
|
|
ed3237f808 | ||
|
|
9321c3c334 | ||
|
|
adc7d41183 | ||
|
|
4ca69d8818 | ||
|
|
cca52e271b | ||
|
|
a2e15bbc87 | ||
|
|
9d6ad0303c | ||
|
|
bbaa23c22d | ||
|
|
bacb860cc1 | ||
|
|
7a4191e16d | ||
|
|
0fa620e3ba | ||
|
|
96642d8bc3 | ||
|
|
8a26c3783a | ||
|
|
d2742a177c | ||
|
|
6d4713e069 | ||
|
|
342170b077 | ||
|
|
df02d784d6 | ||
|
|
340874996e | ||
|
|
3bd89154d3 |
@@ -0,0 +1,81 @@
|
||||
# Docs - https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema
|
||||
name: Application Bug Report
|
||||
description: Found a problem with the application itself (ie. bad file path handling, UX issue)? Help us improve it.
|
||||
title: "[BUG]: "
|
||||
labels: [Bug]
|
||||
# assignees:
|
||||
# - octocat
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
## Important: Read First
|
||||
|
||||
Please do not make support requests on GitHub. Our issue tracker is for tracking bugs and feature requests only
|
||||
If you need help configuring the emulator please make a request on our forums or contact us on discord
|
||||
|
||||
If you are unsure, start with [discord](https://discord.com/invite/TCz3t9k) or the [forums](https://forums.pcsx2.net/index.php)
|
||||
|
||||
Please make an effort to make sure your issue isn't already reported
|
||||
|
||||
### Please Avoid Issues Pertaining to the Following:
|
||||
- We are **not** accepting bug reports for **PSX mode** at this time
|
||||
- If you are interested in helping contribute to PSX mode please do so on the forums. Otherwise our recommendation is that you use a [proper PSX emulator](https://emulation.gametechwiki.com/index.php/PlayStation_emulators)
|
||||
- We do **not** accept issues relating to **upscaling** at this time
|
||||
- We are aware of the various problems with upscaling. The issue spans many games and having hundreds of issues for the same fundamental issues isn't particularly helpful. There are several workarounds for graphical problems that come as a result of upscaling
|
||||
- Please try your game at native resolution before creating an issue
|
||||
- If your bug is the result of upscaling please use the forums or discord for assistance with various upscaling workarounds. Additionally, the unofficial PCSX2 [Wiki](https://wiki.pcsx2.net/Main_Page) often lists various fixes for upscaling issues
|
||||
- type: textarea
|
||||
id: desc
|
||||
attributes:
|
||||
label: Describe the Bug
|
||||
description: "A clear and concise description of what the bug is"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: repro
|
||||
attributes:
|
||||
label: Reproduction Steps
|
||||
description: "Steps to reproduce the behavior"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: expect
|
||||
attributes:
|
||||
label: Expected Behavior
|
||||
description: "A clear and concise description of what you expected to happen"
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: rev
|
||||
attributes:
|
||||
label: PCSX2 Revision
|
||||
description: "Please ensure you are on the latest version before making an issue"
|
||||
placeholder: "Example: v1.7.1337"
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating System
|
||||
options:
|
||||
- Windows 11
|
||||
- Windows 10 (32bit)
|
||||
- Windows 10 (64bit)
|
||||
- Windows 8.1 (32bit)
|
||||
- Windows 8.1 (64bit)
|
||||
- Linux (32bit) - Specify Distro Below
|
||||
- Linux (64bit) - Specify Distro Below
|
||||
- macOS (Monteray)
|
||||
- macOS (BigSur)
|
||||
- macOS (Catalina)
|
||||
- macOS (Mojave)
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: os-distro
|
||||
attributes:
|
||||
label: If Linux - Specify Distro
|
||||
placeholder: "Example: Arch"
|
||||
validations:
|
||||
required: false
|
||||
@@ -1,6 +1,6 @@
|
||||
# Docs - https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema
|
||||
name: Bug Report
|
||||
description: Found a problem? Help us improve.
|
||||
name: Emulation Bug Report
|
||||
description: Problem in a game (ie. graphical artifacts, crashes)? Help us improve it.
|
||||
title: "[BUG]: "
|
||||
labels: [Bug]
|
||||
# assignees:
|
||||
@@ -69,7 +69,7 @@ body:
|
||||
attributes:
|
||||
label: PCSX2 Revision
|
||||
description: "We only accept bug reports for the latest dev version. Please try upgrading before making an issue."
|
||||
placeholder: "Example: dev-525"
|
||||
placeholder: "Example: v1.7.1337"
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
@@ -77,6 +77,7 @@ body:
|
||||
attributes:
|
||||
label: Operating System
|
||||
options:
|
||||
- Windows 11
|
||||
- Windows 10 (32bit)
|
||||
- Windows 10 (64bit)
|
||||
- Windows 8.1 (32bit)
|
||||
@@ -84,7 +84,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
continue-on-error: ${{ matrix.experimental }}
|
||||
# Set some sort of timeout in the event of run-away builds. We are limited on concurrent jobs so, get rid of them.
|
||||
timeout-minutes: 30
|
||||
timeout-minutes: 60
|
||||
|
||||
env:
|
||||
CCACHE_BASEDIR: ${{ github.workspace }}
|
||||
@@ -118,7 +118,7 @@ jobs:
|
||||
message("::set-output name=timestamp::${current_date}")
|
||||
|
||||
- name: ccache cache files
|
||||
uses: actions/cache@v2.1.6
|
||||
uses: actions/cache@v2.1.7
|
||||
with:
|
||||
path: .ccache
|
||||
key: ${{ matrix.os }} ${{ matrix.platform }} ${{ matrix.compiler }}${{ matrix.detail }} ccache ${{ steps.ccache_cache_timestamp.outputs.timestamp }}
|
||||
|
||||
@@ -99,7 +99,7 @@ jobs:
|
||||
run: |
|
||||
# To save time, only brew update if running the install without it fails
|
||||
function do-install() {
|
||||
brew install sound-touch portaudio wxmac sdl2 libsamplerate
|
||||
brew install sound-touch portaudio wxwidgets sdl2 libsamplerate
|
||||
}
|
||||
if ! do-install; then
|
||||
brew update
|
||||
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
# - https://github.community/t/github-actions-workflow-not-triggering-with-tag-push/17053/7
|
||||
- name: Bump Version and Push Tag
|
||||
id: tag_version
|
||||
uses: mathieudutour/github-tag-action@v5.6
|
||||
uses: mathieudutour/github-tag-action@v6.0
|
||||
with:
|
||||
github_token: ${{ secrets.BOT_PAT }}
|
||||
tag_prefix: v
|
||||
|
||||
@@ -49,9 +49,8 @@ chmod a+x ./squashfs-root/usr/optional/exec.so
|
||||
echo "$name" > "$GITHUB_WORKSPACE"/squashfs-root/version.txt
|
||||
mkdir -p "$GITHUB_WORKSPACE"/squashfs-root/usr/bin/app
|
||||
cp -r "$GITHUB_WORKSPACE"/bin/Langs "$GITHUB_WORKSPACE"/squashfs-root/usr/bin/
|
||||
cp -r "$GITHUB_WORKSPACE"/bin/resources "$GITHUB_WORKSPACE"/squashfs-root/usr/bin/app/
|
||||
cp "$GITHUB_WORKSPACE"/bin/docs/{Configuration_Guide.pdf,PCSX2_FAQ.pdf} "$GITHUB_WORKSPACE"/squashfs-root/usr/bin/app
|
||||
cp "$GITHUB_WORKSPACE"/bin/cheats_ws.zip "$GITHUB_WORKSPACE"/squashfs-root/usr/bin/app
|
||||
cp ./bin/GameIndex.yaml "$GITHUB_WORKSPACE"/squashfs-root/usr/bin/app/GameIndex.yaml
|
||||
cp /usr/lib/$LIBARCH/libthai.so.0 "$GITHUB_WORKSPACE"/squashfs-root/usr/lib/
|
||||
cp --dereference /usr/lib/"$LIBARCH"/libstdc++.so.6 "$GITHUB_WORKSPACE"/squashfs-root/usr/optional/libstdc++/libstdc++.so.6
|
||||
cp --dereference /lib/"$LIBARCH"/libgcc_s.so.1 "$GITHUB_WORKSPACE"/squashfs-root/usr/optional/libgcc_s/libgcc_s.so.1
|
||||
|
||||
@@ -20,6 +20,7 @@ cmake \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DPACKAGE_MODE=TRUE \
|
||||
-DWAYLAND_API=TRUE \
|
||||
-DDISABLE_ADVANCE_SIMD=TRUE \
|
||||
-DCMAKE_INSTALL_LIBDIR="/tmp/" \
|
||||
-DCMAKE_INSTALL_DATADIR="/tmp/" \
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
import { MessageEmbed, WebhookClient } from "discord.js";
|
||||
import * as github from '@actions/github';
|
||||
|
||||
const assets = github.context.payload.release.assets;
|
||||
const releaseInfo = github.context.payload.release;
|
||||
|
||||
if (!releaseInfo.prerelease) {
|
||||
console.log("Not announcing - release was not a pre-release (aka a Nightly)");
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const assets = releaseInfo.assets;
|
||||
let windowsAssetLinks = "";
|
||||
let linuxAssetLinks = "";
|
||||
|
||||
@@ -34,10 +41,10 @@ const embed = new MessageEmbed()
|
||||
.setColor('#FF8000')
|
||||
.setTitle('New PCSX2 Nightly Build Available!')
|
||||
.addFields(
|
||||
{ name: 'Version', value: github.context.payload.release.tag_name, inline: true },
|
||||
{ name: 'Release Link', value: `[Github Release](${github.context.payload.release.html_url})`, inline: true },
|
||||
{ name: 'Version', value: releaseInfo.tag_name, inline: true },
|
||||
{ name: 'Release Link', value: `[Github Release](${releaseInfo.html_url})`, inline: true },
|
||||
{ name: 'Installation Steps', value: '[See Here](https://github.com/PCSX2/pcsx2/wiki/Nightly-Build-Usage-Guide)', inline: true },
|
||||
{ name: 'Included Changes', value: github.context.payload.release.body, inline: false }
|
||||
{ name: 'Included Changes', value: releaseInfo.body, inline: false }
|
||||
);
|
||||
|
||||
if (windowsAssetLinks != "") {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import yaml
|
||||
|
||||
# Assumes this is ran from the root of the repository
|
||||
file_path = "./bin/GameIndex.yaml"
|
||||
file_path = "./bin/resources/GameIndex.yaml"
|
||||
|
||||
# These settings have to be manually kept in sync with the emulator code unfortunately.
|
||||
# up to date validation should ALWAYS be provided via the application!
|
||||
|
||||
@@ -79,6 +79,7 @@ oprofile_data/
|
||||
/bin/PCSX2-linux.sh
|
||||
/bin/GS*.txt
|
||||
/bin/bios
|
||||
/bin/cache
|
||||
/bin/dumps
|
||||
/bin/help
|
||||
/bin/inis
|
||||
|
||||
+4
-13
@@ -1,13 +1,9 @@
|
||||
# Project Name
|
||||
project(Pcsx2)
|
||||
|
||||
# Debian-based distributions require at least 2.8.5 due to multiarch.
|
||||
# Bumping up to 3.0 seems reasonable at this point, and will let us modernize
|
||||
# things a bit.
|
||||
#
|
||||
# Setting it to a range tells it that it supports the features on the newer
|
||||
# versions as well, avoiding setting policies.
|
||||
cmake_minimum_required(VERSION 3.10...3.17)
|
||||
cmake_minimum_required(VERSION 3.11...3.22)
|
||||
|
||||
# Project Name
|
||||
project(Pcsx2)
|
||||
|
||||
# Variable to check that people use the good file
|
||||
set(TOP_CMAKE_WAS_SOURCED TRUE)
|
||||
@@ -58,11 +54,6 @@ endif()
|
||||
|
||||
# Install some files to ease package creation
|
||||
if(PACKAGE_MODE)
|
||||
if(NOT DISABLE_CHEATS_ZIP)
|
||||
INSTALL(FILES "${CMAKE_SOURCE_DIR}/bin/cheats_ws.zip" DESTINATION "${CMAKE_INSTALL_DATADIR}/PCSX2")
|
||||
endif()
|
||||
INSTALL(FILES "${CMAKE_SOURCE_DIR}/bin/GameIndex.yaml" DESTINATION "${CMAKE_INSTALL_DATADIR}/PCSX2")
|
||||
|
||||
# set categories depending on system/distribution in pcsx2.desktop
|
||||
if(openSUSE)
|
||||
set(PCSX2_MENU_CATEGORIES "System;Emulator;")
|
||||
|
||||
@@ -15,7 +15,7 @@ The latest officially released stable version is version 1.6.0.
|
||||
|
||||
Installers and binaries for both Windows and Linux are available from [our website](https://pcsx2.net/download.html).
|
||||
|
||||
Development builds are also available from [our website](https://pcsx2.net/download/development.html).
|
||||
Development builds are also available from [Github](https://github.com/PCSX2/pcsx2/releases).
|
||||
|
||||
## System Requirements
|
||||
|
||||
|
||||
@@ -57,8 +57,6 @@ Sys_TakeSnapshot = F8
|
||||
Sys_RenderswitchToggle = F9
|
||||
|
||||
Sys_LoggingToggle = F10
|
||||
# The FreezeGS function is currently disabled internally.
|
||||
Sys_FreezeGS = F11
|
||||
Sys_RecordingToggle = F12
|
||||
|
||||
GSwindow_CycleAspectRatio = F6
|
||||
|
||||
@@ -48,6 +48,12 @@ PAPX-90223:
|
||||
PAPX-90231:
|
||||
name: "Kaitou Sly Cooper [Demo, Taikenban]"
|
||||
region: "NTSC-J"
|
||||
PAPX-90506:
|
||||
name: "Dark Chronicle[Demo, Taikenban]"
|
||||
region: "NTSC-J"
|
||||
compat: 5
|
||||
clampModes:
|
||||
eeClampMode: 3 # Fixes textbox.
|
||||
PAPX-90512:
|
||||
name: "Gran Turismo 4 - Toyota Prius [Trial]"
|
||||
region: "NTSC-J"
|
||||
@@ -1408,6 +1414,11 @@ SCED-51700:
|
||||
region: "PAL-M5"
|
||||
gameFixes:
|
||||
- VUKickstartHack # Fixes Character SPS.
|
||||
SCED-51922:
|
||||
name: "Ghosthunter [Demo]"
|
||||
region: "PAL-G"
|
||||
clampModes:
|
||||
vuClampMode: 3 # Fixes SPS.
|
||||
SCED-51935:
|
||||
name: "Official PlayStation 2 Magazine Demo 38" # German
|
||||
region: "PAL-E-G"
|
||||
@@ -1736,6 +1747,13 @@ SCED-53325:
|
||||
SCED-53348:
|
||||
name: "Official PlayStation 2 Magazine Demo 58" # French
|
||||
region: "PAL-F"
|
||||
SCED-53679:
|
||||
name: "Fire It Up Lads Demo"
|
||||
region: "PAL-E"
|
||||
patches:
|
||||
default:
|
||||
content: |-
|
||||
comment=- WRC Rally needs XGKick fix enabled
|
||||
SCED-53684:
|
||||
name: "SingStar '80s [Demo]"
|
||||
region: "PAL-E"
|
||||
@@ -2326,9 +2344,10 @@ SCES-51135:
|
||||
region: "PAL-M5"
|
||||
compat: 5
|
||||
roundModes:
|
||||
vuRoundMode: 0 # Fixes SPS.
|
||||
vuRoundMode: 1 # Fixes SPS.
|
||||
eeRoundMode: 0 # Fixes textures on the doors.
|
||||
clampModes:
|
||||
vuClampMode: 2 # Fix other SPS.
|
||||
vuClampMode: 0 # Fix other SPS.
|
||||
gameFixes:
|
||||
- VUKickstartHack # Fixes objects disappearing.
|
||||
SCES-51159:
|
||||
@@ -2359,6 +2378,8 @@ SCES-51190:
|
||||
name: "Dark Chronicle"
|
||||
region: "PAL-M5"
|
||||
compat: 5
|
||||
clampModes:
|
||||
eeClampMode: 3 # Fixes textbox.
|
||||
SCES-51224:
|
||||
name: "War of the Monsters"
|
||||
region: "PAL-E"
|
||||
@@ -2378,6 +2399,8 @@ SCES-51463:
|
||||
name: "Ghosthunter"
|
||||
region: "PAL-M6"
|
||||
compat: 5
|
||||
clampModes:
|
||||
vuClampMode: 3 # Fixes SPS.
|
||||
gameFixes:
|
||||
- VUKickstartHack # Fixes Missing Graphics.
|
||||
SCES-51480:
|
||||
@@ -2473,9 +2496,10 @@ SCES-51685:
|
||||
name: "Primal"
|
||||
region: "PAL-E-R"
|
||||
roundModes:
|
||||
vuRoundMode: 0 # Fixes SPS.
|
||||
vuRoundMode: 1 # Fixes SPS.
|
||||
eeRoundMode: 0 # Fixes textures on the doors.
|
||||
clampModes:
|
||||
vuClampMode: 2 # Fix other SPS.
|
||||
vuClampMode: 0 # Fix other SPS.
|
||||
gameFixes:
|
||||
- VUKickstartHack # Fixes objects disappearing.
|
||||
SCES-51706:
|
||||
@@ -2566,6 +2590,8 @@ SCES-52154:
|
||||
SCES-52156:
|
||||
name: "Ghosthunter - Hunter on the spectres"
|
||||
region: "PAL-M3"
|
||||
clampModes:
|
||||
vuClampMode: 3 # Fixes SPS.
|
||||
SCES-52268:
|
||||
name: "SingStar"
|
||||
region: "PAL-E"
|
||||
@@ -3676,6 +3702,8 @@ SCKA-20014:
|
||||
name: "Dark Cloud 2"
|
||||
region: "NTSC-K"
|
||||
compat: 5
|
||||
clampModes:
|
||||
eeClampMode: 3 # Fixes textbox.
|
||||
SCKA-20015:
|
||||
name: "Time Crisis 3"
|
||||
region: "NTSC-K"
|
||||
@@ -4244,6 +4272,8 @@ SCPS-15032:
|
||||
SCPS-15033:
|
||||
name: "Dark Chronicle"
|
||||
region: "NTSC-J"
|
||||
clampModes:
|
||||
eeClampMode: 3 # Fixes textbox.
|
||||
SCPS-15034:
|
||||
name: "This is Football 2003"
|
||||
region: "NTSC-J"
|
||||
@@ -4730,6 +4760,8 @@ SCPS-19214:
|
||||
SCPS-19215:
|
||||
name: "Dark Chronicle [PlayStation 2 The Best]"
|
||||
region: "NTSC-J"
|
||||
clampModes:
|
||||
eeClampMode: 3 # Fixes textbox.
|
||||
SCPS-19251:
|
||||
name: "Wild ARMs - Alter Code F [PlayStation 2 The Best]"
|
||||
region: "NTSC-J"
|
||||
@@ -4789,6 +4821,8 @@ SCPS-19305:
|
||||
SCPS-19306:
|
||||
name: "Dark Chronicle [PlayStation 2 The Best]"
|
||||
region: "NTSC-J"
|
||||
clampModes:
|
||||
eeClampMode: 3 # Fixes textbox.
|
||||
SCPS-19307:
|
||||
name: "Popolocrois - The First Adventure [PlayStation 2 The Best]"
|
||||
region: "NTSC-J"
|
||||
@@ -5143,6 +5177,8 @@ SCPS-55047:
|
||||
SCPS-55048:
|
||||
name: "Dark Chronicle"
|
||||
region: "NTSC-J"
|
||||
clampModes:
|
||||
eeClampMode: 3 # Fixes textbox.
|
||||
SCPS-55049:
|
||||
name: "King of Fighters 2000, The"
|
||||
region: "NTSC-J"
|
||||
@@ -5406,9 +5442,10 @@ SCUS-97142:
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
roundModes:
|
||||
vuRoundMode: 0 # Fixes SPS.
|
||||
vuRoundMode: 1 # Fixes SPS.
|
||||
eeRoundMode: 0 # Fixes textures on the doors.
|
||||
clampModes:
|
||||
vuClampMode: 2 # Fix other SPS.
|
||||
vuClampMode: 0 # Fix other SPS.
|
||||
gameFixes:
|
||||
- VUKickstartHack # Fixes objects disappearing.
|
||||
SCUS-97144:
|
||||
@@ -5639,6 +5676,8 @@ SCUS-97213:
|
||||
name: "Dark Cloud 2"
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
clampModes:
|
||||
eeClampMode: 3 # Fixes textbox.
|
||||
SCUS-97214:
|
||||
name: "NCAA GameBreaker 2003"
|
||||
region: "NTSC-U"
|
||||
@@ -5675,9 +5714,10 @@ SCUS-97225:
|
||||
name: "Primal [Demo]"
|
||||
region: "NTSC-U"
|
||||
roundModes:
|
||||
vuRoundMode: 0 # Fixes SPS.
|
||||
vuRoundMode: 1 # Fixes SPS.
|
||||
eeRoundMode: 0 # Fixes textures on the doors.
|
||||
clampModes:
|
||||
vuClampMode: 2 # Fix other SPS.
|
||||
vuClampMode: 0 # Fix other SPS.
|
||||
gameFixes:
|
||||
- VUKickstartHack # Fixes objects disappearing.
|
||||
SCUS-97226:
|
||||
@@ -5689,6 +5729,8 @@ SCUS-97227:
|
||||
SCUS-97229:
|
||||
name: "Dark Cloud 2 [Demo]"
|
||||
region: "NTSC-U"
|
||||
clampModes:
|
||||
eeClampMode: 3 # Fixes textbox.
|
||||
SCUS-97230:
|
||||
name: "SOCOM - U.S. Navy SEALs (Online)"
|
||||
region: "NTSC-U"
|
||||
@@ -7044,6 +7086,8 @@ SLAJ-35003:
|
||||
SLED-50117:
|
||||
name: "Metal Gear Solid 2 - Sons of Liberty [Demo] [Zone of the Enders Bonus Disc]"
|
||||
region: "PAL-E"
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
SLED-50359:
|
||||
name: "Devil May Cry [Demo]"
|
||||
region: "PAL-E"
|
||||
@@ -7988,12 +8032,18 @@ SLES-50383:
|
||||
name: "Metal Gear Solid 2 - Sons of Liberty"
|
||||
region: "PAL-M3"
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
SLES-50384:
|
||||
name: "Project Zero II"
|
||||
name: "Metal Gear Solid 2 - Sons of Liberty"
|
||||
region: "PAL-I"
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
SLES-50385:
|
||||
name: "Metal Gear Solid 2 - Sons of Liberty"
|
||||
region: "PAL-S"
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
SLES-50386:
|
||||
name: "Crash Bandicoot - Wrath of Cortex"
|
||||
region: "PAL-M6"
|
||||
@@ -8105,6 +8155,8 @@ SLES-50446:
|
||||
name: "Shadow Man - 2econd Coming"
|
||||
region: "PAL-M4"
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes cutscene freezes.
|
||||
speedHacks:
|
||||
InstantVU1SpeedHack: 0 # Fixes SPS.
|
||||
SLES-50447:
|
||||
@@ -8364,6 +8416,8 @@ SLES-50608:
|
||||
name: "Shadow Man - 2econd Coming"
|
||||
region: "PAL-G"
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes cutscene freezes.
|
||||
speedHacks:
|
||||
InstantVU1SpeedHack: 0 # Fixes SPS.
|
||||
SLES-50613:
|
||||
@@ -8677,6 +8731,8 @@ SLES-50788:
|
||||
SLES-50789:
|
||||
name: "Men in Black II: Alien Escape"
|
||||
region: "PAL-M5"
|
||||
gameFixes:
|
||||
- VIFFIFOHack # Needed to load the main game properly.
|
||||
SLES-50790:
|
||||
name: "International Superstar Soccer 2002"
|
||||
region: "PAL-M3"
|
||||
@@ -9367,6 +9423,8 @@ SLES-51113:
|
||||
name: "Zone of the Enders: The 2nd Runner Special Edition"
|
||||
region: "PAL-M5"
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- DMABusyHack # Fixes the corrupted fade effect in cutscenes.
|
||||
SLES-51114:
|
||||
name: "Pro Evolution Soccer 2"
|
||||
region: "PAL-M5"
|
||||
@@ -9444,6 +9502,8 @@ SLES-51145:
|
||||
SLES-51150:
|
||||
name: "Scrabble Interactive - 2003 Edition"
|
||||
region: "PAL-M3"
|
||||
clampModes:
|
||||
vuClampMode: 0 # Fixes missing UI and game elements.
|
||||
SLES-51151:
|
||||
name: "NHL 2003"
|
||||
region: "PAL-M6"
|
||||
@@ -12073,6 +12133,7 @@ SLES-52568:
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- XGKickHack # Fixes bad Geometry.
|
||||
- VUKickstartHack # Fixes graphical glitches.
|
||||
SLES-52569:
|
||||
name: "Spyro - A Hero's Tail"
|
||||
region: "PAL-M6"
|
||||
@@ -12389,6 +12450,8 @@ SLES-52710:
|
||||
SLES-52711:
|
||||
name: "Titeuf Mega Compet"
|
||||
region: "PAL-F"
|
||||
gameFixes:
|
||||
- GIFFIFOHack # Fixes corrupted textures.
|
||||
patches:
|
||||
958e5086:
|
||||
content: |-
|
||||
@@ -13072,6 +13135,14 @@ SLES-53021:
|
||||
SLES-53022:
|
||||
name: "ESPN NBA 2K5"
|
||||
region: "PAL-E"
|
||||
gameFixes:
|
||||
- SkipMPEGHack # Fixes videos.
|
||||
patches:
|
||||
CA37B42E:
|
||||
content: |-
|
||||
author=Prafull
|
||||
comment=fixes hang at start
|
||||
patch=1,EE,0034DA98,word,00000000
|
||||
SLES-53023:
|
||||
name: "RTL Ski Jump 2005"
|
||||
region: "PAL-E-G"
|
||||
@@ -13951,6 +14022,8 @@ SLES-53491:
|
||||
SLES-53492:
|
||||
name: "Total Overdose"
|
||||
region: "PAL-M5"
|
||||
gameFixes:
|
||||
- VUKickstartHack # Fixes SPS.
|
||||
SLES-53494:
|
||||
name: "Spongebob SquarePants - Lights, Camera, PANTS!"
|
||||
region: "PAL-E"
|
||||
@@ -14488,6 +14561,12 @@ SLES-53686:
|
||||
SLES-53687:
|
||||
name: "NBA 2K6"
|
||||
region: "PAL-M5"
|
||||
patches:
|
||||
04808D11:
|
||||
content: |-
|
||||
author=Prafull
|
||||
comment=fixes hang at start
|
||||
patch=1,EE,00441ff8,word,00000000
|
||||
SLES-53689:
|
||||
name: "World Poker Tour 2K6"
|
||||
region: "PAL-M3"
|
||||
@@ -14770,6 +14849,14 @@ SLES-53805:
|
||||
SLES-53809:
|
||||
name: "K-1 Premium Dynamite!!"
|
||||
region: "PAL-E"
|
||||
gameFixes:
|
||||
- XGKickHack # Fixes black and white fighters.
|
||||
patches:
|
||||
B6F9C8D3:
|
||||
content: |-
|
||||
comment=Fixes black screen in hardware mode.
|
||||
patch=1,EE,0030a420,word,0000948c
|
||||
patch=1,EE,0030a448,word,0000948c
|
||||
SLES-53810:
|
||||
name: "Sensible Soccer 2006"
|
||||
region: "PAL-M5"
|
||||
@@ -15581,6 +15668,12 @@ SLES-54209:
|
||||
SLES-54210:
|
||||
name: "NBA 2K7"
|
||||
region: "PAL-M5"
|
||||
patches:
|
||||
04808D11:
|
||||
content: |-
|
||||
author=Prafull
|
||||
comment=fixes hang at start
|
||||
patch=1,EE,0044f0f8,word,00000000
|
||||
SLES-54211:
|
||||
name: "NHL 2K7"
|
||||
region: "PAL-M5"
|
||||
@@ -16783,11 +16876,15 @@ SLES-54767:
|
||||
SLES-54770:
|
||||
name: "DreamWorks Shrek the Third"
|
||||
region: "PAL-E"
|
||||
roundModes:
|
||||
vuRoundMode: 0 # Fixes black zones.
|
||||
clampModes:
|
||||
eeClampMode: 3 # Fixes objects spawning.
|
||||
SLES-54771:
|
||||
name: "DreamWorks Shrek the Third"
|
||||
region: "PAL-M5"
|
||||
roundModes:
|
||||
vuRoundMode: 0 # Fixes black zones.
|
||||
clampModes:
|
||||
eeClampMode: 3 # Fixes objects spawning.
|
||||
SLES-54772:
|
||||
@@ -16795,6 +16892,8 @@ SLES-54772:
|
||||
region: "PAL-E"
|
||||
SLES-54774:
|
||||
name: "DreamWorks Shrek the Third"
|
||||
roundModes:
|
||||
vuRoundMode: 0 # Fixes black zones.
|
||||
region: "PAL-M5"
|
||||
clampModes:
|
||||
eeClampMode: 3 # Fixes objects spawning.
|
||||
@@ -18570,6 +18669,8 @@ SLES-82009:
|
||||
name: "Metal Gear Solid 2 - Substance"
|
||||
region: "PAL-M5"
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
SLES-82010:
|
||||
name: "Metal Gear Solid 2, Document of"
|
||||
region: "PAL-E"
|
||||
@@ -18820,6 +18921,11 @@ SLKA-25026:
|
||||
region: "NTSC-K"
|
||||
clampModes:
|
||||
vuClampMode: 2 # Fixes SPS in item menu.
|
||||
SLKA-25029:
|
||||
name: "MVP Baseball 2003"
|
||||
region: "NTSC-K"
|
||||
clampModes:
|
||||
vuClampMode: 3 # Fixes missing environment.
|
||||
SLKA-25030:
|
||||
name: "WWE SmackDown! Shut Your Mouth"
|
||||
region: "NTSC-K"
|
||||
@@ -18853,6 +18959,12 @@ SLKA-25043:
|
||||
name: "Virtua Fighter 4 - Evolution"
|
||||
region: "NTSC-K"
|
||||
compat: 5
|
||||
SLKA-25044:
|
||||
name: "Robotech: Battlecry"
|
||||
region: "NTSC-K"
|
||||
SLKA-25045:
|
||||
name: "The King of Fighters 2000"
|
||||
region: "NTSC-K"
|
||||
SLKA-25046:
|
||||
name: "Dragon Ball Z"
|
||||
region: "NTSC-K"
|
||||
@@ -19058,12 +19170,18 @@ SLKA-25202:
|
||||
memcardFilters:
|
||||
- "SLKA-25201"
|
||||
- "SLKA-25202"
|
||||
SLKA-25203:
|
||||
name: "World Soccer Winning Eleven 8 International"
|
||||
region: "NTSC-K"
|
||||
SLKA-25204:
|
||||
name: "Showdown - Legends of Wrestling"
|
||||
region: "NTSC-K"
|
||||
SLKA-25205:
|
||||
name: "Dragon Ball Z 3"
|
||||
region: "NTSC-K"
|
||||
SLKA-25206:
|
||||
name: "Burnout 3: Takedown"
|
||||
region: "NTSC-K"
|
||||
SLKA-25207:
|
||||
name: "Sakura Taisen V - Episode 0 - Samurai Girl of Wild"
|
||||
region: "NTSC-K"
|
||||
@@ -19171,6 +19289,9 @@ SLKA-25259:
|
||||
SLKA-25261:
|
||||
name: "Tsukiyo ni Saraba"
|
||||
region: "NTSC-K"
|
||||
SLKA-25262:
|
||||
name: "World Soccer Winning Eleven 8 International"
|
||||
region: "NTSC-K"
|
||||
SLKA-25263:
|
||||
name: "NanoBreaker"
|
||||
region: "NTSC-J"
|
||||
@@ -19312,6 +19433,9 @@ SLKA-25331:
|
||||
SLKA-25333:
|
||||
name: "Metal Slug Complete"
|
||||
region: "NTSC-K"
|
||||
SLKA-25335:
|
||||
name: "Shadow the Hedgehog"
|
||||
region: "NTSC-K"
|
||||
SLKA-25341:
|
||||
name: "Driver - Parallel Lines"
|
||||
region: "NTSC-K"
|
||||
@@ -19420,6 +19544,8 @@ SLKA-35001:
|
||||
name: "Metal Gear Solid 2 Substance"
|
||||
region: "NTSC-K"
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
SLKA-35003:
|
||||
name: "Sakura Taisen - Atsuki Chishioni"
|
||||
region: "NTSC-K"
|
||||
@@ -19533,6 +19659,9 @@ SLPM-55131:
|
||||
SLPM-55138:
|
||||
name: "Harukanaru Toki no Naka de - Yume no Ukihashi Special"
|
||||
region: "NTSC-J"
|
||||
SLPM-55146:
|
||||
name: "Jikkyou Powerful Pro Yakyuu 2009"
|
||||
region: "NTSC-J"
|
||||
SLPM-55148:
|
||||
name: "007: Nagusame no Houshuu"
|
||||
region: "NTSC-J"
|
||||
@@ -19641,6 +19770,11 @@ SLPM-60254:
|
||||
SLPM-60256:
|
||||
name: "Dengeki D73 demo"
|
||||
region: "NTSC-J"
|
||||
SLPM-60260:
|
||||
name: "D1 Professional Drift Grand Prix Series [Taikenban]"
|
||||
region: "NTSC-J"
|
||||
clampModes:
|
||||
eeClampMode: 3 # Fixes black void.
|
||||
SLPM-60262:
|
||||
name: "10th Anniversary Memorial Save Data [Disc 2]"
|
||||
region: "NTSC-J"
|
||||
@@ -20840,6 +20974,8 @@ SLPM-62485:
|
||||
SLPM-62486:
|
||||
name: "Chou Saisoku! Zokusha King B.U. [Simple Series DX]"
|
||||
region: "NTSC-J"
|
||||
clampModes:
|
||||
eeClampMode: 3 # Fixes white shadows.
|
||||
SLPM-62488:
|
||||
name: "Hot Gimmick Cosplay Mahjong"
|
||||
region: "NTSC-J"
|
||||
@@ -21111,6 +21247,14 @@ SLPM-62580:
|
||||
SLPM-62581:
|
||||
name: "K-1 Premium 2004 - Fighting Dynamite!!"
|
||||
region: "NTSC-J"
|
||||
gameFixes:
|
||||
- XGKickHack # Fixes black and white fighters.
|
||||
patches:
|
||||
0A1042EE:
|
||||
content: |-
|
||||
comment=Fixes black screen in hardware mode.
|
||||
patch=1,EE,00301de0,word,0000948c
|
||||
patch=1,EE,00301e08,word,0000948c
|
||||
SLPM-62582:
|
||||
name: "Slotter-Up Core 6"
|
||||
region: "NTSC-J"
|
||||
@@ -21953,9 +22097,13 @@ SLPM-65076:
|
||||
SLPM-65077:
|
||||
name: "Metal Gear Solid 2 - Sons of Liberty [Premium Package]"
|
||||
region: "NTSC-J"
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
SLPM-65078:
|
||||
name: "Metal Gear Solid 2 - Sons of Liberty"
|
||||
region: "NTSC-J"
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
SLPM-65080:
|
||||
name: "Tokimeki Memorial 3"
|
||||
region: "NTSC-J"
|
||||
@@ -24288,6 +24436,8 @@ SLPM-65862:
|
||||
SLPM-65863:
|
||||
name: "D1 Grand Prix Series - Professional Drift"
|
||||
region: "NTSC-J"
|
||||
clampModes:
|
||||
eeClampMode: 3 # Fixes black void.
|
||||
SLPM-65864:
|
||||
name: "Nobunaga no Yabou - Tenka Sousei [with Power-Up Kit]"
|
||||
region: "NTSC-J"
|
||||
@@ -24938,6 +25088,14 @@ SLPM-66077:
|
||||
name: "K-1 World Max 2005"
|
||||
region: "NTSC-J"
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- XGKickHack # Fixes black and white fighters.
|
||||
patches:
|
||||
08E3C435:
|
||||
content: |-
|
||||
comment=Fixes black screen in hardware mode.
|
||||
patch=1,EE,003dfe60,word,0000948c
|
||||
patch=1,EE,003dfe88,word,0000948c
|
||||
SLPM-66078:
|
||||
name: "White Princess the Second"
|
||||
region: "NTSC-J"
|
||||
@@ -25622,6 +25780,13 @@ SLPM-66294:
|
||||
SLPM-66295:
|
||||
name: "Yamiyo ni Sasayaku - Tantei Sagara Kyouichirou [Limited Edition]"
|
||||
region: "NTSC-J"
|
||||
patches:
|
||||
23A9A026:
|
||||
content: |-
|
||||
author=PSI, Jelta
|
||||
// Game does weird stack manipulation, causing data sent to the IOP to be corrupted unless EE data cache is enabled.
|
||||
// This patch skips over the stack code, allowing the game to boot.
|
||||
patch=1,EE,00156888,word,10000003
|
||||
SLPM-66296:
|
||||
name: "Yamiyo ni Sasayaku - Tantei Sagara Kyouichirou"
|
||||
region: "NTSC-J"
|
||||
@@ -25818,6 +25983,8 @@ SLPM-66356:
|
||||
SLPM-66358:
|
||||
name: "Shinobido Takumi"
|
||||
region: "NTSC-J"
|
||||
clampModes:
|
||||
eeClampMode: 3 # Fixes crash after main menu.
|
||||
SLPM-66359:
|
||||
name: "Mutsu-boshi Kirari - Hoshifuru Miyako"
|
||||
region: "NTSC-J"
|
||||
@@ -25932,6 +26099,13 @@ SLPM-66398:
|
||||
SLPM-66399:
|
||||
name: "Samurai 7 [Limited Edition]"
|
||||
region: "NTSC-J"
|
||||
patches:
|
||||
836F4606:
|
||||
content: |-
|
||||
author=PSI, Jelta
|
||||
// Game does weird stack manipulation, causing data sent to the IOP to be corrupted unless EE data cache is enabled.
|
||||
// This patch skips over the stack code, allowing the game to boot.
|
||||
patch=1,EE,00157F78,word,10000003
|
||||
SLPM-66400:
|
||||
name: "Samurai 7"
|
||||
region: "NTSC-J"
|
||||
@@ -26099,6 +26273,12 @@ SLPM-66450:
|
||||
SLPM-66451:
|
||||
name: "Major League Baseball 2K6"
|
||||
region: "NTSC-J"
|
||||
patches:
|
||||
F0393708:
|
||||
content: |-
|
||||
author=Prafull
|
||||
comment=fixes hang at start
|
||||
patch=1,EE,0035d8b8,word,00000000
|
||||
SLPM-66452:
|
||||
name: "Kamaitachi no Yoru 3"
|
||||
region: "NTSC-J"
|
||||
@@ -26299,6 +26479,8 @@ SLPM-66502:
|
||||
SLPM-66503:
|
||||
name: "Metal Gear Solid 2 [Mega Hits]"
|
||||
region: "NTSC-J"
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
SLPM-66504:
|
||||
name: "Onimusha 2 [Mega Hits]"
|
||||
region: "NTSC-J"
|
||||
@@ -27242,6 +27424,8 @@ SLPM-66791:
|
||||
SLPM-66792:
|
||||
name: "Metal Gear Solid 2 - Sons of Liberty [20th Anniversary Edition]"
|
||||
region: "NTSC-J"
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
SLPM-66794:
|
||||
name: "Metal Gear Solid 3 - Snake Eater [20th Anniversary Edition]"
|
||||
region: "NTSC-J"
|
||||
@@ -27758,6 +27942,9 @@ SLPM-66978:
|
||||
name: "Persona 4 [Konami-style Special Edition]"
|
||||
region: "NTSC-J"
|
||||
compat: 5
|
||||
SLPM-66980:
|
||||
name: "Gin no Eclipse"
|
||||
region: "NTSC-J"
|
||||
SLPM-66987:
|
||||
name: "Kowloon Youma Gakuen Ki [Best Version]"
|
||||
region: "NTSC-J"
|
||||
@@ -27801,6 +27988,8 @@ SLPM-67000:
|
||||
SLPM-67002:
|
||||
name: "Metal Gear Solid 2 - Substance"
|
||||
region: "NTSC-J"
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
SLPM-67003:
|
||||
name: "Sakura Taisen - Atsuki Chishioni"
|
||||
region: "NTSC-J"
|
||||
@@ -28350,6 +28539,8 @@ SLPS-20048:
|
||||
SLPS-20050:
|
||||
name: "Happy! Happy!! Boarders in Hokkaidou Rusutsu Resort"
|
||||
region: "NTSC-J"
|
||||
speedHacks:
|
||||
mvuFlagSpeedHack: 0 # Fixes graphical issues.
|
||||
SLPS-20051:
|
||||
name: "Hissatsu Pachinko Station V"
|
||||
region: "NTSC-J"
|
||||
@@ -28579,6 +28770,15 @@ SLPS-20187:
|
||||
name: "Black Matrix 2"
|
||||
region: "NTSC-J"
|
||||
compat: 5
|
||||
SLPS-20190:
|
||||
name: "Netsu Chu! Pro Yakyuu 2002"
|
||||
region: "NTSC-J"
|
||||
patches:
|
||||
78E100AD:
|
||||
content: |-
|
||||
author=Prafull
|
||||
comment=fixes hang before ingame
|
||||
patch=1,EE,001022c0,word,00000000
|
||||
SLPS-20194:
|
||||
name: "Underwater Unit"
|
||||
region: "NTSC-J"
|
||||
@@ -28666,7 +28866,7 @@ SLPS-20272:
|
||||
region: "NTSC-J"
|
||||
compat: 5
|
||||
SLPS-20273:
|
||||
name: "Netsu Chu! Pro Baseball 2003"
|
||||
name: "Netsu Chu! Pro Yakyuu 2003"
|
||||
region: "NTSC-J"
|
||||
patches:
|
||||
34fb1fb7:
|
||||
@@ -28752,8 +28952,14 @@ SLPS-20321:
|
||||
region: "NTSC-J"
|
||||
compat: 5
|
||||
SLPS-20322:
|
||||
name: "Netsu Chu! Pro Baseball 2003 Fall"
|
||||
name: "Netsu Chu! Pro Yakyuu 2003: Aki no Night Matsuri"
|
||||
region: "NTSC-J"
|
||||
patches:
|
||||
D3DAF7F4:
|
||||
content: |-
|
||||
author=Prafull
|
||||
comment=fixes hang before ingame
|
||||
patch=1,EE,00102398,word,00000000
|
||||
SLPS-20323:
|
||||
name: "Pochi to Nyaa"
|
||||
region: "NTSC-J"
|
||||
@@ -29074,6 +29280,12 @@ SLPS-20453:
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- XGKickHack # Fixes black and white fighters.
|
||||
patches:
|
||||
602B7A48:
|
||||
content: |-
|
||||
comment=Fixes black screen in hardware mode.
|
||||
patch=1,EE,00336a20,word,0000948c
|
||||
patch=1,EE,00336a48,word,0000948c
|
||||
SLPS-20454:
|
||||
name: "Simple 2000 Series Vol.93 - The Right Brain Drill"
|
||||
region: "NTSC-J"
|
||||
@@ -30016,6 +30228,8 @@ SLPS-25250:
|
||||
SLPS-25251:
|
||||
name: "MVP Baseball 2003"
|
||||
region: "NTSC-J"
|
||||
clampModes:
|
||||
vuClampMode: 3 # Fixes missing environment.
|
||||
SLPS-25252:
|
||||
name: "Star wars - Jango Fett"
|
||||
region: "NTSC-J"
|
||||
@@ -31089,6 +31303,14 @@ SLPS-25577:
|
||||
SLPS-25578:
|
||||
name: "K-1 World Grand Prix 2005"
|
||||
region: "NTSC-J"
|
||||
gameFixes:
|
||||
- XGKickHack # Fixes black and white fighters.
|
||||
patches:
|
||||
F8664E20:
|
||||
content: |-
|
||||
comment=Fixes black screen in hardware mode.
|
||||
patch=1,EE,004269f0,word,0000948c
|
||||
patch=1,EE,00426a18,word,0000948c
|
||||
SLPS-25579:
|
||||
name: "Little Aid"
|
||||
region: "NTSC-J"
|
||||
@@ -33195,6 +33417,8 @@ SLUS-20144:
|
||||
name: "Metal Gear Solid 2 - Sons of Liberty"
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
SLUS-20145:
|
||||
name: "Ring of Red"
|
||||
region: "NTSC-U"
|
||||
@@ -34301,6 +34525,8 @@ SLUS-20413:
|
||||
name: "Shadow Man - 2econd Coming"
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes cutscene freezes.
|
||||
speedHacks:
|
||||
InstantVU1SpeedHack: 0 # Fixes SPS.
|
||||
SLUS-20414:
|
||||
@@ -34894,6 +35120,8 @@ SLUS-20554:
|
||||
name: "Metal Gear Solid 2 - Substance"
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
SLUS-20555:
|
||||
name: "Reel Fishing 3"
|
||||
region: "NTSC-U"
|
||||
@@ -35316,6 +35544,8 @@ SLUS-20649:
|
||||
SLUS-20650:
|
||||
name: "MVP Baseball 2003"
|
||||
region: "NTSC-U"
|
||||
clampModes:
|
||||
vuClampMode: 3 # Fixes missing environment.
|
||||
SLUS-20651:
|
||||
name: "NBA Street Vol. 2"
|
||||
region: "NTSC-U"
|
||||
@@ -36355,6 +36585,7 @@ SLUS-20909:
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- XGKickHack # Fixes bad geometry.
|
||||
- VUKickstartHack # Fixes graphical glitches.
|
||||
SLUS-20910:
|
||||
name: "Test Drive - Eve of Destruction"
|
||||
region: "NTSC-U"
|
||||
@@ -38090,6 +38321,8 @@ SLUS-21283:
|
||||
name: "Total Overdose - A Gunslinger's Tale in Mexico"
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- VUKickstartHack # Fixes SPS.
|
||||
SLUS-21284:
|
||||
name: "Nicktoons Unite!"
|
||||
region: "NTSC-U"
|
||||
@@ -38259,6 +38492,8 @@ SLUS-21322:
|
||||
name: "Eragon"
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
clampModes:
|
||||
vuClampMode: 3 # Fixes SPS and spawn issues.
|
||||
SLUS-21323:
|
||||
name: "Rampage - Total Destruction"
|
||||
region: "NTSC-U"
|
||||
@@ -38703,6 +38938,8 @@ SLUS-21416:
|
||||
name: "D1 Grand Prix"
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
clampModes:
|
||||
eeClampMode: 3 # Fixes black screen.
|
||||
SLUS-21417:
|
||||
name: "Xenosaga - Episode III - Also Sprach Zarathustra [Disc2of2]"
|
||||
region: "NTSC-U"
|
||||
@@ -38895,6 +39132,8 @@ SLUS-21454:
|
||||
name: "DreamWorks Shrek the Third"
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
roundModes:
|
||||
vuRoundMode: 0 # Fixes black zones.
|
||||
clampModes:
|
||||
eeClampMode: 3 # Fixes objects spawning.
|
||||
SLUS-21455:
|
||||
@@ -39232,6 +39471,12 @@ SLUS-21560:
|
||||
SLUS-21561:
|
||||
name: "Major League Baseball 2K7"
|
||||
region: "NTSC-U"
|
||||
patches:
|
||||
73D6D171:
|
||||
content: |-
|
||||
author=Prafull
|
||||
comment=fixes hang at start
|
||||
patch=1,EE,003CDE10,word,00000000
|
||||
SLUS-21563:
|
||||
name: "Horsez"
|
||||
region: "NTSC-U"
|
||||
@@ -40530,6 +40775,12 @@ SLUS-21870:
|
||||
SLUS-21871:
|
||||
name: "Major League Baseball 2K9"
|
||||
region: "NTSC-U"
|
||||
patches:
|
||||
72905002:
|
||||
content: |-
|
||||
author=Prafull
|
||||
comment=fixes hang at start
|
||||
patch=1,EE,003CC5D8,word,00000000
|
||||
SLUS-21872:
|
||||
name: "MTV Pimp my Ride - Street Racing"
|
||||
region: "NTSC-U"
|
||||
@@ -40808,6 +41059,12 @@ SLUS-21944:
|
||||
SLUS-21945:
|
||||
name: "Major League Baseball 2K11"
|
||||
region: "NTSC-U"
|
||||
patches:
|
||||
3D621C56:
|
||||
content: |-
|
||||
author=By Prafull
|
||||
comment=fixes hang at start
|
||||
patch=1,EE,003CFE58,word,00000000
|
||||
SLUS-21946:
|
||||
name: "Madden NFL 12"
|
||||
region: "NTSC-U"
|
||||
@@ -40830,6 +41087,12 @@ SLUS-21950:
|
||||
SLUS-21951:
|
||||
name: "Major League Baseball 2K12"
|
||||
region: "NTSC-U"
|
||||
patches:
|
||||
C26C70A9:
|
||||
content: |-
|
||||
author=By Prafull
|
||||
comment=fixes hang at start
|
||||
patch=1,EE,003D4098,word,00000000
|
||||
SLUS-21954:
|
||||
name: "FIFA 13"
|
||||
region: "NTSC-U" # Latin America with En,Fr,Es
|
||||
@@ -40998,6 +41261,8 @@ SLUS-29003:
|
||||
name: "Metal Gear Solid 2 - Sons of Liberty [Demo]"
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- EETimingHack # Fixes broken half-bottom artifacts.
|
||||
SLUS-29004:
|
||||
name: "Unison & Dead or Alive 2 Hardcore [Demo]"
|
||||
region: "NTSC-U"
|
||||
@@ -39,6 +39,7 @@
|
||||
03000000120c0000200e000000010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
03000000120c0000210e000000010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
030000008305000031b0000000000000,Cideko AK08b,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
03000000d8140000cecf000000000000,Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
03000000260900008888000088020000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Mac OS X,
|
||||
03000000a306000022f6000001030000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
030000000d0f00008400000000010000,Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
@@ -54,10 +55,10 @@
|
||||
03000000280400000140000000020000,Gravis Gamepad Pro,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:Mac OS X,
|
||||
030000008f0e00000300000007010000,GreenAsia USB Joystick,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Mac OS X,
|
||||
030000000d0f00002d00000000100000,Hori Fighting Commander 3 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
030000000d0f00005f00000000010000,Hori Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
030000000d0f00005e00000000010000,Hori Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
030000000d0f00005f00000000000000,Hori Fighting Commander 4 PS3,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:Mac OS X,
|
||||
030000000d0f00005f00000000010000,Hori Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
030000000d0f00005e00000000000000,Hori Fighting Commander 4 PS4,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:Mac OS X,
|
||||
030000000d0f00005e00000000010000,Hori Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
030000000d0f00004d00000000000000,Hori Gem Pad 3,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:Mac OS X,
|
||||
030000000d0f00009200000000010000,Hori Pokken Tournament DX Pro Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
030000000d0f00006e00000000010000,Horipad 4 PS3,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:Mac OS X,
|
||||
@@ -90,8 +91,7 @@
|
||||
0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Mac OS X,
|
||||
03000000790000000018000000010000,Mayflash Wii U Pro Controller Adapter,a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X,
|
||||
03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X,
|
||||
03000000d8140000cecf000000000000,Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
030000005e0400002700000001010000,Microsoft SideWinder Plug and Play,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,leftx:a0,lefty:a1,righttrigger:b5,x:b2,y:b3,platform:Mac OS X,
|
||||
030000005e0400002700000001010000,Microsoft SideWinder Plug and Play,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,righttrigger:b5,x:b2,y:b3,platform:Mac OS X,
|
||||
03000000d62000007162000001000000,Moga Pro 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Mac OS X,
|
||||
03000000c62400002a89000000010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||
03000000c62400002b89000000010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||
@@ -125,9 +125,9 @@
|
||||
03000000321500000009000000020000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X,
|
||||
030000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X,
|
||||
0300000032150000030a000000000000,Razer Wildcat,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||
03000000830500006020000000010000,Retro Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b8,righttrigger:b9,start:b7,x:b2,y:b3,platform:Mac OS X,
|
||||
03000000790000001100000000000000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
03000000790000001100000005010000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b4,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
03000000830500006020000000010000,Retro Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b8,righttrigger:b9,start:b7,x:b2,y:b3,platform:Mac OS X,
|
||||
03000000790000001100000006010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||
030000006b140000010d000000010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
030000006b140000130d000000010000,Revolution Pro Controller 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
@@ -146,8 +146,8 @@
|
||||
03000000110100002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,
|
||||
03000000381000002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,
|
||||
05000000484944204465766963650000,SteelSeries Nimbus Plus,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,platform:Mac OS X,
|
||||
05000000556e6b6e6f776e2048494400,SteelSeries Nimbus Plus,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,platform:Mac OS X,
|
||||
050000004e696d6275732b0000000000,SteelSeries Nimbus Plus,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,platform:Mac OS X,
|
||||
05000000556e6b6e6f776e2048494400,SteelSeries Nimbus Plus,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,platform:Mac OS X,
|
||||
03000000110100001714000000000000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,
|
||||
03000000110100001714000020010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,
|
||||
03000000457500002211000000010000,SZMY Power PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
@@ -194,9 +194,9 @@
|
||||
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,
|
||||
03000000022000000090000011010000,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:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||
03000000c82d00000190000011010000,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:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||
05000000203800000900000000010000,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:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||
05000000c82d00002038000000010000,8Bitdo NES30 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:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||
03000000c82d00000190000011010000,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:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||
05000000c82d00000060000000010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||
05000000c82d00000061000000010000,8Bitdo SF30 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:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||
030000003512000021ab000010010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
|
||||
@@ -252,7 +252,6 @@
|
||||
03000000120c0000200e000011010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000120c0000210e000011010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000120c0000f70e000011010000,Brook Universal Fighting Board,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,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000ffff0000ffff000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
|
||||
03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||
030000000b0400003365000000010000,Competition Pro,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Linux,
|
||||
03000000260900008888000000010000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Linux,
|
||||
@@ -261,16 +260,15 @@
|
||||
030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000c11100000191000011010000,EasySMX,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||
030000006e0500000320000010010000,Elecom U3613M,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux,
|
||||
03000000430b00000300000000010000,EMS Production PS2 Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a5,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
|
||||
03000000b40400001124000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
05000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||
03000000341a000005f7000010010000,HuiJia GameCube Controller Adpater,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000bc2000000055000011010000,GameSir G3w,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,
|
||||
05000000ac0500002d0200001b010000,Gamesir G4s,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b33,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,
|
||||
03000000bc2000005656000011010000,Gamesir T4w,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux,
|
||||
03000000bc2000005656000011010000,Gamesir T4w,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||
030000006f0e00000104000000010000,Gamestop Logic3 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,
|
||||
030000008f0e00000800000010010000,Gasia PlayStation Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||
030000006f0e00001304000000010000,Xbox 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,
|
||||
03000000451300000010000010010000,Genius Maxfire Grandias 12,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||
03000000f0250000c183000010010000,Goodbetterbest Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
0300000079000000d418000000010000,GPD Win 2 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,
|
||||
@@ -283,28 +281,28 @@
|
||||
06000000adde0000efbe000002010000,Hidromancer Game 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,
|
||||
03000000d81400000862000011010000,HitBox PS3 PC Analog Mode,a:b1,b:b2,back:b8,guide:b9,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux,
|
||||
03000000c9110000f055000011010000,HJC Game Gamepqd,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||
03000000300f00001210000010010000,Qanba Joystick Plus,a:b0,b:b1,back:b8,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,start:b9,x:b2,y:b3,platform:Linux,
|
||||
03000000632500002605000010010000,HJDX,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:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
030000000d0f00000d00000000010000,Hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,rightshoulder:b7,start:b9,x:b1,y:b2,platform:Linux,
|
||||
030000000d0f00001000000011010000,Hori Fighting Stick 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000000d0f0000c100000011010000,Horipad S,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000000d0f00006a00000011010000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000000d0f00006b00000011010000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000000d0f00002200000011010000,Hori Real Arcade Pro 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000000d0f00008500000010010000,Hori Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000000d0f00008600000002010000,Hori Fighting Commander,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||
030000000d0f00005f00000011010000,Hori Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000000d0f00005e00000011010000,Hori Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000000d0f00005001000009040000,Hori Fighting Commander OCTA,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,
|
||||
030000000d0f00001000000011010000,Hori Fighting Stick 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
030000000d0f00003801000011010000,Hori PC Engine Mini Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,platform:Linux,
|
||||
030000000d0f00009200000011010000,Hori Pokken Tournament DX Pro Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000000d0f0000aa00000011010000,Hori Real Arcade Pro,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,
|
||||
030000000d0f00002200000011010000,Hori Real Arcade Pro 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000000d0f00006a00000011010000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000000d0f00006b00000011010000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000000d0f00001600000000010000,Hori Real Arcade Pro EXSE,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux,
|
||||
030000000d0f00006e00000011010000,Horipad 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000000d0f00006600000011010000,Horipad 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000000d0f0000ee00000011010000,Horipad Mini 4,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:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000000d0f00006700000001010000,Horipad 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,
|
||||
030000000d0f0000c100000011010000,Horipad S,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000341a000005f7000010010000,HuiJia GameCube Controller Adpater,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000008f0e00001330000010010000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,platform:Linux,
|
||||
03000000242e00008816000001010000,Hyperkin X91,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,
|
||||
050000006964726f69643a636f6e0000,idroidcon Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
@@ -313,6 +311,8 @@
|
||||
03000000fd0500000030000000010000,InterAct GoPad I73000,a:b3,b:b4,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b7,x:b0,y:b1,platform:Linux,
|
||||
0500000049190000020400001b010000,Ipega PG 9069 Bluetooth Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b161,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,
|
||||
03000000632500007505000011010000,Ipega PG 9099 Bluetooth Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||
0500000049190000030400001b010000,Ipega PG9099,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,
|
||||
05000000491900000204000000000000,Ipega PG9118,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,
|
||||
03000000300f00001001000010010000,Jess Tech Dual Analog Rumble Pad,a:b2,b:b3,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:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
|
||||
03000000300f00000b01000010010000,Jess Tech GGE909 PC Recoil Pad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
|
||||
03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
|
||||
@@ -333,11 +333,9 @@
|
||||
030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),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,
|
||||
030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),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,
|
||||
030000006d0400000ac2000010010000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Linux,
|
||||
030000006d04000018c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,platform:Linux,
|
||||
050000004d4f435554452d3035335800,Mocute 053X,a:b0,b:b1,x:b2,y:b3,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux
|
||||
050000004d4f435554452d3035305800,Mocute 054X,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,
|
||||
030000006d0400000ac2000010010000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Linux,
|
||||
05000000380700006652000025010000,Mad Catz CTRLR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000380700005032000011010000,Mad Catz FightPad PRO PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000380700005082000011010000,Mad Catz FightPad PRO PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||
@@ -351,31 +349,33 @@
|
||||
03000000ad1b000016f0000090040000,Mad Catz Xbox 360 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,
|
||||
03000000380700001888000010010000,MadCatz PC USB Wired Stick 8818,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000380700003888000010010000,MadCatz PC USB Wired Stick 8838,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:a0,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000242f0000f700000001010000,Mayflash Magic S Pro,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,
|
||||
03000000120c00000500000000010000,Manta Dualshock 2,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:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
|
||||
03000000790000004418000010010000,Mayflash GameCube Controller,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
|
||||
03000000790000004318000010010000,Mayflash GameCube Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000242f00007300000011010000,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:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux,
|
||||
0300000079000000d218000011010000,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:Linux,
|
||||
03000000d620000010a7000011010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000242f0000f700000001010000,Mayflash Magic S Pro,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,
|
||||
0300000025090000e803000001010000,Mayflash Wii Classic Controller,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:Linux,
|
||||
03000000780000000600000010010000,Microntek USB Joystick,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
|
||||
030000005e0400000e00000000010000,Microsoft SideWinder,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux,
|
||||
030000005e0400000700000000010000,Microsoft SideWinder Game Pad USB,a:b0,b:b1,back:b8,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Linux,
|
||||
030000005e0400002700000000010000,Microsoft SideWinder Plug and Play,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,righttrigger:b5,x:b2,y:b3,platform:Linux,
|
||||
030000005e0400008e02000056210000,Microsoft X-Box 360 pad,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,
|
||||
030000005e0400008e02000004010000,Microsoft Xbox 360 pad,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,
|
||||
030000005e0400008e02000056210000,Microsoft X-Box 360 pad,a:b0,b:b1,x:b2,y:b3,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux
|
||||
030000005e0400008e02000062230000,Microsoft Xbox 360 pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
030000005e040000000b000008040000,Microsoft Xbox One Elite 2 pad,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,
|
||||
050000005e040000050b000003090000,Microsoft Xbox One Elite 2 pad,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,
|
||||
030000005e040000e302000003020000,Microsoft Xbox One Elite pad,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,
|
||||
030000005e040000d102000001010000,Microsoft Xbox One pad,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,
|
||||
030000005e040000dd02000003020000,Microsoft Xbox One pad 2015,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,
|
||||
030000005e040000d102000003020000,Microsoft Xbox One pad v2,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,
|
||||
030000005e040000ea02000008040000,Microsoft Xbox One S pad,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,
|
||||
030000005e0400008502000000010000,Microsoft Xbox pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
|
||||
030000005e0400008902000021010000,Microsoft Xbox pad v2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
|
||||
030000005e040000000b000008040000,Microsoft Xbox One Elite 2 pad,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,
|
||||
030000005e040000ea02000008040000,Microsoft Xbox One S pad,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,
|
||||
03000000c62400001a53000000010000,PowerA Mini Pro Ex,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,
|
||||
050000004d4f435554452d3035335800,Mocute 053X,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||
050000004d4f435554452d3035305800,Mocute 054X,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,
|
||||
05000000d6200000e589000001000000,Moga 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
|
||||
05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
|
||||
05000000d62000007162000001000000,Moga Pro 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
|
||||
@@ -390,10 +390,11 @@
|
||||
030000001008000001e5000010010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Linux,
|
||||
060000007e0500003713000000000000,Nintendo 3DS,a:b0,b:b1,back:b8,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,
|
||||
060000007e0500000820000000000000,Nintendo Combined Joy-Cons (joycond),a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
|
||||
030000007e0500003703000000016800,Nintendo GameCube Controller,a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,platform:Linux,
|
||||
050000004c69632050726f20436f6e00,Nintendo Switch Controller,a:b0,b:b1,x:b2,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux,
|
||||
030000007e0500003703000000016800,Nintendo GameCube Controller,a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,platform:Linux,
|
||||
03000000790000004618000010010000,Nintendo GameCube Controller Adapter,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5~,righty:a2~,start:b9,x:b2,y:b3,platform:Linux,
|
||||
050000004c69632050726f20436f6e00,Nintendo Switch Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||
050000007e0500000620000001800000,Nintendo Switch Left Joy-Con,a:b9,b:b8,back:b5,leftshoulder:b2,leftstick:b6,leftx:a1,lefty:a0~,rightshoulder:b4,start:b0,x:b7,y:b10,platform:Linux,
|
||||
03000000d620000013a7000011010000,Nintendo Switch PowerA Wired Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000007e0500000920000011810000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
|
||||
050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||
050000007e0500000920000001800000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
|
||||
@@ -408,7 +409,6 @@
|
||||
03000000451300000830000010010000,NYKO CORE,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:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||
19000000010000000100000001010000,odroidgo2 joypad,a:b1,b:b0,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,guide:b10,leftshoulder:b4,leftstick:b12,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b13,righttrigger:b14,start:b15,x:b2,y:b3,platform:Linux,
|
||||
19000000010000000200000011000000,odroidgo2 joypad v11,a:b1,b:b0,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b12,leftshoulder:b4,leftstick:b14,lefttrigger:b13,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:b16,start:b17,x:b2,y:b3,platform:Linux,
|
||||
030000005e0400000202000000010000,Xbox pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
|
||||
03000000c0160000dc27000001010000,OnyxSoft Dual JoyDivision,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,platform:Linux,
|
||||
05000000362800000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,
|
||||
05000000362800000100000003010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,
|
||||
@@ -418,31 +418,26 @@
|
||||
030000006f0e0000b802000001010000,PDP Afterglow Wired Xbox One 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,
|
||||
030000006f0e0000b802000013020000,PDP Afterglow Wired Xbox One 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,
|
||||
030000006f0e00006401000001010000,PDP Battlefield 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,
|
||||
030000006f0e00008001000011010000,PDP Faceoff Wired Pro Controller for Nintendo Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000006f0e00003101000000010000,PDP EA Sports 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,
|
||||
030000006f0e00008001000011010000,PDP Faceoff Wired Pro Controller for Nintendo Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000006f0e0000c802000012010000,PDP Kingdom Hearts 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,
|
||||
030000006f0e00008701000011010000,PDP Rock Candy Wired Controller for Nintendo Switch,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,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,
|
||||
03000000c6240000fefa000000010000,Rock Candy Xbox 360 Controller, 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,
|
||||
030000006f0e00000901000011010000,PDP Versus Fighting Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000006f0e0000a802000023020000,PDP Wired Controller for Xbox One,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||
030000006f0e00008501000011010000,PDP Wired Fight Pad Pro for Nintendo Switch,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,
|
||||
030000006f0e0000a702000023020000,PDP Xbox One Raven Black,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,
|
||||
0500000049190000030400001b010000,Ipega PG9099,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,
|
||||
05000000491900000204000000000000,Ipega PG9118,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,
|
||||
030000006f0e0000a702000023020000,PDP Xbox One Raven Black,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
030000004c050000da0c000011010000,Playstation Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
|
||||
03000000d9040000160f000000010000,Playstation Controller Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
|
||||
030000004c0500003713000011010000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000c62400000053000000010000,PowerA,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,
|
||||
03000000c62400003a54000001010000,PowerA 1428124-01,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,
|
||||
03000000c62400001a53000000010000,PowerA Mini Pro Ex,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,
|
||||
03000000d62000006dca000011010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000d62000000228000001010000,PowerA Wired Controller for 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,
|
||||
03000000d62000000220000001010000,PowerA Wired Controller for Xbox One and Xbox Series S and X,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux,
|
||||
03000000c62400001a58000001010000,PowerA 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,
|
||||
03000000c62400001a54000001010000,PowerA Xbox One Mini Wired Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
03000000d620000013a7000011010000,Nintendo Switch PowerA Wired Controller,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux,
|
||||
030000006d040000d2ca000011010000,Precision Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000ba2200000701000001010000,Technology Innovation PS2 Adapter,b:b1,a:b0,x:b3,y:b2,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:b6,righttrigger:b7,platform:Linux,
|
||||
03000000430b00000300000000010000,EMS Production PS2 Adapter,b:b1,a:b2,x:b3,y:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:b12,dpleft:b15,dpdown:b14,dpright:b13,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:b4,righttrigger:b5,platform:Linux,
|
||||
03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
|
||||
03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000004c0500006802000010010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,
|
||||
@@ -475,19 +470,20 @@
|
||||
050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000ff000000cb01000010010000,PSP,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,
|
||||
03000000300f00001211000011010000,Qanba Arcade Joystick,a:b2,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b9,x:b1,y:b3,platform:Linux,
|
||||
03000000300f00001210000010010000,Qanba Joystick Plus,a:b0,b:b1,back:b8,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,start:b9,x:b2,y:b3,platform:Linux,
|
||||
030000009b2800004200000001010000,Raphnet Technologies Dual NES to USB v2.0,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Linux,
|
||||
030000009b2800003200000001010000,Raphnet Technologies GC/N64 to USB v3.4,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
|
||||
030000009b2800006000000001010000,Raphnet Technologies GC/N64 to USB v3.6,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
|
||||
030000009b2800000300000001010000,raphnet.net 4nes4snes v1.5,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux,
|
||||
030000008916000001fd000024010000,Razer Onza Classic Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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,
|
||||
030000008916000000fd000024010000,Razer Onza Tournament Edition,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,
|
||||
03000000321500000810000011010000,Razer Panthera Evo Arcade Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000321500000204000011010000,Razer Panthera PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000321500000104000011010000,Razer Panthera PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000321500000810000011010000,Razer Panthera Evo Arcade Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000321500000010000011010000,Razer Rainu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000321500000507000000010000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
05000000321500000a10000001000000,Razer Raiju Tournament Edition,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000321500000710000000010000,Razer Raiju Tournament Edition Wired,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000321500000010000011010000,Razer Rainu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000321500000011000011010000,Razer Raion Fightpad for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000008916000000fe000024010000,Razer Sabertooth,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,
|
||||
03000000c6240000045d000024010000,Razer Sabertooth,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,
|
||||
@@ -502,16 +498,17 @@
|
||||
030000006b140000130d000011010000,Revolution Pro Controller 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||
030000006f0e00001f01000000010000,Rock Candy,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,
|
||||
030000006f0e00001e01000011010000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000c6240000fefa000000010000,Rock Candy Xbox 360 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,
|
||||
030000006f0e00004601000001010000,Rock Candy Xbox One Controller,a:b0,b:b1,back:b6,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,
|
||||
03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000a30600001005000000010000,Saitek P150,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b2,righttrigger:b5,x:b3,y:b4,platform:Linux,
|
||||
03000000a30600000701000000010000,Saitek P220,a:b2,b:b3,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,x:b0,y:b1,platform:Linux,
|
||||
03000000a30600000cff000010010000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b0,y:b1,platform:Linux,
|
||||
03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,platform:Linux,
|
||||
03000000a306000018f5000010010000,Saitek P3200 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000300f00001201000010010000,Saitek P380,a:b2,b:b3,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:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
|
||||
03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux,
|
||||
03000000a30600000b04000000010000,Saitek P990 Dual Analog Pad,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Linux,
|
||||
03000000a306000018f5000010010000,Saitek P3200 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000a306000020f6000011010000,Saitek PS2700 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000d81d00000e00000010010000,Savior,a:b0,b:b1,back:b8,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,start:b9,x:b4,y:b5,platform:Linux,
|
||||
03000000a30c00002500000011010000,Sega Genesis Mini 3B controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,righttrigger:b5,start:b9,platform:Linux,
|
||||
@@ -546,9 +543,10 @@
|
||||
030000003b07000004a1000000010000,Suncom SFX Plus for USB,a:b0,b:b2,back:b7,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b5,start:b8,x:b1,y:b3,platform:Linux,
|
||||
03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,
|
||||
0300000000f00000f100000000010000,Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux,
|
||||
03000000457500002211000010010000,SZMY Power 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,
|
||||
030000008f0e00000d31000010010000,SZMY Power 3 Turbo,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000457500002211000010010000,SZMY Power 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,
|
||||
030000008f0e00001431000010010000,SZMY Power PS3 gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
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,
|
||||
030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,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,
|
||||
030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3 in 1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||
@@ -580,12 +578,15 @@
|
||||
050000000d0f0000f600000001000000,Wireless HORIPAD Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||
030000005e0400008e02000010010000,Xbox 360 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,
|
||||
030000005e0400008e02000014010000,Xbox 360 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,
|
||||
0000000058626f782033363020576900,Xbox 360 Wireless Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux,
|
||||
030000005e0400001907000000010000,Xbox 360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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,
|
||||
030000005e0400009102000007010000,Xbox 360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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,
|
||||
030000005e040000a102000000010000,Xbox 360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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,
|
||||
030000005e040000a102000007010000,Xbox 360 Wireless 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,
|
||||
0000000058626f782033363020576900,Xbox 360 Wireless Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux,
|
||||
030000005e0400008e02000000010000,Xbox 360 Wireless EasySMX,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,
|
||||
030000005e040000a102000014010000,Xbox 360 Wireless Receiver,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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,
|
||||
030000006f0e00001304000000010000,Xbox 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,
|
||||
03000000ffff0000ffff000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
|
||||
0000000058626f782047616d65706100,Xbox Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
|
||||
030000005e0400000a0b000005040000,Xbox One Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,
|
||||
030000005e040000d102000002010000,Xbox One 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,
|
||||
@@ -597,12 +598,12 @@
|
||||
050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,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,
|
||||
030000005e040000ea02000001030000,Xbox One Wireless Controller (Model 1708),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,
|
||||
060000005e040000120b000007050000,Xbox One Wireless Controller (Model 1914),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,
|
||||
030000005e0400000202000000010000,Xbox pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
|
||||
030000005e040000120b000001050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
030000005e040000120b000005050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
030000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
050000005e040000130b000001050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
050000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
030000005e040000120b000005050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
030000005e0400008e02000000010000,Xbox 360 Wireless EasySMX,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,
|
||||
03000000450c00002043000010010000,XEOX Gamepad SL6556 BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||
03000000ac0500005b05000010010000,Xiaoji Gamesir G3w,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,
|
||||
05000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Linux,
|
||||
@@ -49,7 +49,7 @@ VS_OUTPUT vs_main(VS_INPUT input)
|
||||
return output;
|
||||
}
|
||||
|
||||
PS_OUTPUT ps_main0(PS_INPUT input)
|
||||
PS_OUTPUT ps_copy(PS_INPUT input)
|
||||
{
|
||||
PS_OUTPUT output;
|
||||
|
||||
@@ -58,7 +58,7 @@ PS_OUTPUT ps_main0(PS_INPUT input)
|
||||
return output;
|
||||
}
|
||||
|
||||
PS_OUTPUT ps_main7(PS_INPUT input)
|
||||
PS_OUTPUT ps_filter_transparency(PS_INPUT input)
|
||||
{
|
||||
PS_OUTPUT output;
|
||||
|
||||
@@ -95,7 +95,7 @@ float4 ps_scanlines(PS_INPUT input, int i)
|
||||
return sample_c(input.t) * saturate(mask[i] + 0.5f);
|
||||
}
|
||||
|
||||
uint ps_main1(PS_INPUT input) : SV_Target0
|
||||
uint ps_convert_rgba8_16bits(PS_INPUT input) : SV_Target0
|
||||
{
|
||||
float4 c = sample_c(input.t);
|
||||
|
||||
@@ -106,7 +106,7 @@ uint ps_main1(PS_INPUT input) : SV_Target0
|
||||
return (i.x & 0x001f) | (i.y & 0x03e0) | (i.z & 0x7c00) | (i.w & 0x8000);
|
||||
}
|
||||
|
||||
PS_OUTPUT ps_main2(PS_INPUT input)
|
||||
PS_OUTPUT ps_datm1(PS_INPUT input)
|
||||
{
|
||||
PS_OUTPUT output;
|
||||
|
||||
@@ -117,7 +117,7 @@ PS_OUTPUT ps_main2(PS_INPUT input)
|
||||
return output;
|
||||
}
|
||||
|
||||
PS_OUTPUT ps_main3(PS_INPUT input)
|
||||
PS_OUTPUT ps_datm0(PS_INPUT input)
|
||||
{
|
||||
PS_OUTPUT output;
|
||||
|
||||
@@ -128,7 +128,7 @@ PS_OUTPUT ps_main3(PS_INPUT input)
|
||||
return output;
|
||||
}
|
||||
|
||||
PS_OUTPUT ps_main4(PS_INPUT input)
|
||||
PS_OUTPUT ps_mod256(PS_INPUT input)
|
||||
{
|
||||
PS_OUTPUT output;
|
||||
|
||||
@@ -142,7 +142,7 @@ PS_OUTPUT ps_main4(PS_INPUT input)
|
||||
return output;
|
||||
}
|
||||
|
||||
PS_OUTPUT ps_main5(PS_INPUT input) // scanlines
|
||||
PS_OUTPUT ps_filter_scanlines(PS_INPUT input)
|
||||
{
|
||||
PS_OUTPUT output;
|
||||
|
||||
@@ -153,7 +153,7 @@ PS_OUTPUT ps_main5(PS_INPUT input) // scanlines
|
||||
return output;
|
||||
}
|
||||
|
||||
PS_OUTPUT ps_main6(PS_INPUT input) // diagonal
|
||||
PS_OUTPUT ps_filter_diagonal(PS_INPUT input)
|
||||
{
|
||||
PS_OUTPUT output;
|
||||
|
||||
@@ -164,7 +164,7 @@ PS_OUTPUT ps_main6(PS_INPUT input) // diagonal
|
||||
return output;
|
||||
}
|
||||
|
||||
PS_OUTPUT ps_main8(PS_INPUT input) // triangular
|
||||
PS_OUTPUT ps_filter_triangular(PS_INPUT input)
|
||||
{
|
||||
PS_OUTPUT output;
|
||||
|
||||
@@ -177,7 +177,7 @@ PS_OUTPUT ps_main8(PS_INPUT input) // triangular
|
||||
}
|
||||
|
||||
static const float PI = 3.14159265359f;
|
||||
PS_OUTPUT ps_main9(PS_INPUT input) // triangular
|
||||
PS_OUTPUT ps_filter_complex(PS_INPUT input) // triangular
|
||||
{
|
||||
PS_OUTPUT output;
|
||||
|
||||
@@ -191,13 +191,13 @@ PS_OUTPUT ps_main9(PS_INPUT input) // triangular
|
||||
return output;
|
||||
}
|
||||
|
||||
uint ps_main10(PS_INPUT input) : SV_Target0
|
||||
uint ps_convert_float32_32bits(PS_INPUT input) : SV_Target0
|
||||
{
|
||||
// Convert a FLOAT32 depth texture into a 32 bits UINT texture
|
||||
return uint(exp2(32.0f) * sample_c(input.t).r);
|
||||
}
|
||||
|
||||
PS_OUTPUT ps_main11(PS_INPUT input)
|
||||
PS_OUTPUT ps_convert_float32_rgba8(PS_INPUT input)
|
||||
{
|
||||
PS_OUTPUT output;
|
||||
|
||||
@@ -212,7 +212,7 @@ PS_OUTPUT ps_main11(PS_INPUT input)
|
||||
return output;
|
||||
}
|
||||
|
||||
PS_OUTPUT ps_main12(PS_INPUT input)
|
||||
PS_OUTPUT ps_convert_float16_rgb5a1(PS_INPUT input)
|
||||
{
|
||||
PS_OUTPUT output;
|
||||
|
||||
@@ -225,7 +225,7 @@ PS_OUTPUT ps_main12(PS_INPUT input)
|
||||
|
||||
return output;
|
||||
}
|
||||
float ps_main13(PS_INPUT input) : SV_Depth
|
||||
float ps_convert_rgba8_float32(PS_INPUT input) : SV_Depth
|
||||
{
|
||||
// Convert a RRGBA texture into a float depth texture
|
||||
// FIXME: I'm afraid of the accuracy
|
||||
@@ -234,7 +234,7 @@ float ps_main13(PS_INPUT input) : SV_Depth
|
||||
return dot(sample_c(input.t), bitSh);
|
||||
}
|
||||
|
||||
float ps_main14(PS_INPUT input) : SV_Depth
|
||||
float ps_convert_rgba8_float24(PS_INPUT input) : SV_Depth
|
||||
{
|
||||
// Same as above but without the alpha channel (24 bits Z)
|
||||
|
||||
@@ -244,7 +244,7 @@ float ps_main14(PS_INPUT input) : SV_Depth
|
||||
return dot(sample_c(input.t).rgb, bitSh);
|
||||
}
|
||||
|
||||
float ps_main15(PS_INPUT input) : SV_Depth
|
||||
float ps_convert_rgba8_float16(PS_INPUT input) : SV_Depth
|
||||
{
|
||||
// Same as above but without the A/B channels (16 bits Z)
|
||||
|
||||
@@ -255,7 +255,7 @@ float ps_main15(PS_INPUT input) : SV_Depth
|
||||
return dot(sample_c(input.t).rg, bitSh);
|
||||
}
|
||||
|
||||
float ps_main16(PS_INPUT input) : SV_Depth
|
||||
float ps_convert_rgb5a1_float16(PS_INPUT input) : SV_Depth
|
||||
{
|
||||
// Convert a RGB5A1 (saved as RGBA8) color to a 16 bit Z
|
||||
// FIXME: I'm afraid of the accuracy
|
||||
@@ -266,7 +266,7 @@ float ps_main16(PS_INPUT input) : SV_Depth
|
||||
return dot(float4(color), bitSh);
|
||||
}
|
||||
|
||||
PS_OUTPUT ps_main17(PS_INPUT input)
|
||||
PS_OUTPUT ps_convert_rgba_8i(PS_INPUT input)
|
||||
{
|
||||
PS_OUTPUT output;
|
||||
|
||||
@@ -358,7 +358,7 @@ PS_OUTPUT ps_main17(PS_INPUT input)
|
||||
}
|
||||
|
||||
// DUMMY
|
||||
PS_OUTPUT ps_main18(PS_INPUT input)
|
||||
PS_OUTPUT ps_yuv(PS_INPUT input)
|
||||
{
|
||||
PS_OUTPUT output;
|
||||
|
||||
@@ -367,11 +367,11 @@ PS_OUTPUT ps_main18(PS_INPUT input)
|
||||
return output;
|
||||
}
|
||||
|
||||
PS_OUTPUT ps_main19(PS_INPUT input)
|
||||
PS_OUTPUT ps_osd(PS_INPUT input)
|
||||
{
|
||||
PS_OUTPUT output;
|
||||
|
||||
output.c = input.c * float4(1.0, 1.0, 1.0, sample_c(input.t).r);
|
||||
output.c = input.c * float4(1.0, 1.0, 1.0, sample_c(input.t).a);
|
||||
|
||||
return output;
|
||||
}
|
||||
@@ -410,6 +410,23 @@ float4 fetch_red(int2 xy)
|
||||
return sample_p(rt.r) * 255.0f;
|
||||
}
|
||||
|
||||
float4 fetch_green(int2 xy)
|
||||
{
|
||||
float4 rt;
|
||||
|
||||
if ((PS_DEPTH_FMT == 1) || (PS_DEPTH_FMT == 2))
|
||||
{
|
||||
int depth = (fetch_raw_depth(xy) >> 8) & 0xFF;
|
||||
rt = (float4)(depth) / 255.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
rt = fetch_raw_color(xy);
|
||||
}
|
||||
|
||||
return sample_p(rt.g) * 255.0f;
|
||||
}
|
||||
|
||||
float4 fetch_blue(int2 xy)
|
||||
{
|
||||
float4 rt;
|
||||
@@ -427,12 +444,6 @@ float4 fetch_blue(int2 xy)
|
||||
return sample_p(rt.b) * 255.0f;
|
||||
}
|
||||
|
||||
float4 fetch_green(int2 xy)
|
||||
{
|
||||
float4 rt = fetch_raw_color(xy);
|
||||
return sample_p(rt.g) * 255.0f;
|
||||
}
|
||||
|
||||
float4 fetch_alpha(int2 xy)
|
||||
{
|
||||
float4 rt = fetch_raw_color(xy);
|
||||
@@ -667,6 +678,24 @@ void ps_dither(inout float3 C, float2 pos_xy)
|
||||
}
|
||||
}
|
||||
|
||||
void ps_color_clamp_wrap(inout float3 C)
|
||||
{
|
||||
// When dithering the bottom 3 bits become meaningless and cause lines in the picture
|
||||
// so we need to limit the color depth on dithered items
|
||||
if (SW_BLEND || PS_DITHER)
|
||||
{
|
||||
// Standard Clamp
|
||||
if (PS_COLCLIP == 0 && PS_HDR == 0)
|
||||
C = clamp(C, (float3)0.0f, (float3)255.0f);
|
||||
|
||||
// In 16 bits format, only 5 bits of color are used. It impacts shadows computation of Castlevania
|
||||
if (PS_DFMT == FMT_16)
|
||||
C = (float3)((int3)C & (int3)0xF8);
|
||||
else if (PS_COLCLIP == 1 && PS_HDR == 0)
|
||||
C = (float3)((int3)C & (int3)0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
void ps_blend(inout float4 Color, float As, float2 pos_xy)
|
||||
{
|
||||
if (SW_BLEND)
|
||||
@@ -688,19 +717,6 @@ void ps_blend(inout float4 Color, float As, float2 pos_xy)
|
||||
// PABE
|
||||
if (PS_PABE)
|
||||
Color.rgb = (As >= 1.0f) ? Color.rgb : Cs;
|
||||
|
||||
// Dithering
|
||||
ps_dither(Color.rgb, pos_xy);
|
||||
|
||||
// Standard Clamp
|
||||
if (PS_COLCLIP == 0 && PS_HDR == 0)
|
||||
Color.rgb = clamp(Color.rgb, (float3)0.0f, (float3)255.0f);
|
||||
|
||||
// In 16 bits format, only 5 bits of color are used. It impacts shadows computation of Castlevania
|
||||
if (PS_DFMT == FMT_16)
|
||||
Color.rgb = (float3)((int3)Color.rgb & (int3)0xF8);
|
||||
else if (PS_COLCLIP == 1 && PS_HDR == 0)
|
||||
Color.rgb = (float3)((int3)Color.rgb & (int3)0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -752,21 +768,14 @@ PS_OUTPUT ps_main(PS_INPUT input)
|
||||
if (C.a < A_one) C.a += A_one;
|
||||
}
|
||||
|
||||
if (!SW_BLEND)
|
||||
ps_dither(C.rgb, input.p.xy);
|
||||
|
||||
ps_blend(C, alpha_blend, input.p.xy);
|
||||
|
||||
ps_fbmask(C, input.p.xy);
|
||||
ps_dither(C.rgb, input.p.xy);
|
||||
|
||||
// When dithering the bottom 3 bits become meaningless and cause lines in the picture
|
||||
// so we need to limit the color depth on dithered items
|
||||
// SW_BLEND already deals with this so no need to do in those cases
|
||||
if (!SW_BLEND && PS_DITHER && PS_DFMT == FMT_16 && !PS_COLCLIP)
|
||||
{
|
||||
C.rgb = clamp(C.rgb, (float3)0.0f, (float3)255.0f);
|
||||
C.rgb = (uint3)((uint3)C.rgb & (uint3)0xF8);
|
||||
}
|
||||
// Color clamp/wrap needs to be done after sw blending and dithering
|
||||
ps_color_clamp_wrap(C.rgb);
|
||||
|
||||
ps_fbmask(C, input.p.xy);
|
||||
|
||||
output.c0 = C / 255.0f;
|
||||
output.c1 = (float4)(alpha_blend);
|
||||
+5
-8
@@ -52,8 +52,7 @@ layout(std140, binding = 15) uniform cb15
|
||||
|
||||
int EMODA;
|
||||
int EMODC;
|
||||
int _pad0;
|
||||
int _pad1;
|
||||
ivec2 pad_cb15;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -63,7 +62,8 @@ layout(std140, binding = 20) uniform cb20
|
||||
vec2 VertexScale;
|
||||
vec2 VertexOffset;
|
||||
|
||||
vec4 TextureOffset;
|
||||
vec2 TextureScale;
|
||||
vec2 TextureOffset;
|
||||
|
||||
vec2 PointSize;
|
||||
uint MaxDepth;
|
||||
@@ -80,7 +80,7 @@ layout(std140, binding = 21) uniform cb21
|
||||
vec4 WH;
|
||||
|
||||
vec2 TA;
|
||||
float pad0_cb21;
|
||||
float MaxDepthPS;
|
||||
float Af;
|
||||
|
||||
uvec4 MskFix;
|
||||
@@ -91,12 +91,9 @@ layout(std140, binding = 21) uniform cb21
|
||||
|
||||
vec4 MinMax;
|
||||
|
||||
vec2 TextureScale;
|
||||
vec2 pad_cb21;
|
||||
vec2 TC_OffsetHack;
|
||||
|
||||
vec3 pad1_cb21;
|
||||
float MaxDepthPS;
|
||||
|
||||
mat4 DitherMatrix;
|
||||
};
|
||||
#endif
|
||||
@@ -42,7 +42,7 @@ in SHADER
|
||||
} PSin;
|
||||
|
||||
// Give a different name so I remember there is a special case!
|
||||
#if defined(ps_main1) || defined(ps_main10)
|
||||
#if defined(ps_convert_rgba8_16bits) || defined(ps_convert_float32_32bits)
|
||||
layout(location = 0) out uint SV_Target1;
|
||||
#else
|
||||
layout(location = 0) out vec4 SV_Target0;
|
||||
@@ -65,15 +65,15 @@ vec4 ps_crt(uint i)
|
||||
return sample_c() * clamp((mask[i] + 0.5f), 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
#ifdef ps_main0
|
||||
void ps_main0()
|
||||
#ifdef ps_copy
|
||||
void ps_copy()
|
||||
{
|
||||
SV_Target0 = sample_c();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_main1
|
||||
void ps_main1()
|
||||
#ifdef ps_convert_rgba8_16bits
|
||||
void ps_convert_rgba8_16bits()
|
||||
{
|
||||
// Input Color is RGBA8
|
||||
|
||||
@@ -117,16 +117,16 @@ void ps_main1()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_main10
|
||||
void ps_main10()
|
||||
#ifdef ps_convert_float32_32bits
|
||||
void ps_convert_float32_32bits()
|
||||
{
|
||||
// Convert a GL_FLOAT32 depth texture into a 32 bits UINT texture
|
||||
SV_Target1 = uint(exp2(32.0f) * sample_c().r);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_main11
|
||||
void ps_main11()
|
||||
#ifdef ps_convert_float32_rgba8
|
||||
void ps_convert_float32_rgba8()
|
||||
{
|
||||
// Convert a GL_FLOAT32 depth texture into a RGBA color texture
|
||||
const vec4 bitSh = vec4(exp2(24.0f), exp2(16.0f), exp2(8.0f), exp2(0.0f));
|
||||
@@ -138,8 +138,8 @@ void ps_main11()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_main12
|
||||
void ps_main12()
|
||||
#ifdef ps_convert_float16_rgb5a1
|
||||
void ps_convert_float16_rgb5a1()
|
||||
{
|
||||
// Convert a GL_FLOAT32 (only 16 lsb) depth into a RGB5A1 color texture
|
||||
const vec4 bitSh = vec4(exp2(32.0f), exp2(27.0f), exp2(22.0f), exp2(17.0f));
|
||||
@@ -150,8 +150,8 @@ void ps_main12()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_main13
|
||||
void ps_main13()
|
||||
#ifdef ps_convert_rgba8_float32
|
||||
void ps_convert_rgba8_float32()
|
||||
{
|
||||
// Convert a RRGBA texture into a float depth texture
|
||||
// FIXME: I'm afraid of the accuracy
|
||||
@@ -160,8 +160,8 @@ void ps_main13()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_main14
|
||||
void ps_main14()
|
||||
#ifdef ps_convert_rgba8_float24
|
||||
void ps_convert_rgba8_float24()
|
||||
{
|
||||
// Same as above but without the alpha channel (24 bits Z)
|
||||
|
||||
@@ -172,8 +172,8 @@ void ps_main14()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_main15
|
||||
void ps_main15()
|
||||
#ifdef ps_convert_rgba8_float16
|
||||
void ps_convert_rgba8_float16()
|
||||
{
|
||||
// Same as above but without the A/B channels (16 bits Z)
|
||||
|
||||
@@ -184,8 +184,8 @@ void ps_main15()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_main16
|
||||
void ps_main16()
|
||||
#ifdef ps_convert_rgb5a1_float16
|
||||
void ps_convert_rgb5a1_float16()
|
||||
{
|
||||
// Convert a RGB5A1 (saved as RGBA8) color to a 16 bit Z
|
||||
// FIXME: I'm afraid of the accuracy
|
||||
@@ -196,8 +196,8 @@ void ps_main16()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_main17
|
||||
void ps_main17()
|
||||
#ifdef ps_convert_rgba_8i
|
||||
void ps_convert_rgba_8i()
|
||||
{
|
||||
|
||||
// Potential speed optimization. There is a high probability that
|
||||
@@ -278,15 +278,15 @@ void ps_main17()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_main19
|
||||
void ps_main19()
|
||||
#ifdef ps_osd
|
||||
void ps_osd()
|
||||
{
|
||||
SV_Target0 = PSin.c * vec4(1.0, 1.0, 1.0, sample_c().r);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_main7
|
||||
void ps_main7()
|
||||
#ifdef ps_filter_transparency
|
||||
void ps_filter_transparency()
|
||||
{
|
||||
vec4 c = sample_c();
|
||||
|
||||
@@ -296,7 +296,7 @@ void ps_main7()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_main5
|
||||
#ifdef ps_filter_scanlines
|
||||
vec4 ps_scanlines(uint i)
|
||||
{
|
||||
vec4 mask[2] =
|
||||
@@ -308,7 +308,7 @@ vec4 ps_scanlines(uint i)
|
||||
return sample_c() * clamp((mask[i] + 0.5f), 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
void ps_main5() // scanlines
|
||||
void ps_filter_scanlines() // scanlines
|
||||
{
|
||||
highp uvec4 p = uvec4(gl_FragCoord);
|
||||
|
||||
@@ -318,8 +318,8 @@ void ps_main5() // scanlines
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_main6
|
||||
void ps_main6() // diagonal
|
||||
#ifdef ps_filter_diagonal
|
||||
void ps_filter_diagonal() // diagonal
|
||||
{
|
||||
highp uvec4 p = uvec4(gl_FragCoord);
|
||||
|
||||
@@ -329,8 +329,8 @@ void ps_main6() // diagonal
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_main8
|
||||
void ps_main8() // triangular
|
||||
#ifdef ps_filter_triangular
|
||||
void ps_filter_triangular() // triangular
|
||||
{
|
||||
highp uvec4 p = uvec4(gl_FragCoord);
|
||||
|
||||
@@ -340,8 +340,8 @@ void ps_main8() // triangular
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_main9
|
||||
void ps_main9()
|
||||
#ifdef ps_filter_complex
|
||||
void ps_filter_complex()
|
||||
{
|
||||
|
||||
const float PI = 3.14159265359f;
|
||||
@@ -362,8 +362,8 @@ void ps_main9()
|
||||
|
||||
// Used for DATE (stencil)
|
||||
// DATM == 1
|
||||
#ifdef ps_main2
|
||||
void ps_main2()
|
||||
#ifdef ps_datm1
|
||||
void ps_datm1()
|
||||
{
|
||||
if(sample_c().a < (127.5f / 255.0f)) // >= 0x80 pass
|
||||
discard;
|
||||
@@ -372,23 +372,23 @@ void ps_main2()
|
||||
|
||||
// Used for DATE (stencil)
|
||||
// DATM == 0
|
||||
#ifdef ps_main3
|
||||
void ps_main3()
|
||||
#ifdef ps_datm0
|
||||
void ps_datm0()
|
||||
{
|
||||
if((127.5f / 255.0f) < sample_c().a) // < 0x80 pass (== 0x80 should not pass)
|
||||
discard;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_main4
|
||||
void ps_main4()
|
||||
#ifdef ps_mod256
|
||||
void ps_mod256()
|
||||
{
|
||||
SV_Target0 = mod(round(sample_c() * 255.0f), 256.0f) / 255.0f;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ps_main18
|
||||
void ps_main18()
|
||||
#ifdef ps_yuv
|
||||
void ps_yuv()
|
||||
{
|
||||
vec4 i = sample_c();
|
||||
vec4 o;
|
||||
@@ -369,6 +369,17 @@ vec4 fetch_red()
|
||||
return sample_p(rt.r) * 255.0f;
|
||||
}
|
||||
|
||||
vec4 fetch_green()
|
||||
{
|
||||
#if PS_DEPTH_FMT == 1 || PS_DEPTH_FMT == 2
|
||||
int depth = (fetch_raw_depth() >> 8) & 0xFF;
|
||||
vec4 rt = vec4(depth) / 255.0f;
|
||||
#else
|
||||
vec4 rt = fetch_raw_color();
|
||||
#endif
|
||||
return sample_p(rt.g) * 255.0f;
|
||||
}
|
||||
|
||||
vec4 fetch_blue()
|
||||
{
|
||||
#if PS_DEPTH_FMT == 1 || PS_DEPTH_FMT == 2
|
||||
@@ -380,12 +391,6 @@ vec4 fetch_blue()
|
||||
return sample_p(rt.b) * 255.0f;
|
||||
}
|
||||
|
||||
vec4 fetch_green()
|
||||
{
|
||||
vec4 rt = fetch_raw_color();
|
||||
return sample_p(rt.g) * 255.0f;
|
||||
}
|
||||
|
||||
vec4 fetch_alpha()
|
||||
{
|
||||
vec4 rt = fetch_raw_color();
|
||||
@@ -611,7 +616,7 @@ void ps_fbmask(inout vec4 C)
|
||||
#endif
|
||||
}
|
||||
|
||||
void ps_dither(inout vec4 C)
|
||||
void ps_dither(inout vec3 C)
|
||||
{
|
||||
#if PS_DITHER
|
||||
#if PS_DITHER == 2
|
||||
@@ -619,7 +624,35 @@ void ps_dither(inout vec4 C)
|
||||
#else
|
||||
ivec2 fpos = ivec2(gl_FragCoord.xy / ScalingFactor.x);
|
||||
#endif
|
||||
C.rgb += DitherMatrix[fpos.y&3][fpos.x&3];
|
||||
C += DitherMatrix[fpos.y&3][fpos.x&3];
|
||||
#endif
|
||||
}
|
||||
|
||||
void ps_color_clamp_wrap(inout vec3 C)
|
||||
{
|
||||
// When dithering the bottom 3 bits become meaningless and cause lines in the picture
|
||||
// so we need to limit the color depth on dithered items
|
||||
#if SW_BLEND || PS_DITHER
|
||||
|
||||
// Correct the Color value based on the output format
|
||||
#if PS_COLCLIP == 0 && PS_HDR == 0
|
||||
// Standard Clamp
|
||||
C = clamp(C, vec3(0.0f), vec3(255.0f));
|
||||
#endif
|
||||
|
||||
// FIXME rouding of negative float?
|
||||
// compiler uses trunc but it might need floor
|
||||
|
||||
// Warning: normally blending equation is mult(A, B) = A * B >> 7. GPU have the full accuracy
|
||||
// GS: Color = 1, Alpha = 255 => output 1
|
||||
// GPU: Color = 1/255, Alpha = 255/255 * 255/128 => output 1.9921875
|
||||
#if PS_DFMT == FMT_16
|
||||
// In 16 bits format, only 5 bits of colors are used. It impacts shadows computation of Castlevania
|
||||
C = vec3(ivec3(C) & ivec3(0xF8));
|
||||
#elif PS_COLCLIP == 1 && PS_HDR == 0
|
||||
C = vec3(ivec3(C) & ivec3(0xFF));
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -683,29 +716,6 @@ void ps_blend(inout vec4 Color, float As)
|
||||
Color.rgb = (As >= 1.0f) ? Color.rgb : Cs;
|
||||
#endif
|
||||
|
||||
// Dithering
|
||||
ps_dither(Color);
|
||||
|
||||
// Correct the Color value based on the output format
|
||||
#if PS_COLCLIP == 0 && PS_HDR == 0
|
||||
// Standard Clamp
|
||||
Color.rgb = clamp(Color.rgb, vec3(0.0f), vec3(255.0f));
|
||||
#endif
|
||||
|
||||
// FIXME rouding of negative float?
|
||||
// compiler uses trunc but it might need floor
|
||||
|
||||
// Warning: normally blending equation is mult(A, B) = A * B >> 7. GPU have the full accuracy
|
||||
// GS: Color = 1, Alpha = 255 => output 1
|
||||
// GPU: Color = 1/255, Alpha = 255/255 * 255/128 => output 1.9921875
|
||||
#if PS_DFMT == FMT_16
|
||||
// In 16 bits format, only 5 bits of colors are used. It impacts shadows computation of Castlevania
|
||||
|
||||
Color.rgb = vec3(ivec3(Color.rgb) & ivec3(0xF8));
|
||||
#elif PS_COLCLIP == 1 && PS_HDR == 0
|
||||
Color.rgb = vec3(ivec3(Color.rgb) & ivec3(0xFF));
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -834,31 +844,15 @@ void ps_main()
|
||||
return;
|
||||
#endif
|
||||
|
||||
#if !SW_BLEND
|
||||
ps_dither(C);
|
||||
#endif
|
||||
|
||||
ps_blend(C, alpha_blend);
|
||||
|
||||
ps_dither(C.rgb);
|
||||
|
||||
// Color clamp/wrap needs to be done after sw blending and dithering
|
||||
ps_color_clamp_wrap(C.rgb);
|
||||
|
||||
ps_fbmask(C);
|
||||
|
||||
// When dithering the bottom 3 bits become meaningless and cause lines in the picture
|
||||
// so we need to limit the color depth on dithered items
|
||||
// SW_BLEND already deals with this so no need to do in those cases
|
||||
#if !SW_BLEND && PS_DITHER && PS_DFMT == FMT_16 && PS_COLCLIP == 0
|
||||
C.rgb = clamp(C.rgb, vec3(0.0f), vec3(255.0f));
|
||||
C.rgb = uvec3(uvec3(C.rgb) & uvec3(0xF8));
|
||||
#endif
|
||||
|
||||
// #if PS_HDR == 1
|
||||
// Use negative value to avoid overflow of the texture (in accumulation mode)
|
||||
// Note: code were initially done for an Half-Float texture. Due to overflow
|
||||
// the texture was upgraded to a full float. Maybe this code is useless now!
|
||||
// Good testcase is castlevania
|
||||
// if (any(greaterThan(C.rgb, vec3(128.0f)))) {
|
||||
// C.rgb = (C.rgb - 256.0f);
|
||||
// }
|
||||
// #endif
|
||||
SV_Target0 = C / 255.0f;
|
||||
SV_Target1 = vec4(alpha_blend);
|
||||
|
||||
@@ -24,8 +24,8 @@ const float exp_min32 = exp2(-32.0f);
|
||||
|
||||
void texture_coord()
|
||||
{
|
||||
vec2 uv = vec2(i_uv) - TextureOffset.xy;
|
||||
vec2 st = i_st - TextureOffset.xy;
|
||||
vec2 uv = vec2(i_uv) - TextureOffset;
|
||||
vec2 st = i_st - TextureOffset;
|
||||
|
||||
// Float coordinate
|
||||
VSout.t_float.xy = st;
|
||||
@@ -43,7 +43,6 @@ option(BUILD_REPLAY_LOADERS "Build GS replayer to ease testing (developer option
|
||||
# Path and lib option
|
||||
#-------------------------------------------------------------------------------
|
||||
option(PACKAGE_MODE "Use this option to ease packaging of PCSX2 (developer/distribution option)")
|
||||
option(DISABLE_CHEATS_ZIP "Disable including the cheats_ws.zip file")
|
||||
option(DISABLE_PCSX2_WRAPPER "Disable including the PCSX2-linux.sh file")
|
||||
option(DISABLE_SETCAP "Do not set files capabilities")
|
||||
option(XDG_STD "Use XDG standard path instead of the standard PCSX2 path")
|
||||
@@ -59,7 +58,7 @@ endif()
|
||||
if(PACKAGE_MODE)
|
||||
# Compile all source codes with those defines
|
||||
list(APPEND PCSX2_DEFS
|
||||
GAMEINDEX_DIR_COMPILATION=${CMAKE_INSTALL_FULL_DATADIR}/PCSX2
|
||||
PCSX2_APP_DATADIR="${CMAKE_INSTALL_FULL_DATADIR}/PCSX2"
|
||||
DOC_DIR_COMPILATION=${CMAKE_INSTALL_FULL_DOCDIR})
|
||||
endif()
|
||||
|
||||
@@ -73,7 +72,7 @@ endif()
|
||||
#-------------------------------------------------------------------------------
|
||||
option(USE_ASAN "Enable address sanitizer")
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
|
||||
set(USE_CLANG TRUE)
|
||||
message(STATUS "Building with Clang/LLVM.")
|
||||
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
|
||||
@@ -121,15 +120,7 @@ endif()
|
||||
# It only cost several MB so disbable it by default
|
||||
option(CMAKE_BUILD_STRIP "Srip binaries to save a couple of MB (developer option)")
|
||||
|
||||
if(NOT DEFINED CMAKE_BUILD_PO)
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
set(CMAKE_BUILD_PO TRUE)
|
||||
message(STATUS "Enable the building of po files by default in ${CMAKE_BUILD_TYPE} build !!!")
|
||||
else()
|
||||
set(CMAKE_BUILD_PO FALSE)
|
||||
message(STATUS "Disable the building of po files by default in ${CMAKE_BUILD_TYPE} build !!!")
|
||||
endif()
|
||||
endif()
|
||||
option(CMAKE_BUILD_PO "Build po files (modifies git-tracked files)" OFF)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Select the architecture
|
||||
@@ -223,7 +214,10 @@ option(USE_PGO_OPTIMIZE "Enable PGO optimization (use profile)")
|
||||
if(MSVC)
|
||||
add_compile_options("$<$<COMPILE_LANGUAGE:CXX>:/Zc:externConstexpr>")
|
||||
else()
|
||||
add_compile_options(-pipe -fvisibility=hidden -pthread -fno-builtin-strcmp -fno-builtin-memcmp -mfpmath=sse -fno-operator-names)
|
||||
add_compile_options(-pipe -fvisibility=hidden -pthread -fno-builtin-strcmp -fno-builtin-memcmp -mfpmath=sse)
|
||||
|
||||
# -fno-operator-names should only be for C++ files, not C files.
|
||||
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-fno-operator-names>)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
|
||||
+38
-36
@@ -2,16 +2,13 @@
|
||||
#
|
||||
# This will define:
|
||||
#
|
||||
# WAYLAND_FOUND - True if Wayland is found
|
||||
# WAYLAND_LIBRARIES - Link these to use Wayland
|
||||
# WAYLAND_INCLUDE_DIR - Include directory for Wayland
|
||||
# WAYLAND_DEFINITIONS - Compiler flags for using Wayland
|
||||
# Wayland_FOUND - True if Wayland is found
|
||||
#
|
||||
# In addition the following more fine grained variables will be defined:
|
||||
#
|
||||
# WAYLAND_CLIENT_FOUND WAYLAND_CLIENT_INCLUDE_DIR WAYLAND_CLIENT_LIBRARIES
|
||||
# WAYLAND_SERVER_FOUND WAYLAND_SERVER_INCLUDE_DIR WAYLAND_SERVER_LIBRARIES
|
||||
# WAYLAND_EGL_FOUND WAYLAND_EGL_INCLUDE_DIR WAYLAND_EGL_LIBRARIES
|
||||
# The following imported targets:
|
||||
# Wayland::Client - Imported Client
|
||||
# Wayland::Server - Imported Server
|
||||
# Wayland::Egl - Imported Egl
|
||||
# Wayland::Cursor - Imported Cursor
|
||||
#
|
||||
# Copyright (c) 2013 Martin Gräßlin <mgraesslin@kde.org>
|
||||
#
|
||||
@@ -24,39 +21,44 @@ IF (NOT WIN32)
|
||||
SET(WAYLAND_FIND_QUIETLY TRUE)
|
||||
ENDIF ()
|
||||
|
||||
# Use pkg-config to get the directories and then use these values
|
||||
# in the FIND_PATH() and FIND_LIBRARY() calls
|
||||
FIND_PACKAGE(PkgConfig)
|
||||
PKG_CHECK_MODULES(PKG_WAYLAND QUIET wayland-client wayland-server wayland-egl wayland-cursor)
|
||||
FIND_PATH(WAYLAND_CLIENT_INCLUDE_DIR NAMES wayland-client.h)
|
||||
FIND_PATH(WAYLAND_SERVER_INCLUDE_DIR NAMES wayland-server.h)
|
||||
FIND_PATH(WAYLAND_EGL_INCLUDE_DIR NAMES wayland-egl.h)
|
||||
FIND_PATH(WAYLAND_CURSOR_INCLUDE_DIR NAMES wayland-cursor.h)
|
||||
|
||||
SET(WAYLAND_DEFINITIONS ${PKG_WAYLAND_CFLAGS})
|
||||
|
||||
FIND_PATH(WAYLAND_CLIENT_INCLUDE_DIR NAMES wayland-client.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
|
||||
FIND_PATH(WAYLAND_SERVER_INCLUDE_DIR NAMES wayland-server.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
|
||||
FIND_PATH(WAYLAND_EGL_INCLUDE_DIR NAMES wayland-egl.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
|
||||
FIND_PATH(WAYLAND_CURSOR_INCLUDE_DIR NAMES wayland-cursor.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
|
||||
|
||||
FIND_LIBRARY(WAYLAND_CLIENT_LIBRARIES NAMES wayland-client HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
|
||||
FIND_LIBRARY(WAYLAND_SERVER_LIBRARIES NAMES wayland-server HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
|
||||
FIND_LIBRARY(WAYLAND_EGL_LIBRARIES NAMES wayland-egl HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
|
||||
FIND_LIBRARY(WAYLAND_CURSOR_LIBRARIES NAMES wayland-cursor HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
|
||||
|
||||
set(WAYLAND_INCLUDE_DIR ${WAYLAND_CLIENT_INCLUDE_DIR} ${WAYLAND_SERVER_INCLUDE_DIR} ${WAYLAND_EGL_INCLUDE_DIR} ${WAYLAND_CURSOR_INCLUDE_DIR})
|
||||
|
||||
set(WAYLAND_LIBRARIES ${WAYLAND_CLIENT_LIBRARIES} ${WAYLAND_SERVER_LIBRARIES} ${WAYLAND_EGL_LIBRARIES} ${WAYLAND_CURSOR_LIBRARIES})
|
||||
|
||||
list(REMOVE_DUPLICATES WAYLAND_INCLUDE_DIR)
|
||||
FIND_LIBRARY(WAYLAND_CLIENT_LIBRARIES NAMES wayland-client)
|
||||
FIND_LIBRARY(WAYLAND_SERVER_LIBRARIES NAMES wayland-server)
|
||||
FIND_LIBRARY(WAYLAND_EGL_LIBRARIES NAMES wayland-egl)
|
||||
FIND_LIBRARY(WAYLAND_CURSOR_LIBRARIES NAMES wayland-cursor)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_CLIENT DEFAULT_MSG WAYLAND_CLIENT_LIBRARIES WAYLAND_CLIENT_INCLUDE_DIR)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_SERVER DEFAULT_MSG WAYLAND_SERVER_LIBRARIES WAYLAND_SERVER_INCLUDE_DIR)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_EGL DEFAULT_MSG WAYLAND_EGL_LIBRARIES WAYLAND_EGL_INCLUDE_DIR)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_CURSOR DEFAULT_MSG WAYLAND_CURSOR_LIBRARIES WAYLAND_CURSOR_INCLUDE_DIR)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND DEFAULT_MSG WAYLAND_LIBRARIES WAYLAND_INCLUDE_DIR)
|
||||
# FIND_PACKAGE_HANDLE_STANDARD_ARGS is just meant to find the main package and set package found. Not set variables or find individual libs
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Wayland REQUIRED_VARS
|
||||
WAYLAND_CLIENT_LIBRARIES WAYLAND_CLIENT_INCLUDE_DIR
|
||||
WAYLAND_SERVER_LIBRARIES WAYLAND_SERVER_INCLUDE_DIR
|
||||
WAYLAND_EGL_LIBRARIES WAYLAND_EGL_INCLUDE_DIR
|
||||
WAYLAND_CURSOR_LIBRARIES WAYLAND_CURSOR_INCLUDE_DIR
|
||||
)
|
||||
|
||||
if (WAYLAND_CLIENT_INCLUDE_DIR AND WAYLAND_CLIENT_LIBRARIES AND NOT TARGET Wayland::Client)
|
||||
add_library(Wayland::Client UNKNOWN IMPORTED)
|
||||
set_target_properties(Wayland::Client PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${WAYLAND_CLIENT_INCLUDE_DIR}" IMPORTED_LOCATION "${WAYLAND_CLIENT_LIBRARIES}")
|
||||
endif()
|
||||
if (WAYLAND_SERVER_INCLUDE_DIR AND WAYLAND_SERVER_LIBRARIES AND NOT TARGET Wayland::Server)
|
||||
add_library(Wayland::Server UNKNOWN IMPORTED)
|
||||
set_target_properties(Wayland::Server PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${WAYLAND_SERVER_INCLUDE_DIR}" IMPORTED_LOCATION "${WAYLAND_SERVER_LIBRARIES}")
|
||||
endif()
|
||||
if (WAYLAND_EGL_INCLUDE_DIR AND WAYLAND_EGL_LIBRARIES AND NOT TARGET Wayland::Egl)
|
||||
add_library(Wayland::Egl UNKNOWN IMPORTED)
|
||||
set_target_properties(Wayland::Egl PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${WAYLAND_EGL_INCLUDE_DIR}" IMPORTED_LOCATION "${WAYLAND_EGL_LIBRARIES}")
|
||||
endif()
|
||||
if (WAYLAND_CURSOR_INCLUDE_DIR AND WAYLAND_CURSOR_LIBRARIES AND NOT TARGET Wayland::Cursor)
|
||||
add_library(Wayland::Cursor UNKNOWN IMPORTED)
|
||||
set_target_properties(Wayland::Cursor PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${WAYLAND_CURSOR_INCLUDE_DIR}" IMPORTED_LOCATION "${WAYLAND_CURSOR_LIBRARIES}")
|
||||
endif()
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
WAYLAND_INCLUDE_DIR WAYLAND_LIBRARIES
|
||||
WAYLAND_CLIENT_INCLUDE_DIR WAYLAND_CLIENT_LIBRARIES
|
||||
WAYLAND_SERVER_INCLUDE_DIR WAYLAND_SERVER_LIBRARIES
|
||||
WAYLAND_EGL_INCLUDE_DIR WAYLAND_EGL_LIBRARIES
|
||||
|
||||
@@ -162,11 +162,7 @@ else()
|
||||
if(UNIX AND NOT APPLE)
|
||||
find_package(X11 REQUIRED)
|
||||
make_imported_target_if_missing(X11::X11 X11)
|
||||
endif()
|
||||
if(APPLE)
|
||||
check_lib(GIO gio-2.0 gio/gio.h)
|
||||
elseif(UNIX)
|
||||
# Most plugins (if not all) and PCSX2 core need gtk2, so set the required flags
|
||||
|
||||
if (GTK2_API)
|
||||
find_package(GTK2 REQUIRED gtk)
|
||||
alias_library(GTK::gtk GTK2::gtk)
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
|
||||
#if !defined(_WIN32)
|
||||
|
||||
#include "common/AlignedMalloc.h"
|
||||
#include "common/Assertions.h"
|
||||
#include "common/ScopedAlloc.h"
|
||||
|
||||
void* __fastcall _aligned_malloc(size_t size, size_t align)
|
||||
{
|
||||
|
||||
@@ -80,50 +80,57 @@ extern Fnptr_OutOfMemory pxDoOutOfMemory;
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// BaseScopedAlloc
|
||||
// AlignedBuffer
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Base class that allows various ScopedMalloc types to be passed to functions that act
|
||||
// on them.
|
||||
// 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.
|
||||
//
|
||||
// Rationale: This class and the derived varieties are provided as a simple autonomous self-
|
||||
// destructing container for malloc. The entire class is almost completely dependency free,
|
||||
// and thus can be included everywhere and anywhere without dependency hassles.
|
||||
//
|
||||
template <typename T>
|
||||
class BaseScopedAlloc
|
||||
template <typename T, uint align>
|
||||
class AlignedBuffer
|
||||
{
|
||||
protected:
|
||||
T* m_buffer;
|
||||
uint m_size;
|
||||
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:
|
||||
BaseScopedAlloc()
|
||||
AlignedBuffer(size_t size = 0)
|
||||
{
|
||||
m_buffer = NULL;
|
||||
m_size = 0;
|
||||
Alloc(size);
|
||||
}
|
||||
|
||||
virtual ~BaseScopedAlloc()
|
||||
{
|
||||
//pxAssert(m_buffer==NULL);
|
||||
}
|
||||
|
||||
public:
|
||||
size_t GetSize() const { return m_size; }
|
||||
size_t GetLength() const { return m_size; }
|
||||
|
||||
// Allocates the object to the specified size. If an existing allocation is in
|
||||
// place, it is freed and replaced with the new allocation, and all data is lost.
|
||||
// Parameter:
|
||||
// newSize - size of the new allocation, in elements (not bytes!). If the specified
|
||||
// size is 0, the the allocation is freed, same as calling Free().
|
||||
virtual void Alloc(size_t newsize) = 0;
|
||||
void Alloc(size_t newsize)
|
||||
{
|
||||
m_size = newsize;
|
||||
m_buffer.reset();
|
||||
if (!m_size)
|
||||
return;
|
||||
|
||||
// Re-sizes the allocation to the requested size, without any data loss.
|
||||
// Parameter:
|
||||
// newSize - size of the new allocation, in elements (not bytes!). If the specified
|
||||
// size is 0, the the allocation is freed, same as calling Free().
|
||||
virtual void Resize(size_t newsize) = 0;
|
||||
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()
|
||||
{
|
||||
@@ -162,103 +169,3 @@ public:
|
||||
return m_buffer[idx];
|
||||
}
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ScopedAlloc
|
||||
// --------------------------------------------------------------------------------------
|
||||
// A simple container class for a standard malloc 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.
|
||||
//
|
||||
// See docs for BaseScopedAlloc for details and rationale.
|
||||
//
|
||||
template <typename T>
|
||||
class ScopedAlloc : public BaseScopedAlloc<T>
|
||||
{
|
||||
typedef BaseScopedAlloc<T> _parent;
|
||||
|
||||
public:
|
||||
ScopedAlloc(size_t size = 0)
|
||||
: _parent()
|
||||
{
|
||||
Alloc(size);
|
||||
}
|
||||
|
||||
virtual ~ScopedAlloc()
|
||||
{
|
||||
safe_free(this->m_buffer);
|
||||
}
|
||||
|
||||
virtual void Alloc(size_t newsize)
|
||||
{
|
||||
safe_free(this->m_buffer);
|
||||
this->m_size = newsize;
|
||||
if (!this->m_size)
|
||||
return;
|
||||
|
||||
this->m_buffer = (T*)malloc(this->m_size * sizeof(T));
|
||||
if (!this->m_buffer)
|
||||
throw Exception::OutOfMemory(L"ScopedAlloc");
|
||||
}
|
||||
|
||||
virtual void Resize(size_t newsize)
|
||||
{
|
||||
this->m_size = newsize;
|
||||
this->m_buffer = (T*)realloc(this->m_buffer, this->m_size * sizeof(T));
|
||||
|
||||
if (!this->m_buffer)
|
||||
throw Exception::OutOfMemory(L"ScopedAlloc::Resize");
|
||||
}
|
||||
|
||||
using _parent::operator[];
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ScopedAlignedAlloc
|
||||
// --------------------------------------------------------------------------------------
|
||||
// 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.
|
||||
//
|
||||
// See docs for BaseScopedAlloc for details and rationale.
|
||||
//
|
||||
template <typename T, uint align>
|
||||
class ScopedAlignedAlloc : public BaseScopedAlloc<T>
|
||||
{
|
||||
typedef BaseScopedAlloc<T> _parent;
|
||||
|
||||
public:
|
||||
ScopedAlignedAlloc(size_t size = 0)
|
||||
: _parent()
|
||||
{
|
||||
Alloc(size);
|
||||
}
|
||||
|
||||
virtual ~ScopedAlignedAlloc()
|
||||
{
|
||||
safe_aligned_free(this->m_buffer);
|
||||
}
|
||||
|
||||
virtual void Alloc(size_t newsize)
|
||||
{
|
||||
safe_aligned_free(this->m_buffer);
|
||||
this->m_size = newsize;
|
||||
if (!this->m_size)
|
||||
return;
|
||||
|
||||
this->m_buffer = (T*)_aligned_malloc(this->m_size * sizeof(T), align);
|
||||
if (!this->m_buffer)
|
||||
throw Exception::OutOfMemory(L"ScopedAlignedAlloc");
|
||||
}
|
||||
|
||||
virtual void Resize(size_t newsize)
|
||||
{
|
||||
this->m_buffer = (T*)pcsx2_aligned_realloc(this->m_buffer, newsize * sizeof(T), align, this->m_size * sizeof(T));
|
||||
this->m_size = newsize;
|
||||
|
||||
if (!this->m_buffer)
|
||||
throw Exception::OutOfMemory(L"ScopedAlignedAlloc::Resize");
|
||||
}
|
||||
|
||||
using _parent::operator[];
|
||||
};
|
||||
+12
-1
@@ -20,12 +20,14 @@ target_sources(common PRIVATE
|
||||
FastJmp.cpp
|
||||
GL/Context.cpp
|
||||
GL/StreamBuffer.cpp
|
||||
FileSystem.cpp
|
||||
IniInterface.cpp
|
||||
Mutex.cpp
|
||||
Misc.cpp
|
||||
PathUtils.cpp
|
||||
PrecompiledHeader.cpp
|
||||
Perf.cpp
|
||||
ProgressCallback.cpp
|
||||
pxStreams.cpp
|
||||
pxTranslate.cpp
|
||||
RwMutex.cpp
|
||||
@@ -33,6 +35,7 @@ target_sources(common PRIVATE
|
||||
SettingsWrapper.cpp
|
||||
StringHelpers.cpp
|
||||
StringUtil.cpp
|
||||
Timer.cpp
|
||||
ThreadTools.cpp
|
||||
WindowInfo.cpp
|
||||
emitter/bmi.cpp
|
||||
@@ -61,6 +64,7 @@ target_sources(common PRIVATE
|
||||
# x86emitter headers
|
||||
target_sources(common PRIVATE
|
||||
Align.h
|
||||
AlignedMalloc.h
|
||||
Assertions.h
|
||||
boost_spsc_queue.hpp
|
||||
Console.h
|
||||
@@ -68,6 +72,7 @@ target_sources(common PRIVATE
|
||||
EventSource.h
|
||||
Exceptions.h
|
||||
FastJmp.h
|
||||
FileSystem.h
|
||||
General.h
|
||||
GL/Context.h
|
||||
GL/StreamBuffer.h
|
||||
@@ -76,18 +81,19 @@ target_sources(common PRIVATE
|
||||
Path.h
|
||||
PageFaultSource.h
|
||||
PrecompiledHeader.h
|
||||
ProgressCallback.h
|
||||
pxForwardDefs.h
|
||||
pxStreams.h
|
||||
RedtapeWindows.h
|
||||
RwMutex.h
|
||||
SafeArray.h
|
||||
ScopedAlloc.h
|
||||
ScopedGuard.h
|
||||
ScopedPtrMT.h
|
||||
SettingsInterface.h
|
||||
SettingsWrapper.h
|
||||
StringHelpers.h
|
||||
StringUtil.h
|
||||
Timer.h
|
||||
Threading.h
|
||||
TraceLog.h
|
||||
WindowInfo.h
|
||||
@@ -170,6 +176,11 @@ else()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (USE_GCC AND CMAKE_INTERPROCEDURAL_OPTIMIZATION)
|
||||
# GCC LTO doesn't work with asm statements
|
||||
set_source_files_properties(FastJmp.cpp PROPERTIES COMPILE_FLAGS -fno-lto)
|
||||
endif()
|
||||
|
||||
target_link_libraries(common PRIVATE ${LIBC_LIBRARIES} PUBLIC wxWidgets::all glad)
|
||||
target_compile_features(common PUBLIC cxx_std_17)
|
||||
target_include_directories(common PUBLIC ../3rdparty/include ../)
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
pxAssert(EnumIsValid(id)); \
|
||||
} \
|
||||
\
|
||||
extern const wxChar* EnumToString(enumName id)
|
||||
extern const char* EnumToString(enumName id)
|
||||
|
||||
class pxEnumEnd_t
|
||||
{
|
||||
@@ -277,4 +277,4 @@ extern wxString fromAscii(const char* src);
|
||||
|
||||
#include "common/Assertions.h"
|
||||
#include "common/Exceptions.h"
|
||||
#include "common/ScopedAlloc.h"
|
||||
#include "common/AlignedMalloc.h"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,162 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2021 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 <cstdio>
|
||||
#include <ctime>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define FS_OSPATH_SEPARATOR_CHARACTER '\\'
|
||||
#define FS_OSPATH_SEPARATOR_STR "\\"
|
||||
#else
|
||||
#define FS_OSPATH_SEPARATOR_CHARACTER '/'
|
||||
#define FS_OSPATH_SEPARATOR_STR "/"
|
||||
#endif
|
||||
|
||||
enum FILESYSTEM_FILE_ATTRIBUTES
|
||||
{
|
||||
FILESYSTEM_FILE_ATTRIBUTE_DIRECTORY = 1,
|
||||
FILESYSTEM_FILE_ATTRIBUTE_READ_ONLY = 2,
|
||||
FILESYSTEM_FILE_ATTRIBUTE_COMPRESSED = 4,
|
||||
};
|
||||
|
||||
enum FILESYSTEM_FIND_FLAGS
|
||||
{
|
||||
FILESYSTEM_FIND_RECURSIVE = (1 << 0),
|
||||
FILESYSTEM_FIND_RELATIVE_PATHS = (1 << 1),
|
||||
FILESYSTEM_FIND_HIDDEN_FILES = (1 << 2),
|
||||
FILESYSTEM_FIND_FOLDERS = (1 << 3),
|
||||
FILESYSTEM_FIND_FILES = (1 << 4),
|
||||
FILESYSTEM_FIND_KEEP_ARRAY = (1 << 5),
|
||||
};
|
||||
|
||||
struct FILESYSTEM_STAT_DATA
|
||||
{
|
||||
std::time_t ModificationTime;
|
||||
s64 Size;
|
||||
u32 Attributes;
|
||||
};
|
||||
|
||||
struct FILESYSTEM_FIND_DATA
|
||||
{
|
||||
std::time_t ModificationTime;
|
||||
std::string FileName;
|
||||
s64 Size;
|
||||
u32 Attributes;
|
||||
};
|
||||
|
||||
namespace FileSystem
|
||||
{
|
||||
|
||||
using FindResultsArray = std::vector<FILESYSTEM_FIND_DATA>;
|
||||
|
||||
/// Builds a path relative to the specified file
|
||||
std::string BuildRelativePath(const std::string_view& filename, const std::string_view& new_filename);
|
||||
|
||||
/// Joins path components together, producing a new path.
|
||||
std::string JoinPath(const std::string_view& base, const std::string_view& next);
|
||||
|
||||
/// Sanitizes a filename for use in a filesystem.
|
||||
void SanitizeFileName(char* Destination, u32 cbDestination, const char* FileName, bool StripSlashes /* = true */);
|
||||
void SanitizeFileName(std::string& Destination, bool StripSlashes = true);
|
||||
|
||||
/// Returns true if the specified path is an absolute path (C:\Path on Windows or /path on Unix).
|
||||
bool IsAbsolutePath(const std::string_view& path);
|
||||
|
||||
/// Returns a view of the extension of a filename.
|
||||
std::string_view GetExtension(const std::string_view& path);
|
||||
|
||||
/// Removes the extension of a filename.
|
||||
std::string_view StripExtension(const std::string_view& path);
|
||||
|
||||
/// Replaces the extension of a filename with another.
|
||||
std::string ReplaceExtension(const std::string_view& path, const std::string_view& new_extension);
|
||||
|
||||
/// Returns the display name of a filename. Usually this is the same as the path.
|
||||
std::string GetDisplayNameFromPath(const std::string_view& path);
|
||||
|
||||
/// Returns the directory component of a filename.
|
||||
std::string_view GetPathDirectory(const std::string_view& path);
|
||||
|
||||
/// Returns the filename component of a filename.
|
||||
std::string_view GetFileNameFromPath(const std::string_view& path);
|
||||
|
||||
/// Returns the file title (less the extension and path) from a filename.
|
||||
std::string_view GetFileTitleFromPath(const std::string_view& path);
|
||||
|
||||
/// Returns a list of "root directories" (i.e. root/home directories on Linux, drive letters on Windows).
|
||||
std::vector<std::string> GetRootDirectoryList();
|
||||
|
||||
/// Search for files
|
||||
bool FindFiles(const char* path, const char* pattern, u32 flags, FindResultsArray* results);
|
||||
|
||||
/// Stat file
|
||||
bool StatFile(const char* path, struct stat* st);
|
||||
bool StatFile(std::FILE* fp, struct stat* st);
|
||||
bool StatFile(const char* path, FILESYSTEM_STAT_DATA* pStatData);
|
||||
bool StatFile(std::FILE* fp, FILESYSTEM_STAT_DATA* pStatData);
|
||||
s64 GetPathFileSize(const char* path);
|
||||
|
||||
/// File exists?
|
||||
bool FileExists(const char* path);
|
||||
|
||||
/// Directory exists?
|
||||
bool DirectoryExists(const char* path);
|
||||
|
||||
/// Delete file
|
||||
bool DeleteFilePath(const char* path);
|
||||
|
||||
/// Rename file
|
||||
bool RenamePath(const char* OldPath, const char* NewPath);
|
||||
|
||||
/// 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);
|
||||
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);
|
||||
|
||||
std::optional<std::vector<u8>> ReadBinaryFile(const char* filename);
|
||||
std::optional<std::vector<u8>> ReadBinaryFile(std::FILE* fp);
|
||||
std::optional<std::string> ReadFileToString(const char* filename);
|
||||
std::optional<std::string> ReadFileToString(std::FILE* fp);
|
||||
bool WriteBinaryFile(const char* filename, const void* data, size_t data_length);
|
||||
bool WriteFileToString(const char* filename, const std::string_view& sv);
|
||||
|
||||
/// creates a directory in the local filesystem
|
||||
/// if the directory already exists, the return value will be true.
|
||||
/// if Recursive is specified, all parent directories will be created
|
||||
/// if they do not exist.
|
||||
bool CreateDirectoryPath(const char* path, bool recursive);
|
||||
|
||||
/// Returns the path to the current executable.
|
||||
std::string GetProgramPath();
|
||||
|
||||
/// Retrieves the current working directory.
|
||||
std::string GetWorkingDirectory();
|
||||
|
||||
/// Sets the current working directory. Returns true if successful.
|
||||
bool SetWorkingDirectory(const char* path);
|
||||
|
||||
}; // namespace FileSystem
|
||||
@@ -225,6 +225,8 @@ namespace Path
|
||||
extern wxString Combine(const wxString& srcPath, const wxString& srcFile);
|
||||
extern wxString Combine(const wxDirName& srcPath, const wxFileName& srcFile);
|
||||
extern wxString Combine(const wxString& srcPath, const wxDirName& srcFile);
|
||||
extern std::string CombineStdString(const wxDirName& srcPath, const std::string_view& srcFile);
|
||||
extern std::string CombineStdString(const std::string_view& srcPath, const std::string_view& srcFile);
|
||||
extern wxString ReplaceExtension(const wxString& src, const wxString& ext);
|
||||
extern wxString ReplaceFilename(const wxString& src, const wxString& newfilename);
|
||||
extern wxString GetFilename(const wxString& src);
|
||||
|
||||
@@ -149,6 +149,21 @@ wxString Path::Combine(const wxString& srcPath, const wxDirName& srcFile)
|
||||
return (wxDirName(srcPath) + srcFile).ToString();
|
||||
}
|
||||
|
||||
std::string Path::CombineStdString(const wxDirName& srcPath, const std::string_view& srcFile)
|
||||
{
|
||||
const wxString wxResult((srcPath + wxString::FromUTF8(srcFile.data(), srcFile.length())).GetFullPath());
|
||||
const wxCharBuffer wxBuf(wxResult.ToUTF8());
|
||||
return std::string(wxBuf.data(), wxBuf.length());
|
||||
}
|
||||
|
||||
std::string Path::CombineStdString(const std::string_view& srcPath, const std::string_view& srcFile)
|
||||
{
|
||||
const wxDirName srcPathDir(wxString::FromUTF8(srcPath.data(), srcPath.length()));
|
||||
const wxString wxResult((srcPathDir + wxString::FromUTF8(srcFile.data(), srcFile.length())).GetFullPath());
|
||||
const wxCharBuffer wxBuf(wxResult.ToUTF8());
|
||||
return std::string(wxBuf.data(), wxBuf.length());
|
||||
}
|
||||
|
||||
// Replaces the extension of the file with the one given.
|
||||
// This function works for path names as well as file names.
|
||||
wxString Path::ReplaceExtension(const wxString& src, const wxString& ext)
|
||||
|
||||
@@ -0,0 +1,248 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2021 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 "Assertions.h"
|
||||
#include "ProgressCallback.h"
|
||||
#include "StringUtil.h"
|
||||
#include "Console.h"
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <limits>
|
||||
|
||||
ProgressCallback::~ProgressCallback() {}
|
||||
|
||||
void ProgressCallback::SetFormattedStatusText(const char* Format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, Format);
|
||||
const std::string str(StringUtil::StdStringFromFormatV(Format, ap));
|
||||
va_end(ap);
|
||||
|
||||
SetStatusText(str.c_str());
|
||||
}
|
||||
|
||||
void ProgressCallback::DisplayFormattedError(const char* format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
const std::string str(StringUtil::StdStringFromFormatV(format, ap));
|
||||
va_end(ap);
|
||||
|
||||
DisplayError(str.c_str());
|
||||
}
|
||||
|
||||
void ProgressCallback::DisplayFormattedWarning(const char* format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
const std::string str(StringUtil::StdStringFromFormatV(format, ap));
|
||||
va_end(ap);
|
||||
|
||||
DisplayWarning(str.c_str());
|
||||
}
|
||||
|
||||
void ProgressCallback::DisplayFormattedInformation(const char* format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
const std::string str(StringUtil::StdStringFromFormatV(format, ap));
|
||||
va_end(ap);
|
||||
|
||||
DisplayInformation(str.c_str());
|
||||
}
|
||||
|
||||
void ProgressCallback::DisplayFormattedDebugMessage(const char* format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
const std::string str(StringUtil::StdStringFromFormatV(format, ap));
|
||||
va_end(ap);
|
||||
|
||||
DisplayDebugMessage(str.c_str());
|
||||
}
|
||||
|
||||
void ProgressCallback::DisplayFormattedModalError(const char* format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
const std::string str(StringUtil::StdStringFromFormatV(format, ap));
|
||||
va_end(ap);
|
||||
|
||||
ModalError(str.c_str());
|
||||
}
|
||||
|
||||
bool ProgressCallback::DisplayFormattedModalConfirmation(const char* format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
const std::string str(StringUtil::StdStringFromFormatV(format, ap));
|
||||
va_end(ap);
|
||||
|
||||
return ModalConfirmation(str.c_str());
|
||||
}
|
||||
|
||||
void ProgressCallback::DisplayFormattedModalInformation(const char* format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
const std::string str(StringUtil::StdStringFromFormatV(format, ap));
|
||||
va_end(ap);
|
||||
|
||||
ModalInformation(str.c_str());
|
||||
}
|
||||
|
||||
class NullProgressCallbacks final : public ProgressCallback
|
||||
{
|
||||
public:
|
||||
void PushState() override {}
|
||||
void PopState() override {}
|
||||
|
||||
bool IsCancelled() const override { return false; }
|
||||
bool IsCancellable() const override { return false; }
|
||||
|
||||
void SetCancellable(bool cancellable) override {}
|
||||
void SetTitle(const char* title) override {}
|
||||
void SetStatusText(const char* statusText) override {}
|
||||
void SetProgressRange(u32 range) override {}
|
||||
void SetProgressValue(u32 value) override {}
|
||||
void IncrementProgressValue() override {}
|
||||
|
||||
void DisplayError(const char* message) override { Console.Error("%s", message); }
|
||||
void DisplayWarning(const char* message) override { Console.Warning("%s", message); }
|
||||
void DisplayInformation(const char* message) override { Console.WriteLn("%s", message); }
|
||||
void DisplayDebugMessage(const char* message) override { DevCon.WriteLn("%s", message); }
|
||||
|
||||
void ModalError(const char* message) override { Console.Error(message); }
|
||||
bool ModalConfirmation(const char* message) override
|
||||
{
|
||||
Console.WriteLn("%s", message);
|
||||
return false;
|
||||
}
|
||||
void ModalInformation(const char* message) override { Console.WriteLn("%s", message); }
|
||||
};
|
||||
|
||||
static NullProgressCallbacks s_nullProgressCallbacks;
|
||||
ProgressCallback* ProgressCallback::NullProgressCallback = &s_nullProgressCallbacks;
|
||||
|
||||
BaseProgressCallback::BaseProgressCallback()
|
||||
: m_cancellable(false)
|
||||
, m_cancelled(false)
|
||||
, m_progress_range(1)
|
||||
, m_progress_value(0)
|
||||
, m_base_progress_value(0)
|
||||
, m_saved_state(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
BaseProgressCallback::~BaseProgressCallback()
|
||||
{
|
||||
State* pNextState = m_saved_state;
|
||||
while (pNextState != NULL)
|
||||
{
|
||||
State* pCurrentState = pNextState;
|
||||
pNextState = pCurrentState->next_saved_state;
|
||||
delete pCurrentState;
|
||||
}
|
||||
}
|
||||
|
||||
void BaseProgressCallback::PushState()
|
||||
{
|
||||
State* pNewState = new State;
|
||||
pNewState->cancellable = m_cancellable;
|
||||
pNewState->status_text = m_status_text;
|
||||
pNewState->progress_range = m_progress_range;
|
||||
pNewState->progress_value = m_progress_value;
|
||||
pNewState->base_progress_value = m_base_progress_value;
|
||||
pNewState->next_saved_state = m_saved_state;
|
||||
m_saved_state = pNewState;
|
||||
}
|
||||
|
||||
void BaseProgressCallback::PopState()
|
||||
{
|
||||
pxAssert(m_saved_state);
|
||||
State* state = m_saved_state;
|
||||
m_saved_state = nullptr;
|
||||
|
||||
// impose the current position into the previous range
|
||||
const u32 new_progress_value =
|
||||
(m_progress_range != 0) ?
|
||||
static_cast<u32>(((float)m_progress_value / (float)m_progress_range) * (float)state->progress_range) :
|
||||
state->progress_value;
|
||||
|
||||
m_cancellable = state->cancellable;
|
||||
m_status_text = std::move(state->status_text);
|
||||
m_progress_range = state->progress_range;
|
||||
m_progress_value = new_progress_value;
|
||||
|
||||
m_base_progress_value = state->base_progress_value;
|
||||
m_saved_state = state->next_saved_state;
|
||||
delete state;
|
||||
}
|
||||
|
||||
bool BaseProgressCallback::IsCancelled() const
|
||||
{
|
||||
return m_cancelled;
|
||||
}
|
||||
|
||||
bool BaseProgressCallback::IsCancellable() const
|
||||
{
|
||||
return m_cancellable;
|
||||
}
|
||||
|
||||
void BaseProgressCallback::SetCancellable(bool cancellable)
|
||||
{
|
||||
m_cancellable = cancellable;
|
||||
}
|
||||
|
||||
void BaseProgressCallback::SetStatusText(const char* text)
|
||||
{
|
||||
m_status_text = text;
|
||||
}
|
||||
|
||||
void BaseProgressCallback::SetProgressRange(u32 range)
|
||||
{
|
||||
if (m_saved_state)
|
||||
{
|
||||
// impose the previous range on this range
|
||||
m_progress_range = m_saved_state->progress_range * range;
|
||||
m_base_progress_value = m_progress_value = m_saved_state->progress_value * range;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_progress_range = range;
|
||||
m_progress_value = 0;
|
||||
m_base_progress_value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void BaseProgressCallback::SetProgressValue(u32 value)
|
||||
{
|
||||
m_progress_value = m_base_progress_value + value;
|
||||
}
|
||||
|
||||
void BaseProgressCallback::IncrementProgressValue()
|
||||
{
|
||||
SetProgressValue((m_progress_value - m_base_progress_value) + 1);
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2021 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>
|
||||
|
||||
/**
|
||||
* Progress callbacks, abstracts a blocking operation and allows it to report progress
|
||||
* without having any dependency on the UI.
|
||||
*/
|
||||
|
||||
class ProgressCallback
|
||||
{
|
||||
public:
|
||||
virtual ~ProgressCallback();
|
||||
|
||||
virtual void PushState() = 0;
|
||||
virtual void PopState() = 0;
|
||||
|
||||
virtual bool IsCancelled() const = 0;
|
||||
virtual bool IsCancellable() const = 0;
|
||||
|
||||
virtual void SetCancellable(bool cancellable) = 0;
|
||||
|
||||
virtual void SetTitle(const char* title) = 0;
|
||||
virtual void SetStatusText(const char* text) = 0;
|
||||
virtual void SetProgressRange(u32 range) = 0;
|
||||
virtual void SetProgressValue(u32 value) = 0;
|
||||
virtual void IncrementProgressValue() = 0;
|
||||
|
||||
void SetFormattedStatusText(const char* Format, ...);
|
||||
|
||||
virtual void DisplayError(const char* message) = 0;
|
||||
virtual void DisplayWarning(const char* message) = 0;
|
||||
virtual void DisplayInformation(const char* message) = 0;
|
||||
virtual void DisplayDebugMessage(const char* message) = 0;
|
||||
|
||||
virtual void ModalError(const char* message) = 0;
|
||||
virtual bool ModalConfirmation(const char* message) = 0;
|
||||
virtual void ModalInformation(const char* message) = 0;
|
||||
|
||||
void DisplayFormattedError(const char* format, ...);
|
||||
void DisplayFormattedWarning(const char* format, ...);
|
||||
void DisplayFormattedInformation(const char* format, ...);
|
||||
void DisplayFormattedDebugMessage(const char* format, ...);
|
||||
void DisplayFormattedModalError(const char* format, ...);
|
||||
bool DisplayFormattedModalConfirmation(const char* format, ...);
|
||||
void DisplayFormattedModalInformation(const char* format, ...);
|
||||
|
||||
public:
|
||||
static ProgressCallback* NullProgressCallback;
|
||||
};
|
||||
|
||||
class BaseProgressCallback : public ProgressCallback
|
||||
{
|
||||
public:
|
||||
BaseProgressCallback();
|
||||
virtual ~BaseProgressCallback();
|
||||
|
||||
virtual void PushState() override;
|
||||
virtual void PopState() override;
|
||||
|
||||
virtual bool IsCancelled() const override;
|
||||
virtual bool IsCancellable() const override;
|
||||
|
||||
virtual void SetCancellable(bool cancellable) override;
|
||||
virtual void SetStatusText(const char* text) override;
|
||||
virtual void SetProgressRange(u32 range) override;
|
||||
virtual void SetProgressValue(u32 value) override;
|
||||
virtual void IncrementProgressValue() override;
|
||||
|
||||
protected:
|
||||
struct State
|
||||
{
|
||||
State* next_saved_state;
|
||||
std::string status_text;
|
||||
u32 progress_range;
|
||||
u32 progress_value;
|
||||
u32 base_progress_value;
|
||||
bool cancellable;
|
||||
};
|
||||
|
||||
bool m_cancellable;
|
||||
bool m_cancelled;
|
||||
std::string m_status_text;
|
||||
u32 m_progress_range;
|
||||
u32 m_progress_value;
|
||||
|
||||
u32 m_base_progress_value;
|
||||
|
||||
State* m_saved_state;
|
||||
};
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <wx/tokenzr.h>
|
||||
#include "common/Dependencies.h"
|
||||
#include "common/SafeArray.h"
|
||||
#include "common/ScopedAlloc.h"
|
||||
#include "common/AlignedMalloc.h"
|
||||
|
||||
#if _WIN32
|
||||
#define WX_STR(str) (str.wc_str())
|
||||
@@ -132,7 +132,7 @@ struct ParsedAssignmentString
|
||||
// accepts Ascii/UTF8 only.
|
||||
//
|
||||
|
||||
typedef ScopedAlignedAlloc<char, 16> CharBufferType;
|
||||
typedef AlignedBuffer<char, 16> CharBufferType;
|
||||
// --------------------------------------------------------------------------------------
|
||||
// FastFormatAscii
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,347 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2021 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 "Timer.h"
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include "RedtapeWindows.h"
|
||||
#elif defined(__APPLE__)
|
||||
#include <mach/mach_init.h>
|
||||
#include <mach/thread_act.h>
|
||||
#include <mach/mach_port.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace Common
|
||||
{
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
static double s_counter_frequency;
|
||||
static bool s_counter_initialized = false;
|
||||
|
||||
Timer::Value Timer::GetCurrentValue()
|
||||
{
|
||||
// even if this races, it should still result in the same value..
|
||||
if (!s_counter_initialized)
|
||||
{
|
||||
LARGE_INTEGER Freq;
|
||||
QueryPerformanceFrequency(&Freq);
|
||||
s_counter_frequency = static_cast<double>(Freq.QuadPart) / 1000000000.0;
|
||||
s_counter_initialized = true;
|
||||
}
|
||||
|
||||
Timer::Value ReturnValue;
|
||||
QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER*>(&ReturnValue));
|
||||
return ReturnValue;
|
||||
}
|
||||
|
||||
double Timer::ConvertValueToNanoseconds(Timer::Value value)
|
||||
{
|
||||
return (static_cast<double>(value) / s_counter_frequency);
|
||||
}
|
||||
|
||||
double Timer::ConvertValueToMilliseconds(Timer::Value value)
|
||||
{
|
||||
return ((static_cast<double>(value) / s_counter_frequency) / 1000000.0);
|
||||
}
|
||||
|
||||
double Timer::ConvertValueToSeconds(Timer::Value value)
|
||||
{
|
||||
return ((static_cast<double>(value) / s_counter_frequency) / 1000000000.0);
|
||||
}
|
||||
|
||||
Timer::Value Timer::ConvertSecondsToValue(double s)
|
||||
{
|
||||
return static_cast<Value>((s * 1000000000.0) * s_counter_frequency);
|
||||
}
|
||||
|
||||
Timer::Value Timer::ConvertMillisecondsToValue(double ms)
|
||||
{
|
||||
return static_cast<Value>((ms * 1000000.0) * s_counter_frequency);
|
||||
}
|
||||
|
||||
Timer::Value Timer::ConvertNanosecondsToValue(double ns)
|
||||
{
|
||||
return static_cast<Value>(ns * s_counter_frequency);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
Timer::Value Timer::GetCurrentValue()
|
||||
{
|
||||
struct timespec tv;
|
||||
clock_gettime(CLOCK_MONOTONIC, &tv);
|
||||
return ((Value)tv.tv_nsec + (Value)tv.tv_sec * 1000000000);
|
||||
}
|
||||
|
||||
double Timer::ConvertValueToNanoseconds(Timer::Value value)
|
||||
{
|
||||
return static_cast<double>(value);
|
||||
}
|
||||
|
||||
double Timer::ConvertValueToMilliseconds(Timer::Value value)
|
||||
{
|
||||
return (static_cast<double>(value) / 1000000.0);
|
||||
}
|
||||
|
||||
double Timer::ConvertValueToSeconds(Timer::Value value)
|
||||
{
|
||||
return (static_cast<double>(value) / 1000000000.0);
|
||||
}
|
||||
|
||||
Timer::Value Timer::ConvertSecondsToValue(double s)
|
||||
{
|
||||
return static_cast<Value>(s * 1000000000.0);
|
||||
}
|
||||
|
||||
Timer::Value Timer::ConvertMillisecondsToValue(double ms)
|
||||
{
|
||||
return static_cast<Value>(ms * 1000000.0);
|
||||
}
|
||||
|
||||
Timer::Value Timer::ConvertNanosecondsToValue(double ns)
|
||||
{
|
||||
return static_cast<Value>(ns);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Timer::Timer()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
void Timer::Reset()
|
||||
{
|
||||
m_tvStartValue = GetCurrentValue();
|
||||
}
|
||||
|
||||
double Timer::GetTimeSeconds() const
|
||||
{
|
||||
return ConvertValueToSeconds(GetCurrentValue() - m_tvStartValue);
|
||||
}
|
||||
|
||||
double Timer::GetTimeMilliseconds() const
|
||||
{
|
||||
return ConvertValueToMilliseconds(GetCurrentValue() - m_tvStartValue);
|
||||
}
|
||||
|
||||
double Timer::GetTimeNanoseconds() const
|
||||
{
|
||||
return ConvertValueToNanoseconds(GetCurrentValue() - m_tvStartValue);
|
||||
}
|
||||
|
||||
double Timer::GetTimeSecondsAndReset()
|
||||
{
|
||||
const Value value = GetCurrentValue();
|
||||
const double ret = ConvertValueToSeconds(value - m_tvStartValue);
|
||||
m_tvStartValue = value;
|
||||
return ret;
|
||||
}
|
||||
|
||||
double Timer::GetTimeMillisecondsAndReset()
|
||||
{
|
||||
const Value value = GetCurrentValue();
|
||||
const double ret = ConvertValueToMilliseconds(value - m_tvStartValue);
|
||||
m_tvStartValue = value;
|
||||
return ret;
|
||||
}
|
||||
|
||||
double Timer::GetTimeNanosecondsAndReset()
|
||||
{
|
||||
const Value value = GetCurrentValue();
|
||||
const double ret = ConvertValueToNanoseconds(value - m_tvStartValue);
|
||||
m_tvStartValue = value;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ThreadCPUTimer::ThreadCPUTimer() = default;
|
||||
|
||||
ThreadCPUTimer::ThreadCPUTimer(ThreadCPUTimer&& move)
|
||||
: m_thread_handle(move.m_thread_handle)
|
||||
{
|
||||
move.m_thread_handle = nullptr;
|
||||
}
|
||||
|
||||
ThreadCPUTimer::~ThreadCPUTimer()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
CloseHandle(reinterpret_cast<HANDLE>(m_thread_handle));
|
||||
#endif
|
||||
}
|
||||
|
||||
ThreadCPUTimer& ThreadCPUTimer::operator=(ThreadCPUTimer&& move)
|
||||
{
|
||||
std::swap(m_thread_handle, move.m_thread_handle);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void ThreadCPUTimer::Reset()
|
||||
{
|
||||
m_start_value = GetCurrentValue();
|
||||
}
|
||||
|
||||
ThreadCPUTimer::Value ThreadCPUTimer::GetCurrentValue() const
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
FILETIME create, exit, user, kernel;
|
||||
if (!m_thread_handle || !GetThreadTimes((HANDLE)m_thread_handle, &create, &exit, &user, &kernel))
|
||||
return 0;
|
||||
|
||||
Value value = (static_cast<Value>(user.dwHighDateTime) << 32) | (static_cast<Value>(user.dwLowDateTime));
|
||||
value += (static_cast<Value>(kernel.dwHighDateTime) << 32) | (static_cast<Value>(kernel.dwLowDateTime));
|
||||
return value;
|
||||
#elif defined(__APPLE__)
|
||||
thread_basic_info_data_t info;
|
||||
mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
|
||||
|
||||
const kern_return_t kr = thread_info((mach_port_t) reinterpret_cast<uintptr_t>(m_thread_handle), THREAD_BASIC_INFO, (thread_info_t)&info, &count);
|
||||
if (kr != KERN_SUCCESS)
|
||||
return 0;
|
||||
|
||||
Value value = (static_cast<Value>(info.user_time.seconds) * 1000000) + (static_cast<Value>(info.user_time.microseconds));
|
||||
value += (static_cast<Value>(info.system_time.seconds) * 1000000) + (static_cast<Value>(info.system_time.microseconds));
|
||||
return value;
|
||||
#else
|
||||
clockid_t cid;
|
||||
if (!m_thread_handle || pthread_getcpuclockid((pthread_t)m_thread_handle, &cid) != 0)
|
||||
return 0;
|
||||
|
||||
struct timespec ts;
|
||||
if (clock_gettime(cid, &ts) != 0)
|
||||
return 0;
|
||||
|
||||
return (static_cast<Value>(ts.tv_nsec) + static_cast<Value>(ts.tv_sec) * 1000000000LL);
|
||||
#endif
|
||||
}
|
||||
|
||||
double ThreadCPUTimer::GetTimeSeconds() const
|
||||
{
|
||||
return ConvertValueToSeconds(GetCurrentValue() - m_start_value);
|
||||
}
|
||||
|
||||
double ThreadCPUTimer::GetTimeMilliseconds() const
|
||||
{
|
||||
return ConvertValueToMilliseconds(GetCurrentValue() - m_start_value);
|
||||
}
|
||||
|
||||
double ThreadCPUTimer::GetTimeNanoseconds() const
|
||||
{
|
||||
return ConvertValueToNanoseconds(GetCurrentValue() - m_start_value);
|
||||
}
|
||||
|
||||
void ThreadCPUTimer::GetUsageInSecondsAndReset(Value time_diff, double* usage_time, double* usage_percent)
|
||||
{
|
||||
const Value new_value = GetCurrentValue();
|
||||
const Value diff = new_value - m_start_value;
|
||||
m_start_value = new_value;
|
||||
|
||||
*usage_time = ConvertValueToSeconds(diff);
|
||||
*usage_percent = GetUtilizationPercentage(time_diff, diff);
|
||||
}
|
||||
|
||||
void ThreadCPUTimer::GetUsageInMillisecondsAndReset(Value time_diff, double* usage_time, double* usage_percent)
|
||||
{
|
||||
const Value new_value = GetCurrentValue();
|
||||
const Value diff = new_value - m_start_value;
|
||||
m_start_value = new_value;
|
||||
|
||||
*usage_time = ConvertValueToMilliseconds(diff);
|
||||
*usage_percent = GetUtilizationPercentage(time_diff, diff);
|
||||
}
|
||||
|
||||
void ThreadCPUTimer::GetUsageInNanosecondsAndReset(Value time_diff, double* usage_time, double* usage_percent)
|
||||
{
|
||||
const Value new_value = GetCurrentValue();
|
||||
const Value diff = new_value - m_start_value;
|
||||
m_start_value = new_value;
|
||||
|
||||
*usage_time = ConvertValueToNanoseconds(diff);
|
||||
*usage_percent = GetUtilizationPercentage(time_diff, diff);
|
||||
}
|
||||
|
||||
double ThreadCPUTimer::GetUtilizationPercentage(Timer::Value time_diff, Value cpu_time_diff)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return ((static_cast<double>(cpu_time_diff) * 10000.0) / (static_cast<double>(time_diff) / s_counter_frequency));
|
||||
#elif defined(__APPLE__)
|
||||
// microseconds, but time_tiff is in nanoseconds, so multiply by 1000 * 100
|
||||
return (static_cast<double>(cpu_time_diff) * 100000.0) / static_cast<double>(time_diff);
|
||||
#else
|
||||
// nanoseconds
|
||||
return (static_cast<double>(cpu_time_diff) * 100.0) / static_cast<double>(time_diff);
|
||||
#endif
|
||||
}
|
||||
|
||||
double ThreadCPUTimer::ConvertValueToSeconds(Value value)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
// 100ns units
|
||||
return (static_cast<double>(value) / 10000000.0);
|
||||
#elif defined(__APPLE__)
|
||||
// microseconds
|
||||
return (static_cast<double>(value) / 1000000.0);
|
||||
#else
|
||||
// nanoseconds
|
||||
return (static_cast<double>(value) / 1000000000.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
double ThreadCPUTimer::ConvertValueToMilliseconds(Value value)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return (static_cast<double>(value) / 10000.0);
|
||||
#elif defined(__APPLE__)
|
||||
return (static_cast<double>(value) / 1000.0);
|
||||
#else
|
||||
return (static_cast<double>(value) / 1000000.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
double ThreadCPUTimer::ConvertValueToNanoseconds(Value value)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return (static_cast<double>(value) * 100.0);
|
||||
#elif defined(__APPLE__)
|
||||
return (static_cast<double>(value) * 1000.0);
|
||||
#else
|
||||
return static_cast<double>(value);
|
||||
#endif
|
||||
}
|
||||
|
||||
ThreadCPUTimer ThreadCPUTimer::GetForCallingThread()
|
||||
{
|
||||
ThreadCPUTimer ret;
|
||||
#if defined(_WIN32)
|
||||
ret.m_thread_handle = (void*)OpenThread(THREAD_QUERY_INFORMATION, FALSE, GetCurrentThreadId());
|
||||
#elif defined(__APPLE__)
|
||||
ret.m_thread_handle = reinterpret_cast<void*>((uintptr_t)mach_thread_self());
|
||||
#else
|
||||
ret.m_thread_handle = (void*)pthread_self();
|
||||
#endif
|
||||
ret.Reset();
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace Common
|
||||
@@ -0,0 +1,94 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2021 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 <cstdint>
|
||||
|
||||
namespace Common
|
||||
{
|
||||
|
||||
class Timer
|
||||
{
|
||||
public:
|
||||
using Value = std::uint64_t;
|
||||
|
||||
Timer();
|
||||
|
||||
static Value GetCurrentValue();
|
||||
static double ConvertValueToSeconds(Value value);
|
||||
static double ConvertValueToMilliseconds(Value value);
|
||||
static double ConvertValueToNanoseconds(Value value);
|
||||
static Value ConvertSecondsToValue(double s);
|
||||
static Value ConvertMillisecondsToValue(double s);
|
||||
static Value ConvertNanosecondsToValue(double ns);
|
||||
|
||||
void Reset();
|
||||
void ResetTo(Value value) { m_tvStartValue = value; }
|
||||
|
||||
Value GetStartValue() const { return m_tvStartValue; }
|
||||
|
||||
double GetTimeSeconds() const;
|
||||
double GetTimeMilliseconds() const;
|
||||
double GetTimeNanoseconds() const;
|
||||
|
||||
double GetTimeSecondsAndReset();
|
||||
double GetTimeMillisecondsAndReset();
|
||||
double GetTimeNanosecondsAndReset();
|
||||
|
||||
private:
|
||||
Value m_tvStartValue;
|
||||
};
|
||||
|
||||
class ThreadCPUTimer
|
||||
{
|
||||
public:
|
||||
using Value = std::uint64_t;
|
||||
|
||||
ThreadCPUTimer();
|
||||
ThreadCPUTimer(ThreadCPUTimer&& move);
|
||||
ThreadCPUTimer(const ThreadCPUTimer&) = delete;
|
||||
~ThreadCPUTimer();
|
||||
|
||||
void Reset();
|
||||
void ResetTo(Value value) { m_start_value = value; }
|
||||
|
||||
Value GetStartValue() const { return m_start_value; }
|
||||
Value GetCurrentValue() const;
|
||||
|
||||
double GetTimeSeconds() const;
|
||||
double GetTimeMilliseconds() const;
|
||||
double GetTimeNanoseconds() const;
|
||||
|
||||
void GetUsageInSecondsAndReset(Value time_diff, double* usage_time, double* usage_percent);
|
||||
void GetUsageInMillisecondsAndReset(Value time_diff, double* usage_time, double* usage_percent);
|
||||
void GetUsageInNanosecondsAndReset(Value time_diff, double* usage_time, double* usage_percent);
|
||||
|
||||
static double GetUtilizationPercentage(Timer::Value time_diff, Value cpu_time_diff);
|
||||
|
||||
static double ConvertValueToSeconds(Value value);
|
||||
static double ConvertValueToMilliseconds(Value value);
|
||||
static double ConvertValueToNanoseconds(Value value);
|
||||
|
||||
static ThreadCPUTimer GetForCallingThread();
|
||||
|
||||
ThreadCPUTimer& operator=(const ThreadCPUTimer&) = delete;
|
||||
ThreadCPUTimer& operator=(ThreadCPUTimer&& move);
|
||||
|
||||
private:
|
||||
void* m_thread_handle = nullptr;
|
||||
Value m_start_value = 0;
|
||||
};
|
||||
|
||||
} // namespace Common
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(SolutionDir)common\vsprops\BaseProjectConfig.props" />
|
||||
<Import Project="$(SolutionDir)common\vsprops\WinSDK.props" />
|
||||
@@ -52,11 +52,14 @@
|
||||
<ClCompile Include="GL\Context.cpp" />
|
||||
<ClCompile Include="GL\ContextWGL.cpp" />
|
||||
<ClCompile Include="GL\StreamBuffer.cpp" />
|
||||
<ClCompile Include="FileSystem.cpp" />
|
||||
<ClCompile Include="IniInterface.cpp" />
|
||||
<ClCompile Include="ProgressCallback.cpp" />
|
||||
<ClCompile Include="pxStreams.cpp" />
|
||||
<ClCompile Include="pxTranslate.cpp" />
|
||||
<ClCompile Include="StringUtil.cpp" />
|
||||
<ClCompile Include="SettingsWrapper.cpp" />
|
||||
<ClCompile Include="Timer.cpp" />
|
||||
<ClCompile Include="VirtualMemory.cpp" />
|
||||
<ClCompile Include="WindowInfo.cpp" />
|
||||
<ClCompile Include="x86\MemcpyFast.cpp" />
|
||||
@@ -100,6 +103,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Align.h" />
|
||||
<ClInclude Include="AlignedMalloc.h" />
|
||||
<ClInclude Include="BitCast.h" />
|
||||
<ClInclude Include="EmbeddedImage.h" />
|
||||
<ClInclude Include="boost_spsc_queue.hpp" />
|
||||
@@ -107,7 +111,8 @@
|
||||
<ClInclude Include="GL\Context.h" />
|
||||
<ClInclude Include="GL\ContextWGL.h" />
|
||||
<ClInclude Include="GL\StreamBuffer.h" />
|
||||
<ClInclude Include="ScopedAlloc.h" />
|
||||
<ClInclude Include="FileSystem.h" />
|
||||
<ClInclude Include="ProgressCallback.h" />
|
||||
<ClInclude Include="ScopedGuard.h" />
|
||||
<ClInclude Include="StringUtil.h" />
|
||||
<ClInclude Include="SettingsInterface.h" />
|
||||
@@ -126,6 +131,7 @@
|
||||
<ClInclude Include="RedtapeWindows.h" />
|
||||
<ClInclude Include="SafeArray.h" />
|
||||
<ClInclude Include="StringHelpers.h" />
|
||||
<ClInclude Include="Timer.h" />
|
||||
<ClInclude Include="WindowInfo.h" />
|
||||
<ClInclude Include="wxBaseTools.h" />
|
||||
<ClInclude Include="Threading.h" />
|
||||
@@ -175,4 +181,4 @@
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -130,8 +130,23 @@
|
||||
<ClCompile Include="GL\StreamBuffer.cpp">
|
||||
<Filter>Source Files\GL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FileSystem.cpp">
|
||||
<Filter>Source Files\GL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="StringUtil.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Timer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ProgressCallback.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="AlignedMalloc.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Assertions.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -222,9 +237,6 @@
|
||||
<ClInclude Include="SafeArray.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ScopedAlloc.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="emitter\implement\simd_arithmetic.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -282,9 +294,6 @@
|
||||
<ClInclude Include="SettingsWrapper.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ScopedGuard.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Align.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -303,6 +312,24 @@
|
||||
<ClInclude Include="GL\StreamBuffer.h">
|
||||
<Filter>Header Files\GL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FileSystem.h">
|
||||
<Filter>Header Files\GL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="StringUtil.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ScopedGuard.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Timer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ProgressCallback.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ScopedGuard.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
|
||||
@@ -21,23 +21,21 @@
|
||||
// AND'ing this mask against an MXCSR prior to LDMXCSR.
|
||||
SSE_MXCSR MXCSR_Mask;
|
||||
|
||||
const wxChar* EnumToString(SSE_RoundMode sse)
|
||||
const char* EnumToString(SSE_RoundMode sse)
|
||||
{
|
||||
switch (sse)
|
||||
{
|
||||
case SSEround_Nearest:
|
||||
return L"Nearest";
|
||||
return "Nearest";
|
||||
case SSEround_NegInf:
|
||||
return L"NegativeInfinity";
|
||||
return "NegativeInfinity";
|
||||
case SSEround_PosInf:
|
||||
return L"PositiveInfinity";
|
||||
return "PositiveInfinity";
|
||||
case SSEround_Chop:
|
||||
return L"Chop";
|
||||
return "Chop";
|
||||
default:
|
||||
return L"Invalid";
|
||||
return "Invalid";
|
||||
}
|
||||
|
||||
return L"Invalid";
|
||||
}
|
||||
|
||||
SSE_RoundMode SSE_MXCSR::GetRoundMode() const
|
||||
|
||||
+34
-33
@@ -24,21 +24,22 @@
|
||||
# include <aio.h>
|
||||
#endif
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
class AsyncFileReader
|
||||
{
|
||||
protected:
|
||||
AsyncFileReader() : m_dataoffset(0), m_blocksize(0) {}
|
||||
|
||||
wxString m_filename;
|
||||
std::string m_filename;
|
||||
|
||||
int m_dataoffset;
|
||||
uint m_blocksize;
|
||||
|
||||
public:
|
||||
virtual ~AsyncFileReader(void) {};
|
||||
virtual ~AsyncFileReader() {};
|
||||
|
||||
virtual bool Open(const wxString& fileName)=0;
|
||||
virtual bool Open(std::string fileName)=0;
|
||||
|
||||
virtual int ReadSync(void* pBuffer, uint sector, uint count)=0;
|
||||
|
||||
@@ -55,7 +56,7 @@ public:
|
||||
|
||||
uint GetBlockSize() const { return m_blocksize; }
|
||||
|
||||
const wxString& GetFilename() const
|
||||
const std::string& GetFilename() const
|
||||
{
|
||||
return m_filename;
|
||||
}
|
||||
@@ -86,22 +87,22 @@ class FlatFileReader : public AsyncFileReader
|
||||
|
||||
public:
|
||||
FlatFileReader(bool shareWrite = false);
|
||||
virtual ~FlatFileReader(void);
|
||||
virtual ~FlatFileReader() override;
|
||||
|
||||
virtual bool Open(const wxString& fileName);
|
||||
virtual bool Open(std::string fileName) override;
|
||||
|
||||
virtual int ReadSync(void* pBuffer, uint sector, uint count);
|
||||
virtual int ReadSync(void* pBuffer, uint sector, uint count) override;
|
||||
|
||||
virtual void BeginRead(void* pBuffer, uint sector, uint count);
|
||||
virtual int FinishRead(void);
|
||||
virtual void CancelRead(void);
|
||||
virtual void BeginRead(void* pBuffer, uint sector, uint count) override;
|
||||
virtual int FinishRead(void) override;
|
||||
virtual void CancelRead(void) override;
|
||||
|
||||
virtual void Close(void);
|
||||
virtual void Close(void) override;
|
||||
|
||||
virtual uint GetBlockCount(void) const;
|
||||
virtual uint GetBlockCount(void) const override;
|
||||
|
||||
virtual void SetBlockSize(uint bytes) { m_blocksize = bytes; }
|
||||
virtual void SetDataOffset(int bytes) { m_dataoffset = bytes; }
|
||||
virtual void SetBlockSize(uint bytes) override { m_blocksize = bytes; }
|
||||
virtual void SetDataOffset(int bytes) override { m_dataoffset = bytes; }
|
||||
};
|
||||
|
||||
class MultipartFileReader : public AsyncFileReader
|
||||
@@ -123,21 +124,21 @@ class MultipartFileReader : public AsyncFileReader
|
||||
|
||||
public:
|
||||
MultipartFileReader(AsyncFileReader* firstPart);
|
||||
virtual ~MultipartFileReader(void);
|
||||
virtual ~MultipartFileReader() override;
|
||||
|
||||
virtual bool Open(const wxString& fileName);
|
||||
virtual bool Open(std::string fileName) override;
|
||||
|
||||
virtual int ReadSync(void* pBuffer, uint sector, uint count);
|
||||
virtual int ReadSync(void* pBuffer, uint sector, uint count) override;
|
||||
|
||||
virtual void BeginRead(void* pBuffer, uint sector, uint count);
|
||||
virtual int FinishRead(void);
|
||||
virtual void CancelRead(void);
|
||||
virtual void BeginRead(void* pBuffer, uint sector, uint count) override;
|
||||
virtual int FinishRead(void) override;
|
||||
virtual void CancelRead(void) override;
|
||||
|
||||
virtual void Close(void);
|
||||
virtual void Close(void) override;
|
||||
|
||||
virtual uint GetBlockCount(void) const;
|
||||
virtual uint GetBlockCount(void) const override;
|
||||
|
||||
virtual void SetBlockSize(uint bytes);
|
||||
virtual void SetBlockSize(uint bytes) override;
|
||||
|
||||
static AsyncFileReader* DetectMultipart(AsyncFileReader* reader);
|
||||
};
|
||||
@@ -146,7 +147,7 @@ class BlockdumpFileReader : public AsyncFileReader
|
||||
{
|
||||
DeclareNoncopyableObject( BlockdumpFileReader );
|
||||
|
||||
wxFileInputStream* m_file;
|
||||
std::FILE* m_file;
|
||||
|
||||
// total number of blocks in the ISO image (including all parts)
|
||||
u32 m_blocks;
|
||||
@@ -159,20 +160,20 @@ class BlockdumpFileReader : public AsyncFileReader
|
||||
int m_lresult;
|
||||
|
||||
public:
|
||||
BlockdumpFileReader(void);
|
||||
virtual ~BlockdumpFileReader(void);
|
||||
BlockdumpFileReader();
|
||||
virtual ~BlockdumpFileReader() override;
|
||||
|
||||
virtual bool Open(const wxString& fileName);
|
||||
virtual bool Open(std::string fileName) override;
|
||||
|
||||
virtual int ReadSync(void* pBuffer, uint sector, uint count);
|
||||
virtual int ReadSync(void* pBuffer, uint sector, uint count) override;
|
||||
|
||||
virtual void BeginRead(void* pBuffer, uint sector, uint count);
|
||||
virtual int FinishRead(void);
|
||||
virtual void CancelRead(void);
|
||||
virtual void BeginRead(void* pBuffer, uint sector, uint count) override;
|
||||
virtual int FinishRead(void) override;
|
||||
virtual void CancelRead(void) override;
|
||||
|
||||
virtual void Close(void);
|
||||
virtual void Close(void) override;
|
||||
|
||||
virtual uint GetBlockCount(void) const;
|
||||
virtual uint GetBlockCount(void) const override;
|
||||
|
||||
static bool DetectBlockdump(AsyncFileReader* reader);
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "AsyncFileReader.h"
|
||||
#include "IopCommon.h"
|
||||
#include "IsoFileFormats.h"
|
||||
#include "common/FileSystem.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
@@ -59,48 +60,45 @@ BlockdumpFileReader::~BlockdumpFileReader(void)
|
||||
Close();
|
||||
}
|
||||
|
||||
bool BlockdumpFileReader::Open(const wxString& fileName)
|
||||
bool BlockdumpFileReader::Open(std::string fileName)
|
||||
{
|
||||
char buf[32];
|
||||
char signature[4];
|
||||
|
||||
m_filename = fileName;
|
||||
|
||||
m_file = new wxFileInputStream(m_filename);
|
||||
|
||||
m_file->SeekI(0);
|
||||
m_file->Read(buf, 4);
|
||||
|
||||
if (strncmp(buf, "BDV2", 4) != 0)
|
||||
m_filename = std::move(fileName);
|
||||
m_file = FileSystem::OpenCFile(m_filename.c_str(), "rb");
|
||||
if (!m_file || std::fread(signature, sizeof(signature), 1, m_file) != 1 || std::memcmp(signature, "BDV2", sizeof(signature)) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//m_flags = ISOFLAGS_BLOCKDUMP_V2;
|
||||
m_file->Read(&m_blocksize, sizeof(m_blocksize));
|
||||
m_file->Read(&m_blocks, sizeof(m_blocks));
|
||||
m_file->Read(&m_blockofs, sizeof(m_blockofs));
|
||||
if (std::fread(&m_blocksize, sizeof(m_blocksize), 1, m_file) != 1 ||
|
||||
std::fread(&m_blocks, sizeof(m_blocks), 1, m_file) != 1 ||
|
||||
std::fread(&m_blockofs, sizeof(m_blockofs), 1, m_file) != 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
wxFileOffset flen = m_file->GetLength();
|
||||
static const wxFileOffset datalen = flen - BlockDumpHeaderSize;
|
||||
const s64 flen = FileSystem::FSize64(m_file);
|
||||
const s64 datalen = flen - BlockDumpHeaderSize;
|
||||
|
||||
pxAssert((datalen % (m_blocksize + 4)) == 0);
|
||||
|
||||
m_dtablesize = datalen / (m_blocksize + 4);
|
||||
m_dtable = std::unique_ptr<u32[]>(new u32[m_dtablesize]);
|
||||
m_dtable = std::make_unique<u32[]>(m_dtablesize);
|
||||
|
||||
m_file->SeekI(BlockDumpHeaderSize);
|
||||
if (FileSystem::FSeek64(m_file, BlockDumpHeaderSize, SEEK_SET) != 0)
|
||||
return false;
|
||||
|
||||
u32 bs = 1024 * 1024;
|
||||
u32 off = 0;
|
||||
u32 has = 0;
|
||||
int i = 0;
|
||||
|
||||
std::unique_ptr<u8[]> buffer(new u8[bs]);
|
||||
std::unique_ptr<u8[]> buffer = std::make_unique<u8[]>(bs);
|
||||
do
|
||||
{
|
||||
m_file->Read(buffer.get(), bs);
|
||||
has = m_file->LastRead();
|
||||
|
||||
has = static_cast<u32>(std::fread(buffer.get(), 1, bs, m_file));
|
||||
while (i < m_dtablesize && off < has)
|
||||
{
|
||||
m_dtable[i++] = *reinterpret_cast<u32*>(buffer.get() + off);
|
||||
@@ -132,15 +130,17 @@ int BlockdumpFileReader::ReadSync(void* pBuffer, uint lsn, uint count)
|
||||
// seek position ends up being based on (m_blocksize + 4) instead of just m_blocksize.
|
||||
|
||||
#ifdef PCSX2_DEBUG
|
||||
u32 check_lsn;
|
||||
m_file->SeekI(BlockDumpHeaderSize + (i * (m_blocksize + 4)));
|
||||
m_file->Read(&check_lsn, sizeof(check_lsn));
|
||||
u32 check_lsn = 0;
|
||||
FileSystem::FSeek64(m_file, BlockDumpHeaderSize + (i * (m_blocksize + 4)), SEEK_SET);
|
||||
std::fread(&check_lsn, sizeof(check_lsn), 1, m_file);
|
||||
pxAssert(check_lsn == lsn);
|
||||
#else
|
||||
m_file->SeekI(BlockDumpHeaderSize + (i * (m_blocksize + 4)) + 4);
|
||||
if (FileSystem::FSeek64(m_file, BlockDumpHeaderSize + (i * (m_blocksize + 4)) + 4, SEEK_SET) != 0)
|
||||
break;
|
||||
#endif
|
||||
|
||||
m_file->Read(dst, m_blocksize);
|
||||
if (std::fread(dst, m_blocksize, 1, m_file) != 1)
|
||||
break;
|
||||
|
||||
ok = true;
|
||||
break;
|
||||
@@ -178,7 +178,7 @@ void BlockdumpFileReader::Close(void)
|
||||
{
|
||||
if (m_file)
|
||||
{
|
||||
delete m_file;
|
||||
std::fclose(m_file);
|
||||
m_file = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
+67
-106
@@ -20,6 +20,8 @@
|
||||
#include <ctype.h>
|
||||
#include <wx/datetime.h>
|
||||
|
||||
#include "common/FileSystem.h"
|
||||
|
||||
#include "CdRom.h"
|
||||
#include "CDVD.h"
|
||||
#include "CDVD_internal.h"
|
||||
@@ -111,34 +113,28 @@ static int mg_BIToffset(u8* buffer)
|
||||
|
||||
static void cdvdGetMechaVer(u8* ver)
|
||||
{
|
||||
wxFileName mecfile(EmuConfig.FullpathToBios());
|
||||
mecfile.SetExt(L"mec");
|
||||
const wxString fname(mecfile.GetFullPath());
|
||||
|
||||
// Likely a bad idea to go further
|
||||
if (mecfile.IsDir())
|
||||
throw Exception::CannotCreateStream(fname);
|
||||
|
||||
|
||||
if (Path::GetFileSize(fname) < 4)
|
||||
std::string mecfile(FileSystem::ReplaceExtension(BiosPath, "mec"));
|
||||
auto fp = FileSystem::OpenManagedCFile(mecfile.c_str(), "rb");
|
||||
if (!fp || FileSystem::FSize64(fp.get()) < 4)
|
||||
{
|
||||
Console.Warning("MEC File Not Found, creating substitute...");
|
||||
|
||||
wxFFile fp(fname, L"wb");
|
||||
if (!fp.IsOpened())
|
||||
throw Exception::CannotCreateStream(fname);
|
||||
fp.reset();
|
||||
fp = FileSystem::OpenManagedCFile(mecfile.c_str(), "w+b");
|
||||
if (!fp)
|
||||
{
|
||||
Console.Error("Failed to read/write NVM/MEC file. Check your BIOS setup/permission settings.");
|
||||
return;
|
||||
}
|
||||
|
||||
u8 version[4] = {0x3, 0x6, 0x2, 0x0};
|
||||
fp.Write(version, sizeof(version));
|
||||
std::fwrite(version, sizeof(version), 1, fp.get());
|
||||
FileSystem::FSeek64(fp.get(), 0, SEEK_SET);
|
||||
}
|
||||
|
||||
wxFFile fp(fname, L"rb");
|
||||
if (!fp.IsOpened())
|
||||
throw Exception::CannotCreateStream(fname);
|
||||
|
||||
size_t ret = fp.Read(ver, 4);
|
||||
auto ret = std::fread(ver, 1, 4, fp.get());
|
||||
if (ret != 4)
|
||||
Console.Error(L"Failed to read from %s. Did only %zu/4 bytes", WX_STR(fname), ret);
|
||||
Console.Error("Failed to read from %s. Did only %zu/4 bytes", mecfile.c_str(), ret);
|
||||
}
|
||||
|
||||
NVMLayout* getNvmLayout()
|
||||
@@ -153,14 +149,10 @@ NVMLayout* getNvmLayout()
|
||||
return nvmLayout;
|
||||
}
|
||||
|
||||
static void cdvdCreateNewNVM(const wxString& filename)
|
||||
static void cdvdCreateNewNVM(std::FILE* fp)
|
||||
{
|
||||
wxFFile fp(filename, L"wb");
|
||||
if (!fp.IsOpened())
|
||||
throw Exception::CannotCreateStream(filename);
|
||||
|
||||
u8 zero[1024] = {0};
|
||||
fp.Write(zero, sizeof(zero));
|
||||
u8 zero[1024] = {};
|
||||
std::fwrite(zero, sizeof(zero), 1, fp);
|
||||
|
||||
// Write NVM ILink area with dummy data (Age of Empires 2)
|
||||
// Also write language data defaulting to English (Guitar Hero 2)
|
||||
@@ -168,36 +160,34 @@ static void cdvdCreateNewNVM(const wxString& filename)
|
||||
NVMLayout* nvmLayout = getNvmLayout();
|
||||
u8 ILinkID_Data[8] = {0x00, 0xAC, 0xFF, 0xFF, 0xFF, 0xFF, 0xB9, 0x86};
|
||||
|
||||
fp.Seek(*(s32*)(((u8*)nvmLayout) + offsetof(NVMLayout, ilinkId)));
|
||||
fp.Write(ILinkID_Data, sizeof(ILinkID_Data));
|
||||
std::fseek(fp, *(s32*)(((u8*)nvmLayout) + offsetof(NVMLayout, ilinkId)), SEEK_SET);
|
||||
std::fwrite(ILinkID_Data, sizeof(ILinkID_Data), 1, fp);
|
||||
|
||||
u8 biosLanguage[16];
|
||||
memcpy(biosLanguage, &biosLangDefaults[BiosRegion][0], 16);
|
||||
// Config sections first 16 bytes are generally blank expect the last byte which is PS1 mode stuff
|
||||
// So let's ignore that and just write the PS2 mode stuff
|
||||
fp.Seek(*(s32*)(((u8*)nvmLayout) + offsetof(NVMLayout, config1)) + 0x10);
|
||||
fp.Write(biosLanguage, sizeof(biosLanguage));
|
||||
|
||||
fp.Close();
|
||||
std::fseek(fp, *(s32*)(((u8*)nvmLayout) + offsetof(NVMLayout, config1)) + 0x10, SEEK_SET);
|
||||
std::fwrite(biosLanguage, sizeof(biosLanguage), 1, fp);
|
||||
}
|
||||
|
||||
// Throws Exception::CannotCreateStream if the file cannot be opened for reading, or cannot
|
||||
// be created for some reason.
|
||||
static void cdvdNVM(u8* buffer, int offset, size_t bytes, bool read)
|
||||
{
|
||||
wxFileName nvmfile(EmuConfig.FullpathToBios());
|
||||
nvmfile.SetExt(L"nvm");
|
||||
const wxString fname(nvmfile.GetFullPath());
|
||||
|
||||
// Likely a bad idea to go further
|
||||
if (nvmfile.IsDir())
|
||||
throw Exception::CannotCreateStream(fname);
|
||||
|
||||
if (Path::GetFileSize(fname) < 1024)
|
||||
std::string nvmfile(FileSystem::ReplaceExtension(BiosPath, "nvm"));
|
||||
auto fp = FileSystem::OpenManagedCFile(nvmfile.c_str(), "r+b");
|
||||
if (!fp || FileSystem::FSize64(fp.get()) < 1024)
|
||||
{
|
||||
Console.Warning("NVM File Not Found, creating substitute...");
|
||||
fp.reset();
|
||||
fp = FileSystem::OpenManagedCFile(nvmfile.c_str(), "w+b");
|
||||
if (!fp)
|
||||
{
|
||||
Console.Error("Failed to open NVM file '%s' for writing", nvmfile.c_str());
|
||||
if (read)
|
||||
std::memset(buffer, 0, bytes);
|
||||
return;
|
||||
}
|
||||
|
||||
cdvdCreateNewNVM(fname);
|
||||
cdvdCreateNewNVM(fp.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -205,38 +195,28 @@ static void cdvdNVM(u8* buffer, int offset, size_t bytes, bool read)
|
||||
u8 zero[16] = {0};
|
||||
NVMLayout* nvmLayout = getNvmLayout();
|
||||
|
||||
wxFFile fp(fname, L"r+b");
|
||||
if (!fp.IsOpened())
|
||||
throw Exception::CannotCreateStream(fname);
|
||||
|
||||
fp.Seek(*(s32*)(((u8*)nvmLayout) + offsetof(NVMLayout, config1)) + 0x10);
|
||||
fp.Read(LanguageParams, 16);
|
||||
|
||||
fp.Close();
|
||||
|
||||
if (memcmp(LanguageParams, zero, sizeof(LanguageParams)) == 0)
|
||||
if (std::fseek(fp.get(), *(s32*)(((u8*)nvmLayout) + offsetof(NVMLayout, config1)) + 0x10, SEEK_SET) != 0 ||
|
||||
std::fread(LanguageParams, 16, 1, fp.get()) != 1 ||
|
||||
std::memcmp(LanguageParams, zero, sizeof(LanguageParams)) == 0)
|
||||
{
|
||||
Console.Warning("Language Parameters missing, filling in defaults");
|
||||
|
||||
cdvdCreateNewNVM(fname);
|
||||
FileSystem::FSeek64(fp.get(), 0, SEEK_SET);
|
||||
cdvdCreateNewNVM(fp.get());
|
||||
}
|
||||
}
|
||||
|
||||
wxFFile fp(fname, L"r+b");
|
||||
if (!fp.IsOpened())
|
||||
throw Exception::CannotCreateStream(fname);
|
||||
|
||||
fp.Seek(offset);
|
||||
std::fseek(fp.get(), offset, SEEK_SET);
|
||||
|
||||
size_t ret;
|
||||
if (read)
|
||||
ret = fp.Read(buffer, bytes);
|
||||
ret = std::fread(buffer, 1, bytes, fp.get());
|
||||
else
|
||||
ret = fp.Write(buffer, bytes);
|
||||
ret = std::fwrite(buffer, 1, bytes, fp.get());
|
||||
|
||||
if (ret != bytes)
|
||||
Console.Error(L"Failed to %s %s. Did only %zu/%zu bytes",
|
||||
read ? L"read from" : L"write to", WX_STR(fname), ret, bytes);
|
||||
read ? L"read from" : L"write to", nvmfile.c_str(), ret, bytes);
|
||||
}
|
||||
|
||||
static void cdvdReadNVM(u8* dst, int offset, int bytes)
|
||||
@@ -384,7 +364,7 @@ static MutexRecursive Mutex_NewDiskCB;
|
||||
static __fi ElfObject* loadElf(const wxString filename, bool isPSXElf)
|
||||
{
|
||||
if (filename.StartsWith(L"host"))
|
||||
return new ElfObject(filename.After(':'), Path::GetFileSize(filename.After(':')), isPSXElf);
|
||||
return new ElfObject(filename.After(':'), FileSystem::GetPathFileSize(filename.After(':').ToUTF8()), isPSXElf);
|
||||
|
||||
// Mimic PS2 behavior!
|
||||
// Much trial-and-error with changing the ISOFS and BOOT2 contents of an image have shown that
|
||||
@@ -1058,7 +1038,7 @@ __fi void cdvdActionInterrupt()
|
||||
cdvd.Spinning = true;
|
||||
cdvd.Ready |= CDVD_DRIVE_READY; //check (rama)
|
||||
cdvd.Sector = cdvd.SeekToSector;
|
||||
cdvd.Status = CDVD_STATUS_READ;
|
||||
cdvd.Status = CDVD_STATUS_PAUSE;
|
||||
cdvd.nextSectorsBuffered = 0;
|
||||
cdvd.triggerDataReady = true;
|
||||
CDVDSECTORREADY_INT(cdvd.ReadTime);
|
||||
@@ -1069,7 +1049,7 @@ __fi void cdvdActionInterrupt()
|
||||
cdvd.Spinning = true; //check (rama)
|
||||
cdvd.Ready |= CDVD_DRIVE_READY; //check (rama)
|
||||
cdvd.Sector = cdvd.SeekToSector;
|
||||
cdvd.Status = CDVD_STATUS_READ;
|
||||
cdvd.Status = CDVD_STATUS_PAUSE;
|
||||
cdvd.nextSectorsBuffered = 0;
|
||||
cdvd.triggerDataReady = true;
|
||||
CDVDSECTORREADY_INT(cdvd.ReadTime);
|
||||
@@ -1123,18 +1103,8 @@ __fi void cdvdSectorReady()
|
||||
}
|
||||
}
|
||||
|
||||
if (cdvd.nextSectorsBuffered == 16 && (cdvd.Ready & CDVD_DRIVE_READY))
|
||||
{
|
||||
cdvd.Status = CDVD_STATUS_PAUSE; // Needed here but could be smth else than Pause (rama)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cdvd.nextSectorsBuffered < 16)
|
||||
{
|
||||
CDVDSECTORREADY_INT(cdvd.ReadTime);
|
||||
cdvd.Status = CDVD_STATUS_READ;
|
||||
}
|
||||
}
|
||||
if (cdvd.nextSectorsBuffered < 16)
|
||||
CDVDSECTORREADY_INT(cdvd.ReadTime);
|
||||
}
|
||||
|
||||
// inlined due to being referenced in only one place.
|
||||
@@ -1159,14 +1129,10 @@ __fi void cdvdReadInterrupt()
|
||||
cdvd.Reading = 1;
|
||||
cdvd.Readed = 1;
|
||||
cdvd.Sector = cdvd.SeekToSector;
|
||||
CDVD_LOG("Cdvd Seek Complete > Scheduling block read interrupt at iopcycle=%8.8x.",
|
||||
psxRegs.cycle + cdvd.ReadTime);
|
||||
|
||||
CDVDREAD_INT(cdvd.ReadTime);
|
||||
cdvd.Status = CDVD_STATUS_READ;
|
||||
return;
|
||||
CDVD_LOG("Cdvd Seek Complete at iopcycle=%8.8x.", psxRegs.cycle);
|
||||
}
|
||||
else if (cdvd.Reading)
|
||||
|
||||
if (cdvd.Reading)
|
||||
{
|
||||
if (cdvd.RErr == 0)
|
||||
{
|
||||
@@ -1237,10 +1203,7 @@ __fi void cdvdReadInterrupt()
|
||||
iopIntcIrq(2);
|
||||
cdvd.Ready |= CDVD_DRIVE_READY;
|
||||
|
||||
if (cdvd.nextSectorsBuffered < 16)
|
||||
cdvd.Status = CDVD_STATUS_READ;
|
||||
else
|
||||
cdvd.Status = CDVD_STATUS_PAUSE;
|
||||
cdvd.Status = CDVD_STATUS_PAUSE;
|
||||
|
||||
cdvd.nCommand = 0;
|
||||
//DevCon.Warning("Scheduling interrupt in %d cycles", cdvd.ReadTime - ((cdvd.BlockSize / 4) * 12));
|
||||
@@ -1264,7 +1227,7 @@ __fi void cdvdReadInterrupt()
|
||||
if (cdvd.nextSectorsBuffered)
|
||||
CDVDREAD_INT((cdvd.BlockSize / 4) * 12);
|
||||
else
|
||||
CDVDREAD_INT(cdvd.ReadTime + ((cdvd.BlockSize / 4) * 12));
|
||||
CDVDREAD_INT((psxRegs.cycle - psxRegs.sCycle[IopEvt_CdvdSectorReady]) + ((cdvd.BlockSize / 4) * 12));
|
||||
}
|
||||
|
||||
// Returns the number of IOP cycles until the event completes.
|
||||
@@ -1274,6 +1237,7 @@ static uint cdvdStartSeek(uint newsector, CDVD_MODE_TYPE mode)
|
||||
|
||||
uint delta = abs((s32)(cdvd.SeekToSector - cdvd.Sector));
|
||||
uint seektime;
|
||||
bool isSeeking = cdvd.nCommand == N_CD_SEEK;
|
||||
|
||||
cdvd.Ready &= ~(CDVD_DRIVE_READY | CDVD_DRIVE_DATARDY);
|
||||
cdvd.Reading = 1;
|
||||
@@ -1311,6 +1275,7 @@ static uint cdvdStartSeek(uint newsector, CDVD_MODE_TYPE mode)
|
||||
CDVD_LOG("CdSeek Begin > to sector %d, from %d - delta=%d [FAST]", cdvd.SeekToSector, cdvd.Sector, delta);
|
||||
seektime = Cdvd_FastSeek_Cycles;
|
||||
}
|
||||
isSeeking = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1318,6 +1283,7 @@ static uint cdvdStartSeek(uint newsector, CDVD_MODE_TYPE mode)
|
||||
|
||||
// if delta > 0 it will read a new sector so the readInterrupt will account for this.
|
||||
seektime = 0;
|
||||
isSeeking = false;
|
||||
|
||||
if (delta == 0)
|
||||
{
|
||||
@@ -1342,12 +1308,11 @@ static uint cdvdStartSeek(uint newsector, CDVD_MODE_TYPE mode)
|
||||
}
|
||||
else
|
||||
{
|
||||
CDVDSECTORREADY_INT(cdvd.ReadTime);
|
||||
seektime = cdvd.ReadTime + ((cdvd.BlockSize / 4) * 12);
|
||||
delta = 1; // Forces it to use the rotational delay since we have no sectors buffered and it isn't buffering any.
|
||||
}
|
||||
}
|
||||
else
|
||||
seektime = (cdvd.BlockSize / 4) * 12;
|
||||
return (cdvd.BlockSize / 4) * 12;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1357,7 +1322,7 @@ static uint cdvdStartSeek(uint newsector, CDVD_MODE_TYPE mode)
|
||||
}
|
||||
|
||||
// Only do this on reads, the seek kind of accounts for this and then it reads the sectors after
|
||||
if (delta && cdvd.nCommand != N_CD_SEEK)
|
||||
if (delta && !isSeeking)
|
||||
{
|
||||
int rotationalLatency = cdvdRotationalLatency((CDVD_MODE_TYPE)cdvdIsDVD());
|
||||
//DevCon.Warning("%s rotational latency at sector %d is %d cycles", (cdvd.SpindlCtrl & CDVD_SPINDLE_CAV) ? "CAV" : "CLV", cdvd.SeekToSector, rotationalLatency);
|
||||
@@ -1365,6 +1330,9 @@ static uint cdvdStartSeek(uint newsector, CDVD_MODE_TYPE mode)
|
||||
CDVDSECTORREADY_INT(seektime);
|
||||
seektime += (cdvd.BlockSize / 4) * 12;
|
||||
}
|
||||
else
|
||||
CDVDSECTORREADY_INT(seektime);
|
||||
|
||||
return seektime;
|
||||
}
|
||||
|
||||
@@ -1642,7 +1610,7 @@ static void cdvdWrite04(u8 rt)
|
||||
cdvdSetIrq();
|
||||
cdvd.nCommand = 0;
|
||||
//After Pausing needs to buffer the next sector
|
||||
cdvd.Status = CDVD_STATUS_READ;
|
||||
cdvd.Status = CDVD_STATUS_PAUSE;
|
||||
cdvd.nextSectorsBuffered = 0;
|
||||
cdvd.triggerDataReady = true;
|
||||
CDVDSECTORREADY_INT(cdvd.ReadTime);
|
||||
@@ -1874,7 +1842,7 @@ static void cdvdWrite04(u8 rt)
|
||||
HW_DMA3_CHCR &= ~0x01000000;
|
||||
psxDmaInterrupt(3);
|
||||
//After reading the TOC it needs to go back to buffer the next sector
|
||||
cdvd.Status = CDVD_STATUS_READ;
|
||||
cdvd.Status = CDVD_STATUS_PAUSE;
|
||||
cdvd.nextSectorsBuffered = 0;
|
||||
cdvd.triggerDataReady = true;
|
||||
CDVDSECTORREADY_INT(cdvd.ReadTime);
|
||||
@@ -1891,7 +1859,7 @@ static void cdvdWrite04(u8 rt)
|
||||
cdvdSetIrq();
|
||||
cdvd.nCommand = 0;
|
||||
//After reading the key it needs to go back to buffer the next sector
|
||||
cdvd.Status = CDVD_STATUS_READ;
|
||||
cdvd.Status = CDVD_STATUS_PAUSE;
|
||||
cdvd.nextSectorsBuffered = 0;
|
||||
cdvd.triggerDataReady = true;
|
||||
CDVDSECTORREADY_INT(cdvd.ReadTime);
|
||||
@@ -1996,7 +1964,6 @@ static __fi void fail_pol_cal()
|
||||
|
||||
static void cdvdWrite16(u8 rt) // SCOMMAND
|
||||
{
|
||||
try
|
||||
{
|
||||
// cdvdTN diskInfo;
|
||||
// cdvdTD trackInfo;
|
||||
@@ -2655,12 +2622,6 @@ static void cdvdWrite16(u8 rt) // SCOMMAND
|
||||
cdvd.ParamP = 0;
|
||||
cdvd.ParamC = 0;
|
||||
}
|
||||
catch (Exception::CannotCreateStream&)
|
||||
{
|
||||
Cpu->ThrowException(Exception::RuntimeError()
|
||||
.SetDiagMsg(L"Failed to read/write NVM/MEC file.")
|
||||
.SetUserMsg(pxE(L"Failed to read/write NVM/MEC file. Check your BIOS setup/permission settings.")));
|
||||
}
|
||||
}
|
||||
|
||||
static __fi void cdvdWrite17(u8 rt)
|
||||
|
||||
+19
-13
@@ -33,6 +33,7 @@
|
||||
#include "IsoFS/IsoFSCDVD.h"
|
||||
#include "CDVDisoReader.h"
|
||||
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/StringUtil.h"
|
||||
#include "DebugTools/SymbolMap.h"
|
||||
#include "Config.h"
|
||||
@@ -376,33 +377,33 @@ bool DoCDVDopen()
|
||||
return true;
|
||||
}
|
||||
|
||||
wxString somepick(Path::GetFilenameWithoutExt(fromUTF8(m_SourceFilename[CurrentSourceType])));
|
||||
std::string somepick(FileSystem::StripExtension(FileSystem::GetDisplayNameFromPath(m_SourceFilename[CurrentSourceType])));
|
||||
//FWIW Disc serial availability doesn't seem reliable enough, sometimes it's there and sometime it's just null
|
||||
//Shouldn't the serial be available all time? Potentially need to look into Elfreloadinfo() reliability
|
||||
//TODO: Add extra fallback case for CRC.
|
||||
if (somepick.IsEmpty() && !DiscSerial.IsEmpty())
|
||||
somepick = L"Untitled-" + DiscSerial;
|
||||
else if (somepick.IsEmpty())
|
||||
somepick = L"Untitled";
|
||||
if (somepick.empty() && !DiscSerial.IsEmpty())
|
||||
somepick = StringUtil::StdStringFromFormat("Untitled-%s", DiscSerial.ToUTF8().data());
|
||||
else if (somepick.empty())
|
||||
somepick = "Untitled";
|
||||
|
||||
if (EmuConfig.CurrentBlockdump.empty())
|
||||
EmuConfig.CurrentBlockdump = StringUtil::wxStringToUTF8String(wxGetCwd());
|
||||
EmuConfig.CurrentBlockdump = FileSystem::GetWorkingDirectory();
|
||||
|
||||
wxString temp(Path::Combine(StringUtil::UTF8StringToWxString(EmuConfig.CurrentBlockdump), somepick));
|
||||
std::string temp(Path::CombineStdString(EmuConfig.CurrentBlockdump, somepick));
|
||||
|
||||
#ifdef ENABLE_TIMESTAMPS
|
||||
wxDateTime curtime(wxDateTime::GetTimeNow());
|
||||
|
||||
temp += pxsFmt(L" (%04d-%02d-%02d %02d-%02d-%02d)",
|
||||
curtime.GetYear(), curtime.GetMonth(), curtime.GetDay(),
|
||||
curtime.GetHour(), curtime.GetMinute(), curtime.GetSecond());
|
||||
temp += StringUtil::StdStringFromFormat(" (%04d-%02d-%02d %02d-%02d-%02d)",
|
||||
curtime.GetYear(), curtime.GetMonth(), curtime.GetDay(),
|
||||
curtime.GetHour(), curtime.GetMinute(), curtime.GetSecond());
|
||||
#endif
|
||||
temp += L".dump";
|
||||
temp += ".dump";
|
||||
|
||||
cdvdTD td;
|
||||
CDVD->getTD(0, &td);
|
||||
|
||||
blockDumpFile.Create(temp, 2);
|
||||
blockDumpFile.Create(std::move(temp), 2);
|
||||
|
||||
if (blockDumpFile.IsOpened())
|
||||
{
|
||||
@@ -432,7 +433,12 @@ bool DoCDVDopen()
|
||||
void DoCDVDclose()
|
||||
{
|
||||
CheckNullCDVD();
|
||||
//blockDumpFile.Close();
|
||||
|
||||
#ifdef PCSX2_CORE
|
||||
// This was commented out, presumably because pausing/resuming in wx reopens CDVD.
|
||||
// This is a non-issue in Qt, so we'll leave it behind the ifdef.
|
||||
blockDumpFile.Close();
|
||||
#endif
|
||||
|
||||
if (CDVD->close != NULL)
|
||||
CDVD->close();
|
||||
|
||||
@@ -52,7 +52,7 @@ s32 CALLBACK ISOopen(const char* pTitle)
|
||||
|
||||
try
|
||||
{
|
||||
iso.Open(fromUTF8(pTitle));
|
||||
iso.Open(pTitle);
|
||||
}
|
||||
catch (BaseException& ex)
|
||||
{
|
||||
|
||||
@@ -16,71 +16,98 @@
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "ChdFileReader.h"
|
||||
|
||||
#include "CDVD/CompressedFileReaderUtils.h"
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include <wx/dir.h>
|
||||
|
||||
bool ChdFileReader::CanHandle(const wxString& fileName)
|
||||
ChdFileReader::~ChdFileReader()
|
||||
{
|
||||
if (!wxFileName::FileExists(fileName) || !fileName.Lower().EndsWith(L".chd"))
|
||||
{
|
||||
Close();
|
||||
|
||||
for (std::FILE* fp : m_files)
|
||||
std::fclose(fp);
|
||||
}
|
||||
|
||||
bool ChdFileReader::CanHandle(const std::string& fileName, const std::string& displayName)
|
||||
{
|
||||
if (!StringUtil::EndsWith(displayName, ".chd"))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChdFileReader::Open2(const wxString& fileName)
|
||||
static chd_error chd_open_wrapper(const char* filename, std::FILE** fp, int mode, chd_file* parent, chd_file** chd)
|
||||
{
|
||||
*fp = FileSystem::OpenCFile(filename, "rb");
|
||||
if (!*fp)
|
||||
return CHDERR_FILE_NOT_FOUND;
|
||||
|
||||
const chd_error err = chd_open_file(*fp, mode, parent, chd);
|
||||
if (err == CHDERR_NONE)
|
||||
return err;
|
||||
|
||||
std::fclose(*fp);
|
||||
*fp = nullptr;
|
||||
return err;
|
||||
}
|
||||
|
||||
bool ChdFileReader::Open2(std::string fileName)
|
||||
{
|
||||
Close2();
|
||||
|
||||
m_filename = fileName;
|
||||
m_filename = std::move(fileName);
|
||||
|
||||
chd_file* child = NULL;
|
||||
chd_file* parent = NULL;
|
||||
chd_file* child = nullptr;
|
||||
chd_file* parent = nullptr;
|
||||
std::FILE* fp = nullptr;
|
||||
chd_header header;
|
||||
chd_header parent_header;
|
||||
|
||||
wxString chds[8];
|
||||
chds[0] = fileName;
|
||||
std::string chds[8];
|
||||
chds[0] = m_filename;
|
||||
int chd_depth = 0;
|
||||
chd_error error;
|
||||
|
||||
// TODO: Unicode correctness on Windows
|
||||
while (CHDERR_REQUIRES_PARENT == (error = chd_open(chds[chd_depth].c_str(), CHD_OPEN_READ, NULL, &child)))
|
||||
std::string dirname;
|
||||
FileSystem::FindResultsArray results;
|
||||
|
||||
while (CHDERR_REQUIRES_PARENT == (error = chd_open_wrapper(chds[chd_depth].c_str(), &fp, CHD_OPEN_READ, NULL, &child)))
|
||||
{
|
||||
if (chd_depth >= static_cast<int>(std::size(chds) - 1))
|
||||
{
|
||||
Console.Error(L"CDVD: chd_open hit recursion limit searching for parents");
|
||||
Console.Error("CDVD: chd_open hit recursion limit searching for parents");
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: This is still broken on Windows. Needs to be fixed in libchdr.
|
||||
if (chd_read_header(chds[chd_depth].c_str(), &header) != CHDERR_NONE)
|
||||
{
|
||||
Console.Error(L"CDVD: chd_open chd_read_header error: %s: %s", chd_error_string(error), WX_STR(chds[chd_depth]));
|
||||
Console.Error("CDVD: chd_open chd_read_header error: %s: %s", chd_error_string(error), chds[chd_depth].c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool found_parent = false;
|
||||
wxFileName wxfilename(chds[chd_depth]);
|
||||
wxString dir_path = wxfilename.GetPath();
|
||||
wxDir dir(dir_path);
|
||||
if (dir.IsOpened())
|
||||
dirname = FileSystem::GetPathDirectory(chds[chd_depth]);
|
||||
if (FileSystem::FindFiles(dirname.c_str(), "*.*", FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES, &results))
|
||||
{
|
||||
wxString parent_fileName;
|
||||
bool cont = dir.GetFirst(&parent_fileName, wxString("*.") + wxfilename.GetExt(), wxDIR_FILES | wxDIR_HIDDEN);
|
||||
for (; cont; cont = dir.GetNext(&parent_fileName))
|
||||
for (const FILESYSTEM_FIND_DATA& fd : results)
|
||||
{
|
||||
parent_fileName = wxFileName(dir_path, parent_fileName).GetFullPath();
|
||||
if (chd_read_header(parent_fileName.c_str(), &parent_header) == CHDERR_NONE &&
|
||||
const std::string_view extension(FileSystem::GetExtension(fd.FileName));
|
||||
if (extension.empty() || StringUtil::Strncasecmp(extension.data(), "chd", 3) != 0)
|
||||
continue;
|
||||
|
||||
if (chd_read_header(fd.FileName.c_str(), &parent_header) == CHDERR_NONE &&
|
||||
memcmp(parent_header.sha1, header.parentsha1, sizeof(parent_header.sha1)) == 0)
|
||||
{
|
||||
found_parent = true;
|
||||
chds[++chd_depth] = wxString(parent_fileName);
|
||||
chds[++chd_depth] = std::move(fd.FileName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_parent)
|
||||
{
|
||||
Console.Error(L"CDVD: chd_open no parent for: %s", WX_STR(chds[chd_depth]));
|
||||
Console.Error("CDVD: chd_open no parent for: %s", chds[chd_depth].c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -91,11 +118,17 @@ bool ChdFileReader::Open2(const wxString& fileName)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (child)
|
||||
{
|
||||
pxAssert(fp != nullptr);
|
||||
m_files.push_back(fp);
|
||||
}
|
||||
|
||||
for (int d = chd_depth - 1; d >= 0; d--)
|
||||
{
|
||||
parent = child;
|
||||
child = NULL;
|
||||
error = chd_open(chds[d].c_str(), CHD_OPEN_READ, parent, &child);
|
||||
error = chd_open_wrapper(chds[d].c_str(), &fp, CHD_OPEN_READ, parent, &child);
|
||||
if (error != CHDERR_NONE)
|
||||
{
|
||||
Console.Error(L"CDVD: chd_open return error: %s", chd_error_string(error));
|
||||
@@ -103,19 +136,17 @@ bool ChdFileReader::Open2(const wxString& fileName)
|
||||
chd_close(parent);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_files.push_back(fp);
|
||||
}
|
||||
ChdFile = child;
|
||||
if (chd_read_header(chds[0].c_str(), &header) != CHDERR_NONE)
|
||||
{
|
||||
Console.Error(L"CDVD: chd_open chd_read_header error: %s: %s", chd_error_string(error), WX_STR(chds[0]));
|
||||
return false;
|
||||
}
|
||||
|
||||
file_size = static_cast<u64>(header.unitbytes) * header.unitcount;
|
||||
hunk_size = header.hunkbytes;
|
||||
const chd_header* chd_header = chd_get_header(ChdFile);
|
||||
file_size = static_cast<u64>(chd_header->unitbytes) * chd_header->unitcount;
|
||||
hunk_size = chd_header->hunkbytes;
|
||||
// CHD likes to use full 2448 byte blocks, but keeps the +24 offset of source ISOs
|
||||
// The rest of PCSX2 likes to use 2448 byte buffers, which can't fit that so trim blocks instead
|
||||
m_internalBlockSize = header.unitbytes;
|
||||
m_internalBlockSize = chd_header->unitbytes;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -136,7 +167,7 @@ ThreadedFileReader::Chunk ChdFileReader::ChunkForOffset(u64 offset)
|
||||
return chunk;
|
||||
}
|
||||
|
||||
int ChdFileReader::ReadChunk(void *dst, s64 chunkID)
|
||||
int ChdFileReader::ReadChunk(void* dst, s64 chunkID)
|
||||
{
|
||||
if (chunkID < 0)
|
||||
return -1;
|
||||
|
||||
@@ -16,16 +16,17 @@
|
||||
#pragma once
|
||||
#include "ThreadedFileReader.h"
|
||||
#include "libchdr/chd.h"
|
||||
#include <vector>
|
||||
|
||||
class ChdFileReader : public ThreadedFileReader
|
||||
{
|
||||
DeclareNoncopyableObject(ChdFileReader);
|
||||
|
||||
public:
|
||||
virtual ~ChdFileReader(void) { Close(); };
|
||||
virtual ~ChdFileReader() override;;
|
||||
|
||||
static bool CanHandle(const wxString& fileName);
|
||||
bool Open2(const wxString& fileName) override;
|
||||
static bool CanHandle(const std::string& fileName, const std::string& displayName);
|
||||
bool Open2(std::string fileName) override;
|
||||
|
||||
Chunk ChunkForOffset(u64 offset) override;
|
||||
int ReadChunk(void *dst, s64 blockID) override;
|
||||
@@ -38,4 +39,5 @@ private:
|
||||
chd_file* ChdFile;
|
||||
u64 file_size;
|
||||
u32 hunk_size;
|
||||
std::vector<std::FILE*> m_files;
|
||||
};
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
void ChunksCache::SetLimit(uint megabytes)
|
||||
{
|
||||
m_limit = (PX_off_t)megabytes * 1024 * 1024;
|
||||
m_limit = (s64)megabytes * 1024 * 1024;
|
||||
MatchLimit();
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ void ChunksCache::MatchLimit(bool removeAll)
|
||||
}
|
||||
}
|
||||
|
||||
void ChunksCache::Take(void* pMallocedSrc, PX_off_t offset, int length, int coverage)
|
||||
void ChunksCache::Take(void* pMallocedSrc, s64 offset, int length, int coverage)
|
||||
{
|
||||
m_entries.push_front(new CacheEntry(pMallocedSrc, offset, length, coverage));
|
||||
m_size += length;
|
||||
@@ -42,7 +42,7 @@ void ChunksCache::Take(void* pMallocedSrc, PX_off_t offset, int length, int cove
|
||||
}
|
||||
|
||||
// By design, succeed only if the entire request is in a single cached chunk
|
||||
int ChunksCache::Read(void* pDest, PX_off_t offset, int length)
|
||||
int ChunksCache::Read(void* pDest, s64 offset, int length)
|
||||
{
|
||||
for (auto it = m_entries.begin(); it != m_entries.end(); it++)
|
||||
{
|
||||
|
||||
@@ -30,11 +30,11 @@ public:
|
||||
void SetLimit(uint megabytes);
|
||||
void Clear() { MatchLimit(true); };
|
||||
|
||||
void Take(void* pMallocedSrc, PX_off_t offset, int length, int coverage);
|
||||
int Read(void* pDest, PX_off_t offset, int length);
|
||||
void Take(void* pMallocedSrc, s64 offset, int length, int coverage);
|
||||
int Read(void* pDest, s64 offset, int length);
|
||||
|
||||
static int CopyAvailable(void* pSrc, PX_off_t srcOffset, int srcSize,
|
||||
void* pDst, PX_off_t dstOffset, int maxCopySize)
|
||||
static int CopyAvailable(void* pSrc, s64 srcOffset, int srcSize,
|
||||
void* pDst, s64 dstOffset, int maxCopySize)
|
||||
{
|
||||
int available = CLAMP(maxCopySize, 0, (int)(srcOffset + srcSize - dstOffset));
|
||||
memcpy(pDst, (char*)pSrc + (dstOffset - srcOffset), available);
|
||||
@@ -45,7 +45,7 @@ private:
|
||||
class CacheEntry
|
||||
{
|
||||
public:
|
||||
CacheEntry(void* pMallocedSrc, PX_off_t offset, int length, int coverage)
|
||||
CacheEntry(void* pMallocedSrc, s64 offset, int length, int coverage)
|
||||
: data(pMallocedSrc)
|
||||
, offset(offset)
|
||||
, coverage(coverage)
|
||||
@@ -58,15 +58,15 @@ private:
|
||||
};
|
||||
|
||||
void* data;
|
||||
PX_off_t offset;
|
||||
s64 offset;
|
||||
int coverage;
|
||||
int size;
|
||||
};
|
||||
|
||||
std::list<CacheEntry*> m_entries;
|
||||
void MatchLimit(bool removeAll = false);
|
||||
PX_off_t m_size;
|
||||
PX_off_t m_limit;
|
||||
s64 m_size;
|
||||
s64 m_limit;
|
||||
};
|
||||
|
||||
#undef CLAMP
|
||||
|
||||
@@ -19,19 +19,27 @@
|
||||
#include "ChdFileReader.h"
|
||||
#include "CsoFileReader.h"
|
||||
#include "GzippedFileReader.h"
|
||||
#include "common/FileSystem.h"
|
||||
#include <cctype>
|
||||
|
||||
// CompressedFileReader factory.
|
||||
AsyncFileReader* CompressedFileReader::GetNewReader(const wxString& fileName)
|
||||
AsyncFileReader* CompressedFileReader::GetNewReader(const std::string& fileName)
|
||||
{
|
||||
if (ChdFileReader::CanHandle(fileName))
|
||||
if (!FileSystem::FileExists(fileName.c_str()))
|
||||
return nullptr;
|
||||
|
||||
std::string displayName(FileSystem::GetDisplayNameFromPath(fileName));
|
||||
std::transform(displayName.begin(), displayName.end(), displayName.begin(), tolower);
|
||||
|
||||
if (ChdFileReader::CanHandle(fileName, displayName))
|
||||
{
|
||||
return new ChdFileReader();
|
||||
}
|
||||
if (GzippedFileReader::CanHandle(fileName))
|
||||
if (GzippedFileReader::CanHandle(fileName, displayName))
|
||||
{
|
||||
return new GzippedFileReader();
|
||||
}
|
||||
if (CsoFileReader::CanHandle(fileName))
|
||||
if (CsoFileReader::CanHandle(fileName, displayName))
|
||||
{
|
||||
return new CsoFileReader();
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
// Factory - creates an AsyncFileReader derived instance which can read a compressed file
|
||||
class CompressedFileReader
|
||||
@@ -23,7 +24,7 @@ public:
|
||||
// If no matching handler is found, NULL is returned.
|
||||
// The returned instance still needs ->Open(filename) before usage.
|
||||
// Open(filename) may still fail.
|
||||
static AsyncFileReader* GetNewReader(const wxString& fileName);
|
||||
static AsyncFileReader* GetNewReader(const std::string& fileName);
|
||||
|
||||
private:
|
||||
virtual ~CompressedFileReader() = 0;
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2014 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/Pcsx2Types.h"
|
||||
|
||||
/////////// Some complementary utilities for zlib_indexed.c //////////
|
||||
|
||||
// This is ugly, but it's hard to find something which will work/compile for both
|
||||
// windows and *nix and work with non-english file names.
|
||||
// Maybe some day we'll convert all file related ops to wxWidgets, which means also the
|
||||
// instances at zlib_indexed.h (which use plain stdio FILE*)
|
||||
#ifdef _WIN32
|
||||
#define PX_wfilename(name_wxstr) (name_wxstr.wc_str())
|
||||
#define PX_fopen_rb(name_wxstr) (_wfopen(PX_wfilename(name_wxstr), L"rb"))
|
||||
#else
|
||||
#define PX_wfilename(name_wxstr) (name_wxstr.mbc_str())
|
||||
#define PX_fopen_rb(name_wxstr) (fopen(PX_wfilename(name_wxstr), "rb"))
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define PX_fseeko _fseeki64
|
||||
#define PX_ftello _ftelli64
|
||||
#define PX_off_t s64 /* __int64 */
|
||||
#else
|
||||
#define PX_fseeko fseeko
|
||||
#define PX_ftello ftello
|
||||
#define PX_off_t off_t
|
||||
#endif
|
||||
|
||||
/////////// End of complementary utilities for zlib_indexed.c //////////
|
||||
@@ -15,9 +15,10 @@
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "AsyncFileReader.h"
|
||||
#include "CompressedFileReaderUtils.h"
|
||||
#include "CsoFileReader.h"
|
||||
#include "common/Pcsx2Types.h"
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/StringUtil.h"
|
||||
#ifdef __POSIX__
|
||||
#include <zlib.h>
|
||||
#else
|
||||
@@ -39,12 +40,12 @@ struct CsoHeader
|
||||
|
||||
static const u32 CSO_READ_BUFFER_SIZE = 256 * 1024;
|
||||
|
||||
bool CsoFileReader::CanHandle(const wxString& fileName)
|
||||
bool CsoFileReader::CanHandle(const std::string& fileName, const std::string& displayName)
|
||||
{
|
||||
bool supported = false;
|
||||
if (wxFileName::FileExists(fileName) && fileName.Lower().EndsWith(L".cso"))
|
||||
if (StringUtil::EndsWith(displayName, ".cso"))
|
||||
{
|
||||
FILE* fp = PX_fopen_rb(fileName);
|
||||
FILE* fp = FileSystem::OpenCFile(fileName.c_str(), "rb");
|
||||
CsoHeader hdr;
|
||||
if (fp)
|
||||
{
|
||||
@@ -67,17 +68,17 @@ bool CsoFileReader::ValidateHeader(const CsoHeader& hdr)
|
||||
}
|
||||
if (hdr.ver > 1)
|
||||
{
|
||||
Console.Error(L"Only CSOv1 files are supported.");
|
||||
Console.Error("Only CSOv1 files are supported.");
|
||||
return false;
|
||||
}
|
||||
if ((hdr.frame_size & (hdr.frame_size - 1)) != 0)
|
||||
{
|
||||
Console.Error(L"CSO frame size must be a power of two.");
|
||||
Console.Error("CSO frame size must be a power of two.");
|
||||
return false;
|
||||
}
|
||||
if (hdr.frame_size < 2048)
|
||||
{
|
||||
Console.Error(L"CSO frame size must be at least one sector.");
|
||||
Console.Error("CSO frame size must be at least one sector.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -85,11 +86,11 @@ bool CsoFileReader::ValidateHeader(const CsoHeader& hdr)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CsoFileReader::Open2(const wxString& fileName)
|
||||
bool CsoFileReader::Open2(std::string fileName)
|
||||
{
|
||||
Close2();
|
||||
m_filename = fileName;
|
||||
m_src = PX_fopen_rb(m_filename);
|
||||
m_filename = std::move(fileName);
|
||||
m_src = FileSystem::OpenCFile(m_filename.c_str(), "rb");
|
||||
|
||||
bool success = false;
|
||||
if (m_src && ReadFileHeader() && InitializeBuffers())
|
||||
@@ -109,16 +110,15 @@ bool CsoFileReader::ReadFileHeader()
|
||||
{
|
||||
CsoHeader hdr = {};
|
||||
|
||||
PX_fseeko(m_src, m_dataoffset, SEEK_SET);
|
||||
if (fread(&hdr, 1, sizeof(hdr), m_src) != sizeof(hdr))
|
||||
if (FileSystem::FSeek64(m_src, m_dataoffset, SEEK_SET) != 0 || std::fread(&hdr, 1, sizeof(hdr), m_src) != sizeof(hdr))
|
||||
{
|
||||
Console.Error(L"Failed to read CSO file header.");
|
||||
Console.Error("Failed to read CSO file header.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ValidateHeader(hdr))
|
||||
{
|
||||
Console.Error(L"CSO has invalid header.");
|
||||
Console.Error("CSO has invalid header.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ bool CsoFileReader::InitializeBuffers()
|
||||
m_index = new u32[indexSize];
|
||||
if (fread(m_index, sizeof(u32), indexSize, m_src) != indexSize)
|
||||
{
|
||||
Console.Error(L"Unable to read index data from CSO.");
|
||||
Console.Error("Unable to read index data from CSO.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ bool CsoFileReader::InitializeBuffers()
|
||||
|
||||
void CsoFileReader::Close2()
|
||||
{
|
||||
m_filename.Empty();
|
||||
m_filename.clear();
|
||||
|
||||
if (m_src)
|
||||
{
|
||||
@@ -235,7 +235,7 @@ int CsoFileReader::ReadChunk(void *dst, s64 chunkID)
|
||||
if (!compressed)
|
||||
{
|
||||
// Just read directly, easy.
|
||||
if (PX_fseeko(m_src, frameRawPos, SEEK_SET) != 0)
|
||||
if (FileSystem::FSeek64(m_src, frameRawPos, SEEK_SET) != 0)
|
||||
{
|
||||
Console.Error("Unable to seek to uncompressed CSO data.");
|
||||
return 0;
|
||||
@@ -244,7 +244,7 @@ int CsoFileReader::ReadChunk(void *dst, s64 chunkID)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PX_fseeko(m_src, frameRawPos, SEEK_SET) != 0)
|
||||
if (FileSystem::FSeek64(m_src, frameRawPos, SEEK_SET) != 0)
|
||||
{
|
||||
Console.Error("Unable to seek to compressed CSO data.");
|
||||
return 0;
|
||||
|
||||
@@ -52,8 +52,8 @@ public:
|
||||
|
||||
~CsoFileReader(void) { Close(); };
|
||||
|
||||
static bool CanHandle(const wxString& fileName);
|
||||
bool Open2(const wxString& fileName) override;
|
||||
static bool CanHandle(const std::string& fileName, const std::string& displayName);
|
||||
bool Open2(std::string fileName) override;
|
||||
|
||||
Chunk ChunkForOffset(u64 offset) override;
|
||||
int ReadChunk(void *dst, s64 chunkID) override;
|
||||
|
||||
@@ -14,29 +14,17 @@
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include <fstream>
|
||||
#include <wx/stdpaths.h>
|
||||
#include <fstream>
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/StringUtil.h"
|
||||
#include "Config.h"
|
||||
#include "ChunksCache.h"
|
||||
#include "CompressedFileReaderUtils.h"
|
||||
#include "GzippedFileReader.h"
|
||||
#include "zlib_indexed.h"
|
||||
|
||||
#define CLAMP(val, minval, maxval) (std::min(maxval, std::max(minval, val)))
|
||||
|
||||
static s64 fsize(const wxString& filename)
|
||||
{
|
||||
if (!wxFileName::FileExists(filename))
|
||||
return -1;
|
||||
|
||||
std::ifstream f(PX_wfilename(filename), std::ifstream::binary);
|
||||
f.seekg(0, f.end);
|
||||
s64 size = f.tellg();
|
||||
f.close();
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
#define GZIP_ID "PCSX2.index.gzip.v1|"
|
||||
#define GZIP_ID_LEN (sizeof(GZIP_ID) - 1) /* sizeof includes the \0 terminator */
|
||||
|
||||
@@ -44,71 +32,75 @@ static s64 fsize(const wxString& filename)
|
||||
// - [GZIP_ID_LEN] GZIP_ID (no \0)
|
||||
// - [sizeof(Access)] index (should be allocated, contains various sizes)
|
||||
// - [rest] the indexed data points (should be allocated, index->list should then point to it)
|
||||
static Access* ReadIndexFromFile(const wxString& filename)
|
||||
static Access* ReadIndexFromFile(const char* filename)
|
||||
{
|
||||
s64 size = fsize(filename);
|
||||
if (size <= 0)
|
||||
auto fp = FileSystem::OpenManagedCFile(filename, "rb");
|
||||
s64 size;
|
||||
if (!fp || (size = FileSystem::FSize64(fp.get())) <= 0)
|
||||
{
|
||||
Console.Error(L"Error: Can't open index file: '%s'", WX_STR(filename));
|
||||
Console.Error("Error: Can't open index file: '%s'", filename);
|
||||
return 0;
|
||||
}
|
||||
std::ifstream infile(PX_wfilename(filename), std::ifstream::binary);
|
||||
|
||||
char fileId[GZIP_ID_LEN + 1] = {0};
|
||||
infile.read(fileId, GZIP_ID_LEN);
|
||||
if (wxString::From8BitData(GZIP_ID) != wxString::From8BitData(fileId))
|
||||
if (std::fread(fileId, GZIP_ID_LEN, 1, fp.get()) != 1 || std::memcmp(fileId, GZIP_ID, 4) != 0)
|
||||
{
|
||||
Console.Error(L"Error: Incompatible gzip index, please delete it manually: '%s'", WX_STR(filename));
|
||||
infile.close();
|
||||
Console.Error("Error: Incompatible gzip index, please delete it manually: '%s'", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Access* index = (Access*)malloc(sizeof(Access));
|
||||
infile.read((char*)index, sizeof(Access));
|
||||
|
||||
s64 datasize = size - GZIP_ID_LEN - sizeof(Access);
|
||||
if (datasize != (s64)index->have * sizeof(Point))
|
||||
Access* const index = (Access*)malloc(sizeof(Access));
|
||||
const s64 datasize = size - GZIP_ID_LEN - sizeof(Access);
|
||||
if (std::fread(index, sizeof(Access), 1, fp.get()) != 1 ||
|
||||
datasize != static_cast<s64>(index->have) * static_cast<s64>(sizeof(Point)))
|
||||
{
|
||||
Console.Error(L"Error: unexpected size of gzip index, please delete it manually: '%s'.", WX_STR(filename));
|
||||
infile.close();
|
||||
Console.Error("Error: unexpected size of gzip index, please delete it manually: '%s'.", filename);
|
||||
free(index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* buffer = (char*)malloc(datasize);
|
||||
infile.read(buffer, datasize);
|
||||
infile.close();
|
||||
if (std::fread(buffer, datasize, 1, fp.get()) != 1)
|
||||
{
|
||||
Console.Error("Error: failed read of gzip index, please delete it manually: '%s'.", filename);
|
||||
free(buffer);
|
||||
free(index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
index->list = (Point*)buffer; // adjust list pointer
|
||||
return index;
|
||||
}
|
||||
|
||||
static void WriteIndexToFile(Access* index, const wxString filename)
|
||||
static void WriteIndexToFile(Access* index, const char* filename)
|
||||
{
|
||||
if (wxFileName::FileExists(filename))
|
||||
if (FileSystem::FileExists(filename))
|
||||
{
|
||||
Console.Warning(L"WARNING: Won't write index - file name exists (please delete it manually): '%s'", WX_STR(filename));
|
||||
Console.Warning("WARNING: Won't write index - file name exists (please delete it manually): '%s'", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
std::ofstream outfile(PX_wfilename(filename), std::ofstream::binary);
|
||||
outfile.write(GZIP_ID, GZIP_ID_LEN);
|
||||
auto fp = FileSystem::OpenManagedCFile(filename, "wb");
|
||||
if (!fp)
|
||||
return;
|
||||
|
||||
bool success = (std::fwrite(GZIP_ID, GZIP_ID_LEN, 1, fp.get()) == 1);
|
||||
|
||||
Point* tmp = index->list;
|
||||
index->list = 0; // current pointer is useless on disk, normalize it as 0.
|
||||
outfile.write((char*)index, sizeof(Access));
|
||||
std::fwrite((char*)index, sizeof(Access), 1, fp.get());
|
||||
index->list = tmp;
|
||||
|
||||
outfile.write((char*)index->list, sizeof(Point) * index->have);
|
||||
outfile.close();
|
||||
success = success && (std::fwrite((char*)index->list, sizeof(Point) * index->have, 1, fp.get()) == 1);
|
||||
|
||||
// Verify
|
||||
if (fsize(filename) != (s64)GZIP_ID_LEN + sizeof(Access) + sizeof(Point) * index->have)
|
||||
if (!success)
|
||||
{
|
||||
Console.Warning(L"Warning: Can't write index file to disk: '%s'", WX_STR(filename));
|
||||
Console.Warning("Warning: Can't write index file to disk: '%s'", filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLn(Color_Green, L"OK: Gzip quick access index file saved to disk: '%s'", WX_STR(filename));
|
||||
Console.WriteLn(Color_Green, "OK: Gzip quick access index file saved to disk: '%s'", filename);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,10 +115,10 @@ static wxString INDEX_TEMPLATE_KEY(L"$(f)");
|
||||
// No checks are performed if the result file name can be created.
|
||||
// If this proves useful, we can move it into Path:: . Right now there's no need.
|
||||
static wxString ApplyTemplate(const wxString& name, const wxDirName& base,
|
||||
const wxString& fileTemplate, const wxString& filename,
|
||||
const std::string& fileTemplate, const std::string& filename,
|
||||
bool canEndWithKey)
|
||||
{
|
||||
wxString tem(fileTemplate);
|
||||
wxString tem(StringUtil::UTF8StringToWxString(fileTemplate));
|
||||
wxString key = INDEX_TEMPLATE_KEY;
|
||||
tem = tem.Trim(true).Trim(false); // both sides
|
||||
|
||||
@@ -141,7 +133,7 @@ static wxString ApplyTemplate(const wxString& name, const wxDirName& base,
|
||||
return L"";
|
||||
}
|
||||
|
||||
wxString fname(filename);
|
||||
wxString fname(StringUtil::UTF8StringToWxString(filename));
|
||||
if (first > 0)
|
||||
fname = Path::GetFilename(fname); // without path
|
||||
|
||||
@@ -179,13 +171,13 @@ static void TestTemplate(const wxDirName &base, const wxString &fname, bool canE
|
||||
}
|
||||
*/
|
||||
|
||||
static wxString iso2indexname(const wxString& isoname)
|
||||
static std::string iso2indexname(const std::string& isoname)
|
||||
{
|
||||
//testTemplate(isoname);
|
||||
wxDirName appRoot = // TODO: have only one of this in PCSX2. Right now have few...
|
||||
(wxDirName)(wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath());
|
||||
//TestTemplate(appRoot, isoname, false);
|
||||
return ApplyTemplate(L"gzip index", appRoot, fromUTF8(EmuConfig.GzipIsoIndexTemplate), isoname, false);
|
||||
return StringUtil::wxStringToUTF8String(ApplyTemplate(L"gzip index", appRoot, EmuConfig.GzipIsoIndexTemplate, isoname, false));
|
||||
}
|
||||
|
||||
GzippedFileReader::GzippedFileReader(void)
|
||||
@@ -218,7 +210,7 @@ void GzippedFileReader::InitZstates()
|
||||
void GzippedFileReader::AsyncPrefetchReset(){};
|
||||
void GzippedFileReader::AsyncPrefetchOpen(){};
|
||||
void GzippedFileReader::AsyncPrefetchClose(){};
|
||||
void GzippedFileReader::AsyncPrefetchChunk(PX_off_t dummy){};
|
||||
void GzippedFileReader::AsyncPrefetchChunk(s64 dummy){};
|
||||
void GzippedFileReader::AsyncPrefetchCancel(){};
|
||||
#else
|
||||
// AsyncPrefetch works as follows:
|
||||
@@ -239,7 +231,7 @@ void GzippedFileReader::AsyncPrefetchReset()
|
||||
void GzippedFileReader::AsyncPrefetchOpen()
|
||||
{
|
||||
hOverlappedFile = CreateFile(
|
||||
m_filename,
|
||||
StringUtil::UTF8StringToWideString(m_filename).c_str(),
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
@@ -258,7 +250,7 @@ void GzippedFileReader::AsyncPrefetchClose()
|
||||
AsyncPrefetchReset();
|
||||
};
|
||||
|
||||
void GzippedFileReader::AsyncPrefetchChunk(PX_off_t start)
|
||||
void GzippedFileReader::AsyncPrefetchChunk(s64 start)
|
||||
{
|
||||
if (hOverlappedFile == INVALID_HANDLE_VALUE || asyncInProgress)
|
||||
{
|
||||
@@ -296,9 +288,9 @@ void GzippedFileReader::AsyncPrefetchCancel()
|
||||
#endif /* _WIN32 */
|
||||
|
||||
// TODO: do better than just checking existance and extension
|
||||
bool GzippedFileReader::CanHandle(const wxString& fileName)
|
||||
bool GzippedFileReader::CanHandle(const std::string& fileName, const std::string& displayName)
|
||||
{
|
||||
return wxFileName::FileExists(fileName) && fileName.Lower().EndsWith(L".gz");
|
||||
return StringUtil::EndsWith(fileName, ".gz");
|
||||
}
|
||||
|
||||
bool GzippedFileReader::OkIndex()
|
||||
@@ -307,29 +299,29 @@ bool GzippedFileReader::OkIndex()
|
||||
return true;
|
||||
|
||||
// Try to read index from disk
|
||||
wxString indexfile = iso2indexname(m_filename);
|
||||
if (indexfile.length() == 0)
|
||||
const std::string indexfile(iso2indexname(m_filename));
|
||||
if (indexfile.empty())
|
||||
return false; // iso2indexname(...) will print errors if it can't apply the template
|
||||
|
||||
if (wxFileName::FileExists(indexfile) && (m_pIndex = ReadIndexFromFile(indexfile)))
|
||||
if (FileSystem::FileExists(indexfile.c_str()) && (m_pIndex = ReadIndexFromFile(indexfile.c_str())))
|
||||
{
|
||||
Console.WriteLn(Color_Green, L"OK: Gzip quick access index read from disk: '%s'", WX_STR(indexfile));
|
||||
Console.WriteLn(Color_Green, "OK: Gzip quick access index read from disk: '%s'", indexfile.c_str());
|
||||
if (m_pIndex->span != GZFILE_SPAN_DEFAULT)
|
||||
{
|
||||
Console.Warning(L"Note: This index has %1.1f MB intervals, while the current default for new indexes is %1.1f MB.",
|
||||
Console.Warning("Note: This index has %1.1f MB intervals, while the current default for new indexes is %1.1f MB.",
|
||||
(float)m_pIndex->span / 1024 / 1024, (float)GZFILE_SPAN_DEFAULT / 1024 / 1024);
|
||||
Console.Warning(L"It will work fine, but if you want to generate a new index with default intervals, delete this index file.");
|
||||
Console.Warning(L"(smaller intervals mean bigger index file and quicker but more frequent decompressions)");
|
||||
Console.Warning("It will work fine, but if you want to generate a new index with default intervals, delete this index file.");
|
||||
Console.Warning("(smaller intervals mean bigger index file and quicker but more frequent decompressions)");
|
||||
}
|
||||
InitZstates();
|
||||
return true;
|
||||
}
|
||||
|
||||
// No valid index file. Generate an index
|
||||
Console.Warning(L"This may take a while (but only once). Scanning compressed file to generate a quick access index...");
|
||||
Console.Warning("This may take a while (but only once). Scanning compressed file to generate a quick access index...");
|
||||
|
||||
Access* index;
|
||||
FILE* infile = PX_fopen_rb(m_filename);
|
||||
FILE* infile = FileSystem::OpenCFile(m_filename.c_str(), "rb");
|
||||
int len = build_index(infile, GZFILE_SPAN_DEFAULT, &index);
|
||||
printf("\n"); // build_index prints progress without \n's
|
||||
fclose(infile);
|
||||
@@ -337,11 +329,11 @@ bool GzippedFileReader::OkIndex()
|
||||
if (len >= 0)
|
||||
{
|
||||
m_pIndex = index;
|
||||
WriteIndexToFile((Access*)m_pIndex, indexfile);
|
||||
WriteIndexToFile((Access*)m_pIndex, indexfile.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.Error(L"ERROR (%d): index could not be generated for file '%s'", len, WX_STR(m_filename));
|
||||
Console.Error("ERROR (%d): index could not be generated for file '%s'", len, m_filename.c_str());
|
||||
free_index(index);
|
||||
InitZstates();
|
||||
return false;
|
||||
@@ -351,11 +343,11 @@ bool GzippedFileReader::OkIndex()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GzippedFileReader::Open(const wxString& fileName)
|
||||
bool GzippedFileReader::Open(std::string fileName)
|
||||
{
|
||||
Close();
|
||||
m_filename = fileName;
|
||||
if (!(m_src = PX_fopen_rb(m_filename)) || !CanHandle(fileName) || !OkIndex())
|
||||
m_filename = std::move(fileName);
|
||||
if (!(m_src = FileSystem::OpenCFile(m_filename.c_str(), "rb")) || !OkIndex())
|
||||
{
|
||||
Close();
|
||||
return false;
|
||||
@@ -384,7 +376,7 @@ int GzippedFileReader::FinishRead(void)
|
||||
|
||||
int GzippedFileReader::ReadSync(void* pBuffer, uint sector, uint count)
|
||||
{
|
||||
PX_off_t offset = (s64)sector * m_blocksize + m_dataoffset;
|
||||
s64 offset = (s64)sector * m_blocksize + m_dataoffset;
|
||||
int bytesToRead = count * m_blocksize;
|
||||
int res = _ReadSync(pBuffer, offset, bytesToRead);
|
||||
if (res < 0)
|
||||
@@ -393,11 +385,11 @@ int GzippedFileReader::ReadSync(void* pBuffer, uint sector, uint count)
|
||||
}
|
||||
|
||||
// If we have a valid and adequate zstate for this span, use it, else, use the index
|
||||
PX_off_t GzippedFileReader::GetOptimalExtractionStart(PX_off_t offset)
|
||||
s64 GzippedFileReader::GetOptimalExtractionStart(s64 offset)
|
||||
{
|
||||
int span = m_pIndex->span;
|
||||
Czstate& cstate = m_zstates[offset / span];
|
||||
PX_off_t stateOffset = cstate.state.isValid ? cstate.state.out_offset : 0;
|
||||
s64 stateOffset = cstate.state.isValid ? cstate.state.out_offset : 0;
|
||||
if (stateOffset && stateOffset <= offset)
|
||||
return stateOffset; // state is faster than indexed
|
||||
|
||||
@@ -409,7 +401,7 @@ PX_off_t GzippedFileReader::GetOptimalExtractionStart(PX_off_t offset)
|
||||
return span * (offset / span); // index direct access boundaries
|
||||
}
|
||||
|
||||
int GzippedFileReader::_ReadSync(void* pBuffer, PX_off_t offset, uint bytesToRead)
|
||||
int GzippedFileReader::_ReadSync(void* pBuffer, s64 offset, uint bytesToRead)
|
||||
{
|
||||
if (!OkIndex())
|
||||
return -1;
|
||||
@@ -441,7 +433,7 @@ int GzippedFileReader::_ReadSync(void* pBuffer, PX_off_t offset, uint bytesToRea
|
||||
// Not available from cache. Decompress from optimal starting
|
||||
// point in GZFILE_READ_CHUNK_SIZE chunks and cache each chunk.
|
||||
PTT s = NOW();
|
||||
PX_off_t extractOffset = GetOptimalExtractionStart(offset); // guaranteed in GZFILE_READ_CHUNK_SIZE boundaries
|
||||
s64 extractOffset = GetOptimalExtractionStart(offset); // guaranteed in GZFILE_READ_CHUNK_SIZE boundaries
|
||||
int size = offset + maxInChunk - extractOffset;
|
||||
unsigned char* extracted = (unsigned char*)malloc(size);
|
||||
|
||||
@@ -501,7 +493,7 @@ int GzippedFileReader::_ReadSync(void* pBuffer, PX_off_t offset, uint bytesToRea
|
||||
|
||||
void GzippedFileReader::Close()
|
||||
{
|
||||
m_filename.Empty();
|
||||
m_filename.clear();
|
||||
if (m_pIndex)
|
||||
{
|
||||
free_index((Access*)m_pIndex);
|
||||
|
||||
@@ -34,8 +34,8 @@ public:
|
||||
|
||||
virtual ~GzippedFileReader(void) { Close(); };
|
||||
|
||||
static bool CanHandle(const wxString& fileName);
|
||||
virtual bool Open(const wxString& fileName);
|
||||
static bool CanHandle(const std::string& fileName, const std::string& displayName);
|
||||
virtual bool Open(std::string fileName);
|
||||
|
||||
virtual int ReadSync(void* pBuffer, uint sector, uint count);
|
||||
|
||||
@@ -71,8 +71,8 @@ private:
|
||||
};
|
||||
|
||||
bool OkIndex(); // Verifies that we have an index, or try to create one
|
||||
PX_off_t GetOptimalExtractionStart(PX_off_t offset);
|
||||
int _ReadSync(void* pBuffer, PX_off_t offset, uint bytesToRead);
|
||||
s64 GetOptimalExtractionStart(s64 offset);
|
||||
int _ReadSync(void* pBuffer, s64 offset, uint bytesToRead);
|
||||
void InitZstates();
|
||||
|
||||
int mBytesRead; // Temp sync read result when simulating async read
|
||||
@@ -93,6 +93,6 @@ private:
|
||||
void AsyncPrefetchReset();
|
||||
void AsyncPrefetchOpen();
|
||||
void AsyncPrefetchClose();
|
||||
void AsyncPrefetchChunk(PX_off_t dummy);
|
||||
void AsyncPrefetchChunk(s64 dummy);
|
||||
void AsyncPrefetchCancel();
|
||||
};
|
||||
|
||||
@@ -194,19 +194,16 @@ void InputIsoFile::_init()
|
||||
//
|
||||
// Note that this is a member method, and that it will clobber any existing ISO state.
|
||||
// (assertions are generated in debug mode if the object state is not already closed).
|
||||
bool InputIsoFile::Test(const wxString& srcfile)
|
||||
bool InputIsoFile::Test(std::string srcfile)
|
||||
{
|
||||
Close();
|
||||
m_filename = srcfile;
|
||||
|
||||
return Open(srcfile, true);
|
||||
return Open(std::move(srcfile), true);
|
||||
}
|
||||
|
||||
bool InputIsoFile::Open(const wxString& srcfile, bool testOnly)
|
||||
bool InputIsoFile::Open(std::string srcfile, bool testOnly)
|
||||
{
|
||||
Close();
|
||||
m_filename = srcfile;
|
||||
m_reader = NULL;
|
||||
m_filename = std::move(srcfile);
|
||||
|
||||
bool isBlockdump = false;
|
||||
bool isCompressed = false;
|
||||
@@ -224,7 +221,8 @@ bool InputIsoFile::Open(const wxString& srcfile, bool testOnly)
|
||||
m_reader = new FlatFileReader(EmuConfig.CdvdShareWrite);
|
||||
}
|
||||
|
||||
m_reader->Open(m_filename);
|
||||
if (!m_reader->Open(m_filename))
|
||||
return false;
|
||||
|
||||
// It might actually be a blockdump file.
|
||||
// Check that before continuing with the FlatFileReader.
|
||||
@@ -270,7 +268,7 @@ bool InputIsoFile::Open(const wxString& srcfile, bool testOnly)
|
||||
|
||||
m_blocks = m_reader->GetBlockCount();
|
||||
|
||||
Console.WriteLn(Color_StrongBlue, L"isoFile open ok: %s", WX_STR(m_filename));
|
||||
Console.WriteLn(Color_StrongBlue, "isoFile open ok: %s", m_filename.c_str());
|
||||
|
||||
ConsoleIndentScope indent;
|
||||
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "CDVD.h"
|
||||
#include "wx/wfstream.h"
|
||||
#include "AsyncFileReader.h"
|
||||
#include "CompressedFileReader.h"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
enum isoType
|
||||
{
|
||||
@@ -45,7 +45,7 @@ protected:
|
||||
uint ReadUnit;
|
||||
|
||||
protected:
|
||||
wxString m_filename;
|
||||
std::string m_filename;
|
||||
AsyncFileReader* m_reader;
|
||||
|
||||
u32 m_current_lsn;
|
||||
@@ -75,13 +75,13 @@ public:
|
||||
uint GetBlockCount() const { return m_blocks; }
|
||||
int GetBlockOffset() const { return m_blockofs; }
|
||||
|
||||
const wxString& GetFilename() const
|
||||
const std::string& GetFilename() const
|
||||
{
|
||||
return m_filename;
|
||||
}
|
||||
|
||||
bool Test(const wxString& srcfile);
|
||||
bool Open(const wxString& srcfile, bool testOnly = false);
|
||||
bool Test(std::string srcfile);
|
||||
bool Open(std::string srcfile, bool testOnly = false);
|
||||
void Close();
|
||||
bool Detect(bool readType = true);
|
||||
|
||||
@@ -102,7 +102,7 @@ class OutputIsoFile
|
||||
DeclareNoncopyableObject(OutputIsoFile);
|
||||
|
||||
protected:
|
||||
wxString m_filename;
|
||||
std::string m_filename;
|
||||
|
||||
u32 m_version;
|
||||
|
||||
@@ -116,7 +116,7 @@ protected:
|
||||
// dtable is used when reading blockdumps
|
||||
std::vector<u32> m_dtable;
|
||||
|
||||
std::unique_ptr<wxFileOutputStream> m_outstream;
|
||||
std::FILE* m_outstream = nullptr;
|
||||
|
||||
public:
|
||||
OutputIsoFile();
|
||||
@@ -125,12 +125,12 @@ public:
|
||||
bool IsOpened() const;
|
||||
u32 GetBlockSize() const;
|
||||
|
||||
const wxString& GetFilename() const
|
||||
const std::string& GetFilename() const
|
||||
{
|
||||
return m_filename;
|
||||
}
|
||||
|
||||
void Create(const wxString& filename, int mode);
|
||||
void Create(std::string filename, int mode);
|
||||
void Close();
|
||||
|
||||
void WriteHeader(int blockofs, uint blocksize, uint blocks);
|
||||
|
||||
@@ -17,15 +17,17 @@
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "IopCommon.h"
|
||||
#include "IsoFileFormats.h"
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
void pxStream_OpenCheck(const wxStreamBase& stream, const wxString& fname, const wxString& mode)
|
||||
void pxStream_OpenCheck(std::FILE* stream, const std::string& fname, const wxString& mode)
|
||||
{
|
||||
if (stream.IsOk())
|
||||
if (stream)
|
||||
return;
|
||||
|
||||
ScopedExcept ex(Exception::FromErrno(fname, errno));
|
||||
ScopedExcept ex(Exception::FromErrno(StringUtil::UTF8StringToWxString(fname), errno));
|
||||
ex->SetDiagMsg(pxsFmt(L"Unable to open the file for %s: %s", WX_STR(mode), WX_STR(ex->DiagMsg())));
|
||||
ex->Rethrow();
|
||||
}
|
||||
@@ -50,20 +52,20 @@ void OutputIsoFile::_init()
|
||||
m_blocks = 0;
|
||||
}
|
||||
|
||||
void OutputIsoFile::Create(const wxString& filename, int version)
|
||||
void OutputIsoFile::Create(std::string filename, int version)
|
||||
{
|
||||
Close();
|
||||
m_filename = filename;
|
||||
m_filename = std::move(filename);
|
||||
|
||||
m_version = version;
|
||||
m_offset = 0;
|
||||
m_blockofs = 24;
|
||||
m_blocksize = 2048;
|
||||
|
||||
m_outstream = std::make_unique<wxFileOutputStream>(m_filename);
|
||||
pxStream_OpenCheck(*m_outstream, m_filename, L"writing");
|
||||
m_outstream = FileSystem::OpenCFile(m_filename.c_str(), "wb");
|
||||
pxStream_OpenCheck(m_outstream, m_filename, L"writing");
|
||||
|
||||
Console.WriteLn("isoFile create ok: %s ", WX_STR(m_filename));
|
||||
Console.WriteLn("isoFile create ok: %s ", m_filename.c_str());
|
||||
}
|
||||
|
||||
// Generates format header information for blockdumps.
|
||||
@@ -100,9 +102,8 @@ void OutputIsoFile::WriteSector(const u8* src, uint lsn)
|
||||
}
|
||||
else
|
||||
{
|
||||
wxFileOffset ofs = (wxFileOffset)lsn * m_blocksize + m_offset;
|
||||
|
||||
m_outstream->SeekO(ofs);
|
||||
const s64 ofs = (s64)lsn * m_blocksize + m_offset;
|
||||
FileSystem::FSeek64(m_outstream, ofs, SEEK_SET);
|
||||
}
|
||||
|
||||
WriteBuffer(src + m_blockofs, m_blocksize);
|
||||
@@ -112,19 +113,27 @@ void OutputIsoFile::Close()
|
||||
{
|
||||
m_dtable.clear();
|
||||
|
||||
if (m_outstream)
|
||||
{
|
||||
std::fclose(m_outstream);
|
||||
m_outstream = nullptr;
|
||||
}
|
||||
|
||||
_init();
|
||||
}
|
||||
|
||||
void OutputIsoFile::WriteBuffer(const void* src, size_t size)
|
||||
{
|
||||
m_outstream->Write(src, size);
|
||||
if (m_outstream->GetLastError() == wxSTREAM_WRITE_ERROR)
|
||||
if (std::fwrite(src, size, 1, m_outstream) != 1)
|
||||
{
|
||||
int err = errno;
|
||||
if (!err)
|
||||
throw Exception::BadStream(m_filename).SetDiagMsg(pxsFmt(L"An error occurred while writing %u bytes to file", size));
|
||||
{
|
||||
throw Exception::BadStream(StringUtil::UTF8StringToWxString(m_filename))
|
||||
.SetDiagMsg(pxsFmt(L"An error occurred while writing %u bytes to file", size));
|
||||
}
|
||||
|
||||
ScopedExcept ex(Exception::FromErrno(m_filename, err));
|
||||
ScopedExcept ex(Exception::FromErrno(StringUtil::UTF8StringToWxString(m_filename), err));
|
||||
ex->SetDiagMsg(pxsFmt(L"An error occurred while writing %u bytes to file: %s", size, WX_STR(ex->DiagMsg())));
|
||||
ex->Rethrow();
|
||||
}
|
||||
@@ -132,7 +141,7 @@ void OutputIsoFile::WriteBuffer(const void* src, size_t size)
|
||||
|
||||
bool OutputIsoFile::IsOpened() const
|
||||
{
|
||||
return m_outstream && m_outstream->IsOk();
|
||||
return m_outstream != nullptr;
|
||||
}
|
||||
|
||||
u32 OutputIsoFile::GetBlockSize() const
|
||||
|
||||
@@ -239,10 +239,10 @@ bool ThreadedFileReader::TryCachedRead(void*& buffer, u64& offset, u32& size, co
|
||||
return allDone;
|
||||
}
|
||||
|
||||
bool ThreadedFileReader::Open(const wxString& fileName)
|
||||
bool ThreadedFileReader::Open(std::string fileName)
|
||||
{
|
||||
CancelAndWaitUntilStopped();
|
||||
return Open2(fileName);
|
||||
return Open2(std::move(fileName));
|
||||
}
|
||||
|
||||
int ThreadedFileReader::ReadSync(void* pBuffer, uint sector, uint count)
|
||||
|
||||
@@ -47,7 +47,7 @@ protected:
|
||||
/// Synchronously read the given block into `dst`
|
||||
virtual int ReadChunk(void* dst, s64 chunkID) = 0;
|
||||
/// AsyncFileReader open but ThreadedFileReader needs prep work first
|
||||
virtual bool Open2(const wxString& fileName) = 0;
|
||||
virtual bool Open2(std::string fileName) = 0;
|
||||
/// AsyncFileReader close but ThreadedFileReader needs prep work first
|
||||
virtual void Close2(void) = 0;
|
||||
|
||||
@@ -109,7 +109,7 @@ private:
|
||||
bool TryCachedRead(void*& buffer, u64& offset, u32& size, const std::lock_guard<std::mutex>&);
|
||||
|
||||
public:
|
||||
bool Open(const wxString& fileName) final override;
|
||||
bool Open(std::string fileName) final override;
|
||||
int ReadSync(void* pBuffer, uint sector, uint count) final override;
|
||||
void BeginRead(void* pBuffer, uint sector, uint count) final override;
|
||||
int FinishRead(void) final override;
|
||||
|
||||
+15
-15
@@ -107,7 +107,7 @@ Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
|
||||
#include <zlib/zlib.h>
|
||||
#endif
|
||||
|
||||
#include "CompressedFileReaderUtils.h"
|
||||
#include "common/FileSystem.h"
|
||||
|
||||
#define local static
|
||||
|
||||
@@ -122,8 +122,8 @@ Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
|
||||
/* access point entry */
|
||||
struct point
|
||||
{
|
||||
PX_off_t out; /* corresponding offset in uncompressed data */
|
||||
PX_off_t in; /* offset in input file of first full byte */
|
||||
s64 out; /* corresponding offset in uncompressed data */
|
||||
s64 in; /* offset in input file of first full byte */
|
||||
int bits; /* number of bits (1-7) from byte at in - 1, or 0 */
|
||||
unsigned char window[WINSIZE]; /* preceding 32K of uncompressed data */
|
||||
}
|
||||
@@ -142,7 +142,7 @@ struct access
|
||||
struct point* list; /* allocated list */
|
||||
|
||||
s32 span; /* once the index is built, holds the span size used to build it */
|
||||
PX_off_t uncompressed_size; /* filled by build_index */
|
||||
s64 uncompressed_size; /* filled by build_index */
|
||||
}
|
||||
#ifndef _WIN32
|
||||
__attribute__((packed))
|
||||
@@ -168,7 +168,7 @@ local void free_index(struct access* index)
|
||||
/* Add an entry to the access point list. If out of memory, deallocate the
|
||||
existing list and return NULL. */
|
||||
local struct access* addpoint(struct access* index, int bits,
|
||||
PX_off_t in, PX_off_t out, unsigned left, unsigned char* window)
|
||||
s64 in, s64 out, unsigned left, unsigned char* window)
|
||||
{
|
||||
struct point* next;
|
||||
|
||||
@@ -224,11 +224,11 @@ local struct access* addpoint(struct access* index, int bits,
|
||||
returns the number of access points on success (>= 1), Z_MEM_ERROR for out
|
||||
of memory, Z_DATA_ERROR for an error in the input file, or Z_ERRNO for a
|
||||
file read error. On success, *built points to the resulting index. */
|
||||
local int build_index(FILE* in, PX_off_t span, struct access** built)
|
||||
local int build_index(FILE* in, s64 span, struct access** built)
|
||||
{
|
||||
int ret;
|
||||
PX_off_t totin, totout, totPrinted; /* our own total counters to avoid 4GB limit */
|
||||
PX_off_t last; /* totout value of last access point */
|
||||
s64 totin, totout, totPrinted; /* our own total counters to avoid 4GB limit */
|
||||
s64 last; /* totout value of last access point */
|
||||
struct access* index; /* access points being generated */
|
||||
z_stream strm;
|
||||
unsigned char input[CHUNK];
|
||||
@@ -344,13 +344,13 @@ build_index_error:
|
||||
|
||||
typedef struct zstate
|
||||
{
|
||||
PX_off_t out_offset;
|
||||
PX_off_t in_offset;
|
||||
s64 out_offset;
|
||||
s64 in_offset;
|
||||
z_stream strm;
|
||||
int isValid;
|
||||
} Zstate;
|
||||
|
||||
static inline PX_off_t getInOffset(zstate* state)
|
||||
static inline s64 getInOffset(zstate* state)
|
||||
{
|
||||
return state->in_offset;
|
||||
}
|
||||
@@ -362,7 +362,7 @@ static inline PX_off_t getInOffset(zstate* state)
|
||||
should not return a data error unless the file was modified since the index
|
||||
was generated. extract() may also return Z_ERRNO if there is an error on
|
||||
reading or seeking the input file. */
|
||||
local int extract(FILE* in, struct access* index, PX_off_t offset,
|
||||
local int extract(FILE* in, struct access* index, s64 offset,
|
||||
unsigned char* buf, int len, zstate* state)
|
||||
{
|
||||
int ret, skip;
|
||||
@@ -386,7 +386,7 @@ local int extract(FILE* in, struct access* index, PX_off_t offset,
|
||||
if (state->isValid)
|
||||
{
|
||||
state->isValid = 0; // we took control over strm. revalidate when/if we give it back
|
||||
PX_fseeko(in, state->in_offset, SEEK_SET);
|
||||
FileSystem::FSeek64(in, state->in_offset, SEEK_SET);
|
||||
state->strm.avail_in = 0;
|
||||
offset = 0;
|
||||
skip = 1;
|
||||
@@ -408,7 +408,7 @@ local int extract(FILE* in, struct access* index, PX_off_t offset,
|
||||
ret = inflateInit2(&state->strm, -15); /* raw inflate */
|
||||
if (ret != Z_OK)
|
||||
return ret;
|
||||
ret = PX_fseeko(in, here->in - (here->bits ? 1 : 0), SEEK_SET);
|
||||
ret = FileSystem::FSeek64(in, here->in - (here->bits ? 1 : 0), SEEK_SET);
|
||||
if (ret == -1)
|
||||
goto extract_ret;
|
||||
if (here->bits)
|
||||
@@ -456,7 +456,7 @@ local int extract(FILE* in, struct access* index, PX_off_t offset,
|
||||
{
|
||||
if (state->strm.avail_in == 0)
|
||||
{
|
||||
state->in_offset = PX_ftello(in);
|
||||
state->in_offset = FileSystem::FTell64(in);
|
||||
state->strm.avail_in = fread(input, 1, CHUNK, in);
|
||||
if (ferror(in))
|
||||
{
|
||||
|
||||
+36
-74
@@ -70,10 +70,6 @@ if(TARGET SDL::SDL)
|
||||
target_link_libraries(PCSX2_FLAGS INTERFACE SDL::SDL)
|
||||
endif()
|
||||
|
||||
if(WAYLAND_CLIENT_FOUND)
|
||||
target_compile_definitions(PCSX2 PRIVATE WAYLAND_BUILD)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
# Resources
|
||||
target_sources(PCSX2 PRIVATE
|
||||
@@ -130,7 +126,7 @@ set(pcsx2Sources
|
||||
IopIrq.cpp
|
||||
IopMem.cpp
|
||||
IopSio2.cpp
|
||||
IPC.cpp
|
||||
PINE.cpp
|
||||
Mdec.cpp
|
||||
Memory.cpp
|
||||
MemoryCardFile.cpp
|
||||
@@ -139,10 +135,10 @@ set(pcsx2Sources
|
||||
MTGS.cpp
|
||||
MTVU.cpp
|
||||
MultipartFileReader.cpp
|
||||
OutputIsoFile.cpp
|
||||
Patch.cpp
|
||||
Patch_Memory.cpp
|
||||
Pcsx2Config.cpp
|
||||
PerformanceMetrics.cpp
|
||||
PrecompiledHeader.cpp
|
||||
R3000A.cpp
|
||||
R3000AInterpreter.cpp
|
||||
@@ -195,6 +191,7 @@ set(pcsx2Headers
|
||||
Gif_Unit.h
|
||||
GS.h
|
||||
Hardware.h
|
||||
Host.h
|
||||
Hw.h
|
||||
IopBios.h
|
||||
IopCommon.h
|
||||
@@ -204,7 +201,7 @@ set(pcsx2Headers
|
||||
IopHw.h
|
||||
IopMem.h
|
||||
IopSio2.h
|
||||
IPC.h
|
||||
PINE.h
|
||||
Mdec.h
|
||||
MTVU.h
|
||||
Memory.h
|
||||
@@ -214,6 +211,7 @@ set(pcsx2Headers
|
||||
Patch.h
|
||||
PathDefs.h
|
||||
PCSX2Base.h
|
||||
PerformanceMetrics.h
|
||||
PrecompiledHeader.h
|
||||
R3000A.h
|
||||
R5900Exceptions.h
|
||||
@@ -268,7 +266,6 @@ set(pcsx2CDVDHeaders
|
||||
CDVD/CDVDisoReader.h
|
||||
CDVD/ChunksCache.h
|
||||
CDVD/CompressedFileReader.h
|
||||
CDVD/CompressedFileReaderUtils.h
|
||||
CDVD/ChdFileReader.h
|
||||
CDVD/CsoFileReader.h
|
||||
CDVD/GzippedFileReader.h
|
||||
@@ -531,18 +528,6 @@ else(WIN32)
|
||||
COMMAND ${BIN2CPP} "${PADImg}/${result_file}.png" "${PADImgHeader}/${result_file}" )
|
||||
endforeach()
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_BINARY_DIR}/pcsx2/PAD/Linux/resources_pad.h
|
||||
COMMAND glib-compile-resources --sourcedir "${CMAKE_SOURCE_DIR}/pcsx2/PAD/Linux/res" --generate-header
|
||||
--c-name PAD_res "${CMAKE_SOURCE_DIR}/pcsx2/PAD/Linux/res/PAD-res.xml" --target=${CMAKE_BINARY_DIR}/pcsx2/PAD/Linux/resources_pad.h
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/pcsx2/PAD/Linux/res/PAD-res.xml ${CMAKE_SOURCE_DIR}/pcsx2/PAD/Linux/res/game_controller_db.txt)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_BINARY_DIR}/pcsx2/PAD/Linux/resources_pad.cpp
|
||||
COMMAND glib-compile-resources --sourcedir "${CMAKE_SOURCE_DIR}/pcsx2/PAD/Linux/res" --generate-source
|
||||
--c-name PAD_res "${CMAKE_SOURCE_DIR}/pcsx2/PAD/Linux/res/PAD-res.xml" --target=${CMAKE_BINARY_DIR}/pcsx2/PAD/Linux/resources_pad.cpp
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/pcsx2/PAD/Linux/res/PAD-res.xml ${CMAKE_SOURCE_DIR}/pcsx2/PAD/Linux/res/game_controller_db.txt)
|
||||
|
||||
# PAD/Linux sources
|
||||
set(pcsx2PADSources
|
||||
PAD/Linux/Device.cpp
|
||||
@@ -557,7 +542,6 @@ else(WIN32)
|
||||
PAD/Linux/wx_dialog/GamepadConfiguration.cpp
|
||||
PAD/Linux/wx_dialog/JoystickConfiguration.cpp
|
||||
PAD/Linux/Config.cpp
|
||||
${CMAKE_BINARY_DIR}/pcsx2/PAD/Linux/resources_pad.cpp
|
||||
)
|
||||
|
||||
# PAD/Linux headers
|
||||
@@ -575,7 +559,6 @@ else(WIN32)
|
||||
PAD/Linux/wx_dialog/opPanel.h
|
||||
PAD/Linux/wx_dialog/GamepadConfiguration.h
|
||||
PAD/Linux/wx_dialog/JoystickConfiguration.h
|
||||
${CMAKE_BINARY_DIR}/pcsx2/PAD/Linux/resources_pad.h
|
||||
# images
|
||||
${PADImgHeader}/analog.h
|
||||
${PADImgHeader}/circle.h
|
||||
@@ -618,6 +601,7 @@ set(pcsx2GSSources
|
||||
GS/GSLzma.cpp
|
||||
GS/GSPerfMon.cpp
|
||||
GS/GSPng.cpp
|
||||
GS/GSRingHeap.cpp
|
||||
GS/GSState.cpp
|
||||
GS/GSTables.cpp
|
||||
GS/GSUtil.cpp
|
||||
@@ -650,7 +634,6 @@ set(pcsx2GSSources
|
||||
GS/Renderers/OpenGL/GSDeviceOGL.cpp
|
||||
GS/Renderers/OpenGL/GSRendererOGL.cpp
|
||||
GS/Renderers/OpenGL/GSShaderOGL.cpp
|
||||
GS/Renderers/OpenGL/GSTextureCacheOGL.cpp
|
||||
GS/Renderers/OpenGL/GSTextureOGL.cpp
|
||||
GS/Window/GSSetting.cpp
|
||||
GS/Window/GSwxDialog.cpp
|
||||
@@ -677,6 +660,7 @@ set(pcsx2GSHeaders
|
||||
GS/GSLzma.h
|
||||
GS/GSPerfMon.h
|
||||
GS/GSPng.h
|
||||
GS/GSRingHeap.h
|
||||
GS/GSState.h
|
||||
GS/GSTables.h
|
||||
GS/GSThread_CXX11.h
|
||||
@@ -720,7 +704,6 @@ set(pcsx2GSHeaders
|
||||
GS/Renderers/OpenGL/GSDeviceOGL.h
|
||||
GS/Renderers/OpenGL/GSRendererOGL.h
|
||||
GS/Renderers/OpenGL/GSShaderOGL.h
|
||||
GS/Renderers/OpenGL/GSTextureCacheOGL.h
|
||||
GS/Renderers/OpenGL/GSTextureOGL.h
|
||||
GS/Renderers/OpenGL/GSUniformBufferOGL.h
|
||||
GS/Window/GSCaptureDlg.h
|
||||
@@ -795,7 +778,6 @@ if(WIN32)
|
||||
GS/Renderers/DX11/GSDevice11.cpp
|
||||
GS/Renderers/DX11/GSRendererDX11.cpp
|
||||
GS/Renderers/DX11/GSTexture11.cpp
|
||||
GS/Renderers/DX11/GSTextureCache11.cpp
|
||||
GS/Renderers/DX11/GSTextureFX11.cpp
|
||||
GS/Window/GSCaptureDlg.cpp
|
||||
GS/Window/GSDialog.cpp
|
||||
@@ -805,7 +787,6 @@ if(WIN32)
|
||||
GS/Renderers/DX11/GSDevice11.h
|
||||
GS/Renderers/DX11/GSRendererDX11.h
|
||||
GS/Renderers/DX11/GSTexture11.h
|
||||
GS/Renderers/DX11/GSTextureCache11.h
|
||||
)
|
||||
else(WIN32)
|
||||
list(APPEND pcsx2SPU2Sources
|
||||
@@ -860,42 +841,6 @@ else(WIN32)
|
||||
USB/usb-pad/evdev/evdev.h
|
||||
USB/usb-pad/evdev/shared.h
|
||||
)
|
||||
|
||||
|
||||
# GS resources
|
||||
set(pcsx2GSResources
|
||||
GS/res/fxaa.fx
|
||||
GS/res/glsl/common_header.glsl
|
||||
GS/res/glsl/convert.glsl
|
||||
GS/res/glsl/interlace.glsl
|
||||
GS/res/glsl/merge.glsl
|
||||
GS/res/glsl/shadeboost.glsl
|
||||
GS/res/glsl/tfx_fs.glsl
|
||||
GS/res/glsl/tfx_vgs.glsl)
|
||||
|
||||
set(GSBin "${CMAKE_BINARY_DIR}/pcsx2/GS")
|
||||
target_include_directories(PCSX2_FLAGS INTERFACE "${GSBin}")
|
||||
file(MAKE_DIRECTORY "${GSBin}")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_BINARY_DIR}/pcsx2/GS/GS_res.h
|
||||
COMMAND glib-compile-resources --sourcedir "${CMAKE_SOURCE_DIR}/pcsx2/GS/res" --generate-header
|
||||
--c-name GS_res "${CMAKE_SOURCE_DIR}/pcsx2/GS/res/GS-res.xml" --target=${CMAKE_BINARY_DIR}/pcsx2/GS/GS_res.h
|
||||
DEPENDS ${pcsx2GSResources})
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_BINARY_DIR}/pcsx2/GS/GS_res.cpp
|
||||
COMMAND glib-compile-resources --sourcedir "${CMAKE_SOURCE_DIR}/pcsx2/GS/res" --generate-source
|
||||
--c-name GS_res "${CMAKE_SOURCE_DIR}/pcsx2/GS/res/GS-res.xml" --target=${CMAKE_BINARY_DIR}/pcsx2/GS/GS_res.cpp
|
||||
DEPENDS ${pcsx2GSResources})
|
||||
|
||||
list(APPEND pcsx2GSSources
|
||||
GS/GS_res.cpp
|
||||
)
|
||||
|
||||
list(APPEND pcsx2GSHeaders
|
||||
GS/GS_res.h
|
||||
)
|
||||
endif(WIN32)
|
||||
|
||||
|
||||
@@ -939,14 +884,13 @@ set(pcsx2GuiSources
|
||||
gui/AppConfig.cpp
|
||||
gui/AppCoreThread.cpp
|
||||
gui/AppEventSources.cpp
|
||||
gui/AppGameDatabase.cpp
|
||||
gui/AppHost.cpp
|
||||
gui/AppUserMode.cpp
|
||||
gui/AppInit.cpp
|
||||
gui/AppMain.cpp
|
||||
gui/AppRes.cpp
|
||||
gui/CheckedStaticBox.cpp
|
||||
gui/ConsoleLogger.cpp
|
||||
gui/CpuUsageProvider.cpp
|
||||
gui/Dialogs/AboutBoxDialog.cpp
|
||||
gui/Dialogs/GSDumpDialog.cpp
|
||||
gui/Dialogs/AssertionDialog.cpp
|
||||
@@ -960,7 +904,7 @@ set(pcsx2GuiSources
|
||||
gui/Dialogs/McdConfigDialog.cpp
|
||||
gui/Dialogs/PickUserModeDialog.cpp
|
||||
gui/Dialogs/SysConfigDialog.cpp
|
||||
gui/Dialogs/IPCDialog.cpp
|
||||
gui/Dialogs/PINEDialog.cpp
|
||||
gui/Debugger/BreakpointWindow.cpp
|
||||
gui/Debugger/CtrlDisassemblyView.cpp
|
||||
gui/Debugger/CtrlRegisterList.cpp
|
||||
@@ -1015,13 +959,11 @@ set(pcsx2GuiHeaders
|
||||
gui/AppCoreThread.h
|
||||
gui/AppEventListeners.h
|
||||
gui/AppForwardDefs.h
|
||||
gui/AppGameDatabase.h
|
||||
gui/App.h
|
||||
gui/ApplyState.h
|
||||
gui/AppSaveStates.h
|
||||
gui/CheckedStaticBox.h
|
||||
gui/ConsoleLogger.h
|
||||
gui/CpuUsageProvider.h
|
||||
gui/Debugger/BreakpointWindow.h
|
||||
gui/Debugger/CtrlDisassemblyView.h
|
||||
gui/Debugger/CtrlMemView.h
|
||||
@@ -1398,7 +1340,7 @@ if(UNIX AND NOT APPLE)
|
||||
endif()
|
||||
if(WAYLAND_API)
|
||||
target_link_libraries(PCSX2_FLAGS INTERFACE
|
||||
${WAYLAND_CLIENT_LIBRARIES}
|
||||
Wayland::Client
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
@@ -1468,7 +1410,6 @@ if(WIN32)
|
||||
)
|
||||
elseif(APPLE)
|
||||
target_link_libraries(PCSX2_FLAGS INTERFACE
|
||||
PkgConfig::GIO
|
||||
PCAP::PCAP
|
||||
LibXml2::LibXml2
|
||||
)
|
||||
@@ -1523,6 +1464,31 @@ if(COMMAND target_precompile_headers)
|
||||
target_precompile_headers(PCSX2_FLAGS INTERFACE PrecompiledHeader.h)
|
||||
endif()
|
||||
|
||||
# Copy resource files if needed
|
||||
function(pcsx2_resource path basedir)
|
||||
get_filename_component(dir ${path} DIRECTORY)
|
||||
file(RELATIVE_PATH subdir ${basedir} ${dir})
|
||||
if(APPLE)
|
||||
target_sources(PCSX2 PRIVATE ${path})
|
||||
set_source_files_properties(${path} PROPERTIES MACOSX_PACKAGE_LOCATION Resources/${subdir})
|
||||
elseif(PACKAGE_MODE)
|
||||
install(FILES ${path} DESTINATION ${CMAKE_INSTALL_DATADIR}/PCSX2/resources/${subdir})
|
||||
endif()
|
||||
source_group(Resources/${subdir} FILES ${path})
|
||||
endfunction()
|
||||
|
||||
file(GLOB_RECURSE RESOURCE_FILES ${CMAKE_SOURCE_DIR}/bin/resources/*)
|
||||
foreach(path IN LISTS RESOURCE_FILES)
|
||||
get_filename_component(file ${path} NAME)
|
||||
if("${file}" MATCHES "^\\.") # Don't copy macOS garbage (mainly Finder's .DS_Store files) into application
|
||||
continue()
|
||||
endif()
|
||||
if (NOT WIN32 AND "${path}" MATCHES "/dx11/") # Don't include unneccessary stuff
|
||||
continue()
|
||||
endif()
|
||||
pcsx2_resource(${path} ${CMAKE_SOURCE_DIR}/bin/resources/)
|
||||
endforeach()
|
||||
|
||||
if (APPLE)
|
||||
# MacOS defaults to having a maximum protection of the __DATA segment of rw (non-executable)
|
||||
# We have a bunch of page-sized arrays in bss that we use for jit
|
||||
@@ -1535,10 +1501,7 @@ if (APPLE)
|
||||
OUTPUT_NAME PCSX2
|
||||
)
|
||||
|
||||
target_sources(PCSX2 PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/gui/Resources/PCSX2.icns")
|
||||
target_sources(PCSX2 PRIVATE "${CMAKE_SOURCE_DIR}/bin/GameIndex.yaml")
|
||||
set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/gui/Resources/PCSX2.icns" PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||
set_source_files_properties("${CMAKE_SOURCE_DIR}/bin/GameIndex.yaml" PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||
pcsx2_resource(${CMAKE_CURRENT_SOURCE_DIR}/gui/Resources/PCSX2.icns ${CMAKE_CURRENT_SOURCE_DIR}/gui/Resources)
|
||||
|
||||
# If they say to skip postprocess bundle, leave the target in but make it so they have
|
||||
# to manually run it
|
||||
@@ -1583,5 +1546,4 @@ source_group(System/Ps2/USB REGULAR_EXPRESSION USB/*)
|
||||
source_group(Resources/GUI FILES ${pcsx2GuiResources})
|
||||
source_group(Resources/PAD FILES ${pcsx2PADResources})
|
||||
source_group(Resources/Recording FILES ${pcsx2RecordingVirtualPadResources})
|
||||
source_group(Resources FILES ../bin/GameIndex.yaml gui/Resources/PCSX2.icns)
|
||||
source_group(Resources REGULAR_EXPRESSION ${CMAKE_CURRENT_BINARY_DIR}/*)
|
||||
|
||||
+4
-2
@@ -545,7 +545,7 @@ struct Pcsx2Config
|
||||
CdvdShareWrite : 1, // allows the iso to be modified while it's loaded
|
||||
EnablePatches : 1, // enables patch detection and application
|
||||
EnableCheats : 1, // enables cheat detection and application
|
||||
EnableIPC : 1, // enables inter-process communication
|
||||
EnablePINE : 1, // enables inter-process communication
|
||||
EnableWideScreenPatches : 1,
|
||||
#ifndef DISABLE_RECORDING
|
||||
EnableRecordingTools : 1,
|
||||
@@ -598,7 +598,7 @@ struct Pcsx2Config
|
||||
void LoadSaveMemcards(SettingsWrapper& wrap);
|
||||
|
||||
// TODO: Make these std::string when we remove wxFile...
|
||||
wxString FullpathToBios() const;
|
||||
std::string FullpathToBios() const;
|
||||
wxString FullpathToMcd(uint slot) const;
|
||||
|
||||
bool MultitapEnabled(uint port) const;
|
||||
@@ -627,6 +627,8 @@ namespace EmuFolders
|
||||
extern wxDirName Logs;
|
||||
extern wxDirName Cheats;
|
||||
extern wxDirName CheatsWS;
|
||||
extern wxDirName Resources;
|
||||
extern wxDirName Cache;
|
||||
} // namespace EmuFolders
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "GS.h"
|
||||
#include "VUmicro.h"
|
||||
#include "PerformanceMetrics.h"
|
||||
|
||||
#include "ps2/HwInternal.h"
|
||||
#include "Sio.h"
|
||||
@@ -400,6 +401,8 @@ u32 UpdateVSyncRate()
|
||||
cpuRcntSet();
|
||||
}
|
||||
|
||||
PerformanceMetrics::SetVerticalFrequency(vertical_frequency);
|
||||
|
||||
if (m_iTicks != ticks)
|
||||
m_iTicks = ticks;
|
||||
|
||||
|
||||
+21
-7
@@ -45,6 +45,7 @@ char errbuf[PCAP_ERRBUF_SIZE];
|
||||
|
||||
int pcap_io_running = 0;
|
||||
bool pcap_io_switched;
|
||||
bool pcap_io_blocking;
|
||||
|
||||
extern u8 eeprom[];
|
||||
|
||||
@@ -83,7 +84,7 @@ bool PCAPGetWin32Adapter(const char* name, PIP_ADAPTER_ADDRESSES adapter, std::u
|
||||
dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize;
|
||||
DevCon.WriteLn("DEV9: New size %i", neededSize);
|
||||
|
||||
DWORD dwStatus = GetAdaptersAddresses(
|
||||
dwStatus = GetAdaptersAddresses(
|
||||
AF_UNSPEC,
|
||||
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS,
|
||||
NULL,
|
||||
@@ -219,6 +220,14 @@ int pcap_io_init(char* adapter, bool switched, mac_address virtual_mac)
|
||||
}
|
||||
}
|
||||
|
||||
if (pcap_setnonblock(adhandle, 1, errbuf) == -1)
|
||||
{
|
||||
Console.Error("DEV9: Error setting non-blocking: %s", pcap_geterr(adhandle));
|
||||
Console.Error("DEV9: Continuing in blocking mode");
|
||||
pcap_io_blocking = true;
|
||||
}
|
||||
else
|
||||
pcap_io_blocking = false;
|
||||
|
||||
dlt = pcap_datalink(adhandle);
|
||||
dlt_name = (char*)pcap_datalink_val_to_name(dlt);
|
||||
@@ -370,6 +379,12 @@ PCAPAdapter::PCAPAdapter()
|
||||
host_mac = hostMAC;
|
||||
ps2_mac = newMAC; //Needed outside of this class
|
||||
|
||||
if (pcap_io_init(config.Eth, config.EthApi == NetApi::PCAP_Switched, newMAC) == -1)
|
||||
{
|
||||
Console.Error("DEV9: Can't open Device '%s'", config.Eth);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
IP_ADAPTER_ADDRESSES adapter;
|
||||
std::unique_ptr<IP_ADAPTER_ADDRESSES[]> buffer;
|
||||
@@ -394,15 +409,11 @@ PCAPAdapter::PCAPAdapter()
|
||||
InitInternalServer(nullptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pcap_io_init(config.Eth, config.EthApi == NetApi::PCAP_Switched, newMAC) == -1)
|
||||
{
|
||||
Console.Error("Can't open Device '%s'\n", config.Eth);
|
||||
}
|
||||
}
|
||||
bool PCAPAdapter::blocks()
|
||||
{
|
||||
return true;
|
||||
pxAssert(pcap_io_running);
|
||||
return pcap_io_blocking;
|
||||
}
|
||||
bool PCAPAdapter::isInitialised()
|
||||
{
|
||||
@@ -411,6 +422,9 @@ bool PCAPAdapter::isInitialised()
|
||||
//gets a packet.rv :true success
|
||||
bool PCAPAdapter::recv(NetPacket* pkt)
|
||||
{
|
||||
if (!pcap_io_blocking && NetAdapter::recv(pkt))
|
||||
return true;
|
||||
|
||||
int size = pcap_io_recv(pkt->buffer, sizeof(pkt->buffer));
|
||||
if (size > 0 && VerifyPkt(pkt, size))
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "AsyncFileReader.h"
|
||||
#include "common/FileSystem.h"
|
||||
|
||||
// The aio module has been reported to cause issues with FreeBSD 10.3, so let's
|
||||
// disable it for 10.3 and earlier and hope FreeBSD 11 and onwards is fine.
|
||||
@@ -36,11 +37,11 @@ FlatFileReader::~FlatFileReader(void)
|
||||
Close();
|
||||
}
|
||||
|
||||
bool FlatFileReader::Open(const wxString& fileName)
|
||||
bool FlatFileReader::Open(std::string fileName)
|
||||
{
|
||||
m_filename = fileName;
|
||||
m_filename = std::move(fileName);
|
||||
|
||||
m_fd = wxOpen(fileName, O_RDONLY, 0);
|
||||
m_fd = FileSystem::OpenFDFile(m_filename.c_str(), O_RDONLY, 0);
|
||||
|
||||
return (m_fd != -1);
|
||||
}
|
||||
|
||||
+2
-1
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "Common.h"
|
||||
#include "common/FileSystem.h"
|
||||
|
||||
#include "GS.h" // for sending game crc to mtgs
|
||||
#include "Elfheader.h"
|
||||
@@ -152,7 +153,7 @@ void ElfObject::readIso(IsoFile& file)
|
||||
void ElfObject::readFile()
|
||||
{
|
||||
int rsize = 0;
|
||||
FILE *f = wxFopen( filename, "rb" );
|
||||
FILE *f = FileSystem::OpenCFile( filename.ToUTF8(), "rb" );
|
||||
if (f == NULL) throw Exception::FileNotFound( filename );
|
||||
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
+8
-93
@@ -738,7 +738,10 @@ const std::string root_hw("/tmp/GS_HW_dump32/");
|
||||
|
||||
void* vmalloc(size_t size, bool code)
|
||||
{
|
||||
return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, code ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE);
|
||||
void* ptr = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, code ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE);
|
||||
if (!ptr)
|
||||
throw std::bad_alloc();
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void vmfree(void* ptr, size_t size)
|
||||
@@ -845,7 +848,10 @@ void* vmalloc(size_t size, bool code)
|
||||
#endif
|
||||
}
|
||||
|
||||
return mmap(NULL, size, prot, flags, -1, 0);
|
||||
void* ptr = mmap(NULL, size, prot, flags, -1, 0);
|
||||
if (ptr == MAP_FAILED)
|
||||
throw std::bad_alloc();
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void vmfree(void* ptr, size_t size)
|
||||
@@ -906,91 +912,6 @@ void fifo_free(void* ptr, size_t size, size_t repeat)
|
||||
|
||||
#endif
|
||||
|
||||
static void* s_hModule;
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
bool GSApp::LoadResource(int id, std::vector<char>& buff, const wchar_t* type)
|
||||
{
|
||||
buff.clear();
|
||||
HRSRC hRsrc = FindResource((HMODULE)s_hModule, MAKEINTRESOURCE(id), type != NULL ? type : (LPWSTR)RT_RCDATA);
|
||||
if (!hRsrc)
|
||||
return false;
|
||||
HGLOBAL hGlobal = ::LoadResource((HMODULE)s_hModule, hRsrc);
|
||||
if (!hGlobal)
|
||||
return false;
|
||||
DWORD size = SizeofResource((HMODULE)s_hModule, hRsrc);
|
||||
if (!size)
|
||||
return false;
|
||||
// On Linux resources are always NULL terminated
|
||||
// Add + 1 on size to do the same for compatibility sake (required by GSDeviceOGL)
|
||||
buff.resize(size + 1);
|
||||
memcpy(buff.data(), LockResource(hGlobal), size);
|
||||
return true;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include "GS_res.h"
|
||||
|
||||
bool GSApp::LoadResource(int id, std::vector<char>& buff, const char* type)
|
||||
{
|
||||
std::string path;
|
||||
switch (id)
|
||||
{
|
||||
case IDR_COMMON_GLSL:
|
||||
path = "/GS/res/glsl/common_header.glsl";
|
||||
break;
|
||||
case IDR_CONVERT_GLSL:
|
||||
path = "/GS/res/glsl/convert.glsl";
|
||||
break;
|
||||
case IDR_FXAA_FX:
|
||||
path = "/GS/res/fxaa.fx";
|
||||
break;
|
||||
case IDR_INTERLACE_GLSL:
|
||||
path = "/GS/res/glsl/interlace.glsl";
|
||||
break;
|
||||
case IDR_MERGE_GLSL:
|
||||
path = "/GS/res/glsl/merge.glsl";
|
||||
break;
|
||||
case IDR_SHADEBOOST_GLSL:
|
||||
path = "/GS/res/glsl/shadeboost.glsl";
|
||||
break;
|
||||
case IDR_TFX_VGS_GLSL:
|
||||
path = "/GS/res/glsl/tfx_vgs.glsl";
|
||||
break;
|
||||
case IDR_TFX_FS_GLSL:
|
||||
path = "/GS/res/glsl/tfx_fs.glsl";
|
||||
break;
|
||||
case IDR_FONT_ROBOTO:
|
||||
path = "/GS/res/fonts-roboto/Roboto-Regular.ttf";
|
||||
break;
|
||||
default:
|
||||
printf("LoadResource not implemented for id %d\n", id);
|
||||
return false;
|
||||
}
|
||||
|
||||
GBytes* bytes = g_resource_lookup_data(GS_res_get_resource(), path.c_str(), G_RESOURCE_LOOKUP_FLAGS_NONE, nullptr);
|
||||
|
||||
size_t size = 0;
|
||||
const void* data = g_bytes_get_data(bytes, &size);
|
||||
|
||||
if (data == nullptr || size == 0)
|
||||
{
|
||||
printf("Failed to get data for resource: %d\n", id);
|
||||
return false;
|
||||
}
|
||||
|
||||
buff.clear();
|
||||
buff.resize(size + 1);
|
||||
memcpy(buff.data(), data, size + 1);
|
||||
|
||||
g_bytes_unref(bytes);
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t GSApp::GetIniString(const char* lpAppName, const char* lpKeyName, const char* lpDefault, char* lpReturnedString, size_t nSize, const char* lpFileName)
|
||||
{
|
||||
BuildConfigurationMap(lpFileName);
|
||||
@@ -1213,7 +1134,6 @@ void GSApp::Init()
|
||||
m_default_configuration["extrathreads"] = "2";
|
||||
m_default_configuration["extrathreads_height"] = "4";
|
||||
m_default_configuration["filter"] = std::to_string(static_cast<s8>(BiFiltering::PS2));
|
||||
m_default_configuration["force_texture_clear"] = "0";
|
||||
m_default_configuration["fxaa"] = "0";
|
||||
m_default_configuration["interlace"] = "7";
|
||||
m_default_configuration["conservative_framebuffer"] = "1";
|
||||
@@ -1355,11 +1275,6 @@ void GSApp::BuildConfigurationMap(const char* lpFileName)
|
||||
}
|
||||
}
|
||||
|
||||
void* GSApp::GetModuleHandlePtr()
|
||||
{
|
||||
return s_hModule;
|
||||
}
|
||||
|
||||
void GSApp::SetConfigDir()
|
||||
{
|
||||
// we need to initialize the ini folder later at runtime than at theApp init, as
|
||||
|
||||
@@ -149,14 +149,6 @@ public:
|
||||
GSApp();
|
||||
|
||||
void Init();
|
||||
void* GetModuleHandlePtr();
|
||||
|
||||
#ifdef _WIN32
|
||||
HMODULE GetModuleHandle()
|
||||
{
|
||||
return (HMODULE)GetModuleHandlePtr();
|
||||
}
|
||||
#endif
|
||||
|
||||
void BuildConfigurationMap(const char* lpFileName);
|
||||
void ReloadConfig();
|
||||
@@ -165,12 +157,6 @@ public:
|
||||
bool WriteIniString(const char* lpAppName, const char* lpKeyName, const char* pString, const char* lpFileName);
|
||||
int GetIniInt(const char* lpAppName, const char* lpKeyName, int nDefault, const char* lpFileName);
|
||||
|
||||
#ifdef _WIN32
|
||||
bool LoadResource(int id, std::vector<char>& buff, const wchar_t* type = nullptr);
|
||||
#else
|
||||
bool LoadResource(int id, std::vector<char>& buff, const char* type = nullptr);
|
||||
#endif
|
||||
|
||||
void SetConfig(const char* entry, const char* value);
|
||||
void SetConfig(const char* entry, int value);
|
||||
// Avoid issue with overloading
|
||||
|
||||
@@ -44,54 +44,9 @@ BEGIN
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""res/tfx.fx""\r\n"
|
||||
"#include ""res/convert.fx""\r\n"
|
||||
"#include ""res/interlace.fx""\r\n"
|
||||
"#include ""res/merge.fx""\r\n"
|
||||
"#include ""res/fxaa.fx""\r\n"
|
||||
"#include ""res/shadeboost.fx""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// RCDATA
|
||||
//
|
||||
|
||||
IDR_TFX_FX RCDATA "res\\tfx.fx"
|
||||
|
||||
IDR_CONVERT_FX RCDATA "res\\convert.fx"
|
||||
|
||||
IDR_INTERLACE_FX RCDATA "res\\interlace.fx"
|
||||
|
||||
IDR_MERGE_FX RCDATA "res\\merge.fx"
|
||||
|
||||
IDR_FXAA_FX RCDATA "res\\fxaa.fx"
|
||||
|
||||
IDR_SHADEBOOST_FX RCDATA "res\\shadeboost.fx"
|
||||
|
||||
IDR_CONVERT_GLSL RCDATA "res\\glsl\\convert.glsl";
|
||||
|
||||
IDR_INTERLACE_GLSL RCDATA "res\\glsl\\interlace.glsl";
|
||||
|
||||
IDR_MERGE_GLSL RCDATA "res\\glsl\\merge.glsl";
|
||||
|
||||
IDR_SHADEBOOST_GLSL RCDATA "res\\glsl\\shadeboost.glsl";
|
||||
|
||||
IDR_COMMON_GLSL RCDATA "res\\glsl\\common_header.glsl";
|
||||
|
||||
IDR_TFX_VGS_GLSL RCDATA "res\\glsl\\tfx_vgs.glsl";
|
||||
|
||||
IDR_TFX_FS_GLSL RCDATA "res\\glsl\\tfx_fs.glsl";
|
||||
|
||||
IDR_FONT_ROBOTO RCDATA "res\\fonts-roboto\\Roboto-Regular.ttf";
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
@@ -139,18 +94,4 @@ END
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
#include "res/tfx.fx"
|
||||
#include "res/convert.fx"
|
||||
#include "res/interlace.fx"
|
||||
#include "res/merge.fx"
|
||||
#include "res/fxaa.fx"
|
||||
#include "res/shadeboost.fx"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
// clang-format on
|
||||
|
||||
@@ -33,6 +33,17 @@ public:
|
||||
_aligned_free(p);
|
||||
}
|
||||
|
||||
void* operator new(size_t size, void* ptr)
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void operator delete(void* ptr, void* placement_ptr)
|
||||
{
|
||||
// Just here to satisfy compilers
|
||||
// Person who calls in-place placement new must handle error case
|
||||
}
|
||||
|
||||
void* operator new[](size_t size)
|
||||
{
|
||||
return _aligned_malloc(size, i);
|
||||
|
||||
+4
-3
@@ -148,16 +148,17 @@ bool GSClut::WriteTest(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT)
|
||||
__assume(0);
|
||||
}
|
||||
|
||||
return m_write.IsDirty(TEX0, TEXCLUT);
|
||||
// CLUT only reloads if PSM is a valid index type, avoid unnecessary flushes
|
||||
return ((TEX0.PSM & 0x7) >= 3) && m_write.IsDirty(TEX0, TEXCLUT);
|
||||
}
|
||||
|
||||
void GSClut::Write(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT)
|
||||
{
|
||||
m_write.TEX0 = TEX0;
|
||||
m_write.TEXCLUT = TEXCLUT;
|
||||
m_write.dirty = false;
|
||||
m_read.dirty = true;
|
||||
|
||||
m_write.dirty = false;
|
||||
|
||||
(this->*m_wc[TEX0.CSM][TEX0.CPSM][TEX0.PSM])(TEX0, TEXCLUT);
|
||||
}
|
||||
|
||||
|
||||
@@ -1733,7 +1733,7 @@ void GSLocalMemory::SaveBMP(const std::string& fn, u32 bp, u32 bw, u32 psm, int
|
||||
}
|
||||
}
|
||||
|
||||
GSTextureSW t(GSTexture::Offscreen, w, h);
|
||||
GSTextureSW t(GSTexture::Type::Offscreen, w, h);
|
||||
|
||||
if (t.Update(GSVector4i(0, 0, w, h), bits, pitch))
|
||||
{
|
||||
|
||||
@@ -0,0 +1,256 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2021 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 "GSRingHeap.h"
|
||||
#include "GS.h"
|
||||
#include "GSExtra.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
/// Align `value` to `align` bytes
|
||||
template <size_t align>
|
||||
size_t alignTo(size_t value)
|
||||
{
|
||||
return ((value + (align - 1)) / align) * align;
|
||||
}
|
||||
|
||||
/// Align to a power of 2 using a mask that's equal to that value - 1
|
||||
size_t alignUsingMask(size_t align_mask, size_t value)
|
||||
{
|
||||
return (value + align_mask) & ~align_mask;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
/// GSRingHeap operates as a ring buffer, with usage counters for each quadrant
|
||||
/// If a new quadrant needs to be used but is still in use by existing allocations,
|
||||
/// the buffer is orphaned and a replaced with a new, larger buffer
|
||||
struct GSRingHeap::Buffer
|
||||
{
|
||||
friend class GSRingHeap;
|
||||
|
||||
static const size_t BEGINNING_OFFSET;
|
||||
|
||||
static constexpr size_t USAGE_ARR_SIZE = sizeof(uint64_t) / sizeof(size_t);
|
||||
static constexpr size_t USAGE_ARR_ELEMS_PER_ENTRY = sizeof(size_t) / sizeof(uint16_t);
|
||||
|
||||
/// Refcount, main heap holds onto buffer with a +1
|
||||
/// Each allocation adds `sizeof(allocation)`, to allow for detection of buffers being used inefficiently
|
||||
/// (e.g. if a buffer is orphaned with very little usage that means allocations aren't being freed in a similar order to being made)
|
||||
/// Buffer is freed when the main heap drops it (-1) and every allocation is freed, causing this to reach 0
|
||||
std::atomic<size_t> m_amt_allocated;
|
||||
/// Holds 4x 16-bit usage counters, indicating how many allocations have been made from the nth quadrant of memory
|
||||
/// Merged into `size_t` chunks so that they can be operated on with fewer atomic operations
|
||||
std::atomic<size_t> m_usage[USAGE_ARR_SIZE];
|
||||
/// Size of whole buffer (including header)
|
||||
/// Should be kept to at least 2x the largest allocation
|
||||
size_t m_size;
|
||||
/// Offset of new allocations
|
||||
size_t m_write_loc;
|
||||
/// Amount to rshift buffer offset to get which quadrant it's in (`log2(m_size/4)`)
|
||||
int m_quadrant_shift;
|
||||
|
||||
/// Increment usage counts (use when allocating)
|
||||
void beginUse(uint64_t usage)
|
||||
{
|
||||
for (size_t i = 0; i < USAGE_ARR_SIZE; i++)
|
||||
{
|
||||
size_t piece = static_cast<size_t>(usage >> (i * (64 / USAGE_ARR_SIZE)));
|
||||
size_t prev = m_usage[i].fetch_add(piece, std::memory_order_relaxed);
|
||||
for (size_t j = 0; j < USAGE_ARR_ELEMS_PER_ENTRY; j++)
|
||||
{
|
||||
[[maybe_unused]] uint16_t section = prev >> (j * 16);
|
||||
assert(section != UINT16_MAX && "Usage count overflow");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Decrement usage counts (use when freeing)
|
||||
void endUse(uint64_t usage)
|
||||
{
|
||||
for (size_t i = 0; i < USAGE_ARR_SIZE; i++)
|
||||
{
|
||||
size_t piece = static_cast<size_t>(usage >> (i * (64 / USAGE_ARR_SIZE)));
|
||||
m_usage[i].fetch_sub(piece, std::memory_order_release);
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if the given quadrant is still in use
|
||||
bool isStillInUse(uint32_t quadrant)
|
||||
{
|
||||
int arridx = (quadrant / USAGE_ARR_ELEMS_PER_ENTRY) % USAGE_ARR_SIZE;
|
||||
int shift = (quadrant % USAGE_ARR_ELEMS_PER_ENTRY) * 16;
|
||||
return ((m_usage[arridx].load(std::memory_order_acquire) >> shift) & 0xFFFF) != 0;
|
||||
}
|
||||
|
||||
uint32_t quadrant(size_t off)
|
||||
{
|
||||
return static_cast<uint32_t>(off >> m_quadrant_shift);
|
||||
}
|
||||
|
||||
/// Calculate a usage mask from an offset + size
|
||||
uint64_t usageMask(size_t begin_off, size_t size)
|
||||
{
|
||||
// We guarantee size <= two quadrants
|
||||
// Therefore we only need to check beginning, middle, and end
|
||||
uint64_t mask = 0;
|
||||
mask |= 1ull << (quadrant(begin_off) * 16);
|
||||
size_t mid_off = begin_off + size / 2;
|
||||
mask |= 1ull << (quadrant(mid_off) * 16);
|
||||
size_t end_off = begin_off + size - 1;
|
||||
mask |= 1ull << (quadrant(end_off) * 16);
|
||||
return mask;
|
||||
}
|
||||
|
||||
/// Decrement the main amt_allocated refcount
|
||||
void decref(size_t amt)
|
||||
{
|
||||
if (unlikely(m_amt_allocated.fetch_sub(amt, std::memory_order_release) == amt))
|
||||
{
|
||||
std::atomic_thread_fence(std::memory_order_acquire);
|
||||
vmfree(this, m_size);
|
||||
}
|
||||
}
|
||||
|
||||
/// Free an allocation
|
||||
void free(void* allocation, size_t size)
|
||||
{
|
||||
const char* base = reinterpret_cast<const char*>(this);
|
||||
size_t begin_off = static_cast<const char*>(allocation) - base;
|
||||
endUse(usageMask(begin_off, size));
|
||||
decref(size);
|
||||
}
|
||||
|
||||
/// Allocate a value of `size` bytes with `prefix_size` bytes before it (for allocation tracking) and alignment specified by `align_mask`
|
||||
void* alloc(size_t size, size_t align_mask, size_t prefix_size)
|
||||
{
|
||||
uint32_t prev_quadrant = quadrant(m_write_loc - 1);
|
||||
size_t base_off = alignUsingMask(align_mask, m_write_loc + prefix_size);
|
||||
uint64_t usage_mask = 1ull << (quadrant(base_off - prefix_size) * 16);
|
||||
uint32_t new_quadrant = quadrant(base_off + size - 1);
|
||||
if (prev_quadrant != new_quadrant)
|
||||
{
|
||||
uint32_t cur_quadrant = prev_quadrant + 1;
|
||||
if (new_quadrant >= 4)
|
||||
{
|
||||
cur_quadrant = 0;
|
||||
usage_mask = 0;
|
||||
base_off = alignUsingMask(align_mask, BEGINNING_OFFSET + prefix_size);
|
||||
new_quadrant = quadrant(base_off + size - 1);
|
||||
}
|
||||
do
|
||||
{
|
||||
usage_mask |= 1ull << (cur_quadrant * 16);
|
||||
if (unlikely(isStillInUse(cur_quadrant)))
|
||||
return nullptr;
|
||||
} while (++cur_quadrant <= new_quadrant);
|
||||
}
|
||||
|
||||
m_write_loc = base_off + size;
|
||||
beginUse(usage_mask);
|
||||
m_amt_allocated.fetch_add(size + prefix_size, std::memory_order_relaxed);
|
||||
return reinterpret_cast<char*>(this) + base_off - prefix_size;
|
||||
}
|
||||
|
||||
static Buffer* make(int quadrant_shift)
|
||||
{
|
||||
size_t size = 4ull << quadrant_shift;
|
||||
Buffer* buffer = reinterpret_cast<Buffer*>(vmalloc(size, false));
|
||||
buffer->m_size = size;
|
||||
buffer->m_quadrant_shift = quadrant_shift;
|
||||
buffer->m_amt_allocated.store(1, std::memory_order_relaxed);
|
||||
for (std::atomic<size_t>& usage : buffer->m_usage)
|
||||
usage.store(0, std::memory_order_relaxed);
|
||||
buffer->m_write_loc = BEGINNING_OFFSET;
|
||||
return buffer;
|
||||
}
|
||||
};
|
||||
|
||||
const size_t GSRingHeap::Buffer::BEGINNING_OFFSET = alignTo<64>(sizeof(Buffer));
|
||||
constexpr size_t GSRingHeap::MIN_ALIGN;
|
||||
|
||||
GSRingHeap::GSRingHeap()
|
||||
{
|
||||
m_current_buffer = Buffer::make(14); // Start with 64k buffer
|
||||
}
|
||||
|
||||
GSRingHeap::~GSRingHeap() noexcept
|
||||
{
|
||||
orphanBuffer();
|
||||
}
|
||||
|
||||
void GSRingHeap::orphanBuffer() noexcept
|
||||
{
|
||||
m_current_buffer->decref(1);
|
||||
}
|
||||
|
||||
void* GSRingHeap::alloc_internal(size_t size, size_t align_mask, size_t prefix_size)
|
||||
{
|
||||
prefix_size += sizeof(Buffer*); // Add space for a pointer to the buffer
|
||||
size_t total_size = size + prefix_size;
|
||||
|
||||
if (likely(total_size <= (m_current_buffer->m_size / 2)))
|
||||
{
|
||||
if (void* ptr = m_current_buffer->alloc(size, align_mask, prefix_size))
|
||||
{
|
||||
Buffer** bptr = static_cast<Buffer**>(ptr);
|
||||
*bptr = m_current_buffer;
|
||||
return bptr + 1;
|
||||
}
|
||||
else if (IsDevBuild)
|
||||
{
|
||||
size_t total = m_current_buffer->m_size;
|
||||
size_t mb = 1024 * 1024;
|
||||
if (total >= mb)
|
||||
{
|
||||
size_t used = m_current_buffer->m_amt_allocated.load(std::memory_order_relaxed) - 1;
|
||||
if (used * 4 < total)
|
||||
{
|
||||
fprintf(stderr, "GSRingHeap: Orphaning %dmb buffer with low usage of %d%%, check that allocations are actually being deallocated approximately in order\n", total / mb, static_cast<int>((used * 100) / total));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Couldn't allocate, orphan buffer and make a new one
|
||||
int shift = m_current_buffer->m_quadrant_shift;
|
||||
do
|
||||
{
|
||||
shift++;
|
||||
} while (total_size > (2ull << shift));
|
||||
|
||||
if (shift > 24 && total_size <= (2ull << (shift - 1)))
|
||||
{
|
||||
// If this needs to be >64 mb, we're doing something wrong
|
||||
fprintf(stderr, "GSRingHeap: Refusing to grow to %umb\n", 4u << (shift - 20));
|
||||
shift--;
|
||||
}
|
||||
Buffer* new_buffer = Buffer::make(shift);
|
||||
orphanBuffer();
|
||||
m_current_buffer = new_buffer;
|
||||
void* ptr = m_current_buffer->alloc(size, align_mask, prefix_size);
|
||||
assert(ptr && "Fresh buffer failed to allocate!");
|
||||
|
||||
Buffer** bptr = static_cast<Buffer**>(ptr);
|
||||
*bptr = m_current_buffer;
|
||||
return bptr + 1;
|
||||
}
|
||||
|
||||
void GSRingHeap::free_internal(void* ptr, size_t size) noexcept
|
||||
{
|
||||
size += sizeof(Buffer*);
|
||||
Buffer** bptr = static_cast<Buffer**>(ptr) - 1;
|
||||
(*bptr)->free(bptr, size);
|
||||
}
|
||||
@@ -0,0 +1,282 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2021 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 <algorithm>
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
|
||||
/// A ring buffer pretending to be a heap (screams if you don't actually use it like a ring buffer)
|
||||
/// Meant for one producer thread creating data and sharing it with multiple consumer threads
|
||||
/// Expectations:
|
||||
/// - One thread allocates and writes to allocations
|
||||
/// - Other threads read from allocations (once shared, no one writes)
|
||||
/// - Any thread can free
|
||||
/// - Frees are done in approximately the same order as allocations (but not exactly the same order)
|
||||
class GSRingHeap
|
||||
{
|
||||
struct Buffer;
|
||||
Buffer* m_current_buffer;
|
||||
|
||||
void orphanBuffer() noexcept;
|
||||
/// Allocate a value of `size` bytes with `prefix_size` bytes before it (for allocation tracking) and alignment specified by `align_mask`
|
||||
void* alloc_internal(size_t size, size_t align_mask, size_t prefix_size);
|
||||
/// Free a value of size `size` (equal to prefix_size + size when allocated)
|
||||
static void free_internal(void* ptr, size_t size) noexcept;
|
||||
|
||||
static constexpr size_t MIN_ALIGN = std::max(alignof(size_t), alignof(void*));
|
||||
|
||||
static size_t getAlignMask(size_t align)
|
||||
{
|
||||
return std::max(MIN_ALIGN, align) - 1;
|
||||
}
|
||||
|
||||
public:
|
||||
GSRingHeap(GSRingHeap&&) = delete;
|
||||
GSRingHeap();
|
||||
~GSRingHeap() noexcept;
|
||||
|
||||
/// Allocate a piece of memory with the given size and alignment
|
||||
void* alloc(size_t size, size_t align)
|
||||
{
|
||||
size_t alloc_size = size + sizeof(size_t);
|
||||
void* ptr = alloc_internal(size, getAlignMask(align), sizeof(size_t));
|
||||
size_t* header = static_cast<size_t*>(ptr);
|
||||
*header = alloc_size;
|
||||
return static_cast<void*>(header + 1);
|
||||
};
|
||||
|
||||
/// Allocate and initialize a T*
|
||||
template <typename T, typename... Args>
|
||||
T* make(Args&&... args)
|
||||
{
|
||||
std::unique_ptr<void, void(*)(void*)> ptr(alloc(sizeof(T), alignof(T)), GSRingHeap::free);
|
||||
new (ptr.get()) T(std::forward<Args>(args)...);
|
||||
return static_cast<T*>(ptr.release());
|
||||
}
|
||||
|
||||
/// Allocate and default-initialize `count` `T`s
|
||||
template <typename T>
|
||||
T* make_array(size_t count)
|
||||
{
|
||||
std::unique_ptr<void, void(*)(void*)> ptr(alloc(sizeof(T) * count, alignof(T)), GSRingHeap::free);
|
||||
new (ptr.get()) T[count]();
|
||||
return static_cast<T*>(ptr.release());
|
||||
}
|
||||
|
||||
/// Free a pointer allocated with `alloc`
|
||||
static void free(void* ptr)
|
||||
{
|
||||
size_t* header = static_cast<size_t*>(ptr) - 1;
|
||||
free_internal(static_cast<void*>(header), *header);
|
||||
}
|
||||
|
||||
/// Deinitialize and free a pointer created with `make`
|
||||
template <typename T>
|
||||
static void destroy(T* ptr)
|
||||
{
|
||||
ptr->~T();
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
/// Deinitialize and free an array allocated with `make_array`
|
||||
template <typename T>
|
||||
static void destroy_array(T* ptr)
|
||||
{
|
||||
size_t* header = const_cast<size_t*>(reinterpret_cast<const size_t*>(ptr)) - 1;
|
||||
size_t size = (*header - sizeof(size_t)) / sizeof(T);
|
||||
for (size_t i = 0; i < size; i++)
|
||||
ptr[i].~T();
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
/// Like `std::shared_ptr` but holds a pointer on this allocator
|
||||
template <typename T>
|
||||
class SharedPtr
|
||||
{
|
||||
friend class GSRingHeap;
|
||||
|
||||
struct alignas(MIN_ALIGN) AllocationHeader
|
||||
{
|
||||
uint32_t size;
|
||||
std::atomic<uint32_t> refcnt;
|
||||
};
|
||||
|
||||
T* m_ptr;
|
||||
|
||||
SharedPtr(T* ptr)
|
||||
: m_ptr(ptr)
|
||||
{
|
||||
}
|
||||
|
||||
AllocationHeader* getHeader()
|
||||
{
|
||||
return const_cast<AllocationHeader*>(reinterpret_cast<const AllocationHeader*>(m_ptr)) - 1;
|
||||
}
|
||||
|
||||
public:
|
||||
SharedPtr()
|
||||
: m_ptr(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
SharedPtr(std::nullptr_t)
|
||||
: m_ptr(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
SharedPtr(const SharedPtr& other)
|
||||
: m_ptr(other.m_ptr)
|
||||
{
|
||||
if (m_ptr)
|
||||
getHeader()->refcnt.fetch_add(1, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
SharedPtr(SharedPtr&& other)
|
||||
: m_ptr(other.m_ptr)
|
||||
{
|
||||
other.m_ptr = nullptr;
|
||||
}
|
||||
|
||||
SharedPtr& operator=(const SharedPtr& other)
|
||||
{
|
||||
this->~SharedPtr();
|
||||
new (this) SharedPtr(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SharedPtr& operator=(SharedPtr&& other)
|
||||
{
|
||||
this->~SharedPtr();
|
||||
new (this) SharedPtr(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
~SharedPtr()
|
||||
{
|
||||
if (!m_ptr)
|
||||
return;
|
||||
AllocationHeader* header = getHeader();
|
||||
// (See top) Expectation: Once shared, no one writes
|
||||
// Therefore we don't need acquire/release semantics here
|
||||
if (header->refcnt.fetch_sub(1, std::memory_order_relaxed) == 1)
|
||||
{
|
||||
m_ptr->~T();
|
||||
free_internal(static_cast<void*>(header), header->size);
|
||||
}
|
||||
}
|
||||
|
||||
T& operator*() const { return *m_ptr; }
|
||||
T* operator->() const { return m_ptr; }
|
||||
T* get() const { return m_ptr; }
|
||||
|
||||
/// static_cast the pointer to another type
|
||||
template <typename Other>
|
||||
SharedPtr<Other> cast() const&
|
||||
{
|
||||
getHeader().refcount.fetch_add(1, std::memory_order_relaxed);
|
||||
return SharedPtr<Other>(static_cast<Other*>(m_ptr));
|
||||
}
|
||||
|
||||
/// static_cast the pointer to another type
|
||||
template <typename Other>
|
||||
SharedPtr<Other> cast() &&
|
||||
{
|
||||
SharedPtr<Other> other(static_cast<Other*>(m_ptr));
|
||||
m_ptr = nullptr;
|
||||
return other;
|
||||
}
|
||||
};
|
||||
|
||||
/// Make a shared pointer with a different alignment from what the type would normally expect
|
||||
template <typename T, typename... Args>
|
||||
SharedPtr<T> make_shared(Args&&... args)
|
||||
{
|
||||
using Header = typename SharedPtr<T>::AllocationHeader;
|
||||
static constexpr size_t alloc_size = sizeof(T) + sizeof(Header);
|
||||
static_assert(alignof(Header) <= MIN_ALIGN, "Header alignment too high");
|
||||
static_assert(alloc_size <= UINT32_MAX, "Allocation overflow");
|
||||
|
||||
void* ptr = alloc_internal(sizeof(T), getAlignMask(alignof(T)), sizeof(Header));
|
||||
std::unique_ptr<void, void(*)(void*)> guard(ptr, [](void* p){ free_internal(p, alloc_size); });
|
||||
Header* header = static_cast<Header*>(ptr);
|
||||
header->size = static_cast<uint32_t>(alloc_size);
|
||||
header->refcnt.store(1, std::memory_order_relaxed);
|
||||
|
||||
T* tptr = reinterpret_cast<T*>(header + 1);
|
||||
new (tptr) T(std::forward<Args>(args)...);
|
||||
guard.release();
|
||||
return SharedPtr<T>(tptr);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct Deleter
|
||||
{
|
||||
void operator()(T* t)
|
||||
{
|
||||
if (t)
|
||||
destroy(t);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct Deleter<T[]>
|
||||
{
|
||||
void operator()(T* t)
|
||||
{
|
||||
if (t)
|
||||
destroy_array(t);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using UniquePtr = std::unique_ptr<T, Deleter<T>>;
|
||||
|
||||
template <typename T>
|
||||
struct _unique_if
|
||||
{
|
||||
typedef UniquePtr<T> _unique_single;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct _unique_if<T[]>
|
||||
{
|
||||
typedef UniquePtr<T[]> _unique_array_unknown_bound;
|
||||
};
|
||||
|
||||
template <typename T, size_t N>
|
||||
struct _unique_if<T[N]>
|
||||
{
|
||||
typedef void _unique_array_known_bound;
|
||||
};
|
||||
|
||||
template <typename T, typename... Args>
|
||||
typename _unique_if<T>::_unique_single make_unique(Args&&... args)
|
||||
{
|
||||
return UniquePtr<T>(make<T>(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename _unique_if<T>::_unique_array_unknown_bound make_unique(size_t count)
|
||||
{
|
||||
typedef typename std::remove_extent<T>::type Base;
|
||||
return UniquePtr<T>(make_array<Base>(count));
|
||||
}
|
||||
|
||||
template <class T, class... _Args>
|
||||
typename _unique_if<T>::_unique_array_known_bound make_unique(_Args&&...) = delete;
|
||||
};
|
||||
@@ -2546,8 +2546,13 @@ __forceinline void GSState::VertexKick(u32 skip)
|
||||
__assume(0);
|
||||
}
|
||||
|
||||
if (auto_flush && PRIM->TME && (m_context->FRAME.Block() == m_context->TEX0.TBP0))
|
||||
FlushPrim();
|
||||
if (m_context->FRAME.FBMSK != 0xFFFFFFFF)
|
||||
{
|
||||
m_mem.m_clut.Invalidate(m_context->FRAME.Block());
|
||||
|
||||
if (auto_flush && PRIM->TME && (m_context->FRAME.Block() == m_context->TEX0.TBP0))
|
||||
FlushPrim();
|
||||
}
|
||||
}
|
||||
|
||||
void GSState::GetTextureMinMax(GSVector4i& r, const GIFRegTEX0& TEX0, const GIFRegCLAMP& CLAMP, bool linear)
|
||||
|
||||
@@ -18,6 +18,36 @@
|
||||
#include "GS/GSGL.h"
|
||||
#include "GS/GS.h"
|
||||
|
||||
const char* shaderName(ShaderConvert value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case ShaderConvert::COPY: return "ps_copy";
|
||||
case ShaderConvert::RGBA8_TO_16_BITS: return "ps_convert_rgba8_16bits";
|
||||
case ShaderConvert::DATM_1: return "ps_datm1";
|
||||
case ShaderConvert::DATM_0: return "ps_datm0";
|
||||
case ShaderConvert::MOD_256: return "ps_mod256";
|
||||
case ShaderConvert::SCANLINE: return "ps_filter_scanlines";
|
||||
case ShaderConvert::DIAGONAL_FILTER: return "ps_filter_diagonal";
|
||||
case ShaderConvert::TRANSPARENCY_FILTER: return "ps_filter_transparency";
|
||||
case ShaderConvert::TRIANGULAR_FILTER: return "ps_filter_triangular";
|
||||
case ShaderConvert::COMPLEX_FILTER: return "ps_filter_complex";
|
||||
case ShaderConvert::FLOAT32_TO_32_BITS: return "ps_convert_float32_32bits";
|
||||
case ShaderConvert::FLOAT32_TO_RGBA8: return "ps_convert_float32_rgba8";
|
||||
case ShaderConvert::FLOAT16_TO_RGB5A1: return "ps_convert_float16_rgb5a1";
|
||||
case ShaderConvert::RGBA8_TO_FLOAT32: return "ps_convert_rgba8_float32";
|
||||
case ShaderConvert::RGBA8_TO_FLOAT24: return "ps_convert_rgba8_float24";
|
||||
case ShaderConvert::RGBA8_TO_FLOAT16: return "ps_convert_rgba8_float16";
|
||||
case ShaderConvert::RGB5A1_TO_FLOAT16: return "ps_convert_rgb5a1_float16";
|
||||
case ShaderConvert::RGBA_TO_8I: return "ps_convert_rgba_8i";
|
||||
case ShaderConvert::YUV: return "ps_yuv";
|
||||
case ShaderConvert::OSD: return "ps_osd";
|
||||
default:
|
||||
ASSERT(0);
|
||||
return "ShaderConvertUnknownShader";
|
||||
}
|
||||
}
|
||||
|
||||
GSDevice::GSDevice()
|
||||
: m_vsync(false)
|
||||
, m_rbswapped(false)
|
||||
@@ -36,9 +66,7 @@ GSDevice::GSDevice()
|
||||
|
||||
GSDevice::~GSDevice()
|
||||
{
|
||||
for (auto t : m_pool)
|
||||
delete t;
|
||||
|
||||
PurgePool();
|
||||
delete m_backbuffer;
|
||||
delete m_merge;
|
||||
delete m_weavebob;
|
||||
@@ -53,10 +81,7 @@ bool GSDevice::Create(const WindowInfo& wi)
|
||||
|
||||
bool GSDevice::Reset(int w, int h)
|
||||
{
|
||||
for (auto t : m_pool)
|
||||
delete t;
|
||||
|
||||
m_pool.clear();
|
||||
PurgePool();
|
||||
|
||||
delete m_backbuffer;
|
||||
delete m_merge;
|
||||
@@ -64,13 +89,13 @@ bool GSDevice::Reset(int w, int h)
|
||||
delete m_blend;
|
||||
delete m_target_tmp;
|
||||
|
||||
m_backbuffer = NULL;
|
||||
m_merge = NULL;
|
||||
m_weavebob = NULL;
|
||||
m_blend = NULL;
|
||||
m_target_tmp = NULL;
|
||||
m_backbuffer = nullptr;
|
||||
m_merge = nullptr;
|
||||
m_weavebob = nullptr;
|
||||
m_blend = nullptr;
|
||||
m_target_tmp = nullptr;
|
||||
|
||||
m_current = NULL; // current is special, points to other textures, no need to delete
|
||||
m_current = nullptr; // current is special, points to other textures, no need to delete
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -89,9 +114,9 @@ void GSDevice::Present(const GSVector4i& r, int shader)
|
||||
|
||||
if (m_current)
|
||||
{
|
||||
static int s_shader[5] = {ShaderConvert_COPY, ShaderConvert_SCANLINE,
|
||||
ShaderConvert_DIAGONAL_FILTER, ShaderConvert_TRIANGULAR_FILTER,
|
||||
ShaderConvert_COMPLEX_FILTER}; // FIXME
|
||||
static constexpr ShaderConvert s_shader[5] = {ShaderConvert::COPY, ShaderConvert::SCANLINE,
|
||||
ShaderConvert::DIAGONAL_FILTER, ShaderConvert::TRIANGULAR_FILTER,
|
||||
ShaderConvert::COMPLEX_FILTER}; // FIXME
|
||||
|
||||
Present(m_current, m_backbuffer, GSVector4(r), s_shader[shader]);
|
||||
RenderOsd(m_backbuffer);
|
||||
@@ -100,28 +125,53 @@ void GSDevice::Present(const GSVector4i& r, int shader)
|
||||
Flip();
|
||||
}
|
||||
|
||||
void GSDevice::Present(GSTexture* sTex, GSTexture* dTex, const GSVector4& dRect, int shader)
|
||||
void GSDevice::Present(GSTexture* sTex, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader)
|
||||
{
|
||||
StretchRect(sTex, dTex, dRect, shader, m_linear_present);
|
||||
}
|
||||
|
||||
GSTexture* GSDevice::FetchSurface(int type, int w, int h, int format)
|
||||
GSTexture* GSDevice::FetchSurface(GSTexture::Type type, int w, int h, GSTexture::Format format)
|
||||
{
|
||||
const GSVector2i size(w, h);
|
||||
|
||||
GSTexture* t = nullptr;
|
||||
|
||||
for (auto i = m_pool.begin(); i != m_pool.end(); ++i)
|
||||
{
|
||||
GSTexture* t = *i;
|
||||
t = *i;
|
||||
|
||||
assert(t);
|
||||
|
||||
if (t->GetType() == type && t->GetFormat() == format && t->GetSize() == size)
|
||||
{
|
||||
m_pool.erase(i);
|
||||
|
||||
return t;
|
||||
break;
|
||||
}
|
||||
|
||||
t = nullptr;
|
||||
}
|
||||
|
||||
return CreateSurface(type, w, h, format);
|
||||
if (!t)
|
||||
t = CreateSurface(type, w, h, format);
|
||||
|
||||
if (!t)
|
||||
throw std::bad_alloc();
|
||||
|
||||
t->Commit(); // Clear won't be done if the texture isn't committed.
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case GSTexture::Type::RenderTarget:
|
||||
ClearRenderTarget(t, 0);
|
||||
break;
|
||||
case GSTexture::Type::DepthStencil:
|
||||
ClearDepth(t);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
void GSDevice::PrintMemoryUsage()
|
||||
@@ -184,46 +234,67 @@ void GSDevice::AgePool()
|
||||
|
||||
void GSDevice::PurgePool()
|
||||
{
|
||||
// OOM emergency. Let's free this useless pool
|
||||
while (!m_pool.empty())
|
||||
{
|
||||
delete m_pool.back();
|
||||
|
||||
m_pool.pop_back();
|
||||
}
|
||||
for (auto t : m_pool)
|
||||
delete t;
|
||||
m_pool.clear();
|
||||
}
|
||||
|
||||
GSTexture* GSDevice::CreateSparseRenderTarget(int w, int h, int format)
|
||||
GSTexture* GSDevice::CreateSparseRenderTarget(int w, int h, GSTexture::Format format)
|
||||
{
|
||||
return FetchSurface(HasColorSparse() ? GSTexture::SparseRenderTarget : GSTexture::RenderTarget, w, h, format);
|
||||
return FetchSurface(HasColorSparse() ? GSTexture::Type::SparseRenderTarget : GSTexture::Type::RenderTarget, w, h, format);
|
||||
}
|
||||
|
||||
GSTexture* GSDevice::CreateSparseDepthStencil(int w, int h, int format)
|
||||
GSTexture* GSDevice::CreateSparseDepthStencil(int w, int h, GSTexture::Format format)
|
||||
{
|
||||
return FetchSurface(HasDepthSparse() ? GSTexture::SparseDepthStencil : GSTexture::DepthStencil, w, h, format);
|
||||
return FetchSurface(HasDepthSparse() ? GSTexture::Type::SparseDepthStencil : GSTexture::Type::DepthStencil, w, h, format);
|
||||
}
|
||||
|
||||
GSTexture* GSDevice::CreateRenderTarget(int w, int h, int format)
|
||||
GSTexture* GSDevice::CreateRenderTarget(int w, int h, GSTexture::Format format)
|
||||
{
|
||||
return FetchSurface(GSTexture::RenderTarget, w, h, format);
|
||||
return FetchSurface(GSTexture::Type::RenderTarget, w, h, format);
|
||||
}
|
||||
|
||||
GSTexture* GSDevice::CreateDepthStencil(int w, int h, int format)
|
||||
GSTexture* GSDevice::CreateDepthStencil(int w, int h, GSTexture::Format format)
|
||||
{
|
||||
return FetchSurface(GSTexture::DepthStencil, w, h, format);
|
||||
return FetchSurface(GSTexture::Type::DepthStencil, w, h, format);
|
||||
}
|
||||
|
||||
GSTexture* GSDevice::CreateTexture(int w, int h, int format)
|
||||
GSTexture* GSDevice::CreateTexture(int w, int h, GSTexture::Format format)
|
||||
{
|
||||
return FetchSurface(GSTexture::Texture, w, h, format);
|
||||
return FetchSurface(GSTexture::Type::Texture, w, h, format);
|
||||
}
|
||||
|
||||
GSTexture* GSDevice::CreateOffscreen(int w, int h, int format)
|
||||
GSTexture* GSDevice::CreateOffscreen(int w, int h, GSTexture::Format format)
|
||||
{
|
||||
return FetchSurface(GSTexture::Offscreen, w, h, format);
|
||||
return FetchSurface(GSTexture::Type::Offscreen, w, h, format);
|
||||
}
|
||||
|
||||
void GSDevice::StretchRect(GSTexture* sTex, GSTexture* dTex, const GSVector4& dRect, int shader, bool linear)
|
||||
GSTexture::Format GSDevice::GetDefaultTextureFormat(GSTexture::Type type)
|
||||
{
|
||||
if (type == GSTexture::Type::DepthStencil || type == GSTexture::Type::SparseDepthStencil)
|
||||
return GSTexture::Format::DepthStencil;
|
||||
else
|
||||
return GSTexture::Format::Color;
|
||||
}
|
||||
|
||||
bool GSDevice::DownloadTextureConvert(GSTexture* src, const GSVector4& sRect, const GSVector2i& dSize, GSTexture::Format format, ShaderConvert ps_shader, GSTexture::GSMap& out_map, const bool linear)
|
||||
{
|
||||
ASSERT(src);
|
||||
ASSERT(format == GSTexture::Format::Color || format == GSTexture::Format::UInt16 || format == GSTexture::Format::UInt32);
|
||||
|
||||
GSTexture* dst = CreateRenderTarget(dSize.x, dSize.y, format);
|
||||
if (!dst)
|
||||
return false;
|
||||
|
||||
GSVector4i dRect(0, 0, dSize.x, dSize.y);
|
||||
StretchRect(src, sRect, dst, GSVector4(dRect), ps_shader, linear);
|
||||
|
||||
bool ret = DownloadTexture(dst, dRect, out_map);
|
||||
Recycle(dst);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void GSDevice::StretchRect(GSTexture* sTex, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader, bool linear)
|
||||
{
|
||||
StretchRect(sTex, GSVector4(0, 0, 1, 1), dTex, dRect, shader, linear);
|
||||
}
|
||||
@@ -315,7 +386,7 @@ void GSDevice::ExternalFX()
|
||||
const GSVector4 sRect(0, 0, 1, 1);
|
||||
const GSVector4 dRect(0, 0, s.x, s.y);
|
||||
|
||||
StretchRect(m_current, sRect, m_target_tmp, dRect, ShaderConvert_TRANSPARENCY_FILTER, false);
|
||||
StretchRect(m_current, sRect, m_target_tmp, dRect, ShaderConvert::TRANSPARENCY_FILTER, false);
|
||||
DoExternalFX(m_target_tmp, m_current);
|
||||
}
|
||||
}
|
||||
@@ -329,7 +400,7 @@ void GSDevice::FXAA()
|
||||
const GSVector4 sRect(0, 0, 1, 1);
|
||||
const GSVector4 dRect(0, 0, s.x, s.y);
|
||||
|
||||
StretchRect(m_current, sRect, m_target_tmp, dRect, ShaderConvert_TRANSPARENCY_FILTER, false);
|
||||
StretchRect(m_current, sRect, m_target_tmp, dRect, ShaderConvert::TRANSPARENCY_FILTER, false);
|
||||
DoFXAA(m_target_tmp, m_current);
|
||||
}
|
||||
}
|
||||
@@ -343,12 +414,12 @@ void GSDevice::ShadeBoost()
|
||||
const GSVector4 sRect(0, 0, 1, 1);
|
||||
const GSVector4 dRect(0, 0, s.x, s.y);
|
||||
|
||||
StretchRect(m_current, sRect, m_target_tmp, dRect, ShaderConvert_COPY, false);
|
||||
StretchRect(m_current, sRect, m_target_tmp, dRect, ShaderConvert::COPY, false);
|
||||
DoShadeBoost(m_target_tmp, m_current);
|
||||
}
|
||||
}
|
||||
|
||||
bool GSDevice::ResizeTexture(GSTexture** t, int type, int w, int h)
|
||||
bool GSDevice::ResizeTexture(GSTexture** t, GSTexture::Type type, int w, int h)
|
||||
{
|
||||
if (t == NULL)
|
||||
{
|
||||
@@ -360,9 +431,10 @@ bool GSDevice::ResizeTexture(GSTexture** t, int type, int w, int h)
|
||||
|
||||
if (t2 == NULL || t2->GetWidth() != w || t2->GetHeight() != h)
|
||||
{
|
||||
GSTexture::Format fmt = t2 ? t2->GetFormat() : GetDefaultTextureFormat(type);
|
||||
delete t2;
|
||||
|
||||
t2 = FetchSurface(type, w, h, 0);
|
||||
t2 = FetchSurface(type, w, h, fmt);
|
||||
|
||||
*t = t2;
|
||||
}
|
||||
@@ -372,18 +444,18 @@ bool GSDevice::ResizeTexture(GSTexture** t, int type, int w, int h)
|
||||
|
||||
bool GSDevice::ResizeTexture(GSTexture** t, int w, int h)
|
||||
{
|
||||
return ResizeTexture(t, GSTexture::Texture, w, h);
|
||||
return ResizeTexture(t, GSTexture::Type::Texture, w, h);
|
||||
}
|
||||
|
||||
bool GSDevice::ResizeTarget(GSTexture** t, int w, int h)
|
||||
{
|
||||
return ResizeTexture(t, GSTexture::RenderTarget, w, h);
|
||||
return ResizeTexture(t, GSTexture::Type::RenderTarget, w, h);
|
||||
}
|
||||
|
||||
bool GSDevice::ResizeTarget(GSTexture** t)
|
||||
{
|
||||
GSVector2i s = m_current->GetSize();
|
||||
return ResizeTexture(t, GSTexture::RenderTarget, s.x, s.y);
|
||||
return ResizeTexture(t, GSTexture::Type::RenderTarget, s.x, s.y);
|
||||
}
|
||||
|
||||
GSAdapter::operator std::string() const
|
||||
@@ -438,15 +510,15 @@ std::array<HWBlend, 3*3*3*3 + 1> GSDevice::m_blendMap =
|
||||
{ BLEND_NO_REC , OP_ADD , CONST_ONE , CONST_ZERO} , // 0020: (Cs - Cs)*F + Cs ==> Cs
|
||||
{ 0 , OP_ADD , CONST_ZERO , CONST_ONE} , // 0021: (Cs - Cs)*F + Cd ==> Cd
|
||||
{ BLEND_NO_REC , OP_ADD , CONST_ZERO , CONST_ZERO} , // 0022: (Cs - Cs)*F + 0 ==> 0
|
||||
{ BLEND_A_MAX , OP_SUBTRACT , CONST_ONE , SRC1_ALPHA} , //*0100: (Cs - Cd)*As + Cs ==> Cs*(As + 1) - Cd*As
|
||||
{ 0 , OP_ADD , SRC1_ALPHA , INV_SRC1_ALPHA} , // 0101: (Cs - Cd)*As + Cd ==> Cs*As + Cd*(1 - As)
|
||||
{ 0 , OP_SUBTRACT , SRC1_ALPHA , SRC1_ALPHA} , // 0102: (Cs - Cd)*As + 0 ==> Cs*As - Cd*As
|
||||
{ BLEND_A_MAX | BLEND_MIX2 , OP_SUBTRACT , CONST_ONE , SRC1_ALPHA} , //*0100: (Cs - Cd)*As + Cs ==> Cs*(As + 1) - Cd*As
|
||||
{ BLEND_MIX1 , OP_ADD , SRC1_ALPHA , INV_SRC1_ALPHA} , // 0101: (Cs - Cd)*As + Cd ==> Cs*As + Cd*(1 - As)
|
||||
{ BLEND_MIX1 , OP_SUBTRACT , SRC1_ALPHA , SRC1_ALPHA} , // 0102: (Cs - Cd)*As + 0 ==> Cs*As - Cd*As
|
||||
{ BLEND_A_MAX , OP_SUBTRACT , CONST_ONE , DST_ALPHA} , //*0110: (Cs - Cd)*Ad + Cs ==> Cs*(Ad + 1) - Cd*Ad
|
||||
{ 0 , OP_ADD , DST_ALPHA , INV_DST_ALPHA} , // 0111: (Cs - Cd)*Ad + Cd ==> Cs*Ad + Cd*(1 - Ad)
|
||||
{ 0 , OP_SUBTRACT , DST_ALPHA , DST_ALPHA} , // 0112: (Cs - Cd)*Ad + 0 ==> Cs*Ad - Cd*Ad
|
||||
{ BLEND_A_MAX , OP_SUBTRACT , CONST_ONE , CONST_COLOR} , //*0120: (Cs - Cd)*F + Cs ==> Cs*(F + 1) - Cd*F
|
||||
{ 0 , OP_ADD , CONST_COLOR , INV_CONST_COLOR} , // 0121: (Cs - Cd)*F + Cd ==> Cs*F + Cd*(1 - F)
|
||||
{ 0 , OP_SUBTRACT , CONST_COLOR , CONST_COLOR} , // 0122: (Cs - Cd)*F + 0 ==> Cs*F - Cd*F
|
||||
{ BLEND_A_MAX | BLEND_MIX2 , OP_SUBTRACT , CONST_ONE , CONST_COLOR} , //*0120: (Cs - Cd)*F + Cs ==> Cs*(F + 1) - Cd*F
|
||||
{ BLEND_MIX1 , OP_ADD , CONST_COLOR , INV_CONST_COLOR} , // 0121: (Cs - Cd)*F + Cd ==> Cs*F + Cd*(1 - F)
|
||||
{ BLEND_MIX1 , OP_SUBTRACT , CONST_COLOR , CONST_COLOR} , // 0122: (Cs - Cd)*F + 0 ==> Cs*F - Cd*F
|
||||
{ BLEND_NO_REC | BLEND_A_MAX , OP_ADD , CONST_ONE , CONST_ZERO} , //*0200: (Cs - 0)*As + Cs ==> Cs*(As + 1)
|
||||
{ BLEND_ACCU , OP_ADD , SRC1_ALPHA , CONST_ONE} , //?0201: (Cs - 0)*As + Cd ==> Cs*As + Cd
|
||||
{ BLEND_NO_REC , OP_ADD , SRC1_ALPHA , CONST_ZERO} , // 0202: (Cs - 0)*As + 0 ==> Cs*As
|
||||
@@ -456,15 +528,15 @@ std::array<HWBlend, 3*3*3*3 + 1> GSDevice::m_blendMap =
|
||||
{ BLEND_NO_REC | BLEND_A_MAX , OP_ADD , CONST_ONE , CONST_ZERO} , //*0220: (Cs - 0)*F + Cs ==> Cs*(F + 1)
|
||||
{ BLEND_ACCU , OP_ADD , CONST_COLOR , CONST_ONE} , //?0221: (Cs - 0)*F + Cd ==> Cs*F + Cd
|
||||
{ BLEND_NO_REC , OP_ADD , CONST_COLOR , CONST_ZERO} , // 0222: (Cs - 0)*F + 0 ==> Cs*F
|
||||
{ 0 , OP_ADD , INV_SRC1_ALPHA , SRC1_ALPHA} , // 1000: (Cd - Cs)*As + Cs ==> Cd*As + Cs*(1 - As)
|
||||
{ BLEND_A_MAX , OP_REV_SUBTRACT , SRC1_ALPHA , CONST_ONE} , //*1001: (Cd - Cs)*As + Cd ==> Cd*(As + 1) - Cs*As
|
||||
{ 0 , OP_REV_SUBTRACT , SRC1_ALPHA , SRC1_ALPHA} , // 1002: (Cd - Cs)*As + 0 ==> Cd*As - Cs*As
|
||||
{ BLEND_MIX3 , OP_ADD , INV_SRC1_ALPHA , SRC1_ALPHA} , // 1000: (Cd - Cs)*As + Cs ==> Cd*As + Cs*(1 - As)
|
||||
{ BLEND_A_MAX | BLEND_MIX1 , OP_REV_SUBTRACT , SRC1_ALPHA , CONST_ONE} , //*1001: (Cd - Cs)*As + Cd ==> Cd*(As + 1) - Cs*As
|
||||
{ BLEND_MIX1 , OP_REV_SUBTRACT , SRC1_ALPHA , SRC1_ALPHA} , // 1002: (Cd - Cs)*As + 0 ==> Cd*As - Cs*As
|
||||
{ 0 , OP_ADD , INV_DST_ALPHA , DST_ALPHA} , // 1010: (Cd - Cs)*Ad + Cs ==> Cd*Ad + Cs*(1 - Ad)
|
||||
{ BLEND_A_MAX , OP_REV_SUBTRACT , DST_ALPHA , CONST_ONE} , //*1011: (Cd - Cs)*Ad + Cd ==> Cd*(Ad + 1) - Cs*Ad
|
||||
{ 0 , OP_REV_SUBTRACT , DST_ALPHA , DST_ALPHA} , // 1012: (Cd - Cs)*Ad + 0 ==> Cd*Ad - Cs*Ad
|
||||
{ 0 , OP_ADD , INV_CONST_COLOR , CONST_COLOR} , // 1020: (Cd - Cs)*F + Cs ==> Cd*F + Cs*(1 - F)
|
||||
{ BLEND_A_MAX , OP_REV_SUBTRACT , CONST_COLOR , CONST_ONE} , //*1021: (Cd - Cs)*F + Cd ==> Cd*(F + 1) - Cs*F
|
||||
{ 0 , OP_REV_SUBTRACT , CONST_COLOR , CONST_COLOR} , // 1022: (Cd - Cs)*F + 0 ==> Cd*F - Cs*F
|
||||
{ BLEND_MIX3 , OP_ADD , INV_CONST_COLOR , CONST_COLOR} , // 1020: (Cd - Cs)*F + Cs ==> Cd*F + Cs*(1 - F)
|
||||
{ BLEND_A_MAX | BLEND_MIX1 , OP_REV_SUBTRACT , CONST_COLOR , CONST_ONE} , //*1021: (Cd - Cs)*F + Cd ==> Cd*(F + 1) - Cs*F
|
||||
{ BLEND_MIX1 , OP_REV_SUBTRACT , CONST_COLOR , CONST_COLOR} , // 1022: (Cd - Cs)*F + 0 ==> Cd*F - Cs*F
|
||||
{ BLEND_NO_REC , OP_ADD , CONST_ONE , CONST_ZERO} , // 1100: (Cd - Cd)*As + Cs ==> Cs
|
||||
{ 0 , OP_ADD , CONST_ZERO , CONST_ONE} , // 1101: (Cd - Cd)*As + Cd ==> Cd
|
||||
{ BLEND_NO_REC , OP_ADD , CONST_ZERO , CONST_ZERO} , // 1102: (Cd - Cd)*As + 0 ==> 0
|
||||
|
||||
@@ -26,31 +26,35 @@
|
||||
#include <dxgi.h>
|
||||
#endif
|
||||
|
||||
enum ShaderConvert
|
||||
enum class ShaderConvert
|
||||
{
|
||||
ShaderConvert_COPY = 0,
|
||||
ShaderConvert_RGBA8_TO_16_BITS,
|
||||
ShaderConvert_DATM_1,
|
||||
ShaderConvert_DATM_0,
|
||||
ShaderConvert_MOD_256,
|
||||
ShaderConvert_SCANLINE = 5,
|
||||
ShaderConvert_DIAGONAL_FILTER,
|
||||
ShaderConvert_TRANSPARENCY_FILTER,
|
||||
ShaderConvert_TRIANGULAR_FILTER,
|
||||
ShaderConvert_COMPLEX_FILTER,
|
||||
ShaderConvert_FLOAT32_TO_32_BITS = 10,
|
||||
ShaderConvert_FLOAT32_TO_RGBA8,
|
||||
ShaderConvert_FLOAT16_TO_RGB5A1,
|
||||
ShaderConvert_RGBA8_TO_FLOAT32 = 13,
|
||||
ShaderConvert_RGBA8_TO_FLOAT24,
|
||||
ShaderConvert_RGBA8_TO_FLOAT16,
|
||||
ShaderConvert_RGB5A1_TO_FLOAT16,
|
||||
ShaderConvert_RGBA_TO_8I = 17,
|
||||
ShaderConvert_YUV,
|
||||
ShaderConvert_OSD,
|
||||
ShaderConvert_Count
|
||||
COPY = 0,
|
||||
RGBA8_TO_16_BITS,
|
||||
DATM_1,
|
||||
DATM_0,
|
||||
MOD_256,
|
||||
SCANLINE = 5,
|
||||
DIAGONAL_FILTER,
|
||||
TRANSPARENCY_FILTER,
|
||||
TRIANGULAR_FILTER,
|
||||
COMPLEX_FILTER,
|
||||
FLOAT32_TO_32_BITS = 10,
|
||||
FLOAT32_TO_RGBA8,
|
||||
FLOAT16_TO_RGB5A1,
|
||||
RGBA8_TO_FLOAT32 = 13,
|
||||
RGBA8_TO_FLOAT24,
|
||||
RGBA8_TO_FLOAT16,
|
||||
RGB5A1_TO_FLOAT16,
|
||||
RGBA_TO_8I = 17,
|
||||
YUV,
|
||||
OSD,
|
||||
Count
|
||||
};
|
||||
|
||||
/// Get the name of a shader
|
||||
/// (Can't put methods on an enum class)
|
||||
const char* shaderName(ShaderConvert value);
|
||||
|
||||
enum ChannelFetch
|
||||
{
|
||||
ChannelFetch_NONE = 0,
|
||||
@@ -115,6 +119,9 @@ public:
|
||||
enum HWBlendFlags
|
||||
{
|
||||
// A couple of flag to determine the blending behavior
|
||||
BLEND_MIX1 = 0x20, // Mix of hw and sw, do Cs*F or Cs*As in shader
|
||||
BLEND_MIX2 = 0x40, // Mix of hw and sw, do Cs*(As + 1) or Cs*(F + 1) in shader
|
||||
BLEND_MIX3 = 0x80, // Mix of hw and sw, do Cs*(1 - As) or Cs*(1 - F) in shader
|
||||
BLEND_A_MAX = 0x100, // Impossible blending uses coeff bigger than 1
|
||||
BLEND_C_CLR = 0x200, // Clear color blending (use directly the destination color as blending factor)
|
||||
BLEND_NO_REC = 0x400, // Doesn't require sampling of the RT as a texture
|
||||
@@ -168,8 +175,8 @@ protected:
|
||||
unsigned int m_frame; // for ageing the pool
|
||||
bool m_linear_present;
|
||||
|
||||
virtual GSTexture* CreateSurface(int type, int w, int h, int format) = 0;
|
||||
virtual GSTexture* FetchSurface(int type, int w, int h, int format);
|
||||
virtual GSTexture* CreateSurface(GSTexture::Type type, int w, int h, GSTexture::Format format) = 0;
|
||||
virtual GSTexture* FetchSurface(GSTexture::Type type, int w, int h, GSTexture::Format format);
|
||||
|
||||
virtual void DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, const GSVector4& c) = 0;
|
||||
virtual void DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset) = 0;
|
||||
@@ -197,15 +204,12 @@ public:
|
||||
virtual bool Reset(int w, int h);
|
||||
virtual bool IsLost(bool update = false) { return false; }
|
||||
virtual void Present(const GSVector4i& r, int shader);
|
||||
virtual void Present(GSTexture* sTex, GSTexture* dTex, const GSVector4& dRect, int shader = 0);
|
||||
virtual void Present(GSTexture* sTex, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader = ShaderConvert::COPY);
|
||||
virtual void Flip() {}
|
||||
|
||||
virtual void SetVSync(int vsync) { m_vsync = vsync; }
|
||||
|
||||
virtual void BeginScene() {}
|
||||
virtual void DrawPrimitive() {};
|
||||
virtual void DrawIndexedPrimitive() {}
|
||||
virtual void DrawIndexedPrimitive(int offset, int count) {}
|
||||
virtual void EndScene();
|
||||
|
||||
virtual bool HasDepthSparse() { return false; }
|
||||
@@ -216,24 +220,30 @@ public:
|
||||
virtual void ClearDepth(GSTexture* t) {}
|
||||
virtual void ClearStencil(GSTexture* t, u8 c) {}
|
||||
|
||||
GSTexture* CreateSparseRenderTarget(int w, int h, int format = 0);
|
||||
GSTexture* CreateSparseDepthStencil(int w, int h, int format = 0);
|
||||
GSTexture* CreateRenderTarget(int w, int h, int format = 0);
|
||||
GSTexture* CreateDepthStencil(int w, int h, int format = 0);
|
||||
GSTexture* CreateTexture(int w, int h, int format = 0);
|
||||
GSTexture* CreateOffscreen(int w, int h, int format = 0);
|
||||
GSTexture* CreateSparseRenderTarget(int w, int h, GSTexture::Format format);
|
||||
GSTexture* CreateSparseDepthStencil(int w, int h, GSTexture::Format format);
|
||||
GSTexture* CreateRenderTarget(int w, int h, GSTexture::Format format);
|
||||
GSTexture* CreateDepthStencil(int w, int h, GSTexture::Format format);
|
||||
GSTexture* CreateTexture(int w, int h, GSTexture::Format format);
|
||||
GSTexture* CreateOffscreen(int w, int h, GSTexture::Format format);
|
||||
GSTexture::Format GetDefaultTextureFormat(GSTexture::Type type);
|
||||
|
||||
virtual GSTexture* CopyOffscreen(GSTexture* src, const GSVector4& sRect, int w, int h, int format = 0, int ps_shader = 0) { return NULL; }
|
||||
/// Download the region `rect` of `src` into `out_map`
|
||||
/// `out_map` will be valid a call to `DownloadTextureComplete`
|
||||
virtual bool DownloadTexture(GSTexture* src, const GSVector4i& rect, GSTexture::GSMap& out_map) { return false; }
|
||||
|
||||
/// Scale the region `sRect` of `src` to the size `dSize` using `ps_shader` and store the result in `out_map`
|
||||
/// `out_map` will be valid a call to `DownloadTextureComplete`
|
||||
virtual bool DownloadTextureConvert(GSTexture* src, const GSVector4& sRect, const GSVector2i& dSize, GSTexture::Format format, ShaderConvert ps_shader, GSTexture::GSMap& out_map, bool linear);
|
||||
|
||||
/// Must be called to free resources after calling `DownloadTexture` or `DownloadTextureConvert`
|
||||
virtual void DownloadTextureComplete() {}
|
||||
|
||||
virtual void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r) {}
|
||||
virtual void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, int shader = 0, bool linear = true) {}
|
||||
virtual void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader = ShaderConvert::COPY, bool linear = true) {}
|
||||
virtual void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red, bool green, bool blue, bool alpha) {}
|
||||
|
||||
void StretchRect(GSTexture* sTex, GSTexture* dTex, const GSVector4& dRect, int shader = 0, bool linear = true);
|
||||
|
||||
virtual void PSSetShaderResources(GSTexture* sr0, GSTexture* sr1) {}
|
||||
virtual void PSSetShaderResource(int i, GSTexture* sRect) {}
|
||||
virtual void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor = NULL) {}
|
||||
void StretchRect(GSTexture* sTex, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader = ShaderConvert::COPY, bool linear = true);
|
||||
|
||||
GSTexture* GetCurrent();
|
||||
|
||||
@@ -244,7 +254,7 @@ public:
|
||||
void ExternalFX();
|
||||
virtual void RenderOsd(GSTexture* dt) {};
|
||||
|
||||
bool ResizeTexture(GSTexture** t, int type, int w, int h);
|
||||
bool ResizeTexture(GSTexture** t, GSTexture::Type type, int w, int h);
|
||||
bool ResizeTexture(GSTexture** t, int w, int h);
|
||||
bool ResizeTarget(GSTexture** t, int w, int h);
|
||||
bool ResizeTarget(GSTexture** t);
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "GSOsdManager.h"
|
||||
#include "GS/GS.h"
|
||||
#ifdef _WIN32
|
||||
#include "GS/resource.h"
|
||||
#endif
|
||||
#include "Host.h"
|
||||
|
||||
#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 4)
|
||||
#include <codecvt>
|
||||
@@ -31,8 +29,12 @@ void GSOsdManager::LoadFont()
|
||||
if (error)
|
||||
{
|
||||
FT_Error error_load_res = 1;
|
||||
if (theApp.LoadResource(IDR_FONT_ROBOTO, resource_data_buffer))
|
||||
error_load_res = FT_New_Memory_Face(m_library, (const FT_Byte*)resource_data_buffer.data(), resource_data_buffer.size(), 0, &m_face);
|
||||
auto buffer = Host::ReadResourceFile("fonts/Roboto-Regular.ttf");
|
||||
if (buffer.has_value())
|
||||
{
|
||||
resource_data_buffer = std::move(*buffer);
|
||||
error_load_res = FT_New_Memory_Face(m_library, resource_data_buffer.data(), resource_data_buffer.size(), 0, &m_face);
|
||||
}
|
||||
|
||||
if (error_load_res)
|
||||
{
|
||||
|
||||
@@ -94,5 +94,5 @@ public:
|
||||
size_t GeneratePrimitives(GSVertexPT1* dst, size_t count);
|
||||
|
||||
private:
|
||||
std::vector<char> resource_data_buffer;
|
||||
std::vector<u8> resource_data_buffer;
|
||||
};
|
||||
|
||||
@@ -512,18 +512,17 @@ void GSRenderer::VSync(int field)
|
||||
{
|
||||
GSVector2i size = m_capture.GetSize();
|
||||
|
||||
if (GSTexture* offscreen = m_dev->CopyOffscreen(current, GSVector4(0, 0, 1, 1), size.x, size.y))
|
||||
bool res;
|
||||
GSTexture::GSMap m;
|
||||
if (size == current->GetSize())
|
||||
res = m_dev->DownloadTexture(current, GSVector4i(0, 0, size.x, size.y), m);
|
||||
else
|
||||
res = m_dev->DownloadTextureConvert(current, GSVector4(0, 0, 1, 1), size, GSTexture::Format::Color, ShaderConvert::COPY, m, true);
|
||||
|
||||
if (res)
|
||||
{
|
||||
GSTexture::GSMap m;
|
||||
|
||||
if (offscreen->Map(m))
|
||||
{
|
||||
m_capture.DeliverFrame(m.bits, m.pitch, !m_dev->IsRBSwapped());
|
||||
|
||||
offscreen->Unmap();
|
||||
}
|
||||
|
||||
m_dev->Recycle(offscreen);
|
||||
m_capture.DeliverFrame(m.bits, m.pitch, !m_dev->IsRBSwapped());
|
||||
m_dev->DownloadTextureComplete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ public:
|
||||
virtual bool CanUpscale() { return false; }
|
||||
virtual int GetUpscaleMultiplier() { return 1; }
|
||||
virtual GSVector2i GetCustomResolution() { return GSVector2i(0, 0); }
|
||||
virtual GSVector2 GetTextureScaleFactor() { return { 1.0f, 1.0f }; }
|
||||
GSVector2i GetInternalResolution();
|
||||
void SetVSync(int vsync);
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ GSTexture::GSTexture()
|
||||
, m_size(0, 0)
|
||||
, m_committed_size(0, 0)
|
||||
, m_gpu_page_size(0, 0)
|
||||
, m_type(0)
|
||||
, m_format(0)
|
||||
, m_type(Type::Invalid)
|
||||
, m_format(Format::Invalid)
|
||||
, m_sparse(false)
|
||||
, last_frame_used(0)
|
||||
, LikelyOffset(false)
|
||||
|
||||
@@ -19,15 +19,6 @@
|
||||
|
||||
class GSTexture
|
||||
{
|
||||
protected:
|
||||
GSVector2 m_scale;
|
||||
GSVector2i m_size;
|
||||
GSVector2i m_committed_size;
|
||||
GSVector2i m_gpu_page_size;
|
||||
int m_type;
|
||||
int m_format;
|
||||
bool m_sparse;
|
||||
|
||||
public:
|
||||
struct GSMap
|
||||
{
|
||||
@@ -35,17 +26,40 @@ public:
|
||||
int pitch;
|
||||
};
|
||||
|
||||
enum
|
||||
enum class Type
|
||||
{
|
||||
Invalid = 0,
|
||||
RenderTarget = 1,
|
||||
DepthStencil,
|
||||
Texture,
|
||||
Offscreen,
|
||||
Backbuffer,
|
||||
SparseRenderTarget,
|
||||
SparseDepthStencil
|
||||
SparseDepthStencil,
|
||||
};
|
||||
|
||||
enum class Format
|
||||
{
|
||||
Invalid = 0, ///< Used for initialization
|
||||
Backbuffer, ///< For displaying to the screen
|
||||
Color, ///< Standard (RGBA8) color texture
|
||||
FloatColor, ///< Float-based color texture for colclip emulation (RGBA32F)
|
||||
DepthStencil, ///< Depth stencil texture
|
||||
UNorm8, ///< A8UNorm texture for paletted textures and the OSD font
|
||||
UInt16, ///< UInt16 texture for reading back 16-bit depth
|
||||
UInt32, ///< UInt32 texture for reading back 24 and 32-bit depth
|
||||
Int32, ///< Int32 texture for date emulation
|
||||
};
|
||||
|
||||
protected:
|
||||
GSVector2 m_scale;
|
||||
GSVector2i m_size;
|
||||
GSVector2i m_committed_size;
|
||||
GSVector2i m_gpu_page_size;
|
||||
Type m_type;
|
||||
Format m_format;
|
||||
bool m_sparse;
|
||||
|
||||
public:
|
||||
GSTexture();
|
||||
virtual ~GSTexture() {}
|
||||
@@ -70,8 +84,8 @@ public:
|
||||
int GetHeight() const { return m_size.y; }
|
||||
GSVector2i GetSize() const { return m_size; }
|
||||
|
||||
int GetType() const { return m_type; }
|
||||
int GetFormat() const { return m_format; }
|
||||
Type GetType() const { return m_type; }
|
||||
Format GetFormat() const { return m_format; }
|
||||
|
||||
virtual void CommitPages(const GSVector2i& region, bool commit) {}
|
||||
void CommitRegion(const GSVector2i& region);
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "GS/Renderers/DX11/D3D.h"
|
||||
#include "GS/GSExtra.h"
|
||||
#include "GS/GSUtil.h"
|
||||
#include "GS/resource.h"
|
||||
#include "Host.h"
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <VersionHelpers.h>
|
||||
@@ -218,6 +218,11 @@ bool GSDevice11::Create(const WindowInfo& wi)
|
||||
m_hack_topleft_offset = (m_upscale_multiplier != 1 && D3D::IsNvidia(adapter.get()) && !disable_safe_features) ? -0.01f : 0.0f;
|
||||
}
|
||||
|
||||
std::optional<std::string> shader = Host::ReadResourceFileToString("shaders/dx11/tfx.fx");
|
||||
if (!shader.has_value())
|
||||
return false;
|
||||
m_tfx_source = std::move(*shader);
|
||||
|
||||
// convert
|
||||
|
||||
D3D11_INPUT_ELEMENT_DESC il_convert[] =
|
||||
@@ -229,9 +234,10 @@ bool GSDevice11::Create(const WindowInfo& wi)
|
||||
|
||||
ShaderMacro sm_model(m_shader.model);
|
||||
|
||||
std::vector<char> shader;
|
||||
theApp.LoadResource(IDR_CONVERT_FX, shader);
|
||||
CreateShader(shader, "convert.fx", nullptr, "vs_main", sm_model.GetPtr(), &m_convert.vs, il_convert, std::size(il_convert), m_convert.il.put());
|
||||
shader = Host::ReadResourceFileToString("shaders/dx11/convert.fx");
|
||||
if (!shader.has_value())
|
||||
return false;
|
||||
CreateShader(*shader, "convert.fx", nullptr, "vs_main", sm_model.GetPtr(), &m_convert.vs, il_convert, std::size(il_convert), m_convert.il.put());
|
||||
|
||||
ShaderMacro sm_convert(m_shader.model);
|
||||
sm_convert.AddMacro("PS_SCALE_FACTOR", std::max(1, m_upscale_multiplier));
|
||||
@@ -240,7 +246,7 @@ bool GSDevice11::Create(const WindowInfo& wi)
|
||||
|
||||
for (size_t i = 0; i < std::size(m_convert.ps); i++)
|
||||
{
|
||||
CreateShader(shader, "convert.fx", nullptr, format("ps_main%d", i).c_str(), sm_convert_ptr, m_convert.ps[i].put());
|
||||
CreateShader(*shader, "convert.fx", nullptr, shaderName(static_cast<ShaderConvert>(i)), sm_convert_ptr, m_convert.ps[i].put());
|
||||
}
|
||||
|
||||
memset(&dsd, 0, sizeof(dsd));
|
||||
@@ -269,10 +275,13 @@ bool GSDevice11::Create(const WindowInfo& wi)
|
||||
|
||||
m_dev->CreateBuffer(&bd, nullptr, m_merge.cb.put());
|
||||
|
||||
theApp.LoadResource(IDR_MERGE_FX, shader);
|
||||
shader = Host::ReadResourceFileToString("shaders/dx11/merge.fx");
|
||||
if (!shader.has_value())
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < std::size(m_merge.ps); i++)
|
||||
{
|
||||
CreateShader(shader, "merge.fx", nullptr, format("ps_main%d", i).c_str(), sm_model.GetPtr(), m_merge.ps[i].put());
|
||||
CreateShader(*shader, "merge.fx", nullptr, format("ps_main%d", i).c_str(), sm_model.GetPtr(), m_merge.ps[i].put());
|
||||
}
|
||||
|
||||
memset(&bsd, 0, sizeof(bsd));
|
||||
@@ -298,10 +307,12 @@ bool GSDevice11::Create(const WindowInfo& wi)
|
||||
|
||||
m_dev->CreateBuffer(&bd, nullptr, m_interlace.cb.put());
|
||||
|
||||
theApp.LoadResource(IDR_INTERLACE_FX, shader);
|
||||
shader = Host::ReadResourceFileToString("shaders/dx11/interlace.fx");
|
||||
if (!shader.has_value())
|
||||
return false;
|
||||
for (size_t i = 0; i < std::size(m_interlace.ps); i++)
|
||||
{
|
||||
CreateShader(shader, "interlace.fx", nullptr, format("ps_main%d", i).c_str(), sm_model.GetPtr(), m_interlace.ps[i].put());
|
||||
CreateShader(*shader, "interlace.fx", nullptr, format("ps_main%d", i).c_str(), sm_model.GetPtr(), m_interlace.ps[i].put());
|
||||
}
|
||||
|
||||
// Shade Boost
|
||||
@@ -320,8 +331,10 @@ bool GSDevice11::Create(const WindowInfo& wi)
|
||||
|
||||
m_dev->CreateBuffer(&bd, nullptr, m_shadeboost.cb.put());
|
||||
|
||||
theApp.LoadResource(IDR_SHADEBOOST_FX, shader);
|
||||
CreateShader(shader, "shadeboost.fx", nullptr, "ps_main", sm_sboost.GetPtr(), m_shadeboost.ps.put());
|
||||
shader = Host::ReadResourceFileToString("shaders/dx11/shadeboost.fx");
|
||||
if (!shader.has_value())
|
||||
return false;
|
||||
CreateShader(*shader, "shadeboost.fx", nullptr, "ps_main", sm_sboost.GetPtr(), m_shadeboost.ps.put());
|
||||
|
||||
// External fx shader
|
||||
|
||||
@@ -418,7 +431,7 @@ bool GSDevice11::Create(const WindowInfo& wi)
|
||||
const GSVector2i tex_font = m_osd.get_texture_font_size();
|
||||
|
||||
m_font = std::unique_ptr<GSTexture>(
|
||||
CreateSurface(GSTexture::Texture, tex_font.x, tex_font.y, DXGI_FORMAT_R8_UNORM));
|
||||
CreateSurface(GSTexture::Type::Texture, tex_font.x, tex_font.y, GSTexture::Format::UNorm8));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -443,7 +456,7 @@ bool GSDevice11::Reset(int w, int h)
|
||||
return false;
|
||||
}
|
||||
|
||||
m_backbuffer = new GSTexture11(std::move(backbuffer));
|
||||
m_backbuffer = new GSTexture11(std::move(backbuffer), GSTexture::Format::Backbuffer);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -562,16 +575,32 @@ void GSDevice11::ClearStencil(GSTexture* t, u8 c)
|
||||
m_ctx->ClearDepthStencilView(*(GSTexture11*)t, D3D11_CLEAR_STENCIL, 0, c);
|
||||
}
|
||||
|
||||
GSTexture* GSDevice11::CreateSurface(int type, int w, int h, int format)
|
||||
GSTexture* GSDevice11::CreateSurface(GSTexture::Type type, int w, int h, GSTexture::Format format)
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
|
||||
memset(&desc, 0, sizeof(desc));
|
||||
|
||||
DXGI_FORMAT dxformat;
|
||||
switch (format)
|
||||
{
|
||||
case GSTexture::Format::Color: dxformat = DXGI_FORMAT_R8G8B8A8_UNORM; break;
|
||||
case GSTexture::Format::FloatColor: dxformat = DXGI_FORMAT_R32G32B32A32_FLOAT; break;
|
||||
case GSTexture::Format::DepthStencil: dxformat = DXGI_FORMAT_R32G8X24_TYPELESS; break;
|
||||
case GSTexture::Format::UNorm8: dxformat = DXGI_FORMAT_A8_UNORM; break;
|
||||
case GSTexture::Format::UInt16: dxformat = DXGI_FORMAT_R16_UINT; break;
|
||||
case GSTexture::Format::UInt32: dxformat = DXGI_FORMAT_R32_UINT; break;
|
||||
case GSTexture::Format::Int32: dxformat = DXGI_FORMAT_R32_SINT; break;
|
||||
case GSTexture::Format::Invalid:
|
||||
case GSTexture::Format::Backbuffer:
|
||||
ASSERT(0);
|
||||
dxformat = DXGI_FORMAT_UNKNOWN;
|
||||
}
|
||||
|
||||
// Texture limit for D3D10/11 min 1, max 8192 D3D10, max 16384 D3D11.
|
||||
desc.Width = std::max(1, std::min(w, m_d3d_texsize));
|
||||
desc.Height = std::max(1, std::min(h, m_d3d_texsize));
|
||||
desc.Format = (DXGI_FORMAT)format;
|
||||
desc.Format = dxformat;
|
||||
desc.MipLevels = 1;
|
||||
desc.ArraySize = 1;
|
||||
desc.SampleDesc.Count = 1;
|
||||
@@ -580,44 +609,35 @@ GSTexture* GSDevice11::CreateSurface(int type, int w, int h, int format)
|
||||
|
||||
// mipmap = m_mipmap > 1 || m_filter != TriFiltering::None;
|
||||
const bool mipmap = m_mipmap > 1;
|
||||
const int layers = mipmap && format == DXGI_FORMAT_R8G8B8A8_UNORM ? (int)log2(std::max(w, h)) : 1;
|
||||
const int layers = mipmap && format == GSTexture::Format::Color ? (int)log2(std::max(w, h)) : 1;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case GSTexture::RenderTarget:
|
||||
case GSTexture::Type::RenderTarget:
|
||||
desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
|
||||
break;
|
||||
case GSTexture::DepthStencil:
|
||||
case GSTexture::Type::DepthStencil:
|
||||
desc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;
|
||||
break;
|
||||
case GSTexture::Texture:
|
||||
case GSTexture::Type::Texture:
|
||||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
desc.MipLevels = layers;
|
||||
break;
|
||||
case GSTexture::Offscreen:
|
||||
case GSTexture::Type::Offscreen:
|
||||
desc.Usage = D3D11_USAGE_STAGING;
|
||||
desc.CPUAccessFlags |= D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
|
||||
break;
|
||||
}
|
||||
|
||||
GSTexture11* t = NULL;
|
||||
GSTexture11* t = nullptr;
|
||||
|
||||
wil::com_ptr_nothrow<ID3D11Texture2D> texture;
|
||||
HRESULT hr = m_dev->CreateTexture2D(&desc, nullptr, texture.put());
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
t = new GSTexture11(std::move(texture));
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case GSTexture::RenderTarget:
|
||||
ClearRenderTarget(t, 0);
|
||||
break;
|
||||
case GSTexture::DepthStencil:
|
||||
ClearDepth(t);
|
||||
break;
|
||||
}
|
||||
t = new GSTexture11(std::move(texture), format);
|
||||
assert(type == t->GetType());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -627,42 +647,24 @@ GSTexture* GSDevice11::CreateSurface(int type, int w, int h, int format)
|
||||
return t;
|
||||
}
|
||||
|
||||
GSTexture* GSDevice11::FetchSurface(int type, int w, int h, int format)
|
||||
bool GSDevice11::DownloadTexture(GSTexture* src, const GSVector4i& rect, GSTexture::GSMap& out_map)
|
||||
{
|
||||
if (format == 0)
|
||||
format = (type == GSTexture::DepthStencil || type == GSTexture::SparseDepthStencil) ? DXGI_FORMAT_R32G8X24_TYPELESS : DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
|
||||
return __super::FetchSurface(type, w, h, format);
|
||||
ASSERT(src);
|
||||
ASSERT(!m_download_tex);
|
||||
m_download_tex.reset(static_cast<GSTexture11*>(CreateOffscreen(rect.width(), rect.height(), src->GetFormat())));
|
||||
if (!m_download_tex)
|
||||
return false;
|
||||
CopyRect(src, m_download_tex.get(), rect);
|
||||
return m_download_tex->Map(out_map);
|
||||
}
|
||||
|
||||
GSTexture* GSDevice11::CopyOffscreen(GSTexture* src, const GSVector4& sRect, int w, int h, int format, int ps_shader)
|
||||
void GSDevice11::DownloadTextureComplete()
|
||||
{
|
||||
GSTexture* dst = NULL;
|
||||
|
||||
if (format == 0)
|
||||
if (m_download_tex)
|
||||
{
|
||||
format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
m_download_tex->Unmap();
|
||||
Recycle(m_download_tex.release());
|
||||
}
|
||||
|
||||
ASSERT(format == DXGI_FORMAT_R8G8B8A8_UNORM || format == DXGI_FORMAT_R16_UINT || format == DXGI_FORMAT_R32_UINT);
|
||||
|
||||
if (GSTexture* rt = CreateRenderTarget(w, h, format))
|
||||
{
|
||||
GSVector4 dRect(0, 0, w, h);
|
||||
|
||||
StretchRect(src, sRect, rt, dRect, m_convert.ps[ps_shader].get(), NULL);
|
||||
|
||||
dst = CreateOffscreen(w, h, format);
|
||||
|
||||
if (dst)
|
||||
{
|
||||
m_ctx->CopyResource(*(GSTexture11*)dst, *(GSTexture11*)rt);
|
||||
}
|
||||
|
||||
Recycle(rt);
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
void GSDevice11::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r)
|
||||
@@ -678,7 +680,7 @@ void GSDevice11::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r)
|
||||
// DX api isn't happy if we pass a box for depth copy
|
||||
// It complains that depth/multisample must be a full copy
|
||||
// and asks us to use a NULL for the box
|
||||
const bool depth = (sTex->GetType() == GSTexture::DepthStencil);
|
||||
const bool depth = (sTex->GetType() == GSTexture::Type::DepthStencil);
|
||||
auto pBox = depth ? nullptr : &box;
|
||||
|
||||
m_ctx->CopySubresourceRegion(*(GSTexture11*)dTex, 0, 0, 0, 0, *(GSTexture11*)sTex, 0, pBox);
|
||||
@@ -686,7 +688,7 @@ void GSDevice11::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r)
|
||||
|
||||
void GSDevice11::CloneTexture(GSTexture* src, GSTexture** dest)
|
||||
{
|
||||
if (!src || !(src->GetType() == GSTexture::DepthStencil || src->GetType() == GSTexture::RenderTarget))
|
||||
if (!src || !(src->GetType() == GSTexture::Type::DepthStencil || src->GetType() == GSTexture::Type::RenderTarget))
|
||||
{
|
||||
ASSERT(0);
|
||||
return;
|
||||
@@ -695,7 +697,7 @@ void GSDevice11::CloneTexture(GSTexture* src, GSTexture** dest)
|
||||
const int w = src->GetWidth();
|
||||
const int h = src->GetHeight();
|
||||
|
||||
if (src->GetType() == GSTexture::DepthStencil)
|
||||
if (src->GetType() == GSTexture::Type::DepthStencil)
|
||||
*dest = CreateDepthStencil(w, h, src->GetFormat());
|
||||
else
|
||||
*dest = CreateRenderTarget(w, h, src->GetFormat());
|
||||
@@ -703,9 +705,9 @@ void GSDevice11::CloneTexture(GSTexture* src, GSTexture** dest)
|
||||
CopyRect(src, *dest, GSVector4i(0, 0, w, h));
|
||||
}
|
||||
|
||||
void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, int shader, bool linear)
|
||||
void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader, bool linear)
|
||||
{
|
||||
StretchRect(sTex, sRect, dTex, dRect, m_convert.ps[shader].get(), nullptr, linear);
|
||||
StretchRect(sTex, sRect, dTex, dRect, m_convert.ps[static_cast<int>(shader)].get(), nullptr, linear);
|
||||
}
|
||||
|
||||
void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, bool linear)
|
||||
@@ -729,7 +731,7 @@ void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture*
|
||||
wil::com_ptr_nothrow<ID3D11BlendState> bs;
|
||||
m_dev->CreateBlendState(&bd, bs.put());
|
||||
|
||||
StretchRect(sTex, sRect, dTex, dRect, m_convert.ps[ShaderConvert_COPY].get(), nullptr, bs.get(), false);
|
||||
StretchRect(sTex, sRect, dTex, dRect, m_convert.ps[static_cast<int>(ShaderConvert::COPY)].get(), nullptr, bs.get(), false);
|
||||
}
|
||||
|
||||
void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, ID3D11BlendState* bs, bool linear)
|
||||
@@ -740,8 +742,10 @@ void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture*
|
||||
return;
|
||||
}
|
||||
|
||||
const bool draw_in_depth = (ps == m_convert.ps[ShaderConvert_RGBA8_TO_FLOAT32] || ps == m_convert.ps[ShaderConvert_RGBA8_TO_FLOAT24]
|
||||
|| ps == m_convert.ps[ShaderConvert_RGBA8_TO_FLOAT16] || ps == m_convert.ps[ShaderConvert_RGB5A1_TO_FLOAT16]);
|
||||
const bool draw_in_depth = ps == m_convert.ps[static_cast<int>(ShaderConvert::RGBA8_TO_FLOAT32)]
|
||||
|| ps == m_convert.ps[static_cast<int>(ShaderConvert::RGBA8_TO_FLOAT24)]
|
||||
|| ps == m_convert.ps[static_cast<int>(ShaderConvert::RGBA8_TO_FLOAT16)]
|
||||
|| ps == m_convert.ps[static_cast<int>(ShaderConvert::RGB5A1_TO_FLOAT16)];
|
||||
|
||||
BeginScene();
|
||||
|
||||
@@ -827,7 +831,7 @@ void GSDevice11::RenderOsd(GSTexture* dt)
|
||||
// ps
|
||||
PSSetShaderResource(0, m_font.get());
|
||||
PSSetSamplerState(m_convert.pt.get(), nullptr);
|
||||
PSSetShader(m_convert.ps[ShaderConvert_OSD].get(), nullptr);
|
||||
PSSetShader(m_convert.ps[static_cast<int>(ShaderConvert::OSD)].get(), nullptr);
|
||||
|
||||
// ia
|
||||
IASetInputLayout(m_convert.il.get());
|
||||
@@ -920,9 +924,8 @@ void GSDevice11::DoExternalFX(GSTexture* sTex, GSTexture* dTex)
|
||||
|
||||
shader << fshader.rdbuf();
|
||||
const std::string& s = shader.str();
|
||||
std::vector<char> buff(s.begin(), s.end());
|
||||
ShaderMacro sm(m_shader.model);
|
||||
CreateShader(buff, shader_name.c_str(), D3D_COMPILE_STANDARD_FILE_INCLUDE, "ps_main", sm.GetPtr(), m_shaderfx.ps.put());
|
||||
CreateShader(s, shader_name.c_str(), D3D_COMPILE_STANDARD_FILE_INCLUDE, "ps_main", sm.GetPtr(), m_shaderfx.ps.put());
|
||||
}
|
||||
catch (GSRecoverableError)
|
||||
{
|
||||
@@ -952,10 +955,12 @@ void GSDevice11::DoFXAA(GSTexture* sTex, GSTexture* dTex)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::vector<char> shader;
|
||||
theApp.LoadResource(IDR_FXAA_FX, shader);
|
||||
ShaderMacro sm(m_shader.model);
|
||||
CreateShader(shader, "fxaa.fx", nullptr, "ps_main", sm.GetPtr(), m_fxaa.ps.put());
|
||||
std::optional<std::string> shader = Host::ReadResourceFileToString("shaders/common/fxaa.fx");
|
||||
if (shader.has_value())
|
||||
{
|
||||
ShaderMacro sm(m_shader.model);
|
||||
CreateShader(*shader, "fxaa.fx", nullptr, "ps_main", sm.GetPtr(), m_fxaa.ps.put());
|
||||
}
|
||||
}
|
||||
catch (GSRecoverableError)
|
||||
{
|
||||
@@ -1022,7 +1027,7 @@ void GSDevice11::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* vert
|
||||
// ps
|
||||
PSSetShaderResources(rt, nullptr);
|
||||
PSSetSamplerState(m_convert.pt.get(), nullptr);
|
||||
PSSetShader(m_convert.ps[datm ? ShaderConvert_DATM_1 : ShaderConvert_DATM_0].get(), nullptr);
|
||||
PSSetShader(m_convert.ps[static_cast<int>(datm ? ShaderConvert::DATM_1 : ShaderConvert::DATM_0)].get(), nullptr);
|
||||
|
||||
//
|
||||
|
||||
@@ -1394,7 +1399,7 @@ D3D_SHADER_MACRO* GSDevice11::ShaderMacro::GetPtr(void)
|
||||
return (D3D_SHADER_MACRO*)mout.data();
|
||||
}
|
||||
|
||||
void GSDevice11::CreateShader(const std::vector<char>& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11VertexShader** vs, D3D11_INPUT_ELEMENT_DESC* layout, int count, ID3D11InputLayout** il)
|
||||
void GSDevice11::CreateShader(const std::string& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11VertexShader** vs, D3D11_INPUT_ELEMENT_DESC* layout, int count, ID3D11InputLayout** il)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
@@ -1417,7 +1422,7 @@ void GSDevice11::CreateShader(const std::vector<char>& source, const char* fn, I
|
||||
}
|
||||
}
|
||||
|
||||
void GSDevice11::CreateShader(const std::vector<char>& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11GeometryShader** gs)
|
||||
void GSDevice11::CreateShader(const std::string& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11GeometryShader** gs)
|
||||
{
|
||||
wil::com_ptr_nothrow<ID3DBlob> shader;
|
||||
|
||||
@@ -1431,7 +1436,7 @@ void GSDevice11::CreateShader(const std::vector<char>& source, const char* fn, I
|
||||
}
|
||||
}
|
||||
|
||||
void GSDevice11::CreateShader(const std::vector<char>& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11PixelShader** ps)
|
||||
void GSDevice11::CreateShader(const std::string& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11PixelShader** ps)
|
||||
{
|
||||
wil::com_ptr_nothrow<ID3DBlob> shader;
|
||||
|
||||
@@ -1445,7 +1450,7 @@ void GSDevice11::CreateShader(const std::vector<char>& source, const char* fn, I
|
||||
}
|
||||
}
|
||||
|
||||
void GSDevice11::CompileShader(const std::vector<char>& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3DBlob** shader, const std::string& shader_model)
|
||||
void GSDevice11::CompileShader(const std::string& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3DBlob** shader, const std::string& shader_model)
|
||||
{
|
||||
wil::com_ptr_nothrow<ID3DBlob> error;
|
||||
|
||||
@@ -1456,7 +1461,7 @@ void GSDevice11::CompileShader(const std::vector<char>& source, const char* fn,
|
||||
#endif
|
||||
|
||||
const HRESULT hr = D3DCompile(
|
||||
source.data(), source.size(), fn, macro,
|
||||
source.c_str(), source.size(), fn, macro,
|
||||
include, entry, shader_model.c_str(),
|
||||
flags, 0, shader, error.put());
|
||||
|
||||
|
||||
@@ -336,6 +336,7 @@ public:
|
||||
u32 blend_index : 7;
|
||||
u32 abe : 1;
|
||||
u32 accu_blend : 1;
|
||||
u32 blend_mix : 1;
|
||||
};
|
||||
|
||||
struct
|
||||
@@ -347,7 +348,7 @@ public:
|
||||
u32 key;
|
||||
};
|
||||
|
||||
operator u32() { return key & 0x1fff; }
|
||||
operator u32() { return key & 0x3fff; }
|
||||
|
||||
OMBlendSelector()
|
||||
: key(0)
|
||||
@@ -395,8 +396,7 @@ private:
|
||||
int m_mipmap;
|
||||
int m_d3d_texsize;
|
||||
|
||||
GSTexture* CreateSurface(int type, int w, int h, int format);
|
||||
GSTexture* FetchSurface(int type, int w, int h, int format);
|
||||
GSTexture* CreateSurface(GSTexture::Type type, int w, int h, GSTexture::Format format) final;
|
||||
|
||||
void DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, const GSVector4& c) final;
|
||||
void DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset = 0) final;
|
||||
@@ -449,7 +449,7 @@ private:
|
||||
{
|
||||
wil::com_ptr_nothrow<ID3D11InputLayout> il;
|
||||
wil::com_ptr_nothrow<ID3D11VertexShader> vs;
|
||||
wil::com_ptr_nothrow<ID3D11PixelShader> ps[ShaderConvert_Count];
|
||||
wil::com_ptr_nothrow<ID3D11PixelShader> ps[static_cast<int>(ShaderConvert::Count)];
|
||||
wil::com_ptr_nothrow<ID3D11SamplerState> ln;
|
||||
wil::com_ptr_nothrow<ID3D11SamplerState> pt;
|
||||
wil::com_ptr_nothrow<ID3D11DepthStencilState> dss;
|
||||
@@ -512,6 +512,9 @@ private:
|
||||
PSConstantBuffer m_ps_cb_cache;
|
||||
|
||||
std::unique_ptr<GSTexture> m_font;
|
||||
std::unique_ptr<GSTexture11> m_download_tex;
|
||||
|
||||
std::string m_tfx_source;
|
||||
|
||||
protected:
|
||||
struct
|
||||
@@ -532,22 +535,23 @@ public:
|
||||
void Flip();
|
||||
void SetVSync(int vsync) final;
|
||||
|
||||
void DrawPrimitive() final;
|
||||
void DrawPrimitive();
|
||||
void DrawIndexedPrimitive();
|
||||
void DrawIndexedPrimitive(int offset, int count) final;
|
||||
void DrawIndexedPrimitive(int offset, int count);
|
||||
|
||||
void ClearRenderTarget(GSTexture* t, const GSVector4& c) final;
|
||||
void ClearRenderTarget(GSTexture* t, u32 c) final;
|
||||
void ClearDepth(GSTexture* t) final;
|
||||
void ClearStencil(GSTexture* t, u8 c) final;
|
||||
|
||||
GSTexture* CopyOffscreen(GSTexture* src, const GSVector4& sRect, int w, int h, int format = 0, int ps_shader = 0) final;
|
||||
bool DownloadTexture(GSTexture* src, const GSVector4i& rect, GSTexture::GSMap& out_map) final;
|
||||
void DownloadTextureComplete() final;
|
||||
|
||||
void CloneTexture(GSTexture* src, GSTexture** dest);
|
||||
|
||||
void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r);
|
||||
|
||||
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, int shader = 0, bool linear = true) final;
|
||||
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader = ShaderConvert::COPY, bool linear = true) final;
|
||||
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, bool linear = true);
|
||||
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red, bool green, bool blue, bool alpha);
|
||||
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, ID3D11BlendState* bs, bool linear = true);
|
||||
@@ -566,8 +570,8 @@ public:
|
||||
void VSSetShader(ID3D11VertexShader* vs, ID3D11Buffer* vs_cb);
|
||||
void GSSetShader(ID3D11GeometryShader* gs, ID3D11Buffer* gs_cb = NULL);
|
||||
|
||||
void PSSetShaderResources(GSTexture* sr0, GSTexture* sr1) final;
|
||||
void PSSetShaderResource(int i, GSTexture* sr) final;
|
||||
void PSSetShaderResources(GSTexture* sr0, GSTexture* sr1);
|
||||
void PSSetShaderResource(int i, GSTexture* sr);
|
||||
void PSSetShaderResourceView(int i, ID3D11ShaderResourceView* srv, GSTexture* sr);
|
||||
void PSSetShader(ID3D11PixelShader* ps, ID3D11Buffer* ps_cb);
|
||||
void PSUpdateShaderState();
|
||||
@@ -575,7 +579,7 @@ public:
|
||||
|
||||
void OMSetDepthStencilState(ID3D11DepthStencilState* dss, u8 sref);
|
||||
void OMSetBlendState(ID3D11BlendState* bs, float bf);
|
||||
void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor = NULL) final;
|
||||
void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor = NULL);
|
||||
|
||||
bool CreateTextureFX();
|
||||
void SetupVS(VSSelector sel, const VSConstantBuffer* cb);
|
||||
@@ -587,9 +591,9 @@ public:
|
||||
operator ID3D11Device*() { return m_dev.get(); }
|
||||
operator ID3D11DeviceContext*() { return m_ctx.get(); }
|
||||
|
||||
void CreateShader(const std::vector<char>& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11VertexShader** vs, D3D11_INPUT_ELEMENT_DESC* layout, int count, ID3D11InputLayout** il);
|
||||
void CreateShader(const std::vector<char>& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11GeometryShader** gs);
|
||||
void CreateShader(const std::vector<char>& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11PixelShader** ps);
|
||||
void CreateShader(const std::string& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11VertexShader** vs, D3D11_INPUT_ELEMENT_DESC* layout, int count, ID3D11InputLayout** il);
|
||||
void CreateShader(const std::string& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11GeometryShader** gs);
|
||||
void CreateShader(const std::string& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11PixelShader** ps);
|
||||
|
||||
void CompileShader(const std::vector<char>& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3DBlob** shader, const std::string& shader_model);
|
||||
void CompileShader(const std::string& source, const char* fn, ID3DInclude* include, const char* entry, D3D_SHADER_MACRO* macro, ID3DBlob** shader, const std::string& shader_model);
|
||||
};
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include "GSRendererDX11.h"
|
||||
|
||||
GSRendererDX11::GSRendererDX11()
|
||||
: GSRendererHW(new GSTextureCache11(this))
|
||||
{
|
||||
m_sw_blending = theApp.GetConfigI("accurate_blending_unit_d3d11");
|
||||
|
||||
@@ -317,7 +316,7 @@ void GSRendererDX11::EmulateChannelShuffle(GSTexture** rt, const GSTextureCache:
|
||||
m_channel_shuffle = false;
|
||||
}
|
||||
}
|
||||
else if ((tex->m_texture->GetType() == GSTexture::DepthStencil) && !(tex->m_32_bits_fmt))
|
||||
else if ((tex->m_texture->GetType() == GSTexture::Type::DepthStencil) && !(tex->m_32_bits_fmt))
|
||||
{
|
||||
// So far 2 games hit this code path. Urban Chaos and Tales of Abyss
|
||||
// UC: will copy depth to green channel
|
||||
@@ -361,11 +360,10 @@ void GSRendererDX11::EmulateChannelShuffle(GSTexture** rt, const GSTextureCache:
|
||||
{
|
||||
// Typically used in Terminator 3
|
||||
const int blue_mask = m_context->FRAME.FBMSK >> 24;
|
||||
const int green_mask = ~blue_mask & 0xFF;
|
||||
int blue_shift = -1;
|
||||
|
||||
// Note: potentially we could also check the value of the clut
|
||||
switch (m_context->FRAME.FBMSK >> 24)
|
||||
switch (blue_mask)
|
||||
{
|
||||
case 0xFF: ASSERT(0); break;
|
||||
case 0xFE: blue_shift = 1; break;
|
||||
@@ -375,21 +373,22 @@ void GSRendererDX11::EmulateChannelShuffle(GSTexture** rt, const GSTextureCache:
|
||||
case 0xE0: blue_shift = 5; break;
|
||||
case 0xC0: blue_shift = 6; break;
|
||||
case 0x80: blue_shift = 7; break;
|
||||
default: ASSERT(0); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
const int green_shift = 8 - blue_shift;
|
||||
ps_cb.ChannelShuffle = GSVector4i(blue_mask, blue_shift, green_mask, green_shift);
|
||||
|
||||
if (blue_shift >= 0)
|
||||
{
|
||||
const int green_mask = ~blue_mask & 0xFF;
|
||||
const int green_shift = 8 - blue_shift;
|
||||
|
||||
// fprintf(stderr, "%d: Green/Blue channel (%d, %d)\n", s_n, blue_shift, green_shift);
|
||||
ps_cb.ChannelShuffle = GSVector4i(blue_mask, blue_shift, green_mask, green_shift);
|
||||
m_ps_sel.channel = ChannelFetch_GXBY;
|
||||
m_context->FRAME.FBMSK = 0x00FFFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
// fprintf(stderr, "%d: Green channel (wrong mask) (fbmask %x)\n", s_n, m_context->FRAME.FBMSK >> 24);
|
||||
// fprintf(stderr, "%d: Green channel (wrong mask) (fbmask %x)\n", s_n, blue_mask);
|
||||
m_ps_sel.channel = ChannelFetch_GREEN;
|
||||
}
|
||||
}
|
||||
@@ -438,7 +437,7 @@ void GSRendererDX11::EmulateChannelShuffle(GSTexture** rt, const GSTextureCache:
|
||||
}
|
||||
}
|
||||
|
||||
void GSRendererDX11::EmulateBlending()
|
||||
void GSRendererDX11::EmulateBlending(u8& afix)
|
||||
{
|
||||
// Partial port of OGL SW blending. Currently only works for accumulation and non recursive blend.
|
||||
|
||||
@@ -461,6 +460,16 @@ void GSRendererDX11::EmulateBlending()
|
||||
// Blending doesn't require sampling of the rt
|
||||
const bool blend_non_recursive = !!(blend_flag & BLEND_NO_REC);
|
||||
|
||||
// BLEND MIX selection, use a mix of hw/sw blending
|
||||
if (!m_vt.m_alpha.valid && (ALPHA.C == 0))
|
||||
GetAlphaMinMax();
|
||||
const bool blend_mix1 = !!(blend_flag & BLEND_MIX1);
|
||||
const bool blend_mix2 = !!(blend_flag & BLEND_MIX2);
|
||||
const bool blend_mix3 = !!(blend_flag & BLEND_MIX3);
|
||||
bool blend_mix = (blend_mix1 || blend_mix2 || blend_mix3)
|
||||
// Do not enable if As > 128 or F > 128, hw blend clamps to 1
|
||||
&& !((ALPHA.C == 0 && m_vt.m_alpha.max > 128) || (ALPHA.C == 2 && ALPHA.FIX > 128u));
|
||||
|
||||
bool sw_blending = false;
|
||||
switch (m_sw_blending)
|
||||
{
|
||||
@@ -473,6 +482,13 @@ void GSRendererDX11::EmulateBlending()
|
||||
break;
|
||||
}
|
||||
|
||||
// Do not run BLEND MIX if sw blending is already present, it's less accurate
|
||||
if (m_sw_blending)
|
||||
{
|
||||
blend_mix &= !sw_blending;
|
||||
sw_blending |= blend_mix;
|
||||
}
|
||||
|
||||
// Color clip
|
||||
if (m_env.COLCLAMP.CLAMP == 0)
|
||||
{
|
||||
@@ -484,7 +500,7 @@ void GSRendererDX11::EmulateBlending()
|
||||
m_ps_sel.colclip = 1;
|
||||
sw_blending = true;
|
||||
}
|
||||
else if (accumulation_blend)
|
||||
else if (accumulation_blend || blend_mix)
|
||||
{
|
||||
// fprintf(stderr, "%d: COLCLIP Fast HDR mode ENABLED\n", s_n);
|
||||
sw_blending = true;
|
||||
@@ -514,6 +530,7 @@ void GSRendererDX11::EmulateBlending()
|
||||
{
|
||||
// fprintf(stderr, "%d: PABE mode ENABLED\n", s_n);
|
||||
m_ps_sel.pabe = 1;
|
||||
sw_blending = blend_non_recursive;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -529,8 +546,9 @@ void GSRendererDX11::EmulateBlending()
|
||||
|
||||
if (accumulation_blend)
|
||||
{
|
||||
// Keep HW blending to do the addition/subtraction
|
||||
m_om_bsel.accu_blend = 1;
|
||||
|
||||
afix = 0;
|
||||
if (ALPHA.A == 2)
|
||||
{
|
||||
// The blend unit does a reverse subtraction so it means
|
||||
@@ -542,11 +560,36 @@ void GSRendererDX11::EmulateBlending()
|
||||
// Remove the addition/substraction from the SW blending
|
||||
m_ps_sel.blend_d = 2;
|
||||
}
|
||||
else if (blend_mix)
|
||||
{
|
||||
afix = (ALPHA.C == 2) ? ALPHA.FIX : 0;
|
||||
m_om_bsel.blend_mix = 1;
|
||||
|
||||
if (blend_mix1)
|
||||
{
|
||||
m_ps_sel.blend_a = 0;
|
||||
m_ps_sel.blend_b = 2;
|
||||
m_ps_sel.blend_d = 2;
|
||||
}
|
||||
else if (blend_mix2)
|
||||
{
|
||||
m_ps_sel.blend_a = 0;
|
||||
m_ps_sel.blend_b = 2;
|
||||
m_ps_sel.blend_d = 0;
|
||||
}
|
||||
else if (blend_mix3)
|
||||
{
|
||||
m_ps_sel.blend_a = 2;
|
||||
m_ps_sel.blend_b = 0;
|
||||
m_ps_sel.blend_d = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Disable HW blending
|
||||
m_om_bsel.abe = 0;
|
||||
m_om_bsel.blend_index = 0;
|
||||
afix = 0;
|
||||
|
||||
// Only BLEND_NO_REC should hit this code path for now
|
||||
ASSERT(blend_non_recursive);
|
||||
@@ -559,6 +602,7 @@ void GSRendererDX11::EmulateBlending()
|
||||
else
|
||||
{
|
||||
m_ps_sel.clr1 = !!(blend_flag & BLEND_C_CLR);
|
||||
afix = (ALPHA.C == 2) ? ALPHA.FIX : 0;
|
||||
// FIXME: When doing HW blending with a 24 bit frambuffer and ALPHA.C == 1 (Ad) it should be handled
|
||||
// as if Ad = 1.0f. As with OGL side it is probably best to set m_om_bsel.c = 1 (Af) and use
|
||||
// AFIX = 0x80 (Af = 1.0f).
|
||||
@@ -608,7 +652,7 @@ void GSRendererDX11::EmulateTextureSampler(const GSTextureCache::Source* tex)
|
||||
// Require a float conversion if the texure is a depth otherwise uses Integral scaling
|
||||
if (psm.depth)
|
||||
{
|
||||
m_ps_sel.depth_fmt = (tex->m_texture->GetType() != GSTexture::DepthStencil) ? 3 : 1;
|
||||
m_ps_sel.depth_fmt = (tex->m_texture->GetType() != GSTexture::Type::DepthStencil) ? 3 : 1;
|
||||
}
|
||||
|
||||
// Shuffle is a 16 bits format, so aem is always required
|
||||
@@ -655,7 +699,7 @@ void GSRendererDX11::EmulateTextureSampler(const GSTextureCache::Source* tex)
|
||||
}
|
||||
|
||||
// Depth format
|
||||
if (tex->m_texture->GetType() == GSTexture::DepthStencil)
|
||||
if (tex->m_texture->GetType() == GSTexture::Type::DepthStencil)
|
||||
{
|
||||
// Require a float conversion if the texure is a depth format
|
||||
m_ps_sel.depth_fmt = (psm.bpp == 16) ? 2 : 1;
|
||||
@@ -835,19 +879,20 @@ void GSRendererDX11::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sou
|
||||
}
|
||||
|
||||
// Blend
|
||||
u8 afix = 0;
|
||||
if (!IsOpaque() && rt)
|
||||
{
|
||||
EmulateBlending();
|
||||
EmulateBlending(afix);
|
||||
}
|
||||
|
||||
if (m_ps_sel.hdr)
|
||||
{
|
||||
const GSVector4 dRect(ComputeBoundingBox(rtscale, rtsize));
|
||||
const GSVector4 sRect = dRect / GSVector4(rtsize.x, rtsize.y).xyxy();
|
||||
hdr_rt = dev->CreateRenderTarget(rtsize.x, rtsize.y, DXGI_FORMAT_R32G32B32A32_FLOAT);
|
||||
hdr_rt = dev->CreateRenderTarget(rtsize.x, rtsize.y, GSTexture::Format::FloatColor);
|
||||
// Warning: StretchRect must be called before BeginScene otherwise
|
||||
// vertices will be overwritten. Trust me you don't want to do that.
|
||||
dev->StretchRect(rt, sRect, hdr_rt, dRect, ShaderConvert_COPY, false);
|
||||
dev->StretchRect(rt, sRect, hdr_rt, dRect, ShaderConvert::COPY, false);
|
||||
}
|
||||
|
||||
if (m_ps_sel.dfmt == 1)
|
||||
@@ -1050,7 +1095,6 @@ void GSRendererDX11::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sou
|
||||
|
||||
SetupIA(sx, sy);
|
||||
|
||||
const u8 afix = m_context->ALPHA.FIX;
|
||||
dev->SetupOM(m_om_dssel, m_om_bsel, afix);
|
||||
dev->SetupVS(m_vs_sel, &vs_cb);
|
||||
dev->SetupGS(m_gs_sel, &gs_cb);
|
||||
@@ -1135,7 +1179,7 @@ void GSRendererDX11::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sou
|
||||
{
|
||||
const GSVector4 dRect(ComputeBoundingBox(rtscale, rtsize));
|
||||
const GSVector4 sRect = dRect / GSVector4(rtsize.x, rtsize.y).xyxy();
|
||||
dev->StretchRect(hdr_rt, sRect, rt, dRect, ShaderConvert_MOD_256, false);
|
||||
dev->StretchRect(hdr_rt, sRect, rt, dRect, ShaderConvert::MOD_256, false);
|
||||
|
||||
dev->Recycle(hdr_rt);
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GSDevice11.h"
|
||||
#include "GS/Renderers/HW/GSRendererHW.h"
|
||||
#include "GSTextureCache11.h"
|
||||
#include "GS/Renderers/HW/GSVertexHW.h"
|
||||
|
||||
class GSRendererDX11 final : public GSRendererHW
|
||||
@@ -36,7 +36,7 @@ private:
|
||||
inline void ResetStates();
|
||||
inline void SetupIA(const float& sx, const float& sy);
|
||||
inline void EmulateZbuffer();
|
||||
inline void EmulateBlending();
|
||||
inline void EmulateBlending(u8& afix);
|
||||
inline void EmulateTextureShuffleAndFbmask();
|
||||
inline void EmulateChannelShuffle(GSTexture** rt, const GSTextureCache::Source* tex);
|
||||
inline void EmulateTextureSampler(const GSTextureCache::Source* tex);
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "GSTexture11.h"
|
||||
#include "GS/GSPng.h"
|
||||
|
||||
GSTexture11::GSTexture11(wil::com_ptr_nothrow<ID3D11Texture2D> texture)
|
||||
GSTexture11::GSTexture11(wil::com_ptr_nothrow<ID3D11Texture2D> texture, GSTexture::Format format)
|
||||
: m_texture(std::move(texture)), m_layer(0)
|
||||
{
|
||||
ASSERT(m_texture);
|
||||
@@ -31,15 +31,15 @@ GSTexture11::GSTexture11(wil::com_ptr_nothrow<ID3D11Texture2D> texture)
|
||||
m_size.y = (int)m_desc.Height;
|
||||
|
||||
if (m_desc.BindFlags & D3D11_BIND_RENDER_TARGET)
|
||||
m_type = RenderTarget;
|
||||
m_type = Type::RenderTarget;
|
||||
else if (m_desc.BindFlags & D3D11_BIND_DEPTH_STENCIL)
|
||||
m_type = DepthStencil;
|
||||
m_type = Type::DepthStencil;
|
||||
else if (m_desc.BindFlags & D3D11_BIND_SHADER_RESOURCE)
|
||||
m_type = Texture;
|
||||
m_type = Type::Texture;
|
||||
else if (m_desc.Usage == D3D11_USAGE_STAGING)
|
||||
m_type = Offscreen;
|
||||
m_type = Type::Offscreen;
|
||||
|
||||
m_format = (int)m_desc.Format;
|
||||
m_format = format;
|
||||
|
||||
m_max_layer = m_desc.MipLevels;
|
||||
}
|
||||
@@ -168,7 +168,7 @@ bool GSTexture11::Save(const std::string& fn)
|
||||
|
||||
res->GetDesc(&desc);
|
||||
|
||||
#ifdef ENABLE_OGL_DEBUG
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
GSPng::Format format = GSPng::RGB_A_PNG;
|
||||
#else
|
||||
GSPng::Format format = GSPng::RGB_PNG;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user