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 |
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
+19
-42
@@ -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);
|
||||
|
||||
@@ -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())))
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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">
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user