Compare commits

...
30 Commits
Author SHA1 Message Date
Connor McLaughlin fac171fa95 CDVD: Check file actually opened before proceeding
If you loaded an invalid file, particularly with compression, the file
open may fail, leading to a division by zero (on block size), or trying
to read from nothing.
2021-12-18 13:41:56 +00:00
refractionpcsx2 fa1b6493da CDVD GZip: Correct type causing index creation to fail 2021-12-17 11:46:31 +00:00
refractionpcsx2 e58766745c Log: Restore BIOS Found message 2021-12-16 11:45:12 +00:00
Mrlinkwii d8a9c5b479 Gamedb add gamefixes to 'Titeuf Mega-compet' and patch 'Yamiyo ni Sasayaku - Tantei Sagara Kyouichirou' series 2021-12-15 17:17:18 +00:00
Mrlinkwii 9a4d8ba934 Gamedb: add more 2k games patches 2021-12-15 10:52:22 +00:00
refractionpcsx2 ab816543c8 CDVD: Fixed typo opening gzip files
Fixes #5162
2021-12-15 09:38:04 +00:00
refractionpcsx2 37ccd81985 GS: Avoid some unnecessary flushes
CLUT only updates if valid index type used in PSM
2021-12-14 18:28:21 +00:00
refractionpcsx2 42dad4ade8 GS: Check CLUT dirty write on vertex kick 2021-12-14 18:28:21 +00:00
refractionpcsx2 b2ac035862 VS: Fix location of shaders in project 2021-12-14 17:47:53 +00:00
refractionpcsx2 f42d7eec74 CDVD: Don't set as Reading when buffering. 2021-12-14 10:35:12 +00:00
refractionpcsx2 e4ef41f86a CDVD: Fix some read timing logic 2021-12-14 10:35:12 +00:00
Mrlinkwii 103dd3954a missing UI and game elements. 2021-12-14 09:22:31 +00:00
Tokman5 2f9577a28e Add "Jikkyou Powerful Pro Yakyuu 2009" to GameIndex.yaml 2021-12-14 08:06:34 +00:00
Gauvain 'GovanifY' Roussel-Tarbouriech 33ec4d9430 msvc: fix issues with size() not being correctly evaluated as const 2021-12-13 09:34:24 +00:00
Gauvain 'GovanifY' Roussel-Tarbouriech 209f09ca7a pine: send serial without gui beautification 2021-12-13 09:34:24 +00:00
Gauvain 'GovanifY' Roussel-Tarbouriech 2e6af75f1d pine: add vle replies 2021-12-13 09:34:24 +00:00
Gauvain 'GovanifY' Roussel-Tarbouriech f68122a380 ipc: rename to pine 2021-12-13 09:34:24 +00:00
TellowKrinkle d51bdccf7f CMake: Remove gio dependency on macOS 2021-12-13 03:29:16 -06:00
iMineLink 7d8377b133 GS-hw: define some consts only in debug mode. 2021-12-13 08:06:52 +01:00
iMineLink 80d3a8a757 GS-hw, TC: don't linearly interpolate downloads.
Greatly improves Burnout games clouds rendering
with even (x2, x4, ...) upscaling factors.
2021-12-13 08:06:52 +01:00
iMineLink 2e6c5cde29 GS-hw: rework surface fetching.
Factorized code.
Always clear render targets and depth stencils
when being fetched.
"force_texture_clear" OGL only config removed.
2021-12-13 08:06:52 +01:00
iMineLink 0f2768dca4 GS-hw, TC: improve LookupTarget.
allow propagation of increased target size and
correct the rescaling.
2021-12-13 08:06:52 +01:00
iMineLink d5be095482 GS-hw: fix burnout black sky and no clouds.
Achieved with a combination of OI+OO hacks that operate
during level loading to consolidate the rendering results
in the GS local memory.

