From 310814ac716534b20fbfeb0d7983dcaebb9d161f Mon Sep 17 00:00:00 2001 From: TheTurtle <47210458+raphaelthegreat@users.noreply.github.com> Date: Sun, 6 Oct 2024 19:43:59 +0300 Subject: [PATCH 1/9] shader_recompiler: Support for more offset layouts (#1270) --- .../backend/spirv/emit_spirv.cpp | 6 ++++-- .../backend/spirv/spirv_emit_context.cpp | 18 ++++++++++-------- src/shader_recompiler/frontend/copy_shader.cpp | 16 +++++++++------- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index a585f3283..f199860af 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp @@ -27,8 +27,10 @@ static constexpr spv::ExecutionMode GetInputPrimitiveType(AmdGpu::PrimitiveType case AmdGpu::PrimitiveType::TriangleList: case AmdGpu::PrimitiveType::TriangleStrip: return spv::ExecutionMode::Triangles; + case AmdGpu::PrimitiveType::AdjTriangleList: + return spv::ExecutionMode::InputTrianglesAdjacency; default: - UNREACHABLE(); + UNREACHABLE_MSG("Unknown input primitive type {}", u32(type)); } } @@ -41,7 +43,7 @@ static constexpr spv::ExecutionMode GetOutputPrimitiveType(AmdGpu::GsOutputPrimi case AmdGpu::GsOutputPrimitiveType::TriangleStrip: return spv::ExecutionMode::OutputTriangleStrip; default: - UNREACHABLE(); + UNREACHABLE_MSG("Unknown output primitive type {}", u32(type)); } } diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index f5b60d51d..c753b4a47 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp @@ -34,14 +34,17 @@ std::string_view StageName(Stage stage) { throw InvalidArgument("Invalid stage {}", u32(stage)); } -static constexpr u32 NumVertices(AmdGpu::GsOutputPrimitiveType type) { +static constexpr u32 NumVertices(AmdGpu::PrimitiveType type) { switch (type) { - case AmdGpu::GsOutputPrimitiveType::PointList: + case AmdGpu::PrimitiveType::PointList: return 1u; - case AmdGpu::GsOutputPrimitiveType::LineStrip: + case AmdGpu::PrimitiveType::LineList: return 2u; - case AmdGpu::GsOutputPrimitiveType::TriangleStrip: + case AmdGpu::PrimitiveType::TriangleList: + case AmdGpu::PrimitiveType::TriangleStrip: return 3u; + case AmdGpu::PrimitiveType::AdjTriangleList: + return 6u; default: UNREACHABLE(); } @@ -321,16 +324,15 @@ void EmitContext::DefineInputs() { MemberDecorate(gl_per_vertex, 2, spv::Decoration::BuiltIn, static_cast(spv::BuiltIn::ClipDistance)); Decorate(gl_per_vertex, spv::Decoration::Block); - const auto vertices_in = - TypeArray(gl_per_vertex, ConstU32(NumVertices(runtime_info.gs_info.out_primitive[0]))); + const auto num_verts_in = NumVertices(runtime_info.gs_info.in_primitive); + const auto vertices_in = TypeArray(gl_per_vertex, ConstU32(num_verts_in)); gl_in = Name(DefineVar(vertices_in, spv::StorageClass::Input), "gl_in"); interfaces.push_back(gl_in); const auto num_params = runtime_info.gs_info.in_vertex_data_size / 4 - 1u; for (int param_id = 0; param_id < num_params; ++param_id) { const IR::Attribute param{IR::Attribute::Param0 + param_id}; - const Id type{ - TypeArray(F32[4], ConstU32(NumVertices(runtime_info.gs_info.out_primitive[0])))}; + const Id type{TypeArray(F32[4], ConstU32(num_verts_in))}; const Id id{DefineInput(type, param_id)}; Name(id, fmt::format("in_attr{}", param_id)); input_params[param_id] = {id, input_f32, F32[1], 4}; diff --git a/src/shader_recompiler/frontend/copy_shader.cpp b/src/shader_recompiler/frontend/copy_shader.cpp index a194aec95..363c1c821 100644 --- a/src/shader_recompiler/frontend/copy_shader.cpp +++ b/src/shader_recompiler/frontend/copy_shader.cpp @@ -15,18 +15,18 @@ CopyShaderData ParseCopyShader(const std::span& code) { ASSERT_MSG(code[0] == token_mov_vcchi, "First instruction is not s_mov_b32 vcc_hi, #imm"); std::array offsets{}; - std::fill(offsets.begin(), offsets.end(), -1); + offsets.fill(-1); + + std::array sources{}; + sources.fill(-1); CopyShaderData data{}; - Gcn::OperandField sgpr{}; auto last_attr{IR::Attribute::Position0}; - s32 soffset{0}; while (!code_slice.atEnd()) { auto inst = decoder.decodeInstruction(code_slice); switch (inst.opcode) { case Gcn::Opcode::S_MOVK_I32: { - sgpr = inst.dst[0].field; - soffset = inst.control.sopk.simm; + sources[inst.dst[0].code] = inst.control.sopk.simm; break; } case Gcn::Opcode::EXP: { @@ -46,8 +46,9 @@ CopyShaderData ParseCopyShader(const std::span& code) { case Gcn::Opcode::BUFFER_LOAD_DWORD: { offsets[inst.src[1].code] = inst.control.mubuf.offset; if (inst.src[3].field != Gcn::OperandField::ConstZero) { - ASSERT(inst.src[3].field == sgpr); - offsets[inst.src[1].code] += soffset; + const u32 index = inst.src[3].code; + ASSERT(sources[index] != -1); + offsets[inst.src[1].code] += sources[index]; } break; } @@ -59,6 +60,7 @@ CopyShaderData ParseCopyShader(const std::span& code) { if (last_attr != IR::Attribute::Position0) { data.num_attrs = static_cast(last_attr) - static_cast(IR::Attribute::Param0) + 1; } + return data; } From 3c0255b9537201bd179240b99b6719302e24014e Mon Sep 17 00:00:00 2001 From: baggins183 Date: Sun, 6 Oct 2024 12:34:40 -0700 Subject: [PATCH 2/9] DebugPrintf in shaders (#1252) * Add shader debug print opcode that uses NonSemantic DebugPrintf extension * small correction for flags in Inst * Fix IR Debug Print. Add StringLiteral op * add missing microinstruction changes for debugprint * cleanup. delete vaarg stuff. Smuggle format string in Info and flags * more cleanup * more * (dont merge??) update sirit submodule * fix num args 4 -> 5 * add notes about DebugPrint IR op * use NumArgsOf again * copyright * update sirit submodule * fix clangformat * add new Value variant for string literal. Use arg0 for fmt string * remove string pool changes * Update src/shader_recompiler/ir/value.cpp Co-authored-by: TheTurtle <47210458+raphaelthegreat@users.noreply.github.com> --------- Co-authored-by: TheTurtle <47210458+raphaelthegreat@users.noreply.github.com> --- externals/sirit | 2 +- .../backend/spirv/emit_spirv.cpp | 2 + .../backend/spirv/emit_spirv_instructions.h | 1 + .../backend/spirv/emit_spirv_special.cpp | 8 ++++ .../backend/spirv/spirv_emit_context.cpp | 2 + src/shader_recompiler/info.h | 1 + src/shader_recompiler/ir/debug_print.h | 21 +++++++++++ src/shader_recompiler/ir/ir_emitter.cpp | 37 +++++++++++++++++++ src/shader_recompiler/ir/ir_emitter.h | 2 + src/shader_recompiler/ir/microinstruction.cpp | 1 + src/shader_recompiler/ir/opcodes.h | 3 +- src/shader_recompiler/ir/opcodes.inc | 1 + src/shader_recompiler/ir/type.cpp | 7 ++-- src/shader_recompiler/ir/type.h | 1 + src/shader_recompiler/ir/value.cpp | 5 +++ src/shader_recompiler/ir/value.h | 11 ++++++ 16 files changed, 99 insertions(+), 6 deletions(-) create mode 100644 src/shader_recompiler/ir/debug_print.h diff --git a/externals/sirit b/externals/sirit index 37090c74c..6cecb95d6 160000 --- a/externals/sirit +++ b/externals/sirit @@ -1 +1 @@ -Subproject commit 37090c74cc6e680f2bc334cac8fd182f7634a1f6 +Subproject commit 6cecb95d679c82c413d1f989e0b7ad9af130600d diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index f199860af..f90e9db77 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp @@ -70,6 +70,8 @@ ArgType Arg(EmitContext& ctx, const IR::Value& arg) { return arg.ScalarReg(); } else if constexpr (std::is_same_v) { return arg.VectorReg(); + } else if constexpr (std::is_same_v) { + return arg.StringLiteral(); } } diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h index ec86e5cc9..6ae1ef24a 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h @@ -48,6 +48,7 @@ void EmitPrologue(EmitContext& ctx); void EmitEpilogue(EmitContext& ctx); void EmitDiscard(EmitContext& ctx); void EmitDiscardCond(EmitContext& ctx, Id condition); +void EmitDebugPrint(EmitContext& ctx, IR::Inst* inst, Id arg0, Id arg1, Id arg2, Id arg3, Id arg4); void EmitBarrier(EmitContext& ctx); void EmitWorkgroupMemoryBarrier(EmitContext& ctx); void EmitDeviceMemoryBarrier(EmitContext& ctx); diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp index c12e4997f..e9ffdcce8 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp @@ -3,6 +3,7 @@ #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" #include "shader_recompiler/backend/spirv/spirv_emit_context.h" +#include "shader_recompiler/ir/debug_print.h" namespace Shader::Backend::SPIRV { @@ -57,4 +58,11 @@ void EmitEndPrimitive(EmitContext& ctx, const IR::Value& stream) { throw NotImplementedException("Geometry streams"); } +void EmitDebugPrint(EmitContext& ctx, IR::Inst* inst, Id fmt, Id arg0, Id arg1, Id arg2, Id arg3) { + IR::DebugPrintFlags flags = inst->Flags(); + std::array fmt_args = {arg0, arg1, arg2, arg3}; + auto fmt_args_span = std::span(fmt_args.begin(), fmt_args.begin() + flags.num_args); + ctx.OpDebugPrintf(fmt, fmt_args_span); +} + } // namespace Shader::Backend::SPIRV diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index c753b4a47..5eee656dd 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp @@ -91,6 +91,8 @@ Id EmitContext::Def(const IR::Value& value) { return ConstF32(value.F32()); case IR::Type::F64: return Constant(F64[1], value.F64()); + case IR::Type::StringLiteral: + return String(value.StringLiteral()); default: throw NotImplementedException("Immediate type {}", value.Type()); } diff --git a/src/shader_recompiler/info.h b/src/shader_recompiler/info.h index 7fc7be753..78a6805fd 100644 --- a/src/shader_recompiler/info.h +++ b/src/shader_recompiler/info.h @@ -3,6 +3,7 @@ #pragma once #include +#include #include #include #include "common/assert.h" diff --git a/src/shader_recompiler/ir/debug_print.h b/src/shader_recompiler/ir/debug_print.h new file mode 100644 index 000000000..1ab1575de --- /dev/null +++ b/src/shader_recompiler/ir/debug_print.h @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/bit_field.h" +#include "shader_recompiler/ir/opcodes.h" +#include "src/common/types.h" + +#pragma once + +namespace Shader::IR { + +constexpr size_t DEBUGPRINT_NUM_FORMAT_ARGS = NumArgsOf(IR::Opcode::DebugPrint) - 1; + +union DebugPrintFlags { + u32 raw; + // For now, only flag is the number of variadic format args actually used + // So bitfield not really needed + BitField<0, 32, u32> num_args; +}; + +} // namespace Shader::IR \ No newline at end of file diff --git a/src/shader_recompiler/ir/ir_emitter.cpp b/src/shader_recompiler/ir/ir_emitter.cpp index 01336c567..4f5eb5c33 100644 --- a/src/shader_recompiler/ir/ir_emitter.cpp +++ b/src/shader_recompiler/ir/ir_emitter.cpp @@ -1,10 +1,15 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include #include #include +#include +#include "common/assert.h" #include "shader_recompiler/exception.h" +#include "shader_recompiler/ir/debug_print.h" #include "shader_recompiler/ir/ir_emitter.h" +#include "shader_recompiler/ir/opcodes.h" #include "shader_recompiler/ir/value.h" namespace Shader::IR { @@ -1553,6 +1558,38 @@ void IREmitter::ImageWrite(const Value& handle, const Value& coords, const Value Inst(Opcode::ImageWrite, Flags{info}, handle, coords, color); } +// Debug print maps to SPIRV's NonSemantic DebugPrintf instruction +// Renderdoc will hook in its own implementation of the SPIRV instruction +// Renderdoc accepts format specifiers, e.g. %u, listed here: +// https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/main/docs/debug_printf.md +// +// fmt must be a string literal (pointer is shallow copied into a Value) +// Example usage: +// ir.DebugPrint("invocation xyz: (%u, %u, %u)", +// {ir.GetVectorReg(IR::VectorReg::V0), +// ir.GetVectorReg(IR::VectorReg::V1), +// ir.GetVectorReg(IR::VectorReg::V2)}); +void IREmitter::DebugPrint(const char* fmt, boost::container::small_vector format_args) { + std::array args; + + ASSERT_MSG(format_args.size() < DEBUGPRINT_NUM_FORMAT_ARGS, + "DebugPrint only supports up to {} format args", DEBUGPRINT_NUM_FORMAT_ARGS); + + for (int i = 0; i < format_args.size(); i++) { + args[i] = format_args[i]; + } + + for (int i = format_args.size(); i < DEBUGPRINT_NUM_FORMAT_ARGS; i++) { + args[i] = Inst(Opcode::Void); + } + + IR::Value fmt_val{fmt}; + + DebugPrintFlags flags; + flags.num_args.Assign(format_args.size()); + Inst(Opcode::DebugPrint, Flags{flags}, fmt_val, args[0], args[1], args[2], args[3]); +} + void IREmitter::EmitVertex() { Inst(Opcode::EmitVertex); } diff --git a/src/shader_recompiler/ir/ir_emitter.h b/src/shader_recompiler/ir/ir_emitter.h index 8657c430b..2ebac037e 100644 --- a/src/shader_recompiler/ir/ir_emitter.h +++ b/src/shader_recompiler/ir/ir_emitter.h @@ -6,6 +6,7 @@ #include #include +#include "shader_recompiler/info.h" #include "shader_recompiler/ir/attribute.h" #include "shader_recompiler/ir/basic_block.h" #include "shader_recompiler/ir/condition.h" @@ -43,6 +44,7 @@ public: void Epilogue(); void Discard(); void Discard(const U1& cond); + void DebugPrint(const char* fmt, boost::container::small_vector args); void Barrier(); void WorkgroupMemoryBarrier(); diff --git a/src/shader_recompiler/ir/microinstruction.cpp b/src/shader_recompiler/ir/microinstruction.cpp index 8d606a6cc..f0b4882b3 100644 --- a/src/shader_recompiler/ir/microinstruction.cpp +++ b/src/shader_recompiler/ir/microinstruction.cpp @@ -89,6 +89,7 @@ bool Inst::MayHaveSideEffects() const noexcept { case Opcode::ImageAtomicOr32: case Opcode::ImageAtomicXor32: case Opcode::ImageAtomicExchange32: + case Opcode::DebugPrint: case Opcode::EmitVertex: case Opcode::EmitPrimitive: return true; diff --git a/src/shader_recompiler/ir/opcodes.h b/src/shader_recompiler/ir/opcodes.h index 06f1a6117..2cea70090 100644 --- a/src/shader_recompiler/ir/opcodes.h +++ b/src/shader_recompiler/ir/opcodes.h @@ -51,6 +51,7 @@ constexpr Type F32x4{Type::F32x4}; constexpr Type F64x2{Type::F64x2}; constexpr Type F64x3{Type::F64x3}; constexpr Type F64x4{Type::F64x4}; +constexpr Type StringLiteral{Type::StringLiteral}; constexpr OpcodeMeta META_TABLE[]{ #define OPCODE(name_token, type_token, ...) \ @@ -81,7 +82,7 @@ constexpr u8 NUM_ARGS[]{ } /// Get the number of arguments an opcode accepts -[[nodiscard]] inline size_t NumArgsOf(Opcode op) noexcept { +[[nodiscard]] constexpr inline size_t NumArgsOf(Opcode op) noexcept { return static_cast(Detail::NUM_ARGS[static_cast(op)]); } diff --git a/src/shader_recompiler/ir/opcodes.inc b/src/shader_recompiler/ir/opcodes.inc index c69dc90a5..41e94ab13 100644 --- a/src/shader_recompiler/ir/opcodes.inc +++ b/src/shader_recompiler/ir/opcodes.inc @@ -14,6 +14,7 @@ OPCODE(Prologue, Void, OPCODE(Epilogue, Void, ) OPCODE(Discard, Void, ) OPCODE(DiscardCond, Void, U1, ) +OPCODE(DebugPrint, Void, StringLiteral, Opaque, Opaque, Opaque, Opaque, ) // Constant memory operations OPCODE(ReadConst, U32, U32x2, U32, ) diff --git a/src/shader_recompiler/ir/type.cpp b/src/shader_recompiler/ir/type.cpp index 9d303b4db..08157f108 100644 --- a/src/shader_recompiler/ir/type.cpp +++ b/src/shader_recompiler/ir/type.cpp @@ -9,10 +9,9 @@ namespace Shader::IR { std::string NameOf(Type type) { static constexpr std::array names{ - "Opaque", "Label", "Reg", "Pred", "Attribute", "U1", "U8", "U16", "U32", - "U64", "F16", "F32", "F64", "U32x2", "U32x3", "U32x4", "F16x2", "F16x3", - "F16x4", "F32x2", "F32x3", "F32x4", "F64x2", "F64x3", "F64x4", - }; + "Opaque", "Label", "Reg", "Pred", "Attribute", "U1", "U8", "U16", "U32", + "U64", "F16", "F32", "F64", "U32x2", "U32x3", "U32x4", "F16x2", "F16x3", + "F16x4", "F32x2", "F32x3", "F32x4", "F64x2", "F64x3", "F64x4", "StringLiteral"}; const size_t bits{static_cast(type)}; if (bits == 0) { return "Void"; diff --git a/src/shader_recompiler/ir/type.h b/src/shader_recompiler/ir/type.h index d7f47e1de..ec855a77e 100644 --- a/src/shader_recompiler/ir/type.h +++ b/src/shader_recompiler/ir/type.h @@ -36,6 +36,7 @@ enum class Type { F64x2 = 1 << 22, F64x3 = 1 << 23, F64x4 = 1 << 24, + StringLiteral = 1 << 25, }; DECLARE_ENUM_FLAG_OPERATORS(Type) diff --git a/src/shader_recompiler/ir/value.cpp b/src/shader_recompiler/ir/value.cpp index 86e5dd141..cf7a70f76 100644 --- a/src/shader_recompiler/ir/value.cpp +++ b/src/shader_recompiler/ir/value.cpp @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include #include "shader_recompiler/ir/value.h" namespace Shader::IR { @@ -27,6 +28,8 @@ Value::Value(u64 value) noexcept : type{Type::U64}, imm_u64{value} {} Value::Value(f64 value) noexcept : type{Type::F64}, imm_f64{value} {} +Value::Value(const char* value) noexcept : type{Type::StringLiteral}, string_literal{value} {} + IR::Type Value::Type() const noexcept { if (IsPhi()) { // The type of a phi node is stored in its flags @@ -69,6 +72,8 @@ bool Value::operator==(const Value& other) const { case Type::U64: case Type::F64: return imm_u64 == other.imm_u64; + case Type::StringLiteral: + return std::string_view(string_literal) == other.string_literal; case Type::U32x2: case Type::U32x3: case Type::U32x4: diff --git a/src/shader_recompiler/ir/value.h b/src/shader_recompiler/ir/value.h index db939eaa5..060b9d2bb 100644 --- a/src/shader_recompiler/ir/value.h +++ b/src/shader_recompiler/ir/value.h @@ -39,6 +39,7 @@ public: explicit Value(f32 value) noexcept; explicit Value(u64 value) noexcept; explicit Value(f64 value) noexcept; + explicit Value(const char* value) noexcept; [[nodiscard]] bool IsIdentity() const noexcept; [[nodiscard]] bool IsPhi() const noexcept; @@ -60,6 +61,7 @@ public: [[nodiscard]] f32 F32() const; [[nodiscard]] u64 U64() const; [[nodiscard]] f64 F64() const; + [[nodiscard]] const char* StringLiteral() const; [[nodiscard]] bool operator==(const Value& other) const; [[nodiscard]] bool operator!=(const Value& other) const; @@ -78,6 +80,7 @@ private: f32 imm_f32; u64 imm_u64; f64 imm_f64; + const char* string_literal; }; }; static_assert(static_cast(IR::Type::Void) == 0, "memset relies on IR::Type being zero"); @@ -348,6 +351,14 @@ inline f64 Value::F64() const { return imm_f64; } +inline const char* Value::StringLiteral() const { + if (IsIdentity()) { + return inst->Arg(0).StringLiteral(); + } + DEBUG_ASSERT(type == Type::StringLiteral); + return string_literal; +} + [[nodiscard]] inline bool IsPhi(const Inst& inst) { return inst.GetOpcode() == Opcode::Phi; } From 75c92a7cd1f60fcef09c0a2a36da3090b9aa5bf3 Mon Sep 17 00:00:00 2001 From: Dzmitry Dubrova Date: Sun, 6 Oct 2024 22:34:55 +0300 Subject: [PATCH 3/9] net: Stub sceNetErrnoLoc (#1271) --- src/core/libraries/network/net.cpp | 6 ++++-- src/core/libraries/network/net.h | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/libraries/network/net.cpp b/src/core/libraries/network/net.cpp index 2c03dde3e..35d5851ea 100644 --- a/src/core/libraries/network/net.cpp +++ b/src/core/libraries/network/net.cpp @@ -18,6 +18,8 @@ namespace Libraries::Net { +static thread_local int32_t net_errno = 0; + int PS4_SYSV_ABI in6addr_any() { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; @@ -563,9 +565,9 @@ int PS4_SYSV_ABI sceNetEpollWait() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNetErrnoLoc() { +int* PS4_SYSV_ABI sceNetErrnoLoc() { LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; + return &net_errno; } int PS4_SYSV_ABI sceNetEtherNtostr() { diff --git a/src/core/libraries/network/net.h b/src/core/libraries/network/net.h index eababdb67..3f010f685 100644 --- a/src/core/libraries/network/net.h +++ b/src/core/libraries/network/net.h @@ -136,7 +136,7 @@ int PS4_SYSV_ABI sceNetEpollControl(); int PS4_SYSV_ABI sceNetEpollCreate(); int PS4_SYSV_ABI sceNetEpollDestroy(); int PS4_SYSV_ABI sceNetEpollWait(); -int PS4_SYSV_ABI sceNetErrnoLoc(); +int* PS4_SYSV_ABI sceNetErrnoLoc(); int PS4_SYSV_ABI sceNetEtherNtostr(); int PS4_SYSV_ABI sceNetEtherStrton(); int PS4_SYSV_ABI sceNetEventCallbackCreate(); From d7e5b5f13f3ef95ee9808dedb0c6c7293b4a360a Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Mon, 7 Oct 2024 13:04:09 +0300 Subject: [PATCH 4/9] updated sdl to fix touchpad issue (#1275) --- externals/date | 2 +- externals/sdl3 | 2 +- src/audio_core/sdl_audio.cpp | 2 +- src/imgui/renderer/imgui_impl_sdl3.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/externals/date b/externals/date index 51ce7e131..dd8affc6d 160000 --- a/externals/date +++ b/externals/date @@ -1 +1 @@ -Subproject commit 51ce7e131079c061533d741be5fe7cca57f2faac +Subproject commit dd8affc6de5755e07638bf0a14382d29549d6ee9 diff --git a/externals/sdl3 b/externals/sdl3 index 0548050fc..54e622c2e 160000 --- a/externals/sdl3 +++ b/externals/sdl3 @@ -1 +1 @@ -Subproject commit 0548050fc5a4edf1f47c3633c2cd06d8762b5532 +Subproject commit 54e622c2e6af456bfef382fae44c17682d5ac88a diff --git a/src/audio_core/sdl_audio.cpp b/src/audio_core/sdl_audio.cpp index 894f5da55..7fed42a44 100644 --- a/src/audio_core/sdl_audio.cpp +++ b/src/audio_core/sdl_audio.cpp @@ -103,7 +103,7 @@ s32 SDLAudio::AudioOutOutput(s32 handle, const void* ptr) { const size_t data_size = port.samples_num * port.sample_size * port.channels_num; - SDL_bool result = SDL_PutAudioStreamData(port.stream, ptr, data_size); + bool result = SDL_PutAudioStreamData(port.stream, ptr, data_size); lock.unlock(); // Unlock only after necessary operations diff --git a/src/imgui/renderer/imgui_impl_sdl3.cpp b/src/imgui/renderer/imgui_impl_sdl3.cpp index bb194bff7..cecf504a7 100644 --- a/src/imgui/renderer/imgui_impl_sdl3.cpp +++ b/src/imgui/renderer/imgui_impl_sdl3.cpp @@ -581,7 +581,7 @@ static void UpdateMouseData() { // (below) // SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries // shouldn't e.g. trigger other operations outside - SDL_CaptureMouse((bd->mouse_buttons_down != 0) ? SDL_TRUE : SDL_FALSE); + SDL_CaptureMouse((bd->mouse_buttons_down != 0) ? true : false); SDL_Window* focused_window = SDL_GetKeyboardFocus(); const bool is_app_focused = (bd->window == focused_window); From 20db37f2351a0670ba666fa247ba0d158f299912 Mon Sep 17 00:00:00 2001 From: DanielSvoboda Date: Mon, 7 Oct 2024 08:52:38 -0300 Subject: [PATCH 5/9] fix update linux console (#1238) --- src/qt_gui/check_update.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/qt_gui/check_update.cpp b/src/qt_gui/check_update.cpp index 023c6e7bb..48adbb88a 100644 --- a/src/qt_gui/check_update.cpp +++ b/src/qt_gui/check_update.cpp @@ -454,6 +454,10 @@ void CheckUpdate::Install() { " sleep 2\n" " extract_file\n" " sleep 2\n" + " if pgrep -f \"Shadps4-qt.AppImage\" > /dev/null; then\n" + " pkill -f \"Shadps4-qt.AppImage\"\n" + " sleep 2\n" + " fi\n" " cp -r \"%2/\"* \"%3/\"\n" " sleep 2\n" " rm \"%3/update.sh\"\n" @@ -525,4 +529,4 @@ void CheckUpdate::Install() { this, tr("Error"), QString(tr("Failed to create the update script file") + ":\n" + scriptFileName)); } -} \ No newline at end of file +} From 7389cf3e897bdf489f9260cfdef6fdddee88f72c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=A5IGA?= <164882787+Xphalnos@users.noreply.github.com> Date: Mon, 7 Oct 2024 15:29:07 +0200 Subject: [PATCH 6/9] PM4 old removed + fixes (#1259) --- src/qt_gui/settings_dialog.cpp | 4 +--- src/qt_gui/settings_dialog.h | 2 +- src/qt_gui/translations/ar.ts | 10 ---------- src/qt_gui/translations/da_DK.ts | 10 ---------- src/qt_gui/translations/de.ts | 10 ---------- src/qt_gui/translations/el.ts | 10 ---------- src/qt_gui/translations/en.ts | 10 ---------- src/qt_gui/translations/es_ES.ts | 10 ---------- src/qt_gui/translations/fa_IR.ts | 10 ---------- src/qt_gui/translations/fi.ts | 10 ---------- src/qt_gui/translations/fr.ts | 10 ---------- src/qt_gui/translations/hu_HU.ts | 10 ---------- src/qt_gui/translations/id.ts | 10 ---------- src/qt_gui/translations/it.ts | 10 ---------- src/qt_gui/translations/ja_JP.ts | 10 ---------- src/qt_gui/translations/ko_KR.ts | 10 ---------- src/qt_gui/translations/lt_LT.ts | 10 ---------- src/qt_gui/translations/nb.ts | 10 ---------- src/qt_gui/translations/nl.ts | 10 ---------- src/qt_gui/translations/pl_PL.ts | 10 ---------- src/qt_gui/translations/pt_BR.ts | 10 ---------- src/qt_gui/translations/ro_RO.ts | 10 ---------- src/qt_gui/translations/ru_RU.ts | 10 ---------- src/qt_gui/translations/sq.ts | 10 ---------- src/qt_gui/translations/tr_TR.ts | 10 ---------- src/qt_gui/translations/vi_VN.ts | 10 ---------- src/qt_gui/translations/zh_CN.ts | 10 ---------- src/qt_gui/translations/zh_TW.ts | 10 ---------- 28 files changed, 2 insertions(+), 264 deletions(-) diff --git a/src/qt_gui/settings_dialog.cpp b/src/qt_gui/settings_dialog.cpp index 4a42e1961..1c0b0bc07 100644 --- a/src/qt_gui/settings_dialog.cpp +++ b/src/qt_gui/settings_dialog.cpp @@ -334,8 +334,6 @@ void SettingsDialog::updateNoteTextEdit(const QString& elementName) { text = tr("dumpShadersCheckBox"); } else if (elementName == "nullGpuCheckBox") { text = tr("nullGpuCheckBox"); - } else if (elementName == "dumpPM4CheckBox") { - text = tr("dumpPM4CheckBox"); } // Debug @@ -352,7 +350,7 @@ void SettingsDialog::updateNoteTextEdit(const QString& elementName) { ui->descriptionText->setText(text.replace("\\n", "\n")); } -bool SettingsDialog::override(QObject* obj, QEvent* event) { +bool SettingsDialog::eventFilter(QObject* obj, QEvent* event) { if (event->type() == QEvent::Enter || event->type() == QEvent::Leave) { if (qobject_cast(obj)) { bool hovered = (event->type() == QEvent::Enter); diff --git a/src/qt_gui/settings_dialog.h b/src/qt_gui/settings_dialog.h index 71307d398..85ae39aaa 100644 --- a/src/qt_gui/settings_dialog.h +++ b/src/qt_gui/settings_dialog.h @@ -21,7 +21,7 @@ public: explicit SettingsDialog(std::span physical_devices, QWidget* parent = nullptr); ~SettingsDialog(); - bool override(QObject* obj, QEvent* event); + bool eventFilter(QObject* obj, QEvent* event) override; void updateNoteTextEdit(const QString& groupName); int exec() override; diff --git a/src/qt_gui/translations/ar.ts b/src/qt_gui/translations/ar.ts index b385b491b..ca23620bb 100644 --- a/src/qt_gui/translations/ar.ts +++ b/src/qt_gui/translations/ar.ts @@ -474,11 +474,6 @@ Enable NULL GPU تمكين وحدة معالجة الرسومات الفارغة - - - Enable PM4 Dumping - PM4 تمكين تفريغ - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox تمكين GPU الافتراضية:\nلأغراض تصحيح الأخطاء التقنية، يقوم بتعطيل عرض اللعبة كما لو لم يكن هناك بطاقة رسومات. - - - dumpPM4CheckBox - تمكين تفريغ PM4:\nلأغراض تصحيح الأخطاء التقنية، يحفظ بيانات تعليمات GPU الأولية في مجلد أثناء معالجتها. - debugDump diff --git a/src/qt_gui/translations/da_DK.ts b/src/qt_gui/translations/da_DK.ts index 73bc37189..0d81e2357 100644 --- a/src/qt_gui/translations/da_DK.ts +++ b/src/qt_gui/translations/da_DK.ts @@ -474,11 +474,6 @@ Enable NULL GPU Enable NULL GPU - - - Enable PM4 Dumping - Enable PM4 Dumping - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Aktiver virtuel GPU:\nTil teknisk fejlfinding deaktiverer det spilvisning, som om der ikke var et grafikkort. - - - dumpPM4CheckBox - Aktiver dumping af PM4:\nTil teknisk fejlfinding gemmer det rå GPU-kommandoer i en mappe under behandling. - debugDump diff --git a/src/qt_gui/translations/de.ts b/src/qt_gui/translations/de.ts index 771d3bf8e..9e31afd6e 100644 --- a/src/qt_gui/translations/de.ts +++ b/src/qt_gui/translations/de.ts @@ -474,11 +474,6 @@ Enable NULL GPU NULL GPU aktivieren - - - Enable PM4 Dumping - PM4-Dumping aktivieren - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Virtuelle GPU aktivieren:\nFür das technische Debugging deaktiviert es die Spielanzeige, als ob keine Grafikkarte vorhanden wäre. - - - dumpPM4CheckBox - PM4-Dumping aktivieren:\nZum technischen Debuggen speichert es rohe GPU-Befehlsdaten in einem Ordner während der Verarbeitung. - debugDump diff --git a/src/qt_gui/translations/el.ts b/src/qt_gui/translations/el.ts index f2265c7d7..de10fc3a8 100644 --- a/src/qt_gui/translations/el.ts +++ b/src/qt_gui/translations/el.ts @@ -474,11 +474,6 @@ Enable NULL GPU Enable NULL GPU - - - Enable PM4 Dumping - Enable PM4 Dumping - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Ενεργοποίηση Εικονικής GPU:\nΓια τεχνικό εντοπισμό σφαλμάτων, απενεργοποιεί την εμφάνιση του παιχνιδιού σαν να μην υπάρχει κάρτα γραφικών. - - - dumpPM4CheckBox - Ενεργοποίηση Καταγραφής PM4:\nΓια τεχνικό εντοπισμό σφαλμάτων, αποθηκεύει τις ακατέργαστες εντολές της GPU σε φάκελο κατά την επεξεργασία. - debugDump diff --git a/src/qt_gui/translations/en.ts b/src/qt_gui/translations/en.ts index e45ac475a..4052b4ef5 100644 --- a/src/qt_gui/translations/en.ts +++ b/src/qt_gui/translations/en.ts @@ -474,11 +474,6 @@ Enable NULL GPU Enable NULL GPU - - - Enable PM4 Dumping - Enable PM4 Dumping - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Enable Null GPU:\nFor the sake of technical debugging, disables game rendering as if there were no graphics card. - - - dumpPM4CheckBox - Enable PM4 Dumping:\nFor the sake of technical debugging, saves raw GPU instruction data to a folder as the emulator processes it. - debugDump diff --git a/src/qt_gui/translations/es_ES.ts b/src/qt_gui/translations/es_ES.ts index 4242bc91e..86a3e1adc 100644 --- a/src/qt_gui/translations/es_ES.ts +++ b/src/qt_gui/translations/es_ES.ts @@ -474,11 +474,6 @@ Enable NULL GPU Habilitar GPU NULL - - - Enable PM4 Dumping - Habilitar volcado de PM4 - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Habilitar GPU Nula:\nPor el bien de la depuración técnica, desactiva el renderizado del juego como si no hubiera tarjeta gráfica. - - - dumpPM4CheckBox - Habilitar la Volcadura de PM4:\nPor el bien de la depuración técnica, guarda los datos de instrucciones crudas de GPU en una carpeta a medida que el emulador los procesa. - debugDump diff --git a/src/qt_gui/translations/fa_IR.ts b/src/qt_gui/translations/fa_IR.ts index 15e07c886..a613af70b 100644 --- a/src/qt_gui/translations/fa_IR.ts +++ b/src/qt_gui/translations/fa_IR.ts @@ -474,11 +474,6 @@ Enable NULL GPU NULL GPU فعال کردن - - - Enable PM4 Dumping - PM4 Dumping فعال کردن - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Enable Null GPU:\nFor the sake of technical debugging, disables game rendering as if there were no graphics card. - - - dumpPM4CheckBox - Enable PM4 Dumping:\nFor the sake of technical debugging, saves raw GPU instruction data to a folder as the emulator processes it. - debugDump diff --git a/src/qt_gui/translations/fi.ts b/src/qt_gui/translations/fi.ts index a2b319280..e4010b872 100644 --- a/src/qt_gui/translations/fi.ts +++ b/src/qt_gui/translations/fi.ts @@ -474,11 +474,6 @@ Enable NULL GPU Enable NULL GPU - - - Enable PM4 Dumping - Enable PM4 Dumping - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Ota Null GPU käyttöön:\nTeknistä vianetsintää varten pelin renderöinti estetään niin, että ikään kuin grafiikkakorttia ei olisi. - - - dumpPM4CheckBox - Ota PM4 dumpaus käyttöön:\nTeknistä vianetsintää varten raakoja GPU-ohjeita tallennetaan kansioon emulaattorin käsitellessä sitä. - debugDump diff --git a/src/qt_gui/translations/fr.ts b/src/qt_gui/translations/fr.ts index 05c70f195..b11b585c9 100644 --- a/src/qt_gui/translations/fr.ts +++ b/src/qt_gui/translations/fr.ts @@ -474,11 +474,6 @@ Enable NULL GPU NULL GPU - - - Enable PM4 Dumping - Dumper le PM4 - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Activer le GPU nul :\nPour le débogage technique, désactive le rendu du jeu comme s'il n'y avait pas de carte graphique. - - - dumpPM4CheckBox - Activer l'exportation PM4 :\nPour le débogage technique, enregistre les données brutes des instructions GPU dans un dossier pendant que l'émulateur les traite. - debugDump diff --git a/src/qt_gui/translations/hu_HU.ts b/src/qt_gui/translations/hu_HU.ts index fb348ee29..5986193c4 100644 --- a/src/qt_gui/translations/hu_HU.ts +++ b/src/qt_gui/translations/hu_HU.ts @@ -474,11 +474,6 @@ Enable NULL GPU NULL GPU Engedélyezése - - - Enable PM4 Dumping - PM4 Dumpolás Engedélyezése - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Null GPU engedélyezése:\nMűszaki hibaelhárítás céljából letiltja a játék renderelését, mintha nem lenne grafikus kártya. - - - dumpPM4CheckBox - PM4 dumpolás engedélyezése:\nMűszaki hibaelhárítás céljából a nyers GPU utasítási adatokat elmenti egy mappába, ahogy az emulátor feldolgozza őket. - debugDump diff --git a/src/qt_gui/translations/id.ts b/src/qt_gui/translations/id.ts index 86c58c6ce..274029bd0 100644 --- a/src/qt_gui/translations/id.ts +++ b/src/qt_gui/translations/id.ts @@ -474,11 +474,6 @@ Enable NULL GPU Enable NULL GPU - - - Enable PM4 Dumping - Enable PM4 Dumping - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Aktifkan GPU Null:\nUntuk tujuan debugging teknis, menonaktifkan rendering permainan seolah-olah tidak ada kartu grafis. - - - dumpPM4CheckBox - Aktifkan Pembuangan PM4:\nUntuk tujuan debugging teknis, menyimpan data instruksi GPU mentah ke folder saat emulator memprosesnya. - debugDump diff --git a/src/qt_gui/translations/it.ts b/src/qt_gui/translations/it.ts index f5ea9a65c..07976865c 100644 --- a/src/qt_gui/translations/it.ts +++ b/src/qt_gui/translations/it.ts @@ -474,11 +474,6 @@ Enable NULL GPU Abilita NULL GPU - - - Enable PM4 Dumping - Abilita Dump PM4 - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Abilita GPU Null:\nPer scopi di debug tecnico, disabilita il rendering del gioco come se non ci fosse alcuna scheda grafica. - - - dumpPM4CheckBox - Abilita Pompaggio PM4:\nPer scopi di debug tecnico, salva i dati delle istruzioni GPU grezze in una cartella mentre l'emulatore li elabora. - debugDump diff --git a/src/qt_gui/translations/ja_JP.ts b/src/qt_gui/translations/ja_JP.ts index 166100db6..c3444906b 100644 --- a/src/qt_gui/translations/ja_JP.ts +++ b/src/qt_gui/translations/ja_JP.ts @@ -474,11 +474,6 @@ Enable NULL GPU NULL GPUを有効にする - - - Enable PM4 Dumping - PM4ダンプを有効にする - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Null GPUを有効にする:\n技術的なデバッグの目的で、グラフィックスカードがないかのようにゲームのレンダリングを無効にします。 - - - dumpPM4CheckBox - PM4ダンプを有効にする:\n技術的なデバッグの目的で、エミュレーターが処理している間に生のGPU命令データをフォルダーに保存します。 - debugDump diff --git a/src/qt_gui/translations/ko_KR.ts b/src/qt_gui/translations/ko_KR.ts index 93ceb9e35..e816e2f4b 100644 --- a/src/qt_gui/translations/ko_KR.ts +++ b/src/qt_gui/translations/ko_KR.ts @@ -474,11 +474,6 @@ Enable NULL GPU Enable NULL GPU - - - Enable PM4 Dumping - Enable PM4 Dumping - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Enable Null GPU:\nFor the sake of technical debugging, disables game rendering as if there were no graphics card. - - - dumpPM4CheckBox - Enable PM4 Dumping:\nFor the sake of technical debugging, saves raw GPU instruction data to a folder as the emulator processes it. - debugDump diff --git a/src/qt_gui/translations/lt_LT.ts b/src/qt_gui/translations/lt_LT.ts index cac8ebbfc..d5b4ff3ad 100644 --- a/src/qt_gui/translations/lt_LT.ts +++ b/src/qt_gui/translations/lt_LT.ts @@ -474,11 +474,6 @@ Enable NULL GPU Enable NULL GPU - - - Enable PM4 Dumping - Enable PM4 Dumping - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Įjungti tuščią GPU:\nTechninio derinimo tikslais išjungia žaidimo renderiavimą, tarsi nebūtų grafikos plokštės. - - - dumpPM4CheckBox - Įjungti PM4 išmetimą:\nTechninio derinimo tikslais saugo žalius GPU nurodymų duomenis į aplanką, kai emuliatorius juos apdoroja. - debugDump diff --git a/src/qt_gui/translations/nb.ts b/src/qt_gui/translations/nb.ts index e0bc1a550..334600950 100644 --- a/src/qt_gui/translations/nb.ts +++ b/src/qt_gui/translations/nb.ts @@ -474,11 +474,6 @@ Enable NULL GPU Enable NULL GPU - - - Enable PM4 Dumping - Enable PM4 Dumping - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Aktiver Null GPU:\nFor teknisk feilsøking deaktiverer spillrendering som om det ikke var noe grafikkort. - - - dumpPM4CheckBox - Aktiver PM4 dumping:\nFor teknisk feilsøking lagrer rå GPU-instruksjonsdata i en mappe mens emulatoren behandler dem. - debugDump diff --git a/src/qt_gui/translations/nl.ts b/src/qt_gui/translations/nl.ts index 29a60ecc8..6e49d4640 100644 --- a/src/qt_gui/translations/nl.ts +++ b/src/qt_gui/translations/nl.ts @@ -474,11 +474,6 @@ Enable NULL GPU Enable NULL GPU - - - Enable PM4 Dumping - Enable PM4 Dumping - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Null GPU inschakelen:\nVoor technische foutopsporing schakelt de game-rendering uit alsof er geen grafische kaart is. - - - dumpPM4CheckBox - PM4 dumpen inschakelen:\nVoor technische foutopsporing slaat het ruwe GPU-instructiegegevens op in een map terwijl de emulator ze verwerkt. - debugDump diff --git a/src/qt_gui/translations/pl_PL.ts b/src/qt_gui/translations/pl_PL.ts index bd772b0fe..e95b8ba0c 100644 --- a/src/qt_gui/translations/pl_PL.ts +++ b/src/qt_gui/translations/pl_PL.ts @@ -474,11 +474,6 @@ Enable NULL GPU Wyłącz kartę graficzną - - - Enable PM4 Dumping - Włącz zgrywanie PM4 - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Włącz Null GPU:\nDla technicznego debugowania dezaktywuje renderowanie gry tak, jakby nie było karty graficznej. - - - dumpPM4CheckBox - Włącz zrzucanie PM4:\nDla technicznego debugowania zapisuje surowe dane instrukcji GPU w folderze, gdy emulator je przetwarza. - debugDump diff --git a/src/qt_gui/translations/pt_BR.ts b/src/qt_gui/translations/pt_BR.ts index 38836b1d0..e1570b2cd 100644 --- a/src/qt_gui/translations/pt_BR.ts +++ b/src/qt_gui/translations/pt_BR.ts @@ -474,11 +474,6 @@ Enable NULL GPU Ativar GPU NULA - - - Enable PM4 Dumping - Ativar Dumping de PM4 - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Ativar GPU NULA:\nDesativa a renderização do jogo para fins de depuração técnica, como se não houvesse nenhuma placa gráfica. - - - dumpPM4CheckBox - Ativar Dumping de PM4:\nArmazena os dados de instrução bruta da GPU em uma pasta enquanto o emulador os processa, para fins de depuração técnica. Recomendado deixar desativado. - debugDump diff --git a/src/qt_gui/translations/ro_RO.ts b/src/qt_gui/translations/ro_RO.ts index a5c3783bb..e98b7e5c9 100644 --- a/src/qt_gui/translations/ro_RO.ts +++ b/src/qt_gui/translations/ro_RO.ts @@ -474,11 +474,6 @@ Enable NULL GPU Enable NULL GPU - - - Enable PM4 Dumping - Enable PM4 Dumping - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Activează GPU Null:\nÎn scopuri de depanare tehnică, dezactivează redarea jocului ca și cum nu ar exista o placă grafică. - - - dumpPM4CheckBox - Activează salvarea PM4:\nÎn scopuri de depanare tehnică, salvează datele brute ale instrucțiunilor GPU într-un folder pe măsură ce emulatorul le procesează. - debugDump diff --git a/src/qt_gui/translations/ru_RU.ts b/src/qt_gui/translations/ru_RU.ts index 13cc49f20..aaff66ef9 100644 --- a/src/qt_gui/translations/ru_RU.ts +++ b/src/qt_gui/translations/ru_RU.ts @@ -474,11 +474,6 @@ Enable NULL GPU Включить NULL GPU - - - Enable PM4 Dumping - Включить дамп PM4 - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Включить NULL GPU:\nДля технической отладки отключает рендеринг игры так, как будто графической карты нет. - - - dumpPM4CheckBox - Включить дамп PM4:\nДля технической отладки сохраняет необработанные данные инструкций GPU в папку, пока эмулятор их обрабатывает. - debugDump diff --git a/src/qt_gui/translations/sq.ts b/src/qt_gui/translations/sq.ts index d9f1d3859..c6e4c018d 100644 --- a/src/qt_gui/translations/sq.ts +++ b/src/qt_gui/translations/sq.ts @@ -474,11 +474,6 @@ Enable NULL GPU Aktivizo GPU-në NULL - - - Enable PM4 Dumping - Aktivizo Zbrazjen PM4 - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Aktivizo GPU Null:\nPër qëllime të debugimit teknik, deaktivizon renditjen e lojës sikur nuk do të kishte një kartë grafike. - - - dumpPM4CheckBox - Aktivizo dump-in e PM4:\nPër qëllime të debugimit teknik, ruan të dhënat e instruksioneve të GPU-së në një folder ndërsa emulatori i përpunon ato. - debugDump diff --git a/src/qt_gui/translations/tr_TR.ts b/src/qt_gui/translations/tr_TR.ts index 32e5c4bd6..5cd71af34 100644 --- a/src/qt_gui/translations/tr_TR.ts +++ b/src/qt_gui/translations/tr_TR.ts @@ -474,11 +474,6 @@ Enable NULL GPU NULL GPU'yu Etkinleştir - - - Enable PM4 Dumping - PM4 Kaydını Etkinleştir - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Null GPU'yu Etkinleştir:\nTeknik hata ayıklama amacıyla, oyunun render edilmesini grafik kartı yokmuş gibi devre dışı bırakır. - - - dumpPM4CheckBox - PM4 Dışa Aktarmayı Etkinleştir:\nTeknik hata ayıklama amacıyla, emülatör bunları işlerken GPU komut verilerini bir klasöre kaydeder. - debugDump diff --git a/src/qt_gui/translations/vi_VN.ts b/src/qt_gui/translations/vi_VN.ts index 8f377f2a7..523683621 100644 --- a/src/qt_gui/translations/vi_VN.ts +++ b/src/qt_gui/translations/vi_VN.ts @@ -474,11 +474,6 @@ Enable NULL GPU Enable NULL GPU - - - Enable PM4 Dumping - Enable PM4 Dumping - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Bật GPU Null:\nĐể mục đích gỡ lỗi kỹ thuật, vô hiệu hóa việc kết xuất trò chơi như thể không có card đồ họa. - - - dumpPM4CheckBox - Bật xuất PM4:\nĐể mục đích gỡ lỗi kỹ thuật, lưu dữ liệu lệnh GPU vào một thư mục khi trình giả lập xử lý chúng. - debugDump diff --git a/src/qt_gui/translations/zh_CN.ts b/src/qt_gui/translations/zh_CN.ts index 0eae5a5bd..f2abc4f4b 100644 --- a/src/qt_gui/translations/zh_CN.ts +++ b/src/qt_gui/translations/zh_CN.ts @@ -474,11 +474,6 @@ Enable NULL GPU 启用 NULL GPU - - - Enable PM4 Dumping - 启用 PM4 转储 - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox 启用空 GPU:\n为了技术调试,将游戏渲染禁用,仿佛没有图形卡。 - - - dumpPM4CheckBox - 启用 PM4 转储:\n为了技术调试,在模拟器处理时将原始 GPU 指令数据保存到文件夹中。 - debugDump diff --git a/src/qt_gui/translations/zh_TW.ts b/src/qt_gui/translations/zh_TW.ts index cead22ecf..2d34f8d12 100644 --- a/src/qt_gui/translations/zh_TW.ts +++ b/src/qt_gui/translations/zh_TW.ts @@ -474,11 +474,6 @@ Enable NULL GPU Enable NULL GPU - - - Enable PM4 Dumping - Enable PM4 Dumping - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox 啟用空GPU:\n為了技術調試,禁用遊戲渲染,彷彿沒有顯示卡。 - - - dumpPM4CheckBox - 啟用PM4轉儲:\n為了技術調試,將原始GPU指令數據在模擬器處理時保存到文件夾中。 - debugDump From ce53c412050c39c161a2ce2f6e18bdf6a9554a27 Mon Sep 17 00:00:00 2001 From: fireph <443370+fireph@users.noreply.github.com> Date: Mon, 7 Oct 2024 23:15:30 -0700 Subject: [PATCH 7/9] Add support to click touchpad using back button on non PS4/5 controllers (#1258) * Working touchpad support Tested on PS5 controller plugged in via USB. * fix lint * Add support to click touchpad using back button on other controllers Takes the back button and allows the user to change the behavior of how it clicks the touchpad. The current options are left, right, center, and none. * add description text * make more generic so translations can be supported in combobox * fix lint * linter again * support back button to touchpad for spacebar as well * linter at it again --- README.md | 2 +- src/common/config.cpp | 12 ++++++++ src/common/config.h | 2 ++ src/qt_gui/settings_dialog.cpp | 24 ++++++++++++++++ src/qt_gui/settings_dialog.ui | 52 +++++++++++++++++++++++++--------- src/qt_gui/translations/en.ts | 35 +++++++++++++++++++++++ src/sdl_window.cpp | 26 +++++++++++++++-- 7 files changed, 136 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index da01833e5..95428dfd0 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ PAD DOWN | DOWN | PAD LEFT | LEFT | PAD RIGHT | RIGHT | OPTIONS | RETURN | -TOUCH PAD | SPACE | +BACK BUTTON / TOUCH PAD | SPACE | L1 | Q | R1 | U | L2 | E | diff --git a/src/common/config.cpp b/src/common/config.cpp index 8ac3c694b..8c1c4f79d 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -41,6 +41,7 @@ static std::string logFilter; static std::string logType = "async"; static std::string userName = "shadPS4"; static std::string updateChannel; +static std::string backButtonBehavior = "left"; static bool useSpecialPad = false; static int specialPadClass = 1; static bool isDebugDump = false; @@ -123,6 +124,10 @@ std::string getUpdateChannel() { return updateChannel; } +std::string getBackButtonBehavior() { + return backButtonBehavior; +} + bool getUseSpecialPad() { return useSpecialPad; } @@ -275,6 +280,10 @@ void setUpdateChannel(const std::string& type) { updateChannel = type; } +void setBackButtonBehavior(const std::string& type) { + backButtonBehavior = type; +} + void setUseSpecialPad(bool use) { useSpecialPad = use; } @@ -435,6 +444,7 @@ void load(const std::filesystem::path& path) { } isShowSplash = toml::find_or(general, "showSplash", true); isAutoUpdate = toml::find_or(general, "autoUpdate", false); + backButtonBehavior = toml::find_or(general, "backButtonBehavior", "left"); } if (data.contains("Input")) { @@ -533,6 +543,7 @@ void save(const std::filesystem::path& path) { data["General"]["updateChannel"] = updateChannel; data["General"]["showSplash"] = isShowSplash; data["General"]["autoUpdate"] = isAutoUpdate; + data["General"]["backButtonBehavior"] = backButtonBehavior; data["Input"]["useSpecialPad"] = useSpecialPad; data["Input"]["specialPadClass"] = specialPadClass; data["GPU"]["screenWidth"] = screenWidth; @@ -591,6 +602,7 @@ void setDefaultValues() { } else { updateChannel = "Nightly"; } + backButtonBehavior = "left"; useSpecialPad = false; specialPadClass = 1; isDebugDump = false; diff --git a/src/common/config.h b/src/common/config.h index daee9e078..4aad7bede 100644 --- a/src/common/config.h +++ b/src/common/config.h @@ -20,6 +20,7 @@ std::string getLogFilter(); std::string getLogType(); std::string getUserName(); std::string getUpdateChannel(); +std::string getBackButtonBehavior(); bool getUseSpecialPad(); int getSpecialPadClass(); @@ -54,6 +55,7 @@ void setLanguage(u32 language); void setNeoMode(bool enable); void setUserName(const std::string& type); void setUpdateChannel(const std::string& type); +void setBackButtonBehavior(const std::string& type); void setUseSpecialPad(bool use); void setSpecialPadClass(int type); diff --git a/src/qt_gui/settings_dialog.cpp b/src/qt_gui/settings_dialog.cpp index 1c0b0bc07..bcf5762f2 100644 --- a/src/qt_gui/settings_dialog.cpp +++ b/src/qt_gui/settings_dialog.cpp @@ -98,6 +98,15 @@ SettingsDialog::SettingsDialog(std::span physical_devices, QWidge ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)->setText(tr("Restore Defaults")); ui->buttonBox->button(QDialogButtonBox::Close)->setText(tr("Close")); + ui->backButtonBehaviorComboBox->addItem(tr("Touchpad Left"), "left"); + ui->backButtonBehaviorComboBox->addItem(tr("Touchpad Center"), "center"); + ui->backButtonBehaviorComboBox->addItem(tr("Touchpad Right"), "right"); + ui->backButtonBehaviorComboBox->addItem(tr("None"), "none"); + + QString currentBackButtonBehavior = QString::fromStdString(Config::getBackButtonBehavior()); + int index = ui->backButtonBehaviorComboBox->findData(currentBackButtonBehavior); + ui->backButtonBehaviorComboBox->setCurrentIndex(index != -1 ? index : 0); + connect(ui->tabWidgetSettings, &QTabWidget::currentChanged, this, [this]() { ui->buttonBox->button(QDialogButtonBox::Close)->setFocus(); }); @@ -151,6 +160,14 @@ SettingsDialog::SettingsDialog(std::span physical_devices, QWidge Config::setBGMvolume(val); BackgroundMusicPlayer::getInstance().setVolume(val); }); + + connect(ui->backButtonBehaviorComboBox, QOverload::of(&QComboBox::currentIndexChanged), + this, [this](int index) { + if (index >= 0 && index < ui->backButtonBehaviorComboBox->count()) { + QString data = ui->backButtonBehaviorComboBox->itemData(index).toString(); + Config::setBackButtonBehavior(data.toStdString()); + } + }); } // GPU TAB @@ -204,6 +221,7 @@ SettingsDialog::SettingsDialog(std::span physical_devices, QWidge ui->logFilter->installEventFilter(this); ui->updaterGroupBox->installEventFilter(this); ui->GUIgroupBox->installEventFilter(this); + ui->backButtonBehaviorGroupBox->installEventFilter(this); // Graphics ui->graphicsAdapterGroupBox->installEventFilter(this); @@ -258,6 +276,10 @@ void SettingsDialog::LoadValuesFromConfig() { } } ui->updateComboBox->setCurrentText(QString::fromStdString(updateChannel)); + + QString backButtonBehavior = QString::fromStdString(Config::getBackButtonBehavior()); + int index = ui->backButtonBehaviorComboBox->findData(backButtonBehavior); + ui->backButtonBehaviorComboBox->setCurrentIndex(index != -1 ? index : 0); } void SettingsDialog::InitializeEmulatorLanguages() { @@ -319,6 +341,8 @@ void SettingsDialog::updateNoteTextEdit(const QString& elementName) { text = tr("updaterGroupBox"); } else if (elementName == "GUIgroupBox") { text = tr("GUIgroupBox"); + } else if (elementName == "backButtonBehaviorGroupBox") { + text = tr("backButtonBehaviorGroupBox"); } // Graphics diff --git a/src/qt_gui/settings_dialog.ui b/src/qt_gui/settings_dialog.ui index 4edec9e1b..a6264af6f 100644 --- a/src/qt_gui/settings_dialog.ui +++ b/src/qt_gui/settings_dialog.ui @@ -442,20 +442,44 @@ - - - Qt::Orientation::Horizontal - - - QSizePolicy::Policy::Expanding - - - - 0 - 0 - - - + + + + + + 0 + 0 + + + + Controller Settings + + + + + 12 + 30 + 241 + 65 + + + + Back Button Behavior + + + + + 12 + 30 + 217 + 28 + + + + + + + diff --git a/src/qt_gui/translations/en.ts b/src/qt_gui/translations/en.ts index 4052b4ef5..18c54428f 100644 --- a/src/qt_gui/translations/en.ts +++ b/src/qt_gui/translations/en.ts @@ -534,6 +534,16 @@ Volume Volume + + + Controller Settings + Controller Settings + + + + Back Button Behavior + Back Button Behavior + MainWindow @@ -1023,6 +1033,31 @@ GUIgroupBox Play Title Music:\nIf a game supports it, enable playing special music when selecting the game in the GUI. + + + backButtonBehaviorGroupBox + Back Button Behavior:\nAllows setting which part of the touchpad the back button will emulate a touch on. + + + + Touchpad Left + Touchpad Left + + + + Touchpad Right + Touchpad Right + + + + Touchpad Center + Touchpad Center + + + + None + None + graphicsAdapterGroupBox diff --git a/src/sdl_window.cpp b/src/sdl_window.cpp index 4a4020a42..470f12de3 100644 --- a/src/sdl_window.cpp +++ b/src/sdl_window.cpp @@ -145,6 +145,7 @@ void WindowSDL::onKeyPress(const SDL_Event* event) { Input::Axis axis = Input::Axis::AxisMax; int axisvalue = 0; int ax = 0; + std::string backButtonBehavior = Config::getBackButtonBehavior(); switch (event->key.key) { case SDLK_UP: button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_UP; @@ -278,7 +279,15 @@ void WindowSDL::onKeyPress(const SDL_Event* event) { ax = Input::GetAxis(0, 0x80, axisvalue); break; case SDLK_SPACE: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_TOUCH_PAD; + if (backButtonBehavior != "none") { + float x = backButtonBehavior == "left" ? 0.25f + : (backButtonBehavior == "right" ? 0.75f : 0.5f); + // trigger a touchpad event so that the touchpad emulation for back button works + controller->SetTouchpadState(0, true, x, 0.5f); + button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_TOUCH_PAD; + } else { + button = 0; + } break; case SDLK_F11: if (event->type == SDL_EVENT_KEY_DOWN) { @@ -330,7 +339,20 @@ void WindowSDL::onGamepadEvent(const SDL_Event* event) { case SDL_EVENT_GAMEPAD_BUTTON_UP: button = sdlGamepadToOrbisButton(event->gbutton.button); if (button != 0) { - controller->CheckButton(0, button, event->type == SDL_EVENT_GAMEPAD_BUTTON_DOWN); + if (event->gbutton.button == SDL_GAMEPAD_BUTTON_BACK) { + std::string backButtonBehavior = Config::getBackButtonBehavior(); + if (backButtonBehavior != "none") { + float x = backButtonBehavior == "left" + ? 0.25f + : (backButtonBehavior == "right" ? 0.75f : 0.5f); + // trigger a touchpad event so that the touchpad emulation for back button works + controller->SetTouchpadState(0, true, x, 0.5f); + controller->CheckButton(0, button, + event->type == SDL_EVENT_GAMEPAD_BUTTON_DOWN); + } + } else { + controller->CheckButton(0, button, event->type == SDL_EVENT_GAMEPAD_BUTTON_DOWN); + } } if (SDL_GetCursor() != NULL) { SDL_HideCursor(); From 01fb320f4e6b47a6caacb9769ebb9ff8cb573df2 Mon Sep 17 00:00:00 2001 From: DanielSvoboda Date: Tue, 8 Oct 2024 03:15:50 -0300 Subject: [PATCH 8/9] Fixes encoding in update text (#1283) * Fixes encoding in update text * + --- src/qt_gui/check_update.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/qt_gui/check_update.cpp b/src/qt_gui/check_update.cpp index 48adbb88a..ca6009ca3 100644 --- a/src/qt_gui/check_update.cpp +++ b/src/qt_gui/check_update.cpp @@ -374,11 +374,17 @@ void CheckUpdate::Install() { QString userPath; Common::FS::PathToQString(userPath, Common::FS::GetUserPath(Common::FS::PathType::UserDir)); - QString startingUpdate = tr("Starting Update..."); - QString tempDirPath = userPath + "/temp_download_update"; QString rootPath; Common::FS::PathToQString(rootPath, std::filesystem::current_path()); + QString tempDirPath = userPath + "/temp_download_update"; + QString startingUpdate = tr("Starting Update..."); + + QString binaryStartingUpdate; + for (QChar c : startingUpdate) { + binaryStartingUpdate.append(QString::number(c.unicode(), 2).rightJustified(16, '0')); + } + QString scriptContent; QString scriptFileName; QStringList arguments; @@ -389,7 +395,13 @@ void CheckUpdate::Install() { scriptFileName = tempDirPath + "/update.ps1"; scriptContent = QStringLiteral( "Set-ExecutionPolicy Bypass -Scope Process -Force\n" - "Write-Output '%1'\n" + "$binaryStartingUpdate = '%1'\n" + "$chars = @()\n" + "for ($i = 0; $i -lt $binaryStartingUpdate.Length; $i += 16) {\n" + " $chars += [char]([convert]::ToInt32($binaryStartingUpdate.Substring($i, 16), 2))\n" + "}\n" + "$startingUpdate = -join $chars\n" + "Write-Output $startingUpdate\n" "Expand-Archive -Path '%2\\temp_download_update.zip' -DestinationPath '%2' -Force\n" "Start-Sleep -Seconds 3\n" "Copy-Item -Recurse -Force '%2\\*' '%3\\'\n" @@ -512,7 +524,12 @@ void CheckUpdate::Install() { QFile scriptFile(scriptFileName); if (scriptFile.open(QIODevice::WriteOnly | QIODevice::Text)) { QTextStream out(&scriptFile); +#ifdef Q_OS_WIN + out << scriptContent.arg(binaryStartingUpdate).arg(tempDirPath).arg(rootPath); +#endif +#if defined(Q_OS_LINUX) || defined(Q_OS_MAC) out << scriptContent.arg(startingUpdate).arg(tempDirPath).arg(rootPath); +#endif scriptFile.close(); // Make the script executable on Unix-like systems From 96344873d649663cd4c35c4f3079a6f2415968eb Mon Sep 17 00:00:00 2001 From: Vinicius Rangel Date: Tue, 8 Oct 2024 03:16:06 -0300 Subject: [PATCH 9/9] SaveDataLib: use param.sfo to store max_blocks instead of txt (#1287) --- src/core/file_format/psf.cpp | 6 ++++ src/core/file_format/psf.h | 1 + .../libraries/save_data/save_instance.cpp | 32 ++++++++----------- src/core/libraries/save_data/save_instance.h | 2 +- src/core/libraries/save_data/savedata.cpp | 7 ++-- 5 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/core/file_format/psf.cpp b/src/core/file_format/psf.cpp index a5e502f98..0502f29d2 100644 --- a/src/core/file_format/psf.cpp +++ b/src/core/file_format/psf.cpp @@ -227,6 +227,12 @@ void PSF::AddBinary(std::string key, std::vector value, bool update) { map_binaries.emplace(entry_list.size() - 1, std::move(value)); } +void PSF::AddBinary(std::string key, uint64_t value, bool update) { + std::vector data(8); + std::memcpy(data.data(), &value, 8); + return AddBinary(std::move(key), std::move(data), update); +} + void PSF::AddString(std::string key, std::string value, bool update) { auto [it, index] = FindEntry(key); bool exist = it != entry_list.end(); diff --git a/src/core/file_format/psf.h b/src/core/file_format/psf.h index d25b79eec..6f35fa69a 100644 --- a/src/core/file_format/psf.h +++ b/src/core/file_format/psf.h @@ -67,6 +67,7 @@ public: std::optional GetInteger(std::string_view key) const; void AddBinary(std::string key, std::vector value, bool update = false); + void AddBinary(std::string key, uint64_t value, bool update = false); // rsv4 format void AddString(std::string key, std::string value, bool update = false); void AddInteger(std::string key, s32 value, bool update = false); diff --git a/src/core/libraries/save_data/save_instance.cpp b/src/core/libraries/save_data/save_instance.cpp index 1127a5452..0d6c5173c 100644 --- a/src/core/libraries/save_data/save_instance.cpp +++ b/src/core/libraries/save_data/save_instance.cpp @@ -12,9 +12,9 @@ #include "core/file_sys/fs.h" #include "save_instance.h" -constexpr u32 OrbisSaveDataBlocksMax = 32768; // 1 GiB +constexpr auto OrbisSaveDataBlocksMin2 = 96; // 3MiB +constexpr auto OrbisSaveDataBlocksMax = 32768; // 1 GiB constexpr std::string_view sce_sys = "sce_sys"; // system folder inside save -constexpr std::string_view max_block_file_name = "max_block.txt"; static Core::FileSys::MntPoints* g_mnt = Common::Singleton::Instance(); @@ -58,18 +58,13 @@ std::filesystem::path SaveInstance::MakeDirSavePath(OrbisUserServiceUserId user_ game_serial / dir_name; } -int SaveInstance::GetMaxBlocks(const std::filesystem::path& save_path) { - Common::FS::IOFile max_blocks_file{save_path / sce_sys / max_block_file_name, - Common::FS::FileAccessMode::Read}; - int max_blocks = 0; - if (max_blocks_file.IsOpen()) { - max_blocks = std::atoi(max_blocks_file.ReadString(16).c_str()); +uint64_t SaveInstance::GetMaxBlockFromSFO(const PSF& psf) { + const auto vec = psf.GetBinary(std::string{SaveParams::SAVEDATA_BLOCKS}); + if (!vec.has_value()) { + return OrbisSaveDataBlocksMax; } - if (max_blocks <= 0) { - max_blocks = OrbisSaveDataBlocksMax; - } - - return max_blocks; + auto value = vec.value(); + return *(uint64_t*)value.data(); } std::filesystem::path SaveInstance::GetParamSFOPath(const std::filesystem::path& dir_path) { @@ -92,13 +87,15 @@ void SaveInstance::SetupDefaultParamSFO(PSF& param_sfo, std::string dir_name, P(String, SaveParams::SAVEDATA_DIRECTORY, std::move(dir_name)); P(Integer, SaveParams::SAVEDATA_LIST_PARAM, 0); P(String, SaveParams::TITLE_ID, std::move(game_serial)); + P(Binary, SaveParams::SAVEDATA_BLOCKS, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); #undef P } SaveInstance::SaveInstance(int slot_num, OrbisUserServiceUserId user_id, std::string _game_serial, std::string_view _dir_name, int max_blocks) : slot_num(slot_num), user_id(user_id), game_serial(std::move(_game_serial)), - dir_name(_dir_name), max_blocks(max_blocks) { + dir_name(_dir_name), + max_blocks(std::clamp(max_blocks, OrbisSaveDataBlocksMin2, OrbisSaveDataBlocksMax)) { ASSERT(slot_num >= 0 && slot_num < 16); save_path = MakeDirSavePath(user_id, game_serial, dir_name); @@ -187,7 +184,7 @@ void SaveInstance::SetupAndMount(bool read_only, bool copy_icon, bool ignore_cor } } - max_blocks = GetMaxBlocks(save_path); + max_blocks = static_cast(GetMaxBlockFromSFO(param_sfo)); g_mnt->Mount(save_path, mount_point, read_only); mounted = true; @@ -217,16 +214,13 @@ void SaveInstance::CreateFiles() { fs::create_directories(sce_sys_dir); SetupDefaultParamSFO(param_sfo, dir_name, game_serial); + param_sfo.AddBinary(std::string{SaveParams::SAVEDATA_BLOCKS}, max_blocks, true); const bool ok = param_sfo.Encode(param_sfo_path); if (!ok) { throw std::filesystem::filesystem_error("Failed to write param.sfo", param_sfo_path, std::make_error_code(std::errc::permission_denied)); } - - Common::FS::IOFile max_block{sce_sys_dir / max_block_file_name, - Common::FS::FileAccessMode::Write}; - max_block.WriteString(std::to_string(max_blocks == 0 ? OrbisSaveDataBlocksMax : max_blocks)); } } // namespace Libraries::SaveData \ No newline at end of file diff --git a/src/core/libraries/save_data/save_instance.h b/src/core/libraries/save_data/save_instance.h index f07011047..3be5c4595 100644 --- a/src/core/libraries/save_data/save_instance.h +++ b/src/core/libraries/save_data/save_instance.h @@ -62,7 +62,7 @@ public: std::string_view game_serial, std::string_view dir_name); - static int GetMaxBlocks(const std::filesystem::path& save_path); + static uint64_t GetMaxBlockFromSFO(const PSF& psf); // Get param.sfo path from a dir_path generated by MakeDirSavePath static std::filesystem::path GetParamSFOPath(const std::filesystem::path& dir_path); diff --git a/src/core/libraries/save_data/savedata.cpp b/src/core/libraries/save_data/savedata.cpp index a2af2f159..93b3c20a9 100644 --- a/src/core/libraries/save_data/savedata.cpp +++ b/src/core/libraries/save_data/savedata.cpp @@ -445,7 +445,7 @@ static Error saveDataMount(const OrbisSaveDataMount2* mount_info, fs::create_directories(root_save); const auto available = fs::space(root_save).available; - auto requested_size = mount_info->blocks * OrbisSaveDataBlockSize; + auto requested_size = save_instance.GetMaxBlocks() * OrbisSaveDataBlockSize; if (requested_size > available) { mount_result->required_blocks = (requested_size - available) / OrbisSaveDataBlockSize; return Error::NO_SPACE_FS; @@ -830,10 +830,11 @@ Error PS4_SYSV_ABI sceSaveDataDirNameSearch(const OrbisSaveDataDirNameSearchCond LOG_ERROR(Lib_SaveData, "Failed to read SFO: {}", fmt::UTF(sfo_path.u8string())); ASSERT_MSG(false, "Failed to read SFO"); } - map_dir_sfo.emplace(dir_name, std::move(sfo)); size_t size = Common::FS::GetDirectorySize(dir_path); - size_t total = SaveInstance::GetMaxBlocks(dir_path); + size_t total = SaveInstance::GetMaxBlockFromSFO(sfo); + + map_dir_sfo.emplace(dir_name, std::move(sfo)); map_free_size.emplace(dir_name, total - size / OrbisSaveDataBlockSize); map_max_blocks.emplace(dir_name, total); }