diff --git a/CMakeLists.txt b/CMakeLists.txt index 910f32214e4f..88ffc50c4561 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1575,7 +1575,7 @@ else() endif() if(WIN32) - target_link_libraries(Common winmm dsound dxguid Version) + target_link_libraries(Common winmm dsound dxguid d2d1 dwrite d3d11 Version) endif() if(NOT LIBRETRO) @@ -2952,6 +2952,9 @@ if(HEADLESS) endif() add_executable(PPSSPPHeadless ${HeadlessSource}) target_link_libraries(PPSSPPHeadless ${COCOA_LIBRARY} ${QUARTZ_CORE_LIBRARY} ${IOKIT_LIBRARY} ${LinkCommon}) + if(WIN32) + target_link_libraries(PPSSPPHeadless d2d1 dwrite d3d11) + endif() setup_target_project(PPSSPPHeadless headless) endif() @@ -2980,6 +2983,9 @@ if(UNITTEST) ) endif() target_link_libraries(PPSSPPUnitTest ${COCOA_LIBRARY} ${QUARTZ_CORE_LIBRARY} ${IOKIT_LIBRARY} ${LinkCommon} Common) + if(WIN32) + target_link_libraries(PPSSPPUnitTest d2d1 dwrite d3d11) + endif() setup_target_project(PPSSPPUnitTest unittest) add_test(arm64_emitter PPSSPPUnitTest Arm64Emitter) add_test(arm_emitter PPSSPPUnitTest ArmEmitter) diff --git a/Common/Arm64Emitter.cpp b/Common/Arm64Emitter.cpp index c933793a632a..4c67f813a286 100644 --- a/Common/Arm64Emitter.cpp +++ b/Common/Arm64Emitter.cpp @@ -1953,7 +1953,7 @@ static int Count(const bool part[4]) { void ARM64XEmitter::MOVI2R(ARM64Reg Rd, u64 imm, bool optimize) { unsigned int parts = Is64Bit(Rd) ? 4 : 2; - bool upload_part[4]; + bool upload_part[4]{}; // Always start with a movz! Kills the dependency on the register. bool use_movz = true; diff --git a/Common/GPU/D3D11/thin3d_d3d11.cpp b/Common/GPU/D3D11/thin3d_d3d11.cpp index 434def09af54..c3cc5d3d3c8b 100644 --- a/Common/GPU/D3D11/thin3d_d3d11.cpp +++ b/Common/GPU/D3D11/thin3d_d3d11.cpp @@ -13,6 +13,7 @@ #include "Common/Data/Encoding/Utf8.h" #include "Common/TimeUtil.h" #include "Common/Log.h" +#include "Common/StringUtils.h" #include @@ -149,7 +150,6 @@ class D3D11DrawContext : public DrawContext { stencilDirty_ = true; } - void Draw(int vertexCount, int offset) override; void DrawIndexed(int indexCount, int offset) override; void DrawUP(const void *vdata, int vertexCount) override; @@ -1125,7 +1125,9 @@ ShaderModule *D3D11DrawContext::CreateShaderModule(ShaderStage stage, ShaderLang } if (errorMsgs) { errors = std::string((const char *)errorMsgs->GetBufferPointer(), errorMsgs->GetBufferSize()); - ERROR_LOG(Log::G3D, "Failed compiling %s:\n%s\n%s", tag, data, errors.c_str()); + ERROR_LOG(Log::G3D, "Failed compiling %s:", tag); + ERROR_LOG(Log::G3D, "%s", LineNumberString(std::string((const char *)data, dataSize)).c_str()); + ERROR_LOG(Log::G3D, "%s", errors.c_str()); } if (result != S_OK) { diff --git a/Common/GPU/MiscTypes.h b/Common/GPU/MiscTypes.h index a249145d2e9e..7e1663c53e87 100644 --- a/Common/GPU/MiscTypes.h +++ b/Common/GPU/MiscTypes.h @@ -41,7 +41,6 @@ constexpr size_t FRAME_TIME_HISTORY_LENGTH = 32; // Different APIs use different coordinate conventions enum class CoordConvention { - Direct3D9, Direct3D11, Vulkan, OpenGL, diff --git a/Common/GPU/ShaderWriter.cpp b/Common/GPU/ShaderWriter.cpp index 1bcfa95b6835..8a107af0767b 100644 --- a/Common/GPU/ShaderWriter.cpp +++ b/Common/GPU/ShaderWriter.cpp @@ -28,18 +28,20 @@ const char * const hlsl_preamble_fs = "#define ivec4 int4\n" "#define mat4 float4x4\n" "#define mat3x4 float4x3\n" // note how the conventions are backwards -"#define splat3(x) float3(x, x, x)\n" -"#define mix lerp\n" "#define lowp\n" "#define mediump\n" "#define highp\n" +"#define splat3(x) float3(x, x, x)\n" +"#define mix lerp\n" "#define fract frac\n" "#define mod(x, y) fmod(x, y)\n" -"#define inversesqrt rsqrt\n"; +"#define inversesqrt rsqrt\n" +"\n"; static const char * const hlsl_d3d11_preamble_fs = "#define DISCARD discard\n" -"#define DISCARD_BELOW(x) clip(x);\n"; +"#define DISCARD_BELOW(x) clip(x);\n" +"\n"; static const char * const vulkan_glsl_preamble_vs = "#extension GL_ARB_separate_shader_objects : enable\n" @@ -82,10 +84,13 @@ static const char * const hlsl_preamble_vs = "#define mat2 float2x2\n" "#define mat4 float4x4\n" "#define mat3x4 float4x3\n" // note how the conventions are backwards -"#define splat3(x) vec3(x, x, x)\n" "#define lowp\n" "#define mediump\n" "#define highp\n" +"#define splat3(x) float3(x, x, x)\n" +"#define mix lerp\n" +"#define fract frac\n" +"#define mod(x, y) fmod(x, y)\n" "#define inversesqrt rsqrt\n" "\n"; @@ -196,7 +201,40 @@ void ShaderWriter::Preamble(Slice extensions) { } } +void ShaderWriter::DeclareUniforms(const Slice &uniforms) { + switch (lang_.shaderLanguage) { + case HLSL_D3D11: + if (!uniforms.is_empty()) { + C("cbuffer base : register(b0) {\n"); + + for (auto &uniform : uniforms) { + F(" %s %s;\n", uniform.type, uniform.name); + } + + C("};\n"); + } + break; + case GLSL_VULKAN: + if (!uniforms.is_empty()) { + C("layout(std140, set = 0, binding = 0) uniform bufferVals {\n"); + for (auto &uniform : uniforms) { + F("%s %s;\n", uniform.type, uniform.name); + } + C("};\n"); + } + break; + + default: // GLSL OpenGL + for (auto &uniform : uniforms) { + F("uniform %s %s;\n", uniform.type, uniform.name); + } + break; + } +} + void ShaderWriter::BeginVSMain(Slice inputs, Slice uniforms, Slice varyings) { + DeclareUniforms(uniforms); + _assert_(this->stage_ == ShaderStage::Vertex); switch (lang_.shaderLanguage) { case HLSL_D3D11: @@ -249,18 +287,9 @@ void ShaderWriter::BeginVSMain(Slice inputs, Slice uniform void ShaderWriter::BeginFSMain(Slice uniforms, Slice varyings) { _assert_(this->stage_ == ShaderStage::Fragment); + DeclareUniforms(uniforms); switch (lang_.shaderLanguage) { case HLSL_D3D11: - if (!uniforms.is_empty()) { - C("cbuffer base : register(b0) {\n"); - - for (auto &uniform : uniforms) { - F(" %s %s;\n", uniform.type, uniform.name); - } - - C("};\n"); - } - if (flags_ & ShaderWriterFlags::FS_WRITE_DEPTH) { C("float gl_FragDepth;\n"); } @@ -291,13 +320,6 @@ void ShaderWriter::BeginFSMain(Slice uniforms, Slice var F("layout(location = %d) %s in %s %s; // %s\n", varying.index, varying.precision ? varying.precision : "", varying.type, varying.name, semanticNames[varying.semantic]); } C("layout(location = 0, index = 0) out vec4 fragColor0;\n"); - if (!uniforms.is_empty()) { - C("layout(std140, set = 0, binding = 0) uniform bufferVals {\n"); - for (auto &uniform : uniforms) { - F("%s %s;\n", uniform.type, uniform.name); - } - C("};\n"); - } C("\nvoid main() {\n"); break; @@ -305,9 +327,6 @@ void ShaderWriter::BeginFSMain(Slice uniforms, Slice var for (auto &varying : varyings) { F("%s %s %s %s; // %s\n", lang_.varying_fs, varying.precision ? varying.precision : "", varying.type, varying.name, semanticNames[varying.semantic]); } - for (auto &uniform : uniforms) { - F("uniform %s %s;\n", uniform.type, uniform.name); - } if (!strcmp(lang_.fragColor0, "fragColor0")) { C("out vec4 fragColor0;\n"); } diff --git a/Common/GPU/ShaderWriter.h b/Common/GPU/ShaderWriter.h index 937de6a9f2df..bb686eda3543 100644 --- a/Common/GPU/ShaderWriter.h +++ b/Common/GPU/ShaderWriter.h @@ -119,6 +119,7 @@ class ShaderWriter { // Several of the shader languages ignore samplers, beware of that. void DeclareSampler2D(const SamplerDef &def); void DeclareTexture2D(const SamplerDef &def); + void DeclareUniforms(const Slice &uniforms); const SamplerDef *GetSamplerDef(const char *name) const; void Preamble(Slice extensions); diff --git a/Common/GPU/thin3d.cpp b/Common/GPU/thin3d.cpp index 4e479e384faa..3091c12eaedd 100644 --- a/Common/GPU/thin3d.cpp +++ b/Common/GPU/thin3d.cpp @@ -4,6 +4,7 @@ #include "Common/Data/Convert/ColorConv.h" #include "Common/GPU/thin3d.h" +#include "Common/GPU/ShaderWriter.h" #include "Common/Log.h" #include "Common/System/Display.h" @@ -163,273 +164,59 @@ bool RefCountedObject::ReleaseAssertLast() { return released; } -// ================================== PIXEL/FRAGMENT SHADERS - -// The Vulkan ones can be re-used with modern GL later if desired, as they're just GLSL. - -static const std::vector fsTexCol = { - {ShaderLanguage::GLSL_1xx, - "#ifdef GL_ES\n" - "precision lowp float;\n" - "#endif\n" - "#if __VERSION__ >= 130\n" - "#define varying in\n" - "#define texture2D texture\n" - "#define gl_FragColor fragColor0\n" - "out vec4 fragColor0;\n" - "#endif\n" - "varying vec4 oColor0;\n" - "varying vec2 oTexCoord0;\n" - "uniform sampler2D Sampler0;\n" - "void main() { vec4 col = texture2D(Sampler0, oTexCoord0) * oColor0; col.rgb *= oColor0.a; gl_FragColor = col; }\n" - }, - {ShaderLanguage::HLSL_D3D11, - "struct PS_INPUT { float4 color : COLOR0; float2 uv : TEXCOORD0; };\n" - "SamplerState samp : register(s0);\n" - "Texture2D tex : register(t0);\n" - "float4 main(PS_INPUT input) : SV_Target {\n" - " float4 col = input.color * tex.Sample(samp, input.uv);\n" - " col.rgb *= input.color.a;\n" - " return col;\n" - "}\n" - }, - {ShaderLanguage::GLSL_VULKAN, - "#version 140\n" - "#extension GL_ARB_separate_shader_objects : enable\n" - "#extension GL_ARB_shading_language_420pack : enable\n" - "layout(location = 0) in vec4 oColor0;\n" - "layout(location = 1) in vec2 oTexCoord0;\n" - "layout(location = 0) out vec4 fragColor0;\n" - "layout(set = 0, binding = 1) uniform sampler2D Sampler0;\n" - "void main() { vec4 col = texture(Sampler0, oTexCoord0) * oColor0; col.rgb *= oColor0.a; fragColor0 = col; }\n" +const UniformBufferDesc vsColBufDesc { sizeof(VsColUB), { + { "WorldViewProj", 0, -1, UniformType::MATRIX4X4, 0 }, + { "TintSaturation", 4, -1, UniformType::FLOAT2, 64 }, +} }; + +static_assert(SEM_TEXCOORD0 == 3, "Semantic shader hardcoded in glsl above."); + +const UniformBufferDesc vsTexColBufDesc{ sizeof(VsTexColUB),{ + { "WorldViewProj", 0, -1, UniformType::MATRIX4X4, 0 }, + { "TintSaturation", 4, -1, UniformType::FLOAT2, 64 }, +} }; + +ShaderModule *CreateShader(DrawContext *draw, ShaderStage stage, const std::vector &sources) { + uint32_t supported = draw->GetSupportedShaderLanguages(); + for (const auto &iter : sources) { + if ((uint32_t)iter.lang & supported) { + return draw->CreateShaderModule(stage, iter.lang, (const uint8_t *)iter.src, strlen(iter.src)); + } } + return nullptr; +} + +static const InputDef g_inputs[] = { + { "vec3", "Position", Draw::SEM_POSITION }, + { "vec4", "Color0", Draw::SEM_COLOR0 }, + { "vec2", "TexCoord0", Draw::SEM_TEXCOORD0 }, }; -static const std::vector fsTexColRBSwizzle = { - {GLSL_1xx, - "#ifdef GL_ES\n" - "precision lowp float;\n" - "#endif\n" - "#if __VERSION__ >= 130\n" - "#define varying in\n" - "#define texture2D texture\n" - "#define gl_FragColor fragColor0\n" - "out vec4 fragColor0;\n" - "#endif\n" - "varying vec4 oColor0;\n" - "varying vec2 oTexCoord0;\n" - "uniform sampler2D Sampler0;\n" - "void main() { vec4 col = texture2D(Sampler0, oTexCoord0).zyxw * oColor0; col.rgb *= oColor0.a; gl_FragColor = col; }\n" - }, - {ShaderLanguage::HLSL_D3D11, - "struct PS_INPUT { float4 color : COLOR0; float2 uv : TEXCOORD0; };\n" - "SamplerState samp : register(s0);\n" - "Texture2D tex : register(t0);\n" - "float4 main(PS_INPUT input) : SV_Target {\n" - " float4 col = input.color * tex.Sample(samp, input.uv).bgra;\n" - " col.rgb *= input.color.a;\n" - " return col;\n" - "}\n" - }, - {ShaderLanguage::GLSL_VULKAN, - "#version 140\n" - "#extension GL_ARB_separate_shader_objects : enable\n" - "#extension GL_ARB_shading_language_420pack : enable\n" - "layout(location = 0) in vec4 oColor0;\n" - "layout(location = 1) in vec2 oTexCoord0;\n" - "layout(location = 0) out vec4 fragColor0\n;" - "layout(set = 0, binding = 1) uniform sampler2D Sampler0;\n" - "void main() { vec4 col = texture(Sampler0, oTexCoord0).bgra * oColor0; col.rgb *= oColor0.a; fragColor0 = col; }\n" - } +static const VaryingDef g_varyings[] = { + { "vec4", "oColor0", Draw::SEM_COLOR0, 0, "lowp" }, }; -static const std::vector fsCol = { - { GLSL_1xx, - "#ifdef GL_ES\n" - "precision lowp float;\n" - "#endif\n" - "#if __VERSION__ >= 130\n" - "#define varying in\n" - "#define gl_FragColor fragColor0\n" - "out vec4 fragColor0;\n" - "#endif\n" - "varying vec4 oColor0;\n" - "void main() { vec4 col = oColor0; col.rgb *= oColor0.a; gl_FragColor = col; }\n" - }, - { ShaderLanguage::HLSL_D3D11, - "struct PS_INPUT { float4 color : COLOR0; };\n" - "float4 main(PS_INPUT input) : SV_Target {\n" - " float4 col = input.color;\n" - " col.rgb *= input.color.a;\n" - " return col;\n" - "}\n" - }, - { ShaderLanguage::GLSL_VULKAN, - "#version 140\n" - "#extension GL_ARB_separate_shader_objects : enable\n" - "#extension GL_ARB_shading_language_420pack : enable\n" - "layout(location = 0) in vec4 oColor0;\n" - "layout(location = 0) out vec4 fragColor0;\n" - "void main() { vec4 col = oColor0; col.rgb *= oColor0.a; fragColor0 = col; }\n" - } +static const VaryingDef g_varyingsTex[] = { + { "vec4", "oColor0", Draw::SEM_COLOR0, 0, "lowp" }, + { "vec2", "oTexCoord0", Draw::SEM_TEXCOORD0, 1, "highp" }, }; -// ================================== VERTEX SHADERS - -static const std::vector vsCol = { - { GLSL_1xx, - "#if __VERSION__ >= 130\n" - "#define attribute in\n" - "#define varying out\n" - "#endif\n" - "attribute vec3 Position;\n" - "attribute vec4 Color0;\n" - "varying vec4 oColor0;\n" - - "uniform mat4 WorldViewProj;\n" - "uniform vec2 TintSaturation;\n" - "void main() {\n" - " gl_Position = WorldViewProj * vec4(Position, 1.0);\n" - " oColor0 = Color0;\n" - "}" - }, - { ShaderLanguage::HLSL_D3D11, - "struct VS_INPUT { float3 Position : POSITION; float4 Color0 : COLOR0; };\n" - "struct VS_OUTPUT { float4 Color0 : COLOR0; float4 Position : SV_Position; };\n" - "cbuffer ConstantBuffer : register(b0) {\n" - " matrix WorldViewProj;\n" - " float2 TintSaturation;\n" - "};\n" - "VS_OUTPUT main(VS_INPUT input) {\n" - " VS_OUTPUT output;\n" - " output.Position = mul(WorldViewProj, float4(input.Position, 1.0));\n" - " output.Color0 = input.Color0;\n" - " return output;\n" - "}\n" - }, - { ShaderLanguage::GLSL_VULKAN, -R"(#version 450 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_ARB_shading_language_420pack : enable -layout (std140, set = 0, binding = 0) uniform bufferVals { - mat4 WorldViewProj; - vec2 TintSaturation; -} myBufferVals; -layout (location = 0) in vec4 pos; -layout (location = 1) in vec4 inColor; -layout (location = 0) out vec4 outColor; -out gl_PerVertex { vec4 gl_Position; }; -void main() { - outColor = inColor; - gl_Position = myBufferVals.WorldViewProj * pos; -} -)" - } +static const SamplerDef g_samplers[] = { + { 0, "tex" }, }; -const UniformBufferDesc vsColBufDesc { sizeof(VsColUB), { - { "WorldViewProj", 0, -1, UniformType::MATRIX4X4, 0 }, - { "TintSaturation", 4, -1, UniformType::FLOAT2, 64 }, -} }; +const UniformDef g_uniforms[] = { + { "mat4", "WorldViewProj", 0 }, + { "vec2", "TintSaturation", 1 }, +}; -static const std::vector vsTexColNoTint = { { - GLSL_1xx, - R"( -#if __VERSION__ >= 130 -#define attribute in -#define varying out -#endif -attribute vec3 Position; -attribute vec4 Color0; -attribute vec2 TexCoord0; -varying vec4 oColor0; -varying vec2 oTexCoord0; -uniform mat4 WorldViewProj; -uniform vec2 TintSaturation; -void main() { - gl_Position = WorldViewProj * vec4(Position, 1.0); - oColor0 = Color0; - oTexCoord0 = TexCoord0; -})" -} }; +static ShaderModule *GenerateVShader(DrawContext *draw, bool texCoords, bool tint) { + const ShaderLanguageDesc &shaderLanguageDesc = draw->GetShaderLanguageDesc(); + char code[2048]; + ShaderWriter vsWriter(code, shaderLanguageDesc, ShaderStage::Vertex); -static const std::vector vsTexCol = { - { GLSL_1xx, - R"( -#if __VERSION__ >= 130 -#define attribute in -#define varying out -#endif -attribute vec3 Position; -attribute vec4 Color0; -attribute vec2 TexCoord0; -varying vec4 oColor0; -varying vec2 oTexCoord0; -uniform mat4 WorldViewProj; -uniform vec2 TintSaturation; -vec3 rgb2hsv(vec3 c) { - vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); - vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); - vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); - float d = q.x - min(q.w, q.y); - float e = 1.0e-10; - return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); -} -vec3 hsv2rgb(vec3 c) { - vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); - vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); - return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); -} -void main() { - gl_Position = WorldViewProj * vec4(Position, 1.0); - vec3 hsv = rgb2hsv(Color0.xyz); - hsv.x += TintSaturation.x; - hsv.y *= TintSaturation.y; - oColor0 = vec4(hsv2rgb(hsv), Color0.w); - oTexCoord0 = TexCoord0; -})", - }, - { ShaderLanguage::HLSL_D3D11, -R"( -struct VS_INPUT { float3 Position : POSITION; float2 Texcoord0 : TEXCOORD0; float4 Color0 : COLOR0; }; -struct VS_OUTPUT { float4 Color0 : COLOR0; float2 Texcoord0 : TEXCOORD0; float4 Position : SV_Position; }; -cbuffer ConstantBuffer : register(b0) { - matrix WorldViewProj; - float2 TintSaturation; -}; -float3 rgb2hsv(float3 c) { - float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); - float4 p = lerp(float4(c.bg, K.wz), float4(c.gb, K.xy), step(c.b, c.g)); - float4 q = lerp(float4(p.xyw, c.r), float4(c.r, p.yzx), step(p.x, c.r)); - float d = q.x - min(q.w, q.y); - float e = 1.0e-10; - return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); -} -float3 hsv2rgb(float3 c) { - float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); - float3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www); - return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y); -} -VS_OUTPUT main(VS_INPUT input) { - VS_OUTPUT output; - float3 hsv = rgb2hsv(input.Color0.xyz); - hsv.x += TintSaturation.x; - hsv.y *= TintSaturation.y; - output.Color0 = float4(hsv2rgb(hsv), input.Color0.w); - output.Position = mul(WorldViewProj, float4(input.Position, 1.0)); - output.Texcoord0 = input.Texcoord0; - return output; -} -)" - }, - { ShaderLanguage::GLSL_VULKAN, - R"(#version 450 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_ARB_shading_language_420pack : enable -layout (std140, set = 0, binding = 0) uniform bufferVals { - mat4 WorldViewProj; - vec2 TintSaturation; -} myBufferVals; + if (tint) { + vsWriter.C(R"( vec3 rgb2hsv(vec3 c) { vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); @@ -443,52 +230,62 @@ vec3 hsv2rgb(vec3 c) { vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); } -layout (location = 0) in vec4 pos; -layout (location = 1) in vec4 inColor; -layout (location = 3) in vec2 inTexCoord; -layout (location = 0) out vec4 outColor; -layout (location = 1) out vec2 outTexCoord; -out gl_PerVertex { vec4 gl_Position; }; -void main() { - vec3 hsv = rgb2hsv(inColor.xyz); - hsv.x += myBufferVals.TintSaturation.x; - hsv.y *= myBufferVals.TintSaturation.y; - outColor = vec4(hsv2rgb(hsv), inColor.w); - outTexCoord = inTexCoord; - gl_Position = myBufferVals.WorldViewProj * pos; -} -)" -} }; - -static_assert(SEM_TEXCOORD0 == 3, "Semantic shader hardcoded in glsl above."); +)"); + } -const UniformBufferDesc vsTexColBufDesc{ sizeof(VsTexColUB),{ - { "WorldViewProj", 0, -1, UniformType::MATRIX4X4, 0 }, - { "TintSaturation", 4, -1, UniformType::FLOAT2, 64 }, -} }; + vsWriter.BeginVSMain(g_inputs, g_uniforms, texCoords ? Slice(g_varyingsTex) : Slice(g_varyings)); + vsWriter.C("gl_Position = mul(WorldViewProj, vec4(Position, 1.0));\n"); + if (tint) { + vsWriter.C(R"( + vec3 hsv = rgb2hsv(Color0.xyz); + hsv.x += TintSaturation.x; + hsv.y *= TintSaturation.y; + oColor0 = vec4(hsv2rgb(hsv), Color0.w); +)"); + } else { + vsWriter.C("oColor0 = Color0;\n"); + } + if (texCoords) { + vsWriter.C("oTexCoord0 = TexCoord0;\n"); + } + vsWriter.EndVSMain(texCoords ? Slice(g_varyingsTex) : Slice(g_varyings)); + return draw->CreateShaderModule(ShaderStage::Vertex, shaderLanguageDesc.shaderLanguage, (const uint8_t *)code, strlen(code)); +} -ShaderModule *CreateShader(DrawContext *draw, ShaderStage stage, const std::vector &sources) { - uint32_t supported = draw->GetSupportedShaderLanguages(); - for (const auto &iter : sources) { - if ((uint32_t)iter.lang & supported) { - return draw->CreateShaderModule(stage, iter.lang, (const uint8_t *)iter.src, strlen(iter.src)); +static ShaderModule *GenerateFShader(DrawContext *draw, bool texturing, bool rbSwizzle) { + const ShaderLanguageDesc &shaderLanguageDesc = draw->GetShaderLanguageDesc(); + char code[2048]; + ShaderWriter fsWriter(code, shaderLanguageDesc, ShaderStage::Fragment); + fsWriter.DeclareSamplers(g_samplers); + fsWriter.BeginFSMain(g_uniforms, texturing ? Slice(g_varyingsTex) : Slice(g_varyings)); + if (texturing) { + fsWriter.C("vec4 col = "); + fsWriter.SampleTexture2D("tex", "oTexCoord0"); + if (rbSwizzle) { + fsWriter.C(".zyxw * oColor0;\n"); + } else { + fsWriter.C(" * oColor0;\n"); } + } else { + fsWriter.C("vec4 col = oColor0;\n"); } - return nullptr; + fsWriter.C("col.rgb *= oColor0.a;\n"); // premultiply alpha + fsWriter.EndFSMain("col"); + return draw->CreateShaderModule(ShaderStage::Fragment, shaderLanguageDesc.shaderLanguage, (const uint8_t *)code, strlen(code)); } bool DrawContext::CreatePresets() { + bool tintSupported = true; if (bugs_.Has(Bugs::RASPBERRY_SHADER_COMP_HANG)) { - vsPresets_[VS_TEXTURE_COLOR_2D] = CreateShader(this, ShaderStage::Vertex, vsTexColNoTint); - } else { - vsPresets_[VS_TEXTURE_COLOR_2D] = CreateShader(this, ShaderStage::Vertex, vsTexCol); + tintSupported = false; } - vsPresets_[VS_COLOR_2D] = CreateShader(this, ShaderStage::Vertex, vsCol); + vsPresets_[VS_TEXTURE_COLOR_2D] = GenerateVShader(this, true, tintSupported); + vsPresets_[VS_COLOR_2D] = GenerateVShader(this, false, tintSupported); - fsPresets_[FS_TEXTURE_COLOR_2D] = CreateShader(this, ShaderStage::Fragment, fsTexCol); - fsPresets_[FS_COLOR_2D] = CreateShader(this, ShaderStage::Fragment, fsCol); - fsPresets_[FS_TEXTURE_COLOR_2D_RB_SWIZZLE] = CreateShader(this, ShaderStage::Fragment, fsTexColRBSwizzle); + fsPresets_[FS_TEXTURE_COLOR_2D] = GenerateFShader(this, true, false); + fsPresets_[FS_COLOR_2D] = GenerateFShader(this, false, false); + fsPresets_[FS_TEXTURE_COLOR_2D_RB_SWIZZLE] = GenerateFShader(this, true, true); return vsPresets_[VS_TEXTURE_COLOR_2D] && vsPresets_[VS_COLOR_2D] && fsPresets_[FS_TEXTURE_COLOR_2D] && fsPresets_[FS_COLOR_2D] && fsPresets_[FS_TEXTURE_COLOR_2D_RB_SWIZZLE]; } diff --git a/Common/Render/Text/draw_text.cpp b/Common/Render/Text/draw_text.cpp index 6b1338960f61..a20f8dedc8ad 100644 --- a/Common/Render/Text/draw_text.cpp +++ b/Common/Render/Text/draw_text.cpp @@ -10,7 +10,6 @@ #include "Common/Render/Text/draw_text.h" #include "Common/Render/Text/draw_text_win.h" #include "Common/Render/Text/draw_text_cocoa.h" -#include "Common/Render/Text/draw_text_uwp.h" #include "Common/Render/Text/draw_text_qt.h" #include "Common/Render/Text/draw_text_android.h" #include "Common/Render/Text/draw_text_sdl.h" @@ -273,10 +272,8 @@ TextDrawer *TextDrawer::Create(Draw::DrawContext *draw) { TextDrawer *drawer = nullptr; #if defined(__LIBRETRO__) // No text drawer -#elif defined(_WIN32) && !PPSSPP_PLATFORM(UWP) +#elif defined(_WIN32) && !defined(USING_QT_UI) drawer = new TextDrawerWin32(draw); -#elif PPSSPP_PLATFORM(UWP) - drawer = new TextDrawerUWP(draw); #elif PPSSPP_PLATFORM(MAC) || PPSSPP_PLATFORM(IOS) drawer = new TextDrawerCocoa(draw); #elif defined(USING_QT_UI) diff --git a/Common/Render/Text/draw_text_uwp.cpp b/Common/Render/Text/draw_text_uwp.cpp index bdef18e971ee..bc9113ae875e 100644 --- a/Common/Render/Text/draw_text_uwp.cpp +++ b/Common/Render/Text/draw_text_uwp.cpp @@ -1,5 +1,4 @@ #include "ppsspp_config.h" - #include "Common/System/Display.h" #include "Common/GPU/thin3d.h" #include "Common/Data/Hash/Hash.h" @@ -12,7 +11,8 @@ #include "Common/StringUtils.h" #include "Common/File/Path.h" -#if PPSSPP_PLATFORM(UWP) +#if defined(_WIN32) && !defined(USING_QT_UI) + #include #include @@ -70,19 +70,42 @@ class TextDrawerFontContext { }; struct TextDrawerContext { - ID2D1Bitmap1 *bitmap; - ID2D1Bitmap1 *mirror_bmp; + ID2D1Bitmap1 *bitmap = nullptr; + ID2D1Bitmap1 *mirror_bmp = nullptr; }; TextDrawerUWP::TextDrawerUWP(Draw::DrawContext *draw) : TextDrawer(draw), ctx_(nullptr) { HRESULT hr; - // It's fine to assume we are using D3D11 in UWP - ID3D11Device* d3ddevice = (ID3D11Device *)draw->GetNativeObject(Draw::NativeObject::DEVICE); - IDXGIDevice* dxgiDevice; +#if PPSSPP_PLATFORM(UWP) + // On UWP we can assume D3D11 and reuse the existing device. + ID3D11Device *d3ddevice = (ID3D11Device *)draw->GetNativeObject(Draw::NativeObject::DEVICE); + IDXGIDevice *dxgiDevice; hr = d3ddevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); if (FAILED(hr)) _assert_msg_(false, "ID3DDevice QueryInterface IDXGIDevice failed"); - +#else + // On non-UWP Win32 the draw context may use any backend (Vulkan, GL, etc.), so create + // an independent WARP (software) D3D11 device solely for D2D/DirectWrite rendering. + ID3D11Device *d3ddevice = nullptr; + D3D_FEATURE_LEVEL featureLevel; + hr = D3D11CreateDevice( + nullptr, + D3D_DRIVER_TYPE_WARP, + nullptr, + D3D11_CREATE_DEVICE_BGRA_SUPPORT, + nullptr, 0, + D3D11_SDK_VERSION, + &d3ddevice, + &featureLevel, + nullptr + ); + if (FAILED(hr)) _assert_msg_(false, "D3D11CreateDevice (WARP) for text rendering failed"); + IDXGIDevice *dxgiDevice; + hr = d3ddevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); + d3ddevice->Release(); + if (FAILED(hr)) _assert_msg_(false, "WARP D3D11Device QueryInterface IDXGIDevice failed"); +#endif + // Initialize the Direct2D Factory. D2D1_FACTORY_OPTIONS options = {}; D2D1CreateFactory( @@ -100,7 +123,6 @@ TextDrawerUWP::TextDrawerUWP(Draw::DrawContext *draw) : TextDrawer(draw), ctx_(n ); // Create D2D Device and DeviceContext. - // TODO: We have one sitting right in DX::DeviceResource, there might be a way to use that instead. hr = m_d2dFactory->CreateDevice(dxgiDevice, &m_d2dDevice); dxgiDevice->Release(); if (FAILED(hr)) _assert_msg_(false, "D2D CreateDevice failed"); @@ -118,6 +140,7 @@ TextDrawerUWP::TextDrawerUWP(Draw::DrawContext *draw) : TextDrawer(draw), ctx_(n if (FAILED(hr)) { _assert_msg_(false, "D2D RegisterFontFileLoader failed"); } + // Load our fonts. const std::vector fontFilenames = GetAllFontFilenames(); for (const auto &fname : fontFilenames) { @@ -174,7 +197,7 @@ TextDrawerUWP::TextDrawerUWP(Draw::DrawContext *draw) : TextDrawer(draw), ctx_(n } ctx_ = new TextDrawerContext(); - + D2D1_BITMAP_PROPERTIES1 properties{}; properties.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; properties.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; @@ -192,8 +215,8 @@ TextDrawerUWP::TextDrawerUWP(Draw::DrawContext *draw) : TextDrawer(draw), ctx_(n &ctx_->bitmap ); m_d2dContext->SetTarget(ctx_->bitmap); - - // Create mirror bitmap for mapping + + // Create mirror bitmap for CPU readback properties.bitmapOptions = D2D1_BITMAP_OPTIONS_CANNOT_DRAW | D2D1_BITMAP_OPTIONS_CPU_READ; m_d2dContext->CreateBitmap( D2D1::SizeU(MAX_TEXT_WIDTH, MAX_TEXT_HEIGHT), @@ -240,7 +263,7 @@ void TextDrawerUWP::SetOrCreateFont(const FontStyle &style) { } void TextDrawerUWP::MeasureStringInternal(std::string_view str, float *w, float *h) { - IDWriteTextFormat* format = nullptr; + IDWriteTextFormat *format = nullptr; auto iter = fontMap_.find(fontStyle_); if (iter != fontMap_.end()) { format = iter->second->textFmt; @@ -250,8 +273,8 @@ void TextDrawerUWP::MeasureStringInternal(std::string_view str, float *w, float std::wstring wstr = ConvertUTF8ToWString(ReplaceAll(str, "\n", "\r\n")); format->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_LEADING); - - IDWriteTextLayout* layout = nullptr; + + IDWriteTextLayout *layout = nullptr; HRESULT hr = m_dwriteFactory->CreateTextLayout( (LPWSTR)wstr.c_str(), (int)wstr.size(), @@ -342,7 +365,7 @@ bool TextDrawerUWP::DrawStringBitmap(std::vector &bitmapData, TextStrin m_d2dContext->BeginDraw(); m_d2dContext->Clear(); - m_d2dContext->DrawTextLayout(D2D1::Point2F(0.0f, 0.0f), layout, m_d2dWhiteBrush, texFormat == Draw::DataFormat::R8G8B8A8_UNORM ? D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT : D2D1_DRAW_TEXT_OPTIONS_NONE); + m_d2dContext->DrawTextLayout(D2D1::Point2F(0.0f, 0.0f), layout, m_d2dWhiteBrush, fullColor ? D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT : D2D1_DRAW_TEXT_OPTIONS_NONE); m_d2dContext->EndDraw(); layout->Release(); @@ -357,8 +380,7 @@ bool TextDrawerUWP::DrawStringBitmap(std::vector &bitmapData, TextStrin return false; } - // Convert the bitmap to a Thin3D compatible array of 16-bit pixels. Can't use a single channel format - // because we need white. Well, we could using swizzle, but not all our backends support that. + // Convert the bitmap to a Thin3D compatible array of pixels. if (texFormat == Draw::DataFormat::R8G8B8A8_UNORM || texFormat == Draw::DataFormat::B8G8R8A8_UNORM) { bitmapData.resize(entry.bmWidth * entry.bmHeight * sizeof(uint32_t)); bool swap = texFormat == Draw::DataFormat::R8G8B8A8_UNORM; @@ -418,3 +440,4 @@ void TextDrawerUWP::ClearFonts() { } #endif + diff --git a/Common/Render/Text/draw_text_uwp.h b/Common/Render/Text/draw_text_uwp.h index 6ca02de944f2..447b30ce5e55 100644 --- a/Common/Render/Text/draw_text_uwp.h +++ b/Common/Render/Text/draw_text_uwp.h @@ -5,7 +5,7 @@ #include #include "Common/Render/Text/draw_text.h" -#if PPSSPP_PLATFORM(UWP) +#if defined(_WIN32) && !defined(USING_QT_UI) #include #include @@ -32,16 +32,16 @@ class TextDrawerUWP : public TextDrawer { std::map> fontMap_; // Direct2D drawing components. - ID2D1Factory5* m_d2dFactory = nullptr; - ID2D1Device4* m_d2dDevice = nullptr; - ID2D1DeviceContext4* m_d2dContext = nullptr; - ID2D1SolidColorBrush* m_d2dWhiteBrush = nullptr; + ID2D1Factory5 *m_d2dFactory = nullptr; + ID2D1Device4 *m_d2dDevice = nullptr; + ID2D1DeviceContext4 *m_d2dContext = nullptr; + ID2D1SolidColorBrush *m_d2dWhiteBrush = nullptr; // DirectWrite drawing components. - IDWriteFactory5* m_dwriteFactory = nullptr; - IDWriteFontSet* m_fontSet = nullptr; - IDWriteFontSetBuilder1* m_fontSetBuilder = nullptr; - IDWriteFontCollection1* m_fontCollection = nullptr; + IDWriteFactory5 *m_dwriteFactory = nullptr; + IDWriteFontSet *m_fontSet = nullptr; + IDWriteFontSetBuilder1 *m_fontSetBuilder = nullptr; + IDWriteFontCollection1 *m_fontCollection = nullptr; IDWriteInMemoryFontFileLoader *m_inMemoryLoader = nullptr; std::vector> m_fontFiles; }; diff --git a/Common/Render/Text/draw_text_win.cpp b/Common/Render/Text/draw_text_win.cpp index 05bcf044bb50..dfb348c96d68 100644 --- a/Common/Render/Text/draw_text_win.cpp +++ b/Common/Render/Text/draw_text_win.cpp @@ -1,261 +1,5 @@ #include "ppsspp_config.h" -#include "Common/System/Display.h" -#include "Common/GPU/thin3d.h" -#include "Common/Data/Hash/Hash.h" -#include "Common/Data/Text/WrapText.h" -#include "Common/Data/Encoding/Utf8.h" -#include "Common/Render/Text/draw_text.h" -#include "Common/Render/Text/draw_text_win.h" - -#include "Common/Log.h" -#include "Common/StringUtils.h" - -#if defined(_WIN32) && !defined(USING_QT_UI) && !PPSSPP_PLATFORM(UWP) - -#define WIN32_LEAN_AND_MEAN -#include - -enum { - MAX_TEXT_WIDTH = 4096, - MAX_TEXT_HEIGHT = 512 -}; - -class TextDrawerFontContext { -public: - explicit TextDrawerFontContext(const FontStyle &_style, float _dpiScale) : hFont(0), style(_style), dpiScale(_dpiScale) { - FontStyleFlags styleFlags{}; - std::string fontName = GetFontNameForFontStyle(style, &styleFlags); - if (fontName.empty()) { - // Shouldn't happen. - fontName = "Tahoma"; - } - - int weight = FW_NORMAL; - if (styleFlags & FontStyleFlags::Bold) { - weight = FW_BOLD; - } - if (styleFlags & FontStyleFlags::Light) { - weight = FW_LIGHT; - } - - bool italic = (styleFlags & FontStyleFlags::Italic); - int height = style.sizePts; - - if (hFont) { - Destroy(); - } - // We apparently specify all font sizes in pts (1pt = 1.33px), so divide by only 72 for pixels. - int nHeight = -MulDiv(height, (int)(96.0f * (1.0f / dpiScale)), 72); - hFont = CreateFont(nHeight, 0, 0, 0, weight, italic, - FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, - CLIP_DEFAULT_PRECIS, PROOF_QUALITY, - VARIABLE_PITCH, ConvertUTF8ToWString(fontName).c_str()); - } - - ~TextDrawerFontContext() { - Destroy(); - } - - void Destroy() { - DeleteObject(hFont); - hFont = 0; - } - - HFONT hFont = 0; - FontStyle style; - float dpiScale; -}; - -struct TextDrawerContext { - HDC hDC; - HBITMAP hbmBitmap; - int *pBitmapBits; -}; - -TextDrawerWin32::TextDrawerWin32(Draw::DrawContext *draw) : TextDrawer(draw), ctx_(nullptr) { - ctx_ = new TextDrawerContext(); - ctx_->hDC = CreateCompatibleDC(NULL); - - // Load the font files (pass the all flags so we get all filenames); - std::vector fonts = GetAllFontFilenames(); - for (const auto &iter : fonts) { - std::string fn = "assets/" + iter + ".ttf"; - int numFontsAdded = AddFontResourceEx(ConvertUTF8ToWString(fn).c_str(), FR_PRIVATE, NULL); - if (numFontsAdded == 0) { - ERROR_LOG(Log::G3D, "Failed to add font resource from %s", fn.c_str()); - } - } - - BITMAPINFO bmi{}; - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = MAX_TEXT_WIDTH; - bmi.bmiHeader.biHeight = -MAX_TEXT_HEIGHT; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biCompression = BI_RGB; - bmi.bmiHeader.biBitCount = 32; - - ctx_->hbmBitmap = CreateDIBSection(ctx_->hDC, &bmi, DIB_RGB_COLORS, (VOID**)&ctx_->pBitmapBits, NULL, 0); - _assert_(ctx_->hbmBitmap != nullptr); - SetMapMode(ctx_->hDC, MM_TEXT); - - SelectObject(ctx_->hDC, ctx_->hbmBitmap); -} - -TextDrawerWin32::~TextDrawerWin32() { - ClearCache(); - ClearFonts(); - - // Unload the fonts. - std::vector fonts = GetAllFontFilenames(); - for (const auto &iter : fonts) { - std::string fn = "assets/" + iter + ".ttf"; - RemoveFontResourceEx(ConvertUTF8ToWString(fn).c_str(), FR_PRIVATE, NULL); - } - - DeleteObject(ctx_->hbmBitmap); - DeleteDC(ctx_->hDC); - delete ctx_; -} - -void TextDrawerWin32::SetOrCreateFont(const FontStyle &style) { - auto iter = fontMap_.find(style); - if (iter != fontMap_.end()) { - fontStyle_ = style; - return; - } - - fontMap_[style] = std::make_unique(style, dpiScale_); - fontStyle_ = style; -} - -void TextDrawerWin32::MeasureStringInternal(std::string_view str, float *w, float *h) { - auto iter = fontMap_.find(fontStyle_); - if (iter != fontMap_.end()) { - SelectObject(ctx_->hDC, iter->second->hFont); - } else { - ERROR_LOG(Log::G3D, "Failed to measure string"); - return; - } - - std::vector lines; - SplitString(str, '\n', lines); - - int extW = 0, extH = 0; - for (auto &line : lines) { - SIZE size; - std::wstring wstr = ConvertUTF8ToWString(line); - if (wstr.empty() && lines.size() > 1) { - // Measure empty lines as if it was a space. - wstr = L" "; - } - GetTextExtentPoint32(ctx_->hDC, wstr.c_str(), (int)wstr.size(), &size); - if (size.cx > extW) - extW = size.cx; - extH += size.cy; - } - - *w = extW; - *h = extH; -} - -bool TextDrawerWin32::DrawStringBitmap(std::vector &bitmapData, TextStringEntry &entry, Draw::DataFormat texFormat, std::string_view str, int align, bool fullColor) { - if (str.empty()) { - bitmapData.clear(); - return false; - } - std::wstring wstr = ConvertUTF8ToWString(ReplaceAll(str, "\n", "\r\n")); - - auto iter = fontMap_.find(fontStyle_); - if (iter != fontMap_.end()) { - SelectObject(ctx_->hDC, iter->second->hFont); - } - - // Set text properties - SetTextColor(ctx_->hDC, 0xFFFFFF); - SetBkColor(ctx_->hDC, 0); - SetTextAlign(ctx_->hDC, TA_TOP); - - // This matters for multi-line text - DT_CENTER is horizontal only. - UINT dtAlign = (align & ALIGN_HCENTER) == 0 ? DT_LEFT : DT_CENTER; - - RECT textRect = { 0 }; - DrawTextExW(ctx_->hDC, (LPWSTR)wstr.c_str(), (int)wstr.size(), &textRect, DT_NOPREFIX | DT_TOP | dtAlign | DT_CALCRECT, 0); - SIZE size; - size.cx = textRect.right; - size.cy = textRect.bottom; - - if (size.cx > MAX_TEXT_WIDTH) - size.cx = MAX_TEXT_WIDTH; - if (size.cy > MAX_TEXT_HEIGHT) - size.cy = MAX_TEXT_HEIGHT; - - if (size.cx == 0 || size.cy == 0) { - // Don't draw zero-sized textures. - WARN_LOG(Log::G3D, "Text '%.*s' caused a zero size image", (int)str.length(), str.data()); - return false; - } - - entry.texture = nullptr; - entry.width = size.cx; - entry.height = size.cy; - entry.bmWidth = (size.cx + 3) & ~3; - entry.bmHeight = (size.cy + 3) & ~3; - entry.lastUsedFrame = frameCount_; - - RECT rc = { 0 }; - rc.right = entry.bmWidth; - rc.bottom = entry.bmHeight; - FillRect(ctx_->hDC, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH)); - DrawTextExW(ctx_->hDC, (LPWSTR)wstr.c_str(), (int)wstr.size(), &rc, DT_NOPREFIX | DT_TOP | dtAlign, 0); - - // Convert the bitmap to a Thin3D compatible array of 16-bit pixels. Can't use a single channel format - // because we need white. Well, we could using swizzle, but not all our backends support that. - if (texFormat == Draw::DataFormat::R8G8B8A8_UNORM || texFormat == Draw::DataFormat::B8G8R8A8_UNORM) { - bitmapData.resize(entry.bmWidth * entry.bmHeight * sizeof(uint32_t)); - uint32_t *bitmapData32 = (uint32_t *)&bitmapData[0]; - for (int y = 0; y < entry.bmHeight; y++) { - for (int x = 0; x < entry.bmWidth; x++) { - uint8_t bAlpha = (uint8_t)(ctx_->pBitmapBits[MAX_TEXT_WIDTH * y + x] & 0xff); - bitmapData32[entry.bmWidth * y + x] = AlphaToPremul8888(bAlpha); - } - } - } else if (texFormat == Draw::DataFormat::B4G4R4A4_UNORM_PACK16 || texFormat == Draw::DataFormat::R4G4B4A4_UNORM_PACK16) { - bitmapData.resize(entry.bmWidth * entry.bmHeight * sizeof(uint16_t)); - uint16_t *bitmapData16 = (uint16_t *)&bitmapData[0]; - for (int y = 0; y < entry.bmHeight; y++) { - for (int x = 0; x < entry.bmWidth; x++) { - uint8_t bAlpha = (uint8_t)(ctx_->pBitmapBits[MAX_TEXT_WIDTH * y + x] & 0xff); - bitmapData16[entry.bmWidth * y + x] = AlphaToPremul4444(bAlpha); - } - } - } else if (texFormat == Draw::DataFormat::A4R4G4B4_UNORM_PACK16) { - bitmapData.resize(entry.bmWidth * entry.bmHeight * sizeof(uint16_t)); - uint16_t *bitmapData16 = (uint16_t *)&bitmapData[0]; - for (int y = 0; y < entry.bmHeight; y++) { - for (int x = 0; x < entry.bmWidth; x++) { - uint8_t bAlpha = (uint8_t)(ctx_->pBitmapBits[MAX_TEXT_WIDTH * y + x] & 0xff); - bitmapData16[entry.bmWidth * y + x] = AlphaToPremul4444(bAlpha); - } - } - } else if (texFormat == Draw::DataFormat::R8_UNORM) { - bitmapData.resize(entry.bmWidth * entry.bmHeight); - for (int y = 0; y < entry.bmHeight; y++) { - for (int x = 0; x < entry.bmWidth; x++) { - uint8_t bAlpha = ctx_->pBitmapBits[MAX_TEXT_WIDTH * y + x] & 0xff; - bitmapData[entry.bmWidth * y + x] = bAlpha; - } - } - } else { - _assert_msg_(false, "Bad TextDrawer format"); - } - return true; -} - -void TextDrawerWin32::ClearFonts() { - for (auto &iter : fontMap_) { - iter.second->Destroy(); - } - fontMap_.clear(); -} +#if defined(_WIN32) && !defined(USING_QT_UI) +// TextDrawerWin32 is an alias of TextDrawerUWP; implementation is in draw_text_uwp.cpp. #endif diff --git a/Common/Render/Text/draw_text_win.h b/Common/Render/Text/draw_text_win.h index 3517aca572f4..5f894d5be882 100644 --- a/Common/Render/Text/draw_text_win.h +++ b/Common/Render/Text/draw_text_win.h @@ -1,31 +1,8 @@ #pragma once -#include "ppsspp_config.h" +#include "Common/Render/Text/draw_text_uwp.h" -#include -#include "Common/Render/Text/draw_text.h" - -#if defined(_WIN32) && !defined(USING_QT_UI) && !PPSSPP_PLATFORM(UWP) - -struct TextDrawerContext; -// Internal struct but all details in .cpp file (pimpl to avoid pulling in excessive headers here) -class TextDrawerFontContext; - -class TextDrawerWin32 : public TextDrawer { -public: - TextDrawerWin32(Draw::DrawContext *draw); - ~TextDrawerWin32(); - - void SetOrCreateFont(const FontStyle &style) override; - bool DrawStringBitmap(std::vector &bitmapData, TextStringEntry &entry, Draw::DataFormat texFormat, std::string_view str, int align, bool fullColor) override; - -protected: - void MeasureStringInternal(std::string_view str, float *w, float *h) override; - bool SupportsColorEmoji() const override { return false; } - void ClearFonts() override; - - TextDrawerContext *ctx_; - std::map> fontMap_; -}; +#if defined(_WIN32) && !defined(USING_QT_UI) +using TextDrawerWin32 = TextDrawerUWP; #endif diff --git a/Common/System/Display.cpp b/Common/System/Display.cpp index 0356a1cba116..31e911f3330e 100644 --- a/Common/System/Display.cpp +++ b/Common/System/Display.cpp @@ -116,7 +116,7 @@ void DisplayProperties::Print() { rot_matrix.print(); } -Lin::Matrix4x4 ComputeOrthoMatrix(float xres, float yres, CoordConvention coordConvention) { +Lin::Matrix4x4 ComputeOrthoMatrix(float xres, float yres, CoordConvention coordConvention, bool compensateYFlip) { using namespace Lin; // TODO: Should be able to share the y-flip logic here with the one in postprocessing/presentation, for example. Matrix4x4 ortho; @@ -124,21 +124,20 @@ Lin::Matrix4x4 ComputeOrthoMatrix(float xres, float yres, CoordConvention coordC case CoordConvention::Vulkan: ortho.setOrthoD3D(0.0f, xres, 0, yres, -1.0f, 1.0f); break; - case CoordConvention::Direct3D9: - ortho.setOrthoD3D(0.0f, xres, yres, 0.0f, -1.0f, 1.0f); - Matrix4x4 translation; - // Account for the small window adjustment. - translation.setTranslation(Vec3( - -0.5f * g_display.dpi_scale_x / g_display.dpi_scale_real_x, - -0.5f * g_display.dpi_scale_y / g_display.dpi_scale_real_y, 0.0f)); - ortho = translation * ortho; - break; case CoordConvention::Direct3D11: - ortho.setOrthoD3D(0.0f, xres, yres, 0.0f, -1.0f, 1.0f); + if (compensateYFlip) { + ortho.setOrthoD3D(0.0f, xres, yres, 0.0f, -1.0f, 1.0f); + } else { + ortho.setOrthoD3D(0.0f, xres, 0, yres, -1.0f, 1.0f); + } break; case CoordConvention::OpenGL: default: - ortho.setOrthoGL(0.0f, xres, yres, 0.0f, -1.0f, 1.0f); + if (compensateYFlip) { + ortho.setOrthoGL(0.0f, xres, 0, yres, -1.0f, 1.0f); + } else { + ortho.setOrthoGL(0.0f, xres, yres, 0.0f, -1.0f, 1.0f); + } break; } // Compensate for rotated display if needed. diff --git a/Common/System/Display.h b/Common/System/Display.h index edf15c6320ad..096a378186b4 100644 --- a/Common/System/Display.h +++ b/Common/System/Display.h @@ -61,7 +61,7 @@ struct DisplayRect { void RotateRectToDisplay(DisplayRect &rect, float rtWidth, float rtHeight); void RotateRectToDisplay(DisplayRect &rect, int rtWidth, int rtHeight); -Lin::Matrix4x4 ComputeOrthoMatrix(float xres, float yres, CoordConvention coordConvention); +Lin::Matrix4x4 ComputeOrthoMatrix(float xres, float yres, CoordConvention coordConvention, bool compensateYFlip); // Take this and run through translation. Returns "Portrait", "Landscape" or later "Square" (the latter being the square shape you get when you open a foldable phone). std::string_view DeviceOrientationToString(DeviceOrientation orientation); diff --git a/Common/System/Request.h b/Common/System/Request.h index c860ad132b48..8bfeba4efa01 100644 --- a/Common/System/Request.h +++ b/Common/System/Request.h @@ -11,7 +11,7 @@ class Path; -typedef std::function RequestCallback; +typedef std::function RequestCallback; typedef std::function RequestFailedCallback; typedef int RequesterToken; diff --git a/Common/UI/PopupScreens.cpp b/Common/UI/PopupScreens.cpp index b78dc024df6a..4e059df9fe11 100644 --- a/Common/UI/PopupScreens.cpp +++ b/Common/UI/PopupScreens.cpp @@ -401,7 +401,7 @@ void PopupMultiChoice::UpdateText() { } valueText_ = std::move(text); } else { - valueText_ = ""; + valueText_.clear(); } } } @@ -793,7 +793,7 @@ void SliderFloatPopupScreen::OnCompleted(DialogResult result) { void AskForInput(ScreenManager *screenManager, RequesterToken token, UI::View *sourceView, std::string_view title, std::function callback) { // Choose method depending on platform capabilities. if (System_GetPropertyBool(SYSPROP_HAS_TEXT_INPUT_DIALOG)) { - System_InputBoxGetString(token, title, "", false, [callback](const std::string &enteredValue, int) { + System_InputBoxGetString(token, title, "", false, [callback](std::string_view enteredValue, int) { callback(SanitizeString(StripSpaces(enteredValue), StringRestriction::None, 0, 0), true); }); return; @@ -825,7 +825,7 @@ void PopupTextInputChoice::HandleClick(EventParams &e) { // Choose method depending on platform capabilities. if (System_GetPropertyBool(SYSPROP_HAS_TEXT_INPUT_DIALOG)) { - System_InputBoxGetString(token_, text_, *value_, passwordMasking_, [this](const std::string &enteredValue, int) { + System_InputBoxGetString(token_, text_, *value_, passwordMasking_, [this](std::string_view enteredValue, int) { *value_ = SanitizeString(StripSpaces(enteredValue), restriction_, minLen_, maxLen_); EventParams params{}; params.v = this; @@ -1120,7 +1120,7 @@ std::string ChoiceWithValueDisplay::ValueText(bool *shadow) const { FileChooserChoice::FileChooserChoice(RequesterToken token, std::string *value, std::string_view text, BrowseFileType fileType, LayoutParams *layoutParams) : AbstractChoiceWithValueDisplay(text, layoutParams), value_(value) { OnClick.Add([=](UI::EventParams &) { - System_BrowseForFile(token, text_, fileType, [=](const std::string &returnValue, int) { + System_BrowseForFile(token, text_, fileType, [=](std::string_view returnValue, int) { if (*value_ != returnValue) { *value = returnValue; UI::EventParams e{}; @@ -1144,7 +1144,7 @@ std::string FileChooserChoice::ValueText(bool *shadow) const { FolderChooserChoice::FolderChooserChoice(RequesterToken token, std::string *value, std::string_view text, LayoutParams *layoutParams) : AbstractChoiceWithValueDisplay(text, layoutParams), value_(value), token_(token) { OnClick.Add([=](UI::EventParams &) { - System_BrowseForFolder(token_, text_, Path(*value), [=](const std::string &returnValue, int) { + System_BrowseForFolder(token_, text_, Path(*value), [=](std::string_view returnValue, int) { if (*value_ != returnValue) { *value = returnValue; UI::EventParams e{}; diff --git a/Core/Config.cpp b/Core/Config.cpp index e7fd30d525ca..81304f6b0ad3 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -1602,7 +1602,7 @@ void Config::PostLoadCleanup() { // Remove a legacy value. if (g_Config.sCustomDriver == "Default") { - g_Config.sCustomDriver = ""; + g_Config.sCustomDriver.clear(); } // Squash unsupported screen rotations. diff --git a/Core/ConfigSettings.cpp b/Core/ConfigSettings.cpp index d0062dc447d2..97776658d2d5 100644 --- a/Core/ConfigSettings.cpp +++ b/Core/ConfigSettings.cpp @@ -322,7 +322,7 @@ bool ConfigSetting::RestoreToDefault(ConfigBlock *configBlock, bool log) const { } else if (default_.s != nullptr) { *ptr_s = default_.s; } else { - *ptr_s = ""; + ptr_s->clear(); } if (*ptr_s != origValue) { if (log) { diff --git a/Core/Dialog/PSPOskDialog.cpp b/Core/Dialog/PSPOskDialog.cpp index bdd0e86645d4..f179eb7e52c3 100755 --- a/Core/Dialog/PSPOskDialog.cpp +++ b/Core/Dialog/PSPOskDialog.cpp @@ -810,7 +810,7 @@ int PSPOskDialog::NativeKeyboard() { // There's already ConvertUCS2ToUTF8 in this file. Should we use that instead of the global ones? System_InputBoxGetString(NON_EPHEMERAL_TOKEN, ::ConvertUCS2ToUTF8(titleText), ::ConvertUCS2ToUTF8(defaultText), false, - [this](const std::string &value, int) { + [this](std::string_view value, int) { // Success callback std::lock_guard guard(nativeMutex_); if (nativeStatus_ != PSPOskNativeStatus::WAITING) { diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 17101c59969c..8189abec8853 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -1305,7 +1305,7 @@ void timeoutFriendsRecursive(SceNetAdhocctlPeerInfo * node, int32_t* count) { if (count != NULL) (*count)++; } -void sendChat(const std::string &chatString) { +void sendChat(std::string_view chatString) { SceNetAdhocctlChatPacketC2S chat{}; chat.base.opcode = OPCODE_CHAT; //TODO check network inited, check send success or not, chatlog.pushback error on failed send, pushback error on not connected @@ -1313,7 +1313,7 @@ void sendChat(const std::string &chatString) { // Send Chat to Server if (!chatString.empty()) { //maximum char allowed is 64 character for compability with original server (pro.coldbird.net) - std::string message = chatString.substr(0, 60); // 64 return chat variable corrupted is it out of memory? + std::string message(chatString.substr(0, 60)); // 64 return chat variable corrupted is it out of memory? strcpy(chat.message, message.c_str()); //Send Chat Messages if (IsSocketReady((int)metasocket, false, true) > 0) { @@ -1330,7 +1330,7 @@ void sendChat(const std::string &chatString) { std::lock_guard guard(chatLogLock); auto n = GetI18NCategory(I18NCat::NETWORKING); chatLog.push_back(std::string(n->T("You're in Offline Mode, go to lobby or online hall"))); - INFO_LOG(Log::sceNet, "Offline. Would have sent: %s", chatString.c_str()); + INFO_LOG(Log::sceNet, "Offline. Would have sent: %.*s", STR_VIEW(chatString)); chatMessageGeneration++; } } diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 657feff4d9ae..4ca28ea36061 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -883,7 +883,7 @@ void addFriend(SceNetAdhocctlConnectPacketS2C * packet); * Send chat or get that * @param std::string ChatString */ -void sendChat(const std::string &chatString); +void sendChat(std::string_view chatString); std::vector getChatLog(); int GetChatChangeID(); int GetChatMessageCount(); diff --git a/Core/Loaders.cpp b/Core/Loaders.cpp index a17ce1ec7152..ef035cf05755 100644 --- a/Core/Loaders.cpp +++ b/Core/Loaders.cpp @@ -225,7 +225,7 @@ IdentifiedFileType Identify_File(FileLoader *fileLoader, std::string *errorStrin Path filename = fileLoader->GetPath(); // There are a few elfs misnamed as pbp (like Trig Wars), accept that. Also accept extension-less paths. if (extension == ".plf" || strstr(filename.GetFilename().c_str(), "BOOT.BIN") || - extension == ".elf" || extension == ".prx" || extension == ".pbp" || extension == "") { + extension == ".elf" || extension == ".prx" || extension == ".pbp" || extension.empty()) { return IdentifiedFileType::PSP_ELF; } return IdentifiedFileType::UNKNOWN_ELF; diff --git a/UI/AdhocServerScreen.cpp b/UI/AdhocServerScreen.cpp index 6132d4d8a96c..932442313175 100644 --- a/UI/AdhocServerScreen.cpp +++ b/UI/AdhocServerScreen.cpp @@ -861,7 +861,7 @@ void AskToEditCurrentServer(int requestToken, ScreenManager *screenManager) { // Choose method depending on platform capabilities. if (System_GetPropertyBool(SYSPROP_HAS_TEXT_INPUT_DIALOG)) { - System_InputBoxGetString(requestToken, n->T("Ad hoc server address"), g_Config.sProAdhocServer, false, [](const std::string &enteredValue, int) { + System_InputBoxGetString(requestToken, n->T("Ad hoc server address"), g_Config.sProAdhocServer, false, [](std::string_view enteredValue, int) { EditServerName(enteredValue); }); return; diff --git a/UI/ChatScreen.cpp b/UI/ChatScreen.cpp index 6b086ed561c4..ba7ccc0be27d 100644 --- a/UI/ChatScreen.cpp +++ b/UI/ChatScreen.cpp @@ -114,7 +114,7 @@ void ChatMenu::OnAskForChatMessage(UI::EventParams &e) { using namespace UI; if (System_GetPropertyBool(SYSPROP_HAS_TEXT_INPUT_DIALOG)) { - System_InputBoxGetString(token_, n->T("Chat"), "", false, [](const std::string &value, int) { + System_InputBoxGetString(token_, n->T("Chat"), "", false, [](std::string_view value, int) { sendChat(value); }); } else { @@ -183,7 +183,7 @@ void ChatMenu::Update() { // Could remove the fullscreen check here, it works now. auto n = GetI18NCategory(I18NCat::NETWORKING); if (promptInput_ && g_Config.bBypassOSKWithKeyboard && !g_Config.bFullScreen) { - System_InputBoxGetString(token_, n->T("Chat"), n->T("Chat Here"), false, [](const std::string &value, int) { + System_InputBoxGetString(token_, n->T("Chat"), n->T("Chat Here"), false, [](std::string_view value, int) { sendChat(value); }); promptInput_ = false; diff --git a/UI/CwCheatScreen.cpp b/UI/CwCheatScreen.cpp index 73d83e184155..3bf8234b4169 100644 --- a/UI/CwCheatScreen.cpp +++ b/UI/CwCheatScreen.cpp @@ -437,7 +437,7 @@ void CwCheatScreen::ImportAndReport(const Path &cheatFile) { } void CwCheatScreen::OnImportBrowse(UI::EventParams ¶ms) { - System_BrowseForFile(GetRequesterToken(), "Open cheat DB file", BrowseFileType::DB, [&](const std::string &value, int) { + System_BrowseForFile(GetRequesterToken(), "Open cheat DB file", BrowseFileType::DB, [this](std::string_view value, int) { if (value.empty()) { return; } diff --git a/UI/DeveloperToolsScreen.cpp b/UI/DeveloperToolsScreen.cpp index ebcc716741dd..15118232e828 100644 --- a/UI/DeveloperToolsScreen.cpp +++ b/UI/DeveloperToolsScreen.cpp @@ -758,8 +758,8 @@ void DeveloperToolsScreen::OnMIPSTracerPathChanged(UI::EventParams &e) { dev->T("Select the log file"), "trace.txt", BrowseFileType::ANY, - [this](const std::string &value, int) { - mipsTracer.set_logging_path(value); + [this](std::string_view value, int) { + mipsTracer.set_logging_path(std::string(value)); MIPSTracerPath_ = value; MIPSTracerPath->SetRightText(MIPSTracerPath_); } diff --git a/UI/DriverManagerScreen.cpp b/UI/DriverManagerScreen.cpp index 7cb3c49bbcfa..11355b467601 100644 --- a/UI/DriverManagerScreen.cpp +++ b/UI/DriverManagerScreen.cpp @@ -215,14 +215,14 @@ void DriverManagerScreen::OnCustomDriverUninstall(UI::EventParams &e) { void DriverManagerScreen::OnCustomDriverInstall(UI::EventParams &e) { auto gr = GetI18NCategory(I18NCat::GRAPHICS); - System_BrowseForFile(GetRequesterToken(), gr->T("Install custom driver..."), BrowseFileType::ZIP, [this](const std::string &value, int) { + System_BrowseForFile(GetRequesterToken(), gr->T("Install custom driver..."), BrowseFileType::ZIP, [this](std::string_view value, int) { if (value.empty()) { return; } auto gr = GetI18NCategory(I18NCat::GRAPHICS); - Path zipPath = Path(value); + Path zipPath(value); // Don't bother checking the file extension. Can't always do that with files from Download (they have paths like content://com.android.providers.downloads.documents/document/msf%3A1000001095). // Though, it may be possible to get it in other ways. diff --git a/UI/GameBrowser.cpp b/UI/GameBrowser.cpp index 430fd8afe1d0..a74bfc5033ed 100644 --- a/UI/GameBrowser.cpp +++ b/UI/GameBrowser.cpp @@ -578,7 +578,7 @@ void GameBrowser::LastClick(UI::EventParams &e) { void GameBrowser::BrowseClick(UI::EventParams &e) { auto mm = GetI18NCategory(I18NCat::MAINMENU); - System_BrowseForFolder(token_, mm->T("Choose folder"), path_.GetPath(), [this](const std::string &filename, int) { + System_BrowseForFolder(token_, mm->T("Choose folder"), path_.GetPath(), [this](std::string_view filename, int) { SetPath(Path(filename)); }); } @@ -783,7 +783,7 @@ void GameBrowser::Refresh() { if (System_GetPropertyInt(SYSPROP_DEVICE_TYPE) == DEVICE_TYPE_TV) { topBar->Add(new Choice(mm->T("Enter Path"), new LayoutParams(WRAP_CONTENT, 64.0f)))->OnClick.Add([=](UI::EventParams &) { auto mm = GetI18NCategory(I18NCat::MAINMENU); - System_InputBoxGetString(token_, mm->T("Enter Path"), path_.GetPath().ToString(), false, [=](const char *responseString, int responseValue) { + System_InputBoxGetString(token_, mm->T("Enter Path"), path_.GetPath().ToString(), false, [=](std::string_view responseString, int responseValue) { this->SetPath(Path(responseString)); }); }); diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 1d1891a169b5..60687ad9dde7 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -105,8 +105,8 @@ extern AndroidAudioState *g_audioState; void SetMemStickDirDarwin(int requesterToken) { auto initialPath = g_Config.memStickDirectory; INFO_LOG(Log::System, "Current path: %s", initialPath.c_str()); - System_BrowseForFolder(requesterToken, "", initialPath, [](const std::string &value, int) { - INFO_LOG(Log::System, "Selected path: %s", value.c_str()); + System_BrowseForFolder(requesterToken, "", initialPath, [](std::string_view value, int) { + INFO_LOG(Log::System, "Selected path: %.*s", STR_VIEW(value)); DarwinFileSystemServices::setUserPreferredMemoryStickDirectory(Path(value)); }); } @@ -1628,7 +1628,7 @@ void GameSettingsScreen::OnChangeBackground(UI::EventParams &e) { } auto sy = GetI18NCategory(I18NCat::SYSTEM); - System_BrowseForImage(GetRequesterToken(), sy->T("Set UI background..."), bgJpg, [=](const std::string &value, int converted) { + System_BrowseForImage(GetRequesterToken(), sy->T("Set UI background..."), bgJpg, [this](std::string_view value, int converted) { if (converted == 1) { // The platform code converted and saved the file to the desired path already. INFO_LOG(Log::UI, "Converted file."); @@ -1656,14 +1656,14 @@ void GameSettingsScreen::OnChangeBackground(UI::EventParams &e) { } if (!filename.empty()) { - Path src(value); Path dest = GetSysDirectory(DIRECTORY_SYSTEM) / filename; - File::Copy(src, dest); - if (src.FilePathContainsNoCase("temp_import.jpg")) { - INFO_LOG(Log::UI, "Deleting temp file: %s", GetFriendlyPath(src).c_str()); - File::Delete(src); + File::Copy(path, dest); + if (path.FilePathContainsNoCase("temp_import.jpg")) { + INFO_LOG(Log::UI, "Deleting temp file: %s", GetFriendlyPath(path).c_str()); + File::Delete(path); } } else { + auto sy = GetI18NCategory(I18NCat::SYSTEM); g_OSD.Show(OSDType::MESSAGE_ERROR, sy->T("Only JPG and PNG images are supported"), path.GetFilename(), 5.0); } } diff --git a/UI/IAPScreen.cpp b/UI/IAPScreen.cpp index b0ce6faf4878..ba2096f06844 100644 --- a/UI/IAPScreen.cpp +++ b/UI/IAPScreen.cpp @@ -62,7 +62,7 @@ void IAPScreen::CreateSettingsViews(UI::ViewGroup *rightColumnItems) { buyButton->OnClick.Add([this, requesterToken](UI::EventParams &) { INFO_LOG(Log::System, "Showing purchase UI..."); if (useIAP_) { - System_IAPMakePurchase(requesterToken, "org.ppsspp.gold", [this](const char *responseString, int intValue) { + System_IAPMakePurchase(requesterToken, "org.ppsspp.gold", [this](std::string_view responseString, int intValue) { INFO_LOG(Log::System, "PPSSPP Gold purchase successful!"); auto di = GetI18NCategory(I18NCat::DIALOG); g_OSD.Show(OSDType::MESSAGE_SUCCESS, di->T("GoldThankYou", "Thank you for supporting the PPSSPP project!"), 3.0f); @@ -90,7 +90,7 @@ void IAPScreen::CreateSettingsViews(UI::ViewGroup *rightColumnItems) { restorePurchases->OnClick.Add([this, requesterToken, restorePurchases](UI::EventParams &) { restorePurchases->SetEnabled(false); INFO_LOG(Log::System, "Requesting purchase restore"); - System_IAPRestorePurchases(requesterToken, [this](const char *responseString, int) { + System_IAPRestorePurchases(requesterToken, [this](std::string_view responseString, int) { INFO_LOG(Log::System, "Successfully restored purchases!"); RecreateViews(); }, [](int responseValue) { diff --git a/UI/ImDebugger/ImDebugger.cpp b/UI/ImDebugger/ImDebugger.cpp index 68698d7388c1..8e8ffc073b1c 100644 --- a/UI/ImDebugger/ImDebugger.cpp +++ b/UI/ImDebugger/ImDebugger.cpp @@ -618,7 +618,7 @@ static void RecurseFileSystem(IFileSystem *fs, std::string path, RequesterToken std::string fullPath = path + "/" + file.name; int size = file.size; // save dialog - System_BrowseForFileSave(token, "Save file", file.name, BrowseFileType::ANY, [fullPath, fs, size](const char *responseString, int) { + System_BrowseForFileSave(token, "Save file", file.name, BrowseFileType::ANY, [fullPath, fs, size](std::string_view responseString, int) { int fd = fs->OpenFile(fullPath, FILEACCESS_READ); if (fd >= 0) { std::string data; @@ -1343,7 +1343,7 @@ void DrawMediaDecodersView(ImConfig &cfg, ImControl &control) { if (ctx->BufferState() == ATRAC_STATUS_ALL_DATA_LOADED) { if (ImGui::Button("Save to disk...")) { - System_BrowseForFileSave(cfg.requesterToken, "Save AT3 file", "song.at3", BrowseFileType::ATRAC3, [=](const std::string &filename, int) { + System_BrowseForFileSave(cfg.requesterToken, "Save AT3 file", "song.at3", BrowseFileType::ATRAC3, [&info](std::string_view filename, int) { if (!Memory::IsValidRange(info.buffer, info.bufferByte)) { return; } @@ -2182,7 +2182,7 @@ void ImAtracToolWindow::Draw(ImConfig &cfg) { ImGui::InputText("File", atracPath_, sizeof(atracPath_)); ImGui::SameLine(); if (ImGui::Button("Choose...")) { - System_BrowseForFile(cfg.requesterToken, "Choose AT3 file", BrowseFileType::ATRAC3, [this](const std::string &filename, int) { + System_BrowseForFile(cfg.requesterToken, "Choose AT3 file", BrowseFileType::ATRAC3, [this](std::string_view filename, int) { truncate_cpy(atracPath_, filename); Load(); }, nullptr); @@ -2205,7 +2205,7 @@ void ImAtracToolWindow::Draw(ImConfig &cfg) { if (data_.size()) { if (ImGui::Button("Dump 64 raw frames")) { std::string firstFrames = data_.substr(track_->dataByteOffset, track_->bytesPerFrame * 64); - System_BrowseForFileSave(cfg.requesterToken, "Save .at3raw", "at3.raw", BrowseFileType::ANY, [firstFrames](const std::string &filename, int) { + System_BrowseForFileSave(cfg.requesterToken, "Save .at3raw", "at3.raw", BrowseFileType::ANY, [firstFrames](std::string_view filename, int) { FILE *f = File::OpenCFile(Path(filename), "wb"); if (f) { fwrite(firstFrames.data(), 1, firstFrames.size(), f); @@ -2412,7 +2412,7 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu ImGui::Separator(); if (ImGui::MenuItem("Load .ppmap...")) { - System_BrowseForFile(reqToken_, "Load PPSSPP symbol map", BrowseFileType::SYMBOL_MAP, [&](const char *responseString, int) { + System_BrowseForFile(reqToken_, "Load PPSSPP symbol map", BrowseFileType::SYMBOL_MAP, [this](std::string_view responseString, int) { Path path(responseString); if (!g_symbolMap->LoadSymbolMap(path)) { ERROR_LOG(Log::Common, "Failed to load symbol map"); @@ -2421,7 +2421,7 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu }); } if (ImGui::MenuItem("Save .ppmap...")) { - System_BrowseForFileSave(reqToken_, "Save PPSSPP symbol map", "symbols.ppmap", BrowseFileType::SYMBOL_MAP, [](const char *responseString, int) { + System_BrowseForFileSave(reqToken_, "Save PPSSPP symbol map", "symbols.ppmap", BrowseFileType::SYMBOL_MAP, [](std::string_view responseString, int) { Path path(responseString); if (!g_symbolMap->SaveSymbolMap(path)) { ERROR_LOG(Log::Common, "Failed to save symbol map"); @@ -2429,7 +2429,7 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu }); } if (ImGui::MenuItem("Load No$ .sym...")) { - System_BrowseForFile(reqToken_, "Load No$ symbol map", BrowseFileType::SYMBOL_MAP, [&](const char *responseString, int) { + System_BrowseForFile(reqToken_, "Load No$ symbol map", BrowseFileType::SYMBOL_MAP, [this](std::string_view responseString, int) { Path path(responseString); if (!g_symbolMap->LoadNocashSym(path)) { ERROR_LOG(Log::Common, "Failed to load No$ symbol map"); @@ -2438,7 +2438,7 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu }); } if (ImGui::MenuItem("Save No$ .sym...")) { - System_BrowseForFileSave(reqToken_, "Save No$ symbol map", "symbols.sym", BrowseFileType::SYMBOL_MAP, [](const char *responseString, int) { + System_BrowseForFileSave(reqToken_, "Save No$ symbol map", "symbols.sym", BrowseFileType::SYMBOL_MAP, [](std::string_view responseString, int) { Path path(responseString); if (!g_symbolMap->SaveNocashSym(path)) { ERROR_LOG(Log::Common, "Failed to save No$ symbol map"); diff --git a/UI/ImDebugger/ImStructViewer.cpp b/UI/ImDebugger/ImStructViewer.cpp index 1d605dd87f30..9cb88e92fb88 100644 --- a/UI/ImDebugger/ImStructViewer.cpp +++ b/UI/ImDebugger/ImStructViewer.cpp @@ -194,7 +194,7 @@ void ImStructViewer::WatchForm::Clear() { memset(name, 0, sizeof(name)); memset(expression, 0, sizeof(expression)); dynamic = false; - error = ""; + error.clear(); typeFilter.Clear(); // Not clearing the actual selected type on purpose here, user will have to reselect one anyway and // maybe there is a chance they will reuse the current one @@ -213,7 +213,7 @@ void ImStructViewer::WatchForm::SetFrom(const std::unordered_mapT("Search term"), searchFilter_, false, [&](const std::string &value, int) { + System_InputBoxGetString(GetRequesterToken(), se->T("Search term"), searchFilter_, false, [this](std::string_view value, int) { searchFilter_ = StripSpaces(value); searchChanged_ = true; }); @@ -597,7 +597,7 @@ void MainScreen::update() { void MainScreen::OnLoadFile(UI::EventParams &e) { if (System_GetPropertyBool(SYSPROP_HAS_FILE_BROWSER)) { auto mm = GetI18NCategory(I18NCat::MAINMENU); - System_BrowseForFile(GetRequesterToken(), mm->T("Load"), BrowseFileType::BOOTABLE, [](const std::string &value, int) { + System_BrowseForFile(GetRequesterToken(), mm->T("Load"), BrowseFileType::BOOTABLE, [](std::string_view value, int) { System_PostUIMessage(UIMessage::REQUEST_GAME_BOOT, value); }); } @@ -836,7 +836,7 @@ void UmdReplaceScreen::CreateViews() { if (System_GetPropertyBool(SYSPROP_HAS_FILE_BROWSER)) { rightColumnItems->Add(new Choice(mm->T("Load", "Load...")))->OnClick.Add([&](UI::EventParams &e) { auto mm = GetI18NCategory(I18NCat::MAINMENU); - System_BrowseForFile(GetRequesterToken(), mm->T("Load"), BrowseFileType::BOOTABLE, [this](const std::string &value, int) { + System_BrowseForFile(GetRequesterToken(), mm->T("Load"), BrowseFileType::BOOTABLE, [this](std::string_view value, int) { __UmdReplace(Path(value)); TriggerFinish(DR_OK); }); diff --git a/UI/MemStickScreen.cpp b/UI/MemStickScreen.cpp index 7d77604e492c..f794fe4cc673 100644 --- a/UI/MemStickScreen.cpp +++ b/UI/MemStickScreen.cpp @@ -307,11 +307,11 @@ void MemStickScreen::SetFolderManually(UI::EventParams ¶ms) { // The old way, from before scoped storage. Write in the full path. #if PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(SWITCH) auto sy = GetI18NCategory(I18NCat::SYSTEM); - System_InputBoxGetString(GetRequesterToken(), sy->T("Memory Stick Folder"), g_Config.memStickDirectory.ToString(), false, [&](const std::string &value, int) { + System_InputBoxGetString(GetRequesterToken(), sy->T("Memory Stick Folder"), g_Config.memStickDirectory.ToString(), false, [this](std::string_view value, int) { auto sy = GetI18NCategory(I18NCat::SYSTEM); auto di = GetI18NCategory(I18NCat::DIALOG); - std::string newPath = value; + std::string newPath(value); size_t pos = newPath.find_last_not_of('/'); // Gotta have at least something but a /, and also needs to start with a /. if (newPath.empty() || pos == std::string::npos || newPath[0] != '/') { @@ -417,8 +417,8 @@ void MemStickScreen::UseStorageRoot(UI::EventParams ¶ms) { void MemStickScreen::Browse(UI::EventParams ¶ms) { auto mm = GetI18NCategory(I18NCat::MAINMENU); - System_BrowseForFolder(GetRequesterToken(), mm->T("Choose folder"), g_Config.memStickDirectory, [this](const std::string &value, int) { - Path pendingMemStickFolder = Path(value); + System_BrowseForFolder(GetRequesterToken(), mm->T("Choose folder"), g_Config.memStickDirectory, [this](std::string_view value, int) { + Path pendingMemStickFolder(value); INFO_LOG(Log::System, "Got folder: '%s' (old: %s)", pendingMemStickFolder.c_str(), g_Config.memStickDirectory.c_str()); // Browse finished. Let's pop up the confirmation dialog. if (!pendingMemStickFolder.empty() && pendingMemStickFolder == g_Config.memStickDirectory && File::IsDirectory(pendingMemStickFolder)) { diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 4a2692496078..913068a78220 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -1076,7 +1076,8 @@ void NativeFrame(GraphicsContext *graphicsContext) { g_breakpoints.Frame(); // Apply the UIContext bounds as a 2D transformation matrix. - Matrix4x4 ortho = ComputeOrthoMatrix(g_display.dp_xres, g_display.dp_yres, graphicsContext->GetDrawContext()->GetDeviceCaps().coordConvention); + // NOTE: We compensate for the Y convention in the shaders, so we can use the same matrices in all backends. + Matrix4x4 ortho = ComputeOrthoMatrix(g_display.dp_xres, g_display.dp_yres, g_draw->GetDeviceCaps().coordConvention, false); // Can be overridden by sceDisplay which may pass true for the second argument. g_frameTiming.ComputePresentMode(g_draw, false); diff --git a/UI/RetroAchievementScreens.cpp b/UI/RetroAchievementScreens.cpp index 3e6d519c039c..81e408f5b4c3 100644 --- a/UI/RetroAchievementScreens.cpp +++ b/UI/RetroAchievementScreens.cpp @@ -384,7 +384,7 @@ void RetroAchievementsSettingsScreen::CreateAccountTab(UI::ViewGroup *viewGroup) viewGroup->Add(new Choice(di->T("Log in")))->OnClick.Add([this](UI::EventParams &) -> void { auto di = GetI18NCategory(I18NCat::DIALOG); std::string title = StringFromFormat("RetroAchievements: %s", di->T_cstr("Log in")); - System_AskUsernamePassword(GetRequesterToken(), title, g_Config.sAchievementsUserName, [](const std::string &value, int) { + System_AskUsernamePassword(GetRequesterToken(), title, g_Config.sAchievementsUserName, [](std::string_view value, int) { std::vector parts; SplitString(value, '\n', parts); if (parts.size() == 2 && !parts[0].empty() && !parts[1].empty()) { diff --git a/UI/SavedataScreen.cpp b/UI/SavedataScreen.cpp index 179027120717..a59cfddfbf08 100644 --- a/UI/SavedataScreen.cpp +++ b/UI/SavedataScreen.cpp @@ -672,7 +672,7 @@ void SavedataScreen::CreateExtraButtons(UI::ViewGroup *verticalLayout, int margi void SavedataScreen::OnSearch(UI::EventParams &e) { if (System_GetPropertyBool(SYSPROP_HAS_TEXT_INPUT_DIALOG)) { auto di = GetI18NCategory(I18NCat::DIALOG); - System_InputBoxGetString(GetRequesterToken(), di->T("Filter"), searchFilter_, false, [](const std::string &value, int ivalue) { + System_InputBoxGetString(GetRequesterToken(), di->T("Filter"), searchFilter_, false, [](std::string_view value, int ivalue) { System_PostUIMessage(UIMessage::SAVEDATA_SEARCH, value); }); } diff --git a/UWP/XAudioSoundStream.cpp b/UWP/XAudioSoundStream.cpp index 8852ab3af80b..c2d7eacb4040 100644 --- a/UWP/XAudioSoundStream.cpp +++ b/UWP/XAudioSoundStream.cpp @@ -92,6 +92,7 @@ void XAudioBackend::Stop() { if (xaudioDevice) { xaudioDevice->Release(); xaudioDevice = nullptr; + sourceVoice_ = nullptr; } } diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index 67cca5487f61..0c684163d015 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -352,7 +352,7 @@ namespace MainWindow { DrawMenuBar(hWnd); } - void BrowseAndBootDone(std::string filename); + void BrowseAndBootDone(std::string_view filename); void BrowseAndBoot(RequesterToken token, std::string defaultPath, bool browseDirectory) { bool browsePauseAfter = false; @@ -366,28 +366,29 @@ namespace MainWindow { W32Util::MakeTopMost(GetHWND(), false); if (browseDirectory) { - System_BrowseForFolder(token, mm->T("Load"), Path(), [](const std::string &value, int) { + System_BrowseForFolder(token, mm->T("Load"), Path(), [](std::string_view value, int) { BrowseAndBootDone(value); }); } else { - System_BrowseForFile(token, mm->T("Load"), BrowseFileType::BOOTABLE, [](const std::string &value, int) { + System_BrowseForFile(token, mm->T("Load"), BrowseFileType::BOOTABLE, [](std::string_view value, int) { BrowseAndBootDone(value); }); } } - void BrowseAndBootDone(std::string filename) { + void BrowseAndBootDone(std::string_view filename) { if (GetUIState() == UISTATE_INGAME || GetUIState() == UISTATE_EXCEPTION || GetUIState() == UISTATE_PAUSEMENU) { Core_Resume(); } - filename = ReplaceAll(filename, "\\", "/"); - System_PostUIMessage(UIMessage::REQUEST_GAME_BOOT, filename); + std::string fileStr(filename); + fileStr = ReplaceAll(fileStr, "\\", "/"); + System_PostUIMessage(UIMessage::REQUEST_GAME_BOOT, fileStr); W32Util::MakeTopMost(GetHWND(), g_Config.bTopMost); } static void UmdSwitchAction(RequesterToken token) { auto mm = GetI18NCategory(I18NCat::MAINMENU); - System_BrowseForFile(token, mm->T("Switch UMD"), BrowseFileType::BOOTABLE, [](const std::string &value, int) { + System_BrowseForFile(token, mm->T("Switch UMD"), BrowseFileType::BOOTABLE, [](std::string_view value, int) { // This is safe because the callback runs on the emu thread. __UmdReplace(Path(value)); }); diff --git a/Windows/PPSSPP.vcxproj b/Windows/PPSSPP.vcxproj index 3f62b6e38319..18c8d5d8d7a5 100644 --- a/Windows/PPSSPP.vcxproj +++ b/Windows/PPSSPP.vcxproj @@ -1,4 +1,4 @@ - + @@ -194,7 +194,7 @@ stdcpp17 - avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) ../ffmpeg/Windows/x86/lib true Windows @@ -233,7 +233,7 @@ stdcpp17 - avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) ../ffmpeg/Windows/x86_64/lib true $(OutDir)$(ProjectName).pdb @@ -267,7 +267,7 @@ stdcpp17 - avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies) ../ffmpeg/Windows/aarch64/lib true $(OutDir)$(ProjectName).pdb @@ -303,7 +303,7 @@ stdcpp17 - avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) ../ffmpeg/Windows/x86/lib;%(AdditionalLibraryDirectories) $(OutDir)$(TargetName)$(TargetExt) true @@ -351,7 +351,7 @@ stdcpp17 - avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) ../ffmpeg/Windows/x86_64/lib;%(AdditionalLibraryDirectories) true Windows @@ -393,7 +393,7 @@ stdcpp17 - avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;avrt.lib;mmdevapi.lib;wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;setupapi.lib;hid.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies) ../ffmpeg/Windows/aarch64/lib;%(AdditionalLibraryDirectories) true Windows diff --git a/assets/lang/az_AZ.ini b/assets/lang/az_AZ.ini index e922ae9ea3ac..32d733ca71d2 100644 --- a/assets/lang/az_AZ.ini +++ b/assets/lang/az_AZ.ini @@ -61,7 +61,7 @@ This game has no achievements = Bu oyunun uğurları yoxdur Top players = Ən üst oyunçular Unlocked = Açılmış uğurlar Unofficial = Rəsmi olmayan uğurlar -Unofficial achievements = Rəsmi olmayan nailiyyətlər # AI translated +Unofficial achievements = Rəsmi olmayan uğurlar Unsupported = Dəstəklənməyən uğurlar Win = Qalib gəlmək @@ -85,12 +85,12 @@ Microphone = Mikrofon Microphone Device = Mikrofon qurğusu Mix audio with other apps = Səsi başqa uyğulamalarla qarışdır Mute = Səssiz -Playback mode = İzleme rejimi +Playback mode = Oynatma durumu Respect silent mode = Sakit moda üstünlük ver Reverb volume = Yanxı ucalığı Smooth (reduces artifacts) = Sərt (artifaktları azaldır) -UI sound = AY səsi -UI volume = AY ucalığı +UI sound = İA səsi +UI volume = İA ucalığı Use new audio devices automatically = Yeni səs qurğularını özbaşına işlət [Controls] @@ -98,9 +98,9 @@ Analog Binding = Analoq Qoşması Analog Limiter = Analoq qısıtlayıcı Analog Settings = Analoq Quruluşları Analog Stick = Analoq Çubuğu -Analog stick threshold = Analog nasos səthi # AI translated +Analog stick threshold = Analoq çubuğu eşiyi Analog Style = Analoq Biçimi -Analog to digital mapping = Analoqdan rəqəmsala keçid # AI translated +Analog to digital mapping = Analoqun sayılıya xəritələnişi Analog trigger threshold = Analoq tətik eşiyi AnalogLimiter Tip = Analoq qısıtlayıcısı düyməsi basıdlığında Auto = Özbaşına @@ -119,7 +119,7 @@ Circular deadzone = Dairəvi ölü bölgə Circular stick input = Dairəvi çubuq girişi Classic = Klassik Confine Mouse = Siçanı pəncərə/görüntü içində tut -Control input sources = Daxil etmə mənbələrinə nəzarət # AI translated +Control input sources = Giriliş qaynaqlarını yönəlt Control mapping = Yönəltmə xəritələnişi Custom touch button setup = Özəl toxunuşlu düymə quruluşu Customize = Özəlləşdir # Customize Touch Controls = Toxunuşlu yönəltmə düzənini düzəlt... @@ -134,8 +134,8 @@ Enable analog stick gesture = Analoq çubuğunun hərəkətini aç Enable gesture control = Hərəkət yönəltməsini aç Enable standard shortcut keys = Standart qısayol düymələrini aç frames = kadrlar -Game controller connected = Oyun kontrol cihazı bağlandı # AI translated -Game controller disconnected = Oyun kontrolleri əlaqəsi kəsildi # AI translated +Game controller connected = Oyun yönləndiricisi taxıldı +Game controller disconnected = Oyun yönləndiricisi çıxarıldı Gesture = Hərəkət Gesture mapping = Hərəkət xəritələnişi Glowing borders = Parlayan qıraqlar @@ -176,11 +176,11 @@ Sensitivity = Həssaslıq Shape = Forma Sticky D-Pad = Yapışqan D-Pad Swipe = Sürüşdürmə -Swipe sensitivity = Sürüşdürmə həssaslığı +Swipe sensitivity = Sürüşdürmə duyarlılığı Swipe smoothing = Axıcı sürüşdürmə Thin borders = İncə qıraqlar -Tilt control = Tilt idarəetməsi # AI translated -Tilt control setup = Tilt control setup +Tilt control = Əyim yönəltməsi +Tilt control setup = Əyim yönəltməsi quruluşu Tilt Input Type = Əyim girişi biçimi Tilt Sensitivity along X axis = X oxu yönündə Əyim həssaslığı Tilt Sensitivity along Y axis = Y oxu yönündə Əyim həssaslığı @@ -195,14 +195,14 @@ X = X Y = Y [CwCheats] -A cheat database already exists. Downloading a new one will overwrite it. = Artıq bir fırıldaq verilənlər bazası mövcuddur. Yeni birini yükləmək onu əvəz edəcək. # AI translated -Added %1 cheats for this game = %1 kod oyuna əlavə edildi # AI translated +A cheat database already exists. Downloading a new one will overwrite it. = Bir hiylə verilən bazası artıq var. Yenisi yükləndikdə onu əvəz edəcək. +Added %1 cheats for this game = Bu oyun üçün %1 hiylə artırıldı Cheats = Hiylələr -Download cheat database = Davam et edin cheat verilənlər bazası # AI translated +Download cheat database = Hiylə verilən bazasını endir Edit Cheat File = Hiylə faylını düzəlt Import Cheats = Cheat.db'dən götür Import from %s = %s yerindən götür -No new cheats found for this game = Bu oyun üçün yeni hilelər tapılmadı # AI translated +No new cheats found for this game = Bu oyun üçün yeni hiylələr tapılmadı Refresh interval = Yeniləniş aralığı [DesktopUI] @@ -372,8 +372,8 @@ Save new textures = Yeni toxumaları qoru Shader Viewer = Kölgələyicini Göstərən Show GPO LEDs = GPO LED'lərini Göstər Show in-game developer menu = Gəliştirici Seçməsini Göstər -Show indicator when saving/loading = Saxlama/yükləmə zamanı göstəricini göstər # AI translated -Show log file in folder = Qovluqda loq faylını göstərin # AI translated +Show indicator when saving/loading = Qorunuş/yükləniş zamanı göstəricini göstər +Show log file in folder = Gündəlik faylını qovluqda göstər Slow (smooth) = Yavaş (axıcı) Stats = Durumlar System Information = Sistem bilgisi @@ -397,8 +397,8 @@ VFPU = VFPU %d ms = %d ms %d seconds = %d saniyə * PSP res = * PSP çöz -Active = Etkindir -Are you sure you want to delete %1? = Əminsiniz, %1-i silmək istəyirsiniz? # AI translated +Active = İşləkdir +Are you sure you want to delete %1? = %1-i silmək istədiyinizdən əminsiniz? Are you sure you want to delete the file? = Faylı silmək istədiyinizdən əminsiz? Are you sure you want to exit? = Çıxmaq istədiyinizdən əminsiz? Auto = Özbaşına @@ -420,8 +420,8 @@ ConnectingAP = Giriş nöqtəsinə qoşulur.\nBuyurun, gözləyin... ConnectingPleaseWait = Qoşulur.\nBuyurun, gözləyin... ConnectionName = Qoşulma adı Copied to clipboard: %1 = Kəsintiliyə köçürüldü: %1 -Copy deep link = Dərin linki kopyalayın # AI translated -Copy to clipboard = Kəsintiliyə köçürt +Copy deep link = Dərin keçidi köçür +Copy to clipboard = Kəsintiliyə köçür Corrupted Data = Korlanmış verilən Default = Varsayılan Delete = Sil @@ -455,10 +455,10 @@ GoldOverview1 = PPSSPP layihəsini dəstəkləmək üçün PPSSPP Gold alın.\n GoldOverview2 = Sizin dəstəyiniz, PPSSPP üzərində işin davam etməsinə şərait yaradır.\nÇox sağolun! GoldThankYou = PPSSPP layihəsini dəstəklədiyiniz üçün çox sağolun! Grid = Tor -Inactive = Etkin deyil +Inactive = İşlək deyil Installing... = Quraşdırılır... InternalError = İç yanlış yaşandı. -Left side = Sol tərəf # AI translated +Left side = Sol yön Links = Keçidlər Load = Yüklə Load completed = Yükləniş Tamamlandı @@ -489,7 +489,7 @@ Resize = Ölçülə Restart = Yenidən başlat Restore purchase = Alışı qaytar Retry = Bir daha yoxla -Right side = Sağ tərəf # AI translated +Right side = Sağ yön Save = Qoru Save completed = Qorunuş tamamlandı Saving = Qorunur\nBuyurun, Gözləyin... @@ -509,7 +509,7 @@ Submit = Göndər Supported = Dəstəklənir There is no data = Verilən yoxdur This change will not take effect until PPSSPP is restarted. = PPSSPP yenidən başladılmadan bu dəyişim işə düşməyəcək. -This will overwrite the existing configuration = Bu, mövcud konfiqurasiyanı üstələyəcək # AI translated +This will overwrite the existing configuration = Bu, var olan görkəmlənişi əvəzləyəcək Toggle All = Hamısını keçirt Toggle List = Sıralığı keçirt Top Center = Üst orta @@ -539,7 +539,7 @@ Error reading file = fayl oxunuşunda yanlış. Failed initializing CPU/Memory = OİB (CPU) ya da yaddaşı başlatmaq uğursuz oldu Failed to load executable: = işlənə bilənin yüklənişi uğursuz oldu: File corrupt = Fayl korlanıb -File format not supported = Fayl formatı dəstəklənmir # AI translated +File format not supported = Fayl biçiki dəstəklənmir File not found: %1 = Fayl tapılmayıb: %1 Game disc read error - ISO corrupt = Oyun diskində oxunuş yanlışı: ISO korlanıb. GenericAllStartupError = PPSSPP istənilən arxa-uclu görüntü kartı ilə başlada bilmədi. Kartınızı və başqa sürücülərinizi yüksəltməyi sınayın. @@ -582,8 +582,8 @@ ZIP file detected (Require UnRAR) = fayl sıxılıb (ZIP).\nÖncə onu geri aç ZIP file detected (Require WINRAR) = fayl sıxılıb (ZIP).\nÖncə onu geri açın (WinRAR ilə yoxlayın). [Game] -Are you sure you want to create a game-specific config? = Oyun spesifik konfiqurasiya yaratmaq istədiyinizə əminsiniz? # AI translated -Are you sure you want to reset the played time counter? = Əminsinizmi, oynanılan vaxt sayğacını sıfırlamaq istəyirsiniz? # AI translated +Are you sure you want to create a game-specific config? = Oyuna-özəl görkəmləniş yaratmaq istədiyinizdən əminsiniz? +Are you sure you want to reset the played time counter? = Oynanılmış vaxt sayğacını sıfırlamaq istədiyinizdən əminsiniz? Asia = Asiya Calculate CRC = CRC'ni hesabla Click "Calculate CRC" to verify ISO = ISO'nu doğrulamaq üçün "CRC'ni Hesabla"ya tıkla @@ -614,7 +614,7 @@ Setting Background = Arxafon quruluşu Time Played: %1h %2m %3s = Oynanış vaxtı: %1h %2m %3s Uncompressed = Sıxışdırılmamış USA = ABŞ -Use background as UI background = AY arxafonunu işlət +Use background as UI background = İA arxafonunu işlət [Graphics] % of the void = % boşluq @@ -717,7 +717,7 @@ Lazy texture caching Tip = Sürətlidir, ancaq bir sıra oyunda yazı sıxıntı Lens flare occlusion = Linza parlaması tıxanıqlığı Linear = Düz xəttli Low = Aşağı -Low latency display = Low latency display +Low latency display = Alçaq gecikməli ekran LowCurves = Spline/Bezier əyrisi keyfiyyəti LowCurves Tip = Ancaq bir sıra oyunda işlənir. Əyrilərin axışqanlığını yönəldir Lower resolution for effects = Effektlər üçün aşağı çözünürlük @@ -730,11 +730,11 @@ Native device resolution = Qurğunun doğma çözünürlüyü Nearest = Ən yaxın No = Yoxdur No buffer = Ara yaddaşsız -PSP display rotation = PSP ekran döndərilməsi # AI translated +PSP display rotation = PSP ekran döndərilişi Reduces artifacts = Artifaktları azaldır Render all frames = Bütün kadrları işlət Request 60 Hz = Request 60 Hz -Rotate controls = İdarələri döndər # AI translated +Rotate controls = Yönəltmələri döndər Same as Rendering resolution = İşlənişli çözünürlük kimi Show Battery % = Batareya % göstər Show Speed = Sürəti göstər @@ -751,8 +751,8 @@ Postprocessing shaders = İşləm sonrası kölgələndirmələr Recreate Activity = Etkinliyi yenidən yarat Render duplicate frames to 60hz = Kopyalanmış kadrları 60 Hz'yə işlət RenderDuplicateFrames Tip = Aşağı kadr tezliyi olan oyunların tezliyini daha axıcı edə bilir -Rendering Mode = İşləniş modu -Rendering Resolution = İşləniş çözünürlüyü +Rendering Mode = İşləniş Durumu +Rendering Resolution = İşləniş Çözünürlüyü RenderingMode NonBuffered Tip = Sürətlidir, ancaq bir sıra oyunda heç nə çizməyə bilər Rotation = Döndərmə Safe = Güvənli @@ -794,11 +794,11 @@ Import savedata from ZIP file = Qorunuş verilənini ZIP fayldan götür Install = Quraşdır Install game from ZIP file? = Oyun ZIP fayldan quraşdırılsın? Install into folder = Qovluqda quraşdır -Install plugin from ZIP file? = ZIP faylından plagin quraşdırın? # AI translated +Install plugin from ZIP file? = Qoşma ZIP faylından quraşdırılsın? Install textures from ZIP file? = Toxumalar ZIP fayldan quraşdırılsın? Installation failed = Quraşdırma uğursuz oldu Installed! = Quraşdırıldı! -Supported games: = Dəstəklənən oyunlar: # AI translated +Supported games: = Dəstəklənən oyunlar: Texture pack doesn't support install = Toxuma bağlaması quraşdırmanı dəstəkləmir Zip archive corrupt = ZIP arxivi korlanıb ZIP file = ZIP faylı @@ -868,8 +868,8 @@ Analog limiter = Analoq qısıtlayıcısı Analog speed = Analoq sürəti Analog Stick = Analoq çubuğu Audio/Video Recording = Səs/Görüntü yazılışı -Axis swap (hold) = Oxların dəyişimi (saxla) # AI translated -Axis swap (toggle) = Oxların dəyişimi (keçid) # AI translated +Axis swap (hold) = Oxların dəyişimi (saxla) +Axis swap (toggle) = Oxların dəyişimi (keçid) Circle = Dairə Cross = Xaç Custom %d = Özəl %d @@ -936,7 +936,7 @@ Toggle Debugger = Yolaqoyuş keçidi Toggle Fullscreen = Bütün Ekran keçidi Toggle mode = Mod keçiricisi Toggle mouse input = Siçan girişi keçidi -Toggle tilt control = Toggle tilt control +Toggle tilt control = Əyim yönəl. keçidi Toggle touch controls = Toxunuşlu yönl. keçidi Toggle WLAN = WLAN keçidi Triangle = Üçbucaq @@ -947,8 +947,8 @@ Vol - = Ucalıq - Wlan = WLAN [MemStick] -Already contains PSP data = PSP veriləni artıq var -Cancelled - try again = İmtina olunub - bir daha sına +Already contains PSP data = PSP verilənini artıq daşıyır +Cancelled - try again = Vaz keçilib - bir daha sınayın Checking... = Yoxlanır... Create or Choose a PSP folder = PSP qovluğu Yarat ya da Seç Current = İndiki @@ -963,7 +963,7 @@ Failed to save config = Görkəmlənişi qorumaq alınmadı Free space = Boş yer Manually specify PSP folder = PSP qovuluğunu əl ilə seç MemoryStickDescription = PSP verilənini tutacağınız yeri seçin (Yaddaş Çubuğu) -MissingFileBrowserError = Bu cihazda fayl/qovluq brauzeri yoxdur. 'Fayllar' tətbiqini deaktiv etmisinizsə, lütfən aktiv edin və yenidən cəhd edin. # AI translated +MissingFileBrowserError = Bu qurğuda fayl/qovluq göz atıcısı yoxdur. 'Fayllar' uyğulamasını işə salmamısınızsa, lütfən işə salın və yenidən sınayın. Move Data = Veriləni Daşı Moving the memstick directory is NOT recommended on iOS = yaddaş çubuğu qovluğunu daşımaq iOS üçün önərilmir Selected PSP Data Folder = Seçilən PSP Verilən Qovluğu @@ -981,10 +981,10 @@ Welcome to PPSSPP! = PPSSPP Xoş Gəldiniz! WhatsThis = Bu nədir? [Networking] -Ad Hoc multiplayer = Ad Hoc çox oyunculu # AI translated +Ad Hoc multiplayer = Ad Hoc çox oyunçusu Ad hoc server address = Ad hoc qulluqçu adresi Ad hoc server address hint = (localhost = çoxlu örnək) -Add server = Server əlavə et # AI translated +Add server = Qulluqçu artır AdHoc server = Ad hoc qulluqçusu AdhocServer Failed to Bind Port = Ad hoc qulluqçusu portu birləşdirə bilmədi Allow speed control while connected (not recommended) = Qoşulu ikən sürət yönəltməsinə yol ver (önərilmir) @@ -998,9 +998,9 @@ Chat Button Position = Danışıq düyməsinin yerləşimi Chat Here = Burada Danış Chat message = Danışıq göndərişi Chat Screen Position = Danışıq ekranının yerləşimi -Connected to relay = Relay ilə bağlı # AI translated -Connection to relay has recovered = Relay ilə bağlantı bərpa edildi # AI translated -Custom server list = Özelleştirilmiş server siyahısı # AI translated +Connected to relay = Releyə qoşulub +Connection to relay has recovered = Relay ilə bağlantı qaytarıldı +Custom server list = Özəl qulluqçu sıralığı Disconnected from AdhocServer = Ad hoc qulluqçusundan ayrılıb DNS Error Resolving = DNS yanlışınən çözülüşü DNS server = DNS qulluqçusu @@ -1010,52 +1010,52 @@ Enable networking = Bağlantını/WLAN aç Enable quick chat = Tez danışığı aç Enable UPnP = UPnP'ni aç (tapılması bir neçə saniyə alır) Error = Yanlış -Failed connecting to relay server = Relay server-ə bağlanmadı # AI translated -Failed connecting to relay server for %1 seconds, relay disabled = Relay server-ə %1 saniyə ərzində qoşulmaq mümkün olmadı, relay deaktiv edildi # AI translated +Failed connecting to relay server = Rele qulluqçusuna bağlantı uğursuz oldu +Failed connecting to relay server for %1 seconds, relay disabled = Rele qullquçusuna %1 saniyə içində qoşulma uğursuz oldu, rele qoşulmadı Failed to Bind Localhost IP = Localhost IP'ni birləşdirmə uğursuz oldu Failed to Bind Port = Portu birləşdirmə uğursuz oldu Failed to connect to Adhoc Server = Ad hoc qulluqçusuna qoşulma uğursuz oldu File transfer completed: %1 = File transfer completed: %1 Forced First Connect = İlk qoşulmaya güc verdi (daha sürətli qoşulma) GM: Data from Unknown Port = GM: Bilinməyən Port Veriləni -groups: %1 = qruplar: %1 # AI translated -Hostname or IP = Hostname və ya IP # AI translated +groups: %1 = qruplar: %1 +Hostname or IP = Yiyə adı ya da IP Infrastructure = İnfrastruktur Infrastructure server provided by: = İnfrastruktur qulluqçusunu təmin edən: Invalid IP or hostname = Keçərsiz IP ya da sahibin adı -Local network addresses = Yerli şəbəkə ünvanları # AI translated +Local network addresses = Yerli tor adresləri MAC address = MAC adresi dəyiş Minimum Timeout = Ən aşağı vaxt doluşu (gecikmə msan'də, 0 = vasrayılan) Misc = Çeşidli (varsayılan = PSP uyumluğu) Network connected = BAğlantı qoşulub Network functionality in this game is not guaranteed = Bu oyunda bağlantı söz verilmir Network initialized = Bağlantı başlandı -No games in progress on this server = Bu serverdə heç bir oyun davam etmir # AI translated +No games in progress on this server = Bu qulluqçuda irəliləyən oyun yoxdur Other versions of this game that should work: = Bu oyunun çalışası olan başqa sürümləri: -P2P mode = P2P rejimi # AI translated +P2P mode = P2P durumu PacketRelayHint = Socom.cc kimi 'aemu_postoffice' paket relayi təqdim edən serverlərdə mövcuddur. LAN və ya VPN oyunu üçün bunu deaktiv edin. Daha etibarlı ola bilər, amma bəzən yavaşdır. -Players waiting: %1 = Gözləyən oyunçular: %1 # AI translated -players: %1 = oyunçular: %1 # AI translated +Players waiting: %1 = Gözləyən oyunçular: %1 +players: %1 = oyunçular: %1 Please change your Port Offset = Port keçidinizi dəyişin Open PPSSPP Multiplayer Wiki Page = PPSSPP çox oyunçu Viki Səhifəsini aç Port offset = Port keçdi -PortOffsetHint = Default port offset 10000-dır. Dəyişdirin 0-a, dəyişdirilməmiş PSP konsolları ilə uyğunluğu üçün. # AI translated -Public server list = İctimai serverlərin siyahısı # AI translated -Quick start guide for multiplayer = Çox oyunculu üçün tez başlama təlimatı # AI translated +PortOffsetHint = Varsayılan giriş sürüşməsi 10000'dir. PSP konsolları ilə uyumluluq üçün 0'a dəyişin. +Public server list = Toplum qulluqçusu sıralığı +Quick start guide for multiplayer = Çox oyunçu üçün tez başlama göstərişi Quick chat %1 = Tez danışıq %1 Quick chat = Tez danışıq -Randomize = Təsadüfi +Randomize = Təsadüflət Relay = Rejimi -Relay server mode = Relay server rejimi # AI translated +Relay server mode = Rele qulluqçusu durumu Send = Göndər Send Discord Presence information = Discord "Bol Varlıq" bilgisini göndər -Server status: %1 = Server vəziyyəti: %1 # AI translated -Show player port numbers = Oyunçunun port nömrələrini göstərin # AI translated +Server status: %1 = Qulluqçu durumu: %1 +Show player port numbers = Oyunçu girişi sayılarını göstər Some network functionality in this game is not working = Bu oyundakı bəzi bağlantı işləvsəlliklər işləmir -Status = Status # AI translated +Status = Durum To play in Infrastructure Mode, you must enter a username = İnfrastruktur Modunda oynamaq üçün işlədici adı yazmalısınız -Transfer files = Faylları köçürmək -Try to pick a unique nickname for ad hoc play = Təsadüfi oyun üçün unikal ləqəb seçməyə çalışın # AI translated +Transfer files = Faylları köçür +Try to pick a unique nickname for ad hoc play = Ad hoc oyunu üçün taysız taxma ad götürməyə çalışın Try to use server-provided packet relay = Server tərəfindən təmin edilən paket relay-dən istifadə etməyə çalışın Unable to find UPnP device = UPnP qurğusu tapılmır Upload files = Faylları yükləyin @@ -1380,7 +1380,7 @@ System Information = Sistem bilgisi System Name = Sistem adı System Version = Sistem sürümü Threads = Axınlar -UI resolution = AY çözünürlüyü +UI resolution = İA çözünürlüyü Vendor = İstehsalçı Vendor (detected) = İstehsalçı (tapılıb) Version Information = Sürüm bilgisi @@ -1412,7 +1412,7 @@ Failed to load state for load undo. Error in the file system. = Geri yükləniş Final processed image = Son işlənmiş görüntü Floating symbols = Üzən simgələr Game crashed = Oyun çökdü -Hide navigation bar = Naviqasiya çubuğunu gizlət # AI translated +Hide navigation bar = Yönəliş çubuğunu gizlət I/O timing method = G/Ç zamanlama yöntəmi JIT using IR = IR işlədən JIT Language = Dil @@ -1426,7 +1426,7 @@ ChangingMemstickPathInvalid = Bu yol, Yaddaş Çubuğu fayllarının qorunuşu Cheats = Hiylələr Clear Recent = "Az öncə"ni təmizlə Clear Recent Games List = Az öncəki oyunlar sıralığını təmizlə -Clear UI background = AY arxa fonunu təmizlə +Clear UI background = İA arxa fonunu təmizlə Confirmation Button = Onaylanış düyməsi Date Format = Tarix biçimi DDMMYYYY = GGAAİİİİ @@ -1489,7 +1489,7 @@ Savestate slot count = Saxlama vəziyyət slotu sayı Screenshot mode = Ekran çəkimi modu Screenshots as PNG = Ekran çəkimlərini PNG biçimində qoru Set Memory Stick folder = Yaddaş Çubuğu qovluğunu qur -Set UI background... = AY arxa fonunu qur... +Set UI background... = İA arxa fonunu qur... Show ID = ID'ni göstər Show Memory Stick folder = Yaddaş Çubuğu qovluğunu göstər Show region flag = Bölgə bayrağını göstər @@ -1506,10 +1506,10 @@ Swipe once to switch app (indicator auto-hides) = Uyğulamanı dəyişmək üç Swipe twice to switch app (indicator stays visible) = Uyğulamanı dəyişmək üçün iki dəfə sürüşdür (göstərici qalır) Theme = Tema Time Format = Vaxt formatı -Transparent UI background = Şəffaf AY arxa fonu -UI = AY -UI background animation = AY arxa fonunun animasiyası -UI size adjustment (DPI) = AY ölçü dəyişimi (DPI) +Transparent UI background = Şəffaf İA arxa fonu +UI = İA +UI background animation = İA arxa fonunun animasiyası +UI size adjustment (DPI) = İA ölçü dəyişimi (DPI) undo %c = geri al %c USB = USB Use Lossless Video Codec (FFV1) = İtkisiz video çözücünü işlət (FFV1) diff --git a/ext/imgui/imgui_impl_thin3d.cpp b/ext/imgui/imgui_impl_thin3d.cpp index 4bef970ed895..757f0ef494a0 100644 --- a/ext/imgui/imgui_impl_thin3d.cpp +++ b/ext/imgui/imgui_impl_thin3d.cpp @@ -73,7 +73,7 @@ void ImGui_ImplThin3d_RenderDrawData(ImDrawData* draw_data, Draw::DrawContext *d viewport.MaxDepth = 1.0f; draw->SetViewport(viewport); - Lin::Matrix4x4 mtx = ComputeOrthoMatrix(draw_data->DisplaySize.x, draw_data->DisplaySize.y, draw->GetDeviceCaps().coordConvention); + Lin::Matrix4x4 mtx = ComputeOrthoMatrix(draw_data->DisplaySize.x, draw_data->DisplaySize.y, draw->GetDeviceCaps().coordConvention, true); Draw::VsTexColUB ub{}; memcpy(ub.WorldViewProj, mtx.getReadPtr(), sizeof(Lin::Matrix4x4)); diff --git a/headless/Headless.vcxproj b/headless/Headless.vcxproj index 52a171dc42e0..4ad32aa9fde2 100644 --- a/headless/Headless.vcxproj +++ b/headless/Headless.vcxproj @@ -150,7 +150,7 @@ Console true - winhttp.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;winhttp.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) 0x00400000 false true @@ -183,7 +183,7 @@ Console true - winhttp.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;winhttp.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) 0x00400000 false true @@ -215,7 +215,7 @@ Console true - winhttp.lib;ole32.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;winhttp.lib;ole32.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/aarch64/lib @@ -248,7 +248,7 @@ true true true - winhttp.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;winhttp.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) 0x00400000 false true @@ -286,7 +286,7 @@ true true true - winhttp.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;winhttp.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) 0x00400000 false true @@ -323,7 +323,7 @@ true true true - winhttp.lib;ole32.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;winhttp.lib;ole32.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/aarch64/lib;%(AdditionalLibraryDirectories) diff --git a/unittest/UnitTests.vcxproj b/unittest/UnitTests.vcxproj index 13ac7577c7a4..00bbdc2befc1 100644 --- a/unittest/UnitTests.vcxproj +++ b/unittest/UnitTests.vcxproj @@ -165,7 +165,7 @@ Console true - winhttp.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;winhttp.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/x86_64/lib @@ -188,7 +188,7 @@ Console true - winhttp.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;winhttp.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/aarch64/lib @@ -216,7 +216,7 @@ true true true - winhttp.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;winhttp.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/x86/lib @@ -245,7 +245,7 @@ true true true - winhttp.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;winhttp.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/x86_64/lib @@ -274,7 +274,7 @@ true true true - winhttp.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies) + d2d1.lib;dwrite.lib;d3d11.lib;winhttp.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/aarch64/lib