* OI_BurnoutGames to perform small draws directly in local memory:
** improved OI_PointListPalette to draw clouds CLUT,
** improved SwSpriteRender to draw sky texture;
* OO_BurnoutGames used to download clouds texture from GPU.
2021-12-13 08:06:52 +01:00
iMineLink b315625a94 GS-hw: resize rt and ds before draw if necessary. 2021-12-13 08:06:52 +01:00
iMineLink 6b51462fa0 GS-hw: use CanUpscale to check for upscaling. 2021-12-13 08:06:52 +01:00
iMineLink 373e698545 GS-hw, TC: fix tex scaling for native res draws.
The GSTextureCache::ScaleTexture method did not work
correctly when an old texture with a scale factor
different from 1 was recycled for a draw which was forced at
native resolution (the old scale factor was kept).
2021-12-13 08:06:52 +01:00
iMineLink 3b309c6d4e GS: dump alpha channel too. 2021-12-13 08:06:52 +01:00
kenshen112 8e93e9f516 CMake: Switch Wayland find script and usage to use imported targets
Also clears warning about mismatched names getting sent to FIND_PACKAGE_HANDLE_STANDARD_ARGS
2021-12-13 00:23:52 -06:00
kenshen112 ac8582eca7 CMake: Set minimum version first
Makes policy enabling based on minimum version work properly
Also increases minimum version to 3.11 because we actually do use 3.11 features
2021-12-13 00:23:52 -06:00
kenshen112 e6f72fdde7 GHActions: Enable Wayland in CI builds 2021-12-13 00:23:52 -06:00
45 changed files with 645 additions and 564 deletions
+1 -1
View File
@@ -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 wxwidgets sdl2 libsamplerate glib
brew install sound-touch portaudio wxwidgets sdl2 libsamplerate
}
if ! do-install; then
brew update
@@ -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/" \
+4 -8
View File
@@ -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)
+64
View File
@@ -9502,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"
@@ -12448,6 +12450,8 @@ SLES-52710:
SLES-52711:
name: "Titeuf Mega Compet"
region: "PAL-F"
gameFixes:
- GIFFIFOHack # Fixes corrupted textures.
patches:
958e5086:
content: |-
@@ -13131,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"
@@ -14549,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"
@@ -15650,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"
@@ -19635,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"
@@ -25753,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"
@@ -26239,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"
@@ -39431,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"
@@ -40729,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"
@@ -41007,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"
@@ -41029,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
+1 -1
View File
@@ -72,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")
+38 -36
View File
@@ -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
+1 -5
View File
@@ -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)
+19 -42
View File
@@ -1038,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);
@@ -1049,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);
@@ -1103,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.
@@ -1139,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)
{
@@ -1217,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));
@@ -1300,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)
{
@@ -1324,24 +1308,16 @@ 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
{
if (delta < cdvd.nextSectorsBuffered)
{
isSeeking = false;
}
else
{
psxRegs.interrupt &= ~(1 << IopEvt_CdvdSectorReady);
cdvd.nextSectorsBuffered = 0;
}
psxRegs.interrupt &= ~(1 << IopEvt_CdvdSectorReady);
cdvd.nextSectorsBuffered = 0;
}
}
@@ -1354,8 +1330,9 @@ static uint cdvdStartSeek(uint newsector, CDVD_MODE_TYPE mode)
CDVDSECTORREADY_INT(seektime);
seektime += (cdvd.BlockSize / 4) * 12;
}
else if(cdvd.nCommand != N_CD_SEEK)
CDVDSECTORREADY_INT(seektime + ((cdvd.BlockSize / 4) * 12));
else
CDVDSECTORREADY_INT(seektime);
return seektime;
}
@@ -1633,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);
@@ -1865,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);
@@ -1882,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);
+2 -2
View File
@@ -80,7 +80,7 @@ static void WriteIndexToFile(Access* index, const char* filename)
return;
}
auto fp = FileSystem::OpenManagedCFile(filename, "rb");
auto fp = FileSystem::OpenManagedCFile(filename, "wb");
if (!fp)
return;
@@ -300,7 +300,7 @@ bool GzippedFileReader::OkIndex()
// Try to read index from disk
const std::string indexfile(iso2indexname(m_filename));
if (indexfile.empty() == 0)
if (indexfile.empty())
return false; // iso2indexname(...) will print errors if it can't apply the template
if (FileSystem::FileExists(indexfile.c_str()) && (m_pIndex = ReadIndexFromFile(indexfile.c_str())))
+2 -1
View File
@@ -221,7 +221,8 @@ bool InputIsoFile::Open(std::string 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.
+4 -9
View File
@@ -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
@@ -205,7 +201,7 @@ set(pcsx2Headers
IopHw.h
IopMem.h
IopSio2.h
IPC.h
PINE.h
Mdec.h
MTVU.h
Memory.h
@@ -908,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
@@ -1344,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()
@@ -1414,7 +1410,6 @@ if(WIN32)
)
elseif(APPLE)
target_link_libraries(PCSX2_FLAGS INTERFACE
PkgConfig::GIO
PCAP::PCAP
LibXml2::LibXml2
)
+1 -1
View File
@@ -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,
-1
View File
@@ -1134,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";
+4 -3
View File
@@ -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);
}
+7 -2
View File
@@ -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)
+42 -26
View File
@@ -66,9 +66,7 @@ GSDevice::GSDevice()
GSDevice::~GSDevice()
{
for (auto t : m_pool)
delete t;
PurgePool();
delete m_backbuffer;
delete m_merge;
delete m_weavebob;
@@ -83,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;
@@ -94,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;
}
@@ -139,19 +134,44 @@ GSTexture* GSDevice::FetchSurface(GSTexture::Type type, int w, int h, GSTexture:
{
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()
@@ -214,13 +234,9 @@ 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, GSTexture::Format format)
@@ -261,7 +277,7 @@ GSTexture::Format GSDevice::GetDefaultTextureFormat(GSTexture::Type type)
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)
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);
@@ -271,7 +287,7 @@ bool GSDevice::DownloadTextureConvert(GSTexture* src, const GSVector4& sRect, co
return false;
GSVector4i dRect(0, 0, dSize.x, dSize.y);
StretchRect(src, sRect, dst, GSVector4(dRect), ps_shader);
StretchRect(src, sRect, dst, GSVector4(dRect), ps_shader, linear);
bool ret = DownloadTexture(dst, dRect, out_map);
Recycle(dst);
+1 -1
View File
@@ -234,7 +234,7 @@ public:
/// 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);
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() {}
+1 -1
View File
@@ -517,7 +517,7 @@ void GSRenderer::VSync(int field)
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);
res = m_dev->DownloadTextureConvert(current, GSVector4(0, 0, 1, 1), size, GSTexture::Format::Color, ShaderConvert::COPY, m, true);
if (res)
{
+1
View File
@@ -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);
+2 -16
View File
@@ -629,7 +629,7 @@ GSTexture* GSDevice11::CreateSurface(GSTexture::Type type, int w, int h, GSTextu
break;
}
GSTexture11* t = NULL;
GSTexture11* t = nullptr;
wil::com_ptr_nothrow<ID3D11Texture2D> texture;
HRESULT hr = m_dev->CreateTexture2D(&desc, nullptr, texture.put());
@@ -637,16 +637,7 @@ GSTexture* GSDevice11::CreateSurface(GSTexture::Type type, int w, int h, GSTextu
if (SUCCEEDED(hr))
{
t = new GSTexture11(std::move(texture), format);
switch (type)
{
case GSTexture::Type::RenderTarget:
ClearRenderTarget(t, 0);
break;
case GSTexture::Type::DepthStencil:
ClearDepth(t);
break;
}
assert(type == t->GetType());
}
else
{
@@ -656,11 +647,6 @@ GSTexture* GSDevice11::CreateSurface(GSTexture::Type type, int w, int h, GSTextu
return t;
}
GSTexture* GSDevice11::FetchSurface(GSTexture::Type type, int w, int h, GSTexture::Format format)
{
return __super::FetchSurface(type, w, h, format);
}
bool GSDevice11::DownloadTexture(GSTexture* src, const GSVector4i& rect, GSTexture::GSMap& out_map)
{
ASSERT(src);
-1
View File
@@ -397,7 +397,6 @@ private:
int m_d3d_texsize;
GSTexture* CreateSurface(GSTexture::Type type, int w, int h, GSTexture::Format format) final;
GSTexture* FetchSurface(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;
+1 -1
View File
@@ -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;
+240 -151
View File
@@ -17,8 +17,6 @@
#include "GSRendererHW.h"
#include "GS/GSGL.h"
const float GSRendererHW::SSR_UV_TOLERANCE = 1e-3f;
GSRendererHW::GSRendererHW()
: m_width(default_rt_size.x)
, m_height(default_rt_size.y)
@@ -775,6 +773,29 @@ void GSRendererHW::MergeSprite(GSTextureCache::Source* tex)
}
}
GSVector2 GSRendererHW::GetTextureScaleFactor()
{
GSVector2 scale_factor{ 1.0f, 1.0f };
if (CanUpscale())
{
const int multiplier = GetUpscaleMultiplier();
if (multiplier == 0)
{
// Custom resolution.
const GSVector4i display_rect = GetDisplayRect();
const GSVector2i requested_resolution = GetCustomResolution();
scale_factor.x = static_cast<float>(requested_resolution.x) / display_rect.width();
scale_factor.y = static_cast<float>(requested_resolution.y) / display_rect.height();
}
else
{
scale_factor.x = multiplier;
scale_factor.y = multiplier;
}
}
return scale_factor;
}
void GSRendererHW::InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r)
{
// printf("[%d] InvalidateVideoMem %d,%d - %d,%d %05x (%d)\n", (int)m_perfmon.GetFrame(), r.left, r.top, r.right, r.bottom, (int)BITBLTBUF.DBP, (int)BITBLTBUF.DPSM);
@@ -840,36 +861,32 @@ void GSRendererHW::SwSpriteRender()
const bool texture_mapping_enabled = PRIM->TME;
// Setup registers for SW rendering
GIFRegBITBLTBUF bitbltbuf = {};
const GSVector4i r = m_r;
if (texture_mapping_enabled)
{
bitbltbuf.SBP = m_context->TEX0.TBP0;
bitbltbuf.SBW = m_context->TEX0.TBW;
bitbltbuf.SPSM = m_context->TEX0.PSM;
}
bitbltbuf.DBP = m_context->FRAME.Block();
bitbltbuf.DBW = m_context->FRAME.FBW;
bitbltbuf.DPSM = m_context->FRAME.PSM;
ASSERT(m_r.x == 0 && m_r.y == 0); // No rendering region offset
ASSERT(!PRIM->TME || (abs(m_vt.m_min.t.x) <= SSR_UV_TOLERANCE && abs(m_vt.m_min.t.y) <= SSR_UV_TOLERANCE)); // No input texture offset, if any
ASSERT(!PRIM->TME || (abs(m_vt.m_max.t.x - m_r.z) <= SSR_UV_TOLERANCE && abs(m_vt.m_max.t.y - m_r.w) <= SSR_UV_TOLERANCE)); // No input texture min/mag, if any
ASSERT(!PRIM->TME || (m_vt.m_max.t.x <= (1 << m_context->TEX0.TW) && m_vt.m_max.t.y <= (1 << m_context->TEX0.TH))); // No texture UV wrap, if any
#ifndef NDEBUG
const int tw = 1 << m_context->TEX0.TW;
const int th = 1 << m_context->TEX0.TH;
const float meas_tw = m_vt.m_max.t.x - m_vt.m_min.t.x;
const float meas_th = m_vt.m_max.t.y - m_vt.m_min.t.y;
ASSERT(!PRIM->TME || (abs(meas_tw - r.width()) <= SSR_UV_TOLERANCE && abs(meas_th - r.height()) <= SSR_UV_TOLERANCE)); // No input texture min/mag, if any.
ASSERT(!PRIM->TME || (abs(m_vt.m_min.t.x) <= SSR_UV_TOLERANCE && abs(m_vt.m_min.t.y) <= SSR_UV_TOLERANCE && abs(meas_tw - tw) <= SSR_UV_TOLERANCE && abs(meas_th - th) <= SSR_UV_TOLERANCE)); // No texture UV wrap, if any.
#endif
GIFRegTRXPOS trxpos = {};
trxpos.DSAX = 0;
trxpos.DSAY = 0;
trxpos.SSAX = 0;
trxpos.SSAY = 0;
trxpos.DSAX = r.x;
trxpos.DSAY = r.y;
trxpos.SSAX = static_cast<int>(m_vt.m_min.t.x / 2) * 2; // Rounded down to closest even integer.
trxpos.SSAY = static_cast<int>(m_vt.m_min.t.y / 2) * 2;
ASSERT(r.x % 2 == 0 && r.y % 2 == 0);
GIFRegTRXREG trxreg = {};
trxreg.RRW = m_r.z;
trxreg.RRH = m_r.w;
trxreg.RRW = r.width();
trxreg.RRH = r.height();
ASSERT(r.width() % 2 == 0 && r.height() % 2 == 0);
// SW rendering code, mainly taken from GSState::Move(), TRXPOS.DIR{X,Y} management excluded
@@ -880,20 +897,16 @@ void GSRendererHW::SwSpriteRender()
const int w = trxreg.RRW;
const int h = trxreg.RRH;
GL_INS("SwSpriteRender: Dest 0x%x W:%d F:%s, size(%d %d)", bitbltbuf.DBP, bitbltbuf.DBW, psm_str(bitbltbuf.DPSM), w, h);
GL_INS("SwSpriteRender: Dest 0x%x W:%d F:%s, size(%d %d)", m_context->FRAME.Block(), m_context->FRAME.FBW, psm_str(m_context->FRAME.PSM), w, h);
if (texture_mapping_enabled)
InvalidateLocalMem(bitbltbuf, GSVector4i(sx, sy, sx + w, sy + h));
InvalidateVideoMem(bitbltbuf, GSVector4i(dx, dy, dx + w, dy + h));
GSOffset spo = texture_mapping_enabled ? m_mem.GetOffset(bitbltbuf.SBP, bitbltbuf.SBW, bitbltbuf.SPSM) : GSOffset();
GSOffset dpo = m_mem.GetOffset(bitbltbuf.DBP, bitbltbuf.DBW, bitbltbuf.DPSM);
const GSOffset& spo = m_context->offset.tex;
const GSOffset& dpo = m_context->offset.fb;
const bool alpha_blending_enabled = PRIM->ABE;
const GSVertex& v = m_vertex.buff[m_index.buff[m_index.tail - 1]]; // Last vertex.
const GSVector4i vc = GSVector4i(v.RGBAQ.R, v.RGBAQ.G, v.RGBAQ.B, v.RGBAQ.A) // 0x000000AA000000BB000000GG000000RR
.ps32(); // 0x00AA00BB00GG00RR00AA00BB00GG00RR
.ps32(); // 0x00AA00BB00GG00RR00AA00BB00GG00RR
const GSVector4i a_mask = GSVector4i::xff000000().u8to16(); // 0x00FF00000000000000FF000000000000
@@ -902,28 +915,36 @@ void GSRendererHW::SwSpriteRender()
const u8 tex0_tfx = m_context->TEX0.TFX;
const u8 tex0_tcc = m_context->TEX0.TCC;
const u8 alpha_a = m_context->ALPHA.A;
const u8 alpha_b = m_context->ALPHA.B;
const u8 alpha_c = m_context->ALPHA.C;
const u8 alpha_d = m_context->ALPHA.D;
const u8 alpha_fix = m_context->ALPHA.FIX;
if (texture_mapping_enabled)
m_tc->InvalidateLocalMem(spo, GSVector4i(sx, sy, sx + w, sy + h));
constexpr bool invalidate_local_mem_before_fb_read = false;
if (invalidate_local_mem_before_fb_read && (alpha_blending_enabled || fb_mask_enabled))
m_tc->InvalidateLocalMem(dpo, m_r);
for (int y = 0; y < h; y++, ++sy, ++dy)
{
auto spa = texture_mapping_enabled ? spo.paMulti(m_mem.m_vm32, sx, sy) : GSOffset::PAPtrHelper<u32>();
auto dpa = dpo.paMulti(m_mem.m_vm32, dx, dy);
const auto& spa = spo.paMulti(m_mem.m_vm32, sx, sy);
const auto& dpa = dpo.paMulti(m_mem.m_vm32, dx, dy);
ASSERT(w % 2 == 0);
for (int x = 0; x < w; x += 2)
{
u32* di = dpa.value(x);
ASSERT(*di + 1 == *dpa.value(x + 1)); // Destination pixel pair is adjacent in memory
ASSERT(di + 1 == dpa.value(x + 1)); // Destination pixel pair is adjacent in memory
GSVector4i sc;
if (texture_mapping_enabled)
{
u32* si = spa.value(x);
const u32* si = spa.value(x);
// Read 2 source pixel colors
ASSERT((*si + 1) == *spa.value(x + 1)); // Source pixel pair is adjacent in memory
ASSERT(si + 1 == spa.value(x + 1)); // Source pixel pair is adjacent in memory
sc = GSVector4i::loadl(si).u8to16(); // 0x00AA00BB00GG00RR00aa00bb00gg00rr
// Apply TFX
@@ -951,31 +972,14 @@ void GSRendererHW::SwSpriteRender()
if (alpha_blending_enabled)
{
// Blending
ASSERT(m_context->ALPHA.A == 0);
ASSERT(alpha_b == 1 || alpha_b == 2);
ASSERT(m_context->ALPHA.D == 1);
// Flag C
GSVector4i sc_alpha_vec;
if (alpha_c == 2)
sc_alpha_vec = GSVector4i(alpha_fix).xxxx().ps32();
else
sc_alpha_vec = (alpha_c == 0 ? sc : dc0)
.yyww() // 0x00AA00BB00AA00BB00aa00bb00aa00bb
.srl32(16) // 0x000000AA000000AA000000aa000000aa
.ps32() // 0x00AA00AA00aa00aa00AA00AA00aa00aa
.xxyy(); // 0x00AA00AA00AA00AA00aa00aa00aa00aa
switch (alpha_b)
{
case 1:
dc = sc.sub16(dc0).mul16l(sc_alpha_vec).sra16(7).add16(dc0); // (((Cs - Cd) * C) >> 7) + Cd, must use sra16 due to signed 16 bit values
break;
default:
dc = sc.mul16l(sc_alpha_vec).sra16(7).add16(dc0); // (((Cs - 0) * C) >> 7) + Cd, must use sra16 due to signed 16 bit values
break;
}
const GSVector4i A = alpha_a == 0 ? sc : alpha_a == 1 ? dc0 : GSVector4i::zero();
const GSVector4i B = alpha_b == 0 ? sc : alpha_b == 1 ? dc0 : GSVector4i::zero();
const GSVector4i C = alpha_c == 2 ? GSVector4i(alpha_fix).xxxx().ps32() : (alpha_c == 0 ? sc : dc0).yyww() // 0x00AA00BB00AA00BB00aa00bb00aa00bb
.srl32(16) // 0x000000AA000000AA000000aa000000aa
.ps32() // 0x00AA00AA00aa00aa00AA00AA00aa00aa
.xxyy(); // 0x00AA00AA00AA00AA00aa00aa00aa00aa
const GSVector4i D = alpha_d == 0 ? sc : alpha_d == 1 ? dc0 : GSVector4i::zero();
dc = A.sub16(B).mul16l(C).sra16(7).add16(D); // (((A - B) * C) >> 7) + D, must use sra16 due to signed 16 bit values.
// dc alpha channels (dc.u16[3], dc.u16[7]) dirty
}
else
@@ -1003,16 +1007,21 @@ void GSRendererHW::SwSpriteRender()
GSVector4i::storel(di, dc);
}
}
m_tc->InvalidateVideoMem(dpo, m_r);
}
bool GSRendererHW::CanUseSwSpriteRender(bool allow_64x64_sprite)
bool GSRendererHW::CanUseSwSpriteRender()
{
const bool r_0_0_64_64 = allow_64x64_sprite ? (m_r == GSVector4i(0, 0, 64, 64)).alltrue() : false;
if (r_0_0_64_64 && !allow_64x64_sprite) // Rendering region 64x64 support is enabled via parameter
return false;
const bool r_0_0_16_16 = (m_r == GSVector4i(0, 0, 16, 16)).alltrue();
if (!r_0_0_16_16 && !r_0_0_64_64) // Rendering region is 16x16 or 64x64, without offset
return false;
const GSVector4i r = m_r;
if (r.x % 2 != 0 || r.y % 2 != 0)
return false; // Even offset.
const int w = r.width();
const int h = r.height();
if (w % 2 != 0 || h % 2 != 0)
return false; // Even size.
if (w > 64 || h > 64)
return false; // Small draw.
if (PRIM->PRIM != GS_SPRITE
&& ((PRIM->IIP && m_vt.m_eq.rgba != 0xffff)
|| (PRIM->TME && !PRIM->FST && m_vt.m_eq.q != 0x1)
@@ -1020,7 +1029,7 @@ bool GSRendererHW::CanUseSwSpriteRender(bool allow_64x64_sprite)
return false;
if (m_vt.m_primclass != GS_TRIANGLE_CLASS && m_vt.m_primclass != GS_SPRITE_CLASS) // Triangle or sprite class prims
return false;
if (PRIM->PRIM != GS_TRIANGLESTRIP && PRIM->PRIM != GS_SPRITE) // Triangle strip or sprite draw
if (PRIM->PRIM != GS_TRIANGLESTRIP && PRIM->PRIM != GS_SPRITE) // Triangle strip or sprite draw
return false;
if (m_vt.m_primclass == GS_TRIANGLE_CLASS && (PRIM->PRIM != GS_TRIANGLESTRIP || m_vertex.tail != 4)) // If triangle class, strip draw with 4 vertices (two prims, emulating single sprite prim)
return false;
@@ -1037,15 +1046,18 @@ bool GSRendererHW::CanUseSwSpriteRender(bool allow_64x64_sprite)
if (m_context->TEX0.PSM != PSM_PSMCT32) // Input texture format is 32 bit color
return false;
if (IsMipMapDraw()) // No mipmapping
return false;
if (abs(m_vt.m_min.t.x) > SSR_UV_TOLERANCE || abs(m_vt.m_min.t.y) > SSR_UV_TOLERANCE) // No horizontal nor vertical offset
return false;
if (abs(m_vt.m_max.t.x - m_r.z) > SSR_UV_TOLERANCE || abs(m_vt.m_max.t.y - m_r.w) > SSR_UV_TOLERANCE) // No texture width or height mag/min
if (IsMipMapDraw()) // No mipmapping.
return false;
const int tw = 1 << m_context->TEX0.TW;
const int th = 1 << m_context->TEX0.TH;
if (m_vt.m_max.t.x > tw || m_vt.m_max.t.y > th) // No UV wrapping
const float meas_tw = m_vt.m_max.t.x - m_vt.m_min.t.x;
const float meas_th = m_vt.m_max.t.y - m_vt.m_min.t.y;
if (abs(m_vt.m_min.t.x) > SSR_UV_TOLERANCE ||
abs(m_vt.m_min.t.y) > SSR_UV_TOLERANCE ||
abs(meas_tw - tw) > SSR_UV_TOLERANCE ||
abs(meas_th - th) > SSR_UV_TOLERANCE) // No UV wrapping.
return false;
if (abs(meas_tw - w) > SSR_UV_TOLERANCE || abs(meas_th - h) > SSR_UV_TOLERANCE) // No texture width or height mag/min.
return false;
}
@@ -1272,8 +1284,8 @@ void GSRendererHW::Draw()
TEX0.TBW = context->FRAME.FBW;
TEX0.PSM = context->FRAME.PSM;
GSTextureCache::Target* rt = NULL;
GSTexture* rt_tex = NULL;
GSTextureCache::Target* rt = nullptr;
GSTexture* rt_tex = nullptr;
if (!no_rt)
{
rt = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::RenderTarget, true, fm);
@@ -1284,8 +1296,8 @@ void GSRendererHW::Draw()
TEX0.TBW = context->FRAME.FBW;
TEX0.PSM = context->ZBUF.PSM;
GSTextureCache::Target* ds = NULL;
GSTexture* ds_tex = NULL;
GSTextureCache::Target* ds = nullptr;
GSTexture* ds_tex = nullptr;
if (!no_ds)
{
ds = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::DepthStencil, context->DepthWrite());
@@ -1468,6 +1480,41 @@ void GSRendererHW::Draw()
rt->m_32_bits_fmt = m_texture_shuffle || (GSLocalMemory::m_psm[context->FRAME.PSM].bpp != 16);
}
// The rectangle of the draw
m_r = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(GSVector4i(context->scissor.in));
{
const GSVector2 up_s = GetTextureScaleFactor();
const int up_w = static_cast<int>(std::ceil(static_cast<float>(m_r.z) * up_s.x));
const int up_h = static_cast<int>(std::ceil(static_cast<float>(m_r.w) * up_s.y));
const int new_w = std::max(up_w, std::max(rt_tex ? rt_tex->GetWidth() : 0, ds_tex ? ds_tex->GetWidth() : 0));
const int new_h = std::max(up_h, std::max(rt_tex ? rt_tex->GetHeight() : 0, ds_tex ? ds_tex->GetHeight() : 0));
std::array<GSTextureCache::Target*, 2> ts{ rt, ds };
for (GSTextureCache::Target* t : ts)
{
if (t)
{
// Adjust texture size to fit current draw if necessary.
GSTexture* tex = t->m_texture;
assert(up_s == tex->GetScale());
const int w = tex->GetWidth();
const int h = tex->GetHeight();
if (w != new_w || h != new_h)
{
const bool is_rt = t == rt;
t->m_texture = is_rt ?
m_dev->CreateSparseRenderTarget(new_w, new_h, tex->GetFormat()) :
m_dev->CreateSparseDepthStencil(new_w, new_h, tex->GetFormat());
const GSVector4i r{ 0, 0, w, h };
m_dev->CopyRect(tex, t->m_texture, r);
m_dev->Recycle(tex);
t->m_texture->SetScale(up_s);
(is_rt ? rt_tex : ds_tex) = t->m_texture;
}
}
}
}
if (s_dump)
{
const u64 frame = m_perfmon.GetFrame();
@@ -1505,8 +1552,8 @@ void GSRendererHW::Draw()
{
s = format("%05d_f%lld_rt0_%05x_%s.bmp", s_n, frame, context->FRAME.Block(), psm_str(context->FRAME.PSM));
if (rt)
rt->m_texture->Save(m_dump_root + s);
if (rt_tex)
rt_tex->Save(m_dump_root + s);
}
if (s_savez && s_n >= s_saven)
@@ -1518,9 +1565,6 @@ void GSRendererHW::Draw()
}
}
// The rectangle of the draw
m_r = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(GSVector4i(context->scissor.in));
if (m_hacks.m_oi && !(this->*m_hacks.m_oi)(rt_tex, ds_tex, m_src))
{
GL_INS("Warning skipping a draw call (%d)", s_n);
@@ -1553,7 +1597,7 @@ void GSRendererHW::Draw()
// A couple of hack to avoid upscaling issue. So far it seems to impacts mostly sprite
// Note: first hack corrects both position and texture coordinate
// Note: second hack corrects only the texture coordinate
if ((m_upscale_multiplier > 1) && (m_vt.m_primclass == GS_SPRITE_CLASS))
if (CanUpscale() && (m_vt.m_primclass == GS_SPRITE_CLASS))
{
const size_t count = m_vertex.next;
GSVertex* v = &m_vertex.buff[0];
@@ -1611,18 +1655,6 @@ void GSRendererHW::Draw()
//
// Help to detect rendering outside of the framebuffer
#if _DEBUG
if (m_upscale_multiplier * m_r.z > m_width)
{
GL_INS("ERROR: RT width is too small only %d but require %d", m_width, m_upscale_multiplier * m_r.z);
}
if (m_upscale_multiplier * m_r.w > m_height)
{
GL_INS("ERROR: RT height is too small only %d but require %d", m_height, m_upscale_multiplier * m_r.w);
}
#endif
if (fm != 0xffffffff && rt)
{
//rt->m_valid = rt->m_valid.runion(r);
@@ -1660,8 +1692,8 @@ void GSRendererHW::Draw()
{
s = format("%05d_f%lld_rt1_%05x_%s.bmp", s_n, frame, context->FRAME.Block(), psm_str(context->FRAME.PSM));
if (rt)
rt->m_texture->Save(m_dump_root + s);
if (rt_tex)
rt_tex->Save(m_dump_root + s);
}
if (s_savez && s_n >= s_saven)
@@ -1708,7 +1740,14 @@ GSRendererHW::Hacks::Hacks()
m_oi_list.push_back(HackEntry<OI_Ptr>(CRC::Jak3, CRC::RegionCount, &GSRendererHW::OI_JakGames));
m_oi_list.push_back(HackEntry<OI_Ptr>(CRC::JakX, CRC::RegionCount, &GSRendererHW::OI_JakGames));
m_oi_list.push_back(HackEntry<OI_Ptr>(CRC::BurnoutTakedown, CRC::RegionCount, &GSRendererHW::OI_BurnoutGames));
m_oi_list.push_back(HackEntry<OI_Ptr>(CRC::BurnoutRevenge, CRC::RegionCount, &GSRendererHW::OI_BurnoutGames));
m_oi_list.push_back(HackEntry<OI_Ptr>(CRC::BurnoutDominator, CRC::RegionCount, &GSRendererHW::OI_BurnoutGames));
m_oo_list.push_back(HackEntry<OO_Ptr>(CRC::MajokkoALaMode2, CRC::RegionCount, &GSRendererHW::OO_MajokkoALaMode2));
m_oo_list.push_back(HackEntry<OO_Ptr>(CRC::BurnoutTakedown, CRC::RegionCount, &GSRendererHW::OO_BurnoutGames));
m_oo_list.push_back(HackEntry<OO_Ptr>(CRC::BurnoutRevenge, CRC::RegionCount, &GSRendererHW::OO_BurnoutGames));
m_oo_list.push_back(HackEntry<OO_Ptr>(CRC::BurnoutDominator, CRC::RegionCount, &GSRendererHW::OO_BurnoutGames));
m_cu_list.push_back(HackEntry<CU_Ptr>(CRC::MajokkoALaMode2, CRC::RegionCount, &GSRendererHW::CU_MajokkoALaMode2));
m_cu_list.push_back(HackEntry<CU_Ptr>(CRC::TalesOfAbyss, CRC::RegionCount, &GSRendererHW::CU_TalesOfAbyss));
@@ -1968,8 +2007,11 @@ bool GSRendererHW::OI_DBZBTGames(GSTexture* rt, GSTexture* ds, GSTextureCache::S
if (t && t->m_from_target) // Avoid slow framebuffer readback
return true;
if (!((m_r == GSVector4i(0, 0, 16, 16)).alltrue() || (m_r == GSVector4i(0, 0, 64, 64)).alltrue()))
return true; // Only 16x16 or 64x64 draws.
// Sprite rendering
if (!CanUseSwSpriteRender(true))
if (!CanUseSwSpriteRender())
return true;
SwSpriteRender();
@@ -2192,60 +2234,52 @@ bool GSRendererHW::OI_SonicUnleashed(GSTexture* rt, GSTexture* ds, GSTextureCach
bool GSRendererHW::OI_PointListPalette(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t)
{
if (m_vt.m_primclass == GS_POINT_CLASS && !PRIM->TME)
const size_t n_vertices = m_vertex.next;
const int w = m_r.width();
const int h = m_r.height();
if (m_vt.m_primclass == GS_POINT_CLASS && w <= 64 // Small draws.
&& h <= 64 // Small draws.
&& n_vertices <= 256 // Small draws.
&& PRIM->ABE // Alpha blending.
&& !PRIM->TME // No texturing please.
&& m_context->FRAME.PSM == PSM_PSMCT32 // Only 32-bit pixel format (CLUT format).
&& !PRIM->FGE // No FOG.
&& !PRIM->AA1 // No antialiasing.
&& !PRIM->FIX // Normal fragment value control.
&& !m_env.DTHE.DTHE // No dithering.
&& !m_context->TEST.ATE // No alpha test.
&& !m_context->TEST.DATE // No destination alpha test.
&& (!m_context->DepthRead() && !m_context->DepthWrite()) // No depth handling.
&& !m_context->TEX0.CSM // No CLUT usage.
&& !m_env.PABE.PABE // No PABE.
&& m_context->FBA.FBA == 0 // No Alpha Correction.
&& m_context->FRAME.FBMSK == 0 // No frame buffer masking.
&& m_context->ALPHA.A == m_context->ALPHA.B // (A - B) == 0 in blending equation, makes C value irrelevant.
&& m_context->ALPHA.D == 0 // Copy source RGB(A) color into frame buffer.
)
{
const u32 FBP = m_context->FRAME.Block();
const u32 FBW = m_context->FRAME.FBW;
if (FBP >= 0x03f40 && (FBP & 0x1f) == 0)
GL_INS("PointListPalette - m_r = <%d, %d => %d, %d>, n_vertices = %zu, FBP = 0x%x, FBW = %u", m_r.x, m_r.y, m_r.z, m_r.w, n_vertices, FBP, FBW);
const GSVertex* RESTRICT v = m_vertex.buff;
const int ox(m_context->XYOFFSET.OFX);
const int oy(m_context->XYOFFSET.OFY);
for (size_t i = 0; i < n_vertices; ++i)
{
if (m_vertex.next == 16)
{
GSVertex* RESTRICT v = m_vertex.buff;
for (int i = 0; i < 16; i++, v++)
{
u32 c = v->RGBAQ.U32[0];
const u32 a = c >> 24;
c = (a >= 0x80 ? 0xff000000 : (a << 25)) | (c & 0x00ffffff);
v->RGBAQ.U32[0] = c;
m_mem.WritePixel32(i & 7, i >> 3, c, FBP, FBW);
}
m_mem.m_clut.Invalidate();
return false;
}
else if (m_vertex.next == 256)
{
GSVertex* RESTRICT v = m_vertex.buff;
for (int i = 0; i < 256; i++, v++)
{
u32 c = v->RGBAQ.U32[0];
const u32 a = c >> 24;
c = (a >= 0x80 ? 0xff000000 : (a << 25)) | (c & 0x00ffffff);
v->RGBAQ.U32[0] = c;
m_mem.WritePixel32(i & 15, i >> 4, c, FBP, FBW);
}
m_mem.m_clut.Invalidate();
return false;
}
else
{
ASSERT(0);
}
const GSVertex& vi = v[i];
const GIFRegXYZ& xyz = vi.XYZ;
const int x = (int(xyz.X) - ox) / 16;
const int y = (int(xyz.Y) - oy) / 16;
if (x < m_r.x || x > m_r.z)
continue;
if (y < m_r.y || y > m_r.w)
continue;
const u32 c = vi.RGBAQ.U32[0];
m_mem.WritePixel32(x, y, c, FBP, FBW);
}
m_tc->InvalidateVideoMem(m_context->offset.fb, m_r);
return false;
}
return true;
}
@@ -2315,7 +2349,10 @@ bool GSRendererHW::OI_ArTonelico2(GSTexture* rt, GSTexture* ds, GSTextureCache::
bool GSRendererHW::OI_JakGames(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t)
{
if (!CanUseSwSpriteRender(false))
if (!(m_r == GSVector4i(0, 0, 16, 16)).alltrue())
return true; // Only 16x16 draws.
if (!CanUseSwSpriteRender())
return true;
// Render 16x16 palette via CPU.
@@ -2324,6 +2361,23 @@ bool GSRendererHW::OI_JakGames(GSTexture* rt, GSTexture* ds, GSTextureCache::Sou
return false; // Skip current draw.
}
bool GSRendererHW::OI_BurnoutGames(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t)
{
if (!OI_PointListPalette(rt, ds, t))
return false; // Render point list palette.
if (t && t->m_from_target) // Avoid slow framebuffer readback
return true;
if (!CanUseSwSpriteRender())
return true;
// Render palette via CPU.
SwSpriteRender();
return false;
}
// OO (others output?) hacks: invalidate extra local memory after the draw call
void GSRendererHW::OO_MajokkoALaMode2()
@@ -2344,6 +2398,41 @@ void GSRendererHW::OO_MajokkoALaMode2()
}
}
void GSRendererHW::OO_BurnoutGames()
{
const GIFRegTEX0& TEX0 = m_context->TEX0;
const GIFRegALPHA& ALPHA = m_context->ALPHA;
const GIFRegFRAME& FRAME = m_context->FRAME;
if (PRIM->PRIM == GS_SPRITE
&& !PRIM->IIP
&& PRIM->TME
&& !PRIM->FGE
&& PRIM->ABE
&& !PRIM->AA1
&& !PRIM->FST
&& !PRIM->FIX
&& TEX0.TBW == 16
&& TEX0.TW == 10
&& TEX0.TCC
&& !TEX0.TFX
&& TEX0.PSM == PSM_PSMT8
&& TEX0.CPSM == PSM_PSMCT32
&& !TEX0.CSM
&& TEX0.TH == 8
&& ALPHA.A == ALPHA.B
&& ALPHA.D == 0
&& FRAME.FBW == 16
&& FRAME.PSM == PSM_PSMCT32)
{
// Readback clouds being rendered during level loading.
// Later the alpha channel from the 32 bit frame buffer is used as an 8 bit indexed texture to draw
// the clouds on top of the sky at each frame.
// Burnout 3 PAL 50Hz: 0x3ba0 => 0x1e80.
GL_INS("OO_BurnoutGames - Readback clouds renderered from TEX0.TBP0 = 0x%04x (TEX0.CBP = 0x%04x) to FBP = 0x%04x", TEX0.TBP0, TEX0.CBP, FRAME.Block());
m_tc->InvalidateLocalMem(m_context->offset.fb, m_r);
}
}
// Can Upscale hacks: disable upscaling for some draw calls
bool GSRendererHW::CU_MajokkoALaMode2()
+5 -2
View File
@@ -35,7 +35,7 @@ private:
bool m_userhacks_enabled_gs_mem_clear;
bool m_userHacks_merge_sprite;
static const float SSR_UV_TOLERANCE;
static constexpr float SSR_UV_TOLERANCE = 1.0f;
#pragma region hacks
@@ -59,8 +59,10 @@ private:
bool OI_SuperManReturns(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t);
bool OI_ArTonelico2(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t);
bool OI_JakGames(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t);
bool OI_BurnoutGames(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t);
void OO_MajokkoALaMode2();
void OO_BurnoutGames();
bool CU_MajokkoALaMode2();
bool CU_TalesOfAbyss();
@@ -136,7 +138,7 @@ private:
float alpha0(int L, int X0, int X1);
float alpha1(int L, int X0, int X1);
void SwSpriteRender();
bool CanUseSwSpriteRender(bool allow_64x64_sprite);
bool CanUseSwSpriteRender();
template <bool linear>
void RoundSpriteOffset();
@@ -179,6 +181,7 @@ public:
GSVector4 RealignTargetTextureCoordinate(const GSTextureCache::Source* tex);
GSVector4i ComputeBoundingBox(const GSVector2& rtscale, const GSVector2i& rtsize);
void MergeSprite(GSTextureCache::Source* tex);
GSVector2 GetTextureScaleFactor();
void Reset();
void VSync(int field);
+19 -26
View File
@@ -498,24 +498,8 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con
void GSTextureCache::ScaleTexture(GSTexture* texture)
{
if (!m_renderer->CanUpscale())
return;
float multiplier = static_cast<float>(m_renderer->GetUpscaleMultiplier());
bool custom_resolution = (multiplier == 0);
GSVector2 scale_factor(multiplier);
if (custom_resolution)
{
int width = m_renderer->GetDisplayRect().width();
int height = m_renderer->GetDisplayRect().height();
GSVector2i requested_resolution = m_renderer->GetCustomResolution();
scale_factor.x = static_cast<float>(requested_resolution.x) / width;
scale_factor.y = static_cast<float>(requested_resolution.y) / height;
}
texture->SetScale(scale_factor);
if (texture)
texture->SetScale(m_renderer->GetTextureScaleFactor());
}
bool GSTextureCache::ShallSearchTextureInsideRt()
@@ -582,22 +566,31 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, int
if (dst_match)
{
GSVector4 sRect(0, 0, 1, 1);
GSVector4 dRect(0, 0, w, h);
const GSVector2& new_s = m_renderer->GetTextureScaleFactor();
const GSVector2& old_s = dst_match->m_texture->GetScale();
const GSVector2 ratio{ new_s.x / old_s.x, new_s.y / old_s.y };
const int old_w = dst_match->m_texture->GetWidth();
const int old_h = dst_match->m_texture->GetHeight();
const float res_w = static_cast<float>(old_w) * ratio.x;
const float res_h = static_cast<float>(old_h) * ratio.y;
const int new_w = std::max(static_cast<int>(std::ceil(res_w)), w);
const int new_h = std::max(static_cast<int>(std::ceil(res_h)), h);
const GSVector4 sRect(0, 0, 1, 1);
const GSVector4 dRect(0.0f, 0.0f, res_w, res_h);
dst = CreateTarget(TEX0, w, h, type);
dst = CreateTarget(TEX0, new_w, new_h, type);
dst->m_32_bits_fmt = dst_match->m_32_bits_fmt;
ShaderConvert shader;
bool fmt_16_bits = (psm_s.bpp == 16 && GSLocalMemory::m_psm[dst_match->m_TEX0.PSM].bpp == 16);
if (type == DepthStencil)
{
GL_CACHE("TC: Lookup Target(Depth) %dx%d, hit Color (0x%x, %s was %s)", w, h, bp, psm_str(TEX0.PSM), psm_str(dst_match->m_TEX0.PSM));
GL_CACHE("TC: Lookup Target(Depth) %dx%d, hit Color (0x%x, %s was %s)", new_w, new_h, bp, psm_str(TEX0.PSM), psm_str(dst_match->m_TEX0.PSM));
shader = (fmt_16_bits) ? ShaderConvert::RGB5A1_TO_FLOAT16 : (ShaderConvert)((int)ShaderConvert::RGBA8_TO_FLOAT32 + psm_s.fmt);
}
else
{
GL_CACHE("TC: Lookup Target(Color) %dx%d, hit Depth (0x%x, %s was %s)", w, h, bp, psm_str(TEX0.PSM), psm_str(dst_match->m_TEX0.PSM));
GL_CACHE("TC: Lookup Target(Color) %dx%d, hit Depth (0x%x, %s was %s)", new_w, new_h, bp, psm_str(TEX0.PSM), psm_str(dst_match->m_TEX0.PSM));
shader = (fmt_16_bits) ? ShaderConvert::FLOAT16_TO_RGB5A1 : ShaderConvert::FLOAT32_TO_RGBA8;
}
m_renderer->m_dev->StretchRect(dst_match->m_texture, sRect, dst->m_texture, dRect, shader, false);
@@ -1700,7 +1693,7 @@ void GSTextureCache::Read(Target* t, const GSVector4i& r)
GL_PERF("TC: Read Back Target: %d (0x%x)[fmt: 0x%x]. Size %dx%d",
t->m_texture->GetID(), TEX0.TBP0, TEX0.PSM, r.width(), r.height());
GSVector4 src = GSVector4(r) * GSVector4(t->m_texture->GetScale()).xyxy() / GSVector4(t->m_texture->GetSize()).xyxy();
const GSVector4 src = GSVector4(r) * GSVector4(t->m_texture->GetScale()).xyxy() / GSVector4(t->m_texture->GetSize()).xyxy();
bool res;
GSTexture::GSMap m;
@@ -1708,11 +1701,11 @@ void GSTextureCache::Read(Target* t, const GSVector4i& r)
if (t->m_texture->GetScale() == GSVector2(1, 1) && ps_shader == ShaderConvert::COPY)
res = m_renderer->m_dev->DownloadTexture(t->m_texture, r, m);
else
res = m_renderer->m_dev->DownloadTextureConvert(t->m_texture, src, GSVector2i(r.width(), r.height()), fmt, ps_shader, m);
res = m_renderer->m_dev->DownloadTextureConvert(t->m_texture, src, GSVector2i(r.width(), r.height()), fmt, ps_shader, m, false);
if (res)
{
GSOffset off = m_renderer->m_mem.GetOffset(TEX0.TBP0, TEX0.TBW, TEX0.PSM);
const GSOffset off = m_renderer->m_mem.GetOffset(TEX0.TBP0, TEX0.TBW, TEX0.PSM);
switch (TEX0.PSM)
{
+2 -64
View File
@@ -49,8 +49,7 @@ int GSDeviceOGL::m_shader_reg = 0;
FILE* GSDeviceOGL::m_debug_gl_file = NULL;
GSDeviceOGL::GSDeviceOGL()
: m_force_texture_clear(0)
, m_fbo(0)
: m_fbo(0)
, m_fbo_read(0)
, m_apitrace(0)
, m_palette_ss(0)
@@ -238,68 +237,9 @@ GSTexture* GSDeviceOGL::CreateSurface(GSTexture::Type type, int w, int h, GSText
{
GL_PUSH("Create surface");
// A wrapper to call GSTextureOGL, with the different kind of parameter
// A wrapper to call GSTextureOGL, with the different kind of parameters.
GSTextureOGL* t = new GSTextureOGL(type, w, h, fmt, m_fbo_read, m_mipmap > 1 || m_filter != TriFiltering::None);
// NOTE: I'm not sure RenderTarget always need to be cleared. It could be costly for big upscale.
// FIXME: it will be more logical to do it in FetchSurface. This code is only called at first creation
// of the texture. However we could reuse a deleted texture.
if (m_force_texture_clear == 0)
{
// Clear won't be done if the texture isn't committed. Commit the full texture to ensure
// correct behavior of force clear option (debug option)
t->Commit();
switch (type)
{
case GSTexture::Type::RenderTarget:
ClearRenderTarget(t, 0);
break;
case GSTexture::Type::DepthStencil:
ClearDepth(t);
// No need to clear the stencil now.
break;
default:
break;
}
}
return t;
}
GSTexture* GSDeviceOGL::FetchSurface(GSTexture::Type type, int w, int h, GSTexture::Format format)
{
GSTexture* t = GSDevice::FetchSurface(type, w, h, format);
if (m_force_texture_clear)
{
// Clear won't be done if the texture isn't committed. Commit the full texture to ensure
// correct behavior of force clear option (debug option)
t->Commit();
const GSVector4 red(1.0f, 0.0f, 0.0f, 1.0f);
switch (type)
{
case GSTexture::Type::RenderTarget:
ClearRenderTarget(t, 0);
break;
case GSTexture::Type::DepthStencil:
ClearDepth(t);
// No need to clear the stencil now.
break;
case GSTexture::Type::Texture:
if (m_force_texture_clear > 1)
static_cast<GSTextureOGL*>(t)->Clear((void*)&red);
else if (m_force_texture_clear)
static_cast<GSTextureOGL*>(t)->Clear(NULL);
break;
default:
break;
}
}
return t;
}
@@ -346,8 +286,6 @@ bool GSDeviceOGL::Create(const WindowInfo& wi)
}
#endif
m_force_texture_clear = theApp.GetConfigI("force_texture_clear");
// WARNING it must be done after the control setup (at least on MESA)
GL_PUSH("GSDeviceOGL::Create");
-2
View File
@@ -462,7 +462,6 @@ public:
private:
std::unique_ptr<GL::Context> m_gl_context;
int m_force_texture_clear;
int m_mipmap;
TriFiltering m_filter;
@@ -559,7 +558,6 @@ private:
AlignedBuffer<u8, 32> m_download_buffer;
GSTexture* CreateSurface(GSTexture::Type type, int w, int h, GSTexture::Format format) final;
GSTexture* FetchSurface(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;
+1 -1
View File
@@ -573,7 +573,7 @@ bool GSTextureOGL::Save(const std::string& fn)
u32 pitch = 4 * m_committed_size.x;
u32 buf_size = pitch * m_committed_size.y * 2; // Note *2 for security (depth/stencil)
std::unique_ptr<u8[]> image(new u8[buf_size]);
#ifdef ENABLE_OGL_DEBUG
#ifdef PCSX2_DEVBUILD
GSPng::Format fmt = GSPng::RGB_A_PNG;
#else
GSPng::Format fmt = GSPng::RGB_PNG;
-2
View File
@@ -578,8 +578,6 @@ void GSRendererSW::Queue(GSRingHeap::SharedPtr<GSRasterizerData>& item)
if (sd->global.sel.fwrite)
{
m_tc->InvalidatePages(sd->m_fb_pages, sd->m_fpsm);
m_mem.m_clut.Invalidate(m_context->FRAME.Block());
}
if (sd->global.sel.zwrite)
+1 -1
View File
@@ -81,7 +81,7 @@ void GSTextureSW::Unmap()
bool GSTextureSW::Save(const std::string& fn)
{
#ifdef ENABLE_OGL_DEBUG
#ifdef PCSX2_DEVBUILD
GSPng::Format fmt = GSPng::RGB_A_PNG;
#else
GSPng::Format fmt = GSPng::RGB_PNG;
+68 -47
View File
@@ -40,10 +40,10 @@
#include "gui/AppCoreThread.h"
#include "System/SysThreads.h"
#include "svnrev.h"
#include "IPC.h"
#include "PINE.h"
SocketIPC::SocketIPC(SysCoreThread* vm, unsigned int slot)
: pxThread("IPC_Socket")
PINEServer::PINEServer(SysCoreThread* vm, unsigned int slot)
: pxThread("PINE_Server")
{
#ifdef _WIN32
WSADATA wsa;
@@ -52,14 +52,14 @@ SocketIPC::SocketIPC(SysCoreThread* vm, unsigned int slot)
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
Console.WriteLn(Color_Red, "IPC: Cannot initialize winsock! Shutting down...");
Console.WriteLn(Color_Red, "PINE: Cannot initialize winsock! Shutting down...");
return;
}
m_sock = socket(AF_INET, SOCK_STREAM, 0);
if ((m_sock == INVALID_SOCKET) || slot > 65536)
{
Console.WriteLn(Color_Red, "IPC: Cannot open socket! Shutting down...");
Console.WriteLn(Color_Red, "PINE: Cannot open socket! Shutting down...");
return;
}
@@ -71,7 +71,7 @@ SocketIPC::SocketIPC(SysCoreThread* vm, unsigned int slot)
if (bind(m_sock, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
{
Console.WriteLn(Color_Red, "IPC: Error while binding to socket! Shutting down...");
Console.WriteLn(Color_Red, "PINE: Error while binding to socket! Shutting down...");
return;
}
@@ -85,14 +85,14 @@ SocketIPC::SocketIPC(SysCoreThread* vm, unsigned int slot)
// fallback in case macOS or other OSes don't implement the XDG base
// spec
if (runtime_dir == nullptr)
m_socket_name = "/tmp/" IPC_EMULATOR_NAME ".sock";
m_socket_name = "/tmp/" PINE_EMULATOR_NAME ".sock";
else
{
m_socket_name = runtime_dir;
m_socket_name += "/" IPC_EMULATOR_NAME ".sock";
m_socket_name += "/" PINE_EMULATOR_NAME ".sock";
}
if (slot != IPC_DEFAULT_SLOT)
if (slot != PINE_DEFAULT_SLOT)
m_socket_name += "." + std::to_string(slot);
struct sockaddr_un server;
@@ -100,7 +100,7 @@ SocketIPC::SocketIPC(SysCoreThread* vm, unsigned int slot)
m_sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (m_sock < 0)
{
Console.WriteLn(Color_Red, "IPC: Cannot open socket! Shutting down...");
Console.WriteLn(Color_Red, "PINE: Cannot open socket! Shutting down...");
return;
}
server.sun_family = AF_UNIX;
@@ -111,7 +111,7 @@ SocketIPC::SocketIPC(SysCoreThread* vm, unsigned int slot)
unlink(m_socket_name.c_str());
if (bind(m_sock, (struct sockaddr*)&server, sizeof(struct sockaddr_un)))
{
Console.WriteLn(Color_Red, "IPC: Error while binding to socket! Shutting down...");
Console.WriteLn(Color_Red, "PINE: Error while binding to socket! Shutting down...");
return;
}
#endif
@@ -128,21 +128,21 @@ SocketIPC::SocketIPC(SysCoreThread* vm, unsigned int slot)
Start();
}
char* SocketIPC::MakeOkIPC(char* ret_buffer, uint32_t size = 5)
char* PINEServer::MakeOkIPC(char* ret_buffer, uint32_t size = 5)
{
ToArray<uint32_t>(ret_buffer, size, 0);
ret_buffer[4] = IPC_OK;
return ret_buffer;
}
char* SocketIPC::MakeFailIPC(char* ret_buffer, uint32_t size = 5)
char* PINEServer::MakeFailIPC(char* ret_buffer, uint32_t size = 5)
{
ToArray<uint32_t>(ret_buffer, size, 0);
ret_buffer[4] = IPC_FAIL;
return ret_buffer;
}
int SocketIPC::StartSocket()
int PINEServer::StartSocket()
{
m_msgsock = accept(m_sock, 0, 0);
@@ -160,7 +160,7 @@ int SocketIPC::StartSocket()
if (!(errno == ECONNABORTED || errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK))
{
#endif
fprintf(stderr, "IPC: An unrecoverable error happened! Shutting down...\n");
fprintf(stderr, "PINE: An unrecoverable error happened! Shutting down...\n");
m_end = true;
return -1;
}
@@ -168,7 +168,7 @@ int SocketIPC::StartSocket()
return 0;
}
void SocketIPC::ExecuteTaskInThread()
void PINEServer::ExecuteTaskInThread()
{
m_end = false;
@@ -216,7 +216,7 @@ void SocketIPC::ExecuteTaskInThread()
}
}
}
SocketIPC::IPCBuffer res;
PINEServer::IPCBuffer res;
// we remove 4 bytes to get the message size out of the IPC command
// size in ParseCommand.
@@ -238,7 +238,7 @@ void SocketIPC::ExecuteTaskInThread()
return;
}
SocketIPC::~SocketIPC()
PINEServer::~PINEServer()
{
m_end = true;
#ifdef _WIN32
@@ -258,7 +258,7 @@ SocketIPC::~SocketIPC()
DESTRUCTOR_CATCHALL
}
SocketIPC::IPCBuffer SocketIPC::ParseCommand(char* buf, char* ret_buffer, u32 buf_size)
PINEServer::IPCBuffer PINEServer::ParseCommand(char* buf, char* ret_buffer, u32 buf_size)
{
u32 ret_cnt = 5;
u32 buf_cnt = 0;
@@ -380,6 +380,8 @@ SocketIPC::IPCBuffer SocketIPC::ParseCommand(char* buf, char* ret_buffer, u32 bu
}
case MsgVersion:
{
if (!m_vm->HasActiveMachine())
goto error;
char version[256] = {};
if (GIT_TAGGED_COMMIT) // Nightly builds
{
@@ -391,11 +393,14 @@ SocketIPC::IPCBuffer SocketIPC::ParseCommand(char* buf, char* ret_buffer, u32 bu
{
sprintf(version, "PCSX2 %u.%u.%u-%lld", PCSX2_VersionHi, PCSX2_VersionMid, PCSX2_VersionLo, SVN_REV);
}
version[255] = 0x00;
if (!SafetyChecks(buf_cnt, 0, ret_cnt, 256, buf_size))
const u32 size = strlen(version) + 1;
version[size] = 0x00;
if (!SafetyChecks(buf_cnt, 0, ret_cnt, size + 4, buf_size))
goto error;
memcpy(&ret_buffer[ret_cnt], version, 256);
ret_cnt += 256;
ToArray(ret_buffer, size, ret_cnt);
ret_cnt += 4;
memcpy(&ret_buffer[ret_cnt], version, size);
ret_cnt += size;
break;
}
case MsgSaveState:
@@ -422,52 +427,68 @@ SocketIPC::IPCBuffer SocketIPC::ParseCommand(char* buf, char* ret_buffer, u32 bu
{
if (!m_vm->HasActiveMachine())
goto error;
if (!SafetyChecks(buf_cnt, 0, ret_cnt, 256, buf_size))
goto error;
char title[256] = {};
char* title = new char[GameInfo::gameName.size() + 1];
sprintf(title, "%s", GameInfo::gameName.ToUTF8().data());
title[255] = 0x00;
memcpy(&ret_buffer[ret_cnt], title, 256);
ret_cnt += 256;
const u32 size = strlen(title) + 1;
title[size] = 0x00;
if (!SafetyChecks(buf_cnt, 0, ret_cnt, size + 4, buf_size))
goto error;
ToArray(ret_buffer, size, ret_cnt);
ret_cnt += 4;
memcpy(&ret_buffer[ret_cnt], title, size);
ret_cnt += size;
delete[] title;
break;
}
case MsgID:
{
if (!m_vm->HasActiveMachine())
goto error;
if (!SafetyChecks(buf_cnt, 0, ret_cnt, 256, buf_size))
char* title = new char[GameInfo::gameSerial.size() + 1];
sprintf(title, "%s", GameInfo::gameSerial.ToUTF8().data());
const u32 size = strlen(title) + 1;
title[size] = 0x00;
if (!SafetyChecks(buf_cnt, 0, ret_cnt, size + 4, buf_size))
goto error;
char id[256] = {};
sprintf(id, "%s", GameInfo::gameSerial.ToUTF8().data());
id[255] = 0x00;
memcpy(&ret_buffer[ret_cnt], id, 256);
ret_cnt += 256;
ToArray(ret_buffer, size, ret_cnt);
ret_cnt += 4;
memcpy(&ret_buffer[ret_cnt], title, size);
ret_cnt += size;
delete[] title;
break;
}
case MsgUUID:
{
if (!m_vm->HasActiveMachine())
goto error;
if (!SafetyChecks(buf_cnt, 0, ret_cnt, 256, buf_size))
char* title = new char[GameInfo::gameCRC.size() + 1];
sprintf(title, "%s", GameInfo::gameCRC.ToUTF8().data());
const u32 size = strlen(title) + 1;
title[size] = 0x00;
if (!SafetyChecks(buf_cnt, 0, ret_cnt, size + 4, buf_size))
goto error;
char uuid[256] = {};
sprintf(uuid, "%s", GameInfo::gameCRC.ToUTF8().data());
uuid[255] = 0x00;
memcpy(&ret_buffer[ret_cnt], uuid, 256);
ret_cnt += 256;
ToArray(ret_buffer, size, ret_cnt);
ret_cnt += 4;
memcpy(&ret_buffer[ret_cnt], title, size);
ret_cnt += size;
delete[] title;
break;
}
case MsgGameVersion:
{
if (!m_vm->HasActiveMachine())
goto error;
if (!SafetyChecks(buf_cnt, 0, ret_cnt, 256, buf_size))
char* title = new char[GameInfo::gameVersion.size() + 1];
sprintf(title, "%s", GameInfo::gameVersion.ToUTF8().data());
const u32 size = strlen(title) + 1;
title[size] = 0x00;
if (!SafetyChecks(buf_cnt, 0, ret_cnt, size + 4, buf_size))
goto error;
char version[256] = {};
sprintf(version, "%s", GameInfo::gameVersion.ToUTF8().data());
version[255] = 0x00;
memcpy(&ret_buffer[ret_cnt], version, 256);
ret_cnt += 256;
ToArray(ret_buffer, size, ret_cnt);
ret_cnt += 4;
memcpy(&ret_buffer[ret_cnt], title, size);
ret_cnt += size;
delete[] title;
break;
}
case MsgStatus:
+27 -27
View File
@@ -13,17 +13,17 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
/* Client code example for interfacing with the IPC interface is available
* here: https://code.govanify.com/govanify/pcsx2_ipc/ */
/* A reference client implementation for interfacing with PINE is available
* here: https://code.govanify.com/govanify/pine/ */
#pragma once
// IPC uses a concept of "slot" to be able to communicate with multiple
// PINE uses a concept of "slot" to be able to communicate with multiple
// emulators at the same time, each slot should be unique to each emulator to
// allow PnP and configurable by the end user so that several runs don't
// conflict with each others
#define IPC_DEFAULT_SLOT 28011
#define IPC_EMULATOR_NAME "pcsx2"
#define PINE_DEFAULT_SLOT 28011
#define PINE_EMULATOR_NAME "pcsx2"
#include "common/PersistentThread.h"
#include "System/SysThreads.h"
@@ -35,7 +35,7 @@
using namespace Threading;
class SocketIPC : public pxThread
class PINEServer : public pxThread
{
// parent thread
typedef pxThread _parent;
@@ -89,22 +89,22 @@ protected:
*/
enum IPCCommand : unsigned char
{
MsgRead8 = 0, /**< Read 8 bit value to memory. */
MsgRead16 = 1, /**< Read 16 bit value to memory. */
MsgRead32 = 2, /**< Read 32 bit value to memory. */
MsgRead64 = 3, /**< Read 64 bit value to memory. */
MsgWrite8 = 4, /**< Write 8 bit value to memory. */
MsgWrite16 = 5, /**< Write 16 bit value to memory. */
MsgWrite32 = 6, /**< Write 32 bit value to memory. */
MsgWrite64 = 7, /**< Write 64 bit value to memory. */
MsgVersion = 8, /**< Returns PCSX2 version. */
MsgSaveState = 9, /**< Saves a savestate. */
MsgLoadState = 0xA, /**< Loads a savestate. */
MsgTitle = 0xB, /**< Returns the game title. */
MsgID = 0xC, /**< Returns the game ID. */
MsgUUID = 0xD, /**< Returns the game UUID. */
MsgGameVersion = 0xE, /**< Returns the game verion. */
MsgStatus = 0xF, /**< Returns the emulator status. */
MsgRead8 = 0, /**< Read 8 bit value to memory. */
MsgRead16 = 1, /**< Read 16 bit value to memory. */
MsgRead32 = 2, /**< Read 32 bit value to memory. */
MsgRead64 = 3, /**< Read 64 bit value to memory. */
MsgWrite8 = 4, /**< Write 8 bit value to memory. */
MsgWrite16 = 5, /**< Write 16 bit value to memory. */
MsgWrite32 = 6, /**< Write 32 bit value to memory. */
MsgWrite64 = 7, /**< Write 64 bit value to memory. */
MsgVersion = 8, /**< Returns PCSX2 version. */
MsgSaveState = 9, /**< Saves a savestate. */
MsgLoadState = 0xA, /**< Loads a savestate. */
MsgTitle = 0xB, /**< Returns the game title. */
MsgID = 0xC, /**< Returns the game ID. */
MsgUUID = 0xD, /**< Returns the game UUID. */
MsgGameVersion = 0xE, /**< Returns the game verion. */
MsgStatus = 0xF, /**< Returns the emulator status. */
MsgUnimplemented = 0xFF /**< Unimplemented IPC message. */
};
@@ -115,7 +115,7 @@ protected:
enum EmuStatus : uint32_t
{
Running = 0, /**< Game is running */
Paused = 1, /**< Game is paused */
Paused = 1, /**< Game is paused */
Shutdown = 2 /**< Game is shutdown */
};
@@ -125,7 +125,7 @@ protected:
*/
struct IPCBuffer
{
int size; /**< Size of the buffer. */
int size; /**< Size of the buffer. */
char* buffer; /**< Buffer. */
};
@@ -137,7 +137,7 @@ protected:
*/
enum IPCResult : unsigned char
{
IPC_OK = 0, /**< IPC command successfully completed. */
IPC_OK = 0, /**< IPC command successfully completed. */
IPC_FAIL = 0xFF /**< IPC command failed to complete. */
};
@@ -218,7 +218,7 @@ public:
bool m_end = true;
/* Initializers */
SocketIPC(SysCoreThread* vm, unsigned int slot = IPC_DEFAULT_SLOT);
virtual ~SocketIPC();
PINEServer(SysCoreThread* vm, unsigned int slot = PINE_DEFAULT_SLOT);
virtual ~PINEServer();
}; // class SocketIPC
+2 -2
View File
@@ -572,7 +572,7 @@ void Pcsx2Config::LoadSave(SettingsWrapper& wrap)
SettingsWrapBitBool(CdvdShareWrite);
SettingsWrapBitBool(EnablePatches);
SettingsWrapBitBool(EnableCheats);
SettingsWrapBitBool(EnableIPC);
SettingsWrapBitBool(EnablePINE);
SettingsWrapBitBool(EnableWideScreenPatches);
#ifndef DISABLE_RECORDING
SettingsWrapBitBool(EnableRecordingTools);
@@ -708,7 +708,7 @@ void Pcsx2Config::CopyConfig(const Pcsx2Config& cfg)
CdvdShareWrite = cfg.CdvdShareWrite;
EnablePatches = cfg.EnablePatches;
EnableCheats = cfg.EnableCheats;
EnableIPC = cfg.EnableIPC;
EnablePINE = cfg.EnablePINE;
EnableWideScreenPatches = cfg.EnableWideScreenPatches;
#ifndef DISABLE_RECORDING
EnableRecordingTools = cfg.EnableRecordingTools;
+8 -8
View File
@@ -29,7 +29,7 @@ extern WindowInfo g_gs_window_info;
#include "Patch.h"
#include "SysThreads.h"
#include "MTVU.h"
#include "IPC.h"
#include "PINE.h"
#include "FW.h"
#include "SPU2/spu2.h"
#include "DEV9/DEV9.h"
@@ -53,9 +53,9 @@ extern WindowInfo g_gs_window_info;
bool g_CDVDReset = false;
namespace IPCSettings
namespace PINESettings
{
unsigned int slot = IPC_DEFAULT_SLOT;
unsigned int slot = PINE_DEFAULT_SLOT;
};
// --------------------------------------------------------------------------------------
@@ -267,13 +267,13 @@ void SysCoreThread::GameStartingInThread()
#ifdef USE_SAVESLOT_UI_UPDATES
UI_UpdateSysControls();
#endif
if (EmuConfig.EnableIPC && m_IpcState == OFF)
if (EmuConfig.EnablePINE && m_PineState == OFF)
{
m_IpcState = ON;
m_socketIpc = std::make_unique<SocketIPC>(this, IPCSettings::slot);
m_PineState = ON;
m_pineServer = std::make_unique<PINEServer>(this, PINESettings::slot);
}
if (m_IpcState == ON && m_socketIpc->m_end)
m_socketIpc->Start();
if (m_PineState == ON && m_pineServer->m_end)
m_pineServer->Start();
}
bool SysCoreThread::StateCheckInThread()
+7 -7
View File
@@ -19,7 +19,7 @@
#include "common/PersistentThread.h"
#include "common/emitter/tools.h"
#include "IPC.h"
#include "PINE.h"
using namespace Threading;
@@ -185,16 +185,16 @@ protected:
bool m_resetVsyncTimers;
bool m_resetVirtualMachine;
// Stores the state of the socket IPC thread.
std::unique_ptr<SocketIPC> m_socketIpc;
// Stores the state of the PINE thread.
std::unique_ptr<PINEServer> m_pineServer;
// Current state of the IPC thread
enum StateIPC
// Current state of the PINE thread
enum StatePINE
{
OFF,
ON
};
StateIPC m_IpcState = OFF;
StatePINE m_PineState = OFF;
// Indicates if the system has an active virtual machine state. Pretty much always
// true anytime between subcomponents being initialized and being shutdown. Gets
@@ -284,7 +284,7 @@ extern SysCoreThread& GetCoreThread();
extern bool g_CDVDReset;
namespace IPCSettings
namespace PINESettings
{
extern unsigned int slot;
};
+4 -4
View File
@@ -199,10 +199,10 @@ enum MenuIdentifiers
MenuId_Recording_VirtualPad_Port1,
#endif
// IPC Subsection
MenuId_IPC,
MenuId_IPC_Enable,
MenuId_IPC_Settings,
// Subsection
MenuId_PINE,
MenuId_PINE_Enable,
MenuId_PINE_Settings,
};
+2 -2
View File
@@ -424,7 +424,7 @@ static void _ApplySettings(const Pcsx2Config& src, Pcsx2Config& fixup)
GameInfo::gameCRC = L""; // Needs to be reset when rebooting otherwise previously loaded patches may load
if (ingame && !DiscSerial.IsEmpty())
GameInfo::gameSerial = L" [" + DiscSerial + L"]";
GameInfo::gameSerial = DiscSerial;
const wxString newGameKey(ingame ? SysGetDiscID() : SysGetBiosDiscID());
const bool verbose(newGameKey != curGameKey && ingame);
@@ -512,7 +512,7 @@ static void _ApplySettings(const Pcsx2Config& src, Pcsx2Config& fixup)
// When we're booting, the bios loader will set a a title which would be more interesting than this
// to most users - with region, version, etc, so don't overwrite it with patch info. That's OK. Those
// users which want to know the status of the patches at the bios can check the console content.
wxString consoleTitle = GameInfo::gameName + GameInfo::gameSerial;
wxString consoleTitle = GameInfo::gameName + L" [" + GameInfo::gameSerial + L"]";
consoleTitle += L" [" + GameInfo::gameCRC.MakeUpper() + L"]" + gameCompat + gameFixes + gamePatch + gameCheats + gameWsHacks;
if (ingame)
Console.SetTitle(consoleTitle);
+4 -4
View File
@@ -400,14 +400,14 @@ namespace Dialogs
virtual ~AssertionDialog() = default;
};
class IPCDialog : public wxDialogWithHelpers
class PINEDialog : public wxDialogWithHelpers
{
public:
IPCDialog(wxWindow* parent = NULL);
virtual ~IPCDialog() = default;
PINEDialog(wxWindow* parent = NULL);
virtual ~PINEDialog() = default;
void OnConfirm(wxCommandEvent& evt);
static wxString GetNameStatic() { return L"IPCSettings"; }
static wxString GetNameStatic() { return L"PINESettings"; }
wxString GetDialogName() const { return GetNameStatic(); }
};
} // namespace Dialogs
@@ -26,7 +26,7 @@
#include "gui/AppConfig.h"
using namespace pxSizerFlags;
/* This dialog currently assumes the IPC server is started when launching a
/* This dialog currently assumes the PINE server is started when launching a
* game, as such we can allow the IPC Settings window to change the slot in a
* volatile fashion so that it returns to the default but you can change it at
* each restart of the emulator to allow for multiple emulator sessions.
@@ -34,25 +34,25 @@ using namespace pxSizerFlags;
*/
// --------------------------------------------------------------------------------------
// IPCDialog Implementation
// PINEDialog Implementation
// --------------------------------------------------------------------------------------
Dialogs::IPCDialog::IPCDialog(wxWindow* parent)
: wxDialogWithHelpers(parent, _("IPC Settings"), pxDialogFlags())
Dialogs::PINEDialog::PINEDialog(wxWindow* parent)
: wxDialogWithHelpers(parent, _("PINE Settings"), pxDialogFlags())
{
wxTextCtrl* ipc_slot = new wxTextCtrl(this, wxID_ANY, wxString::Format(wxT("%u"), IPCSettings::slot), wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
ipc_slot->Bind(wxEVT_TEXT_ENTER, &Dialogs::IPCDialog::OnConfirm, this);
wxTextCtrl* ipc_slot = new wxTextCtrl(this, wxID_ANY, wxString::Format(wxT("%u"), PINESettings::slot), wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
ipc_slot->Bind(wxEVT_TEXT_ENTER, &Dialogs::PINEDialog::OnConfirm, this);
*this += new wxStaticText(this, wxID_ANY, _("IPC Slot"));
*this += new wxStaticText(this, wxID_ANY, _("PINE Slot"));
*this += ipc_slot;
}
void Dialogs::IPCDialog::OnConfirm(wxCommandEvent& evt)
void Dialogs::PINEDialog::OnConfirm(wxCommandEvent& evt)
{
wxTextCtrl* obj = static_cast<wxTextCtrl*>(evt.GetEventObject());
if (obj != nullptr)
{
IPCSettings::slot = (unsigned int)atoi(obj->GetValue().ToUTF8().data());
PINESettings::slot = (unsigned int)atoi(obj->GetValue().ToUTF8().data());
Destroy();
}
}
+7 -7
View File
@@ -262,8 +262,8 @@ void MainEmuFrame::ConnectMenus()
Bind(wxEVT_MENU, &MainEmuFrame::Menu_EnablePatches_Click, this, MenuId_EnablePatches);
Bind(wxEVT_MENU, &MainEmuFrame::Menu_EnableCheats_Click, this, MenuId_EnableCheats);
Bind(wxEVT_MENU, &MainEmuFrame::Menu_IPC_Enable_Click, this, MenuId_IPC_Enable);
Bind(wxEVT_MENU, &MainEmuFrame::Menu_IPC_Settings_Click, this, MenuId_IPC_Settings);
Bind(wxEVT_MENU, &MainEmuFrame::Menu_PINE_Enable_Click, this, MenuId_PINE_Enable);
Bind(wxEVT_MENU, &MainEmuFrame::Menu_PINE_Settings_Click, this, MenuId_PINE_Settings);
Bind(wxEVT_MENU, &MainEmuFrame::Menu_EnableWideScreenPatches_Click, this, MenuId_EnableWideScreenPatches);
#ifndef DISABLE_RECORDING
Bind(wxEVT_MENU, &MainEmuFrame::Menu_EnableRecordingTools_Click, this, MenuId_EnableInputRecording);
@@ -395,12 +395,12 @@ void MainEmuFrame::CreatePcsx2Menu()
m_GameSettingsSubmenu.Append(MenuId_EnableCheats, _("Enable &Cheats"),
_("Use cheats otherwise known as pnachs from the cheats folder."), wxITEM_CHECK);
m_GameSettingsSubmenu.Append(MenuId_IPC, _("Configure &IPC"), &m_submenuIPC);
m_GameSettingsSubmenu.Append(MenuId_PINE, _("Configure &PINE"), &m_submenuPINE);
m_submenuIPC.Append(MenuId_IPC_Enable, _("&Enable IPC"),
m_submenuPINE.Append(MenuId_PINE_Enable, _("&Enable PINE"),
wxEmptyString, wxITEM_CHECK);
m_submenuIPC.Append(MenuId_IPC_Settings, _("IPC &Settings"));
m_submenuPINE.Append(MenuId_PINE_Settings, _("PINE &Settings"));
m_GameSettingsSubmenu.Append(MenuId_EnableWideScreenPatches, _("Enable &Widescreen Patches"),
_("Enabling Widescreen Patches may occasionally cause issues."), wxITEM_CHECK);
@@ -568,7 +568,7 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title)
, m_menuWindow(*new wxMenu())
, m_menuCapture(*new wxMenu())
, m_submenuVideoCapture(*new wxMenu())
, m_submenuIPC(*new wxMenu())
, m_submenuPINE(*new wxMenu())
, m_submenuScreenshot(*new wxMenu())
#ifndef DISABLE_RECORDING
, m_menuRecording(*new wxMenu())
@@ -830,7 +830,7 @@ void MainEmuFrame::ApplyConfigToGui(AppConfig& configToApply, int flags)
{ //these should not be affected by presets
menubar.Check(MenuId_EnableBackupStates, configToApply.EmuOptions.BackupSavestate);
menubar.Check(MenuId_EnableCheats, configToApply.EmuOptions.EnableCheats);
menubar.Check(MenuId_IPC_Enable, configToApply.EmuOptions.EnableIPC);
menubar.Check(MenuId_PINE_Enable, configToApply.EmuOptions.EnablePINE);
menubar.Check(MenuId_EnableWideScreenPatches, configToApply.EmuOptions.EnableWideScreenPatches);
menubar.Check(MenuId_Capture_Video_IncludeAudio, configToApply.AudioCapture.EnableAudio);
#ifndef DISABLE_RECORDING
+3 -3
View File
@@ -69,7 +69,7 @@ protected:
wxMenu& m_menuCapture;
wxMenu& m_submenuVideoCapture;
wxMenu& m_submenuIPC;
wxMenu& m_submenuPINE;
wxMenu& m_submenuScreenshot;
#ifndef DISABLE_RECORDING
@@ -165,8 +165,8 @@ protected:
void Menu_EnableBackupStates_Click(wxCommandEvent& event);
void Menu_EnablePatches_Click(wxCommandEvent& event);
void Menu_EnableCheats_Click(wxCommandEvent& event);
void Menu_IPC_Enable_Click(wxCommandEvent& event);
void Menu_IPC_Settings_Click(wxCommandEvent& event);
void Menu_PINE_Enable_Click(wxCommandEvent& event);
void Menu_PINE_Settings_Click(wxCommandEvent& event);
void Menu_EnableWideScreenPatches_Click(wxCommandEvent& event);
#ifndef DISABLE_RECORDING
void Menu_EnableRecordingTools_Click(wxCommandEvent& event);
+4 -4
View File
@@ -54,9 +54,9 @@ void MainEmuFrame::Menu_SysSettings_Click(wxCommandEvent& event)
AppOpenModalDialog<SysConfigDialog>(wxEmptyString, this);
}
void MainEmuFrame::Menu_IPC_Settings_Click(wxCommandEvent& event)
void MainEmuFrame::Menu_PINE_Settings_Click(wxCommandEvent& event)
{
AppOpenDialog<IPCDialog>(this);
AppOpenDialog<PINEDialog>(this);
}
void MainEmuFrame::Menu_AudioSettings_Click(wxCommandEvent& event)
@@ -634,9 +634,9 @@ void MainEmuFrame::Menu_EnableCheats_Click(wxCommandEvent&)
AppSaveSettings();
}
void MainEmuFrame::Menu_IPC_Enable_Click(wxCommandEvent&)
void MainEmuFrame::Menu_PINE_Enable_Click(wxCommandEvent&)
{
g_Conf->EmuOptions.EnableIPC = GetMenuBar()->IsChecked(MenuId_IPC_Enable);
g_Conf->EmuOptions.EnablePINE = GetMenuBar()->IsChecked(MenuId_PINE_Enable);
AppApplySettings();
AppSaveSettings();
}
+17 -17
View File
@@ -71,19 +71,19 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="GS\res\glsl\common_header.glsl" />
<None Include="GS\res\glsl\convert.glsl" />
<None Include="GS\res\glsl\interlace.glsl" />
<None Include="GS\res\glsl\merge.glsl" />
<None Include="GS\res\glsl\shadeboost.glsl" />
<None Include="GS\res\glsl\tfx_fs.glsl" />
<None Include="GS\res\glsl\tfx_vgs.glsl" />
<None Include="GS\res\convert.fx" />
<None Include="GS\res\fxaa.fx" />
<None Include="GS\res\interlace.fx" />
<None Include="GS\res\merge.fx" />
<None Include="GS\res\shadeboost.fx" />
<None Include="GS\res\tfx.fx" />
<None Include="..\bin\resources\shaders\opengl\common_header.glsl" />
<None Include="..\bin\resources\shaders\opengl\convert.glsl" />
<None Include="..\bin\resources\shaders\opengl\interlace.glsl" />
<None Include="..\bin\resources\shaders\opengl\merge.glsl" />
<None Include="..\bin\resources\shaders\opengl\shadeboost.glsl" />
<None Include="..\bin\resources\shaders\opengl\tfx_fs.glsl" />
<None Include="..\bin\resources\shaders\opengl\tfx_vgs.glsl" />
<None Include="..\bin\resources\shaders\dx11\convert.fx" />
<None Include="..\bin\resources\shaders\common\fxaa.fx" />
<None Include="..\bin\resources\shaders\dx11\interlace.fx" />
<None Include="..\bin\resources\shaders\dx11\merge.fx" />
<None Include="..\bin\resources\shaders\dx11\shadeboost.fx" />
<None Include="..\bin\resources\shaders\dx11\tfx.fx" />
<None Include="PAD\Windows\Default.ini" />
<None Include="Utilities\folderdesc.txt" />
<None Include="Docs\License.txt" />
@@ -318,7 +318,7 @@
<ClCompile Include="gui\Debugger\DebugEvents.cpp" />
<ClCompile Include="gui\Debugger\DebuggerLists.cpp" />
<ClCompile Include="gui\Debugger\DisassemblyDialog.cpp" />
<ClCompile Include="gui\Dialogs\IPCDialog.cpp" />
<ClCompile Include="gui\Dialogs\PINEDialog.cpp" />
<ClCompile Include="gui\Dialogs\GSDumpDialog.cpp" />
<ClCompile Include="gui\Dialogs\McdConfigDialog.cpp" />
<ClCompile Include="gui\DriveList.cpp" />
@@ -331,7 +331,7 @@
<ClCompile Include="gui\wxAppWithHelpers.cpp" />
<ClCompile Include="gui\wxSettingsInterface.cpp" />
<ClCompile Include="IopGte.cpp" />
<ClCompile Include="IPC.cpp" />
<ClCompile Include="PINE.cpp" />
<ClCompile Include="FW.cpp" />
<ClCompile Include="MemoryCardFile.cpp" />
<ClCompile Include="MemoryCardFolder.cpp" />
@@ -767,7 +767,7 @@
<ClInclude Include="gui\wxSettingsInterface.h" />
<ClInclude Include="Host.h" />
<ClInclude Include="IopGte.h" />
<ClInclude Include="IPC.h" />
<ClInclude Include="PINE.h" />
<ClInclude Include="FW.h" />
<ClInclude Include="MemoryCardFile.h" />
<ClInclude Include="MemoryCardFolder.h" />
@@ -1169,4 +1169,4 @@
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />
</Project>
</Project>
+16 -16
View File
@@ -330,43 +330,43 @@
<None Include="PAD\Windows\Default.ini">
<Filter>System\Ps2\PAD</Filter>
</None>
<None Include="GS\res\glsl\common_header.glsl">
<None Include="..\bin\resources\shaders\opengl\common_header.glsl">
<Filter>System\Ps2\GS\Shaders</Filter>
</None>
<None Include="GS\res\glsl\convert.glsl">
<None Include="..\bin\resources\shaders\opengl\convert.glsl">
<Filter>System\Ps2\GS\Shaders</Filter>
</None>
<None Include="GS\res\glsl\interlace.glsl">
<None Include="..\bin\resources\shaders\opengl\interlace.glsl">
<Filter>System\Ps2\GS\Shaders</Filter>
</None>
<None Include="GS\res\glsl\merge.glsl">
<None Include="..\bin\resources\shaders\opengl\merge.glsl">
<Filter>System\Ps2\GS\Shaders</Filter>
</None>
<None Include="GS\res\glsl\shadeboost.glsl">
<None Include="..\bin\resources\shaders\opengl\shadeboost.glsl">
<Filter>System\Ps2\GS\Shaders</Filter>
</None>
<None Include="GS\res\glsl\tfx_fs.glsl">
<None Include="..\bin\resources\shaders\opengl\tfx_fs.glsl">
<Filter>System\Ps2\GS\Shaders</Filter>
</None>
<None Include="GS\res\glsl\tfx_vgs.glsl">
<None Include="..\bin\resources\shaders\opengl\tfx_vgs.glsl">
<Filter>System\Ps2\GS\Shaders</Filter>
</None>
<None Include="GS\res\convert.fx">
<None Include="..\bin\resources\shaders\dx11\convert.fx">
<Filter>System\Ps2\GS\Shaders</Filter>
</None>
<None Include="GS\res\fxaa.fx">
<None Include="..\bin\resources\shaders\common\fxaa.fx">
<Filter>System\Ps2\GS\Shaders</Filter>
</None>
<None Include="GS\res\interlace.fx">
<None Include="..\bin\resources\shaders\dx11\interlace.fx">
<Filter>System\Ps2\GS\Shaders</Filter>
</None>
<None Include="GS\res\merge.fx">
<None Include="..\bin\resources\shaders\dx11\merge.fx">
<Filter>System\Ps2\GS\Shaders</Filter>
</None>
<None Include="GS\res\shadeboost.fx">
<None Include="..\bin\resources\shaders\dx11\shadeboost.fx">
<Filter>System\Ps2\GS\Shaders</Filter>
</None>
<None Include="GS\res\tfx.fx">
<None Include="..\bin\resources\shaders\dx11\tfx.fx">
<Filter>System\Ps2\GS\Shaders</Filter>
</None>
</ItemGroup>
@@ -1052,7 +1052,7 @@
<ClCompile Include="gui\DriveList.cpp">
<Filter>AppHost</Filter>
</ClCompile>
<ClCompile Include="IPC.cpp">
<ClCompile Include="PINE.cpp">
<Filter>System</Filter>
</ClCompile>
<ClCompile Include="FW.cpp">
@@ -1466,7 +1466,7 @@
<ClCompile Include="GS\GSLzma.cpp">
<Filter>System\Ps2\GS</Filter>
</ClCompile>
<ClCompile Include="gui\Dialogs\IPCDialog.cpp">
<ClCompile Include="gui\Dialogs\PINEDialog.cpp">
<Filter>AppHost\Dialogs</Filter>
</ClCompile>
<ClCompile Include="gui\Dialogs\GSDumpDialog.cpp">
@@ -2141,7 +2141,7 @@
<ClInclude Include="gui\DriveList.h">
<Filter>AppHost\Include</Filter>
</ClInclude>
<ClInclude Include="IPC.h">
<ClInclude Include="PINE.h">
<Filter>System\Include</Filter>
</ClInclude>
<ClInclude Include="FW.h">
+2
View File
@@ -119,6 +119,8 @@ static bool LoadBiosVersion(std::FILE* fp, u32& version, std::string& descriptio
version = strtol(vermaj, (char**)NULL, 0) << 8;
version |= strtol(vermin, (char**)NULL, 0);
foundRomVer = true;
Console.WriteLn("Bios Found: %s", description.c_str());
}
if ((rd.fileSize % 0x10) == 0)