Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f43b5ee76f | ||
|
|
bab16a5251 | ||
|
|
08c734d7fd | ||
|
|
36126a3ad9 | ||
|
|
ce505d33bd | ||
|
|
de0d859502 | ||
|
|
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 | ||
|
|
1f74f82796 | ||
|
|
876b576679 | ||
|
|
c927e4785b | ||
|
|
97672828e8 | ||
|
|
b96978494b | ||
|
|
2f105cbe15 | ||
|
|
2539a07b7d | ||
|
|
73f903f402 | ||
|
|
94c48a4c2d | ||
|
|
eb8d938c94 | ||
|
|
92b8316182 | ||
|
|
610cb2626b | ||
|
|
2033f813da | ||
|
|
a6fbd0fe69 | ||
|
|
abadb7f80f | ||
|
|
1c6be3f400 | ||
|
|
52111be20a |
@@ -115,11 +115,11 @@
|
||||
- 'pcsx2/IPU/*'
|
||||
- 'pcsx2/IPU/**/*'
|
||||
'Memory Card':
|
||||
- 'pcsx2/gui/MemoryCard*'
|
||||
- 'pcsx2/gui/**/MemoryCard*'
|
||||
- 'pcsx2/SIO/Memcard/*'
|
||||
- 'pcsx2/SIO/Memcard/**/*'
|
||||
'PAD':
|
||||
- 'pcsx2/PAD/*'
|
||||
- 'pcsx2/PAD/**/*'
|
||||
- 'pcsx2/SIO/Pad/*'
|
||||
- 'pcsx2/SIO/Pad/**/*'
|
||||
'SPU2':
|
||||
- 'pcsx2/SPU2/*'
|
||||
- 'pcsx2/SPU2/**/*'
|
||||
|
||||
@@ -37,5 +37,6 @@ jobs:
|
||||
cmakeflags: ""
|
||||
publish: true
|
||||
branch: stable
|
||||
fetchTags: true
|
||||
secrets: inherit
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ retry_command sudo flatpak -y install "${FLATPAK_PACKAGES[@]}"
|
||||
echo "Downloading flat-manager-client"
|
||||
mkdir -p "$FLAT_MANAGER_CLIENT_DIR"
|
||||
pushd "$FLAT_MANAGER_CLIENT_DIR"
|
||||
aria2c -Z "https://raw.githubusercontent.com/flatpak/flat-manager/master/flat-manager-client"
|
||||
aria2c -Z "https://raw.githubusercontent.com/flatpak/flat-manager/9401efbdc0d6bd489507d8401c567ba219d735d5/flat-manager-client"
|
||||
chmod +x flat-manager-client
|
||||
echo "$FLAT_MANAGER_CLIENT_DIR" >> $GITHUB_PATH
|
||||
popd
|
||||
|
||||
@@ -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,9 +647,15 @@ 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("============================================");
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
// We can't handle unicode in filenames if we don't use wmain on Win32.
|
||||
#define main real_main
|
||||
#endif
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
GSRunner::InitializeConsole();
|
||||
@@ -808,4 +820,20 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
return DefWindowProcW(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
int wmain(int argc, wchar_t** argv)
|
||||
{
|
||||
std::vector<std::string> u8_args;
|
||||
u8_args.reserve(static_cast<size_t>(argc));
|
||||
for (int i = 0; i < argc; i++)
|
||||
u8_args.push_back(StringUtil::WideStringToUTF8String(argv[i]));
|
||||
|
||||
std::vector<char*> u8_argptrs;
|
||||
u8_argptrs.reserve(u8_args.size());
|
||||
for (int i = 0; i < argc; i++)
|
||||
u8_argptrs.push_back(u8_args[i].data());
|
||||
u8_argptrs.push_back(nullptr);
|
||||
|
||||
return real_main(argc, u8_argptrs.data());
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -55,6 +55,7 @@ target_sources(pcsx2-qt PRIVATE
|
||||
Settings/BIOSSettingsWidget.ui
|
||||
Settings/ControllerBindingWidget.ui
|
||||
Settings/ControllerBindingWidget_DualShock2.ui
|
||||
Settings/ControllerBindingWidget_Guitar.ui
|
||||
Settings/ControllerBindingWidgets.cpp
|
||||
Settings/ControllerBindingWidgets.h
|
||||
Settings/ControllerLEDSettingsDialog.ui
|
||||
@@ -133,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();
|
||||
}
|
||||
@@ -2273,7 +2285,8 @@ void MainWindow::setGameListEntryCoverImage(const GameList::Entry* entry)
|
||||
if (filename.isEmpty())
|
||||
return;
|
||||
|
||||
if (!GameList::GetCoverImagePathForEntry(entry).empty())
|
||||
const QString old_filename = QString::fromStdString(GameList::GetCoverImagePathForEntry(entry));
|
||||
if (!old_filename.isEmpty())
|
||||
{
|
||||
if (QMessageBox::question(this, tr("Cover Already Exists"),
|
||||
tr("A cover image for this game already exists, do you wish to replace it?"), QMessageBox::Yes,
|
||||
@@ -2299,6 +2312,12 @@ void MainWindow::setGameListEntryCoverImage(const GameList::Entry* entry)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!old_filename.isEmpty() && old_filename != new_filename && !QFile::remove(old_filename))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Copy Error"), tr("Failed to remove '%1'").arg(old_filename));
|
||||
return;
|
||||
}
|
||||
|
||||
m_game_list_widget->refreshGridCovers();
|
||||
}
|
||||
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
#include "pcsx2/Input/InputManager.h"
|
||||
#include "pcsx2/LogSink.h"
|
||||
#include "pcsx2/MTGS.h"
|
||||
#include "pcsx2/PAD/Host/PAD.h"
|
||||
#include "pcsx2/PerformanceMetrics.h"
|
||||
#include "pcsx2/SysForwardDefs.h"
|
||||
#include "pcsx2/VMManager.h"
|
||||
@@ -1080,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;
|
||||
@@ -1469,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);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -1779,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;
|
||||
|
||||
@@ -0,0 +1,317 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ControllerBindingWidget_Guitar</class>
|
||||
<widget class="QWidget" name="ControllerBindingWidget_Guitar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1100</width>
|
||||
<height>500</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="horizontalLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1101</width>
|
||||
<height>322</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<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>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>800</width>
|
||||
<height>320</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../resources/resources.qrc">:/images/guitar.png</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<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>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="gridLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>320</y>
|
||||
<width>1101</width>
|
||||
<height>181</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="6">
|
||||
<widget class="QGroupBox" name="groupBox_7">
|
||||
<property name="title">
|
||||
<string>Yellow</string>
|
||||
</property>
|
||||
<widget class="InputBindingWidget" name="Yellow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>24</x>
|
||||
<y>30</y>
|
||||
<width>90</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Start</string>
|
||||
</property>
|
||||
<widget class="InputBindingWidget" name="Start">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>24</x>
|
||||
<y>30</y>
|
||||
<width>90</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="7">
|
||||
<widget class="QGroupBox" name="groupBox_8">
|
||||
<property name="title">
|
||||
<string>Red</string>
|
||||
</property>
|
||||
<widget class="InputBindingWidget" name="Red">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>24</x>
|
||||
<y>30</y>
|
||||
<width>90</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="8">
|
||||
<widget class="QGroupBox" name="groupBox_9">
|
||||
<property name="title">
|
||||
<string>Green</string>
|
||||
</property>
|
||||
<widget class="InputBindingWidget" name="Green">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>24</x>
|
||||
<y>30</y>
|
||||
<width>90</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QGroupBox" name="groupBox_5">
|
||||
<property name="title">
|
||||
<string>Orange</string>
|
||||
</property>
|
||||
<widget class="InputBindingWidget" name="Orange">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>24</x>
|
||||
<y>30</y>
|
||||
<width>90</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>Select</string>
|
||||
</property>
|
||||
<widget class="InputBindingWidget" name="Select">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>24</x>
|
||||
<y>30</y>
|
||||
<width>90</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Strum Up</string>
|
||||
</property>
|
||||
<widget class="InputBindingWidget" name="Up">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>24</x>
|
||||
<y>30</y>
|
||||
<width>90</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QGroupBox" name="groupBox_4">
|
||||
<property name="title">
|
||||
<string>Strum Down</string>
|
||||
</property>
|
||||
<widget class="InputBindingWidget" name="Down">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>24</x>
|
||||
<y>30</y>
|
||||
<width>90</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="5">
|
||||
<widget class="QGroupBox" name="groupBox_6">
|
||||
<property name="title">
|
||||
<string>Blue</string>
|
||||
</property>
|
||||
<widget class="InputBindingWidget" name="Blue">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>24</x>
|
||||
<y>30</y>
|
||||
<width>90</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_10">
|
||||
<property name="title">
|
||||
<string>Whammy Bar</string>
|
||||
</property>
|
||||
<widget class="InputBindingWidget" name="Whammy">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>24</x>
|
||||
<y>30</y>
|
||||
<width>90</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QGroupBox" name="groupBox_11">
|
||||
<property name="title">
|
||||
<string>Tilt</string>
|
||||
</property>
|
||||
<widget class="InputBindingWidget" name="Tilt">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>30</y>
|
||||
<width>90</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</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>
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include "pcsx2/Host.h"
|
||||
#include "pcsx2/PAD/Host/PAD.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", PAD::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] : PAD::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", PAD::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,25 +100,32 @@ void ControllerBindingWidget::onTypeChanged()
|
||||
m_macros_widget = nullptr;
|
||||
}
|
||||
|
||||
const PAD::ControllerInfo* cinfo = PAD::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);
|
||||
|
||||
if (m_controller_type == "DualShock2")
|
||||
{
|
||||
m_bindings_widget = ControllerBindingWidget_DualShock2::createInstance(this);
|
||||
}
|
||||
else if (m_controller_type == "Guitar")
|
||||
{
|
||||
m_bindings_widget = ControllerBindingWidget_Guitar::createInstance(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bindings_widget = new ControllerBindingWidget_Base(this);
|
||||
}
|
||||
|
||||
m_ui.stackedWidget->addWidget(m_bindings_widget);
|
||||
m_ui.stackedWidget->setCurrentWidget(m_bindings_widget);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -210,13 +218,13 @@ void ControllerBindingWidget::onClearBindingsClicked()
|
||||
{
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
PAD::ClearPortBindings(*Host::Internal::GetBaseSettingsLayer(), m_port_number);
|
||||
Pad::ClearPortBindings(*Host::Internal::GetBaseSettingsLayer(), m_port_number);
|
||||
}
|
||||
Host::CommitBaseSettingChanges();
|
||||
}
|
||||
else
|
||||
{
|
||||
PAD::ClearPortBindings(*m_dialog->getProfileSettingsInterface(), m_port_number);
|
||||
Pad::ClearPortBindings(*m_dialog->getProfileSettingsInterface(), m_port_number);
|
||||
m_dialog->getProfileSettingsInterface()->Save();
|
||||
}
|
||||
|
||||
@@ -240,14 +248,14 @@ void ControllerBindingWidget::doDeviceAutomaticBinding(const QString& device)
|
||||
{
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
result = PAD::MapController(*Host::Internal::GetBaseSettingsLayer(), m_port_number, mapping);
|
||||
result = Pad::MapController(*Host::Internal::GetBaseSettingsLayer(), m_port_number, mapping);
|
||||
}
|
||||
if (result)
|
||||
Host::CommitBaseSettingChanges();
|
||||
}
|
||||
else
|
||||
{
|
||||
result = PAD::MapController(*m_dialog->getProfileSettingsInterface(), m_port_number, mapping);
|
||||
result = Pad::MapController(*m_dialog->getProfileSettingsInterface(), m_port_number, mapping);
|
||||
if (result)
|
||||
{
|
||||
m_dialog->getProfileSettingsInterface()->Save();
|
||||
@@ -312,7 +320,7 @@ ControllerMacroEditWidget::ControllerMacroEditWidget(ControllerMacroWidget* pare
|
||||
|
||||
ControllerSettingsDialog* dialog = m_bwidget->getDialog();
|
||||
const std::string& section = m_bwidget->getConfigSection();
|
||||
const PAD::ControllerInfo* cinfo = PAD::GetControllerInfo(m_bwidget->getControllerType());
|
||||
const Pad::ControllerInfo* cinfo = Pad::GetControllerInfo(m_bwidget->getControllerType());
|
||||
if (!cinfo)
|
||||
{
|
||||
// Shouldn't ever happen.
|
||||
@@ -325,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;
|
||||
|
||||
@@ -350,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();
|
||||
@@ -384,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;
|
||||
@@ -423,12 +439,12 @@ void ControllerMacroEditWidget::updateFrequencyText()
|
||||
void ControllerMacroEditWidget::updateBinds()
|
||||
{
|
||||
ControllerSettingsDialog* dialog = m_bwidget->getDialog();
|
||||
const PAD::ControllerInfo* cinfo = PAD::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)
|
||||
@@ -793,16 +809,15 @@ QIcon ControllerBindingWidget_Base::getIcon() const
|
||||
|
||||
void ControllerBindingWidget_Base::initBindingWidgets()
|
||||
{
|
||||
const PAD::ControllerInfo* cinfo = PAD::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)
|
||||
@@ -820,7 +835,7 @@ void ControllerBindingWidget_Base::initBindingWidgets()
|
||||
|
||||
switch (cinfo->vibration_caps)
|
||||
{
|
||||
case PAD::VibrationCapabilities::LargeSmallMotors:
|
||||
case Pad::VibrationCapabilities::LargeSmallMotors:
|
||||
{
|
||||
InputVibrationBindingWidget* widget = findChild<InputVibrationBindingWidget*>(QStringLiteral("LargeMotor"));
|
||||
if (widget)
|
||||
@@ -832,7 +847,7 @@ void ControllerBindingWidget_Base::initBindingWidgets()
|
||||
}
|
||||
break;
|
||||
|
||||
case PAD::VibrationCapabilities::SingleMotor:
|
||||
case Pad::VibrationCapabilities::SingleMotor:
|
||||
{
|
||||
InputVibrationBindingWidget* widget = findChild<InputVibrationBindingWidget*>(QStringLiteral("Motor"));
|
||||
if (widget)
|
||||
@@ -840,7 +855,7 @@ void ControllerBindingWidget_Base::initBindingWidgets()
|
||||
}
|
||||
break;
|
||||
|
||||
case PAD::VibrationCapabilities::NoVibration:
|
||||
case Pad::VibrationCapabilities::NoVibration:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -867,6 +882,27 @@ ControllerBindingWidget_Base* ControllerBindingWidget_DualShock2::createInstance
|
||||
return new ControllerBindingWidget_DualShock2(parent);
|
||||
}
|
||||
|
||||
ControllerBindingWidget_Guitar::ControllerBindingWidget_Guitar(ControllerBindingWidget* parent)
|
||||
: ControllerBindingWidget_Base(parent)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
initBindingWidgets();
|
||||
}
|
||||
|
||||
ControllerBindingWidget_Guitar::~ControllerBindingWidget_Guitar()
|
||||
{
|
||||
}
|
||||
|
||||
QIcon ControllerBindingWidget_Guitar::getIcon() const
|
||||
{
|
||||
return QIcon::fromTheme("guitar-line");
|
||||
}
|
||||
|
||||
ControllerBindingWidget_Base* ControllerBindingWidget_Guitar::createInstance(ControllerBindingWidget* parent)
|
||||
{
|
||||
return new ControllerBindingWidget_Guitar(parent);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
USBDeviceWidget::USBDeviceWidget(QWidget* parent, ControllerSettingsDialog* dialog, u32 port)
|
||||
@@ -1240,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 "PAD/Host/PAD.h"
|
||||
#include "pcsx2/SIO/Pad/PadTypes.h"
|
||||
|
||||
#include <QtWidgets/QWidget>
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "ui_ControllerBindingWidget.h"
|
||||
#include "ui_ControllerBindingWidget_DualShock2.h"
|
||||
#include "ui_ControllerBindingWidget_Guitar.h"
|
||||
#include "ui_ControllerMacroWidget.h"
|
||||
#include "ui_ControllerMacroEditWidget.h"
|
||||
#include "ui_USBDeviceWidget.h"
|
||||
@@ -91,7 +92,7 @@ public:
|
||||
void updateListItem(u32 index);
|
||||
|
||||
private:
|
||||
static constexpr u32 NUM_MACROS = PAD::NUM_MACRO_BUTTONS_PER_CONTROLLER;
|
||||
static constexpr u32 NUM_MACROS = Pad::NUM_MACRO_BUTTONS_PER_CONTROLLER;
|
||||
|
||||
void createWidgets(ControllerBindingWidget* parent);
|
||||
|
||||
@@ -114,6 +115,7 @@ public:
|
||||
|
||||
private Q_SLOTS:
|
||||
void onPressureChanged();
|
||||
void onDeadzoneChanged();
|
||||
void onSetFrequencyClicked();
|
||||
void updateBinds();
|
||||
|
||||
@@ -193,6 +195,22 @@ private:
|
||||
Ui::ControllerBindingWidget_DualShock2 m_ui;
|
||||
};
|
||||
|
||||
class ControllerBindingWidget_Guitar final : public ControllerBindingWidget_Base
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ControllerBindingWidget_Guitar(ControllerBindingWidget* parent);
|
||||
~ControllerBindingWidget_Guitar();
|
||||
|
||||
QIcon getIcon() const override;
|
||||
|
||||
static ControllerBindingWidget_Base* createInstance(ControllerBindingWidget* parent);
|
||||
|
||||
private:
|
||||
Ui::ControllerBindingWidget_Guitar m_ui;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class USBDeviceWidget final : public QWidget
|
||||
|
||||
@@ -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,8 +22,8 @@
|
||||
#include "Settings/HotkeySettingsWidget.h"
|
||||
|
||||
#include "pcsx2/INISettingsInterface.h"
|
||||
#include "pcsx2/PAD/Host/PAD.h"
|
||||
#include "pcsx2/Sio.h"
|
||||
#include "pcsx2/SIO/Pad/Pad.h"
|
||||
#include "pcsx2/SIO/Sio.h"
|
||||
#include "pcsx2/VMManager.h"
|
||||
|
||||
#include "common/Assertions.h"
|
||||
@@ -130,7 +130,7 @@ void ControllerSettingsDialog::onNewProfileClicked()
|
||||
{
|
||||
// from global
|
||||
auto lock = Host::GetSettingsLock();
|
||||
PAD::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);
|
||||
PAD::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();
|
||||
PAD::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 PAD::ControllerInfo* ci = PAD::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 PAD::ControllerInfo* ci = PAD::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(PAD::GetInputProfileNames());
|
||||
const std::vector<std::string> names = Pad::GetInputProfileNames();
|
||||
|
||||
QSignalBlocker sb(m_ui.currentProfile);
|
||||
m_ui.currentProfile->clear();
|
||||
|
||||
@@ -15,21 +15,28 @@
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "pcsx2/SIO/Pad/Pad.h"
|
||||
#include "GameSummaryWidget.h"
|
||||
#include "SettingsDialog.h"
|
||||
#include "MainWindow.h"
|
||||
#include "QtHost.h"
|
||||
#include "QtProgressCallback.h"
|
||||
#include "QtUtils.h"
|
||||
|
||||
#include "pcsx2/CDVD/IsoHasher.h"
|
||||
#include "pcsx2/GameDatabase.h"
|
||||
#include "pcsx2/GameList.h"
|
||||
#include "pcsx2/PAD/Host/PAD.h"
|
||||
|
||||
#include "common/Error.h"
|
||||
#include "common/MD5Digest.h"
|
||||
#include "common/ScopedGuard.h"
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include "fmt/format.h"
|
||||
|
||||
#include <QtCore/QDir>
|
||||
#include <QtWidgets/QFileDialog>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
|
||||
GameSummaryWidget::GameSummaryWidget(const GameList::Entry* entry, SettingsDialog* dialog, QWidget* parent)
|
||||
: m_dialog(dialog)
|
||||
@@ -51,15 +58,18 @@ GameSummaryWidget::GameSummaryWidget(const GameList::Entry* entry, SettingsDialo
|
||||
populateInputProfiles();
|
||||
populateDetails(entry);
|
||||
populateDiscPath(entry);
|
||||
populateTrackList(entry);
|
||||
|
||||
connect(m_ui.inputProfile, &QComboBox::currentIndexChanged, this, &GameSummaryWidget::onInputProfileChanged);
|
||||
connect(m_ui.verify, &QAbstractButton::clicked, this, &GameSummaryWidget::onVerifyClicked);
|
||||
connect(m_ui.searchHash, &QAbstractButton::clicked, this, &GameSummaryWidget::onSearchHashClicked);
|
||||
}
|
||||
|
||||
GameSummaryWidget::~GameSummaryWidget() = default;
|
||||
|
||||
void GameSummaryWidget::populateInputProfiles()
|
||||
{
|
||||
for (const std::string& name : PAD::GetInputProfileNames())
|
||||
for (const std::string& name : Pad::GetInputProfileNames())
|
||||
m_ui.inputProfile->addItem(QString::fromStdString(name));
|
||||
}
|
||||
|
||||
@@ -137,3 +147,209 @@ void GameSummaryWidget::onDiscPathBrowseClicked()
|
||||
// let the signal take care of it
|
||||
m_ui.discPath->setText(QDir::toNativeSeparators(filename));
|
||||
}
|
||||
|
||||
void GameSummaryWidget::populateTrackList(const GameList::Entry* entry)
|
||||
{
|
||||
if (entry->type != GameList::EntryType::PS1Disc && entry->type != GameList::EntryType::PS2Disc)
|
||||
{
|
||||
m_ui.verify->setEnabled(false);
|
||||
m_ui.verifyResult->setPlainText(tr("Game is not a CD/DVD."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (QtHost::IsVMValid())
|
||||
{
|
||||
m_ui.verify->setEnabled(false);
|
||||
m_ui.verifyResult->setPlainText(tr("Track list unavailable while virtual machine is running."));
|
||||
return;
|
||||
}
|
||||
|
||||
IsoHasher hasher;
|
||||
Error error;
|
||||
if (!hasher.Open(m_entry_path, &error))
|
||||
{
|
||||
m_ui.verify->setEnabled(false);
|
||||
m_ui.verifyResult->setPlainText(QString::fromStdString(error.GetDescription()));
|
||||
return;
|
||||
}
|
||||
|
||||
const auto AddColumn = [this](const QString& text) {
|
||||
QTableWidgetItem* item = new QTableWidgetItem(text);
|
||||
const int column = m_ui.tracks->columnCount();
|
||||
m_ui.tracks->insertColumn(column);
|
||||
m_ui.tracks->setHorizontalHeaderItem(column, item);
|
||||
};
|
||||
const auto SetColumn = [this](int row, int column, const QString& text) {
|
||||
QTableWidgetItem* item = new QTableWidgetItem(text);
|
||||
m_ui.tracks->setItem(row, column, item);
|
||||
};
|
||||
|
||||
// columns depend on CD vs DVD.
|
||||
AddColumn(tr("#"));
|
||||
if (hasher.IsCD())
|
||||
{
|
||||
AddColumn(tr("Mode"));
|
||||
AddColumn(tr("Start"));
|
||||
AddColumn(tr("Sectors"));
|
||||
AddColumn(tr("Size"));
|
||||
AddColumn(tr("MD5"));
|
||||
AddColumn(tr("Status"));
|
||||
}
|
||||
else
|
||||
{
|
||||
AddColumn(tr("Start"));
|
||||
AddColumn(tr("Sectors"));
|
||||
AddColumn(tr("Size"));
|
||||
AddColumn(tr("MD5"));
|
||||
AddColumn(tr("Status"));
|
||||
}
|
||||
|
||||
for (const IsoHasher::Track& track : hasher.GetTracks())
|
||||
{
|
||||
const int row = m_ui.tracks->rowCount();
|
||||
m_ui.tracks->insertRow(row);
|
||||
|
||||
SetColumn(row, 0, tr("%1").arg(track.number));
|
||||
|
||||
if (hasher.IsCD())
|
||||
{
|
||||
SetColumn(row, 1, QtUtils::StringViewToQString(IsoHasher::GetTrackTypeString(track.type)));
|
||||
SetColumn(row, 2, tr("%1").arg(track.start_lsn));
|
||||
SetColumn(row, 3, tr("%1").arg(track.sectors));
|
||||
SetColumn(row, 4, tr("%1").arg(track.size));
|
||||
SetColumn(row, 5, tr("<not computed>"));
|
||||
SetColumn(row, 6, QString());
|
||||
}
|
||||
else
|
||||
{
|
||||
SetColumn(row, 1, tr("%1").arg(track.start_lsn));
|
||||
SetColumn(row, 2, tr("%1").arg(track.sectors));
|
||||
SetColumn(row, 3, tr("%1").arg(track.size));
|
||||
SetColumn(row, 4, tr("<not computed>"));
|
||||
SetColumn(row, 5, QString());
|
||||
}
|
||||
}
|
||||
|
||||
if (hasher.IsCD())
|
||||
QtUtils::ResizeColumnsForTableView(m_ui.tracks, {20, 60, 70, 70, 100, 220, 40});
|
||||
else
|
||||
QtUtils::ResizeColumnsForTableView(m_ui.tracks, {20, 100, 100, 100, 220, 40});
|
||||
}
|
||||
|
||||
void GameSummaryWidget::onVerifyClicked()
|
||||
{
|
||||
// Can't do this while a VM is running because of stupid CDVD.
|
||||
if (QtHost::IsVMValid())
|
||||
{
|
||||
QMessageBox::critical(QtUtils::GetRootWidget(this), tr("Error"), tr("Cannot verify image while a game is running."));
|
||||
return;
|
||||
}
|
||||
|
||||
IsoHasher hasher;
|
||||
Error error;
|
||||
if (!hasher.Open(m_entry_path, &error))
|
||||
{
|
||||
setVerifyResult(QString::fromStdString(error.GetDescription()));
|
||||
return;
|
||||
}
|
||||
|
||||
QtModalProgressCallback callback(this);
|
||||
hasher.ComputeHashes(&callback);
|
||||
if (callback.IsCancelled())
|
||||
return;
|
||||
|
||||
const int hash_column = hasher.IsCD() ? 5 : 4;
|
||||
int row = 0;
|
||||
|
||||
// convert to database format
|
||||
std::vector<GameDatabase::TrackHash> thashes;
|
||||
thashes.reserve(hasher.GetTrackCount());
|
||||
for (const IsoHasher::Track& track : hasher.GetTracks())
|
||||
{
|
||||
GameDatabase::TrackHash thash;
|
||||
thash.size = track.size;
|
||||
if (track.hash.empty() || !thash.parseHash(track.hash))
|
||||
{
|
||||
m_ui.verify->setEnabled(false);
|
||||
m_ui.verifyResult->setPlainText(tr("One or more tracks is missing."));
|
||||
return;
|
||||
}
|
||||
|
||||
// Use the first track's hash as the redump search term.
|
||||
if (m_redump_search_keyword.empty())
|
||||
m_redump_search_keyword = thash.toString();
|
||||
|
||||
thashes.push_back(thash);
|
||||
}
|
||||
|
||||
// match the hashes. can't use vector<bool> here because it's not an actual array
|
||||
std::unique_ptr<bool[]> val_results = std::make_unique<bool[]>(hasher.GetTrackCount());
|
||||
std::string match_error;
|
||||
const GameDatabase::HashDatabaseEntry* hentry =
|
||||
GameDatabase::lookupHash(thashes.data(), thashes.size(), val_results.get(), &match_error);
|
||||
|
||||
// fill the UI with both the hashes and validation results
|
||||
for (u32 i = 0; i < hasher.GetTrackCount(); i++)
|
||||
{
|
||||
QTableWidgetItem* const hash_item = m_ui.tracks->item(row, hash_column);
|
||||
QTableWidgetItem* const status_item = m_ui.tracks->item(row, hash_column + 1);
|
||||
|
||||
const bool result = val_results[i];
|
||||
const QBrush brush(result ? QColor(0, 200, 0) : QColor(200, 0, 0));
|
||||
|
||||
hash_item->setText(QString::fromStdString(hasher.GetTrack(i).hash));
|
||||
hash_item->setForeground(brush);
|
||||
status_item->setText(result ? QStringLiteral("\u2713") : QStringLiteral("\u2715"));
|
||||
status_item->setForeground(brush);
|
||||
row++;
|
||||
}
|
||||
|
||||
if (hentry)
|
||||
{
|
||||
if (!hentry->version.empty())
|
||||
{
|
||||
setVerifyResult(tr("Verified as %1 [%2] (Version %3).")
|
||||
.arg(QString::fromStdString(hentry->name))
|
||||
.arg(QString::fromStdString(hentry->serial))
|
||||
.arg(QString::fromStdString(hentry->version)));
|
||||
}
|
||||
else
|
||||
{
|
||||
setVerifyResult(tr("Verified as %1 [%2].")
|
||||
.arg(QString::fromStdString(hentry->name))
|
||||
.arg(QString::fromStdString(hentry->serial)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setVerifyResult(QString::fromStdString(match_error));
|
||||
}
|
||||
}
|
||||
|
||||
void GameSummaryWidget::onSearchHashClicked()
|
||||
{
|
||||
if (m_redump_search_keyword.empty())
|
||||
return;
|
||||
|
||||
QtUtils::OpenURL(this, fmt::format("http://redump.org/discs/quicksearch/{}", m_redump_search_keyword).c_str());
|
||||
}
|
||||
|
||||
void GameSummaryWidget::setVerifyResult(QString error)
|
||||
{
|
||||
m_ui.verify->setVisible(false);
|
||||
m_ui.verifyButtonLayout->removeWidget(m_ui.verify);
|
||||
m_ui.verify->deleteLater();
|
||||
m_ui.verify = nullptr;
|
||||
m_ui.verifyButtonLayout->removeItem(m_ui.verifyButtonSpacer);
|
||||
delete m_ui.verifyButtonSpacer;
|
||||
m_ui.verifyButtonSpacer = nullptr;
|
||||
m_ui.verifyLayout->removeItem(m_ui.verifyButtonLayout);
|
||||
m_ui.verifyButtonLayout->deleteLater();
|
||||
m_ui.verifyButtonLayout = nullptr;
|
||||
m_ui.verifyLayout->update();
|
||||
updateGeometry();
|
||||
|
||||
m_ui.verifyResult->setPlainText(error);
|
||||
m_ui.verifyResult->setVisible(true);
|
||||
m_ui.searchHash->setVisible(true);
|
||||
}
|
||||
@@ -34,16 +34,22 @@ public:
|
||||
GameSummaryWidget(const GameList::Entry* entry, SettingsDialog* dialog, QWidget* parent);
|
||||
~GameSummaryWidget();
|
||||
|
||||
private Q_SLOTS:
|
||||
void onInputProfileChanged(int index);
|
||||
void onDiscPathChanged(const QString& value);
|
||||
void onDiscPathBrowseClicked();
|
||||
void onVerifyClicked();
|
||||
void onSearchHashClicked();
|
||||
|
||||
private:
|
||||
void populateInputProfiles();
|
||||
void populateDetails(const GameList::Entry* entry);
|
||||
void populateDiscPath(const GameList::Entry* entry);
|
||||
|
||||
void onInputProfileChanged(int index);
|
||||
void onDiscPathChanged(const QString& value);
|
||||
void onDiscPathBrowseClicked();
|
||||
void populateTrackList(const GameList::Entry* entry);
|
||||
void setVerifyResult(QString error);
|
||||
|
||||
Ui::GameSummaryWidget m_ui;
|
||||
SettingsDialog* m_dialog;
|
||||
std::string m_entry_path;
|
||||
std::string m_redump_search_keyword;
|
||||
};
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>692</width>
|
||||
<height>562</height>
|
||||
<width>641</width>
|
||||
<height>467</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="detailsFormLayout">
|
||||
@@ -413,7 +413,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<item row="10" column="0" colspan="2">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
@@ -426,6 +426,90 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="9" column="0" colspan="2">
|
||||
<layout class="QVBoxLayout" name="verifyLayout">
|
||||
<item>
|
||||
<widget class="QTableWidget" name="tracks">
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="cornerButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="verifyButtonLayout">
|
||||
<item>
|
||||
<spacer name="verifyButtonSpacer">
|
||||
<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>
|
||||
<widget class="QPushButton" name="verify">
|
||||
<property name="text">
|
||||
<string>Verify</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="2" column="2">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0" rowspan="3">
|
||||
<widget class="QPlainTextEdit" name="verifyResult">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>60</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QPushButton" name="searchHash">
|
||||
<property name="text">
|
||||
<string>Search on Redump.org...</string>
|
||||
</property>
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#include "MemoryCardConvertWorker.h"
|
||||
|
||||
#include "pcsx2/MemoryCardFile.h"
|
||||
#include "pcsx2/SIO/Memcard/MemoryCardFile.h"
|
||||
|
||||
class MemoryCardConvertDialog final : public QDialog
|
||||
{
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
#include "QtProgressCallback.h"
|
||||
|
||||
#include "pcsx2/MemoryCardFile.h"
|
||||
#include "pcsx2/MemoryCardFolder.h"
|
||||
#include "pcsx2/SIO/Memcard/MemoryCardFile.h"
|
||||
#include "pcsx2/SIO/Memcard/MemoryCardFolder.h"
|
||||
|
||||
class MemoryCardConvertWorker : public QtAsyncProgressThread
|
||||
{
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#include "Settings/MemoryCardCreateDialog.h"
|
||||
|
||||
#include "pcsx2/MemoryCardFile.h"
|
||||
#include "pcsx2/SIO/Memcard/MemoryCardFile.h"
|
||||
#include "pcsx2/System.h"
|
||||
|
||||
MemoryCardCreateDialog::MemoryCardCreateDialog(QWidget* parent /* = nullptr */)
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "SettingWidgetBinder.h"
|
||||
#include "SettingsDialog.h"
|
||||
|
||||
#include "pcsx2/MemoryCardFile.h"
|
||||
#include "pcsx2/SIO/Memcard/MemoryCardFile.h"
|
||||
|
||||
static constexpr const char* CONFIG_SECTION = "MemoryCards";
|
||||
|
||||
|
||||
@@ -79,8 +79,10 @@ void SettingsDialog::setupUi(const GameList::Entry* game)
|
||||
|
||||
if (isPerGameSettings())
|
||||
{
|
||||
QString summary = tr("<strong>Summary</strong><hr>Eventually this will be where we can see patches and compute "
|
||||
"hashes/verify dumps/etc.");
|
||||
QString summary = tr("<strong>Summary</strong><hr>This page shows details about the selected game. Changing the Input "
|
||||
"Profile will set the controller binding scheme for this game to whichever profile is chosen, instead "
|
||||
"of the default (Shared) configuration. The track list and dump verification can be used to determine "
|
||||
"if your disc image matches a known good dump. If it does not match, the game may be broken.");
|
||||
if (game)
|
||||
{
|
||||
addWidget(new GameSummaryWidget(game, this, m_ui.settingsContainer), tr("Summary"),
|
||||
|
||||
@@ -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 "PAD/Host/PAD.h"
|
||||
#include "pcsx2/SIO/Pad/Pad.h"
|
||||
#include "QtHost.h"
|
||||
#include "QtUtils.h"
|
||||
#include "SettingWidgetBinder.h"
|
||||
@@ -151,7 +151,7 @@ void SetupWizardDialog::updatePageLabels(int prev_page)
|
||||
void SetupWizardDialog::updatePageButtons()
|
||||
{
|
||||
const int page = m_ui.pages->currentIndex();
|
||||
m_ui.next->setText((page == Page_Complete) ? "&Finish" : "&Next");
|
||||
m_ui.next->setText((page == Page_Complete) ? tr("&Finish") : tr("&Next"));
|
||||
m_ui.back->setEnabled(page > 0);
|
||||
}
|
||||
|
||||
@@ -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] : PAD::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", PAD::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 = PAD::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")},
|
||||
@@ -337,22 +338,22 @@ static constexpr const QtHost::GlyphInfo s_glyph_info[] = {
|
||||
{
|
||||
"ja-JP", "msgothic.ttc", nullptr, "ヒラギノ角ゴシック W3.ttc",
|
||||
// auto update by update_glyph_ranges.py with pcsx2-qt_ja-JP.ts
|
||||
u"□□△△◯◯✕✕、。〜〜ああいいううええおきくぐここささしすせせそそただっつてにのはびびへべほほまみめもややよれわわをんァイウコサソタチッツテニネパビロワワンンーー一一上下不不中中丸丸了了互互今今他他代代仮仮作作使使保保信信修修倍倍値値停停備備像像入入全全公公内内再再出出切切別別利利制制削削副副割割力力加加効効動動勧勧化化十十南南参参反収取取古古可台右右合合同名向向回回固固国国在在報報場場境境壊壊変変外外大大失失奨奨始始字存完完定定実実左左帰帰常常幅幅度度式式張張形形待待後後御御性性情情想想意意感感態態成成投投択択拡拡推推提提換換敗敗数数整整新新方方既既日日明明時時更更書書替最有有期期本本果果検検標標橙橙機機止正毎毎比比況況注注消消港港湾湾準準無無照照状状率率現現璧璧環環生生用用画画異異的的直直知知確確示示種種稿稿空空索索終終緑緑編編績績能能自自般般行行表表製製複複視視覧覧解解言言設設認認語語読読赤赤起起跡跡転転軸軸込込近近追追送送通通速速進進遅遅遊遊適適選選部部長長閉閉開開関関防防限限除除隅隅集集青青非非面面韓韓音音類類香香高高黄黄++??"
|
||||
u"……□□△△◯◯✕✕ 。々々「』〜〜ああいいううええおせそそたちっぬのばびびぶぶへべほぼまやょろわわをんァイウチッツテニネロワワンン・ー一一上下不与世世両両中中乗乗了了予予事事互互交交今介他他付付代以仮仮件件任任伸伸似似位低体体何何作作使使例例供供係係保保信信修修個個倍倍借借値値停停側側備備像像優優元元先光入入全全公公共共具典内内再再冗冗処処出出分切列列初初判別利利制刷則則削削前前副副割割力力加加効効動動勧勧化化区区十十半半南単印印即即去去参参及及反収取受古古可台右右号号各各合合同名向向否否含含告告周周味味命命品品商商問問善善四四回回囲囲固固国国圧在地地均均垂垂型型域域基基報報場場境境増増壊壊声声変変外外多多大大太太央央失失奇奇奨奨好好妙妙妨妨始始子子字存安安完完定定実実容容寄寄密密対対射射小小少少尾尾展展岐岐崩崩左左巨巨己己帰帰常常幅幅平平序序度座延延式式引引弱弱張張強強当当形形彩彩影影役役待待後後得得御御復復微微心心必必応応忠忠念念急急性性悪悪情情想想意意感感態態慣慣成成戻戻所所手手打打承承投投択択抱抱押押拒拒招招拡拡拳拳持持指指振振挿挿捗捗排排接接推推描提換換揮揮援援揺揺損損撃撃撮撮操操支支改改放放敗敗数数整整文文料料断断新新方方既既日日早早明明時時曲曲更更書書替最有有望望期期未本条条析析果果桁桁案案械械検検極極楽楽概概構構標標権権橙橙機機欄欄欠次止正殊残毎毎比比水水求求汎汎決決況況法法波波注注浪浪浮浮消消深深済済減減渡渡港港湾湾満満源源準準滑滑点為無無照照牲牲特特犠犠状状獲獲率率現現理理璧璧環環生生用用由由申申画画番番異異発登白白的的目目直直相相省省知知短短破破確確示示禁禁秒秒移移程程種種稿稿空空立立端端競競第第算算管管範範精精索索細細終終組組経経結結絞絞統統続続維維緑緒線線編編縦縦縮縮績績繰繰置置義義者者肢肢能能自自致致般般良良色色荷荷落落蔵蔵行行表表衰衰装装製製複複要要見見規規視視覚覚覧覧観観角角解解言言計計記記設設許許訳訳証証試試該詳認認語語誤誤説読調調識識警警象象負負責責費貼質質赤赤起起超超足足跡跡転転軸軸軽軽辞辞込込近近返返追追送送逆逆途途通通速速連連進進遅遅遊遊過過適適選選避避部部配配重量鉄鉄録録長長閉閉開開間間関関閾閾防防降降限限除除陽陽隅隅際際集集離難電電青青非非面面韓韓音音響響頂頂順順領領頻頼題題類類飾飾香香駄駄高高鮮鮮黄黄!!()//12::>?~~"
|
||||
},
|
||||
{
|
||||
"ko-KR", "malgun.ttf", nullptr, "AppleSDGothicNeo.ttc",
|
||||
// auto update by update_glyph_ranges.py with pcsx2-qt_ko-KR.ts
|
||||
u""
|
||||
u"“”……□□▲△▶▶▼▼◀◀◯◯✕✕んん茶茶가각간간갈갈감값강강같같개개거거건건걸걸검겁것것게게겠겠격격견견결결경경계계고곡공공과과관관교교구국군군권권귀귀규규균균그극근근글글금급긍긍기기긴긴길길깁깁깃깃깅깅깊깊까까깝깝깨깨꺼꺼께께꾸꾸끄끄끔끔끝끝나나날날남남낭낮내내낸낸냅냅너너널널넣네넬넬넷넷노녹높놓누누눈눈눌눌뉴뉴느느는는늘늘능능니닉닌닌님닙닛닛다다단단닫달담담당당대대댑댑더더덜덜덤덤덩덩덮덮데덱덴덴델델뎁뎁도독돌돌동동됐됐되되된된될될됨됩두두듀듀듈듈드득든든들들듬듭등등디디딩딩때때떠떠떤떤떨떨또또뛰뛰뛸뛸뜁뜁뜨뜨라락란란랍랍랑랑래랙랜랜램램랫랫량량러럭런런럴럴럼럽렀렀렇렉렌렌렛렛려력련련렬렬렸령로록롤롤롭롭롯롯료료루루룸룸류류률률르르른른를를름름리릭린린릴릴림립릿릿링링마막만만많많말말맞맞매매맨맨맵맵맺맺머머먼먼멀멀멈멈멋멋메메며며면면명명모목못못몽몽무무문문뮬뮬므므미믹민민밀밀밉밉밍밍및및바바반반받밝밥밥방방배백밴밴뱃뱃버버번번벌벌범법벗벗베벡벤벤벨벨벼벽변변별별병병보복본본볼볼부부분분불불붙붙뷰뷰브브블블비빅빈빈빌빌빙빙빛빛빠빠빨빨사삭산산살살삼삽상상새색샘샘생생샷샷서석선선설설성성세섹센센셀셀셈셉셋셋셔셔션션셰셰소속손손솔솔송송쇄쇄쇠쇠쇼쇼수수순순숨숨쉬쉬슈슈스스슬슬습습시식신신실실심십싱싱싶싶쌍쌍쓰쓰쓸쓸씬씬아아안안않않알알암압았앙애액앤앤앨앨앵앵야약양양어어언언얻얼업없었었에에엔엔여역연연열열영영예예오오온온올올옵옵와와완완왑왑외외왼왼요요용용우우운운울울움웁웃웃워워원원월월웨웨웹웹위위유유율율으으은은을을음음응응의의이이인인일읽임입있있자작잘잘잠잠장장재재잿잿저적전전절절점접정정제제젠젠젤젤젯젯져져조족존존종종좋좌죄죄주주준준줄줄줍줍중중즈즉즌즌즐즐즘즘증증지직진진질질짐집짝짝짧짧째째쪽쪽찌찍차착참참창찾채책챕챕처척천천철철첨첩첫첫청청체체쳐쳐초초촬촬최최추축출출춤춥충충춰춰취취츠측치칙칠칠침칩칭칭카카칸칸칼칼캐캐캔캔캘캘캠캡커커컨컨컬컬컴컴케케켓켓켜켜코코콘콘콜콜콩콩쿳쿳쿼쿼퀀퀀퀴퀴큐큐크크큰큰클클큽큽키키킨킨킬킬킵킵킹킹타타탈탈탐탐태택탠탠탬탭터터턴턴텀텀테텍텐텐텔텔템템토토톱톱통통투투툴툴트특튼튼틀틀티틱팀팀팅팅파파팔팔팝팝패패팻팻퍼퍼페펙편편평평포포폴폴폼폼표표푸푸풀풀품품풍풍퓨퓨프프픈픈플플피픽필필핑핑하하한한할할함합핫핫항항해핵했행향향허허헌헌헤헤현현형형호혹혼혼홈홈홍홍화확환환활활황황회획횟횟횡횡효효후후훨훨휠휠휴휴흐흐흔흔희희히히힌힌"
|
||||
},
|
||||
{
|
||||
"zh-CN", "msyh.ttc", nullptr, "Hiragino Sans GB.ttc",
|
||||
// auto update by update_glyph_ranges.py with pcsx2-qt_zh-CN.ts
|
||||
u"‘’□□△△○○、。一丁三下不与且且世世丢丢两两个个中中丰丰串串为主么义之之乎乎乐乐乘乘也也了了事二于于互互亚些交交产产享享亮亮亲亲人人什什仅仅介介仍从他他代以们们件价任任份份伍伍休休优优会会传传估估伸伸似似但但位住佑佑体体何何余余作作佣佣佳佳使使例例供供侧侧便便俄俄保保信信修修倍倍值值倾倾假假偏偏做做停停储储像像儿儿允允元元充充先光克克免免入入全全六六兰共关关兵典兼兼内内册再写写冲决况况净净准准减减几几出击函函刀刀刃刃分切列列则则创创删删利利别别到到制刷刹刹前前剪剪副副力力功务动助势势勿勿包包化化匹区十十升升半半协协单单南南占卡卫卫印印即即压压原原去去参参及及双反发发取变叠叠口古另另只只可台右右号号各各合吉同后向向吗吗否否含含启启呈呈告告员员味味命命和和哈哈响响哪哪唤唤商商善善器器四四回回因因团团围围国图圈圈在在地地场场址址均均坏坐块块坛坛垂垂型型域域基基堆堆堪堪塔塔填填增增士士声声处处备备复复外外多多够够大大天太失失头头夹夹奇奇奏奏套套奥奥奶奶好好如如始始威威娱娱婴婴媒媒子子字存它它安安完完宏宏官官定定宝实害害家家容容宽宽宿宿寄寄密密富富寸对导导封封射射将将小小少少尔尔尚尚尝尝就就尺尺尼尾局局层层屏屏展展属属崩崩工左巨巨差差己已巴巴希希带帧帮帮常常幅幅幕幕平平并并幸幸序序库底度度延延建建开开异弃弊弊式式引引张张弹强归当录录形形彩彩影影径待很很得得循循微微德德心心必忆志志忙忙快快忽忽态态性性怪怪恢恢息息您您悬悬情情惑惑惯惯意意感感慢慢戏我或或战战截截戳戳户户所扁手手打打托托执执扩扩扫扬扳扳找找技技抑抑抖抗护护拆拆拉拉拍拍拒拒拟拟拦拦择择括括拳拳持持指指按按挑挑挡挡挪挪振振捕捕损损换换据据掌掌排排接接控掩描提插插握握搜搜摇摇撕撕撤撤播播操擎支支收收改改放放故故效效敏敏散散数数整整文文断断斯新方方旋旋无无日日旧旧时时明明易易星映是是显显晕晕普普晰晰暂暂暗暗曲曲更更替最有有服服期期未未本本机机权权杆杆束束条条来来板板极极果果柄柄某某染染查查栅栅标栈栏栏校校样根格格框框案案档档桥桥检检棕棕榜榜模模橙橙次次欧欧止步死死殊殊段段每每比比毫毫水水求求汇汇没没油油法法波波注注泻泻洲洲活活流流浅浅测测浏浏浪浪浮浮海海消消深深混混添添清清港港渲渲游游湖湖湾湾溃溃源源溢溢滑滑满满滤滤演演澳澳激激灰灰灵灵点点烈烈热热焦焦然然煞煞照照片版牌牌牙牙特特状状狂狂独独狼狼猎猎猩猩率率王王玩玩环现班班理理瑞瑞甚甚生生用用由甲电电画画畅畅界界留留略略疤疤登登白百的的皇皇盖盘目目直直相相省省看看真眠着着知知短短石石码码破破础础硬硬确确碌碌磁磁示示神神禁禁离离种种秒秒积称移移程程稍稍稳稳空空突突窗窗立立站站端端符符第第等等筛筛签签简简算算管管类类粉粉粘粘精精糊糊系系素素索索紫紫纠纠红红级级纯纯纳纳纹纹线线组组细终经经绑绑结结绕绕绘给络绝统统继继绪绪续续维维绿缀缓缓编编缩缩网网罗罗置置美美翻翻考考者者而而耗耗耳耳联联肩肩胖胖能能腊腊自自至致舍舍良良色色节节芬芬英英范范荐荐荷荷莱莱获获菜菜萄萄著著葡葡蓝蓝藏藏虑虑虚虚融融行行衡衡补补表表被被裁裂装装西西要要覆覆观观规规视视览觉角角解解触触言言警警计计认认让让议议记记许许论论设访证证诊诊译译试试询询该详语语误误说说请诸读读调调谍谍豹豹负负败账质质贴贴费费赛赛起起超超越越足足跟跟跨跨路路跳跳踏踏踪踪身身车车轨轨转转轮软轴轴轻轻载载较较辅辅辑辑输输辨辨边边达达过过运近还这进进连迟述述追追退适选选逐逐递递通通速造遇遇道道避避那那部部都都配配醒醒采采释释里重量量针针钮钮铁铁铺铺链链销锁锐锐错错键锯镜镜长长门门闭问闲闲间间队队防防阴阴附附陆陆降降限限除除险险随隐隔隔隙隙障障雄雄集集零零雾雾需需震震静静非非靠靠面面韩韩音音顶顶项须顿顿预预频频题题颜额风风饱饱馈馈首首香香马马驱驱验验高高鬼鬼魂魂魔魔麦麦黄黄黑黑默默鼓鼓鼠鼠齐齐齿齿,,??"
|
||||
u"‘’□□△△○○、。一丁三下不与且且世世丢丢两两个个中中串串为主么义之之乎乎乐乐乘乘也也了了事二于于互互亚些交交产产享享亮亮亲亲人人什什仅仅今今仍从他他代以们们件价任任份份伍伍休休优优会会传传估估伸伸似似但但位住佑佑体体何何余余作作你你佳佳使使例例供供侧侧便便俄俄保保信信修修倍倍借借值值倾倾假假偏偏做做停停储储像像儿儿允允元元充充先光克克免免入入全全六六兰共关关其兹兼兼内内册再写写冲决况况准准减减几几出击函函刀刀刃刃分切列列则则创创删删利利别别到到制刷刹刹前前剪剪副副力力功务动助势势勿勿包包化化匹区十十升升半半协协单单南南占卡卫卫印印即即卸卸压压原原去去参参叉及双反发发取变叠叠口古另另只只可台右右号号各各合吉同后向向吗吗否否含含启启呈呈告告员员味味命命和和哈哈响响哪哪唤唤商商善善器器四四回回因因团团围围国图圈圈在在地地场场址址均均坏坐块块坛坛垂垂型型域域基基堆堆堪堪塔塔填填增增士士声声处处备备复复外外多多够够大大天太失失头头夹夹奇奇奏奏套套奥奥奶奶好好如如始始威威娱娱婴婴媒媒子子字存它它安安完完宏宏官官定定宝实害害家家容容宽宽宿宿寄寄密密富富寸对导导封封射射将将小小少少尔尔尚尚尝尝就就尺尺尼尾局局层层屏屏展展属属崩崩工左巨巨差差己已巴巴希希带帧帮帮常常幅幅幕幕平平并并幸幸序序库底度度延延建建开开异弃弊弊式式引引张张弹强归当录录形形彩彩影影径待很很律律得得循循微微德德心心必忆志志忙忙快快忽忽态态性性怪怪恢恢息息您您悬悬情情惑惑惯惯想想愉愉意意感感慢慢戏我或或战战截截戳戳户户所扁手手才才打打托托执执扩扩扫扬扳扳找找技技抑抑抖抗护护拆拆拉拉拍拍拒拒拟拟拥拦择择括括拳拳持持指指按按挑挑挡挡挪挪振振捕捕损损换换据据捷捷掌掌排排接接控掩描提插插握握搜搜摇摇摘摘撕撕撤撤播播操擎支支收收改改放放故故效效敏敏散散数数整整文文断断斯新方方旋旋无无日日旧旧时时明明易易星映是是显显晕晕普普晰晰暂暂暗暗曲曲更更替最有有服服望望期期未未本本机机权权杆杆束束条条来来板板极极果果柄柄某某染染查查栅栅标栈栏栏校校样根格格框框案案档档桥桥检检棕棕榜榜槽槽模模橙橙次欢欧欧止步死死殊殊段段每每比比毫毫水水求求汇汇没没油油法法波波注注泻泻洲洲活活流流浅浅测测浏浏浪浪浮浮海海消消淡淡深深混混添添清清港港渲渲游游湖湖湾湾溃溃源源溢溢滑滑满满滤滤演演澳澳激激灰灰灵灵点点烈烈热热焦焦然然煞煞照照片版牌牌牙牙特特状状狂狂独独狼狼猎猎猩猩率率王王玩玩环现班班理理瑞瑞甚甚生生用用由由电电画画畅畅界界留留略略疤疤登登白百的的皇皇盖盘目目直直相相省省看看真眠着着知知短短石石码码破破础础硬硬确确碌碌磁磁示示神神禁禁离离种种秒秒积称移移程程稍稍稳稳空空突突窗窗立立站站端端符符第第等等答答筛筛签签简简算算管管类类粉粉粘粘精精糊糊系系素素索索紫紫纠纠红红级级纳纳纹纹线线组组细终经经绑绑结结绕绕绘给络绝统统继继绪绪续续维维绿缀缓缓编编缩缩缺缺网网罗罗置置美美翻翻考考者者而而耗耗耳耳联联肩肩胖胖能能腊腊自自至致舍舍航航良良色色节节芬芬英英范范荐荐荷荷莱莱获获菜菜萄萄著著葡葡蓝蓝藏藏虑虑虚虚融融行行衡衡补补表表被被裁裂装装西西要要覆覆见观规规视视览觉角角解解触触言言警警计计认认让让议议记记许许论论设访证证识识诊诊译译试试询询该详语语误误说说请诸读读调调谍谍豹豹负负败账质质贴贴费费赛赛赫赫起起超超越越足足跃跃跟跟跨跨路路跳跳踏踏踪踪身身车车轨轨转转轮软轴轴轻轻载载较较辅辅辑辑输输辨辨边边达达过过迎迎运近还这进进连迟述述追追退适逆逆选选逐逐递递通通速造遇遇道道避避那那邻邻部部都都配配醒醒采采释释里重量量针针钮钮铁铁铺铺链链销锁锐锐错错键锯镜镜长长门门闭问闲闲间间阅阅队队防防阴阴附陆降降限限除除险险随隐隔隔隙隙障障雄雄集集零零雾雾需需震震静静非非靠靠面面韩韩音音顶顶项须顿顿预预频频题题颜额风风饱饱馈馈首首香香马马驱驱骤骤高高鬼鬼魂魂魔魔麦麦黄黄黑黑默默鼓鼓鼠鼠齐齐齿齿,,::??"
|
||||
},
|
||||
{
|
||||
"zh-TW", "msyh.ttc", nullptr, "Hiragino Sans GB.ttc",
|
||||
// auto update by update_glyph_ranges.py with pcsx2-qt_zh-TW.ts
|
||||
u""
|
||||
u"、。一一上下不不且且並並中中主主了了互互今今令以件件任任位位何何使使來來係係保保個個優優儲儲免免入入內全具具兼兼冊冊再再到到創創功加助助動動務務勢勢包包協協南南及及取取只只可可合合名名和和商商問問啟啟嘗嘗器器嚮嚮在在壇壇多多失失如如始始娛娛存存它它安安完完官官定定容容密密將將對導就就尼尼局局希希幫幫序序庫庫建建後後得得從從您您情情意意態態應應成成戲戲戶戶所所持持指指接接擇擇擬擬支支改改敗敗新新方方於於是是時時更更會會有有服服望望本本果果查查樂樂標標模模機機檢檢次次歡步沒沒況況消消源源為為然然版版牌牌狀狀獲獲玩玩現現理理生生用用界界登發的的看看硬硬確確碼碼程程種種站站第第管管系系索索組組絡絡統統網網緒緒編編置置而而聯聯能能自自與與虛虛裝裝要要解解言言訪訪設設許許註註試試該該認認語語誤誤請請論論譯議費費起起載載輸輸迎迎這通連連遊遊過過選選配配釋釋重重錄錄錯錯鏈鏈開開間間關關防防附附需需面面項項題題驟驟默默"
|
||||
},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -306,6 +306,9 @@
|
||||
<QtUi Include="Settings\ControllerBindingWidget_DualShock2.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\ControllerBindingWidget_Guitar.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\ControllerBindingWidget.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
@@ -371,6 +374,9 @@
|
||||
</QtUi>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtUi Include="Settings\USBBindingWidget_GunCon2.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
<QtUi Include="SetupWizardDialog.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
@@ -392,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>
|
||||
|
||||
@@ -531,6 +531,9 @@
|
||||
<QtUi Include="Settings\ControllerBindingWidget_DualShock2.ui">
|
||||
<Filter>Settings</Filter>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\ControllerBindingWidget_Guitar.ui">
|
||||
<Filter>Settings</Filter>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\ControllerBindingWidget.ui">
|
||||
<Filter>Settings</Filter>
|
||||
</QtUi>
|
||||
@@ -621,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 |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="guitar_PCSX2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 493.66 474.14"><defs><style>.cls-1,.cls-2{stroke:#000;stroke-miterlimit:10;}.cls-2{stroke-width:20px;}</style></defs><g id="By_maxihplay"><path id="corpo" class="cls-1" d="M188.41,192.55c-.75,14.56,6.75,47.85,20.03,67.76,19.32,28.97,42.12,37.78,54.54,43.83-17.76,8.99-43.47,27.14-53.18,55-1.18,3.26-1.97,6.71-2.27,10.24-3.93,46.09-40.35,63.32-70.26,64.13-14.57,.4-29.14-2.93-42.13-9.52-14.19-7.25-26.02-17.98-35.01-32.02-.41-.58-.81-1.15-1.22-1.73-10.27-14.2-16.49-30.76-17.93-47.84-1.42-16.1,1.39-31.83,7.86-45.71,2.65-5.68,10.86-21.28,28.05-31.02,12.09-6.86,22.94-7.51,28.71-8.28,17.19-2.32,61.18-15.77,82.82-64.84Zm19.53-71.29c-38.91,1.06-45.85,41.06-64.11,71.01-14.61,23.88-38.65,24.92-40.31,24.97h-.1C10.15,223.2-29.95,335.62,26.37,413.63c26.97,41.92,70.63,61.09,111.99,59.96,53.67-1.46,103.78-36.96,109.18-100.8h0c19.93-58.65,105.53-15.58,93.41-112.5-23.14,8.75-40.07,12.44-52.19,12.77-26.98,.73-31.85-18.13-27.99-30.95l-25.37-31.05c-20.51-52.62-2.68-69.18,10.16-86.16-6.4-1.49-32.54-3.87-37.62-3.63h0Z"/><path id="cordas" class="cls-2" d="M103.87,365.16l-2.97-3.25c-3.52-3.71-3.25-9.64,.56-13.17l65.75-61.02c3.8-3.52,9.64-3.25,13.17,.46l2.97,3.25c3.52,3.71,3.25,9.64-.56,13.17l-65.75,61.02c-3.71,3.52-9.64,3.25-13.17-.46h0Z"/><polygon id="braco" class="cls-2" points="239.3 255.5 223.65 236.65 365.87 104.18 382.89 121.88 239.3 255.5"/><path class="cls-1" d="M485.96,27.45l-16.94-18.24c-10.07-10.97-27.21-11.69-38.25-1.56l-68.38,63.39c-10.94,10.08-11.64,27.19-1.51,38.22l16.94,18.24c5.31,5.78,12.58,8.71,19.88,8.71,6.56,0,13.14-2.37,18.37-7.16l68.35-63.35c5.33-4.89,8.42-11.56,8.72-18.79,.29-7.2-2.23-14.09-7.17-19.47Z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -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 |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="guitar_PCSX2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 492.66 473.14"><defs><style>.cls-1,.cls-2{fill:#fff;}.cls-2{stroke:#fff;stroke-miterlimit:10;stroke-width:20px;}</style></defs><g id="By_maxihplay"><path id="corpo" class="cls-1" d="M187.91,192.05c-.75,14.56,6.75,47.85,20.03,67.76,19.32,28.97,42.12,37.78,54.54,43.83-17.76,8.99-43.47,27.14-53.18,55-1.18,3.26-1.97,6.71-2.27,10.24-3.93,46.09-40.35,63.32-70.26,64.13-14.57,.4-29.14-2.93-42.13-9.52-14.19-7.25-26.02-17.98-35.01-32.02-.41-.58-.81-1.15-1.22-1.73-10.27-14.2-16.49-30.76-17.93-47.84-1.42-16.1,1.39-31.83,7.86-45.71,2.65-5.68,10.86-21.28,28.05-31.02,12.09-6.86,22.94-7.51,28.71-8.28,17.19-2.32,61.18-15.77,82.82-64.84Zm19.53-71.29c-38.91,1.06-45.85,41.06-64.11,71.01-14.61,23.88-38.65,24.92-40.31,24.97h-.1C9.65,222.7-30.45,335.12,25.87,413.13c26.97,41.92,70.63,61.09,111.99,59.96,53.67-1.46,103.78-36.96,109.18-100.8h0c19.93-58.65,105.53-15.58,93.41-112.5-23.14,8.75-40.07,12.44-52.19,12.77-26.98,.73-31.85-18.13-27.99-30.95l-25.37-31.05c-20.51-52.62-2.68-69.18,10.16-86.16-6.4-1.49-32.54-3.87-37.62-3.63h0Z"/><path id="cordas" class="cls-2" d="M103.37,364.66l-2.97-3.25c-3.52-3.71-3.25-9.64,.56-13.17l65.75-61.02c3.8-3.52,9.64-3.25,13.17,.46l2.97,3.25c3.52,3.71,3.25,9.64-.56,13.17l-65.75,61.02c-3.71,3.52-9.64,3.25-13.17-.46h0Z"/><polygon id="braco" class="cls-2" points="238.8 255 223.15 236.15 365.37 103.68 382.39 121.38 238.8 255"/><path class="cls-1" d="M485.46,26.95l-16.94-18.24c-10.07-10.97-27.21-11.69-38.25-1.56l-68.38,63.39c-10.94,10.08-11.64,27.19-1.51,38.22l16.94,18.24c5.31,5.78,12.58,8.71,19.88,8.71,6.56,0,13.14-2.37,18.37-7.16l68.35-63.35c5.33-4.89,8.42-11.56,8.72-18.79,.29-7.2-2.23-14.09-7.17-19.47Z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 1.7 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="-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 |
|
After Width: | Height: | Size: 34 KiB |
@@ -1,147 +1,150 @@
|
||||
<RCC>
|
||||
<qresource>
|
||||
<file>icons/AppIcon64.png</file>
|
||||
<file>icons/applications-system-24.png</file>
|
||||
<file>icons/black/index.theme</file>
|
||||
<file>icons/black/svg/arrow-left-right-line.svg</file>
|
||||
<file>icons/black/svg/artboard-2-line.svg</file>
|
||||
<file>icons/black/svg/at.svg</file>
|
||||
<file>icons/black/svg/band-aid-line.svg</file>
|
||||
<file>icons/black/svg/brush-line.svg</file>
|
||||
<file>icons/black/svg/cheats-line.svg</file>
|
||||
<file>icons/black/svg/checkbox-multiple-blank-line.svg</file>
|
||||
<file>icons/black/svg/chip-line.svg</file>
|
||||
<file>icons/black/svg/close-line.svg</file>
|
||||
<file>icons/black/svg/controller-line.svg</file>
|
||||
<file>icons/black/svg/controller-strike-line.svg</file>
|
||||
<file>icons/black/svg/delete-back-2-line.svg</file>
|
||||
<file>icons/black/svg/disc-2-line.svg</file>
|
||||
<file>icons/black/svg/disc-eject-line.svg</file>
|
||||
<file>icons/black/svg/discord.svg</file>
|
||||
<file>icons/black/svg/door-open-line.svg</file>
|
||||
<file>icons/black/svg/download-2-line.svg</file>
|
||||
<file>icons/black/svg/eject-line.svg</file>
|
||||
<file>icons/black/svg/emulation-line.svg</file>
|
||||
<file>icons/black/svg/file-add-line.svg</file>
|
||||
<file>icons/black/svg/file-line.svg</file>
|
||||
<file>icons/black/svg/file-list-line.svg</file>
|
||||
<file>icons/black/svg/file-reduce-line.svg</file>
|
||||
<file>icons/black/svg/file-search-line.svg</file>
|
||||
<file>icons/black/svg/file-settings-line.svg</file>
|
||||
<file>icons/black/svg/filter-line.svg</file>
|
||||
<file>icons/black/svg/flashlight-line.svg</file>
|
||||
<file>icons/black/svg/floppy-in-line.svg</file>
|
||||
<file>icons/black/svg/floppy-out-line.svg</file>
|
||||
<file>icons/black/svg/folder-add-line.svg</file>
|
||||
<file>icons/black/svg/folder-open-line.svg</file>
|
||||
<file>icons/black/svg/folder-reduce-line.svg</file>
|
||||
<file>icons/black/svg/folder-settings-line.svg</file>
|
||||
<file>icons/black/svg/fullscreen-line.svg</file>
|
||||
<file>icons/black/svg/function-line.svg</file>
|
||||
<file>icons/black/svg/github.svg</file>
|
||||
<file>icons/black/svg/global-line.svg</file>
|
||||
<file>icons/black/svg/heart-circle-line.svg</file>
|
||||
<file>icons/black/svg/heart-monitor-line.svg</file>
|
||||
<file>icons/black/svg/image-fill.svg</file>
|
||||
<file>icons/black/svg/interface-line.svg</file>
|
||||
<file>icons/black/svg/keyboard-line.svg</file>
|
||||
<file>icons/black/svg/lightbulb-line.svg</file>
|
||||
<file>icons/black/svg/list-check.svg</file>
|
||||
<file>icons/black/svg/login-box-line.svg</file>
|
||||
<file>icons/black/svg/memcard-line.svg</file>
|
||||
<file>icons/black/svg/mouse-line.svg</file>
|
||||
<file>icons/black/svg/pause-line.svg</file>
|
||||
<file>icons/black/svg/play-line.svg</file>
|
||||
<file>icons/black/svg/price-tag-3-line.svg</file>
|
||||
<file>icons/black/svg/refresh-line.svg</file>
|
||||
<file>icons/black/svg/restart-line.svg</file>
|
||||
<file>icons/black/svg/save-3-line.svg</file>
|
||||
<file>icons/black/svg/screenshot-2-line.svg</file>
|
||||
<file>icons/black/svg/settings-3-line.svg</file>
|
||||
<file>icons/black/svg/shut-down-line.svg</file>
|
||||
<file>icons/black/svg/tools-line.svg</file>
|
||||
<file>icons/black/svg/trophy-line.svg</file>
|
||||
<file>icons/black/svg/tv-2-line.svg</file>
|
||||
<file>icons/black/svg/usb-fill.svg</file>
|
||||
<file>icons/black/svg/volume-up-line.svg</file>
|
||||
<file>icons/black/svg/warning-line.svg</file>
|
||||
<file>icons/black/svg/window-2-line.svg</file>
|
||||
<file>icons/black/svg/zoom-in-line.svg</file>
|
||||
<file>icons/black/svg/zoom-out-line.svg</file>
|
||||
<file>icons/logo.png</file>
|
||||
<file>icons/media-optical-24.png</file>
|
||||
<file>icons/media-optical-gear-24.png</file>
|
||||
<file>icons/media-optical.png</file>
|
||||
<file>icons/QT.png</file>
|
||||
<file>icons/update.png</file>
|
||||
<file>icons/white/index.theme</file>
|
||||
<file>icons/white/svg/arrow-left-right-line.svg</file>
|
||||
<file>icons/white/svg/artboard-2-line.svg</file>
|
||||
<file>icons/white/svg/at.svg</file>
|
||||
<file>icons/white/svg/band-aid-line.svg</file>
|
||||
<file>icons/white/svg/brush-line.svg</file>
|
||||
<file>icons/white/svg/cheats-line.svg</file>
|
||||
<file>icons/white/svg/checkbox-multiple-blank-line.svg</file>
|
||||
<file>icons/white/svg/chip-line.svg</file>
|
||||
<file>icons/white/svg/close-line.svg</file>
|
||||
<file>icons/white/svg/controller-line.svg</file>
|
||||
<file>icons/white/svg/controller-strike-line.svg</file>
|
||||
<file>icons/white/svg/delete-back-2-line.svg</file>
|
||||
<file>icons/white/svg/disc-2-line.svg</file>
|
||||
<file>icons/white/svg/disc-eject-line.svg</file>
|
||||
<file>icons/white/svg/discord.svg</file>
|
||||
<file>icons/white/svg/door-open-line.svg</file>
|
||||
<file>icons/white/svg/download-2-line.svg</file>
|
||||
<file>icons/white/svg/eject-line.svg</file>
|
||||
<file>icons/white/svg/emulation-line.svg</file>
|
||||
<file>icons/white/svg/file-add-line.svg</file>
|
||||
<file>icons/white/svg/file-line.svg</file>
|
||||
<file>icons/white/svg/file-list-line.svg</file>
|
||||
<file>icons/white/svg/file-reduce-line.svg</file>
|
||||
<file>icons/white/svg/file-search-line.svg</file>
|
||||
<file>icons/white/svg/file-settings-line.svg</file>
|
||||
<file>icons/white/svg/filter-line.svg</file>
|
||||
<file>icons/white/svg/flashlight-line.svg</file>
|
||||
<file>icons/white/svg/floppy-in-line.svg</file>
|
||||
<file>icons/white/svg/floppy-out-line.svg</file>
|
||||
<file>icons/white/svg/folder-add-line.svg</file>
|
||||
<file>icons/white/svg/folder-open-line.svg</file>
|
||||
<file>icons/white/svg/folder-reduce-line.svg</file>
|
||||
<file>icons/white/svg/folder-settings-line.svg</file>
|
||||
<file>icons/white/svg/fullscreen-line.svg</file>
|
||||
<file>icons/white/svg/function-line.svg</file>
|
||||
<file>icons/white/svg/github.svg</file>
|
||||
<file>icons/white/svg/global-line.svg</file>
|
||||
<file>icons/white/svg/heart-circle-line.svg</file>
|
||||
<file>icons/white/svg/heart-monitor-line.svg</file>
|
||||
<file>icons/white/svg/image-fill.svg</file>
|
||||
<file>icons/white/svg/interface-line.svg</file>
|
||||
<file>icons/white/svg/keyboard-line.svg</file>
|
||||
<file>icons/white/svg/lightbulb-line.svg</file>
|
||||
<file>icons/white/svg/list-check.svg</file>
|
||||
<file>icons/white/svg/login-box-line.svg</file>
|
||||
<file>icons/white/svg/memcard-line.svg</file>
|
||||
<file>icons/white/svg/mouse-line.svg</file>
|
||||
<file>icons/white/svg/pause-line.svg</file>
|
||||
<file>icons/white/svg/play-line.svg</file>
|
||||
<file>icons/white/svg/price-tag-3-line.svg</file>
|
||||
<file>icons/white/svg/refresh-line.svg</file>
|
||||
<file>icons/white/svg/restart-line.svg</file>
|
||||
<file>icons/white/svg/save-3-line.svg</file>
|
||||
<file>icons/white/svg/screenshot-2-line.svg</file>
|
||||
<file>icons/white/svg/settings-3-line.svg</file>
|
||||
<file>icons/white/svg/shut-down-line.svg</file>
|
||||
<file>icons/white/svg/tools-line.svg</file>
|
||||
<file>icons/white/svg/trophy-line.svg</file>
|
||||
<file>icons/white/svg/tv-2-line.svg</file>
|
||||
<file>icons/white/svg/usb-fill.svg</file>
|
||||
<file>icons/white/svg/volume-up-line.svg</file>
|
||||
<file>icons/white/svg/warning-line.svg</file>
|
||||
<file>icons/white/svg/window-2-line.svg</file>
|
||||
<file>icons/white/svg/zoom-in-line.svg</file>
|
||||
<file>icons/white/svg/zoom-out-line.svg</file>
|
||||
<file>images/DrivingForce.png</file>
|
||||
<file>images/dualshock-2.png</file>
|
||||
<file>images/GTForce.png</file>
|
||||
</qresource>
|
||||
<qresource>
|
||||
<file>icons/AppIcon64.png</file>
|
||||
<file>icons/applications-system-24.png</file>
|
||||
<file>icons/black/index.theme</file>
|
||||
<file>icons/black/svg/arrow-left-right-line.svg</file>
|
||||
<file>icons/black/svg/artboard-2-line.svg</file>
|
||||
<file>icons/black/svg/at.svg</file>
|
||||
<file>icons/black/svg/band-aid-line.svg</file>
|
||||
<file>icons/black/svg/brush-line.svg</file>
|
||||
<file>icons/black/svg/cheats-line.svg</file>
|
||||
<file>icons/black/svg/checkbox-multiple-blank-line.svg</file>
|
||||
<file>icons/black/svg/chip-line.svg</file>
|
||||
<file>icons/black/svg/close-line.svg</file>
|
||||
<file>icons/black/svg/controller-line.svg</file>
|
||||
<file>icons/black/svg/controller-strike-line.svg</file>
|
||||
<file>icons/black/svg/delete-back-2-line.svg</file>
|
||||
<file>icons/black/svg/disc-2-line.svg</file>
|
||||
<file>icons/black/svg/disc-eject-line.svg</file>
|
||||
<file>icons/black/svg/discord.svg</file>
|
||||
<file>icons/black/svg/door-open-line.svg</file>
|
||||
<file>icons/black/svg/download-2-line.svg</file>
|
||||
<file>icons/black/svg/eject-line.svg</file>
|
||||
<file>icons/black/svg/emulation-line.svg</file>
|
||||
<file>icons/black/svg/file-add-line.svg</file>
|
||||
<file>icons/black/svg/file-line.svg</file>
|
||||
<file>icons/black/svg/file-list-line.svg</file>
|
||||
<file>icons/black/svg/file-reduce-line.svg</file>
|
||||
<file>icons/black/svg/file-search-line.svg</file>
|
||||
<file>icons/black/svg/file-settings-line.svg</file>
|
||||
<file>icons/black/svg/filter-line.svg</file>
|
||||
<file>icons/black/svg/flashlight-line.svg</file>
|
||||
<file>icons/black/svg/floppy-in-line.svg</file>
|
||||
<file>icons/black/svg/floppy-out-line.svg</file>
|
||||
<file>icons/black/svg/folder-add-line.svg</file>
|
||||
<file>icons/black/svg/folder-open-line.svg</file>
|
||||
<file>icons/black/svg/folder-reduce-line.svg</file>
|
||||
<file>icons/black/svg/guitar-line.svg</file>
|
||||
<file>icons/black/svg/folder-settings-line.svg</file>
|
||||
<file>icons/black/svg/fullscreen-line.svg</file>
|
||||
<file>icons/black/svg/function-line.svg</file>
|
||||
<file>icons/black/svg/github.svg</file>
|
||||
<file>icons/black/svg/global-line.svg</file>
|
||||
<file>icons/black/svg/heart-circle-line.svg</file>
|
||||
<file>icons/black/svg/heart-monitor-line.svg</file>
|
||||
<file>icons/black/svg/image-fill.svg</file>
|
||||
<file>icons/black/svg/interface-line.svg</file>
|
||||
<file>icons/black/svg/keyboard-line.svg</file>
|
||||
<file>icons/black/svg/lightbulb-line.svg</file>
|
||||
<file>icons/black/svg/list-check.svg</file>
|
||||
<file>icons/black/svg/login-box-line.svg</file>
|
||||
<file>icons/black/svg/memcard-line.svg</file>
|
||||
<file>icons/black/svg/mouse-line.svg</file>
|
||||
<file>icons/black/svg/pause-line.svg</file>
|
||||
<file>icons/black/svg/play-line.svg</file>
|
||||
<file>icons/black/svg/price-tag-3-line.svg</file>
|
||||
<file>icons/black/svg/refresh-line.svg</file>
|
||||
<file>icons/black/svg/restart-line.svg</file>
|
||||
<file>icons/black/svg/save-3-line.svg</file>
|
||||
<file>icons/black/svg/screenshot-2-line.svg</file>
|
||||
<file>icons/black/svg/settings-3-line.svg</file>
|
||||
<file>icons/black/svg/shut-down-line.svg</file>
|
||||
<file>icons/black/svg/tools-line.svg</file>
|
||||
<file>icons/black/svg/trophy-line.svg</file>
|
||||
<file>icons/black/svg/tv-2-line.svg</file>
|
||||
<file>icons/black/svg/usb-fill.svg</file>
|
||||
<file>icons/black/svg/volume-up-line.svg</file>
|
||||
<file>icons/black/svg/warning-line.svg</file>
|
||||
<file>icons/black/svg/window-2-line.svg</file>
|
||||
<file>icons/black/svg/zoom-in-line.svg</file>
|
||||
<file>icons/black/svg/zoom-out-line.svg</file>
|
||||
<file>icons/logo.png</file>
|
||||
<file>icons/media-optical-24.png</file>
|
||||
<file>icons/media-optical-gear-24.png</file>
|
||||
<file>icons/media-optical.png</file>
|
||||
<file>icons/QT.png</file>
|
||||
<file>icons/update.png</file>
|
||||
<file>icons/white/index.theme</file>
|
||||
<file>icons/white/svg/arrow-left-right-line.svg</file>
|
||||
<file>icons/white/svg/artboard-2-line.svg</file>
|
||||
<file>icons/white/svg/at.svg</file>
|
||||
<file>icons/white/svg/band-aid-line.svg</file>
|
||||
<file>icons/white/svg/brush-line.svg</file>
|
||||
<file>icons/white/svg/cheats-line.svg</file>
|
||||
<file>icons/white/svg/checkbox-multiple-blank-line.svg</file>
|
||||
<file>icons/white/svg/chip-line.svg</file>
|
||||
<file>icons/white/svg/close-line.svg</file>
|
||||
<file>icons/white/svg/controller-line.svg</file>
|
||||
<file>icons/white/svg/controller-strike-line.svg</file>
|
||||
<file>icons/white/svg/delete-back-2-line.svg</file>
|
||||
<file>icons/white/svg/disc-2-line.svg</file>
|
||||
<file>icons/white/svg/disc-eject-line.svg</file>
|
||||
<file>icons/white/svg/discord.svg</file>
|
||||
<file>icons/white/svg/door-open-line.svg</file>
|
||||
<file>icons/white/svg/download-2-line.svg</file>
|
||||
<file>icons/white/svg/eject-line.svg</file>
|
||||
<file>icons/white/svg/emulation-line.svg</file>
|
||||
<file>icons/white/svg/file-add-line.svg</file>
|
||||
<file>icons/white/svg/file-line.svg</file>
|
||||
<file>icons/white/svg/file-list-line.svg</file>
|
||||
<file>icons/white/svg/file-reduce-line.svg</file>
|
||||
<file>icons/white/svg/file-search-line.svg</file>
|
||||
<file>icons/white/svg/file-settings-line.svg</file>
|
||||
<file>icons/white/svg/filter-line.svg</file>
|
||||
<file>icons/white/svg/flashlight-line.svg</file>
|
||||
<file>icons/white/svg/floppy-in-line.svg</file>
|
||||
<file>icons/white/svg/floppy-out-line.svg</file>
|
||||
<file>icons/white/svg/folder-add-line.svg</file>
|
||||
<file>icons/white/svg/folder-open-line.svg</file>
|
||||
<file>icons/white/svg/folder-reduce-line.svg</file>
|
||||
<file>icons/white/svg/folder-settings-line.svg</file>
|
||||
<file>icons/white/svg/fullscreen-line.svg</file>
|
||||
<file>icons/white/svg/function-line.svg</file>
|
||||
<file>icons/white/svg/github.svg</file>
|
||||
<file>icons/white/svg/global-line.svg</file>
|
||||
<file>icons/white/svg/guitar-line.svg</file>
|
||||
<file>icons/white/svg/heart-circle-line.svg</file>
|
||||
<file>icons/white/svg/heart-monitor-line.svg</file>
|
||||
<file>icons/white/svg/image-fill.svg</file>
|
||||
<file>icons/white/svg/interface-line.svg</file>
|
||||
<file>icons/white/svg/keyboard-line.svg</file>
|
||||
<file>icons/white/svg/lightbulb-line.svg</file>
|
||||
<file>icons/white/svg/list-check.svg</file>
|
||||
<file>icons/white/svg/login-box-line.svg</file>
|
||||
<file>icons/white/svg/memcard-line.svg</file>
|
||||
<file>icons/white/svg/mouse-line.svg</file>
|
||||
<file>icons/white/svg/pause-line.svg</file>
|
||||
<file>icons/white/svg/play-line.svg</file>
|
||||
<file>icons/white/svg/price-tag-3-line.svg</file>
|
||||
<file>icons/white/svg/refresh-line.svg</file>
|
||||
<file>icons/white/svg/restart-line.svg</file>
|
||||
<file>icons/white/svg/save-3-line.svg</file>
|
||||
<file>icons/white/svg/screenshot-2-line.svg</file>
|
||||
<file>icons/white/svg/settings-3-line.svg</file>
|
||||
<file>icons/white/svg/shut-down-line.svg</file>
|
||||
<file>icons/white/svg/tools-line.svg</file>
|
||||
<file>icons/white/svg/trophy-line.svg</file>
|
||||
<file>icons/white/svg/tv-2-line.svg</file>
|
||||
<file>icons/white/svg/usb-fill.svg</file>
|
||||
<file>icons/white/svg/volume-up-line.svg</file>
|
||||
<file>icons/white/svg/warning-line.svg</file>
|
||||
<file>icons/white/svg/window-2-line.svg</file>
|
||||
<file>icons/white/svg/zoom-in-line.svg</file>
|
||||
<file>icons/white/svg/zoom-out-line.svg</file>
|
||||
<file>images/DrivingForce.png</file>
|
||||
<file>images/dualshock-2.png</file>
|
||||
<file>images/GTForce.png</file>
|
||||
<file>images/guitar.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include "IopHw.h"
|
||||
#include "IopDma.h"
|
||||
#include "VMManager.h"
|
||||
#include "Sio.h"
|
||||
#include "SIO/Sio.h"
|
||||
|
||||
#include "common/Error.h"
|
||||
#include "common/FileSystem.h"
|
||||
|
||||
@@ -0,0 +1,200 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "CDVD/CDVDcommon.h"
|
||||
#include "CDVD/IsoHasher.h"
|
||||
#include "Host.h"
|
||||
|
||||
#include "common/Error.h"
|
||||
#include "common/MD5Digest.h"
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include "fmt/core.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
IsoHasher::IsoHasher() = default;
|
||||
|
||||
IsoHasher::~IsoHasher()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
std::string_view IsoHasher::GetTrackTypeString(u32 type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case CDVD_AUDIO_TRACK:
|
||||
return TRANSLATE_SV("CDVD", "Audio");
|
||||
case CDVD_MODE1_TRACK:
|
||||
return TRANSLATE_SV("CDVD", "Mode 1");
|
||||
case CDVD_MODE2_TRACK:
|
||||
return TRANSLATE_SV("CDVD", "Mode 2");
|
||||
default:
|
||||
return TRANSLATE_SV("CDVD", "Unknown");
|
||||
}
|
||||
}
|
||||
|
||||
bool IsoHasher::Open(std::string iso_path, Error* error)
|
||||
{
|
||||
Close();
|
||||
|
||||
CDVDsys_SetFile(CDVD_SourceType::Iso, std::move(iso_path));
|
||||
CDVDsys_ChangeSource(CDVD_SourceType::Iso);
|
||||
|
||||
m_is_open = DoCDVDopen();
|
||||
if (!m_is_open)
|
||||
{
|
||||
Error::SetString(error, "Failed to open CDVD.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const s32 type = DoCDVDdetectDiskType();
|
||||
switch (type)
|
||||
{
|
||||
case CDVD_TYPE_PSCD:
|
||||
case CDVD_TYPE_PSCDDA:
|
||||
case CDVD_TYPE_PS2CD:
|
||||
case CDVD_TYPE_PS2CDDA:
|
||||
m_is_cd = true;
|
||||
break;
|
||||
|
||||
case CDVD_TYPE_PS2DVD:
|
||||
m_is_cd = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
Error::SetString(error, fmt::format("Unknown CDVD disk type {}", type));
|
||||
return false;
|
||||
}
|
||||
|
||||
cdvdTN tn;
|
||||
if (CDVD->getTN(&tn) < 0)
|
||||
{
|
||||
Error::SetString(error, "Failed to get track count.");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (u8 track = tn.strack; track <= tn.etrack; track++)
|
||||
{
|
||||
cdvdTD td, next_td;
|
||||
if (CDVD->getTD(track, &td) < 0 || CDVD->getTD((track == tn.etrack) ? 0 : (track + 1), &next_td) < 0)
|
||||
{
|
||||
Error::SetString(error, fmt::format("Failed to get track range for {}", static_cast<unsigned>(track)));
|
||||
return false;
|
||||
}
|
||||
|
||||
// sanity check..
|
||||
if (next_td.lsn < td.lsn)
|
||||
{
|
||||
Error::SetString(error,
|
||||
fmt::format("Invalid track range for {} ({},{})", static_cast<unsigned>(track), td.lsn, next_td.lsn));
|
||||
return false;
|
||||
}
|
||||
|
||||
Track strack;
|
||||
strack.number = track;
|
||||
strack.type = td.type;
|
||||
strack.start_lsn = td.lsn;
|
||||
strack.sectors = next_td.lsn - td.lsn;
|
||||
strack.size = static_cast<u64>(strack.sectors) * (m_is_cd ? 2352 : 2048);
|
||||
m_tracks.push_back(std::move(strack));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void IsoHasher::Close()
|
||||
{
|
||||
if (!m_is_open)
|
||||
return;
|
||||
|
||||
DoCDVDclose();
|
||||
m_tracks.clear();
|
||||
m_is_cd = false;
|
||||
m_is_open = false;
|
||||
}
|
||||
|
||||
void IsoHasher::ComputeHashes(ProgressCallback* callback)
|
||||
{
|
||||
callback->SetProgressRange(GetTrackCount());
|
||||
callback->SetProgressValue(0);
|
||||
callback->SetCancellable(true);
|
||||
|
||||
for (u32 index = 0; index < GetTrackCount(); index++)
|
||||
{
|
||||
Track& track = m_tracks[index];
|
||||
if (!track.hash.empty())
|
||||
{
|
||||
callback->SetProgressValue(index + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
callback->PushState();
|
||||
const bool result = ComputeTrackHash(track, callback);
|
||||
callback->PopState();
|
||||
|
||||
if (!result)
|
||||
break;
|
||||
|
||||
callback->SetProgressValue(index + 1);
|
||||
callback->IncrementProgressValue();
|
||||
}
|
||||
|
||||
callback->SetProgressValue(GetTrackCount());
|
||||
}
|
||||
|
||||
bool IsoHasher::ComputeTrackHash(Track& track, ProgressCallback* callback)
|
||||
{
|
||||
// use 2048 byte reads for DVDs, otherwise 2352 raw.
|
||||
const int read_mode = m_is_cd ? CDVD_MODE_2352 : CDVD_MODE_2048;
|
||||
const u32 sector_size = m_is_cd ? 2352 : 2048;
|
||||
std::vector<u8> sector_buffer(sector_size);
|
||||
|
||||
const u32 update_interval = std::max<u32>(track.sectors / 100u, 1u);
|
||||
callback->SetFormattedStatusText("Computing hash for track %u...", track.number);
|
||||
callback->SetProgressRange(track.sectors);
|
||||
|
||||
MD5Digest md5;
|
||||
for (u32 i = 0; i < track.sectors; i++)
|
||||
{
|
||||
if (callback->IsCancelled())
|
||||
return false;
|
||||
|
||||
const u32 lsn = track.start_lsn + i;
|
||||
if (DoCDVDreadSector(sector_buffer.data(), lsn, read_mode) != 0)
|
||||
{
|
||||
callback->DisplayFormattedModalError("Read error at LSN %u", lsn);
|
||||
return false;
|
||||
}
|
||||
|
||||
md5.Update(sector_buffer.data(), sector_size);
|
||||
|
||||
if ((i % update_interval) == 0)
|
||||
callback->SetProgressValue(i);
|
||||
}
|
||||
|
||||
u8 digest[16];
|
||||
md5.Final(digest);
|
||||
track.hash =
|
||||
fmt::format("{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
|
||||
digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], digest[6], digest[7], digest[8],
|
||||
digest[9], digest[10], digest[11], digest[12], digest[13], digest[14], digest[15]);
|
||||
|
||||
callback->SetProgressValue(track.sectors);
|
||||
return true;
|
||||
}
|
||||