Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce96d4bcc5 | ||
|
|
fb242274d5 | ||
|
|
938bc7cdd7 | ||
|
|
36865f2930 | ||
|
|
12e79cccf6 | ||
|
|
6180f12ba3 | ||
|
|
c00b6c6237 | ||
|
|
dbdc74fdef | ||
|
|
5bb0a07164 | ||
|
|
543f09999f | ||
|
|
812f32efdd | ||
|
|
784264eba4 | ||
|
|
ff9ca059c7 | ||
|
|
d4b0c39485 | ||
|
|
87c42aeaf4 | ||
|
|
5ba6e57c71 | ||
|
|
6d2ba5c2d0 | ||
|
|
0d42b81285 | ||
|
|
9ce2ae613b | ||
|
|
13c9e0e666 | ||
|
|
784118e9c1 | ||
|
|
df32a32d99 | ||
|
|
655241aed3 | ||
|
|
60a2b246e2 | ||
|
|
ebd60d93f3 | ||
|
|
cc4ba935b5 | ||
|
|
824147fd7d | ||
|
|
c3446a16cc | ||
|
|
82135d1892 | ||
|
|
1cff63bc01 | ||
|
|
e488e74313 | ||
|
|
1a17c9da86 | ||
|
|
20e1f773fc | ||
|
|
56d80ff293 | ||
|
|
80e176136a | ||
|
|
0ae66d3e24 | ||
|
|
802ab8238e | ||
|
|
ec9c07a646 | ||
|
|
b75ad663f2 | ||
|
|
e4a017fc00 | ||
|
|
5b486ca6b8 | ||
|
|
1c39ed6130 | ||
|
|
a47563b12f | ||
|
|
84491ff655 | ||
|
|
e5991a4379 | ||
|
|
0b3d4615b8 | ||
|
|
a8f6336b47 | ||
|
|
0b33df3341 | ||
|
|
744cc4b705 | ||
|
|
9d3cd5784f | ||
|
|
06ea58198a | ||
|
|
3692d7d090 | ||
|
|
460a2dbbd3 | ||
|
|
228f4f1010 | ||
|
|
2703b91e41 | ||
|
|
24171787f8 | ||
|
|
49d3338d4a | ||
|
|
a9d693e1c3 | ||
|
|
4ef69248d0 | ||
|
|
247b3ed740 | ||
|
|
1edca6235c | ||
|
|
ab5c03b1d9 | ||
|
|
d4cb35469d | ||
|
|
fd1b1d0c24 | ||
|
|
bf96ceeacc | ||
|
|
2c08b385e5 | ||
|
|
051d13ec7a | ||
|
|
a2a9643123 | ||
|
|
1286bfe75b |
@@ -37,5 +37,6 @@ jobs:
|
||||
cmakeflags: ""
|
||||
publish: true
|
||||
branch: stable
|
||||
fetchTags: true
|
||||
secrets: inherit
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ Installers and binaries for both stable and development builds are available fro
|
||||
|
||||
| Operating System | CPU | GPU | RAM |
|
||||
| ------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---- |
|
||||
| - Windows 10 Version 1809 or later (64-bit) <br/> - Ubuntu 22.04/Debian or newer, Arch Linux, or other distro (64-bit) <br/> - macOS 10.14 | - Supports SSE4.1 <br/> - [PassMark Thread Performance](https://www.cpubenchmark.net/CPU_mega_page.html) rating near or greater than 1800<br/> - Two physical cores, with hyperthreading | - Direct3D10 support <br/> - OpenGL 3.x support <br/> - Vulkan 1.1 support <br/> - Metal support <br/> - [PassMark G3D Mark](https://www.videocardbenchmark.net/high_end_gpus.html) rating around 3000 (Geforce GTX 750, Radeon RX 560, Intel Arc A380) <br/> - 2 GB Video Memory | 4 GB |
|
||||
| - Windows 10 Version 1809 or later (64-bit) <br/> - Ubuntu 22.04/Debian or newer, Arch Linux, or other distro (64-bit) <br/> - macOS 10.14 | - Supports SSE4.1 <br/> - [PassMark Thread Performance](https://www.cpubenchmark.net/CPU_mega_page.html) rating near or greater than 1800<br/> - Two physical cores, with hyperthreading | - Direct3D 11 (Feature Level 11.0) support <br/> - OpenGL 3.3 support <br/> - Vulkan 1.1 support <br/> - Metal support <br/> - [PassMark G3D Mark](https://www.videocardbenchmark.net/high_end_gpus.html) rating around 3000 (Geforce GTX 750, Radeon RX 560, Intel Arc A380) <br/> - 2 GB Video Memory | 4 GB |
|
||||
|
||||
_Note: Recommended Single Thread Performance is based on moderately complex games. Games that pushed the PS2 hardware to its limits will struggle on CPUs at this level. Some release titles and 2D games which underutilized the PS2 hardware may run on CPUs rated as low as 1200. A quick reference for CPU **intensive games**: [Wiki](https://wiki.pcsx2.net/Category:CPU_intensive_games), [Forum](https://forums.pcsx2.net/Thread-LIST-The-Most-CPU-Intensive-Games) and CPU **light** games: [Forum](https://forums.pcsx2.net/Thread-LIST-Games-that-don-t-need-a-strong-CPU-to-emulate)_
|
||||
|
||||
|
||||
@@ -13,14 +13,6 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if defined(SHADER_MODEL) || defined(FXAA_GLSL_130) || defined(FXAA_GLSL_VK) || defined(__METAL_VERSION__)
|
||||
|
||||
#ifndef SHADER_MODEL
|
||||
#define SHADER_MODEL 0
|
||||
#endif
|
||||
#ifndef FXAA_HLSL_4
|
||||
#define FXAA_HLSL_4 0
|
||||
#endif
|
||||
#ifndef FXAA_HLSL_5
|
||||
#define FXAA_HLSL_5 0
|
||||
#endif
|
||||
@@ -51,7 +43,7 @@ layout(location = 0) in vec2 PSin_t;
|
||||
layout(location = 0) out vec4 SV_Target0;
|
||||
layout(set = 0, binding = 0) uniform sampler2D TextureSampler;
|
||||
|
||||
#elif (SHADER_MODEL >= 0x400)
|
||||
#elif (FXAA_HLSL_5 == 1)
|
||||
Texture2D Texture : register(t0);
|
||||
SamplerState TextureSampler : register(s0);
|
||||
|
||||
@@ -80,26 +72,6 @@ static constexpr sampler MAIN_SAMPLER(coord::normalized, address::clamp_to_edge,
|
||||
[FXAA CODE SECTION]
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
// We don't use gather4 for alpha/luminance because it would require an additional
|
||||
// pass to compute the values, which would be slower than the extra shader loads.
|
||||
|
||||
#if (SHADER_MODEL >= 0x500)
|
||||
#undef FXAA_HLSL_5
|
||||
#define FXAA_HLSL_5 1
|
||||
#define FXAA_GATHER4_ALPHA 0
|
||||
|
||||
#elif (SHADER_MODEL >= 0x400)
|
||||
#undef FXAA_HLSL_4
|
||||
#define FXAA_HLSL_4 1
|
||||
#define FXAA_GATHER4_ALPHA 0
|
||||
|
||||
#elif (FXAA_GLSL_130 == 1 || FXAA_GLSL_VK == 1)
|
||||
#define FXAA_GATHER4_ALPHA 0
|
||||
|
||||
#elif defined(__METAL_VERSION__)
|
||||
#define FXAA_GATHER4_ALPHA 0
|
||||
#endif
|
||||
|
||||
#if (FXAA_HLSL_5 == 1)
|
||||
struct FxaaTex { SamplerState smpl; Texture2D tex; };
|
||||
#define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)
|
||||
@@ -109,13 +81,6 @@ struct FxaaTex { SamplerState smpl; Texture2D tex; };
|
||||
#define FxaaDiscard clip(-1)
|
||||
#define FxaaSat(x) saturate(x)
|
||||
|
||||
#elif (FXAA_HLSL_4 == 1)
|
||||
struct FxaaTex { SamplerState smpl; Texture2D tex; };
|
||||
#define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)
|
||||
#define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)
|
||||
#define FxaaDiscard clip(-1)
|
||||
#define FxaaSat(x) saturate(x)
|
||||
|
||||
#elif (FXAA_GLSL_130 == 1 || FXAA_GLSL_VK == 1)
|
||||
#define int2 ivec2
|
||||
#define float2 vec2
|
||||
@@ -127,12 +92,6 @@ struct FxaaTex { SamplerState smpl; Texture2D tex; };
|
||||
#define FxaaTexTop(t, p) textureLod(t, p, 0.0)
|
||||
#define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o)
|
||||
|
||||
#if (FXAA_GATHER4_ALPHA == 1)
|
||||
// use #extension GL_ARB_gpu_shader5 : enable
|
||||
#define FxaaTexAlpha4(t, p) textureGather(t, p, 3)
|
||||
#define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)
|
||||
#endif
|
||||
|
||||
#elif defined(__METAL_VERSION__)
|
||||
#define FxaaTex texture2d<float>
|
||||
#define FxaaTexTop(t, p) t.sample(MAIN_SAMPLER, p)
|
||||
@@ -221,21 +180,6 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS
|
||||
posM.x = pos.x;
|
||||
posM.y = pos.y;
|
||||
|
||||
#if (FXAA_GATHER4_ALPHA == 1)
|
||||
float4 rgbyM = FxaaTexTop(tex, posM);
|
||||
float4 luma4A = FxaaTexAlpha4(tex, posM);
|
||||
float4 luma4B = FxaaTexOffAlpha4(tex, posM, int2(-1, -1));
|
||||
rgbyM.w = RGBLuminance(rgbyM.xyz);
|
||||
|
||||
#define lumaM rgbyM.w
|
||||
#define lumaE luma4A.z
|
||||
#define lumaS luma4A.x
|
||||
#define lumaSE luma4A.y
|
||||
#define lumaNW luma4B.w
|
||||
#define lumaN luma4B.z
|
||||
#define lumaW luma4B.x
|
||||
|
||||
#else
|
||||
float4 rgbyM = FxaaTexTop(tex, posM);
|
||||
rgbyM.w = RGBLuminance(rgbyM.xyz);
|
||||
#define lumaM rgbyM.w
|
||||
@@ -244,7 +188,6 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS
|
||||
float lumaE = FxaaLuma(FxaaTexOff(tex, posM, int2( 1, 0), fxaaRcpFrame.xy));
|
||||
float lumaN = FxaaLuma(FxaaTexOff(tex, posM, int2( 0,-1), fxaaRcpFrame.xy));
|
||||
float lumaW = FxaaLuma(FxaaTexOff(tex, posM, int2(-1, 0), fxaaRcpFrame.xy));
|
||||
#endif
|
||||
|
||||
float maxSM = max(lumaS, lumaM);
|
||||
float minSM = min(lumaS, lumaM);
|
||||
@@ -264,15 +207,10 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS
|
||||
if(earlyExit) { return rgbyM; }
|
||||
#endif
|
||||
|
||||
#if (FXAA_GATHER4_ALPHA == 0)
|
||||
float lumaNW = FxaaLuma(FxaaTexOff(tex, posM, int2(-1,-1), fxaaRcpFrame.xy));
|
||||
float lumaSE = FxaaLuma(FxaaTexOff(tex, posM, int2( 1, 1), fxaaRcpFrame.xy));
|
||||
float lumaNE = FxaaLuma(FxaaTexOff(tex, posM, int2( 1,-1), fxaaRcpFrame.xy));
|
||||
float lumaSW = FxaaLuma(FxaaTexOff(tex, posM, int2(-1, 1), fxaaRcpFrame.xy));
|
||||
#else
|
||||
float lumaNE = FxaaLuma(FxaaTexOff(tex, posM, int2( 1,-1), fxaaRcpFrame.xy));
|
||||
float lumaSW = FxaaLuma(FxaaTexOff(tex, posM, int2(-1, 1), fxaaRcpFrame.xy));
|
||||
#endif
|
||||
|
||||
float lumaNS = lumaN + lumaS;
|
||||
float lumaWE = lumaW + lumaE;
|
||||
@@ -518,14 +456,14 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS
|
||||
|
||||
#if (FXAA_GLSL_130 == 1 || FXAA_GLSL_VK == 1)
|
||||
float4 FxaaPass(float4 FxaaColor, float2 uv0)
|
||||
#elif (SHADER_MODEL >= 0x400)
|
||||
#elif (FXAA_HLSL_5 == 1)
|
||||
float4 FxaaPass(float4 FxaaColor : COLOR0, float2 uv0 : TEXCOORD0)
|
||||
#elif defined(__METAL_VERSION__)
|
||||
float4 FxaaPass(float4 FxaaColor, float2 uv0, texture2d<float> tex)
|
||||
#endif
|
||||
{
|
||||
|
||||
#if (SHADER_MODEL >= 0x400)
|
||||
#if (FXAA_HLSL_5 == 1)
|
||||
FxaaTex tex;
|
||||
tex.tex = Texture;
|
||||
tex.smpl = TextureSampler;
|
||||
@@ -559,8 +497,8 @@ void main()
|
||||
SV_Target0 = float4(color.rgb, 1.0);
|
||||
}
|
||||
|
||||
#elif (SHADER_MODEL >= 0x400)
|
||||
PS_OUTPUT ps_main(VS_OUTPUT input)
|
||||
#elif (FXAA_HLSL_5 == 1)
|
||||
PS_OUTPUT main(VS_OUTPUT input)
|
||||
{
|
||||
PS_OUTPUT output;
|
||||
|
||||
@@ -576,5 +514,3 @@ PS_OUTPUT ps_main(VS_OUTPUT input)
|
||||
|
||||
// Metal main function in in fxaa.metal
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef SHADER_MODEL // make safe to include in resource file to enforce dependency
|
||||
|
||||
struct VS_INPUT
|
||||
{
|
||||
float4 p : POSITION;
|
||||
@@ -413,5 +411,3 @@ float ps_stencil_image_init_1(PS_INPUT input) : SV_Target
|
||||
c = float(0x7FFFFFFF);
|
||||
return c;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef SHADER_MODEL // make safe to include in resource file to enforce dependency
|
||||
|
||||
Texture2D Texture;
|
||||
SamplerState Sampler;
|
||||
|
||||
@@ -195,5 +193,3 @@ float4 ps_main4(PS_INPUT input) : SV_Target0
|
||||
|
||||
return float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef SHADER_MODEL // make safe to include in resource file to enforce dependency
|
||||
|
||||
Texture2D Texture;
|
||||
SamplerState Sampler;
|
||||
|
||||
@@ -45,4 +43,3 @@ float4 ps_main1(PS_INPUT input) : SV_Target0
|
||||
c.a = BGColor.a;
|
||||
return c;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -13,12 +13,6 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef SHADER_MODEL // make safe to include in resource file to enforce dependency
|
||||
|
||||
#ifndef PS_SCALE_FACTOR
|
||||
#define PS_SCALE_FACTOR 1
|
||||
#endif
|
||||
|
||||
struct VS_INPUT
|
||||
{
|
||||
float4 p : POSITION;
|
||||
@@ -451,5 +445,3 @@ PS_OUTPUT ps_automagical_supersampling(PS_INPUT input)
|
||||
output.c = float4(col / div, 1);
|
||||
return output;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef SHADER_MODEL // make safe to include in resource file to enforce dependency
|
||||
|
||||
Texture2D Texture;
|
||||
SamplerState Sampler;
|
||||
|
||||
@@ -64,5 +62,3 @@ float4 ps_main(PS_INPUT input) : SV_Target0
|
||||
float4 c = Texture.Sample(Sampler, input.t);
|
||||
return ContrastSaturationBrightness(c);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -661,7 +661,7 @@ float4 sample_color(float2 st, float uv_w)
|
||||
float4 tfx(float4 T, float4 C)
|
||||
{
|
||||
float4 C_out;
|
||||
float4 FxT = trunc(trunc(C) * T / 128.0f);
|
||||
float4 FxT = trunc((C * T) / 128.0f);
|
||||
|
||||
#if (PS_TFX == 0)
|
||||
C_out = FxT;
|
||||
|
||||
@@ -614,7 +614,7 @@ vec4 sample_color(vec2 st)
|
||||
vec4 tfx(vec4 T, vec4 C)
|
||||
{
|
||||
vec4 C_out;
|
||||
vec4 FxT = trunc(trunc(C) * T / 128.0f);
|
||||
vec4 FxT = trunc((C * T) / 128.0f);
|
||||
|
||||
#if (PS_TFX == 0)
|
||||
C_out = FxT;
|
||||
|
||||
@@ -849,7 +849,7 @@ vec4 sample_color(vec2 st)
|
||||
vec4 tfx(vec4 T, vec4 C)
|
||||
{
|
||||
vec4 C_out;
|
||||
vec4 FxT = trunc(trunc(C) * T / 128.0f);
|
||||
vec4 FxT = trunc((C * T) / 128.0f);
|
||||
|
||||
#if (PS_TFX == 0)
|
||||
C_out = FxT;
|
||||
|
||||
@@ -643,7 +643,9 @@ bool unpack_bc7_mode0_2(uint32_t mode, const uint64_t* data_chunks, color_rgba*
|
||||
const uint32_t ENDPOINT_BITS = (mode == 0) ? 4 : 5;
|
||||
const uint32_t ENDPOINT_MASK = (1 << ENDPOINT_BITS) - 1;
|
||||
const uint32_t PBITS = (mode == 0) ? 6 : 0;
|
||||
#ifndef BC7DECOMP_USE_SSE2
|
||||
const uint32_t WEIGHT_VALS = 1 << WEIGHT_BITS;
|
||||
#endif
|
||||
const uint32_t PART_BITS = (mode == 0) ? 4 : 6;
|
||||
const uint32_t PART_MASK = (1 << PART_BITS) - 1;
|
||||
|
||||
@@ -740,7 +742,9 @@ bool unpack_bc7_mode1_3_7(uint32_t mode, const uint64_t* data_chunks, color_rgba
|
||||
const uint32_t ENDPOINT_MASK = (1 << ENDPOINT_BITS) - 1;
|
||||
const uint32_t PBITS = (mode == 1) ? 2 : 4;
|
||||
const uint32_t SHARED_PBITS = (mode == 1) ? true : false;
|
||||
#ifndef BC7DECOMP_USE_SSE2
|
||||
const uint32_t WEIGHT_VALS = 1 << WEIGHT_BITS;
|
||||
#endif
|
||||
|
||||
const uint64_t low_chunk = data_chunks[0];
|
||||
const uint64_t high_chunk = data_chunks[1];
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
#include "pcsx2/Input/InputManager.h"
|
||||
#include "pcsx2/LogSink.h"
|
||||
#include "pcsx2/MTGS.h"
|
||||
#include "pcsx2/PAD/Host/PAD.h"
|
||||
#include "pcsx2/SIO/Pad/Pad.h"
|
||||
#include "pcsx2/PerformanceMetrics.h"
|
||||
#include "pcsx2/VMManager.h"
|
||||
|
||||
@@ -85,11 +85,13 @@ static double s_last_render_passes = 0;
|
||||
static double s_last_barriers = 0;
|
||||
static double s_last_copies = 0;
|
||||
static double s_last_uploads = 0;
|
||||
static double s_last_readbacks = 0;
|
||||
static u64 s_total_draws = 0;
|
||||
static u64 s_total_render_passes = 0;
|
||||
static u64 s_total_barriers = 0;
|
||||
static u64 s_total_copies = 0;
|
||||
static u64 s_total_uploads = 0;
|
||||
static u64 s_total_readbacks = 0;
|
||||
static u32 s_total_frames = 0;
|
||||
|
||||
bool GSRunner::InitializeConfig()
|
||||
@@ -115,7 +117,7 @@ bool GSRunner::InitializeConfig()
|
||||
si.SetStringValue("SPU2/Output", "OutputModule", "nullout");
|
||||
|
||||
// none of the bindings are going to resolve to anything
|
||||
PAD::ClearPortBindings(si, 0);
|
||||
Pad::ClearPortBindings(si, 0);
|
||||
si.ClearSection("Hotkeys");
|
||||
|
||||
// make sure any gamesettings inis in your tree don't get loaded
|
||||
@@ -255,7 +257,7 @@ void Host::OnInputDeviceDisconnected(const std::string_view& identifier)
|
||||
{
|
||||
}
|
||||
|
||||
void Host::SetRelativeMouseMode(bool enabled)
|
||||
void Host::SetMouseMode(bool relative_mode, bool hide_cursor)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -293,6 +295,7 @@ void Host::BeginPresentFrame()
|
||||
update_stat(GSPerfMon::Barriers, s_total_barriers, s_last_barriers);
|
||||
update_stat(GSPerfMon::TextureCopies, s_total_copies, s_last_copies);
|
||||
update_stat(GSPerfMon::TextureUploads, s_total_uploads, s_last_uploads);
|
||||
update_stat(GSPerfMon::Readbacks, s_total_readbacks, s_last_readbacks);
|
||||
s_total_frames++;
|
||||
std::atomic_thread_fence(std::memory_order_release);
|
||||
}
|
||||
@@ -382,12 +385,15 @@ void Host::RequestVMShutdown(bool allow_confirm, bool allow_save_state, bool def
|
||||
VMManager::SetState(VMState::Stopping);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ACHIEVEMENTS
|
||||
void Host::OnAchievementsLoginRequested(Achievements::LoginRequestReason reason)
|
||||
{
|
||||
// noop
|
||||
}
|
||||
|
||||
void Host::OnAchievementsRefreshed()
|
||||
{
|
||||
// noop
|
||||
}
|
||||
#endif
|
||||
|
||||
std::optional<u32> InputManager::ConvertHostKeyboardStringToCode(const std::string_view& str)
|
||||
{
|
||||
@@ -641,6 +647,7 @@ void GSRunner::DumpStats()
|
||||
Console.WriteLn(fmt::format("@HWSTAT@ Barriers: {} (avg {})", s_total_barriers, static_cast<u64>(std::ceil(s_total_barriers / static_cast<double>(s_total_frames)))));
|
||||
Console.WriteLn(fmt::format("@HWSTAT@ Copies: {} (avg {})", s_total_copies, static_cast<u64>(std::ceil(s_total_copies / static_cast<double>(s_total_frames)))));
|
||||
Console.WriteLn(fmt::format("@HWSTAT@ Uploads: {} (avg {})", s_total_uploads, static_cast<u64>(std::ceil(s_total_uploads / static_cast<double>(s_total_frames)))));
|
||||
Console.WriteLn(fmt::format("@HWSTAT@ Readbacks: {} (avg {})", s_total_readbacks, static_cast<u64>(std::ceil(s_total_readbacks / static_cast<double>(s_total_frames)))));
|
||||
Console.WriteLn("============================================");
|
||||
}
|
||||
|
||||
|
||||
@@ -380,6 +380,8 @@ void AutoUpdaterDialog::getChangesComplete(QNetworkReply* reply)
|
||||
changes_html.prepend(tr("<h2>Save State Warning</h2><p>Installing this update will make your save states "
|
||||
"<b>incompatible</b>. Please ensure you have saved your games to a Memory Card "
|
||||
"before installing this update or you will lose progress.</p>"));
|
||||
|
||||
m_update_will_break_save_states = true;
|
||||
}
|
||||
|
||||
if (update_increases_settings_version)
|
||||
@@ -407,6 +409,23 @@ void AutoUpdaterDialog::getChangesComplete(QNetworkReply* reply)
|
||||
|
||||
void AutoUpdaterDialog::downloadUpdateClicked()
|
||||
{
|
||||
if (m_update_will_break_save_states)
|
||||
{
|
||||
QMessageBox msgbox;
|
||||
msgbox.setIcon(QMessageBox::Critical);
|
||||
msgbox.setWindowTitle(tr("Savestate Warning"));
|
||||
msgbox.setText(tr("<h1>WARNING</h1><p style='font-size:12pt;'>Installing this update will make your <b>save states incompatible</b>, <i>be sure to save any progress to your memory cards before proceeding</i>.</p><p>Do you wish to continue?</p>"));
|
||||
msgbox.addButton(QMessageBox::Yes);
|
||||
msgbox.addButton(QMessageBox::No);
|
||||
msgbox.setDefaultButton(QMessageBox::No);
|
||||
// This makes the box wider, for some reason sizing boxes in Qt is hard - Source: The internet.
|
||||
QSpacerItem* horizontalSpacer = new QSpacerItem(500, 0, QSizePolicy::Minimum, QSizePolicy::Expanding);
|
||||
QGridLayout* layout = (QGridLayout*)msgbox.layout();
|
||||
layout->addItem(horizontalSpacer, layout->rowCount(), 0, 1, layout->columnCount());
|
||||
if (msgbox.exec() != QMessageBox::Yes)
|
||||
return;
|
||||
}
|
||||
|
||||
m_display_messages = true;
|
||||
QUrl url(m_download_url);
|
||||
QNetworkRequest request(url);
|
||||
|
||||
@@ -134,6 +134,7 @@ target_sources(pcsx2-qt PRIVATE
|
||||
Settings/SettingsDialog.ui
|
||||
Settings/USBBindingWidget_DrivingForce.ui
|
||||
Settings/USBBindingWidget_GTForce.ui
|
||||
Settings/USBBindingWidget_GunCon2.ui
|
||||
Debugger/CpuWidget.cpp
|
||||
Debugger/CpuWidget.h
|
||||
Debugger/CpuWidget.ui
|
||||
|
||||
@@ -589,7 +589,7 @@ static std::vector<u32> searchWorkerByteArray(DebugInterface* cpu, u32 start, u3
|
||||
bool hit = true;
|
||||
for (qsizetype i = 0; i < value.length(); i++)
|
||||
{
|
||||
if (cpu->read8(addr + i) != value[i])
|
||||
if (static_cast<char>(cpu->read8(addr + i)) != value[i])
|
||||
{
|
||||
hit = false;
|
||||
break;
|
||||
|
||||
@@ -151,9 +151,10 @@ void DisassemblyWidget::contextNoopInstruction()
|
||||
|
||||
void DisassemblyWidget::contextRunToCursor()
|
||||
{
|
||||
Host::RunOnCPUThread([&] { CBreakPoints::AddBreakPoint(m_cpu->getCpuType(), m_selectedAddressStart); });
|
||||
|
||||
m_cpu->resumeCpu();
|
||||
Host::RunOnCPUThread([&] {
|
||||
CBreakPoints::AddBreakPoint(m_cpu->getCpuType(), m_selectedAddressStart, true);
|
||||
m_cpu->resumeCpu();
|
||||
});
|
||||
}
|
||||
|
||||
void DisassemblyWidget::contextJumpToCursor()
|
||||
|
||||
@@ -78,7 +78,7 @@ QVariant BreakpointModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
QString type("");
|
||||
type += (mc->cond & MEMCHECK_READ) ? tr("Read") : "";
|
||||
type += ((mc->cond & MEMCHECK_BOTH) == MEMCHECK_BOTH) ? ", " : " ";
|
||||
type += ((mc->cond & MEMCHECK_READWRITE) == MEMCHECK_READWRITE) ? ", " : " ";
|
||||
//: (C) = changes, as in "look for changes".
|
||||
type += (mc->cond & MEMCHECK_WRITE) ? (mc->cond & MEMCHECK_WRITE_ONCHANGE) ? tr("Write(C)") : tr("Write") : "";
|
||||
return type;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "QtHost.h"
|
||||
#include "QtUtils.h"
|
||||
#include "SettingWidgetBinder.h"
|
||||
#include "Settings/AchievementLoginDialog.h"
|
||||
#include "Settings/ControllerSettingsDialog.h"
|
||||
#include "Settings/GameListSettingsWidget.h"
|
||||
#include "Settings/InterfaceSettingsWidget.h"
|
||||
@@ -414,7 +415,7 @@ void MainWindow::connectVMThreadSignals(EmuThread* thread)
|
||||
connect(thread, &EmuThread::onAcquireRenderWindowRequested, this, &MainWindow::acquireRenderWindow, Qt::BlockingQueuedConnection);
|
||||
connect(thread, &EmuThread::onReleaseRenderWindowRequested, this, &MainWindow::releaseRenderWindow, Qt::BlockingQueuedConnection);
|
||||
connect(thread, &EmuThread::onResizeRenderWindowRequested, this, &MainWindow::displayResizeRequested);
|
||||
connect(thread, &EmuThread::onRelativeMouseModeRequested, this, &MainWindow::relativeMouseModeRequested);
|
||||
connect(thread, &EmuThread::onMouseModeRequested, this, &MainWindow::mouseModeRequested);
|
||||
connect(thread, &EmuThread::onVMStarting, this, &MainWindow::onVMStarting);
|
||||
connect(thread, &EmuThread::onVMStarted, this, &MainWindow::onVMStarted);
|
||||
connect(thread, &EmuThread::onVMPaused, this, &MainWindow::onVMPaused);
|
||||
@@ -423,6 +424,7 @@ void MainWindow::connectVMThreadSignals(EmuThread* thread)
|
||||
connect(thread, &EmuThread::onGameChanged, this, &MainWindow::onGameChanged);
|
||||
connect(thread, &EmuThread::onCaptureStarted, this, &MainWindow::onCaptureStarted);
|
||||
connect(thread, &EmuThread::onCaptureStopped, this, &MainWindow::onCaptureStopped);
|
||||
connect(thread, &EmuThread::onAchievementsLoginRequested, this, &MainWindow::onAchievementsLoginRequested);
|
||||
|
||||
connect(m_ui.actionReset, &QAction::triggered, thread, &EmuThread::resetVM);
|
||||
connect(m_ui.actionPause, &QAction::toggled, thread, &EmuThread::setVMPaused);
|
||||
@@ -628,6 +630,14 @@ void MainWindow::onCaptureStopped()
|
||||
m_ui.actionToolsVideoCapture->setChecked(false);
|
||||
}
|
||||
|
||||
void MainWindow::onAchievementsLoginRequested(Achievements::LoginRequestReason reason)
|
||||
{
|
||||
auto lock = pauseAndLockVM();
|
||||
|
||||
AchievementLoginDialog dlg(this, reason);
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
void MainWindow::onSettingsTriggeredFromToolbar()
|
||||
{
|
||||
if (s_vm_valid)
|
||||
@@ -887,7 +897,8 @@ bool MainWindow::isRenderingToMain() const
|
||||
|
||||
bool MainWindow::shouldHideMouseCursor() const
|
||||
{
|
||||
return (isRenderingFullscreen() && Host::GetBoolSettingValue("UI", "HideMouseCursor", false)) || m_relative_mouse_mode;
|
||||
return ((isRenderingFullscreen() && Host::GetBoolSettingValue("UI", "HideMouseCursor", false)) ||
|
||||
m_relative_mouse_mode || m_hide_mouse_cursor);
|
||||
}
|
||||
|
||||
bool MainWindow::shouldHideMainWindow() const
|
||||
@@ -2003,12 +2014,13 @@ void MainWindow::displayResizeRequested(qint32 width, qint32 height)
|
||||
QtUtils::ResizePotentiallyFixedSizeWindow(this, width, height + extra_height);
|
||||
}
|
||||
|
||||
void MainWindow::relativeMouseModeRequested(bool enabled)
|
||||
void MainWindow::mouseModeRequested(bool relative_mode, bool hide_cursor)
|
||||
{
|
||||
if (m_relative_mouse_mode == enabled)
|
||||
if (m_relative_mouse_mode == relative_mode && m_hide_mouse_cursor == hide_cursor)
|
||||
return;
|
||||
|
||||
m_relative_mouse_mode = enabled;
|
||||
m_relative_mouse_mode = relative_mode;
|
||||
m_hide_mouse_cursor = hide_cursor;
|
||||
if (m_display_widget && !s_vm_paused)
|
||||
updateDisplayWidgetCursor();
|
||||
}
|
||||
|
||||
@@ -39,6 +39,11 @@ class ControllerSettingsDialog;
|
||||
|
||||
class EmuThread;
|
||||
|
||||
namespace Achievements
|
||||
{
|
||||
enum class LoginRequestReason;
|
||||
}
|
||||
|
||||
namespace GameList
|
||||
{
|
||||
struct Entry;
|
||||
@@ -124,7 +129,7 @@ private Q_SLOTS:
|
||||
|
||||
std::optional<WindowInfo> acquireRenderWindow(bool recreate_window, bool fullscreen, bool render_to_main, bool surfaceless);
|
||||
void displayResizeRequested(qint32 width, qint32 height);
|
||||
void relativeMouseModeRequested(bool enabled);
|
||||
void mouseModeRequested(bool relative_mode, bool hide_cursor);
|
||||
void releaseRenderWindow();
|
||||
void focusDisplayWidget();
|
||||
|
||||
@@ -186,6 +191,8 @@ private Q_SLOTS:
|
||||
void onCaptureStarted(const QString& filename);
|
||||
void onCaptureStopped();
|
||||
|
||||
void onAchievementsLoginRequested(Achievements::LoginRequestReason reason);
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent* event) override;
|
||||
void closeEvent(QCloseEvent* event) override;
|
||||
@@ -293,6 +300,7 @@ private:
|
||||
|
||||
bool m_display_created = false;
|
||||
bool m_relative_mouse_mode = false;
|
||||
bool m_hide_mouse_cursor = false;
|
||||
bool m_was_paused_on_surface_loss = false;
|
||||
bool m_was_disc_change_request = false;
|
||||
bool m_is_closing = false;
|
||||
|
||||
@@ -184,6 +184,10 @@
|
||||
<property name="title">
|
||||
<string>Input Recording</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="keyboard-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<addaction name="actionInputRecNew"/>
|
||||
<addaction name="actionInputRecPlay"/>
|
||||
<addaction name="actionInputRecStop"/>
|
||||
@@ -863,6 +867,10 @@
|
||||
<property name="text">
|
||||
<string>Toggle Software Rendering</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="brush-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDebugger">
|
||||
<property name="icon">
|
||||
@@ -877,6 +885,10 @@
|
||||
<property name="text">
|
||||
<string>Reload Cheats/Patches</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="refresh-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEnableSystemConsole">
|
||||
<property name="checkable">
|
||||
@@ -914,6 +926,10 @@
|
||||
<property name="text">
|
||||
<string>Save Single Frame GS Dump</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="save-3-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionInputRecNew">
|
||||
<property name="enabled">
|
||||
|
||||
@@ -1079,6 +1079,11 @@ void Host::OnSaveStateSaved(const std::string_view& filename)
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ACHIEVEMENTS
|
||||
void Host::OnAchievementsLoginRequested(Achievements::LoginRequestReason reason)
|
||||
{
|
||||
emit g_emu_thread->onAchievementsLoginRequested(reason);
|
||||
}
|
||||
|
||||
void Host::OnAchievementsRefreshed()
|
||||
{
|
||||
u32 game_id = 0;
|
||||
@@ -1468,9 +1473,9 @@ void Host::OnInputDeviceDisconnected(const std::string_view& identifier)
|
||||
emit g_emu_thread->onInputDeviceDisconnected(identifier.empty() ? QString() : QString::fromUtf8(identifier.data(), identifier.size()));
|
||||
}
|
||||
|
||||
void Host::SetRelativeMouseMode(bool enabled)
|
||||
void Host::SetMouseMode(bool relative_mode, bool hide_cursor)
|
||||
{
|
||||
emit g_emu_thread->onRelativeMouseModeRequested(enabled);
|
||||
emit g_emu_thread->onMouseModeRequested(relative_mode, hide_cursor);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -1778,6 +1783,7 @@ void QtHost::RegisterTypes()
|
||||
qRegisterMetaType<InputBindingKey>();
|
||||
qRegisterMetaType<CDVD_SourceType>();
|
||||
qRegisterMetaType<const GameList::Entry*>();
|
||||
qRegisterMetaType<Achievements::LoginRequestReason>();
|
||||
}
|
||||
|
||||
bool QtHost::RunSetupWizard()
|
||||
|
||||
@@ -41,11 +41,17 @@ struct VMBootParameters;
|
||||
|
||||
enum class CDVD_SourceType : uint8_t;
|
||||
|
||||
namespace Achievements
|
||||
{
|
||||
enum class LoginRequestReason;
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(std::shared_ptr<VMBootParameters>);
|
||||
Q_DECLARE_METATYPE(std::optional<bool>);
|
||||
Q_DECLARE_METATYPE(GSRendererType);
|
||||
Q_DECLARE_METATYPE(InputBindingKey);
|
||||
Q_DECLARE_METATYPE(CDVD_SourceType);
|
||||
Q_DECLARE_METATYPE(Achievements::LoginRequestReason);
|
||||
|
||||
class EmuThread : public QThread
|
||||
{
|
||||
@@ -119,7 +125,7 @@ Q_SIGNALS:
|
||||
std::optional<WindowInfo> onAcquireRenderWindowRequested(bool recreate_window, bool fullscreen, bool render_to_main, bool surfaceless);
|
||||
void onResizeRenderWindowRequested(qint32 width, qint32 height);
|
||||
void onReleaseRenderWindowRequested();
|
||||
void onRelativeMouseModeRequested(bool enabled);
|
||||
void onMouseModeRequested(bool relative_mode, bool hide_cursor);
|
||||
|
||||
/// Called when the VM is starting initialization, but has not been completed yet.
|
||||
void onVMStarting();
|
||||
@@ -155,6 +161,9 @@ Q_SIGNALS:
|
||||
/// just signifies that the save has started, not necessarily completed.
|
||||
void onSaveStateSaved(const QString& path);
|
||||
|
||||
/// Called when achievements login is requested.
|
||||
void onAchievementsLoginRequested(Achievements::LoginRequestReason reason);
|
||||
|
||||
/// Called when achievements are reloaded/refreshed (e.g. game change, login, option change).
|
||||
void onAchievementsRefreshed(quint32 id, const QString& game_info_string, quint32 total, quint32 points);
|
||||
|
||||
|
||||
@@ -22,13 +22,22 @@
|
||||
|
||||
#include <QtWidgets/QMessageBox>
|
||||
|
||||
AchievementLoginDialog::AchievementLoginDialog(QWidget* parent)
|
||||
AchievementLoginDialog::AchievementLoginDialog(QWidget* parent, Achievements::LoginRequestReason reason)
|
||||
: QDialog(parent)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
m_ui.loginIcon->setPixmap(QIcon::fromTheme("login-box-line").pixmap(32));
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
|
||||
// Adjust text if needed based on reason.
|
||||
if (reason == Achievements::LoginRequestReason::TokenInvalid)
|
||||
{
|
||||
m_ui.instructionText->setText(
|
||||
tr("<strong>Your RetroAchievements login token is no longer valid.</strong> You must re-enter your "
|
||||
"credentials for achievements to be tracked. Your password will not be saved in PCSX2, an access token "
|
||||
"will be generated and used instead."));
|
||||
}
|
||||
|
||||
m_login = m_ui.buttonBox->addButton(tr("&Login"), QDialogButtonBox::AcceptRole);
|
||||
m_login->setEnabled(false);
|
||||
connectUi();
|
||||
|
||||
@@ -18,12 +18,17 @@
|
||||
#include <QtWidgets/QDialog>
|
||||
#include <QtWidgets/QPushButton>
|
||||
|
||||
namespace Achievements
|
||||
{
|
||||
enum class LoginRequestReason;
|
||||
}
|
||||
|
||||
class AchievementLoginDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AchievementLoginDialog(QWidget* parent);
|
||||
AchievementLoginDialog(QWidget* parent, Achievements::LoginRequestReason reason);
|
||||
~AchievementLoginDialog();
|
||||
|
||||
private Q_SLOTS:
|
||||
@@ -38,4 +43,5 @@ private:
|
||||
|
||||
Ui::AchievementLoginDialog m_ui;
|
||||
QPushButton* m_login;
|
||||
Achievements::LoginRequestReason m_reason;
|
||||
};
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<widget class="QLabel" name="instructionText">
|
||||
<property name="text">
|
||||
<string>Please enter user name and password for retroachievements.org below. Your password will not be saved in PCSX2, an access token will be generated and used instead.</string>
|
||||
</property>
|
||||
|
||||
@@ -173,7 +173,7 @@ void AchievementSettingsWidget::onLoginLogoutPressed()
|
||||
return;
|
||||
}
|
||||
|
||||
AchievementLoginDialog login(this);
|
||||
AchievementLoginDialog login(this, Achievements::LoginRequestReason::UserInitiated);
|
||||
int res = login.exec();
|
||||
if (res != 0)
|
||||
return;
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include "pcsx2/Host.h"
|
||||
#include "pcsx2/SIO/Pad/PadConfig.h"
|
||||
#include "pcsx2/SIO/Pad/Pad.h"
|
||||
|
||||
#include "Settings/ControllerBindingWidgets.h"
|
||||
#include "Settings/ControllerSettingsDialog.h"
|
||||
@@ -38,6 +38,7 @@
|
||||
|
||||
#include "ui_USBBindingWidget_DrivingForce.h"
|
||||
#include "ui_USBBindingWidget_GTForce.h"
|
||||
#include "ui_USBBindingWidget_GunCon2.h"
|
||||
|
||||
ControllerBindingWidget::ControllerBindingWidget(QWidget* parent, ControllerSettingsDialog* dialog, u32 port)
|
||||
: QWidget(parent)
|
||||
@@ -52,7 +53,7 @@ ControllerBindingWidget::ControllerBindingWidget(QWidget* parent, ControllerSett
|
||||
onTypeChanged();
|
||||
|
||||
ControllerSettingWidgetBinder::BindWidgetToInputProfileString(
|
||||
m_dialog->getProfileSettingsInterface(), m_ui.controllerType, m_config_section, "Type", g_PadConfig.GetDefaultPadType(port));
|
||||
m_dialog->getProfileSettingsInterface(), m_ui.controllerType, m_config_section, "Type", Pad::GetDefaultPadType(port));
|
||||
|
||||
connect(m_ui.controllerType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ControllerBindingWidget::onTypeChanged);
|
||||
connect(m_ui.bindings, &QPushButton::clicked, this, &ControllerBindingWidget::onBindingsClicked);
|
||||
@@ -71,14 +72,14 @@ QIcon ControllerBindingWidget::getIcon() const
|
||||
|
||||
void ControllerBindingWidget::populateControllerTypes()
|
||||
{
|
||||
for (const auto& [name, display_name] : g_PadConfig.GetControllerTypeNames())
|
||||
m_ui.controllerType->addItem(qApp->translate("Pad", display_name), QString::fromStdString(name));
|
||||
for (const auto& [name, display_name] : Pad::GetControllerTypeNames())
|
||||
m_ui.controllerType->addItem(QString::fromUtf8(display_name), QString::fromUtf8(name));
|
||||
}
|
||||
|
||||
void ControllerBindingWidget::onTypeChanged()
|
||||
{
|
||||
const bool is_initializing = (m_ui.stackedWidget->count() == 0);
|
||||
m_controller_type = m_dialog->getStringValue(m_config_section.c_str(), "Type", g_PadConfig.GetDefaultPadType(m_port_number));
|
||||
m_controller_type = m_dialog->getStringValue(m_config_section.c_str(), "Type", Pad::GetDefaultPadType(m_port_number));
|
||||
|
||||
if (m_bindings_widget)
|
||||
{
|
||||
@@ -99,9 +100,9 @@ void ControllerBindingWidget::onTypeChanged()
|
||||
m_macros_widget = nullptr;
|
||||
}
|
||||
|
||||
const PadConfig::ControllerInfo* cinfo = g_PadConfig.GetControllerInfo(m_controller_type);
|
||||
const bool has_settings = (cinfo && cinfo->num_settings > 0);
|
||||
const bool has_macros = (cinfo && cinfo->num_bindings > 0);
|
||||
const Pad::ControllerInfo* cinfo = Pad::GetControllerInfo(m_controller_type);
|
||||
const bool has_settings = (cinfo && !cinfo->settings.empty());
|
||||
const bool has_macros = (cinfo && !cinfo->bindings.empty());
|
||||
m_ui.settings->setEnabled(has_settings);
|
||||
m_ui.macros->setEnabled(has_macros);
|
||||
|
||||
@@ -123,9 +124,8 @@ void ControllerBindingWidget::onTypeChanged()
|
||||
|
||||
if (has_settings)
|
||||
{
|
||||
const std::span<const SettingInfo> settings(cinfo->settings, cinfo->num_settings);
|
||||
m_settings_widget = new ControllerCustomSettingsWidget(
|
||||
settings, m_config_section, std::string(), "Pad", getDialog(), m_ui.stackedWidget);
|
||||
cinfo->settings, m_config_section, std::string(), "Pad", getDialog(), m_ui.stackedWidget);
|
||||
m_ui.stackedWidget->addWidget(m_settings_widget);
|
||||
}
|
||||
|
||||
@@ -218,13 +218,13 @@ void ControllerBindingWidget::onClearBindingsClicked()
|
||||
{
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
g_PadConfig.ClearPortBindings(*Host::Internal::GetBaseSettingsLayer(), m_port_number);
|
||||
Pad::ClearPortBindings(*Host::Internal::GetBaseSettingsLayer(), m_port_number);
|
||||
}
|
||||
Host::CommitBaseSettingChanges();
|
||||
}
|
||||
else
|
||||
{
|
||||
g_PadConfig.ClearPortBindings(*m_dialog->getProfileSettingsInterface(), m_port_number);
|
||||
Pad::ClearPortBindings(*m_dialog->getProfileSettingsInterface(), m_port_number);
|
||||
m_dialog->getProfileSettingsInterface()->Save();
|
||||
}
|
||||
|
||||
@@ -248,14 +248,14 @@ void ControllerBindingWidget::doDeviceAutomaticBinding(const QString& device)
|
||||
{
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
result = g_PadConfig.MapController(*Host::Internal::GetBaseSettingsLayer(), m_port_number, mapping);
|
||||
result = Pad::MapController(*Host::Internal::GetBaseSettingsLayer(), m_port_number, mapping);
|
||||
}
|
||||
if (result)
|
||||
Host::CommitBaseSettingChanges();
|
||||
}
|
||||
else
|
||||
{
|
||||
result = g_PadConfig.MapController(*m_dialog->getProfileSettingsInterface(), m_port_number, mapping);
|
||||
result = Pad::MapController(*m_dialog->getProfileSettingsInterface(), m_port_number, mapping);
|
||||
if (result)
|
||||
{
|
||||
m_dialog->getProfileSettingsInterface()->Save();
|
||||
@@ -320,7 +320,7 @@ ControllerMacroEditWidget::ControllerMacroEditWidget(ControllerMacroWidget* pare
|
||||
|
||||
ControllerSettingsDialog* dialog = m_bwidget->getDialog();
|
||||
const std::string& section = m_bwidget->getConfigSection();
|
||||
const PadConfig::ControllerInfo* cinfo = g_PadConfig.GetControllerInfo(m_bwidget->getControllerType());
|
||||
const Pad::ControllerInfo* cinfo = Pad::GetControllerInfo(m_bwidget->getControllerType());
|
||||
if (!cinfo)
|
||||
{
|
||||
// Shouldn't ever happen.
|
||||
@@ -333,20 +333,19 @@ ControllerMacroEditWidget::ControllerMacroEditWidget(ControllerMacroWidget* pare
|
||||
|
||||
for (const std::string_view& button : buttons_split)
|
||||
{
|
||||
for (u32 i = 0; i < cinfo->num_bindings; i++)
|
||||
for (const InputBindingInfo& bi : cinfo->bindings)
|
||||
{
|
||||
if (button == cinfo->bindings[i].name)
|
||||
if (button == bi.name)
|
||||
{
|
||||
m_binds.push_back(&cinfo->bindings[i]);
|
||||
m_binds.push_back(&bi);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// populate list view
|
||||
for (u32 i = 0; i < cinfo->num_bindings; i++)
|
||||
for (const InputBindingInfo& bi : cinfo->bindings)
|
||||
{
|
||||
const InputBindingInfo& bi = cinfo->bindings[i];
|
||||
if (bi.bind_type == InputBindingInfo::Type::Motor)
|
||||
continue;
|
||||
|
||||
@@ -358,8 +357,12 @@ ControllerMacroEditWidget::ControllerMacroEditWidget(ControllerMacroWidget* pare
|
||||
|
||||
ControllerSettingWidgetBinder::BindWidgetToInputProfileNormalized(
|
||||
dialog->getProfileSettingsInterface(), m_ui.pressure, section, fmt::format("Macro{}Pressure", index + 1u), 100.0f, 1.0f);
|
||||
ControllerSettingWidgetBinder::BindWidgetToInputProfileNormalized(
|
||||
dialog->getProfileSettingsInterface(), m_ui.deadzone, section, fmt::format("Macro{}Deadzone", index + 1u), 100.0f, 0.0f);
|
||||
connect(m_ui.pressure, &QSlider::valueChanged, this, &ControllerMacroEditWidget::onPressureChanged);
|
||||
connect(m_ui.deadzone, &QSlider::valueChanged, this, &ControllerMacroEditWidget::onDeadzoneChanged);
|
||||
onPressureChanged();
|
||||
onDeadzoneChanged();
|
||||
|
||||
m_frequency = dialog->getIntValue(section.c_str(), fmt::format("Macro{}Frequency", index + 1u).c_str(), 0);
|
||||
updateFrequencyText();
|
||||
@@ -392,6 +395,11 @@ void ControllerMacroEditWidget::onPressureChanged()
|
||||
m_ui.pressureValue->setText(tr("%1%").arg(m_ui.pressure->value()));
|
||||
}
|
||||
|
||||
void ControllerMacroEditWidget::onDeadzoneChanged()
|
||||
{
|
||||
m_ui.deadzoneValue->setText(tr("%1%").arg(m_ui.deadzone->value()));
|
||||
}
|
||||
|
||||
void ControllerMacroEditWidget::onSetFrequencyClicked()
|
||||
{
|
||||
bool okay;
|
||||
@@ -431,12 +439,12 @@ void ControllerMacroEditWidget::updateFrequencyText()
|
||||
void ControllerMacroEditWidget::updateBinds()
|
||||
{
|
||||
ControllerSettingsDialog* dialog = m_bwidget->getDialog();
|
||||
const PadConfig::ControllerInfo* cinfo = g_PadConfig.GetControllerInfo(m_bwidget->getControllerType());
|
||||
const Pad::ControllerInfo* cinfo = Pad::GetControllerInfo(m_bwidget->getControllerType());
|
||||
if (!cinfo)
|
||||
return;
|
||||
|
||||
std::vector<const InputBindingInfo*> new_binds;
|
||||
for (u32 i = 0, bind_index = 0; i < cinfo->num_bindings; i++)
|
||||
for (u32 i = 0, bind_index = 0; i < static_cast<u32>(cinfo->bindings.size()); i++)
|
||||
{
|
||||
const InputBindingInfo& bi = cinfo->bindings[i];
|
||||
if (bi.bind_type == InputBindingInfo::Type::Motor)
|
||||
@@ -801,16 +809,15 @@ QIcon ControllerBindingWidget_Base::getIcon() const
|
||||
|
||||
void ControllerBindingWidget_Base::initBindingWidgets()
|
||||
{
|
||||
const PadConfig::ControllerInfo* cinfo = g_PadConfig.GetControllerInfo(getControllerType());
|
||||
const Pad::ControllerInfo* cinfo = Pad::GetControllerInfo(getControllerType());
|
||||
if (!cinfo)
|
||||
return;
|
||||
|
||||
const std::string& config_section = getConfigSection();
|
||||
SettingsInterface* sif = getDialog()->getProfileSettingsInterface();
|
||||
|
||||
for (u32 i = 0; i < cinfo->num_bindings; i++)
|
||||
for (const InputBindingInfo& bi : cinfo->bindings)
|
||||
{
|
||||
const InputBindingInfo& bi = cinfo->bindings[i];
|
||||
if (bi.bind_type == InputBindingInfo::Type::Axis || bi.bind_type == InputBindingInfo::Type::HalfAxis ||
|
||||
bi.bind_type == InputBindingInfo::Type::Button || bi.bind_type == InputBindingInfo::Type::Pointer ||
|
||||
bi.bind_type == InputBindingInfo::Type::Device)
|
||||
@@ -1269,6 +1276,11 @@ USBBindingWidget* USBBindingWidget::createInstance(
|
||||
has_template = true;
|
||||
}
|
||||
}
|
||||
else if (type == "guncon2")
|
||||
{
|
||||
Ui::USBBindingWidget_GunCon2().setupUi(widget);
|
||||
has_template = true;
|
||||
}
|
||||
|
||||
if (has_template)
|
||||
widget->bindWidgets(bindings);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pcsx2/SIO/Pad/PadMacros.h"
|
||||
#include "pcsx2/SIO/Pad/PadTypes.h"
|
||||
|
||||
#include <QtWidgets/QWidget>
|
||||
|
||||
@@ -92,7 +92,7 @@ public:
|
||||
void updateListItem(u32 index);
|
||||
|
||||
private:
|
||||
static constexpr u32 NUM_MACROS = PadMacros::NUM_MACRO_BUTTONS_PER_CONTROLLER;
|
||||
static constexpr u32 NUM_MACROS = Pad::NUM_MACRO_BUTTONS_PER_CONTROLLER;
|
||||
|
||||
void createWidgets(ControllerBindingWidget* parent);
|
||||
|
||||
@@ -115,6 +115,7 @@ public:
|
||||
|
||||
private Q_SLOTS:
|
||||
void onPressureChanged();
|
||||
void onDeadzoneChanged();
|
||||
void onSetFrequencyClicked();
|
||||
void updateBinds();
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>691</width>
|
||||
<height>547</height>
|
||||
<height>433</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -83,6 +83,9 @@
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksBelow</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
@@ -123,6 +126,46 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<layout class="QHBoxLayout" name="deadzoneLayout" stretch="0,1,0">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Deadzone:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="deadzone">
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksBelow</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="deadzoneValue">
|
||||
<property name="text">
|
||||
<string>100%</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "Settings/HotkeySettingsWidget.h"
|
||||
|
||||
#include "pcsx2/INISettingsInterface.h"
|
||||
#include "pcsx2/SIO/Pad/PadConfig.h"
|
||||
#include "pcsx2/SIO/Pad/Pad.h"
|
||||
#include "pcsx2/SIO/Sio.h"
|
||||
#include "pcsx2/VMManager.h"
|
||||
|
||||
@@ -130,7 +130,7 @@ void ControllerSettingsDialog::onNewProfileClicked()
|
||||
{
|
||||
// from global
|
||||
auto lock = Host::GetSettingsLock();
|
||||
g_PadConfig.CopyConfiguration(&temp_si, *Host::Internal::GetBaseSettingsLayer(), true, true, false);
|
||||
Pad::CopyConfiguration(&temp_si, *Host::Internal::GetBaseSettingsLayer(), true, true, false);
|
||||
USB::CopyConfiguration(&temp_si, *Host::Internal::GetBaseSettingsLayer(), true, true);
|
||||
}
|
||||
else
|
||||
@@ -138,7 +138,7 @@ void ControllerSettingsDialog::onNewProfileClicked()
|
||||
// from profile
|
||||
const bool copy_hotkey_bindings = m_profile_interface->GetBoolValue("Pad", "UseProfileHotkeyBindings", false);
|
||||
temp_si.SetBoolValue("Pad", "UseProfileHotkeyBindings", copy_hotkey_bindings);
|
||||
g_PadConfig.CopyConfiguration(&temp_si, *m_profile_interface, true, true, copy_hotkey_bindings);
|
||||
Pad::CopyConfiguration(&temp_si, *m_profile_interface, true, true, copy_hotkey_bindings);
|
||||
USB::CopyConfiguration(&temp_si, *m_profile_interface, true, true);
|
||||
}
|
||||
}
|
||||
@@ -167,7 +167,7 @@ void ControllerSettingsDialog::onLoadProfileClicked()
|
||||
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
g_PadConfig.CopyConfiguration(Host::Internal::GetBaseSettingsLayer(), *m_profile_interface, true, true, false);
|
||||
Pad::CopyConfiguration(Host::Internal::GetBaseSettingsLayer(), *m_profile_interface, true, true, false);
|
||||
USB::CopyConfiguration(Host::Internal::GetBaseSettingsLayer(), *m_profile_interface, true, true);
|
||||
}
|
||||
Host::CommitBaseSettingChanges();
|
||||
@@ -403,8 +403,8 @@ void ControllerSettingsDialog::createWidgets()
|
||||
m_port_bindings[global_slot] = new ControllerBindingWidget(m_ui.settingsContainer, this, global_slot);
|
||||
m_ui.settingsContainer->addWidget(m_port_bindings[global_slot]);
|
||||
|
||||
const PadConfig::ControllerInfo* ci = g_PadConfig.GetControllerInfo(m_port_bindings[global_slot]->getControllerType());
|
||||
const QString display_name(ci ? qApp->translate("Pad", ci->display_name) : QStringLiteral("Unknown"));
|
||||
const Pad::ControllerInfo* ci = Pad::GetControllerInfo(m_port_bindings[global_slot]->getControllerType());
|
||||
const QString display_name(QString::fromUtf8(ci ? ci->GetLocalizedName() : "Unknown"));
|
||||
|
||||
QListWidgetItem* item = new QListWidgetItem();
|
||||
//: Controller Port is an official term from Sony. Find the official translation for your language inside the console's manual.
|
||||
@@ -459,8 +459,8 @@ void ControllerSettingsDialog::updateListDescription(u32 global_slot, Controller
|
||||
const auto [port, slot] = sioConvertPadToPortAndSlot(global_slot);
|
||||
const bool mtap_enabled = getBoolValue("Pad", (port == 0) ? "MultitapPort1" : "MultitapPort2", false);
|
||||
|
||||
const PadConfig::ControllerInfo* ci = g_PadConfig.GetControllerInfo(widget->getControllerType());
|
||||
const QString display_name(ci ? qApp->translate("Pad", ci->display_name) : QStringLiteral("Unknown"));
|
||||
const Pad::ControllerInfo* ci = Pad::GetControllerInfo(widget->getControllerType());
|
||||
const QString display_name = QString::fromUtf8(ci ? ci->GetLocalizedName() : "Unknown");
|
||||
|
||||
//: Controller Port is an official term from Sony. Find the official translation for your language inside the console's manual.
|
||||
item->setText(mtap_enabled ? (tr("Controller Port %1%2\n%3").arg(port + 1).arg(s_mtap_slot_names[slot]).arg(display_name)) :
|
||||
@@ -492,7 +492,7 @@ void ControllerSettingsDialog::updateListDescription(u32 port, USBDeviceWidget*
|
||||
|
||||
void ControllerSettingsDialog::refreshProfileList()
|
||||
{
|
||||
const std::vector<std::string> names(g_PadConfig.GetInputProfileNames());
|
||||
const std::vector<std::string> names = Pad::GetInputProfileNames();
|
||||
|
||||
QSignalBlocker sb(m_ui.currentProfile);
|
||||
m_ui.currentProfile->clear();
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "pcsx2/SIO/Pad/PadConfig.h"
|
||||
#include "pcsx2/SIO/Pad/Pad.h"
|
||||
#include "GameSummaryWidget.h"
|
||||
#include "SettingsDialog.h"
|
||||
#include "MainWindow.h"
|
||||
@@ -69,7 +69,7 @@ GameSummaryWidget::~GameSummaryWidget() = default;
|
||||
|
||||
void GameSummaryWidget::populateInputProfiles()
|
||||
{
|
||||
for (const std::string& name : g_PadConfig.GetInputProfileNames())
|
||||
for (const std::string& name : Pad::GetInputProfileNames())
|
||||
m_ui.inputProfile->addItem(QString::fromStdString(name));
|
||||
}
|
||||
|
||||
|
||||
@@ -218,12 +218,12 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.halfPixelOffset, "EmuCore/GS", "UserHacks_HalfPixelOffset", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.roundSprite, "EmuCore/GS", "UserHacks_round_sprite_offset", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.bilinearHack, "EmuCore/GS", "UserHacks_BilinearHack", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.textureOffsetX, "EmuCore/GS", "UserHacks_TCOffsetX", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.textureOffsetY, "EmuCore/GS", "UserHacks_TCOffsetY", 0);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.alignSprite, "EmuCore/GS", "UserHacks_align_sprite_X", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.mergeSprite, "EmuCore/GS", "UserHacks_merge_pp_sprite", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.wildHack, "EmuCore/GS", "UserHacks_WildHack", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.bilinearHack, "EmuCore/GS", "UserHacks_BilinearHack", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.nativePaletteDraw, "EmuCore/GS", "UserHacks_NativePaletteDraw", false);
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Texture Replacements
|
||||
|
||||
@@ -1168,14 +1168,14 @@
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="textureOffsetLabel">
|
||||
<property name="text">
|
||||
<string>Texture Offsets:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<item row="3" column="1">
|
||||
<layout class="QHBoxLayout" name="textureOffsetLayout" stretch="0,1,0,1">
|
||||
<item>
|
||||
<widget class="QLabel" name="textureOffsetXLabel">
|
||||
@@ -1207,7 +1207,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<item row="4" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="alignSprite">
|
||||
@@ -1216,20 +1216,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="bilinearHack">
|
||||
<property name="text">
|
||||
<string>Bilinear Dirty Upscale</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="mergeSprite">
|
||||
<property name="text">
|
||||
<string>Merge Sprite</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="nativePaletteDraw">
|
||||
<property name="text">
|
||||
@@ -1244,8 +1230,41 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="mergeSprite">
|
||||
<property name="text">
|
||||
<string>Merge Sprite</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Bilinear Dirty Upscale:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="bilinearHack">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Automatic (Default)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Force Bilinear</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Force Nearest</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab">
|
||||
|
||||
@@ -0,0 +1,779 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>USBBindingWidget_GunCon2</class>
|
||||
<widget class="QWidget" name="USBBindingWidget_GunCon2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1000</width>
|
||||
<height>400</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>1000</width>
|
||||
<height>400</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_16">
|
||||
<item row="2" column="2" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_16">
|
||||
<property name="title">
|
||||
<string>Buttons</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_10">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_19">
|
||||
<property name="title">
|
||||
<string>A</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_19">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="InputBindingWidget" name="A">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QGroupBox" name="groupBox_20">
|
||||
<property name="title">
|
||||
<string>C</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_20">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="InputBindingWidget" name="C">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_23">
|
||||
<property name="title">
|
||||
<string>Start</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_23">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="InputBindingWidget" name="Start">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_35">
|
||||
<property name="title">
|
||||
<string>Select</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_35">
|
||||
<item row="0" column="0">
|
||||
<widget class="InputBindingWidget" name="Select">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_18">
|
||||
<property name="title">
|
||||
<string>B</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_18">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="InputBindingWidget" name="B">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3" rowspan="2">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>D-Pad</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_5">
|
||||
<property name="title">
|
||||
<string>Down</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="InputBindingWidget" name="Down">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>Left</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="InputBindingWidget" name="Left">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Up</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="InputBindingWidget" name="Up">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_4">
|
||||
<property name="title">
|
||||
<string>Right</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="InputBindingWidget" name="Right">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QGroupBox" name="groupBox_15">
|
||||
<property name="title">
|
||||
<string>Pointer Setup</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string><p>By default, GunCon2 will use the mouse pointer. To use the mouse, you <strong>do not</strong> need to configure any bindings apart from the trigger and buttons.</p>
|
||||
|
||||
<p>If you want to use a controller, or lightgun which simulates a controller instead of a mouse, then you should bind it to Relative Aiming. Otherwise, Relative Aiming should be <strong>left unbound</strong>.</p></string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4" rowspan="3">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0" rowspan="3">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="2" rowspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_10">
|
||||
<property name="title">
|
||||
<string extracomment="Try to use Sony's official terminology for this. A good place to start would be in the console or the DualShock 2's manual. If this element was officially translated to your language by Sony in later DualShocks, you may use that term.">Relative Aiming</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_11">
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_11">
|
||||
<property name="title">
|
||||
<string>Down</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_12">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="InputBindingWidget" name="RelativeDown">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_12">
|
||||
<property name="title">
|
||||
<string>Left</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_13">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="InputBindingWidget" name="RelativeLeft">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_13">
|
||||
<property name="title">
|
||||
<string>Up</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_14">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="InputBindingWidget" name="RelativeUp">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_14">
|
||||
<property name="title">
|
||||
<string>Right</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_15">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="InputBindingWidget" name="RelativeRight">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" rowspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_6">
|
||||
<property name="title">
|
||||
<string>Trigger</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_9">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_7">
|
||||
<property name="title">
|
||||
<string>Trigger</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_6">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="InputBindingWidget" name="Trigger">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QGroupBox" name="groupBox_8">
|
||||
<property name="title">
|
||||
<string>Shoot Offscreen</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_7">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="InputBindingWidget" name="ShootOffscreen">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_9">
|
||||
<property name="title">
|
||||
<string>Calibration Shot</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_8">
|
||||
<item row="0" column="1">
|
||||
<widget class="InputBindingWidget" name="Recalibrate">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>125</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="3">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Calibration shot is required to pass the setup screen in some games.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="5">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>InputBindingWidget</class>
|
||||
<extends>QPushButton</extends>
|
||||
<header>Settings/InputBindingWidget.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../resources/resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "pcsx2/SIO/Pad/PadConfig.h"
|
||||
#include "pcsx2/SIO/Pad/Pad.h"
|
||||
#include "QtHost.h"
|
||||
#include "QtUtils.h"
|
||||
#include "SettingWidgetBinder.h"
|
||||
@@ -414,10 +414,10 @@ void SetupWizardDialog::setupControllerPage()
|
||||
const std::string section = fmt::format("Pad{}", port + 1);
|
||||
const PadWidgets& w = pad_widgets[port];
|
||||
|
||||
for (const auto& [name, display_name] : g_PadConfig.GetControllerTypeNames())
|
||||
w.type_combo->addItem(qApp->translate("Pad", display_name), QString::fromStdString(name));
|
||||
for (const auto& [name, display_name] : Pad::GetControllerTypeNames())
|
||||
w.type_combo->addItem(QString::fromUtf8(display_name), QString::fromUtf8(name));
|
||||
ControllerSettingWidgetBinder::BindWidgetToInputProfileString(
|
||||
nullptr, w.type_combo, section, "Type", g_PadConfig.GetDefaultPadType(port));
|
||||
nullptr, w.type_combo, section, "Type", Pad::GetDefaultPadType(port));
|
||||
|
||||
w.mapping_result->setText((port == 0) ? tr("Default (Keyboard)") : tr("Default (None)"));
|
||||
|
||||
@@ -473,7 +473,7 @@ void SetupWizardDialog::doDeviceAutomaticBinding(u32 port, QLabel* update_label,
|
||||
bool result;
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
result = g_PadConfig.MapController(*Host::Internal::GetBaseSettingsLayer(), port, mapping);
|
||||
result = Pad::MapController(*Host::Internal::GetBaseSettingsLayer(), port, mapping);
|
||||
}
|
||||
if (!result)
|
||||
return;
|
||||
|
||||
@@ -258,6 +258,7 @@ std::vector<std::pair<QString, QString>> QtHost::GetAvailableLanguageList()
|
||||
{QStringLiteral("Italiano (it-IT)"), QStringLiteral("it-IT")},
|
||||
{QStringLiteral("日本語 (ja-JP)"), QStringLiteral("ja-JP")},
|
||||
{QStringLiteral("한국어 (ko-KR)"), QStringLiteral("ko-KR")},
|
||||
{QStringLiteral("Latvija (lv-LV)"), QStringLiteral("lv-LV")},
|
||||
{QStringLiteral("Nederlands (nl-NL)"), QStringLiteral("nl-NL")},
|
||||
{QStringLiteral("Norsk (no-NO)"), QStringLiteral("no-NO")},
|
||||
{QStringLiteral("Polski (pl-PL)"), QStringLiteral("pl-PL")},
|
||||
|
||||
@@ -374,6 +374,9 @@
|
||||
</QtUi>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtUi Include="Settings\USBBindingWidget_GunCon2.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
<QtUi Include="SetupWizardDialog.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
@@ -395,8 +398,12 @@
|
||||
<QtUi Include="Settings\GamePatchSettingsWidget.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
<None Include="Settings\USBBindingWidget_DrivingForce.ui" />
|
||||
<None Include="Settings\USBBindingWidget_GTForce.ui" />
|
||||
<QtUi Include="Settings\USBBindingWidget_DrivingForce.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\USBBindingWidget_GTForce.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\USBDeviceWidget.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
|
||||
@@ -624,17 +624,20 @@
|
||||
<Filter>Settings</Filter>
|
||||
</QtUi>
|
||||
<QtUi Include="SetupWizardDialog.ui" />
|
||||
<QtUi Include="Settings\USBBindingWidget_DrivingForce.ui">
|
||||
<Filter>Settings</Filter>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\USBBindingWidget_GTForce.ui">
|
||||
<Filter>Settings</Filter>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\USBBindingWidget_GunCon2.ui">
|
||||
<Filter>Settings</Filter>
|
||||
</QtUi>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Settings\FolderSettingsWidget.ui">
|
||||
<Filter>Settings</Filter>
|
||||
</None>
|
||||
<None Include="Settings\USBBindingWidget_GTForce.ui">
|
||||
<Filter>Settings</Filter>
|
||||
</None>
|
||||
<None Include="Settings\USBBindingWidget_DrivingForce.ui">
|
||||
<Filter>Settings</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtTs Include="Translations\pcsx2-qt_en.ts">
|
||||
|
||||
@@ -1 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="cheats" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.cls-1{fill:none;}.cls-2{fill-rule:evenodd;}</style></defs><g id="tela"><g><path class="cls-1" d="M0,0H24V24H0V0Z"/><path d="M2,4c0-.5,.5-1,1-1H21c.5,0,1,.4,1,1v14c0,.5-.5,1-1,1H3c-.5,0-1-.5-1-1h0V4Zm2,1v12H20V5H4Zm1,15h14v2H5v-2Z"/></g></g><g id="by_maxihplay"><path class="cls-2" d="M13.4,6.7c-1.1-1.2-2.6-.9-4,0-1.4-.9-2.9-1.1-4,0-.3,.4-.4,.9-.5,1.4-.2,1.1,.3,2.3,1.1,3.1l3.4,3.5,3.4-3.5c.8-.8,1.3-1.9,1.1-3.1,0-.5-.1-1-.5-1.4Z"/><path d="M17.1,12.2c.6,0,1,.2,1.5,.6,.4,.4,.6,.9,.6,1.5s-.2,1.1-.6,1.5c-.4,.4-.9,.6-1.5,.6s-1.3-.4-1.8-1c-.6,.7-1.2,1-1.8,1s-1.1-.2-1.4-.6c-.4-.4-.6-.9-.6-1.5s.2-1.1,.6-1.5c.4-.4,.9-.6,1.4-.6,.6,0,1.3,.4,1.8,1.1,.6-.8,1.2-1.1,1.8-1.1Zm-3.7,3c.4,0,.8-.3,1.2-.9-.4-.6-.8-.9-1.2-.9-.2,0-.3,0-.5,.1s-.3,.2-.3,.3-.1,.3-.1,.4c0,.2,.1,.5,.3,.6,.1,.3,.3,.4,.6,.4h0Zm3.9,0h.3c.1,0,.2-.1,.3-.1s.1-.1,.1-.2,.1-.2,.1-.3v-.3c0-.2-.1-.5-.3-.6-.2-.2-.4-.3-.7-.3-.4,0-.8,.3-1.2,.9,.6,.6,1,.9,1.4,.9h0Z"/></g></svg>
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="cheats" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.cls-1{fill:none;}</style></defs><path class="cls-1" d="M0,0H24V24H0V0Z"/><g id="by_maxihplay"><path d="M14.38,5.18c.73,0,1.32,.26,1.87,.82,2.15,3.05-.83,6.31-5.25,10.57-.43,.41-.85,.82-1.25,1.22l-1.88-1.93-2.39-2.46c-.39-.4-.78-.8-1.18-1.13l.04-.04c-1.85-1.78-1.93-3.85-1.39-5.18,.22-.55,.92-1.83,2.53-1.83,.9,0,1.94,.41,3,1.17l1.22,.88,1.26-.81c1.29-.83,2.48-1.27,3.43-1.27m0-2.2c-1.49,0-3.08,.63-4.62,1.62-1.55-1.12-3.01-1.59-4.29-1.59-4.76,0-7.07,6.54-2.67,10.8,0,0,6.96,7.16,6.96,7.16,3.41-4.03,12.75-10.19,8.18-16.37-1.05-1.14-2.27-1.62-3.57-1.62h0Z"/><path d="M20.93,16.35c.72,0,1.34,.27,1.85,.8,.51,.53,.77,1.17,.77,1.92s-.26,1.39-.77,1.92-1.13,.8-1.85,.8c-.84,0-1.61-.45-2.34-1.34-.72,.9-1.5,1.34-2.34,1.34-.72,0-1.34-.27-1.85-.8s-.77-1.17-.77-1.92,.26-1.39,.77-1.92c.51-.53,1.13-.8,1.85-.8,.84,0,1.61,.45,2.34,1.34,.72-.9,1.5-1.34,2.34-1.34Zm-4.67,3.81c.48,0,.97-.36,1.45-1.09-.48-.73-.97-1.09-1.45-1.09-.21,0-.39,.05-.56,.14s-.31,.23-.41,.4-.15,.35-.15,.54c0,.3,.11,.55,.33,.77,.22,.22,.49,.32,.8,.32Zm4.67,0c.12,0,.24-.02,.36-.05s.22-.09,.31-.15,.18-.15,.25-.24,.13-.19,.16-.31,.05-.23,.05-.34c0-.3-.11-.55-.33-.77-.22-.22-.49-.32-.8-.32-.48,0-.97,.36-1.45,1.09,.48,.73,.97,1.09,1.45,1.09Z"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.3 KiB |
@@ -1,81 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
id="Agrupar_1_copiar"
|
||||
data-name="Agrupar 1 copiar"
|
||||
width="384"
|
||||
height="384"
|
||||
viewBox="0 0 384 384"
|
||||
version="1.1"
|
||||
sodipodi:docname="floppy-in-line-black.svg"
|
||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview11"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#ffffff"
|
||||
borderopacity="1"
|
||||
inkscape:showpageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="1"
|
||||
inkscape:deskcolor="#505050"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.5733333"
|
||||
inkscape:cx="118.53814"
|
||||
inkscape:cy="137.92373"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="956"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="42"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Agrupar_1_copiar" />
|
||||
<defs
|
||||
id="defs4">
|
||||
<style
|
||||
id="style2">
|
||||
.cls-1, .cls-2, .cls-3 {
|
||||
fill: none;
|
||||
stroke: #fff;
|
||||
fill-rule: evenodd;
|
||||
}
|
||||
|
||||
.cls-1 {
|
||||
stroke-width: 23px;
|
||||
}
|
||||
|
||||
.cls-2 {
|
||||
stroke-width: 25px;
|
||||
}
|
||||
|
||||
.cls-3 {
|
||||
stroke-width: 33px;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path
|
||||
id="Forma_1"
|
||||
data-name="Forma 1"
|
||||
class="cls-1"
|
||||
d="m 325.91068,295.77571 c 0,0 0.24169,10.49815 0.73613,22.57934 0.49445,12.08118 -9.96947,12.17987 -9.96947,12.17987 0,0 -243.07578,-1.34336 -251.339361,-1.10772 -8.263582,0.23564 -8.86175,-9.96443 -8.86175,-9.96443 V 74.766689 c 0,0 1.492399,-7.461996 8.86175,-8.86175 7.36935,-1.399754 214.801761,0 214.801761,0 l 46.50304,46.503041 0.27492,86.6941"
|
||||
style="stroke:#000000;stroke-width:23;stroke-dasharray:none" />
|
||||
<path
|
||||
id="Forma_2"
|
||||
data-name="Forma 2"
|
||||
class="cls-1"
|
||||
d="m 127.34606,65.908967 1.10771,88.578223 c 0,0 -1.75825,2.69881 5.5386,3.32316 7.29684,0.62435 121.79468,1.10772 121.79468,1.10772 a 5.4681025,5.4681025 0 0 0 3.32316,-5.53859 c -0.0866,-4.38556 0,-88.578232 0,-88.578232"
|
||||
style="stroke:#000000;stroke-width:23;stroke-dasharray:none" />
|
||||
<path
|
||||
id="Forma_5"
|
||||
data-name="Forma 5"
|
||||
class="cls-2"
|
||||
d="m 224.20196,202.12313 c -0.44409,0.33533 -53.03656,46.50304 -53.03656,46.50304 l 51.02253,47.14954"
|
||||
style="stroke:#000000;stroke-width:25;stroke-dasharray:none" />
|
||||
<path
|
||||
id="Forma_6"
|
||||
data-name="Forma 6"
|
||||
class="cls-3"
|
||||
d="M 175.86514,248.44591 339.0019,247.43889"
|
||||
style="stroke:#000000;stroke-width:33;stroke-dasharray:none" />
|
||||
</svg>
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="PCSX2_-_load" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 384"><defs><style>.cls-1{stroke-width:28px;}.cls-1,.cls-2{fill:none;stroke:#000;}.cls-2{stroke-width:29px;}</style></defs><g id="By_maxihplay"><path id="Forma_5" class="cls-1" d="M217.39,192.85c-.45,.33-52.68,43.98-52.68,43.98l52.04,47.7"/><path id="Forma_6" class="cls-1" d="M173.41,238.01l161.32-.73"/><path id="Forma_2" class="cls-1" d="M114.53,59.5l1.11,89.07s-1.77,2.71,5.57,3.34c7.33,.63,122.47,1.11,122.47,1.11,2.21-.93,3.56-3.18,3.34-5.57-.09-4.41,0-89.07,0-89.07"/><path id="Forma_1" class="cls-2" d="M322.31,290.47s-.12,21.8-.1,22.87c.31,13.33-11.31,12.25-11.31,12.25,0,0-244.42-1.35-252.73-1.11s-8.91-10.02-8.91-10.02V68.41s1.5-7.5,8.91-8.91,215.99,0,215.99,0l48.05,46.76,.27,72.95"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 818 B |
@@ -1,81 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
id="Agrupar_1"
|
||||
data-name="Agrupar 1"
|
||||
width="384"
|
||||
height="384"
|
||||
viewBox="0 0 384 384"
|
||||
version="1.1"
|
||||
sodipodi:docname="floppy-out-line-black.svg"
|
||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview11"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#ffffff"
|
||||
borderopacity="1"
|
||||
inkscape:showpageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="1"
|
||||
inkscape:deskcolor="#505050"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.2683333"
|
||||
inkscape:cx="158.08148"
|
||||
inkscape:cy="207.35874"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="956"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="42"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Agrupar_1" />
|
||||
<defs
|
||||
id="defs4">
|
||||
<style
|
||||
id="style2">
|
||||
.cls-1, .cls-2, .cls-3 {
|
||||
fill: none;
|
||||
stroke: #fff;
|
||||
fill-rule: evenodd;
|
||||
}
|
||||
|
||||
.cls-1 {
|
||||
stroke-width: 23px;
|
||||
}
|
||||
|
||||
.cls-2 {
|
||||
stroke-width: 25px;
|
||||
}
|
||||
|
||||
.cls-3 {
|
||||
stroke-width: 33px;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path
|
||||
id="Forma_1"
|
||||
data-name="Forma 1"
|
||||
class="cls-1"
|
||||
d="m 325.86348,300.4432 c 0,0 0.24183,10.50408 0.73655,22.59208 0.49472,12.08801 -9.9751,12.18675 -9.9751,12.18675 0,0 -243.213007,-1.34412 -251.481254,-1.10834 -8.268247,0.23577 -8.866752,-9.97006 -8.866752,-9.97006 V 79.309414 c 0,0 1.493241,-7.466209 8.866752,-8.866753 7.373511,-1.400544 214.923034,0 214.923034,0 l 46.52929,46.529289 0.27507,86.74304"
|
||||
style="stroke:#000000;stroke-width:23;stroke-dasharray:none" />
|
||||
<path
|
||||
id="Forma_2"
|
||||
data-name="Forma 2"
|
||||
class="cls-1"
|
||||
d="m 127.18676,70.446691 1.10835,88.628229 c 0,0 -1.75925,2.70033 5.54172,3.32503 7.30096,0.62471 121.86344,1.10835 121.86344,1.10835 a 5.4711894,5.4711894 0 0 0 3.32503,-5.54172 c -0.0867,-4.38804 0,-88.628233 0,-88.628233"
|
||||
style="stroke:#000000;stroke-width:23;stroke-dasharray:none" />
|
||||
<path
|
||||
id="Forma_5"
|
||||
data-name="Forma 5"
|
||||
class="cls-2"
|
||||
d="m 267.20286,207.74533 c 1.47007,1.13656 53.06651,44.51412 53.06651,44.51412 l -51.05134,47.17617"
|
||||
style="stroke:#000000;stroke-width:25;stroke-dasharray:none" />
|
||||
<path
|
||||
id="Forma_6"
|
||||
data-name="Forma 6"
|
||||
class="cls-3"
|
||||
d="M 315.56697,253.08668 152.33811,252.0791"
|
||||
style="stroke:#000000;stroke-width:33;stroke-dasharray:none" />
|
||||
</svg>
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="PCSX2_-_load" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 384"><defs><style>.cls-1{stroke-width:28px;}.cls-1,.cls-2{fill:none;stroke:#000;}.cls-2{stroke-width:29px;}</style></defs><g id="By_maxihplay"><path id="Forma_6" class="cls-1" d="M309.03,236.01l-132.24-.6"/><path id="Forma_5" class="cls-1" d="M261.32,188.75c.45,.33,52.68,43.98,52.68,43.98l-52.04,47.7"/><path id="Forma_2" class="cls-1" d="M114.53,59.5l1.11,89.07s-1.77,2.71,5.57,3.34c7.33,.63,122.47,1.11,122.47,1.11,2.21-.93,3.56-3.18,3.34-5.57-.09-4.41,0-89.07,0-89.07"/><path id="Forma_1" class="cls-2" d="M322.31,290.47s-.12,21.8-.1,22.87c.31,13.33-11.31,12.25-11.31,12.25,0,0-244.42-1.35-252.73-1.11s-8.91-10.02-8.91-10.02V68.41s1.5-7.5,8.91-8.91,215.99,0,215.99,0l48.05,46.76,.27,72.95"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 818 B |
@@ -1 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="cheats" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.cls-1,.cls-2{fill:#fff;}.cls-2{fill-rule:evenodd;}.cls-3{fill:none;}</style></defs><g id="tela"><g><path class="cls-3" d="M0,0H24V24H0V0Z"/><path class="cls-1" d="M2,4c0-.5,.5-1,1-1H21c.5,0,1,.4,1,1v14c0,.5-.5,1-1,1H3c-.5,0-1-.5-1-1h0V4Zm2,1v12H20V5H4Zm1,15h14v2H5v-2Z"/></g></g><g id="by_maxihplay"><path class="cls-2" d="M13.4,6.7c-1.1-1.2-2.6-.71-4,.19-1.4-.9-2.9-1.29-4-.19-.3,.4-.4,.9-.5,1.4-.2,1.1,.3,2.3,1.1,3.1l3.4,3.5,3.4-3.5c.8-.8,1.3-1.9,1.1-3.1,0-.5-.1-1-.5-1.4Z"/><path class="cls-1" d="M17.1,12.2c.6,0,1,.2,1.5,.6,.4,.4,.6,.9,.6,1.5s-.2,1.1-.6,1.5c-.4,.4-.9,.6-1.5,.6s-1.3-.4-1.8-1c-.6,.7-1.2,1-1.8,1s-1.1-.2-1.4-.6c-.4-.4-.6-.9-.6-1.5s.2-1.1,.6-1.5c.4-.4,.9-.6,1.4-.6,.6,0,1.3,.4,1.8,1.1,.6-.8,1.2-1.1,1.8-1.1Zm-3.7,3c.4,0,.8-.3,1.2-.9-.4-.6-.8-.9-1.2-.9-.2,0-.3,0-.5,.1s-.3,.2-.3,.3-.1,.3-.1,.4c0,.2,.1,.5,.3,.6,.1,.3,.3,.4,.6,.4h0Zm3.9,0h.3c.1,0,.2-.1,.3-.1s.1-.1,.1-.2,.1-.2,.1-.3v-.3c0-.2-.1-.5-.3-.6-.2-.2-.4-.3-.7-.3-.4,0-.8,.3-1.2,.9,.6,.6,1,.9,1.4,.9h0Z"/></g></svg>
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="cheats" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:none;}</style></defs><path class="cls-2" d="M0,0H24V24H0V0Z"/><g id="by_maxihplay"><path class="cls-1" d="M14.38,5.18c.73,0,1.32,.26,1.87,.82,2.15,3.05-.83,6.31-5.25,10.57-.43,.41-.85,.82-1.25,1.22l-1.88-1.93-2.39-2.46c-.39-.4-.78-.8-1.18-1.13l.04-.04c-1.85-1.78-1.93-3.85-1.39-5.18,.22-.55,.92-1.83,2.53-1.83,.9,0,1.94,.41,3,1.17l1.22,.88,1.26-.81c1.29-.83,2.48-1.27,3.43-1.27m0-2.2c-1.49,0-3.08,.63-4.62,1.62-1.55-1.12-3.01-1.59-4.29-1.59-4.76,0-7.07,6.54-2.67,10.8,0,0,6.96,7.16,6.96,7.16,3.41-4.03,12.75-10.19,8.18-16.37-1.05-1.14-2.27-1.62-3.57-1.62h0Z"/><path class="cls-1" d="M20.93,16.35c.72,0,1.34,.27,1.85,.8,.51,.53,.77,1.17,.77,1.92s-.26,1.39-.77,1.92-1.13,.8-1.85,.8c-.84,0-1.61-.45-2.34-1.34-.72,.9-1.5,1.34-2.34,1.34-.72,0-1.34-.27-1.85-.8s-.77-1.17-.77-1.92,.26-1.39,.77-1.92c.51-.53,1.13-.8,1.85-.8,.84,0,1.61,.45,2.34,1.34,.72-.9,1.5-1.34,2.34-1.34Zm-4.67,3.81c.48,0,.97-.36,1.45-1.09-.48-.73-.97-1.09-1.45-1.09-.21,0-.39,.05-.56,.14s-.31,.23-.41,.4-.15,.35-.15,.54c0,.3,.11,.55,.33,.77,.22,.22,.49,.32,.8,.32Zm4.67,0c.12,0,.24-.02,.36-.05s.22-.09,.31-.15,.18-.15,.25-.24,.13-.19,.16-.31,.05-.23,.05-.34c0-.3-.11-.55-.33-.77-.22-.22-.49-.32-.8-.32-.48,0-.97,.36-1.45,1.09,.48,.73,.97,1.09,1.45,1.09Z"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.4 KiB |
@@ -1,77 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
id="Agrupar_1_copiar"
|
||||
data-name="Agrupar 1 copiar"
|
||||
width="384"
|
||||
height="384"
|
||||
viewBox="0 0 384 384"
|
||||
version="1.1"
|
||||
sodipodi:docname="floppy-in-line.svg"
|
||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview11"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#ffffff"
|
||||
borderopacity="1"
|
||||
inkscape:showpageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="1"
|
||||
inkscape:deskcolor="#505050"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.5733333"
|
||||
inkscape:cx="135.06356"
|
||||
inkscape:cy="136.65255"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="956"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="42"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Agrupar_1_copiar" />
|
||||
<defs
|
||||
id="defs4">
|
||||
<style
|
||||
id="style2">
|
||||
.cls-1, .cls-2, .cls-3 {
|
||||
fill: none;
|
||||
stroke: #fff;
|
||||
fill-rule: evenodd;
|
||||
}
|
||||
|
||||
.cls-1 {
|
||||
stroke-width: 23px;
|
||||
}
|
||||
|
||||
.cls-2 {
|
||||
stroke-width: 25px;
|
||||
}
|
||||
|
||||
.cls-3 {
|
||||
stroke-width: 33px;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path
|
||||
id="Forma_1"
|
||||
data-name="Forma 1"
|
||||
class="cls-1"
|
||||
d="m 325.91068,295.77571 c 0,0 0.24169,10.49815 0.73613,22.57934 0.49445,12.08118 -9.96947,12.17987 -9.96947,12.17987 0,0 -243.07578,-1.34336 -251.339361,-1.10772 -8.263582,0.23564 -8.86175,-9.96443 -8.86175,-9.96443 V 74.766689 c 0,0 1.492399,-7.461996 8.86175,-8.86175 7.36935,-1.399754 214.801761,0 214.801761,0 l 46.50304,46.503041 0.27492,86.6941" />
|
||||
<path
|
||||
id="Forma_2"
|
||||
data-name="Forma 2"
|
||||
class="cls-1"
|
||||
d="m 127.34606,65.908967 1.10771,88.578223 c 0,0 -1.75825,2.69881 5.5386,3.32316 7.29684,0.62435 121.79468,1.10772 121.79468,1.10772 a 5.4681025,5.4681025 0 0 0 3.32316,-5.53859 c -0.0866,-4.38556 0,-88.578232 0,-88.578232" />
|
||||
<path
|
||||
id="Forma_5"
|
||||
data-name="Forma 5"
|
||||
class="cls-2"
|
||||
d="m 224.20196,202.12313 c -0.44409,0.33533 -53.03656,46.50304 -53.03656,46.50304 l 51.02253,47.14954" />
|
||||
<path
|
||||
id="Forma_6"
|
||||
data-name="Forma 6"
|
||||
class="cls-3"
|
||||
d="M 175.86514,248.44591 339.0019,247.43889" />
|
||||
</svg>
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="PCSX2_-_Save" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 384"><defs><style>.cls-1{stroke-width:29px;}.cls-1,.cls-2{fill:none;stroke:#fff;}.cls-2{stroke-width:28px;}</style></defs><g id="By_maxihplay"><path id="Forma_5" class="cls-2" d="M217.39,192.85c-.45,.33-52.68,43.98-52.68,43.98l52.04,47.7"/><path id="Forma_6" class="cls-2" d="M173.41,238.01l161.32-.73"/><path id="Forma_2" class="cls-2" d="M114.53,59.5l1.11,89.07s-1.77,2.71,5.57,3.34c7.33,.63,122.47,1.11,122.47,1.11,2.21-.93,3.56-3.18,3.34-5.57-.09-4.41,0-89.07,0-89.07"/><path id="Forma_1" class="cls-1" d="M322.31,290.47s-.12,21.8-.1,22.87c.31,13.33-11.31,12.25-11.31,12.25,0,0-244.42-1.35-252.73-1.11s-8.91-10.02-8.91-10.02V68.41s1.5-7.5,8.91-8.91,215.99,0,215.99,0l48.05,46.76,.27,72.95"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 818 B |
@@ -1,77 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
id="Agrupar_1"
|
||||
data-name="Agrupar 1"
|
||||
width="384"
|
||||
height="384"
|
||||
viewBox="0 0 384 384"
|
||||
version="1.1"
|
||||
sodipodi:docname="floppy-out-line.svg"
|
||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview11"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#ffffff"
|
||||
borderopacity="1"
|
||||
inkscape:showpageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="1"
|
||||
inkscape:deskcolor="#505050"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.2683333"
|
||||
inkscape:cx="179.36926"
|
||||
inkscape:cy="207.35874"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="956"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="42"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Agrupar_1" />
|
||||
<defs
|
||||
id="defs4">
|
||||
<style
|
||||
id="style2">
|
||||
.cls-1, .cls-2, .cls-3 {
|
||||
fill: none;
|
||||
stroke: #fff;
|
||||
fill-rule: evenodd;
|
||||
}
|
||||
|
||||
.cls-1 {
|
||||
stroke-width: 23px;
|
||||
}
|
||||
|
||||
.cls-2 {
|
||||
stroke-width: 25px;
|
||||
}
|
||||
|
||||
.cls-3 {
|
||||
stroke-width: 33px;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path
|
||||
id="Forma_1"
|
||||
data-name="Forma 1"
|
||||
class="cls-1"
|
||||
d="m 325.86348,300.4432 c 0,0 0.24183,10.50408 0.73655,22.59208 0.49472,12.08801 -9.9751,12.18675 -9.9751,12.18675 0,0 -243.213007,-1.34412 -251.481254,-1.10834 -8.268247,0.23577 -8.866752,-9.97006 -8.866752,-9.97006 V 79.309414 c 0,0 1.493241,-7.466209 8.866752,-8.866753 7.373511,-1.400544 214.923034,0 214.923034,0 l 46.52929,46.529289 0.27507,86.74304" />
|
||||
<path
|
||||
id="Forma_2"
|
||||
data-name="Forma 2"
|
||||
class="cls-1"
|
||||
d="m 127.18676,70.446691 1.10835,88.628229 c 0,0 -1.75925,2.70033 5.54172,3.32503 7.30096,0.62471 121.86344,1.10835 121.86344,1.10835 a 5.4711894,5.4711894 0 0 0 3.32503,-5.54172 c -0.0867,-4.38804 0,-88.628233 0,-88.628233" />
|
||||
<path
|
||||
id="Forma_5"
|
||||
data-name="Forma 5"
|
||||
class="cls-2"
|
||||
d="m 267.20286,207.74533 c 1.47007,1.13656 53.06651,44.51412 53.06651,44.51412 l -51.05134,47.17617" />
|
||||
<path
|
||||
id="Forma_6"
|
||||
data-name="Forma 6"
|
||||
class="cls-3"
|
||||
d="M 315.56697,253.08668 152.33811,252.0791" />
|
||||
</svg>
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="PCSX2_-_load" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 384"><defs><style>.cls-1{stroke-width:29px;}.cls-1,.cls-2{fill:none;stroke:#fff;}.cls-2{stroke-width:28px;}</style></defs><g id="By_maxihplay"><path id="Forma_5" class="cls-2" d="M265.05,192.85c.45,.33,52.68,43.98,52.68,43.98l-52.04,47.7"/><path id="Forma_6" class="cls-2" d="M309.03,238.01l-132.24-.6"/><path id="Forma_2" class="cls-2" d="M114.53,59.5l1.11,89.07s-1.77,2.71,5.57,3.34c7.33,.63,122.47,1.11,122.47,1.11,2.21-.93,3.56-3.18,3.34-5.57-.09-4.41,0-89.07,0-89.07"/><path id="Forma_1" class="cls-1" d="M322.31,290.47s-.12,21.8-.1,22.87c.31,13.33-11.31,12.25-11.31,12.25,0,0-244.42-1.35-252.73-1.11s-8.91-10.02-8.91-10.02V68.41s1.5-7.5,8.91-8.91,215.99,0,215.99,0l48.05,46.76,.27,72.95"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 818 B |
@@ -24,9 +24,9 @@
|
||||
inkscape:deskcolor="#505050"
|
||||
inkscape:document-units="px"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.921875"
|
||||
inkscape:cx="47.728814"
|
||||
inkscape:cy="215.32203"
|
||||
inkscape:zoom="1.3037281"
|
||||
inkscape:cx="-8.0538264"
|
||||
inkscape:cy="358.20352"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="956"
|
||||
inkscape:window-x="0"
|
||||
@@ -46,13 +46,13 @@
|
||||
cy="256.1091"
|
||||
r="231.50449" />
|
||||
<path
|
||||
style="fill:none;stroke:#ffffff;stroke-width:38.6591;stroke-linecap:round;stroke-dasharray:none"
|
||||
d="M 256,93.780771 V 418.43743"
|
||||
style="fill:none;stroke:#ffffff;stroke-width:50;stroke-linecap:round;stroke-dasharray:none"
|
||||
d="m 256,132.18075 v 247.8567"
|
||||
id="path1039"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#ffffff;stroke-width:37.7963;stroke-linecap:round;stroke-dasharray:none"
|
||||
d="M 87.841479,256.1091 H 423.27606"
|
||||
style="fill:none;stroke:#ffffff;stroke-width:50;stroke-linecap:round;stroke-dasharray:none"
|
||||
d="M 137.09627,256.1091 H 374.90373"
|
||||
id="path1041"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
@@ -24,9 +24,9 @@
|
||||
inkscape:deskcolor="#505050"
|
||||
inkscape:document-units="px"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.921875"
|
||||
inkscape:cx="47.728814"
|
||||
inkscape:cy="215.32203"
|
||||
inkscape:zoom="1.3037281"
|
||||
inkscape:cx="-7.2867955"
|
||||
inkscape:cy="358.20352"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="956"
|
||||
inkscape:window-x="0"
|
||||
@@ -46,8 +46,8 @@
|
||||
cy="256.1091"
|
||||
r="231.50449" />
|
||||
<path
|
||||
style="fill:none;stroke:#ffffff;stroke-width:37.7963;stroke-linecap:round;stroke-dasharray:none"
|
||||
d="M 87.841479,256.1091 H 423.27606"
|
||||
style="fill:none;stroke:#ffffff;stroke-width:50;stroke-linecap:round;stroke-dasharray:none"
|
||||
d="M 137.09627,256.1091 H 374.90373"
|
||||
id="path1041"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
@@ -106,7 +106,8 @@ namespace Achievements
|
||||
static void EndLoadingScreen(bool was_running_idle);
|
||||
static void LoginCallback(s32 status_code, const std::string& content_type, Common::HTTPDownloader::Request::Data data);
|
||||
static void LoginASyncCallback(s32 status_code, const std::string& content_type, Common::HTTPDownloader::Request::Data data);
|
||||
static void SendLogin(const char* username, const char* password, Common::HTTPDownloader* http_downloader,
|
||||
static void LoginWithTokenCallback(s32 status_code, const std::string& content_type, Common::HTTPDownloader::Request::Data data);
|
||||
static void SendLogin(const char* username, const char* password, const char* api_token, Common::HTTPDownloader* http_downloader,
|
||||
Common::HTTPDownloader::Request::Callback callback);
|
||||
static void DownloadImage(std::string url, std::string cache_filename);
|
||||
static void DisplayAchievementSummary();
|
||||
@@ -129,7 +130,7 @@ namespace Achievements
|
||||
static void UpdateRichPresence();
|
||||
static void SendPingCallback(s32 status_code, const std::string& content_type, Common::HTTPDownloader::Request::Data data);
|
||||
static void UnlockAchievementCallback(s32 status_code, const std::string& content_type, Common::HTTPDownloader::Request::Data data);
|
||||
static void SubmitLeaderboardCallback(s32 status_code, const std::string& content_type, Common::HTTPDownloader::Request::Data data);
|
||||
static void SubmitLeaderboardCallback(s32 status_code, const std::string& content_type, Common::HTTPDownloader::Request::Data data, u32 lboard_id);
|
||||
|
||||
static bool s_active = false;
|
||||
static bool s_logged_in = false;
|
||||
@@ -164,7 +165,6 @@ namespace Achievements
|
||||
static Common::Timer s_last_ping_time;
|
||||
|
||||
static u32 s_last_queried_lboard = 0;
|
||||
static u32 s_submitting_lboard_id = 0;
|
||||
static std::optional<std::vector<Achievements::LeaderboardEntry>> s_lboard_entries;
|
||||
|
||||
template <typename T>
|
||||
@@ -445,6 +445,11 @@ bool Achievements::IsLoggedIn()
|
||||
return s_logged_in;
|
||||
}
|
||||
|
||||
bool Achievements::HasSavedCredentials()
|
||||
{
|
||||
return !s_username.empty() && !s_api_token.empty();
|
||||
}
|
||||
|
||||
bool Achievements::ChallengeModeActive()
|
||||
{
|
||||
#ifdef ENABLE_RAINTEGRATION
|
||||
@@ -513,7 +518,7 @@ void Achievements::Initialize()
|
||||
s_last_ping_time.Reset();
|
||||
s_username = Host::GetBaseStringSettingValue("Achievements", "Username");
|
||||
s_api_token = Host::GetBaseStringSettingValue("Achievements", "Token");
|
||||
s_logged_in = (!s_username.empty() && !s_api_token.empty());
|
||||
s_logged_in = false; // We are not logged in until we confirm those credentials
|
||||
|
||||
if (VMManager::HasValidVM())
|
||||
GameChanged(VMManager::GetDiscCRC(), VMManager::GetCurrentCRC());
|
||||
@@ -634,7 +639,7 @@ void Achievements::SetChallengeMode(bool enabled)
|
||||
s_challenge_mode = enabled;
|
||||
|
||||
if (HasActiveGame())
|
||||
ImGuiFullscreen::ShowToast(std::string(), enabled ? "Hardcore mode is now enabled." : "Hardcore mode is now disabled.", 10.0f);
|
||||
ImGuiFullscreen::ShowToast(std::string(), enabled ? TRANSLATE("Achievements", "Hardcore mode is now enabled.") : TRANSLATE("Achievements", "Hardcore mode is now disabled."), 10.0f);
|
||||
|
||||
if (HasActiveGame() && !IsTestModeActive())
|
||||
{
|
||||
@@ -953,13 +958,36 @@ void Achievements::LoginASyncCallback(s32 status_code, const std::string& conten
|
||||
LoginCallback(status_code, std::move(content_type), std::move(data));
|
||||
}
|
||||
|
||||
void Achievements::LoginWithTokenCallback(s32 status_code, const std::string& content_type, Common::HTTPDownloader::Request::Data data)
|
||||
{
|
||||
std::unique_lock lock(s_achievements_mutex);
|
||||
|
||||
RAPIResponse<rc_api_login_response_t, rc_api_process_login_response, rc_api_destroy_login_response> response(status_code, data);
|
||||
if (!response)
|
||||
{
|
||||
lock.unlock();
|
||||
Logout();
|
||||
Host::OnAchievementsLoginRequested(LoginRequestReason::TokenInvalid);
|
||||
return;
|
||||
}
|
||||
|
||||
if (s_active)
|
||||
{
|
||||
s_logged_in = true;
|
||||
|
||||
// If we have a game running, set it up.
|
||||
if (!s_game_hash.empty())
|
||||
SendGetGameId();
|
||||
}
|
||||
}
|
||||
|
||||
void Achievements::SendLogin(
|
||||
const char* username, const char* password, Common::HTTPDownloader* http_downloader, Common::HTTPDownloader::Request::Callback callback)
|
||||
const char* username, const char* password, const char* api_token, Common::HTTPDownloader* http_downloader, Common::HTTPDownloader::Request::Callback callback)
|
||||
{
|
||||
RAPIRequest<rc_api_login_request_t, rc_api_init_login_request> request;
|
||||
request.username = username;
|
||||
request.password = password;
|
||||
request.api_token = nullptr;
|
||||
request.api_token = api_token;
|
||||
request.Send(http_downloader, std::move(callback));
|
||||
}
|
||||
|
||||
@@ -975,7 +1003,7 @@ bool Achievements::LoginAsync(const char* username, const char* password)
|
||||
ImGuiFullscreen::OpenBackgroundProgressDialog("cheevos_async_login", "Logging in to RetroAchievements...", 0, 0, 0);
|
||||
}
|
||||
|
||||
SendLogin(username, password, s_http_downloader.get(), LoginASyncCallback);
|
||||
SendLogin(username, password, nullptr, s_http_downloader.get(), LoginASyncCallback);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -989,7 +1017,7 @@ bool Achievements::Login(const char* username, const char* password)
|
||||
|
||||
if (s_active)
|
||||
{
|
||||
SendLogin(username, password, s_http_downloader.get(), LoginCallback);
|
||||
SendLogin(username, password, nullptr, s_http_downloader.get(), LoginCallback);
|
||||
s_http_downloader->WaitForAllRequests();
|
||||
return IsLoggedIn();
|
||||
}
|
||||
@@ -1000,12 +1028,21 @@ bool Achievements::Login(const char* username, const char* password)
|
||||
if (!http_downloader)
|
||||
return false;
|
||||
|
||||
SendLogin(username, password, http_downloader.get(), LoginCallback);
|
||||
SendLogin(username, password, nullptr, http_downloader.get(), LoginCallback);
|
||||
http_downloader->WaitForAllRequests();
|
||||
|
||||
return !Host::GetBaseStringSettingValue("Achievements", "Token").empty();
|
||||
}
|
||||
|
||||
bool Achievements::LoginWithTokenAsync(const char* username, const char* api_token)
|
||||
{
|
||||
if (s_logged_in || std::strlen(username) == 0 || std::strlen(api_token) == 0 || IsUsingRAIntegration())
|
||||
return false;
|
||||
|
||||
SendLogin(username, nullptr, api_token, s_http_downloader.get(), LoginWithTokenCallback);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Achievements::Logout()
|
||||
{
|
||||
if (s_active)
|
||||
@@ -1015,11 +1052,11 @@ void Achievements::Logout()
|
||||
if (s_logged_in)
|
||||
{
|
||||
ClearGameInfo();
|
||||
std::string().swap(s_username);
|
||||
std::string().swap(s_api_token);
|
||||
s_logged_in = false;
|
||||
Host::OnAchievementsRefreshed();
|
||||
}
|
||||
std::string().swap(s_username);
|
||||
std::string().swap(s_api_token);
|
||||
}
|
||||
|
||||
// remove from config
|
||||
@@ -1477,6 +1514,8 @@ void Achievements::GameChanged(u32 disc_crc, u32 crc)
|
||||
|
||||
if (IsLoggedIn())
|
||||
SendGetGameId();
|
||||
else if (HasSavedCredentials())
|
||||
LoginWithTokenAsync(s_username.c_str(), s_api_token.c_str());
|
||||
}
|
||||
|
||||
void Achievements::SendGetGameId()
|
||||
@@ -1777,7 +1816,7 @@ void Achievements::UnlockAchievementCallback(s32 status_code, const std::string&
|
||||
Console.WriteLn("Successfully unlocked achievement %u, new score %u", response.awarded_achievement_id, response.new_player_score);
|
||||
}
|
||||
|
||||
void Achievements::SubmitLeaderboardCallback(s32 status_code, const std::string& content_type, Common::HTTPDownloader::Request::Data data)
|
||||
void Achievements::SubmitLeaderboardCallback(s32 status_code, const std::string& content_type, Common::HTTPDownloader::Request::Data data, u32 lboard_id)
|
||||
{
|
||||
if (!VMManager::HasValidVM())
|
||||
return;
|
||||
@@ -1791,11 +1830,7 @@ void Achievements::SubmitLeaderboardCallback(s32 status_code, const std::string&
|
||||
// Force the next leaderboard query to repopulate everything, just in case the user wants to see their new score
|
||||
s_last_queried_lboard = 0;
|
||||
|
||||
// RA API doesn't send us the leaderboard ID back.. hopefully we don't submit two at once :/
|
||||
if (s_submitting_lboard_id == 0)
|
||||
return;
|
||||
|
||||
const Leaderboard* lb = GetLeaderboardByID(std::exchange(s_submitting_lboard_id, 0u));
|
||||
const Leaderboard* lb = GetLeaderboardByID(lboard_id);
|
||||
if (!lb || !FullscreenUI::IsInitialized() || !EmuConfig.Achievements.Notifications)
|
||||
return;
|
||||
|
||||
@@ -1925,16 +1960,15 @@ void Achievements::SubmitLeaderboard(u32 leaderboard_id, int value)
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_lock lock(s_achievements_mutex);
|
||||
s_submitting_lboard_id = leaderboard_id;
|
||||
|
||||
RAPIRequest<rc_api_submit_lboard_entry_request_t, rc_api_init_submit_lboard_entry_request> request;
|
||||
request.username = s_username.c_str();
|
||||
request.api_token = s_api_token.c_str();
|
||||
request.game_hash = s_game_hash.c_str();
|
||||
request.leaderboard_id = leaderboard_id;
|
||||
request.score = value;
|
||||
request.Send(SubmitLeaderboardCallback);
|
||||
request.Send([leaderboard_id](s32 status_code, const std::string& content_type, Common::HTTPDownloader::Request::Data data) {
|
||||
SubmitLeaderboardCallback(status_code, content_type, std::move(data), leaderboard_id);
|
||||
});
|
||||
|
||||
// Technically not going through the resource API, but since we're passing this to something else, we can't.
|
||||
if (EmuConfig.Achievements.SoundEffects)
|
||||
|
||||
@@ -31,6 +31,12 @@
|
||||
|
||||
namespace Achievements
|
||||
{
|
||||
enum class LoginRequestReason
|
||||
{
|
||||
UserInitiated,
|
||||
TokenInvalid,
|
||||
};
|
||||
|
||||
enum class AchievementCategory : u8
|
||||
{
|
||||
Local = 0,
|
||||
@@ -88,6 +94,7 @@ namespace Achievements
|
||||
|
||||
bool IsActive();
|
||||
bool IsLoggedIn();
|
||||
bool HasSavedCredentials();
|
||||
bool ChallengeModeActive();
|
||||
bool LeaderboardsActive();
|
||||
bool IsTestModeActive();
|
||||
@@ -131,6 +138,7 @@ namespace Achievements
|
||||
|
||||
bool LoginAsync(const char* username, const char* password);
|
||||
bool Login(const char* username, const char* password);
|
||||
bool LoginWithTokenAsync(const char* username, const char* api_token);
|
||||
void Logout();
|
||||
|
||||
void GameChanged(u32 disc_crc, u32 crc);
|
||||
@@ -253,6 +261,6 @@ namespace Achievements
|
||||
/// Functions implemented in the frontend.
|
||||
namespace Host
|
||||
{
|
||||
void OnAchievementsLoginRequested(Achievements::LoginRequestReason reason);
|
||||
void OnAchievementsRefreshed();
|
||||
void OnAchievementsChallengeModeChanged();
|
||||
} // namespace Host
|
||||
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
|
||||
static std::string_view GetTrackTypeString(u32 type);
|
||||
|
||||
const u32 GetTrackCount() const { return static_cast<u32>(m_tracks.size()); }
|
||||
u32 GetTrackCount() const { return static_cast<u32>(m_tracks.size()); }
|
||||
const Track& GetTrack(u32 n) const { return m_tracks.at(n); }
|
||||
const std::vector<Track>& GetTracks() const { return m_tracks; }
|
||||
bool IsCD() const { return m_is_cd; }
|
||||
|
||||
@@ -482,23 +482,17 @@ endif()
|
||||
|
||||
# Host PAD
|
||||
set(pcsx2PADSources
|
||||
SIO/Pad/Pad.cpp
|
||||
SIO/Pad/PadBase.cpp
|
||||
SIO/Pad/PadConfig.cpp
|
||||
SIO/Pad/PadDualshock2.cpp
|
||||
SIO/Pad/PadGuitar.cpp
|
||||
SIO/Pad/PadMacros.cpp
|
||||
SIO/Pad/PadManager.cpp
|
||||
SIO/Pad/PadNotConnected.cpp
|
||||
)
|
||||
set(pcsx2PADHeaders
|
||||
SIO/Pad/Pad.h
|
||||
SIO/Pad/PadBase.h
|
||||
SIO/Pad/PadConfig.h
|
||||
SIO/Pad/PadDualshock2.h
|
||||
SIO/Pad/PadDualshock2Types.h
|
||||
SIO/Pad/PadGuitar.h
|
||||
SIO/Pad/PadGuitarTypes.h
|
||||
SIO/Pad/PadMacros.h
|
||||
SIO/Pad/PadManager.h
|
||||
SIO/Pad/PadNotConnected.h
|
||||
SIO/Pad/PadTypes.h
|
||||
)
|
||||
|
||||
@@ -364,6 +364,14 @@ enum class GSTextureInRtMode : u8
|
||||
MergeTargets,
|
||||
};
|
||||
|
||||
enum class GSBilinearDirtyMode : u8
|
||||
{
|
||||
Automatic,
|
||||
ForceBilinear,
|
||||
ForceNearest,
|
||||
MaxCount
|
||||
};
|
||||
|
||||
// Template function for casting enumerations to their underlying type
|
||||
template <typename Enumeration>
|
||||
typename std::underlying_type<Enumeration>::type enum_cast(Enumeration E)
|
||||
@@ -683,7 +691,6 @@ struct Pcsx2Config
|
||||
UserHacks_DisableRenderFixes : 1,
|
||||
UserHacks_MergePPSprite : 1,
|
||||
UserHacks_WildHack : 1,
|
||||
UserHacks_BilinearHack : 1,
|
||||
UserHacks_NativePaletteDraw : 1,
|
||||
UserHacks_TargetPartialInvalidation : 1,
|
||||
UserHacks_EstimateTextureRegion : 1,
|
||||
@@ -763,6 +770,7 @@ struct Pcsx2Config
|
||||
u8 UserHacks_CPUCLUTRender = 0;
|
||||
GSGPUTargetCLUTMode UserHacks_GPUTargetCLUTMode = GSGPUTargetCLUTMode::Disabled;
|
||||
GSTextureInRtMode UserHacks_TextureInsideRt = GSTextureInRtMode::Disabled;
|
||||
GSBilinearDirtyMode UserHacks_BilinearHack = GSBilinearDirtyMode::Automatic;
|
||||
TriFiltering TriFilter = TriFiltering::Automatic;
|
||||
s8 OverrideTextureBarriers = -1;
|
||||
|
||||
|
||||
@@ -547,20 +547,6 @@ static __fi void DoFMVSwitch()
|
||||
RendererSwitched = false;
|
||||
}
|
||||
|
||||
// Convenience function to update UI thread and set patches.
|
||||
static __fi void VSyncUpdateCore()
|
||||
{
|
||||
DoFMVSwitch();
|
||||
|
||||
VMManager::Internal::VSyncOnCPUThread();
|
||||
}
|
||||
|
||||
static __fi void VSyncCheckExit()
|
||||
{
|
||||
if (VMManager::Internal::IsExecutionInterrupted())
|
||||
Cpu->ExitExecution();
|
||||
}
|
||||
|
||||
// Framelimiter - Measures the delta time between calls and stalls until a
|
||||
// certain amount of time passes if such time hasn't passed yet.
|
||||
static __fi void frameLimit()
|
||||
@@ -605,13 +591,13 @@ static __fi void frameLimit()
|
||||
|
||||
static __fi void VSyncStart(u32 sCycle)
|
||||
{
|
||||
// Update vibration at the end of a frame.
|
||||
VSyncUpdateCore();
|
||||
// End-of-frame tasks.
|
||||
DoFMVSwitch();
|
||||
VMManager::Internal::VSyncOnCPUThread();
|
||||
|
||||
frameLimit(); // limit FPS
|
||||
gsPostVsyncStart(); // MUST be after framelimit; doing so before causes funk with frame times!
|
||||
VSyncCheckExit();
|
||||
|
||||
|
||||
if(EmuConfig.Trace.Enabled && EmuConfig.Trace.EE.m_EnableAll)
|
||||
SysTrace.EE.Counters.Write( " ================ EE COUNTER VSYNC START (frame: %d) ================", g_FrameCount );
|
||||
|
||||
@@ -642,6 +628,10 @@ static __fi void VSyncStart(u32 sCycle)
|
||||
// Therefore, there needs to be some delay in order for it to see the interrupt flag before the interrupt is acknowledged, likely helped on real hardware by the pipelines.
|
||||
// Without the patch and fixing this, the games have other issues, so I'm not going to rush to fix it.
|
||||
// Refraction
|
||||
|
||||
// Bail out before the next frame starts if we're paused, or the CPU has changed
|
||||
if (VMManager::Internal::IsExecutionInterrupted())
|
||||
Cpu->ExitExecution();
|
||||
}
|
||||
|
||||
static __fi void GSVSync()
|
||||
|
||||
@@ -187,7 +187,9 @@ bool AdapterUtils::GetAdapter(const std::string& name, Adapter* adapter, Adapter
|
||||
|
||||
do
|
||||
{
|
||||
if (pAdapter->ifa_addr->sa_family == AF_INET && strcmp(pAdapter->ifa_name, name.c_str()) == 0)
|
||||
if (pAdapter->ifa_addr != nullptr &&
|
||||
pAdapter->ifa_addr->sa_family == AF_INET &&
|
||||
strcmp(pAdapter->ifa_name, name.c_str()) == 0)
|
||||
break;
|
||||
|
||||
pAdapter = pAdapter->ifa_next;
|
||||
|
||||
@@ -175,7 +175,7 @@
|
||||
"bilinearUpscale": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 1
|
||||
"maximum": 2
|
||||
},
|
||||
"nativePaletteDraw": {
|
||||
"type": "integer",
|
||||
|
||||
@@ -31,14 +31,6 @@ const CRC::Game CRC::m_games[] =
|
||||
{0x1F88BECD, Tekken5 /* EU */}, // language selector...
|
||||
{0x652050D2, Tekken5 /* US */},
|
||||
{0xEA64EF39, Tekken5 /* KO */},
|
||||
{0xE8FCF8EC, SMTNocturne /* US */},
|
||||
{0xF0A31EE3, SMTNocturne /* EU */}, // SMTNocturne (Lucifers Call in EU)
|
||||
{0xAE0DE7B7, SMTNocturne /* EU */}, // SMTNocturne (Lucifers Call in EU)
|
||||
{0xD60DA6D4, SMTNocturne /* JP */}, // SMTNocturne
|
||||
{0x0E762E8D, SMTNocturne /* JP */}, // SMTNocturne Maniacs
|
||||
{0x47BA9034, SMTNocturne /* JP */}, // SMTNocturne Maniacs Chronicle
|
||||
{0xD3FFC263, SMTNocturne /* KO */},
|
||||
{0x84D1A8DA, SMTNocturne /* KO */},
|
||||
};
|
||||
|
||||
const CRC::Game& CRC::Lookup(u32 crc)
|
||||
|
||||
@@ -23,7 +23,6 @@ public:
|
||||
enum Title : u32
|
||||
{
|
||||
NoTitle,
|
||||
SMTNocturne,
|
||||
Tekken5,
|
||||
TitleCount,
|
||||
};
|
||||
|
||||
@@ -792,6 +792,7 @@ REG_END2
|
||||
__forceinline bool DoFirstPass() const { return !ATE || ATST != ATST_NEVER; } // not all pixels fail automatically
|
||||
__forceinline bool DoSecondPass() const { return ATE && ATST != ATST_ALWAYS && AFAIL != AFAIL_KEEP; } // pixels may fail, write fb/z
|
||||
__forceinline bool NoSecondPass() const { return ATE && ATST != ATST_ALWAYS && AFAIL == AFAIL_KEEP; } // pixels may fail, no output
|
||||
__forceinline u32 GetAFAIL(u32 fpsm) const { return (AFAIL == AFAIL_RGB_ONLY && (fpsm & 0xF) != 0) ? AFAIL_FB_ONLY : AFAIL; } // FB Only when not 32bit Framebuffer
|
||||
REG_END2
|
||||
|
||||
REG64_(GIFReg, TEX0)
|
||||
|
||||
@@ -1696,28 +1696,6 @@ void GSState::Write(const u8* mem, int len)
|
||||
GIFRegBITBLTBUF& blit = m_tr.m_blit;
|
||||
const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[blit.DPSM];
|
||||
|
||||
// The game uses a resolution of 512x244. RT is located at 0x700 and depth at 0x0
|
||||
//
|
||||
// #Bug number 1. (bad top bar)
|
||||
// The game saves the depth buffer in the EE but with a resolution of
|
||||
// 512x255. So it is ending to 0x7F8, ouch it saves the top of the RT too.
|
||||
//
|
||||
// #Bug number 2. (darker screen)
|
||||
// The game will restore the previously saved buffer at position 0x0 to
|
||||
// 0x7F8. Because of the extra RT pixels, GS will partialy invalidate
|
||||
// the texture located at 0x700. Next access will generate a cache miss
|
||||
//
|
||||
// The no-solution: instead to handle garbage (aka RT) at the end of the
|
||||
// depth buffer. Let's reduce the size of the transfer
|
||||
if (m_game.title == CRC::SMTNocturne) // TODO: hack
|
||||
{
|
||||
if (blit.DBP == 0 && blit.DPSM == PSMZ32 && w == 512 && h > 224)
|
||||
{
|
||||
h = 224;
|
||||
m_env.TRXREG.RRH = 224;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_tr.Update(w, h, psm.trbpp, len))
|
||||
return;
|
||||
|
||||
@@ -2720,6 +2698,55 @@ void GSState::GrowVertexBuffer()
|
||||
m_index.buff = index;
|
||||
}
|
||||
|
||||
bool GSState::TrianglesAreQuads() const
|
||||
{
|
||||
// If this is a quad, there should only be two distinct values for both X and Y, which
|
||||
// also happen to be the minimum/maximum bounds of the primitive.
|
||||
const GSVertex* const v = m_vertex.buff;
|
||||
for (u32 idx = 0; idx < m_index.tail; idx += 6)
|
||||
{
|
||||
const u16* const i = m_index.buff + idx;
|
||||
|
||||
// Degenerate triangles should've been culled already, so we can check indices.
|
||||
u32 extra_verts = 0;
|
||||
for (u32 j = 3; j < 6; j++)
|
||||
{
|
||||
const u16 idx = i[j];
|
||||
if (idx != i[0] && idx != i[1] && idx != i[2])
|
||||
extra_verts++;
|
||||
}
|
||||
if (extra_verts == 1)
|
||||
return true;
|
||||
|
||||
// As a fallback, they might've used different vertices with a tri list, not strip.
|
||||
// Note that this won't work unless the quad is axis-aligned.
|
||||
u16 distinct_x_values[2] = {v[i[0]].XYZ.X};
|
||||
u16 distinct_y_values[2] = {v[i[0]].XYZ.Y};
|
||||
u32 num_distinct_x_values = 1, num_distinct_y_values = 1;
|
||||
for (u32 j = 1; j < 6; j++)
|
||||
{
|
||||
const GSVertex& jv = v[i[j]];
|
||||
if (jv.XYZ.X != distinct_x_values[0] && jv.XYZ.X != distinct_x_values[1])
|
||||
{
|
||||
if (num_distinct_x_values > 1)
|
||||
return false;
|
||||
|
||||
distinct_x_values[num_distinct_x_values++] = jv.XYZ.X;
|
||||
}
|
||||
|
||||
if (jv.XYZ.Y != distinct_y_values[0] && jv.XYZ.Y != distinct_y_values[1])
|
||||
{
|
||||
if (num_distinct_y_values > 1)
|
||||
return false;
|
||||
|
||||
distinct_y_values[num_distinct_y_values++] = jv.XYZ.Y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
GSState::PRIM_OVERLAP GSState::PrimitiveOverlap()
|
||||
{
|
||||
// Either 1 triangle or 1 line or 3 POINTs
|
||||
@@ -2727,7 +2754,9 @@ GSState::PRIM_OVERLAP GSState::PrimitiveOverlap()
|
||||
if (m_vertex.next < 4)
|
||||
return PRIM_OVERLAP_NO;
|
||||
|
||||
if (m_vt.m_primclass != GS_SPRITE_CLASS)
|
||||
if (m_vt.m_primclass == GS_TRIANGLE_CLASS)
|
||||
return (m_index.tail == 6 && TrianglesAreQuads()) ? PRIM_OVERLAP_NO : PRIM_OVERLAP_UNKNOW;
|
||||
else if (m_vt.m_primclass != GS_SPRITE_CLASS)
|
||||
return PRIM_OVERLAP_UNKNOW; // maybe, maybe not
|
||||
|
||||
// Check intersection of sprite primitive only
|
||||
@@ -3759,9 +3788,10 @@ bool GSState::TryAlphaTest(u32& fm, const u32 fm_mask, u32& zm)
|
||||
|
||||
const u32 framemask = GSLocalMemory::m_psm[m_context->FRAME.PSM].fmsk;
|
||||
const u32 framemaskalpha = GSLocalMemory::m_psm[m_context->FRAME.PSM].fmsk & 0xFF000000;
|
||||
const u32 fail_type = m_context->TEST.GetAFAIL(m_context->FRAME.PSM);
|
||||
// Alpha test can only control the write of some channels. If channels are already masked
|
||||
// the alpha test is therefore a nop.
|
||||
switch (m_context->TEST.AFAIL)
|
||||
switch (fail_type)
|
||||
{
|
||||
case AFAIL_KEEP:
|
||||
break;
|
||||
@@ -3774,7 +3804,7 @@ bool GSState::TryAlphaTest(u32& fm, const u32 fm_mask, u32& zm)
|
||||
return true;
|
||||
break;
|
||||
case AFAIL_RGB_ONLY:
|
||||
if (zm == 0xFFFFFFFF && ((fm & framemaskalpha) == framemaskalpha || GSLocalMemory::m_psm[m_context->FRAME.PSM].fmt == 1))
|
||||
if (zm == 0xFFFFFFFF && (fm & framemaskalpha) == framemaskalpha)
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
@@ -3858,7 +3888,7 @@ bool GSState::TryAlphaTest(u32& fm, const u32 fm_mask, u32& zm)
|
||||
|
||||
if (!pass)
|
||||
{
|
||||
switch (m_context->TEST.AFAIL)
|
||||
switch (fail_type)
|
||||
{
|
||||
case AFAIL_KEEP:
|
||||
fm = zm = 0xffffffff;
|
||||
|
||||
@@ -418,6 +418,7 @@ public:
|
||||
|
||||
void DumpVertices(const std::string& filename);
|
||||
|
||||
bool TrianglesAreQuads() const;
|
||||
PRIM_OVERLAP PrimitiveOverlap();
|
||||
GIFRegTEX0 GetTex0Layer(u32 lod);
|
||||
};
|
||||
|
||||
@@ -421,20 +421,6 @@ wil::com_ptr_nothrow<ID3DBlob> D3D::CompileShader(D3D::ShaderType type, D3D_FEAT
|
||||
const char* target;
|
||||
switch (feature_level)
|
||||
{
|
||||
case D3D_FEATURE_LEVEL_10_0:
|
||||
{
|
||||
static constexpr std::array<const char*, 4> targets = {{"vs_4_0", "ps_4_0", "cs_4_0"}};
|
||||
target = targets[static_cast<int>(type)];
|
||||
}
|
||||
break;
|
||||
|
||||
case D3D_FEATURE_LEVEL_10_1:
|
||||
{
|
||||
static constexpr std::array<const char*, 4> targets = {{"vs_4_1", "ps_4_1", "cs_4_1"}};
|
||||
target = targets[static_cast<int>(type)];
|
||||
}
|
||||
break;
|
||||
|
||||
case D3D_FEATURE_LEVEL_11_0:
|
||||
{
|
||||
static constexpr std::array<const char*, 4> targets = {{"vs_5_0", "ps_5_0", "cs_5_0"}};
|
||||
@@ -477,6 +463,12 @@ wil::com_ptr_nothrow<ID3DBlob> D3D::CompileShader(D3D::ShaderType type, D3D_FEAT
|
||||
ofs << code;
|
||||
ofs << "\n\nCompile as " << target << " failed: " << hr << "\n";
|
||||
ofs.write(error_string.c_str(), error_string.size());
|
||||
ofs << "\n";
|
||||
if (macros)
|
||||
{
|
||||
for (const D3D_SHADER_MACRO* macro = macros; macro->Name != nullptr; macro++)
|
||||
ofs << "#define " << macro->Name << " " << macro->Definition << "\n";
|
||||
}
|
||||
ofs.close();
|
||||
}
|
||||
|
||||
|
||||
@@ -217,12 +217,6 @@ std::string D3D11ShaderCache::GetCacheBaseFileName(D3D_FEATURE_LEVEL feature_lev
|
||||
|
||||
switch (feature_level)
|
||||
{
|
||||
case D3D_FEATURE_LEVEL_10_0:
|
||||
base_filename += "sm40";
|
||||
break;
|
||||
case D3D_FEATURE_LEVEL_10_1:
|
||||
base_filename += "sm41";
|
||||
break;
|
||||
case D3D_FEATURE_LEVEL_11_0:
|
||||
base_filename += "sm50";
|
||||
break;
|
||||
|
||||
@@ -67,6 +67,7 @@ GSDevice11::GSDevice11()
|
||||
m_features.dual_source_blend = true;
|
||||
m_features.stencil_buffer = true;
|
||||
m_features.clip_control = true;
|
||||
m_features.cas_sharpening = true;
|
||||
m_features.test_and_sample_depth = false;
|
||||
}
|
||||
|
||||
@@ -92,8 +93,8 @@ bool GSDevice11::Create()
|
||||
|
||||
wil::com_ptr_nothrow<IDXGIAdapter1> dxgi_adapter = D3D::GetAdapterByName(m_dxgi_factory.get(), GSConfig.Adapter);
|
||||
|
||||
static constexpr std::array<D3D_FEATURE_LEVEL, 3> requested_feature_levels = {
|
||||
{D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0}};
|
||||
static constexpr std::array<D3D_FEATURE_LEVEL, 1> requested_feature_levels = {
|
||||
{D3D_FEATURE_LEVEL_11_0}};
|
||||
|
||||
wil::com_ptr_nothrow<ID3D11Device> temp_dev;
|
||||
wil::com_ptr_nothrow<ID3D11DeviceContext> temp_ctx;
|
||||
@@ -103,15 +104,12 @@ bool GSDevice11::Create()
|
||||
nullptr, create_flags, requested_feature_levels.data(), static_cast<UINT>(requested_feature_levels.size()),
|
||||
D3D11_SDK_VERSION, temp_dev.put(), nullptr, temp_ctx.put());
|
||||
|
||||
if (FAILED(hr))
|
||||
if (FAILED(hr) || !temp_dev.try_query_to(&m_dev) || !temp_ctx.try_query_to(&m_ctx))
|
||||
{
|
||||
Console.Error("Failed to create D3D device: 0x%08X", hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!temp_dev.try_query_to(&m_dev) || !temp_ctx.try_query_to(&m_ctx))
|
||||
{
|
||||
Console.Error("Direct3D 11.1 is required and not supported.");
|
||||
Host::ReportErrorAsync("GS",
|
||||
fmt::format(
|
||||
"Failed to create D3D device: 0x{:08X}. A GPU which supports Direct3D Feature Level 11.0 is required.",
|
||||
hr));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -166,17 +164,10 @@ bool GSDevice11::Create()
|
||||
if (GSConfig.UseDebugDevice)
|
||||
m_annotation = m_ctx.try_query<ID3DUserDefinedAnnotation>();
|
||||
level = m_dev->GetFeatureLevel();
|
||||
const bool support_feature_level_11_0 = (level >= D3D_FEATURE_LEVEL_11_0);
|
||||
|
||||
if (!m_shader_cache.Open(m_dev->GetFeatureLevel(), GSConfig.UseDebugDevice))
|
||||
Console.Warning("Shader cache failed to open.");
|
||||
|
||||
// Set maximum texture size limit based on supported feature level.
|
||||
if (support_feature_level_11_0)
|
||||
m_d3d_texsize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
||||
else
|
||||
m_d3d_texsize = D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
||||
|
||||
{
|
||||
// HACK: check AMD
|
||||
// Broken point sampler should be enabled only on AMD.
|
||||
@@ -205,20 +196,18 @@ bool GSDevice11::Create()
|
||||
{"COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
};
|
||||
|
||||
ShaderMacro sm_model(m_shader_cache.GetFeatureLevel());
|
||||
|
||||
std::optional<std::string> convert_hlsl = Host::ReadResourceFileToString("shaders/dx11/convert.fx");
|
||||
if (!convert_hlsl.has_value())
|
||||
return false;
|
||||
if (!m_shader_cache.GetVertexShaderAndInputLayout(m_dev.get(), m_convert.vs.put(), m_convert.il.put(),
|
||||
il_convert, std::size(il_convert), *convert_hlsl, sm_model.GetPtr(), "vs_main"))
|
||||
il_convert, std::size(il_convert), *convert_hlsl, nullptr, "vs_main"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < std::size(m_convert.ps); i++)
|
||||
{
|
||||
m_convert.ps[i] = m_shader_cache.GetPixelShader(m_dev.get(), *convert_hlsl, sm_model.GetPtr(), shaderName(static_cast<ShaderConvert>(i)));
|
||||
m_convert.ps[i] = m_shader_cache.GetPixelShader(m_dev.get(), *convert_hlsl, nullptr, shaderName(static_cast<ShaderConvert>(i)));
|
||||
if (!m_convert.ps[i])
|
||||
return false;
|
||||
}
|
||||
@@ -227,14 +216,14 @@ bool GSDevice11::Create()
|
||||
if (!shader.has_value())
|
||||
return false;
|
||||
if (!m_shader_cache.GetVertexShaderAndInputLayout(m_dev.get(), m_present.vs.put(), m_present.il.put(),
|
||||
il_convert, std::size(il_convert), *shader, sm_model.GetPtr(), "vs_main"))
|
||||
il_convert, std::size(il_convert), *shader, nullptr, "vs_main"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < std::size(m_present.ps); i++)
|
||||
{
|
||||
m_present.ps[i] = m_shader_cache.GetPixelShader(m_dev.get(), *shader, sm_model.GetPtr(), shaderName(static_cast<PresentShader>(i)));
|
||||
m_present.ps[i] = m_shader_cache.GetPixelShader(m_dev.get(), *shader, nullptr, shaderName(static_cast<PresentShader>(i)));
|
||||
if (!m_present.ps[i])
|
||||
return false;
|
||||
}
|
||||
@@ -282,7 +271,7 @@ bool GSDevice11::Create()
|
||||
for (size_t i = 0; i < std::size(m_merge.ps); i++)
|
||||
{
|
||||
const std::string entry_point(StringUtil::StdStringFromFormat("ps_main%d", i));
|
||||
m_merge.ps[i] = m_shader_cache.GetPixelShader(m_dev.get(), *shader, sm_model.GetPtr(), entry_point.c_str());
|
||||
m_merge.ps[i] = m_shader_cache.GetPixelShader(m_dev.get(), *shader, nullptr, entry_point.c_str());
|
||||
if (!m_merge.ps[i])
|
||||
return false;
|
||||
}
|
||||
@@ -316,7 +305,7 @@ bool GSDevice11::Create()
|
||||
for (size_t i = 0; i < std::size(m_interlace.ps); i++)
|
||||
{
|
||||
const std::string entry_point(StringUtil::StdStringFromFormat("ps_main%d", i));
|
||||
m_interlace.ps[i] = m_shader_cache.GetPixelShader(m_dev.get(), *shader, sm_model.GetPtr(), entry_point.c_str());
|
||||
m_interlace.ps[i] = m_shader_cache.GetPixelShader(m_dev.get(), *shader, nullptr, entry_point.c_str());
|
||||
if (!m_interlace.ps[i])
|
||||
return false;
|
||||
}
|
||||
@@ -333,7 +322,7 @@ bool GSDevice11::Create()
|
||||
shader = Host::ReadResourceFileToString("shaders/dx11/shadeboost.fx");
|
||||
if (!shader.has_value())
|
||||
return false;
|
||||
m_shadeboost.ps = m_shader_cache.GetPixelShader(m_dev.get(), *shader, sm_model.GetPtr(), "ps_main");
|
||||
m_shadeboost.ps = m_shader_cache.GetPixelShader(m_dev.get(), *shader, nullptr, "ps_main");
|
||||
if (!m_shadeboost.ps)
|
||||
return false;
|
||||
|
||||
@@ -466,12 +455,13 @@ bool GSDevice11::Create()
|
||||
for (size_t i = 0; i < std::size(m_date.primid_init_ps); i++)
|
||||
{
|
||||
const std::string entry_point(StringUtil::StdStringFromFormat("ps_stencil_image_init_%d", i));
|
||||
m_date.primid_init_ps[i] = m_shader_cache.GetPixelShader(m_dev.get(), *convert_hlsl, sm_model.GetPtr(), entry_point.c_str());
|
||||
m_date.primid_init_ps[i] = m_shader_cache.GetPixelShader(m_dev.get(), *convert_hlsl, nullptr, entry_point.c_str());
|
||||
if (!m_date.primid_init_ps[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
m_features.cas_sharpening = support_feature_level_11_0 && CreateCASShaders();
|
||||
if (!CreateCASShaders())
|
||||
return false;
|
||||
|
||||
if (!CreateImGuiResources())
|
||||
return false;
|
||||
@@ -788,8 +778,6 @@ std::string GSDevice11::GetDriverInfo() const
|
||||
std::string ret = "Unknown Feature Level";
|
||||
|
||||
static constexpr std::array<std::tuple<D3D_FEATURE_LEVEL, const char*>, 4> feature_level_names = {{
|
||||
{D3D_FEATURE_LEVEL_10_0, "D3D_FEATURE_LEVEL_10_0"},
|
||||
{D3D_FEATURE_LEVEL_10_0, "D3D_FEATURE_LEVEL_10_1"},
|
||||
{D3D_FEATURE_LEVEL_11_0, "D3D_FEATURE_LEVEL_11_0"},
|
||||
{D3D_FEATURE_LEVEL_11_1, "D3D_FEATURE_LEVEL_11_1"},
|
||||
}};
|
||||
@@ -1121,8 +1109,8 @@ GSTexture* GSDevice11::CreateSurface(GSTexture::Type type, int width, int height
|
||||
D3D11_TEXTURE2D_DESC desc = {};
|
||||
|
||||
// Texture limit for D3D10/11 min 1, max 8192 D3D10, max 16384 D3D11.
|
||||
desc.Width = std::clamp(width, 1, m_d3d_texsize);
|
||||
desc.Height = std::clamp(height, 1, m_d3d_texsize);
|
||||
desc.Width = std::clamp(width, 1, D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION);
|
||||
desc.Height = std::clamp(height, 1, D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION);
|
||||
desc.Format = GSTexture11::GetDXGIFormat(format);
|
||||
desc.MipLevels = levels;
|
||||
desc.ArraySize = 1;
|
||||
@@ -1551,16 +1539,14 @@ void GSDevice11::DoFXAA(GSTexture* sTex, GSTexture* dTex)
|
||||
return;
|
||||
}
|
||||
|
||||
ShaderMacro sm(m_shader_cache.GetFeatureLevel());
|
||||
m_fxaa_ps = m_shader_cache.GetPixelShader(m_dev.get(), *shader, sm.GetPtr(), "ps_main");
|
||||
ShaderMacro sm;
|
||||
sm.AddMacro("FXAA_HLSL_5", "1");
|
||||
m_fxaa_ps = m_shader_cache.GetPixelShader(m_dev.get(), *shader, sm.GetPtr(), "main");
|
||||
if (!m_fxaa_ps)
|
||||
return;
|
||||
}
|
||||
|
||||
StretchRect(sTex, sRect, dTex, dRect, m_fxaa_ps.get(), nullptr, true);
|
||||
|
||||
//sTex->Save("c:\\temp1\\1.bmp");
|
||||
//dTex->Save("c:\\temp1\\2.bmp");
|
||||
}
|
||||
|
||||
void GSDevice11::DoShadeBoost(GSTexture* sTex, GSTexture* dTex, const float params[4])
|
||||
@@ -1593,9 +1579,11 @@ bool GSDevice11::CreateCASShaders()
|
||||
m_cas.cs_sharpen = m_shader_cache.GetComputeShader(m_dev.get(), cas_source.value(), sharpen_only_macros, "main");
|
||||
m_cas.cs_upscale = m_shader_cache.GetComputeShader(m_dev.get(), cas_source.value(), nullptr, "main");
|
||||
if (!m_cas.cs_sharpen || !m_cas.cs_upscale)
|
||||
{
|
||||
Console.Error("Failed to create CAS compute shaders.");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_features.cas_sharpening = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2113,23 +2101,6 @@ void GSDevice11::SetScissor(const GSVector4i& scissor)
|
||||
}
|
||||
}
|
||||
|
||||
GSDevice11::ShaderMacro::ShaderMacro(D3D_FEATURE_LEVEL fl)
|
||||
{
|
||||
switch (fl)
|
||||
{
|
||||
case D3D_FEATURE_LEVEL_10_0:
|
||||
mlist.emplace_back("SHADER_MODEL", "0x400");
|
||||
break;
|
||||
case D3D_FEATURE_LEVEL_10_1:
|
||||
mlist.emplace_back("SHADER_MODEL", "0x401");
|
||||
break;
|
||||
case D3D_FEATURE_LEVEL_11_0:
|
||||
default:
|
||||
mlist.emplace_back("SHADER_MODEL", "0x500");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GSDevice11::ShaderMacro::AddMacro(const char* n, int d)
|
||||
{
|
||||
AddMacro(n, std::to_string(d));
|
||||
@@ -2140,7 +2111,7 @@ void GSDevice11::ShaderMacro::AddMacro(const char* n, std::string d)
|
||||
mlist.emplace_back(n, std::move(d));
|
||||
}
|
||||
|
||||
D3D_SHADER_MACRO* GSDevice11::ShaderMacro::GetPtr(void)
|
||||
D3D_SHADER_MACRO* GSDevice11::ShaderMacro::GetPtr()
|
||||
{
|
||||
mout.clear();
|
||||
|
||||
|
||||
@@ -102,10 +102,9 @@ public:
|
||||
std::vector<mcstr> mout;
|
||||
|
||||
public:
|
||||
ShaderMacro(D3D_FEATURE_LEVEL fl);
|
||||
void AddMacro(const char* n, int d);
|
||||
void AddMacro(const char* n, std::string d);
|
||||
D3D_SHADER_MACRO* GetPtr(void);
|
||||
D3D_SHADER_MACRO* GetPtr();
|
||||
};
|
||||
|
||||
private:
|
||||
@@ -156,7 +155,6 @@ private:
|
||||
u32 m_vb_pos = 0; // bytes
|
||||
u32 m_ib_pos = 0; // indices/sizeof(u32)
|
||||
u32 m_structured_vb_pos = 0; // bytes
|
||||
int m_d3d_texsize = 0;
|
||||
|
||||
bool m_allow_tearing_supported = false;
|
||||
bool m_using_flip_model_swap_chain = true;
|
||||
|
||||
@@ -64,7 +64,7 @@ void GSDevice11::SetupVS(VSSelector sel, const GSHWDrawConfig::VSConstantBuffer*
|
||||
|
||||
if (i == m_vs.end())
|
||||
{
|
||||
ShaderMacro sm(m_shader_cache.GetFeatureLevel());
|
||||
ShaderMacro sm;
|
||||
|
||||
sm.AddMacro("VERTEX_SHADER", 1);
|
||||
sm.AddMacro("VS_TME", sel.tme);
|
||||
@@ -113,7 +113,7 @@ void GSDevice11::SetupPS(const PSSelector& sel, const GSHWDrawConfig::PSConstant
|
||||
|
||||
if (i == m_ps.end())
|
||||
{
|
||||
ShaderMacro sm(m_shader_cache.GetFeatureLevel());
|
||||
ShaderMacro sm;
|
||||
|
||||
sm.AddMacro("PIXEL_SHADER", 1);
|
||||
sm.AddMacro("PS_FST", sel.fst);
|
||||
|
||||
@@ -275,12 +275,6 @@ std::string D3D12ShaderCache::GetCacheBaseFileName(const std::string_view& type,
|
||||
|
||||
switch (feature_level)
|
||||
{
|
||||
case D3D_FEATURE_LEVEL_10_0:
|
||||
base_filename += "sm40";
|
||||
break;
|
||||
case D3D_FEATURE_LEVEL_10_1:
|
||||
base_filename += "sm41";
|
||||
break;
|
||||
case D3D_FEATURE_LEVEL_11_0:
|
||||
base_filename += "sm50";
|
||||
break;
|
||||
|
||||