mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-01-31 01:15:24 +01:00
Compare commits
48 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37555e3048 | ||
|
|
d8f18a3318 | ||
|
|
47a732d0fe | ||
|
|
4eae1b7127 | ||
|
|
a71ea9917a | ||
|
|
500e2c43b1 | ||
|
|
e6a4cee86c | ||
|
|
5a94f6819d | ||
|
|
132e3e507d | ||
|
|
ffa06fbb09 | ||
|
|
028e6cd8a8 | ||
|
|
719063e996 | ||
|
|
5d40f36fa8 | ||
|
|
31ffcfc920 | ||
|
|
c9642b70f6 | ||
|
|
849fa57bf6 | ||
|
|
2c95ef76f1 | ||
|
|
4d9cb885b2 | ||
|
|
e375f98f7a | ||
|
|
1b80f3aea2 | ||
|
|
b0496645f1 | ||
|
|
235cb13647 | ||
|
|
504dd9f513 | ||
|
|
e3fedf1676 | ||
|
|
f113a51783 | ||
|
|
f69d5835b8 | ||
|
|
8e8277c0c9 | ||
|
|
c6c4eaf31c | ||
|
|
6324722b65 | ||
|
|
efd8c9ec69 | ||
|
|
9858aa1aa5 | ||
|
|
256a946f96 | ||
|
|
a507964f33 | ||
|
|
7584a6bb29 | ||
|
|
ce6103be30 | ||
|
|
9da4459ab3 | ||
|
|
3b9b9a84cd | ||
|
|
cce0ae4369 | ||
|
|
efb43ac7f9 | ||
|
|
8132a8a7f8 | ||
|
|
9c753cb692 | ||
|
|
514e6675c4 | ||
|
|
18454fd5d0 | ||
|
|
eeb919325e | ||
|
|
959be142ed | ||
|
|
42be91d48d | ||
|
|
908f916656 | ||
|
|
5441c7ed59 |
2
.github/workflows/linux_build_flatpak.yml
vendored
2
.github/workflows/linux_build_flatpak.yml
vendored
@@ -108,7 +108,7 @@ jobs:
|
||||
branch: beta
|
||||
cache: true
|
||||
restore-cache: true
|
||||
cache-key: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.compiler }} flatpak ${{ hashFiles('.github/workflows/scripts/linux/flatpak/**/*.json') }}
|
||||
cache-key: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.compiler }} flatpak ${{ hashFiles('.github/workflows/scripts/linux/flatpak/**/*.json', '.github/workflows/scripts/common/*.patch') }}
|
||||
|
||||
- name: Build Flatpak (stable)
|
||||
if: ${{ inputs.stableBuild == true || inputs.stableBuild == 'true' }}
|
||||
|
||||
2
.github/workflows/linux_build_qt.yml
vendored
2
.github/workflows/linux_build_qt.yml
vendored
@@ -117,7 +117,7 @@ jobs:
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/deps
|
||||
key: ${{ inputs.os }} ${{ inputs.platform }} deps ${{ hashFiles('.github/workflows/scripts/linux/build-dependencies-qt.sh') }}
|
||||
key: ${{ inputs.os }} ${{ inputs.platform }} deps ${{ hashFiles('.github/workflows/scripts/linux/build-dependencies-qt.sh', '.github/workflows/scripts/common/*.patch') }}
|
||||
|
||||
- name: Build Dependencies
|
||||
if: steps.cache-deps.outputs.cache-hit != 'true'
|
||||
|
||||
2
.github/workflows/macos_build.yml
vendored
2
.github/workflows/macos_build.yml
vendored
@@ -85,7 +85,7 @@ jobs:
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/deps
|
||||
key: ${{ inputs.os }} deps ${{ hashFiles('.github/workflows/scripts/macos/build-dependencies.sh') }}
|
||||
key: ${{ inputs.os }} deps ${{ hashFiles('.github/workflows/scripts/macos/build-dependencies.sh', '.github/workflows/scripts/common/*.patch') }}
|
||||
|
||||
- name: Build Dependencies
|
||||
if: steps.cache-deps.outputs.cache-hit != 'true'
|
||||
|
||||
@@ -114,6 +114,15 @@ diff --git a/libshaderc/include/shaderc/shaderc.h b/libshaderc/include/shaderc/s
|
||||
index 3a3e97d..65d5b77 100644
|
||||
--- a/libshaderc/include/shaderc/shaderc.h
|
||||
+++ b/libshaderc/include/shaderc/shaderc.h
|
||||
@@ -15,6 +15,8 @@
|
||||
#ifndef SHADERC_SHADERC_H_
|
||||
#define SHADERC_SHADERC_H_
|
||||
|
||||
+#define SHADERC_PCSX2_CUSTOM 1
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -317,7 +317,7 @@ SHADERC_EXPORT void shaderc_compile_options_set_source_language(
|
||||
|
||||
// Sets the compiler mode to generate debug information in the output.
|
||||
@@ -123,69 +132,6 @@ index 3a3e97d..65d5b77 100644
|
||||
|
||||
// Sets the compiler optimization level to the given level. Only the last one
|
||||
// takes effect if multiple calls of this function exist.
|
||||
@@ -506,6 +506,10 @@ SHADERC_EXPORT void shaderc_compile_options_set_invert_y(
|
||||
SHADERC_EXPORT void shaderc_compile_options_set_nan_clamp(
|
||||
shaderc_compile_options_t options, bool enable);
|
||||
|
||||
+// Returns a string representation of the specified compilation status.
|
||||
+SHADERC_EXPORT const char* shaderc_compilation_status_to_string(
|
||||
+ shaderc_compilation_status status);
|
||||
+
|
||||
// An opaque handle to the results of a call to any shaderc_compile_into_*()
|
||||
// function.
|
||||
typedef struct shaderc_compilation_result* shaderc_compilation_result_t;
|
||||
@@ -529,28 +533,31 @@ typedef struct shaderc_compilation_result* shaderc_compilation_result_t;
|
||||
// present. May be safely called from multiple threads without explicit
|
||||
// synchronization. If there was failure in allocating the compiler object,
|
||||
// null will be returned.
|
||||
-SHADERC_EXPORT shaderc_compilation_result_t shaderc_compile_into_spv(
|
||||
+SHADERC_EXPORT shaderc_compilation_status shaderc_compile_into_spv(
|
||||
const shaderc_compiler_t compiler, const char* source_text,
|
||||
size_t source_text_size, shaderc_shader_kind shader_kind,
|
||||
const char* input_file_name, const char* entry_point_name,
|
||||
- const shaderc_compile_options_t additional_options);
|
||||
+ const shaderc_compile_options_t additional_options,
|
||||
+ shaderc_compilation_result_t* result);
|
||||
|
||||
// Like shaderc_compile_into_spv, but the result contains SPIR-V assembly text
|
||||
// instead of a SPIR-V binary module. The SPIR-V assembly syntax is as defined
|
||||
// by the SPIRV-Tools open source project.
|
||||
-SHADERC_EXPORT shaderc_compilation_result_t shaderc_compile_into_spv_assembly(
|
||||
+SHADERC_EXPORT shaderc_compilation_status shaderc_compile_into_spv_assembly(
|
||||
const shaderc_compiler_t compiler, const char* source_text,
|
||||
size_t source_text_size, shaderc_shader_kind shader_kind,
|
||||
const char* input_file_name, const char* entry_point_name,
|
||||
- const shaderc_compile_options_t additional_options);
|
||||
+ const shaderc_compile_options_t additional_options,
|
||||
+ shaderc_compilation_result_t* result);
|
||||
|
||||
// Like shaderc_compile_into_spv, but the result contains preprocessed source
|
||||
// code instead of a SPIR-V binary module
|
||||
-SHADERC_EXPORT shaderc_compilation_result_t shaderc_compile_into_preprocessed_text(
|
||||
+SHADERC_EXPORT shaderc_compilation_status shaderc_compile_into_preprocessed_text(
|
||||
const shaderc_compiler_t compiler, const char* source_text,
|
||||
size_t source_text_size, shaderc_shader_kind shader_kind,
|
||||
const char* input_file_name, const char* entry_point_name,
|
||||
- const shaderc_compile_options_t additional_options);
|
||||
+ const shaderc_compile_options_t additional_options,
|
||||
+ shaderc_compilation_result_t* result);
|
||||
|
||||
// Takes an assembly string of the format defined in the SPIRV-Tools project
|
||||
// (https://github.com/KhronosGroup/SPIRV-Tools/blob/master/syntax.md),
|
||||
@@ -561,10 +568,11 @@ SHADERC_EXPORT shaderc_compilation_result_t shaderc_compile_into_preprocessed_te
|
||||
// May be safely called from multiple threads without explicit synchronization.
|
||||
// If there was failure in allocating the compiler object, null will be
|
||||
// returned.
|
||||
-SHADERC_EXPORT shaderc_compilation_result_t shaderc_assemble_into_spv(
|
||||
+SHADERC_EXPORT shaderc_compilation_status shaderc_assemble_into_spv(
|
||||
const shaderc_compiler_t compiler, const char* source_assembly,
|
||||
size_t source_assembly_size,
|
||||
- const shaderc_compile_options_t additional_options);
|
||||
+ const shaderc_compile_options_t additional_options,
|
||||
+ shaderc_compilation_result_t* result);
|
||||
|
||||
// The following functions, operating on shaderc_compilation_result_t objects,
|
||||
// offer only the basic thread-safety guarantee.
|
||||
diff --git a/libshaderc/include/shaderc/shaderc.hpp b/libshaderc/include/shaderc/shaderc.hpp
|
||||
index 3817af8..5592b49 100644
|
||||
--- a/libshaderc/include/shaderc/shaderc.hpp
|
||||
@@ -202,119 +148,6 @@ index 3817af8..5592b49 100644
|
||||
}
|
||||
|
||||
// Sets the compiler optimization level to the given level. Only the last one
|
||||
@@ -425,9 +426,10 @@ class Compiler {
|
||||
const char* input_file_name,
|
||||
const char* entry_point_name,
|
||||
const CompileOptions& options) const {
|
||||
- shaderc_compilation_result_t compilation_result = shaderc_compile_into_spv(
|
||||
+ shaderc_compilation_result_t compilation_result = nullptr;
|
||||
+ shaderc_compile_into_spv(
|
||||
compiler_, source_text, source_text_size, shader_kind, input_file_name,
|
||||
- entry_point_name, options.options_);
|
||||
+ entry_point_name, options.options_, &compilation_result);
|
||||
return SpvCompilationResult(compilation_result);
|
||||
}
|
||||
|
||||
@@ -451,9 +453,10 @@ class Compiler {
|
||||
size_t source_text_size,
|
||||
shaderc_shader_kind shader_kind,
|
||||
const char* input_file_name) const {
|
||||
- shaderc_compilation_result_t compilation_result =
|
||||
- shaderc_compile_into_spv(compiler_, source_text, source_text_size,
|
||||
- shader_kind, input_file_name, "main", nullptr);
|
||||
+ shaderc_compilation_result_t compilation_result = nullptr;
|
||||
+ shaderc_compile_into_spv(compiler_, source_text, source_text_size,
|
||||
+ shader_kind, input_file_name, "main", nullptr,
|
||||
+ &compilation_result);
|
||||
return SpvCompilationResult(compilation_result);
|
||||
}
|
||||
|
||||
@@ -504,8 +507,11 @@ class Compiler {
|
||||
SpvCompilationResult AssembleToSpv(const char* source_assembly,
|
||||
size_t source_assembly_size,
|
||||
const CompileOptions& options) const {
|
||||
- return SpvCompilationResult(shaderc_assemble_into_spv(
|
||||
- compiler_, source_assembly, source_assembly_size, options.options_));
|
||||
+ shaderc_compilation_result_t compilation_result = nullptr;
|
||||
+ shaderc_assemble_into_spv(
|
||||
+ compiler_, source_assembly, source_assembly_size, options.options_,
|
||||
+ &compilation_result);
|
||||
+ return SpvCompilationResult(compilation_result);
|
||||
}
|
||||
|
||||
// Assembles the given SPIR-V assembly and returns a SPIR-V binary module
|
||||
@@ -513,8 +519,11 @@ class Compiler {
|
||||
// Like the first AssembleToSpv method but uses the default compiler options.
|
||||
SpvCompilationResult AssembleToSpv(const char* source_assembly,
|
||||
size_t source_assembly_size) const {
|
||||
- return SpvCompilationResult(shaderc_assemble_into_spv(
|
||||
- compiler_, source_assembly, source_assembly_size, nullptr));
|
||||
+ shaderc_compilation_result_t compilation_result = nullptr;
|
||||
+ shaderc_assemble_into_spv(
|
||||
+ compiler_, source_assembly, source_assembly_size, nullptr,
|
||||
+ &compilation_result);
|
||||
+ return SpvCompilationResult(compilation_result);
|
||||
}
|
||||
|
||||
// Assembles the given SPIR-V assembly and returns a SPIR-V binary module
|
||||
@@ -523,9 +532,11 @@ class Compiler {
|
||||
// std::string.
|
||||
SpvCompilationResult AssembleToSpv(const std::string& source_assembly,
|
||||
const CompileOptions& options) const {
|
||||
- return SpvCompilationResult(
|
||||
- shaderc_assemble_into_spv(compiler_, source_assembly.data(),
|
||||
- source_assembly.size(), options.options_));
|
||||
+ shaderc_compilation_result_t compilation_result = nullptr;
|
||||
+ shaderc_assemble_into_spv(
|
||||
+ compiler_, source_assembly.data(), source_assembly.size(),
|
||||
+ options.options_, &compilation_result);
|
||||
+ return SpvCompilationResult(compilation_result);
|
||||
}
|
||||
|
||||
// Assembles the given SPIR-V assembly and returns a SPIR-V binary module
|
||||
@@ -533,8 +544,10 @@ class Compiler {
|
||||
// Like the first AssembleToSpv method but the source is provided as a
|
||||
// std::string and also uses default compiler options.
|
||||
SpvCompilationResult AssembleToSpv(const std::string& source_assembly) const {
|
||||
- return SpvCompilationResult(shaderc_assemble_into_spv(
|
||||
- compiler_, source_assembly.data(), source_assembly.size(), nullptr));
|
||||
+ shaderc_compilation_result_t compilation_result = nullptr;
|
||||
+ shaderc_assemble_into_spv(compiler_, source_assembly.data(),
|
||||
+ source_assembly.size(), nullptr, &compilation_result);
|
||||
+ return SpvCompilationResult(compilation_result);
|
||||
}
|
||||
|
||||
// Compiles the given source GLSL and returns the SPIR-V assembly text
|
||||
@@ -544,10 +557,11 @@ class Compiler {
|
||||
const char* source_text, size_t source_text_size,
|
||||
shaderc_shader_kind shader_kind, const char* input_file_name,
|
||||
const char* entry_point_name, const CompileOptions& options) const {
|
||||
- shaderc_compilation_result_t compilation_result =
|
||||
- shaderc_compile_into_spv_assembly(
|
||||
- compiler_, source_text, source_text_size, shader_kind,
|
||||
- input_file_name, entry_point_name, options.options_);
|
||||
+ shaderc_compilation_result_t compilation_result = nullptr;
|
||||
+ shaderc_compile_into_spv_assembly(
|
||||
+ compiler_, source_text, source_text_size, shader_kind,
|
||||
+ input_file_name, entry_point_name, options.options_,
|
||||
+ &compilation_result);
|
||||
return AssemblyCompilationResult(compilation_result);
|
||||
}
|
||||
|
||||
@@ -592,10 +606,10 @@ class Compiler {
|
||||
const char* source_text, size_t source_text_size,
|
||||
shaderc_shader_kind shader_kind, const char* input_file_name,
|
||||
const CompileOptions& options) const {
|
||||
- shaderc_compilation_result_t compilation_result =
|
||||
- shaderc_compile_into_preprocessed_text(
|
||||
+ shaderc_compilation_result_t compilation_result;
|
||||
+ shaderc_compile_into_preprocessed_text(
|
||||
compiler_, source_text, source_text_size, shader_kind,
|
||||
- input_file_name, "main", options.options_);
|
||||
+ input_file_name, "main", options.options_, &compilation_result);
|
||||
return PreprocessedSourceCompilationResult(compilation_result);
|
||||
}
|
||||
|
||||
diff --git a/libshaderc/src/shaderc.cc b/libshaderc/src/shaderc.cc
|
||||
index 63f1bbc..c1a9b12 100644
|
||||
--- a/libshaderc/src/shaderc.cc
|
||||
@@ -334,146 +167,6 @@ index 63f1bbc..c1a9b12 100644
|
||||
}
|
||||
|
||||
void shaderc_compile_options_set_optimization_level(
|
||||
@@ -591,8 +595,31 @@ void shaderc_compiler_release(shaderc_compiler_t compiler) {
|
||||
delete compiler;
|
||||
}
|
||||
|
||||
+const char* shaderc_compilation_status_to_string(shaderc_compilation_status status)
|
||||
+{
|
||||
+ static constexpr const std::pair<shaderc_compilation_status, const char*> status_names[] = {
|
||||
+ {shaderc_compilation_status_success, "shaderc_compilation_status_success"},
|
||||
+ {shaderc_compilation_status_invalid_stage, "shaderc_compilation_status_invalid_stage"},
|
||||
+ {shaderc_compilation_status_compilation_error, "shaderc_compilation_status_compilation_error"},
|
||||
+ {shaderc_compilation_status_internal_error, "shaderc_compilation_status_internal_error"},
|
||||
+ {shaderc_compilation_status_null_result_object, "shaderc_compilation_status_null_result_object"},
|
||||
+ {shaderc_compilation_status_invalid_assembly, "shaderc_compilation_status_invalid_assembly"},
|
||||
+ {shaderc_compilation_status_validation_error, "shaderc_compilation_status_validation_error"},
|
||||
+ {shaderc_compilation_status_transformation_error, "shaderc_compilation_status_transformation_error"},
|
||||
+ {shaderc_compilation_status_configuration_error, "shaderc_compilation_status_configuration_error"},
|
||||
+ };
|
||||
+
|
||||
+ for (const auto& it : status_names)
|
||||
+ {
|
||||
+ if (status == it.first)
|
||||
+ return it.second;
|
||||
+ }
|
||||
+
|
||||
+ return "shaderc_compilation_status_unknown";
|
||||
+}
|
||||
+
|
||||
namespace {
|
||||
-shaderc_compilation_result_t CompileToSpecifiedOutputType(
|
||||
+shaderc_compilation_result_vector* CompileToSpecifiedOutputType(
|
||||
const shaderc_compiler_t compiler, const char* source_text,
|
||||
size_t source_text_size, shaderc_shader_kind shader_kind,
|
||||
const char* input_file_name, const char* entry_point_name,
|
||||
@@ -669,48 +696,59 @@ shaderc_compilation_result_t CompileToSpecifiedOutputType(
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
-shaderc_compilation_result_t shaderc_compile_into_spv(
|
||||
+shaderc_compilation_status shaderc_compile_into_spv(
|
||||
const shaderc_compiler_t compiler, const char* source_text,
|
||||
size_t source_text_size, shaderc_shader_kind shader_kind,
|
||||
const char* input_file_name, const char* entry_point_name,
|
||||
- const shaderc_compile_options_t additional_options) {
|
||||
- return CompileToSpecifiedOutputType(
|
||||
+ const shaderc_compile_options_t additional_options,
|
||||
+ shaderc_compilation_result_t* result) {
|
||||
+ shaderc_compilation_result_vector* resultv = CompileToSpecifiedOutputType(
|
||||
compiler, source_text, source_text_size, shader_kind, input_file_name,
|
||||
entry_point_name, additional_options,
|
||||
shaderc_util::Compiler::OutputType::SpirvBinary);
|
||||
+ *result = resultv;
|
||||
+ return resultv ? resultv->compilation_status : shaderc_compilation_status_internal_error;
|
||||
}
|
||||
|
||||
-shaderc_compilation_result_t shaderc_compile_into_spv_assembly(
|
||||
+shaderc_compilation_status shaderc_compile_into_spv_assembly(
|
||||
const shaderc_compiler_t compiler, const char* source_text,
|
||||
size_t source_text_size, shaderc_shader_kind shader_kind,
|
||||
const char* input_file_name, const char* entry_point_name,
|
||||
- const shaderc_compile_options_t additional_options) {
|
||||
- return CompileToSpecifiedOutputType(
|
||||
+ const shaderc_compile_options_t additional_options,
|
||||
+ shaderc_compilation_result_t* result) {
|
||||
+ shaderc_compilation_result_vector* resultv = CompileToSpecifiedOutputType(
|
||||
compiler, source_text, source_text_size, shader_kind, input_file_name,
|
||||
entry_point_name, additional_options,
|
||||
shaderc_util::Compiler::OutputType::SpirvAssemblyText);
|
||||
+ *result = resultv;
|
||||
+ return resultv ? resultv->compilation_status : shaderc_compilation_status_internal_error;
|
||||
}
|
||||
|
||||
-shaderc_compilation_result_t shaderc_compile_into_preprocessed_text(
|
||||
+shaderc_compilation_status shaderc_compile_into_preprocessed_text(
|
||||
const shaderc_compiler_t compiler, const char* source_text,
|
||||
size_t source_text_size, shaderc_shader_kind shader_kind,
|
||||
const char* input_file_name, const char* entry_point_name,
|
||||
- const shaderc_compile_options_t additional_options) {
|
||||
- return CompileToSpecifiedOutputType(
|
||||
+ const shaderc_compile_options_t additional_options,
|
||||
+ shaderc_compilation_result_t* result) {
|
||||
+ shaderc_compilation_result_vector* resultv = CompileToSpecifiedOutputType(
|
||||
compiler, source_text, source_text_size, shader_kind, input_file_name,
|
||||
entry_point_name, additional_options,
|
||||
shaderc_util::Compiler::OutputType::PreprocessedText);
|
||||
+ *result = resultv;
|
||||
+ return resultv ? resultv->compilation_status : shaderc_compilation_status_internal_error;
|
||||
}
|
||||
|
||||
-shaderc_compilation_result_t shaderc_assemble_into_spv(
|
||||
+shaderc_compilation_status shaderc_assemble_into_spv(
|
||||
const shaderc_compiler_t compiler, const char* source_assembly,
|
||||
size_t source_assembly_size,
|
||||
- const shaderc_compile_options_t additional_options) {
|
||||
- auto* result = new (std::nothrow) shaderc_compilation_result_spv_binary;
|
||||
- if (!result) return nullptr;
|
||||
- result->compilation_status = shaderc_compilation_status_invalid_assembly;
|
||||
- if (!compiler->initializer) return result;
|
||||
- if (source_assembly == nullptr) return result;
|
||||
+ const shaderc_compile_options_t additional_options,
|
||||
+ shaderc_compilation_result_t* result) {
|
||||
+ auto* bresult = new (std::nothrow) shaderc_compilation_result_spv_binary;
|
||||
+ if (!bresult) return shaderc_compilation_status_internal_error;
|
||||
+ bresult->compilation_status = shaderc_compilation_status_invalid_assembly;
|
||||
+ *result = bresult;
|
||||
+ if (!compiler->initializer) return bresult->compilation_status;
|
||||
+ if (source_assembly == nullptr) return bresult->compilation_status;
|
||||
|
||||
TRY_IF_EXCEPTIONS_ENABLED {
|
||||
spv_binary assembling_output_data = nullptr;
|
||||
@@ -724,22 +762,22 @@ shaderc_compilation_result_t shaderc_assemble_into_spv(
|
||||
GetCompilerTargetEnvVersion(target_env_version),
|
||||
{source_assembly, source_assembly + source_assembly_size},
|
||||
&assembling_output_data, &errors);
|
||||
- result->num_errors = !assembling_succeeded;
|
||||
+ bresult->num_errors = !assembling_succeeded;
|
||||
if (assembling_succeeded) {
|
||||
- result->SetOutputData(assembling_output_data);
|
||||
- result->output_data_size =
|
||||
+ bresult->SetOutputData(assembling_output_data);
|
||||
+ bresult->output_data_size =
|
||||
assembling_output_data->wordCount * sizeof(uint32_t);
|
||||
- result->compilation_status = shaderc_compilation_status_success;
|
||||
+ bresult->compilation_status = shaderc_compilation_status_success;
|
||||
} else {
|
||||
- result->messages = std::move(errors);
|
||||
- result->compilation_status = shaderc_compilation_status_invalid_assembly;
|
||||
+ bresult->messages = std::move(errors);
|
||||
+ bresult->compilation_status = shaderc_compilation_status_invalid_assembly;
|
||||
}
|
||||
}
|
||||
CATCH_IF_EXCEPTIONS_ENABLED(...) {
|
||||
- result->compilation_status = shaderc_compilation_status_internal_error;
|
||||
+ bresult->compilation_status = shaderc_compilation_status_internal_error;
|
||||
}
|
||||
|
||||
- return result;
|
||||
+ return bresult->compilation_status;
|
||||
}
|
||||
|
||||
size_t shaderc_result_get_length(const shaderc_compilation_result_t result) {
|
||||
diff --git a/libshaderc_util/include/libshaderc_util/compiler.h b/libshaderc_util/include/libshaderc_util/compiler.h
|
||||
index d9d02b9..b076ec8 100644
|
||||
--- a/libshaderc_util/include/libshaderc_util/compiler.h
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/the-tcpdump-group/libpcap.git",
|
||||
"tag": "libpcap-1.10.4",
|
||||
"commit": "104271ba4a14de6743e43bcf87536786d8fddea4"
|
||||
"tag": "libpcap-1.10.5",
|
||||
"commit": "bbcbc9174df3298a854daee2b3e666a4b6e5383a"
|
||||
}
|
||||
],
|
||||
"cleanup": [
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"app-id": "net.pcsx2.PCSX2",
|
||||
"runtime": "org.kde.Platform",
|
||||
"runtime-version": "6.7",
|
||||
"runtime-version": "6.8",
|
||||
"sdk": "org.kde.Sdk",
|
||||
"sdk-extensions": [
|
||||
"org.freedesktop.Sdk.Extension.llvm17"
|
||||
"org.freedesktop.Sdk.Extension.llvm18"
|
||||
],
|
||||
"add-extensions": {
|
||||
"org.freedesktop.Platform.ffmpeg-full": {
|
||||
"directory": "lib/ffmpeg",
|
||||
"version": "23.08",
|
||||
"version": "24.08",
|
||||
"add-ld-path": ".",
|
||||
"autodownload": true
|
||||
}
|
||||
@@ -44,8 +44,8 @@
|
||||
"config-opts": [
|
||||
"-DCMAKE_BUILD_TYPE=Release",
|
||||
"-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON",
|
||||
"-DCMAKE_C_COMPILER=/usr/lib/sdk/llvm17/bin/clang",
|
||||
"-DCMAKE_CXX_COMPILER=/usr/lib/sdk/llvm17/bin/clang++",
|
||||
"-DCMAKE_C_COMPILER=/usr/lib/sdk/llvm18/bin/clang",
|
||||
"-DCMAKE_CXX_COMPILER=/usr/lib/sdk/llvm18/bin/clang++",
|
||||
"-DCMAKE_EXE_LINKER_FLAGS_INIT=-fuse-ld=lld",
|
||||
"-DCMAKE_MODULE_LINKER_FLAGS_INIT=-fuse-ld=lld",
|
||||
"-DCMAKE_SHARED_LINKER_FLAGS_INIT=-fuse-ld=lld",
|
||||
|
||||
@@ -74,7 +74,7 @@ call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/off
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 91c33d9946279c9c613b02e52a33df610cc01d13ea6e321b4c4d8ee708b9a03e || goto error
|
||||
call :downloadfile "zlib%ZLIBSHORT%.zip" "https://zlib.net/zlib%ZLIBSHORT%.zip" 72af66d44fcc14c22013b46b814d5d2514673dda3d115e64b690c1ad636e7b17 || goto error
|
||||
call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" 3b1c3b46e416d36931efd34663122d7f51b550c87f74de2d38249516fe7d8be5 || goto error
|
||||
call :downloadfile "zstd-fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch" https://github.com/facebook/zstd/commit/fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch 675f144b11f8ab2424b64bed8ccdca5d3f35b9326046fa7a883925dd180f0651 || goto error
|
||||
call :downloadfile "zstd-fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch" https://github.com/facebook/zstd/commit/fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch 8df152f4969b308546306c074628de761f0b80265de7de534e3822fab22d7535 || goto error
|
||||
|
||||
call :downloadfile "shaderc-%SHADERC%.zip" "https://github.com/google/shaderc/archive/refs/tags/v%SHADERC%.zip" 6c9f42ed6bf42750f5369b089909abfdcf0101488b4a1f41116d5159d00af8e7 || goto error
|
||||
call :downloadfile "shaderc-glslang-%SHADERC_GLSLANG%.zip" "https://github.com/KhronosGroup/glslang/archive/%SHADERC_GLSLANG%.zip" 03ad8a6fa987af4653d0cfe6bdaed41bcf617f1366a151fb1574da75950cd3e8 || goto error
|
||||
|
||||
@@ -72,7 +72,7 @@ call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/off
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 91c33d9946279c9c613b02e52a33df610cc01d13ea6e321b4c4d8ee708b9a03e || goto error
|
||||
call :downloadfile "zlib%ZLIBSHORT%.zip" "https://zlib.net/zlib%ZLIBSHORT%.zip" 72af66d44fcc14c22013b46b814d5d2514673dda3d115e64b690c1ad636e7b17 || goto error
|
||||
call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" 3b1c3b46e416d36931efd34663122d7f51b550c87f74de2d38249516fe7d8be5 || goto error
|
||||
call :downloadfile "zstd-fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch" https://github.com/facebook/zstd/commit/fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch 675f144b11f8ab2424b64bed8ccdca5d3f35b9326046fa7a883925dd180f0651 || goto error
|
||||
call :downloadfile "zstd-fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch" https://github.com/facebook/zstd/commit/fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch 8df152f4969b308546306c074628de761f0b80265de7de534e3822fab22d7535 || goto error
|
||||
|
||||
call :downloadfile "shaderc-%SHADERC%.zip" "https://github.com/google/shaderc/archive/refs/tags/v%SHADERC%.zip" 6c9f42ed6bf42750f5369b089909abfdcf0101488b4a1f41116d5159d00af8e7 || goto error
|
||||
call :downloadfile "shaderc-glslang-%SHADERC_GLSLANG%.zip" "https://github.com/KhronosGroup/glslang/archive/%SHADERC_GLSLANG%.zip" 03ad8a6fa987af4653d0cfe6bdaed41bcf617f1366a151fb1574da75950cd3e8 || goto error
|
||||
|
||||
2
.github/workflows/windows_build_qt.yml
vendored
2
.github/workflows/windows_build_qt.yml
vendored
@@ -100,7 +100,7 @@ jobs:
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: deps
|
||||
key: ${{ inputs.os }} ${{ inputs.platform }} deps ${{ hashFiles('.github/workflows/scripts/windows/build-dependencies.bat') }}
|
||||
key: ${{ inputs.os }} ${{ inputs.platform }} deps ${{ hashFiles('.github/workflows/scripts/windows/build-dependencies.bat', '.github/workflows/scripts/common/*.patch') }}
|
||||
|
||||
- name: Build Dependencies
|
||||
if: steps.cache-deps.outputs.cache-hit != 'true'
|
||||
|
||||
31
3rdparty/ccc/src/ccc/elf.cpp
vendored
31
3rdparty/ccc/src/ccc/elf.cpp
vendored
@@ -10,34 +10,35 @@ Result<ElfFile> ElfFile::parse(std::vector<u8> image)
|
||||
ElfFile elf;
|
||||
elf.image = std::move(image);
|
||||
|
||||
const ElfIdentHeader* ident = get_packed<ElfIdentHeader>(elf.image, 0);
|
||||
const ElfIdentHeader* ident = get_unaligned<ElfIdentHeader>(elf.image, 0);
|
||||
CCC_CHECK(ident, "ELF ident header out of range.");
|
||||
CCC_CHECK(ident->magic == CCC_FOURCC("\x7f\x45\x4c\x46"), "Not an ELF file.");
|
||||
CCC_CHECK(ident->e_class == ElfIdentClass::B32, "Wrong ELF class (not 32 bit).");
|
||||
|
||||
const ElfFileHeader* header = get_packed<ElfFileHeader>(elf.image, sizeof(ElfIdentHeader));
|
||||
const ElfFileHeader* header = get_unaligned<ElfFileHeader>(elf.image, sizeof(ElfIdentHeader));
|
||||
CCC_CHECK(header, "ELF file header out of range.");
|
||||
elf.file_header = *header;
|
||||
|
||||
const ElfSectionHeader* shstr_section_header = get_packed<ElfSectionHeader>(elf.image, header->shoff + header->shstrndx * sizeof(ElfSectionHeader));
|
||||
const ElfSectionHeader* shstr_section_header =
|
||||
get_unaligned<ElfSectionHeader>(elf.image, header->shoff + header->shstrndx * sizeof(ElfSectionHeader));
|
||||
CCC_CHECK(shstr_section_header, "ELF section name header out of range.");
|
||||
|
||||
for(u32 i = 0; i < header->shnum; i++) {
|
||||
u64 header_offset = header->shoff + i * sizeof(ElfSectionHeader);
|
||||
const ElfSectionHeader* section_header = get_packed<ElfSectionHeader>(elf.image, header_offset);
|
||||
const ElfSectionHeader* section_header = get_unaligned<ElfSectionHeader>(elf.image, header_offset);
|
||||
CCC_CHECK(section_header, "ELF section header out of range.");
|
||||
|
||||
const char* name = get_string(elf.image, shstr_section_header->offset + section_header->name);
|
||||
CCC_CHECK(section_header, "ELF section name out of range.");
|
||||
std::optional<std::string_view> name = get_string(elf.image, shstr_section_header->offset + section_header->name);
|
||||
CCC_CHECK(name.has_value(), "ELF section name out of range.");
|
||||
|
||||
ElfSection& section = elf.sections.emplace_back();
|
||||
section.name = name;
|
||||
section.name = *name;
|
||||
section.header = *section_header;
|
||||
}
|
||||
|
||||
for(u32 i = 0; i < header->phnum; i++) {
|
||||
u64 header_offset = header->phoff + i * sizeof(ElfProgramHeader);
|
||||
const ElfProgramHeader* program_header = get_packed<ElfProgramHeader>(elf.image, header_offset);
|
||||
const ElfProgramHeader* program_header = get_unaligned<ElfProgramHeader>(elf.image, header_offset);
|
||||
CCC_CHECK(program_header, "ELF program header out of range.");
|
||||
|
||||
elf.segments.emplace_back(*program_header);
|
||||
@@ -93,7 +94,7 @@ const ElfProgramHeader* ElfFile::entry_point_segment() const
|
||||
return entry_segment;
|
||||
}
|
||||
|
||||
Result<std::span<const u8>> ElfFile::get_virtual(u32 address, u32 size) const
|
||||
std::optional<std::span<const u8>> ElfFile::get_virtual(u32 address, u32 size) const
|
||||
{
|
||||
u32 end_address = address + size;
|
||||
|
||||
@@ -109,17 +110,19 @@ Result<std::span<const u8>> ElfFile::get_virtual(u32 address, u32 size) const
|
||||
}
|
||||
}
|
||||
|
||||
return CCC_FAILURE("No ELF segment for address range 0x%x to 0x%x.", address, end_address);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
Result<void> ElfFile::copy_virtual(u8* dest, u32 address, u32 size) const
|
||||
bool ElfFile::copy_virtual(u8* dest, u32 address, u32 size) const
|
||||
{
|
||||
Result<std::span<const u8>> block = get_virtual(address, size);
|
||||
CCC_RETURN_IF_ERROR(block);
|
||||
std::optional<std::span<const u8>> block = get_virtual(address, size);
|
||||
if(!block.has_value()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(dest, block->data(), size);
|
||||
|
||||
return Result<void>();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
20
3rdparty/ccc/src/ccc/elf.h
vendored
20
3rdparty/ccc/src/ccc/elf.h
vendored
@@ -125,18 +125,20 @@ struct ElfFile {
|
||||
const ElfProgramHeader* entry_point_segment() const;
|
||||
|
||||
// Retrieve a block of data in an ELF file given its address and size.
|
||||
Result<std::span<const u8>> get_virtual(u32 address, u32 size) const;
|
||||
std::optional<std::span<const u8>> get_virtual(u32 address, u32 size) const;
|
||||
|
||||
// Copy a block of data in an ELF file to the destination buffer given its
|
||||
// address and size.
|
||||
Result<void> copy_virtual(u8* dest, u32 address, u32 size) const;
|
||||
bool copy_virtual(u8* dest, u32 address, u32 size) const;
|
||||
|
||||
// Retrieve an object of type T from an ELF file given its address.
|
||||
template <typename T>
|
||||
Result<T> get_object_virtual(u32 address) const
|
||||
std::optional<T> get_object_virtual(u32 address) const
|
||||
{
|
||||
Result<std::span<const u8>> result = get_virtual(address, sizeof(T));
|
||||
CCC_RETURN_IF_ERROR(result);
|
||||
std::optional<std::span<const u8>> result = get_virtual(address, sizeof(T));
|
||||
if(!result.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return *(T*) result->data();
|
||||
}
|
||||
@@ -144,10 +146,12 @@ struct ElfFile {
|
||||
// Retrieve an array of objects of type T from an ELF file given its
|
||||
// address and element count.
|
||||
template <typename T>
|
||||
Result<std::span<const T>> get_array_virtual(u32 address, u32 element_count) const
|
||||
std::optional<std::span<const T>> get_array_virtual(u32 address, u32 element_count) const
|
||||
{
|
||||
Result<std::span<const u8>> result = get_virtual(address, element_count * sizeof(T));
|
||||
CCC_RETURN_IF_ERROR(result);
|
||||
std::optional<std::span<const u8>> result = get_virtual(address, element_count * sizeof(T));
|
||||
if(!result.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return std::span<const T>((T*) result->data(), (T*) (result->data() + result->size()));
|
||||
}
|
||||
|
||||
25
3rdparty/ccc/src/ccc/elf_symtab.cpp
vendored
25
3rdparty/ccc/src/ccc/elf_symtab.cpp
vendored
@@ -60,7 +60,7 @@ Result<void> import_symbols(
|
||||
DemanglerFunctions demangler)
|
||||
{
|
||||
for(u32 i = 0; i < symtab.size() / sizeof(Symbol); i++) {
|
||||
const Symbol* symbol = get_packed<Symbol>(symtab, i * sizeof(Symbol));
|
||||
const Symbol* symbol = get_unaligned<Symbol>(symtab, i * sizeof(Symbol));
|
||||
CCC_ASSERT(symbol);
|
||||
|
||||
Address address;
|
||||
@@ -86,13 +86,14 @@ Result<void> import_symbols(
|
||||
}
|
||||
}
|
||||
|
||||
const char* string = get_string(strtab, symbol->name);
|
||||
CCC_CHECK(string, "Symbol string out of range.");
|
||||
std::optional<std::string_view> string_view = get_string(strtab, symbol->name);
|
||||
CCC_CHECK(string_view.has_value(), "Symbol string out of range.");
|
||||
std::string string(*string_view);
|
||||
|
||||
switch(symbol->type()) {
|
||||
case SymbolType::NOTYPE: {
|
||||
Result<Label*> label = database.labels.create_symbol(
|
||||
string, group.source, group.module_symbol, address, importer_flags, demangler);
|
||||
std::move(string), group.source, group.module_symbol, address, importer_flags, demangler);
|
||||
CCC_RETURN_IF_ERROR(label);
|
||||
|
||||
// These symbols get emitted at the same addresses as functions
|
||||
@@ -108,7 +109,7 @@ Result<void> import_symbols(
|
||||
case SymbolType::OBJECT: {
|
||||
if(symbol->size != 0) {
|
||||
Result<GlobalVariable*> global_variable = database.global_variables.create_symbol(
|
||||
string, group.source, group.module_symbol, address, importer_flags, demangler);
|
||||
std::move(string), group.source, group.module_symbol, address, importer_flags, demangler);
|
||||
CCC_RETURN_IF_ERROR(global_variable);
|
||||
|
||||
if(*global_variable) {
|
||||
@@ -116,7 +117,7 @@ Result<void> import_symbols(
|
||||
}
|
||||
} else {
|
||||
Result<Label*> label = database.labels.create_symbol(
|
||||
string, group.source, group.module_symbol, address, importer_flags, demangler);
|
||||
std::move(string), group.source, group.module_symbol, address, importer_flags, demangler);
|
||||
CCC_RETURN_IF_ERROR(label);
|
||||
}
|
||||
|
||||
@@ -124,7 +125,7 @@ Result<void> import_symbols(
|
||||
}
|
||||
case SymbolType::FUNC: {
|
||||
Result<Function*> function = database.functions.create_symbol(
|
||||
string, group.source, group.module_symbol, address, importer_flags, demangler);
|
||||
std::move(string), group.source, group.module_symbol, address, importer_flags, demangler);
|
||||
CCC_RETURN_IF_ERROR(function);
|
||||
|
||||
if(*function) {
|
||||
@@ -135,7 +136,7 @@ Result<void> import_symbols(
|
||||
}
|
||||
case SymbolType::FILE: {
|
||||
Result<SourceFile*> source_file = database.source_files.create_symbol(
|
||||
string, group.source, group.module_symbol);
|
||||
std::move(string), group.source, group.module_symbol);
|
||||
CCC_RETURN_IF_ERROR(source_file);
|
||||
|
||||
break;
|
||||
@@ -153,18 +154,18 @@ Result<void> print_symbol_table(FILE* out, std::span<const u8> symtab, std::span
|
||||
fprintf(out, " Num: Value Size Type Bind Vis Ndx Name\n");
|
||||
|
||||
for(u32 i = 0; i < symtab.size() / sizeof(Symbol); i++) {
|
||||
const Symbol* symbol = get_packed<Symbol>(symtab, i * sizeof(Symbol));
|
||||
const Symbol* symbol = get_unaligned<Symbol>(symtab, i * sizeof(Symbol));
|
||||
CCC_ASSERT(symbol);
|
||||
|
||||
const char* type = symbol_type_to_string(symbol->type());
|
||||
const char* bind = symbol_bind_to_string(symbol->bind());
|
||||
const char* visibility = symbol_visibility_to_string(symbol->visibility());
|
||||
|
||||
const char* string = get_string(strtab, symbol->name);
|
||||
CCC_CHECK(string, "Symbol string out of range.");
|
||||
std::optional<std::string_view> string = get_string(strtab, symbol->name);
|
||||
CCC_CHECK(string.has_value(), "Symbol string out of range.");
|
||||
|
||||
fprintf(out, "%6u: %08x %5u %-7s %-7s %-7s %3u %s\n",
|
||||
i, symbol->value, symbol->size, type, bind, visibility, symbol->shndx, string);
|
||||
i, symbol->value, symbol->size, type, bind, visibility, symbol->shndx, string->data());
|
||||
|
||||
}
|
||||
|
||||
|
||||
22
3rdparty/ccc/src/ccc/mdebug_section.cpp
vendored
22
3rdparty/ccc/src/ccc/mdebug_section.cpp
vendored
@@ -90,7 +90,7 @@ Result<void> SymbolTableReader::init(std::span<const u8> elf, s32 section_offset
|
||||
m_elf = elf;
|
||||
m_section_offset = section_offset;
|
||||
|
||||
m_hdrr = get_packed<SymbolicHeader>(m_elf, m_section_offset);
|
||||
m_hdrr = get_unaligned<SymbolicHeader>(m_elf, m_section_offset);
|
||||
CCC_CHECK(m_hdrr != nullptr, "MIPS debug section header out of bounds.");
|
||||
CCC_CHECK(m_hdrr->magic == 0x7009, "Invalid symbolic header.");
|
||||
|
||||
@@ -116,7 +116,7 @@ Result<File> SymbolTableReader::parse_file(s32 index) const
|
||||
File file;
|
||||
|
||||
u64 fd_offset = m_hdrr->file_descriptors_offset + index * sizeof(FileDescriptor);
|
||||
const FileDescriptor* fd_header = get_packed<FileDescriptor>(m_elf, fd_offset + m_fudge_offset);
|
||||
const FileDescriptor* fd_header = get_unaligned<FileDescriptor>(m_elf, fd_offset + m_fudge_offset);
|
||||
CCC_CHECK(fd_header != nullptr, "MIPS debug file descriptor out of bounds.");
|
||||
CCC_CHECK(fd_header->f_big_endian == 0, "Not little endian or bad file descriptor table.");
|
||||
|
||||
@@ -124,16 +124,16 @@ Result<File> SymbolTableReader::parse_file(s32 index) const
|
||||
|
||||
s32 rel_raw_path_offset = fd_header->strings_offset + fd_header->file_path_string_offset;
|
||||
s32 raw_path_offset = m_hdrr->local_strings_offset + rel_raw_path_offset + m_fudge_offset;
|
||||
const char* command_line_path = get_string(m_elf, raw_path_offset);
|
||||
if(command_line_path) {
|
||||
file.command_line_path = command_line_path;
|
||||
std::optional<std::string_view> command_line_path = get_string(m_elf, raw_path_offset);
|
||||
if(command_line_path.has_value()) {
|
||||
file.command_line_path = *command_line_path;
|
||||
}
|
||||
|
||||
// Parse local symbols.
|
||||
for(s64 j = 0; j < fd_header->symbol_count; j++) {
|
||||
u64 rel_symbol_offset = (fd_header->isym_base + j) * sizeof(SymbolHeader);
|
||||
u64 symbol_offset = m_hdrr->local_symbols_offset + rel_symbol_offset + m_fudge_offset;
|
||||
const SymbolHeader* symbol_header = get_packed<SymbolHeader>(m_elf, symbol_offset);
|
||||
const SymbolHeader* symbol_header = get_unaligned<SymbolHeader>(m_elf, symbol_offset);
|
||||
CCC_CHECK(symbol_header != nullptr, "Symbol header out of bounds.");
|
||||
|
||||
s32 strings_offset = m_hdrr->local_strings_offset + fd_header->strings_offset + m_fudge_offset;
|
||||
@@ -155,7 +155,7 @@ Result<File> SymbolTableReader::parse_file(s32 index) const
|
||||
for(s64 i = 0; i < fd_header->procedure_descriptor_count; i++) {
|
||||
u64 rel_procedure_offset = (fd_header->ipd_first + i) * sizeof(ProcedureDescriptor);
|
||||
u64 procedure_offset = m_hdrr->procedure_descriptors_offset + rel_procedure_offset + m_fudge_offset;
|
||||
const ProcedureDescriptor* procedure_descriptor = get_packed<ProcedureDescriptor>(m_elf, procedure_offset);
|
||||
const ProcedureDescriptor* procedure_descriptor = get_unaligned<ProcedureDescriptor>(m_elf, procedure_offset);
|
||||
CCC_CHECK(procedure_descriptor != nullptr, "Procedure descriptor out of bounds.");
|
||||
|
||||
CCC_CHECK(procedure_descriptor->symbol_index < file.symbols.size(), "Symbol index out of bounds.");
|
||||
@@ -175,7 +175,7 @@ Result<std::vector<Symbol>> SymbolTableReader::parse_external_symbols() const
|
||||
std::vector<Symbol> external_symbols;
|
||||
for(s64 i = 0; i < m_hdrr->external_symbols_count; i++) {
|
||||
u64 sym_offset = m_hdrr->external_symbols_offset + i * sizeof(ExternalSymbolHeader);
|
||||
const ExternalSymbolHeader* external_header = get_packed<ExternalSymbolHeader>(m_elf, sym_offset + m_fudge_offset);
|
||||
const ExternalSymbolHeader* external_header = get_unaligned<ExternalSymbolHeader>(m_elf, sym_offset + m_fudge_offset);
|
||||
CCC_CHECK(external_header != nullptr, "External header out of bounds.");
|
||||
|
||||
Result<Symbol> sym = get_symbol(external_header->symbol, m_elf, m_hdrr->external_strings_offset + m_fudge_offset);
|
||||
@@ -351,9 +351,9 @@ static Result<Symbol> get_symbol(const SymbolHeader& header, std::span<const u8>
|
||||
{
|
||||
Symbol symbol;
|
||||
|
||||
const char* string = get_string(elf, strings_offset + header.iss);
|
||||
CCC_CHECK(string, "Symbol has invalid string.");
|
||||
symbol.string = string;
|
||||
std::optional<std::string_view> string = get_string(elf, strings_offset + header.iss);
|
||||
CCC_CHECK(string.has_value(), "Symbol has invalid string.");
|
||||
symbol.string = string->data();
|
||||
|
||||
symbol.value = header.value;
|
||||
symbol.symbol_type = (SymbolType) header.st;
|
||||
|
||||
22
3rdparty/ccc/src/ccc/sndll.cpp
vendored
22
3rdparty/ccc/src/ccc/sndll.cpp
vendored
@@ -54,18 +54,19 @@ static const char* sndll_symbol_type_to_string(SNDLLSymbolType type);
|
||||
|
||||
Result<SNDLLFile> parse_sndll_file(std::span<const u8> image, Address address, SNDLLType type)
|
||||
{
|
||||
const u32* magic = get_packed<u32>(image, 0);
|
||||
std::optional<u32> magic = copy_unaligned<u32>(image, 0);
|
||||
CCC_CHECK(magic.has_value(), "Failed to read SNDLL header.");
|
||||
CCC_CHECK((*magic & 0xffffff) == CCC_FOURCC("SNR\00"), "Not a SNDLL %s.", address.valid() ? "section" : "file");
|
||||
|
||||
char version = *magic >> 24;
|
||||
switch(version) {
|
||||
case '1': {
|
||||
const SNDLLHeaderV1* header = get_packed<SNDLLHeaderV1>(image, 0);
|
||||
const SNDLLHeaderV1* header = get_unaligned<SNDLLHeaderV1>(image, 0);
|
||||
CCC_CHECK(header, "File too small to contain SNDLL V1 header.");
|
||||
return parse_sndll_common(image, address, type, header->common, SNDLL_V1);
|
||||
}
|
||||
case '2': {
|
||||
const SNDLLHeaderV2* header = get_packed<SNDLLHeaderV2>(image, 0);
|
||||
const SNDLLHeaderV2* header = get_unaligned<SNDLLHeaderV2>(image, 0);
|
||||
CCC_CHECK(header, "File too small to contain SNDLL V2 header.");
|
||||
return parse_sndll_common(image, address, type, header->common, SNDLL_V2);
|
||||
}
|
||||
@@ -84,10 +85,9 @@ static Result<SNDLLFile> parse_sndll_common(
|
||||
sndll.version = version;
|
||||
|
||||
if(common.elf_path) {
|
||||
const char* elf_path = get_string(image, common.elf_path);
|
||||
if(elf_path) {
|
||||
sndll.elf_path = elf_path;
|
||||
}
|
||||
std::optional<std::string_view> elf_path = get_string(image, common.elf_path);
|
||||
CCC_CHECK(elf_path.has_value(), "SNDLL header has invalid ELF path field.");
|
||||
sndll.elf_path = *elf_path;
|
||||
}
|
||||
|
||||
CCC_CHECK(common.symbol_count < (32 * 1024 * 1024) / sizeof(SNDLLSymbol), "SNDLL symbol count is too high.");
|
||||
@@ -95,10 +95,10 @@ static Result<SNDLLFile> parse_sndll_common(
|
||||
|
||||
for(u32 i = 0; i < common.symbol_count; i++) {
|
||||
u32 symbol_offset = common.symbols - address.get_or_zero() + i * sizeof(SNDLLSymbolHeader);
|
||||
const SNDLLSymbolHeader* symbol_header = get_packed<SNDLLSymbolHeader>(image, symbol_offset);
|
||||
const SNDLLSymbolHeader* symbol_header = get_unaligned<SNDLLSymbolHeader>(image, symbol_offset);
|
||||
CCC_CHECK(symbol_header, "SNDLL symbol out of range.");
|
||||
|
||||
const char* string = nullptr;
|
||||
std::optional<std::string_view> string;
|
||||
if(symbol_header->string) {
|
||||
string = get_string(image, symbol_header->string - address.get_or_zero());
|
||||
}
|
||||
@@ -106,7 +106,9 @@ static Result<SNDLLFile> parse_sndll_common(
|
||||
SNDLLSymbol& symbol = sndll.symbols.emplace_back();
|
||||
symbol.type = symbol_header->type;
|
||||
symbol.value = symbol_header->value;
|
||||
symbol.string = string;
|
||||
if(string.has_value()) {
|
||||
symbol.string = *string;
|
||||
}
|
||||
}
|
||||
|
||||
return sndll;
|
||||
|
||||
2
3rdparty/ccc/src/ccc/symbol_database.h
vendored
2
3rdparty/ccc/src/ccc/symbol_database.h
vendored
@@ -435,7 +435,7 @@ class Label : public Symbol {
|
||||
public:
|
||||
static constexpr const SymbolDescriptor DESCRIPTOR = LABEL;
|
||||
static constexpr const char* NAME = "Label";
|
||||
static constexpr u32 FLAGS = WITH_ADDRESS_MAP;
|
||||
static constexpr u32 FLAGS = WITH_ADDRESS_MAP | WITH_NAME_MAP;
|
||||
|
||||
LabelHandle handle() const { return m_handle; }
|
||||
|
||||
|
||||
4
3rdparty/ccc/src/ccc/symbol_file.cpp
vendored
4
3rdparty/ccc/src/ccc/symbol_file.cpp
vendored
@@ -7,8 +7,8 @@ namespace ccc {
|
||||
|
||||
Result<std::unique_ptr<SymbolFile>> parse_symbol_file(std::vector<u8> image, std::string file_name)
|
||||
{
|
||||
const u32* magic = get_packed<u32>(image, 0);
|
||||
CCC_CHECK(magic, "File too small.");
|
||||
const std::optional<u32> magic = copy_unaligned<u32>(image, 0);
|
||||
CCC_CHECK(magic.has_value(), "File too small.");
|
||||
|
||||
std::unique_ptr<SymbolFile> symbol_file;
|
||||
|
||||
|
||||
6
3rdparty/ccc/src/ccc/symbol_table.cpp
vendored
6
3rdparty/ccc/src/ccc/symbol_table.cpp
vendored
@@ -100,8 +100,9 @@ Result<std::unique_ptr<SymbolTable>> create_elf_symbol_table(
|
||||
|
||||
Result<ModuleHandle> import_symbol_tables(
|
||||
SymbolDatabase& database,
|
||||
std::string module_name,
|
||||
const std::vector<std::unique_ptr<SymbolTable>>& symbol_tables,
|
||||
std::string module_name,
|
||||
Address base_address,
|
||||
u32 importer_flags,
|
||||
DemanglerFunctions demangler,
|
||||
const std::atomic_bool* interrupt)
|
||||
@@ -109,7 +110,8 @@ Result<ModuleHandle> import_symbol_tables(
|
||||
Result<SymbolSourceHandle> module_source = database.get_symbol_source("Symbol Table Importer");
|
||||
CCC_RETURN_IF_ERROR(module_source);
|
||||
|
||||
Result<Module*> module_symbol = database.modules.create_symbol(std::move(module_name), *module_source, nullptr);
|
||||
Result<Module*> module_symbol = database.modules.create_symbol(
|
||||
std::move(module_name), base_address, *module_source, nullptr);
|
||||
CCC_RETURN_IF_ERROR(module_symbol);
|
||||
|
||||
ModuleHandle module_handle = (*module_symbol)->handle();
|
||||
|
||||
3
3rdparty/ccc/src/ccc/symbol_table.h
vendored
3
3rdparty/ccc/src/ccc/symbol_table.h
vendored
@@ -71,8 +71,9 @@ Result<std::unique_ptr<SymbolTable>> create_elf_symbol_table(
|
||||
// and to generate a module handle.
|
||||
Result<ModuleHandle> import_symbol_tables(
|
||||
SymbolDatabase& database,
|
||||
std::string module_name,
|
||||
const std::vector<std::unique_ptr<SymbolTable>>& symbol_tables,
|
||||
std::string module_name,
|
||||
Address base_address,
|
||||
u32 importer_flags,
|
||||
DemanglerFunctions demangler,
|
||||
const std::atomic_bool* interrupt);
|
||||
|
||||
13
3rdparty/ccc/src/ccc/util.cpp
vendored
13
3rdparty/ccc/src/ccc/util.cpp
vendored
@@ -51,14 +51,17 @@ void set_custom_error_callback(CustomErrorCallback callback)
|
||||
custom_error_callback = callback;
|
||||
}
|
||||
|
||||
const char* get_string(std::span<const u8> bytes, u64 offset)
|
||||
std::optional<std::string_view> get_string(std::span<const u8> bytes, u64 offset)
|
||||
{
|
||||
for(const unsigned char* c = bytes.data() + offset; c < bytes.data() + bytes.size(); c++) {
|
||||
if(*c == '\0') {
|
||||
return (const char*) &bytes[offset];
|
||||
for(u64 i = offset; i < bytes.size(); i++) {
|
||||
if(bytes[i] == '\0') {
|
||||
return std::string_view(
|
||||
reinterpret_cast<const char*>(&bytes[offset]),
|
||||
reinterpret_cast<const char*>(&bytes[i]));
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::string merge_paths(const std::string& base, const std::string& path)
|
||||
|
||||
41
3rdparty/ccc/src/ccc/util.h
vendored
41
3rdparty/ccc/src/ccc/util.h
vendored
@@ -71,8 +71,15 @@ void set_custom_error_callback(CustomErrorCallback callback);
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
#define CCC_ABORT_IF_FALSE(condition, ...) \
|
||||
if(!(condition)) { \
|
||||
ccc::Error error = ccc::format_error(__FILE__, __LINE__, __VA_ARGS__); \
|
||||
ccc::report_error(error); \
|
||||
abort(); \
|
||||
}
|
||||
|
||||
#define CCC_ASSERT(condition) \
|
||||
CCC_CHECK_FATAL(condition, #condition)
|
||||
CCC_ABORT_IF_FALSE(condition, #condition)
|
||||
|
||||
// The main error handling construct in CCC. This class is used to bundle
|
||||
// together a return value and a pointer to error information, so that errors
|
||||
@@ -201,16 +208,38 @@ void warn_impl(const char* source_file, int source_line, const char* format, Arg
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
const T* get_packed(std::span<const u8> bytes, u64 offset)
|
||||
const T* get_aligned(std::span<const u8> bytes, u64 offset)
|
||||
{
|
||||
if(offset + sizeof(T) <= bytes.size()) {
|
||||
return reinterpret_cast<const T*>(&bytes[offset]);
|
||||
} else {
|
||||
if(offset > bytes.size() || bytes.size() - offset < sizeof(T) || offset % alignof(T) != 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return reinterpret_cast<const T*>(&bytes[offset]);
|
||||
}
|
||||
|
||||
const char* get_string(std::span<const u8> bytes, u64 offset);
|
||||
template <typename T>
|
||||
const T* get_unaligned(std::span<const u8> bytes, u64 offset)
|
||||
{
|
||||
if(offset > bytes.size() || bytes.size() - offset < sizeof(T)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return reinterpret_cast<const T*>(&bytes[offset]);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::optional<T> copy_unaligned(std::span<const u8> bytes, u64 offset)
|
||||
{
|
||||
if(offset > bytes.size() || bytes.size() - offset < sizeof(T)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
T value;
|
||||
memcpy(&value, &bytes[offset], sizeof(T));
|
||||
return value;
|
||||
}
|
||||
|
||||
std::optional<std::string_view> get_string(std::span<const u8> bytes, u64 offset);
|
||||
|
||||
#define CCC_BEGIN_END(x) (x).begin(), (x).end()
|
||||
#define CCC_ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
@@ -1588,6 +1588,14 @@ SCAJ-20105:
|
||||
recommendedBlendingLevel: 3 # Fixes level brightness.
|
||||
cpuSpriteRenderBW: 2 # Fixes broken water on "Upper Sea" level.
|
||||
cpuSpriteRenderLevel: 2 # Needed for above.
|
||||
dynaPatches:
|
||||
- pattern:
|
||||
- { offset: 0x0, value: 0x3C023E4C }
|
||||
- { offset: 0x4, value: 0x3442CCCD }
|
||||
- { offset: 0x8, value: 0xE7A300D0 }
|
||||
- { offset: 0xC, value: 0xE7A200D4 }
|
||||
replacement:
|
||||
- { offset: 0x4, value: 0x3442CCE0 }
|
||||
SCAJ-20107:
|
||||
name: "Bakufuu Slash! Kizna Arashi"
|
||||
region: "NTSC-Unk"
|
||||
@@ -6914,6 +6922,14 @@ SCKA-20047:
|
||||
- "SCKA-20047"
|
||||
- "SLKA-25201"
|
||||
- "SLKA-25202"
|
||||
dynaPatches:
|
||||
- pattern:
|
||||
- { offset: 0x0, value: 0x3C023E4C }
|
||||
- { offset: 0x4, value: 0x3442CCCD }
|
||||
- { offset: 0x8, value: 0xE7A300D0 }
|
||||
- { offset: 0xC, value: 0xE7A200D4 }
|
||||
replacement:
|
||||
- { offset: 0x4, value: 0x3442CCE0 }
|
||||
SCKA-20048:
|
||||
name: "Killzone"
|
||||
region: "NTSC-K"
|
||||
@@ -18493,6 +18509,8 @@ SLES-52256:
|
||||
SLES-52257:
|
||||
name: "P.T.O. IV - Pacific Theater of Operations IV"
|
||||
region: "PAL-E"
|
||||
gsHWFixes:
|
||||
minimumBlendingLevel: 3 # Fixes graphical flickering.
|
||||
SLES-52258:
|
||||
name: "Romance of the Three Kingdoms VIII"
|
||||
region: "PAL-E"
|
||||
@@ -18688,6 +18706,9 @@ SLES-52325:
|
||||
- BlitInternalFPSHack # Fixes internal fps detection in some areas.
|
||||
gsHWFixes:
|
||||
estimateTextureRegion: 1 # Improves performance.
|
||||
roundSprite: 1 # Fixes lines in menus HUD and in game.
|
||||
halfPixelOffset: 2 # Fixes edge garbage.
|
||||
PCRTCOverscan: 1 # Fixes offscreen image.
|
||||
SLES-52326:
|
||||
name: "Spawn - Armageddon"
|
||||
region: "PAL-M5"
|
||||
@@ -18788,6 +18809,9 @@ SLES-52373:
|
||||
- BlitInternalFPSHack # Fixes internal fps detection in some areas.
|
||||
gsHWFixes:
|
||||
estimateTextureRegion: 1 # Improves performance.
|
||||
roundSprite: 1 # Fixes lines in menus HUD and in game.
|
||||
halfPixelOffset: 2 # Fixes edge garbage.
|
||||
PCRTCOverscan: 1 # Fixes offscreen image.
|
||||
SLES-52374:
|
||||
name: "Fight Night 2004"
|
||||
region: "PAL-M3"
|
||||
@@ -20855,6 +20879,7 @@ SLES-53039:
|
||||
estimateTextureRegion: 1 # Improves performance.
|
||||
roundSprite: 1 # Fixes lines in menus HUD and in game.
|
||||
halfPixelOffset: 2 # Fixes erroneous line in menus.
|
||||
PCRTCOverscan: 1 # Fixes offscreen image.
|
||||
memcardFilters: # Allows import of characters from first game.
|
||||
- "SLES-53039"
|
||||
- "SLES-52325"
|
||||
@@ -21487,47 +21512,42 @@ SLES-53332:
|
||||
region: "PAL-M4"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 2
|
||||
recommendedBlendingLevel: 3 # Fixes banding and level lighting.
|
||||
autoFlush: 1 # Fixes sun shinging through surfaces and graphical corruptions.
|
||||
halfPixelOffset: 2 # Fixes misaligned blur.
|
||||
cpuSpriteRenderBW: 2 # Fixes black spots appearing on some surfaces and massively reduces RP TC and TU count.
|
||||
cpuSpriteRenderLevel: 2 # Needed for above.
|
||||
nativeScaling: 2 # Fixes bloom misaligment.
|
||||
SLES-53333:
|
||||
name: "Medal of Honor - Les Faucons de Guerre"
|
||||
region: "PAL-F"
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 2
|
||||
recommendedBlendingLevel: 3 # Fixes banding and level lighting.
|
||||
autoFlush: 1 # Fixes sun shinging through surfaces and graphical corruptions.
|
||||
halfPixelOffset: 2 # Fixes misaligned blur.
|
||||
cpuSpriteRenderBW: 2 # Fixes black spots appearing on some surfaces and massively reduces RP TC and TU count.
|
||||
cpuSpriteRenderLevel: 2 # Needed for above.
|
||||
nativeScaling: 2 # Fixes bloom misaligment.
|
||||
SLES-53334:
|
||||
name: "Medal of Honor - European Assault"
|
||||
region: "PAL-G"
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 2
|
||||
recommendedBlendingLevel: 3 # Fixes banding and level lighting.
|
||||
autoFlush: 1 # Fixes sun shinging through surfaces and graphical corruptions.
|
||||
halfPixelOffset: 2 # Fixes misaligned blur.
|
||||
cpuSpriteRenderBW: 2 # Fixes black spots appearing on some surfaces and massively reduces RP TC and TU count.
|
||||
cpuSpriteRenderLevel: 2 # Needed for above.
|
||||
nativeScaling: 2 # Fixes bloom misaligment.
|
||||
SLES-53335:
|
||||
name: "Medal of Honor - European Assault"
|
||||
region: "PAL-I"
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 2
|
||||
recommendedBlendingLevel: 3 # Fixes banding and level lighting.
|
||||
autoFlush: 1 # Fixes sun shinging through surfaces and graphical corruptions.
|
||||
halfPixelOffset: 2 # Fixes misaligned blur.
|
||||
cpuSpriteRenderBW: 2 # Fixes black spots appearing on some surfaces and massively reduces RP TC and TU count.
|
||||
cpuSpriteRenderLevel: 2 # Needed for above.
|
||||
nativeScaling: 2 # Fixes bloom misaligment.
|
||||
SLES-53336:
|
||||
name: "Medal of Honor - European Assault"
|
||||
region: "PAL-S"
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 2
|
||||
recommendedBlendingLevel: 3 # Fixes banding and level lighting.
|
||||
autoFlush: 1 # Fixes sun shinging through surfaces and graphical corruptions.
|
||||
halfPixelOffset: 2 # Fixes misaligned blur.
|
||||
cpuSpriteRenderBW: 2 # Fixes black spots appearing on some surfaces and massively reduces RP TC and TU count.
|
||||
cpuSpriteRenderLevel: 2 # Needed for above.
|
||||
nativeScaling: 2 # Fixes bloom misaligment.
|
||||
SLES-53338:
|
||||
name: "Victorious Boxers 2 - Fighting Spirit"
|
||||
region: "PAL-M3"
|
||||
@@ -22781,11 +22801,27 @@ SLES-53687:
|
||||
name: "NBA 2K6"
|
||||
region: "PAL-M5"
|
||||
patches:
|
||||
04808D11:
|
||||
4047DB34: # English
|
||||
content: |-
|
||||
author=Prafull
|
||||
comment=fixes hang at start
|
||||
patch=1,EE,00441ff8,word,00000000
|
||||
B91D81A3: # French
|
||||
content: |-
|
||||
comment=fixes hang at start
|
||||
patch=1,EE,00441fa0,word,00000000
|
||||
C96E2007: # German
|
||||
content: |-
|
||||
comment=fixes hang at start
|
||||
patch=1,EE,00441e48,word,00000000
|
||||
79A6C879: # Italian
|
||||
content: |-
|
||||
comment=fixes hang at start
|
||||
patch=1,EE,00441de8,word,00000000
|
||||
08349AAF: # Spanish
|
||||
content: |-
|
||||
comment=fixes hang at start
|
||||
patch=1,EE,00441ec8,word,00000000
|
||||
SLES-53689:
|
||||
name: "World Poker Tour 2K6"
|
||||
region: "PAL-M3"
|
||||
@@ -23229,6 +23265,14 @@ SLES-53819:
|
||||
- "SLES-53819"
|
||||
- "SLES-82036"
|
||||
- "SLES-82037"
|
||||
dynaPatches:
|
||||
- pattern:
|
||||
- { offset: 0x0, value: 0x3C023E4C }
|
||||
- { offset: 0x4, value: 0x3442CCCD }
|
||||
- { offset: 0x8, value: 0xE7A300D0 }
|
||||
- { offset: 0xC, value: 0xE7A200D4 }
|
||||
replacement:
|
||||
- { offset: 0x4, value: 0x3442CCE0 }
|
||||
SLES-53820:
|
||||
name: "Armored Core - Last Raven"
|
||||
region: "PAL-E"
|
||||
@@ -29908,11 +29952,10 @@ SLKA-25243:
|
||||
name: "Medal of Honor - European Assault"
|
||||
region: "NTSC-K"
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 2
|
||||
recommendedBlendingLevel: 3 # Fixes banding and level lighting.
|
||||
autoFlush: 1 # Fixes sun shinging through surfaces and graphical corruptions.
|
||||
halfPixelOffset: 2 # Fixes misaligned blur.
|
||||
cpuSpriteRenderBW: 2 # Fixes black spots appearing on some surfaces and massively reduces RP TC and TU count.
|
||||
cpuSpriteRenderLevel: 2 # Needed for above.
|
||||
nativeScaling: 2 # Fixes bloom misaligment.
|
||||
SLKA-25244:
|
||||
name: "WWE SmackDown! vs. Raw"
|
||||
region: "NTSC-K"
|
||||
@@ -31147,11 +31190,10 @@ SLPM-55037:
|
||||
name: "Medal of Honor - European Assault [EASY 1980]"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 2
|
||||
recommendedBlendingLevel: 3 # Fixes banding and level lighting.
|
||||
autoFlush: 1 # Fixes sun shinging through surfaces and graphical corruptions.
|
||||
halfPixelOffset: 2 # Fixes misaligned blur.
|
||||
cpuSpriteRenderBW: 2 # Fixes black spots appearing on some surfaces and massively reduces RP TC and TU count.
|
||||
cpuSpriteRenderLevel: 2 # Needed for above.
|
||||
nativeScaling: 2 # Fixes bloom misaligment.
|
||||
SLPM-55038:
|
||||
name: "Grand Theft Auto - Liberty City Stories [Best Price]"
|
||||
region: "NTSC-J"
|
||||
@@ -33879,6 +33921,8 @@ SLPM-62144:
|
||||
SLPM-62145:
|
||||
name: "Teitoku no Ketsudan IV"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
minimumBlendingLevel: 3 # Fixes graphical flickering.
|
||||
SLPM-62146:
|
||||
name: "Chou Kousoku Mahjong Plus"
|
||||
region: "NTSC-J"
|
||||
@@ -35341,6 +35385,8 @@ SLPM-62469:
|
||||
SLPM-62470:
|
||||
name: "Teitoku no Ketsudan IV with Power Up Kit"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
minimumBlendingLevel: 3 # Fixes graphical flickering.
|
||||
memcardFilters:
|
||||
- "SLPM-62145"
|
||||
- "SLPM-62470"
|
||||
@@ -35406,6 +35452,8 @@ SLPM-62482:
|
||||
name-sort: "ぱちすろとうこんでんしょう いのきまつり あんとにおいのきというなのぱちすろき あんとにおいのきじしんがぱちすろき"
|
||||
name-en: "Pachinko Slot Tokodensho - Inoki Festival"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
textureInsideRT: 1 # Fixes on screen garbage.
|
||||
SLPM-62483:
|
||||
name: "SIMPLE2000シリーズ Vol.48 THE タクシー 〜運転手は君だ〜"
|
||||
name-sort: "しんぷる2000しりーず Vol.48 THE たくしー うんてんしゅはきみだ"
|
||||
@@ -35610,6 +35658,8 @@ SLPM-62518:
|
||||
name-sort: "ていとくのけつだん4 [KOEI The Best]"
|
||||
name-en: "Teitoku no Ketsudan IV [Koei the Best]"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
minimumBlendingLevel: 3 # Fixes graphical flickering.
|
||||
SLPM-62519:
|
||||
name: "三國志VIII [KOEI The Best]"
|
||||
name-sort: "さんごくし8 [KOEI The Best]"
|
||||
@@ -43021,11 +43071,10 @@ SLPM-66079:
|
||||
name: "Medal of Honor - Europe Kyoushuu"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 2
|
||||
recommendedBlendingLevel: 3 # Fixes banding and level lighting.
|
||||
autoFlush: 1 # Fixes sun shinging through surfaces and graphical corruptions.
|
||||
halfPixelOffset: 2 # Fixes misaligned blur.
|
||||
cpuSpriteRenderBW: 2 # Fixes black spots appearing on some surfaces and massively reduces RP TC and TU count.
|
||||
cpuSpriteRenderLevel: 2 # Needed for above.
|
||||
nativeScaling: 2 # Fixes bloom misaligment.
|
||||
SLPM-66080:
|
||||
name: "GENERATION OF CHAOSIII 〜時の封印〜 [IFコレクション]"
|
||||
name-sort: "じぇねれーしょんおぶかおす 3 ときのふういん [あいであふぁくとりーこれくしょん]"
|
||||
@@ -45765,11 +45814,10 @@ SLPM-66514:
|
||||
name-en: "Medal of Honor - European Assault [EA Best Hits]"
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 2
|
||||
recommendedBlendingLevel: 3 # Fixes banding and level lighting.
|
||||
autoFlush: 1 # Fixes sun shinging through surfaces and graphical corruptions.
|
||||
halfPixelOffset: 2 # Fixes misaligned blur.
|
||||
cpuSpriteRenderBW: 2 # Fixes black spots appearing on some surfaces and massively reduces RP TC and TU count.
|
||||
cpuSpriteRenderLevel: 2 # Needed for above.
|
||||
nativeScaling: 2 # Fixes bloom misaligment.
|
||||
SLPM-66515:
|
||||
name: "EA BEST HITS スター・ウォーズ エピソード3 シスの復讐"
|
||||
name-sort: "すたーうぉーず えぴそーど3 しすのふくしゅう [EA BEST HITS]"
|
||||
@@ -54257,6 +54305,14 @@ SLPS-25408:
|
||||
- "SLPS-25339"
|
||||
- "SLPS-73202"
|
||||
- "SLPS-73203"
|
||||
dynaPatches:
|
||||
- pattern:
|
||||
- { offset: 0x0, value: 0x3C023E4C }
|
||||
- { offset: 0x4, value: 0x3442CCCD }
|
||||
- { offset: 0x8, value: 0xE7A300D0 }
|
||||
- { offset: 0xC, value: 0xE7A200D4 }
|
||||
replacement:
|
||||
- { offset: 0x4, value: 0x3442CCE0 }
|
||||
SLPS-25409:
|
||||
name: "双恋—フタコイ— 初回限定版"
|
||||
name-sort: "ふたこい しょかいげんていばん"
|
||||
@@ -61012,6 +61068,8 @@ SLUS-20567:
|
||||
name: "P.T.O. IV - Pacific Theater of Operations"
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
minimumBlendingLevel: 3 # Fixes graphical flickering.
|
||||
SLUS-20568:
|
||||
name: "Hard Hitter Tennis"
|
||||
region: "NTSC-U"
|
||||
@@ -64086,6 +64144,10 @@ SLUS-21113:
|
||||
name: "Atelier Iris - Eternal Mana"
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- SoftwareRendererFMVHack # Fixes horizontal lines in FMV and prevents hash cache from disabling itself.
|
||||
gsHWFixes:
|
||||
roundSprite: 2 # Fixes character portraits when upscaling and reduces lines in FMVs when using HW renderer.
|
||||
SLUS-21114:
|
||||
name: "NHRA Championship Drag Racing"
|
||||
region: "NTSC-U"
|
||||
@@ -64556,11 +64618,10 @@ SLUS-21199:
|
||||
region: "NTSC-U"
|
||||
compat: 5
|
||||
gsHWFixes:
|
||||
recommendedBlendingLevel: 2
|
||||
recommendedBlendingLevel: 3 # Fixes banding and level lighting.
|
||||
autoFlush: 1 # Fixes sun shinging through surfaces and graphical corruptions.
|
||||
halfPixelOffset: 2 # Fixes misaligned blur.
|
||||
cpuSpriteRenderBW: 2 # Fixes black spots appearing on some surfaces and massively reduces RP TC and TU count.
|
||||
cpuSpriteRenderLevel: 2 # Needed for above.
|
||||
nativeScaling: 2 # Fixes bloom misaligment.
|
||||
SLUS-21200:
|
||||
name: "Armored Core - Nine Breaker"
|
||||
region: "NTSC-U"
|
||||
@@ -64574,6 +64635,14 @@ SLUS-21200:
|
||||
- "SLUS-21200"
|
||||
- "SLUS-20986"
|
||||
- "SLUS-21079"
|
||||
dynaPatches:
|
||||
- pattern:
|
||||
- { offset: 0x0, value: 0x3C023E4C }
|
||||
- { offset: 0x4, value: 0x3442CCCD }
|
||||
- { offset: 0x8, value: 0xE7A300D0 }
|
||||
- { offset: 0xC, value: 0xE7A200D4 }
|
||||
replacement:
|
||||
- { offset: 0x4, value: 0x3442CCE0 }
|
||||
SLUS-21201:
|
||||
name: "Tales of Legendia"
|
||||
region: "NTSC-U"
|
||||
|
||||
@@ -109,6 +109,9 @@
|
||||
03000000491900001904000000000000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Windows,
|
||||
03000000710100001904000000000000,Amazon Luna Controller,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b8,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b4,rightstick:b7,rightx:a3,righty:a4,start:b6,x:b3,y:b2,platform:Windows,
|
||||
0300000008100000e501000000000000,Anbernic Game Pad,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||
03000000020500000913000000000000,Anbernic RG P01,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
|
||||
03000000373500000710000000000000,Anbernic RG P01,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||
03000000373500004610000000000000,Anbernic RG P01,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||
03000000830500000160000000000000,Arcade,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b3,x:b4,y:b4,platform:Windows,
|
||||
03000000120c0000100e000000000000,Armor 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||
03000000490b00004406000000000000,ASCII Seamic Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,
|
||||
@@ -498,6 +501,8 @@
|
||||
03000000d620000012a7000000000000,PowerA Fusion Nintendo Switch Fight Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||
03000000dd62000016a7000000000000,PowerA Fusion Pro Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||
03000000d620000013a7000000000000,PowerA Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||
03000000d62000003340000000000000,PowerA OPS Pro Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||
03000000d62000002640000000000000,PowerA OPS Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||
03000000d62000006dca000000000000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||
0300000062060000d570000000000000,PowerA PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||
03000000d620000014a7000000000000,PowerA Spectra Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||
@@ -879,6 +884,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
03000000491900001904000001010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Mac OS X,
|
||||
03000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Mac OS X,
|
||||
0300000008100000e501000019040000,Anbernic Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a4,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||
03000000373500004610000001000000,Anbernic RG P01,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||
03000000a30c00002700000003030000,Astro City Mini,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||
03000000a30c00002800000003030000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a3,lefty:a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||
03000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
|
||||
@@ -1202,6 +1208,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
03000000491900001904000011010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Linux,
|
||||
05000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
|
||||
0300000008100000e501000001010000,Anbernic Gamepad,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a4,start:b11,x:b3,y:b4,platform:Linux,
|
||||
03000000020500000913000010010000,Anbernic RG P01,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
03000000373500000710000010010000,Anbernic RG P01,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
030000005e0400008e02000072050000,Anbernic RG P01,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
05000000373500004610000001000000,Anbernic RG P01,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
03000000790000003018000011010000,Arcade Fightstick F300,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000a30c00002700000011010000,Astro City Mini,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
|
||||
03000000a30c00002800000011010000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
|
||||
@@ -1524,6 +1534,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
05000000504c415953544154494f4e00,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,
|
||||
060000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,
|
||||
030000004c050000a00b000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
|
||||
030000004c050000c405000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
|
||||
030000004c050000a00b000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
|
||||
030000004c050000c405000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
|
||||
030000004c050000c405000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
|
||||
|
||||
@@ -287,3 +287,58 @@ int main() {
|
||||
set(HOST_CACHE_LINE_SIZE ${detect_cache_line_size_output} CACHE STRING "Reported host cache line size")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(get_recursive_include_directories output target inc_prop link_prop)
|
||||
get_target_property(dirs ${target} ${inc_prop})
|
||||
if(NOT dirs)
|
||||
set(dirs)
|
||||
endif()
|
||||
get_target_property(deps ${target} ${link_prop})
|
||||
if(deps)
|
||||
foreach(dep IN LISTS deps)
|
||||
if(TARGET ${dep})
|
||||
get_recursive_include_directories(depdirs ${dep} INTERFACE_INCLUDE_DIRECTORIES INTERFACE_LINK_LIBRARIES)
|
||||
foreach(depdir IN LISTS depdirs)
|
||||
# Only match absolute paths
|
||||
# We'll hope any non-absolute paths will not get set as system directories
|
||||
if(depdir MATCHES "^/")
|
||||
list(APPEND dirs ${depdir})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES dirs)
|
||||
endif()
|
||||
set(${output} "${dirs}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(force_include_last_impl target include inc_prop link_prop)
|
||||
get_recursive_include_directories(dirs ${target} ${inc_prop} ${link_prop})
|
||||
set(remove)
|
||||
foreach(dir IN LISTS dirs)
|
||||
if("${dir}" MATCHES "${include}")
|
||||
list(APPEND remove ${dir})
|
||||
endif()
|
||||
endforeach()
|
||||
if(NOT "${remove}" STREQUAL "")
|
||||
get_target_property(sysdirs ${target} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES)
|
||||
if(NOT sysdirs)
|
||||
set(sysdirs)
|
||||
endif()
|
||||
# Move matching items to the end
|
||||
list(REMOVE_ITEM dirs ${remove})
|
||||
list(APPEND dirs ${remove})
|
||||
# Set them as system include directories
|
||||
list(APPEND sysdirs ${remove})
|
||||
list(REMOVE_DUPLICATES sysdirs)
|
||||
set_target_properties(${target} PROPERTIES
|
||||
${inc_prop} "${dirs}"
|
||||
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${sysdirs}"
|
||||
)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(force_include_last target include)
|
||||
force_include_last_impl(${target} "${include}" INTERFACE_INCLUDE_DIRECTORIES INTERFACE_LINK_LIBRARIES)
|
||||
force_include_last_impl(${target} "${include}" INCLUDE_DIRECTORIES LINK_LIBRARIES)
|
||||
endfunction()
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
#include "QtProgressCallback.h"
|
||||
#include "QtUtils.h"
|
||||
|
||||
#include "pcsx2/BuildVersion.h"
|
||||
#include "pcsx2/Host.h"
|
||||
#include "svnrev.h"
|
||||
|
||||
#include "updater/UpdaterExtractor.h"
|
||||
|
||||
@@ -47,12 +47,6 @@
|
||||
// Interval at which HTTP requests are polled.
|
||||
static constexpr u32 HTTP_POLL_INTERVAL = 10;
|
||||
|
||||
// Logic to detect whether we can use the auto updater.
|
||||
// We use tagged commit, because this gets set on nightly builds.
|
||||
#if (defined(_WIN32) || defined(__linux__) || defined(__APPLE__)) && GIT_TAGGED_COMMIT
|
||||
|
||||
#define AUTO_UPDATER_SUPPORTED 1
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define UPDATE_PLATFORM_STR "Windows"
|
||||
#elif defined(__linux__)
|
||||
@@ -69,10 +63,6 @@ static constexpr u32 HTTP_POLL_INTERVAL = 10;
|
||||
#define UPDATE_ADDITIONAL_TAGS "SSE4"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef AUTO_UPDATER_SUPPORTED
|
||||
|
||||
#define LATEST_RELEASE_URL "https://api.pcsx2.net/v1/%1Releases?pageSize=1"
|
||||
#define CHANGES_URL "https://api.github.com/repos/PCSX2/pcsx2/compare/%1...%2"
|
||||
|
||||
@@ -87,8 +77,6 @@ static const char* UPDATE_TAGS[] = {"stable", "nightly"};
|
||||
#define DEFAULT_UPDATER_CHANNEL "nightly"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
AutoUpdaterDialog::AutoUpdaterDialog(QWidget* parent /* = nullptr */)
|
||||
: QDialog(parent)
|
||||
{
|
||||
@@ -109,7 +97,11 @@ AutoUpdaterDialog::~AutoUpdaterDialog() = default;
|
||||
|
||||
bool AutoUpdaterDialog::isSupported()
|
||||
{
|
||||
#ifdef AUTO_UPDATER_SUPPORTED
|
||||
// Logic to detect whether we can use the auto updater.
|
||||
// We use tagged commit, because this gets set on nightly builds.
|
||||
if (!BuildVersion::GitTaggedCommit)
|
||||
return false;
|
||||
|
||||
#ifdef __linux__
|
||||
// For Linux, we need to check whether we're running from the appimage.
|
||||
if (!std::getenv("APPIMAGE"))
|
||||
@@ -119,10 +111,9 @@ bool AutoUpdaterDialog::isSupported()
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
#elif defined(_WIN32) || defined(__APPLE__)
|
||||
// Windows, MacOS - always supported.
|
||||
return true;
|
||||
#endif
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
@@ -130,39 +121,36 @@ bool AutoUpdaterDialog::isSupported()
|
||||
|
||||
QStringList AutoUpdaterDialog::getTagList()
|
||||
{
|
||||
#ifdef AUTO_UPDATER_SUPPORTED
|
||||
if (!isSupported())
|
||||
return QStringList();
|
||||
|
||||
return QStringList(std::begin(UPDATE_TAGS), std::end(UPDATE_TAGS));
|
||||
#else
|
||||
return QStringList();
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string AutoUpdaterDialog::getDefaultTag()
|
||||
{
|
||||
#ifdef AUTO_UPDATER_SUPPORTED
|
||||
if (!isSupported())
|
||||
return {};
|
||||
|
||||
return DEFAULT_UPDATER_CHANNEL;
|
||||
#else
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
|
||||
QString AutoUpdaterDialog::getCurrentVersion()
|
||||
{
|
||||
return QStringLiteral(GIT_TAG);
|
||||
return QString(BuildVersion::GitTag);
|
||||
}
|
||||
|
||||
QString AutoUpdaterDialog::getCurrentVersionDate()
|
||||
{
|
||||
return QStringLiteral(GIT_DATE);
|
||||
return QString(BuildVersion::GitDate);
|
||||
}
|
||||
|
||||
QString AutoUpdaterDialog::getCurrentUpdateTag() const
|
||||
{
|
||||
#ifdef AUTO_UPDATER_SUPPORTED
|
||||
if (!isSupported())
|
||||
return QString();
|
||||
|
||||
return QString::fromStdString(Host::GetBaseStringSettingValue("AutoUpdater", "UpdateTag", DEFAULT_UPDATER_CHANNEL));
|
||||
#else
|
||||
return QString();
|
||||
#endif
|
||||
}
|
||||
|
||||
void AutoUpdaterDialog::reportError(const char* msg, ...)
|
||||
@@ -215,18 +203,21 @@ void AutoUpdaterDialog::queueUpdateCheck(bool display_message)
|
||||
{
|
||||
m_display_messages = display_message;
|
||||
|
||||
#ifdef AUTO_UPDATER_SUPPORTED
|
||||
if (!ensureHttpReady())
|
||||
if (isSupported())
|
||||
{
|
||||
if (!ensureHttpReady())
|
||||
{
|
||||
emit updateCheckCompleted();
|
||||
return;
|
||||
}
|
||||
|
||||
m_http->CreateRequest(QStringLiteral(LATEST_RELEASE_URL).arg(getCurrentUpdateTag()).toStdString(),
|
||||
std::bind(&AutoUpdaterDialog::getLatestReleaseComplete, this, std::placeholders::_1, std::placeholders::_3));
|
||||
}
|
||||
else
|
||||
{
|
||||
emit updateCheckCompleted();
|
||||
return;
|
||||
}
|
||||
|
||||
m_http->CreateRequest(QStringLiteral(LATEST_RELEASE_URL).arg(getCurrentUpdateTag()).toStdString(),
|
||||
std::bind(&AutoUpdaterDialog::getLatestReleaseComplete, this, std::placeholders::_1, std::placeholders::_3));
|
||||
#else
|
||||
emit updateCheckCompleted();
|
||||
#endif
|
||||
}
|
||||
|
||||
void AutoUpdaterDialog::getLatestReleaseComplete(s32 status_code, std::vector<u8> data)
|
||||
@@ -236,7 +227,9 @@ void AutoUpdaterDialog::getLatestReleaseComplete(s32 status_code, std::vector<u8
|
||||
cpuinfo_initialize();
|
||||
#endif
|
||||
|
||||
#ifdef AUTO_UPDATER_SUPPORTED
|
||||
if (!isSupported())
|
||||
return;
|
||||
|
||||
bool found_update_info = false;
|
||||
|
||||
if (status_code == HTTPDownloader::HTTP_STATUS_OK)
|
||||
@@ -373,23 +366,25 @@ void AutoUpdaterDialog::getLatestReleaseComplete(s32 status_code, std::vector<u8
|
||||
checkIfUpdateNeeded();
|
||||
|
||||
emit updateCheckCompleted();
|
||||
#endif
|
||||
}
|
||||
|
||||
void AutoUpdaterDialog::queueGetChanges()
|
||||
{
|
||||
#ifdef AUTO_UPDATER_SUPPORTED
|
||||
if (!ensureHttpReady())
|
||||
if (!isSupported() || !ensureHttpReady())
|
||||
return;
|
||||
|
||||
m_http->CreateRequest(QStringLiteral(CHANGES_URL).arg(GIT_HASH).arg(m_latest_version).toStdString(),
|
||||
m_http->CreateRequest(QStringLiteral(CHANGES_URL).arg(BuildVersion::GitHash).arg(m_latest_version).toStdString(),
|
||||
std::bind(&AutoUpdaterDialog::getChangesComplete, this, std::placeholders::_1, std::placeholders::_3));
|
||||
#endif
|
||||
}
|
||||
|
||||
void AutoUpdaterDialog::getChangesComplete(s32 status_code, std::vector<u8> data)
|
||||
{
|
||||
#ifdef AUTO_UPDATER_SUPPORTED
|
||||
if (!isSupported())
|
||||
{
|
||||
m_ui.downloadAndInstall->setEnabled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (status_code == HTTPDownloader::HTTP_STATUS_OK)
|
||||
{
|
||||
QJsonParseError parse_error;
|
||||
@@ -456,7 +451,6 @@ void AutoUpdaterDialog::getChangesComplete(s32 status_code, std::vector<u8> data
|
||||
{
|
||||
reportError("Failed to download change list: %d", status_code);
|
||||
}
|
||||
#endif
|
||||
|
||||
m_ui.downloadAndInstall->setEnabled(true);
|
||||
}
|
||||
@@ -542,10 +536,10 @@ void AutoUpdaterDialog::checkIfUpdateNeeded()
|
||||
const QString last_checked_version(
|
||||
QString::fromStdString(Host::GetBaseStringSettingValue("AutoUpdater", "LastVersion")));
|
||||
|
||||
Console.WriteLn(Color_StrongGreen, "Current version: %s", GIT_TAG);
|
||||
Console.WriteLn(Color_StrongGreen, "Current version: %s", BuildVersion::GitTag);
|
||||
Console.WriteLn(Color_StrongYellow, "Latest version: %s", m_latest_version.toUtf8().constData());
|
||||
Console.WriteLn(Color_StrongOrange, "Last checked version: %s", last_checked_version.toUtf8().constData());
|
||||
if (m_latest_version == GIT_TAG || m_latest_version == last_checked_version)
|
||||
if (m_latest_version == BuildVersion::GitTag || m_latest_version == last_checked_version)
|
||||
{
|
||||
Console.WriteLn(Color_StrongGreen, "No update needed.");
|
||||
|
||||
@@ -787,7 +781,7 @@ void AutoUpdaterDialog::cleanupAfterUpdate()
|
||||
|
||||
static QString UpdateVersionNumberInName(QString name, QStringView new_version)
|
||||
{
|
||||
QString current_version_string = QStringLiteral(GIT_TAG);
|
||||
QString current_version_string(BuildVersion::GitTag);
|
||||
QStringView current_version = current_version_string;
|
||||
if (!current_version.empty() && !new_version.empty() && current_version[0] == 'v' && new_version[0] == 'v')
|
||||
{
|
||||
|
||||
@@ -80,6 +80,8 @@ void BreakpointDialog::onRdoButtonToggled()
|
||||
|
||||
void BreakpointDialog::accept()
|
||||
{
|
||||
std::string error;
|
||||
|
||||
if (m_purpose == PURPOSE::CREATE)
|
||||
{
|
||||
if (m_ui.rdoExecute->isChecked())
|
||||
@@ -93,9 +95,9 @@ void BreakpointDialog::accept()
|
||||
PostfixExpression expr;
|
||||
|
||||
u64 address;
|
||||
if (!m_cpu->evaluateExpression(m_ui.txtAddress->text().toStdString().c_str(), address))
|
||||
if (!m_cpu->evaluateExpression(m_ui.txtAddress->text().toStdString().c_str(), address, error))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Invalid Address"), getExpressionError());
|
||||
QMessageBox::warning(this, tr("Invalid Address"), QString::fromStdString(error));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -108,9 +110,9 @@ void BreakpointDialog::accept()
|
||||
bp->hasCond = true;
|
||||
bp->cond.debug = m_cpu;
|
||||
|
||||
if (!m_cpu->initExpression(m_ui.txtCondition->text().toStdString().c_str(), expr))
|
||||
if (!m_cpu->initExpression(m_ui.txtCondition->text().toStdString().c_str(), expr, error))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Invalid Condition"), getExpressionError());
|
||||
QMessageBox::warning(this, tr("Invalid Condition"), QString::fromStdString(error));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -121,16 +123,16 @@ void BreakpointDialog::accept()
|
||||
if (auto* mc = std::get_if<MemCheck>(&m_bp_mc))
|
||||
{
|
||||
u64 startAddress;
|
||||
if (!m_cpu->evaluateExpression(m_ui.txtAddress->text().toStdString().c_str(), startAddress))
|
||||
if (!m_cpu->evaluateExpression(m_ui.txtAddress->text().toStdString().c_str(), startAddress, error))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Invalid Address"), getExpressionError());
|
||||
QMessageBox::warning(this, tr("Invalid Address"), QString::fromStdString(error));
|
||||
return;
|
||||
}
|
||||
|
||||
u64 size;
|
||||
if (!m_cpu->evaluateExpression(m_ui.txtSize->text().toStdString().c_str(), size) || !size)
|
||||
if (!m_cpu->evaluateExpression(m_ui.txtSize->text().toStdString().c_str(), size, error) || !size)
|
||||
{
|
||||
QMessageBox::warning(this, tr("Invalid Size"), getExpressionError());
|
||||
QMessageBox::warning(this, tr("Invalid Size"), QString::fromStdString(error));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -143,9 +145,9 @@ void BreakpointDialog::accept()
|
||||
mc->cond.debug = m_cpu;
|
||||
|
||||
PostfixExpression expr;
|
||||
if (!m_cpu->initExpression(m_ui.txtCondition->text().toStdString().c_str(), expr))
|
||||
if (!m_cpu->initExpression(m_ui.txtCondition->text().toStdString().c_str(), expr, error))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Invalid Condition"), getExpressionError());
|
||||
QMessageBox::warning(this, tr("Invalid Condition"), QString::fromStdString(error));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -170,9 +170,10 @@ void DisassemblyWidget::contextGoToAddress()
|
||||
return;
|
||||
|
||||
u64 address = 0;
|
||||
if (!m_cpu->evaluateExpression(targetString.toStdString().c_str(), address))
|
||||
std::string error;
|
||||
if (!m_cpu->evaluateExpression(targetString.toStdString().c_str(), address, error))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Cannot Go To"), getExpressionError());
|
||||
QMessageBox::warning(this, tr("Cannot Go To"), QString::fromStdString(error));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -599,9 +599,10 @@ void MemoryViewWidget::contextGoToAddress()
|
||||
return;
|
||||
|
||||
u64 address = 0;
|
||||
if (!m_cpu->evaluateExpression(targetString.toStdString().c_str(), address))
|
||||
std::string error;
|
||||
if (!m_cpu->evaluateExpression(targetString.toStdString().c_str(), address, error))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Cannot Go To"), getExpressionError());
|
||||
QMessageBox::warning(this, tr("Cannot Go To"), QString::fromStdString(error));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -273,6 +273,8 @@ Qt::ItemFlags BreakpointModel::flags(const QModelIndex& index) const
|
||||
|
||||
bool BreakpointModel::setData(const QModelIndex& index, const QVariant& value, int role)
|
||||
{
|
||||
std::string error;
|
||||
|
||||
if (role == Qt::CheckStateRole && index.column() == BreakpointColumns::ENABLED)
|
||||
{
|
||||
auto bp_mc = m_breakpoints.at(index.row());
|
||||
@@ -314,9 +316,9 @@ bool BreakpointModel::setData(const QModelIndex& index, const QVariant& value, i
|
||||
{
|
||||
PostfixExpression expr;
|
||||
|
||||
if (!m_cpu.initExpression(condValue.toLocal8Bit().constData(), expr))
|
||||
if (!m_cpu.initExpression(condValue.toLocal8Bit().constData(), expr, error))
|
||||
{
|
||||
QMessageBox::warning(nullptr, "Condition Error", QString(getExpressionError()));
|
||||
QMessageBox::warning(nullptr, "Condition Error", QString::fromStdString(error));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -347,9 +349,9 @@ bool BreakpointModel::setData(const QModelIndex& index, const QVariant& value, i
|
||||
{
|
||||
PostfixExpression expr;
|
||||
|
||||
if (!m_cpu.initExpression(condValue.toLocal8Bit().constData(), expr))
|
||||
if (!m_cpu.initExpression(condValue.toLocal8Bit().constData(), expr, error))
|
||||
{
|
||||
QMessageBox::warning(nullptr, "Condition Error", QString(getExpressionError()));
|
||||
QMessageBox::warning(nullptr, "Condition Error", QString::fromStdString(error));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -456,17 +458,20 @@ void BreakpointModel::refreshData()
|
||||
|
||||
void BreakpointModel::loadBreakpointFromFieldList(QStringList fields)
|
||||
{
|
||||
std::string error;
|
||||
|
||||
bool ok;
|
||||
if (fields.size() != BreakpointModel::BreakpointColumns::COLUMN_COUNT)
|
||||
if (fields.size() != BreakpointColumns::COLUMN_COUNT)
|
||||
{
|
||||
Console.WriteLn("Debugger Breakpoint Model: Invalid number of columns, skipping");
|
||||
return;
|
||||
}
|
||||
|
||||
const int type = fields[BreakpointModel::BreakpointColumns::TYPE].toUInt(&ok);
|
||||
const int type = fields[BreakpointColumns::TYPE].toUInt(&ok);
|
||||
if (!ok)
|
||||
{
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse type '%s', skipping", fields[BreakpointModel::BreakpointColumns::TYPE].toUtf8().constData());
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse type '%s', skipping",
|
||||
fields[BreakpointColumns::TYPE].toUtf8().constData());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -476,34 +481,37 @@ void BreakpointModel::loadBreakpointFromFieldList(QStringList fields)
|
||||
BreakPoint bp;
|
||||
|
||||
// Address
|
||||
bp.addr = fields[BreakpointModel::BreakpointColumns::OFFSET].toUInt(&ok, 16);
|
||||
bp.addr = fields[BreakpointColumns::OFFSET].toUInt(&ok, 16);
|
||||
if (!ok)
|
||||
{
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse address '%s', skipping", fields[BreakpointModel::BreakpointColumns::OFFSET].toUtf8().constData());
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse address '%s', skipping",
|
||||
fields[BreakpointColumns::OFFSET].toUtf8().constData());
|
||||
return;
|
||||
}
|
||||
|
||||
// Condition
|
||||
if (!fields[BreakpointModel::BreakpointColumns::CONDITION].isEmpty())
|
||||
if (!fields[BreakpointColumns::CONDITION].isEmpty())
|
||||
{
|
||||
PostfixExpression expr;
|
||||
bp.hasCond = true;
|
||||
bp.cond.debug = &m_cpu;
|
||||
|
||||
if (!m_cpu.initExpression(fields[BreakpointModel::BreakpointColumns::CONDITION].toUtf8().constData(), expr))
|
||||
if (!m_cpu.initExpression(fields[BreakpointColumns::CONDITION].toUtf8().constData(), expr, error))
|
||||
{
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse cond '%s', skipping", fields[BreakpointModel::BreakpointColumns::CONDITION].toUtf8().constData());
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse cond '%s', skipping",
|
||||
fields[BreakpointModel::CONDITION].toUtf8().constData());
|
||||
return;
|
||||
}
|
||||
bp.cond.expression = expr;
|
||||
bp.cond.expressionString = fields[BreakpointModel::BreakpointColumns::CONDITION].toStdString();
|
||||
bp.cond.expressionString = fields[BreakpointColumns::CONDITION].toStdString();
|
||||
}
|
||||
|
||||
// Enabled
|
||||
bp.enabled = fields[BreakpointModel::BreakpointColumns::ENABLED].toUInt(&ok);
|
||||
bp.enabled = fields[BreakpointColumns::ENABLED].toUInt(&ok);
|
||||
if (!ok)
|
||||
{
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse enable flag '%s', skipping", fields[BreakpointModel::BreakpointColumns::ENABLED].toUtf8().constData());
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse enable flag '%s', skipping",
|
||||
fields[BreakpointColumns::ENABLED].toUtf8().constData());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -515,49 +523,54 @@ void BreakpointModel::loadBreakpointFromFieldList(QStringList fields)
|
||||
// Mode
|
||||
if (type >= MEMCHECK_INVALID)
|
||||
{
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse cond type '%s', skipping", fields[BreakpointModel::BreakpointColumns::TYPE].toUtf8().constData());
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse cond type '%s', skipping",
|
||||
fields[BreakpointColumns::TYPE].toUtf8().constData());
|
||||
return;
|
||||
}
|
||||
mc.memCond = static_cast<MemCheckCondition>(type);
|
||||
|
||||
// Address
|
||||
QString test = fields[BreakpointModel::BreakpointColumns::OFFSET];
|
||||
mc.start = fields[BreakpointModel::BreakpointColumns::OFFSET].toUInt(&ok, 16);
|
||||
QString test = fields[BreakpointColumns::OFFSET];
|
||||
mc.start = fields[BreakpointColumns::OFFSET].toUInt(&ok, 16);
|
||||
if (!ok)
|
||||
{
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse address '%s', skipping", fields[BreakpointModel::BreakpointColumns::OFFSET].toUtf8().constData());
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse address '%s', skipping",
|
||||
fields[BreakpointColumns::OFFSET].toUtf8().constData());
|
||||
return;
|
||||
}
|
||||
|
||||
// Size
|
||||
mc.end = fields[BreakpointModel::BreakpointColumns::SIZE_LABEL].toUInt(&ok) + mc.start;
|
||||
mc.end = fields[BreakpointColumns::SIZE_LABEL].toUInt(&ok) + mc.start;
|
||||
if (!ok)
|
||||
{
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse length '%s', skipping", fields[BreakpointModel::BreakpointColumns::SIZE_LABEL].toUtf8().constData());
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse length '%s', skipping",
|
||||
fields[BreakpointColumns::SIZE_LABEL].toUtf8().constData());
|
||||
return;
|
||||
}
|
||||
|
||||
// Condition
|
||||
if (!fields[BreakpointModel::BreakpointColumns::CONDITION].isEmpty())
|
||||
if (!fields[BreakpointColumns::CONDITION].isEmpty())
|
||||
{
|
||||
PostfixExpression expr;
|
||||
mc.hasCond = true;
|
||||
mc.cond.debug = &m_cpu;
|
||||
|
||||
if (!m_cpu.initExpression(fields[BreakpointModel::BreakpointColumns::CONDITION].toUtf8().constData(), expr))
|
||||
if (!m_cpu.initExpression(fields[BreakpointColumns::CONDITION].toUtf8().constData(), expr, error))
|
||||
{
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse cond '%s', skipping", fields[BreakpointModel::BreakpointColumns::CONDITION].toUtf8().constData());
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse cond '%s', skipping",
|
||||
fields[BreakpointColumns::CONDITION].toUtf8().constData());
|
||||
return;
|
||||
}
|
||||
mc.cond.expression = expr;
|
||||
mc.cond.expressionString = fields[BreakpointModel::BreakpointColumns::CONDITION].toStdString();
|
||||
mc.cond.expressionString = fields[BreakpointColumns::CONDITION].toStdString();
|
||||
}
|
||||
|
||||
// Result
|
||||
const int result = fields[BreakpointModel::BreakpointColumns::ENABLED].toUInt(&ok);
|
||||
const int result = fields[BreakpointColumns::ENABLED].toUInt(&ok);
|
||||
if (!ok)
|
||||
{
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse result flag '%s', skipping", fields[BreakpointModel::BreakpointColumns::ENABLED].toUtf8().constData());
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse result flag '%s', skipping",
|
||||
fields[BreakpointColumns::ENABLED].toUtf8().constData());
|
||||
return;
|
||||
}
|
||||
mc.result = static_cast<MemCheckResult>(result);
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#include "Settings/MemoryCardCreateDialog.h"
|
||||
#include "Tools/InputRecording/InputRecordingViewer.h"
|
||||
#include "Tools/InputRecording/NewInputRecordingDlg.h"
|
||||
#include "svnrev.h"
|
||||
|
||||
#include "pcsx2/Achievements.h"
|
||||
#include "pcsx2/CDVD/CDVDcommon.h"
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
#include "QtProgressCallback.h"
|
||||
#include "QtUtils.h"
|
||||
#include "SetupWizardDialog.h"
|
||||
#include "svnrev.h"
|
||||
|
||||
#include "pcsx2/CDVD/CDVDcommon.h"
|
||||
#include "pcsx2/Achievements.h"
|
||||
#include "pcsx2/BuildVersion.h"
|
||||
#include "pcsx2/CDVD/CDVD.h"
|
||||
#include "pcsx2/Counters.h"
|
||||
#include "pcsx2/DebugTools/Debug.h"
|
||||
@@ -998,8 +998,9 @@ void EmuThread::updatePerformanceMetrics(bool force)
|
||||
QString gs_stat;
|
||||
if (THREAD_VU1)
|
||||
{
|
||||
gs_stat = tr("Slot: %1 | %2 | EE: %3% | VU: %4% | GS: %5%")
|
||||
gs_stat = tr("Slot: %1 | Volume: %2% | %3 |EE: %4% | VU: %5% | GS: %6%")
|
||||
.arg(SaveStateSelectorUI::GetCurrentSlot())
|
||||
.arg(SPU2::GetOutputVolume())
|
||||
.arg(gs_stat_str.c_str())
|
||||
.arg(PerformanceMetrics::GetCPUThreadUsage(), 0, 'f', 0)
|
||||
.arg(PerformanceMetrics::GetVUThreadUsage(), 0, 'f', 0)
|
||||
@@ -1007,8 +1008,9 @@ void EmuThread::updatePerformanceMetrics(bool force)
|
||||
}
|
||||
else
|
||||
{
|
||||
gs_stat = tr("Slot: %1 | %2 | EE: %3% | GS: %4%")
|
||||
gs_stat = tr("Slot: %1 | Volume: %2% | 3% | EE: %4% | GS: %5%")
|
||||
.arg(SaveStateSelectorUI::GetCurrentSlot())
|
||||
.arg(SPU2::GetOutputVolume())
|
||||
.arg(gs_stat_str.c_str())
|
||||
.arg(PerformanceMetrics::GetCPUThreadUsage(), 0, 'f', 0)
|
||||
.arg(PerformanceMetrics::GetGSThreadUsage(), 0, 'f', 0);
|
||||
@@ -1468,7 +1470,7 @@ bool Host::RequestResetSettings(bool folders, bool core, bool controllers, bool
|
||||
|
||||
QString QtHost::GetAppNameAndVersion()
|
||||
{
|
||||
return QStringLiteral("PCSX2 " GIT_REV);
|
||||
return QString("PCSX2 %1").arg(BuildVersion::GitRev);
|
||||
}
|
||||
|
||||
QString QtHost::GetAppConfigSuffix()
|
||||
|
||||
@@ -37,8 +37,8 @@ DebugAnalysisSettingsWidget::DebugAnalysisSettingsWidget(QWidget* parent)
|
||||
}
|
||||
|
||||
m_ui.customAddressRange->setChecked(Host::GetBoolSettingValue("Debugger/Analysis", "CustomFunctionScanRange", false));
|
||||
m_ui.addressRangeStart->setText(QString::fromStdString(Host::GetStringSettingValue("Debugger/Analysis", "FunctionScanStartAddress", "0")));
|
||||
m_ui.addressRangeEnd->setText(QString::fromStdString(Host::GetStringSettingValue("Debugger/Analysis", "FunctionScanEndAddress", "0")));
|
||||
m_ui.addressRangeStart->setText(QString::fromStdString(Host::GetStringSettingValue("Debugger/Analysis", "FunctionScanStartAddress", "")));
|
||||
m_ui.addressRangeEnd->setText(QString::fromStdString(Host::GetStringSettingValue("Debugger/Analysis", "FunctionScanEndAddress", "")));
|
||||
|
||||
m_ui.grayOutOverwrittenFunctions->setChecked(Host::GetBoolSettingValue("Debugger/Analysis", "GenerateFunctionHashes", true));
|
||||
|
||||
@@ -104,7 +104,7 @@ DebugAnalysisSettingsWidget::DebugAnalysisSettingsWidget(SettingsWindow* dialog,
|
||||
else
|
||||
{
|
||||
m_ui.symbolFileLabel->hide();
|
||||
m_ui.symbolFileList->hide();
|
||||
m_ui.symbolFileTable->hide();
|
||||
m_ui.importSymbolFileButtons->hide();
|
||||
}
|
||||
|
||||
@@ -165,18 +165,19 @@ void DebugAnalysisSettingsWidget::parseSettingsFromWidgets(Pcsx2Config::DebugAna
|
||||
output.DemangleSymbols = m_ui.demangleSymbols->isChecked();
|
||||
output.DemangleParameters = m_ui.demangleParameters->isChecked();
|
||||
|
||||
for (int i = 0; i < m_ui.symbolFileList->count(); i++)
|
||||
for (int i = 0; i < m_symbol_file_model->rowCount(); i++)
|
||||
{
|
||||
DebugExtraSymbolFile& file = output.ExtraSymbolFiles.emplace_back();
|
||||
file.Path = m_ui.symbolFileList->item(i)->text().toStdString();
|
||||
|
||||
file.Path = m_symbol_file_model->item(i, PATH_COLUMN)->text().toStdString();
|
||||
file.BaseAddress = m_symbol_file_model->item(i, BASE_ADDRESS_COLUMN)->text().toStdString();
|
||||
file.Condition = m_symbol_file_model->item(i, CONDITION_COLUMN)->text().toStdString();
|
||||
}
|
||||
|
||||
output.FunctionScanMode = static_cast<DebugFunctionScanMode>(m_ui.functionScanMode->currentIndex());
|
||||
output.CustomFunctionScanRange = m_ui.customAddressRange->isChecked();
|
||||
output.FunctionScanStartAddress = m_ui.addressRangeStart->text().toStdString();
|
||||
output.FunctionScanEndAddress = m_ui.addressRangeEnd->text().toStdString();
|
||||
|
||||
output.GenerateFunctionHashes = m_ui.grayOutOverwrittenFunctions->isChecked();
|
||||
}
|
||||
|
||||
void DebugAnalysisSettingsWidget::setupSymbolSourceGrid()
|
||||
@@ -187,27 +188,12 @@ void DebugAnalysisSettingsWidget::setupSymbolSourceGrid()
|
||||
{
|
||||
// Add symbol sources for which the user has already selected whether or
|
||||
// not they should be cleared.
|
||||
int existing_symbol_source_count;
|
||||
if (m_dialog)
|
||||
existing_symbol_source_count = m_dialog->getEffectiveIntValue("Debugger/Analysis/SymbolSources", "Count", 0);
|
||||
else
|
||||
existing_symbol_source_count = Host::GetIntSettingValue("Debugger/Analysis/SymbolSources", "Count", 0);
|
||||
|
||||
int existing_symbol_source_count = getIntSettingValue("Debugger/Analysis/SymbolSources", "Count", 0);
|
||||
for (int i = 0; i < existing_symbol_source_count; i++)
|
||||
{
|
||||
std::string section = "Debugger/Analysis/SymbolSources/" + std::to_string(i);
|
||||
|
||||
std::string name;
|
||||
if (m_dialog)
|
||||
name = m_dialog->getEffectiveStringValue(section.c_str(), "Name", "");
|
||||
else
|
||||
name = Host::GetStringSettingValue(section.c_str(), "Name", "");
|
||||
|
||||
bool value;
|
||||
if (m_dialog)
|
||||
value = m_dialog->getEffectiveBoolValue(section.c_str(), "ClearDuringAnalysis", false);
|
||||
else
|
||||
value = Host::GetBoolSettingValue(section.c_str(), "ClearDuringAnalysis", false);
|
||||
std::string name = getStringSettingValue(section.c_str(), "Name", "");
|
||||
bool value = getBoolSettingValue(section.c_str(), "ClearDuringAnalysis", false);
|
||||
|
||||
SymbolSourceTemp& source = m_symbol_sources[name];
|
||||
source.previous_value = value;
|
||||
@@ -320,45 +306,100 @@ void DebugAnalysisSettingsWidget::saveSymbolSources()
|
||||
|
||||
void DebugAnalysisSettingsWidget::setupSymbolFileList()
|
||||
{
|
||||
int extra_symbol_file_count;
|
||||
if (m_dialog)
|
||||
extra_symbol_file_count = m_dialog->getEffectiveIntValue("Debugger/Analysis/ExtraSymbolFiles", "Count", 0);
|
||||
else
|
||||
extra_symbol_file_count = Host::GetIntSettingValue("Debugger/Analysis/ExtraSymbolFiles", "Count", 0);
|
||||
m_symbol_file_model = new QStandardItemModel(0, SYMBOL_FILE_COLUMN_COUNT, m_ui.symbolFileTable);
|
||||
|
||||
QStringList headers;
|
||||
headers.emplace_back(tr("Path"));
|
||||
headers.emplace_back(tr("Base Address"));
|
||||
headers.emplace_back(tr("Condition"));
|
||||
m_symbol_file_model->setHorizontalHeaderLabels(headers);
|
||||
|
||||
m_ui.symbolFileTable->setModel(m_symbol_file_model);
|
||||
|
||||
m_ui.symbolFileTable->horizontalHeader()->setSectionResizeMode(PATH_COLUMN, QHeaderView::Stretch);
|
||||
m_ui.symbolFileTable->horizontalHeader()->setSectionResizeMode(BASE_ADDRESS_COLUMN, QHeaderView::Fixed);
|
||||
m_ui.symbolFileTable->horizontalHeader()->setSectionResizeMode(CONDITION_COLUMN, QHeaderView::Fixed);
|
||||
|
||||
m_ui.symbolFileTable->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||
|
||||
int extra_symbol_file_count = getIntSettingValue("Debugger/Analysis/ExtraSymbolFiles", "Count", 0);
|
||||
for (int i = 0; i < extra_symbol_file_count; i++)
|
||||
{
|
||||
std::string section = "Debugger/Analysis/ExtraSymbolFiles/" + std::to_string(i);
|
||||
std::string path;
|
||||
if (m_dialog)
|
||||
path = m_dialog->getEffectiveStringValue(section.c_str(), "Path", "");
|
||||
else
|
||||
path = Host::GetStringSettingValue(section.c_str(), "Path", "");
|
||||
|
||||
m_ui.symbolFileList->addItem(QString::fromStdString(path));
|
||||
int row = m_symbol_file_model->rowCount();
|
||||
if (!m_symbol_file_model->insertRow(row))
|
||||
continue;
|
||||
|
||||
QStandardItem* path_item = new QStandardItem();
|
||||
path_item->setText(QString::fromStdString(getStringSettingValue(section.c_str(), "Path", "")));
|
||||
m_symbol_file_model->setItem(row, PATH_COLUMN, path_item);
|
||||
|
||||
QStandardItem* base_address_item = new QStandardItem();
|
||||
base_address_item->setText(QString::fromStdString(getStringSettingValue(section.c_str(), "BaseAddress")));
|
||||
m_symbol_file_model->setItem(row, BASE_ADDRESS_COLUMN, base_address_item);
|
||||
|
||||
QStandardItem* condition_item = new QStandardItem();
|
||||
condition_item->setText(QString::fromStdString(getStringSettingValue(section.c_str(), "Condition")));
|
||||
m_symbol_file_model->setItem(row, CONDITION_COLUMN, condition_item);
|
||||
}
|
||||
|
||||
connect(m_ui.addSymbolFile, &QPushButton::clicked, this, &DebugAnalysisSettingsWidget::addSymbolFile);
|
||||
connect(m_ui.removeSymbolFile, &QPushButton::clicked, this, &DebugAnalysisSettingsWidget::removeSymbolFile);
|
||||
|
||||
connect(m_ui.symbolFileTable->selectionModel(), &QItemSelectionModel::selectionChanged,
|
||||
this, &DebugAnalysisSettingsWidget::updateEnabledStates);
|
||||
|
||||
connect(m_symbol_file_model, &QStandardItemModel::dataChanged,
|
||||
this, &DebugAnalysisSettingsWidget::saveSymbolFiles);
|
||||
connect(m_symbol_file_model, &QStandardItemModel::dataChanged,
|
||||
this, &DebugAnalysisSettingsWidget::updateEnabledStates);
|
||||
}
|
||||
|
||||
void DebugAnalysisSettingsWidget::addSymbolFile()
|
||||
{
|
||||
QString path = QFileDialog::getOpenFileName(this, tr("Add Symbol File"));
|
||||
if (path.isEmpty())
|
||||
std::string path = Path::ToNativePath(QFileDialog::getOpenFileName(this, tr("Add Symbol File")).toStdString());
|
||||
if (path.empty())
|
||||
return;
|
||||
|
||||
m_ui.symbolFileList->addItem(path);
|
||||
std::string relative_path = Path::MakeRelative(path, EmuFolders::GameSettings);
|
||||
if (!relative_path.starts_with(".."))
|
||||
path = std::move(relative_path);
|
||||
|
||||
int row = m_symbol_file_model->rowCount();
|
||||
if (!m_symbol_file_model->insertRow(row))
|
||||
return;
|
||||
|
||||
QStandardItem* path_item = new QStandardItem();
|
||||
path_item->setText(QString::fromStdString(path));
|
||||
m_symbol_file_model->setItem(row, PATH_COLUMN, path_item);
|
||||
|
||||
QStandardItem* base_address_item = new QStandardItem();
|
||||
base_address_item->setText("");
|
||||
m_symbol_file_model->setItem(row, BASE_ADDRESS_COLUMN, base_address_item);
|
||||
|
||||
QStandardItem* condition_item = new QStandardItem();
|
||||
condition_item->setText("");
|
||||
m_symbol_file_model->setItem(row, CONDITION_COLUMN, condition_item);
|
||||
|
||||
saveSymbolFiles();
|
||||
updateEnabledStates();
|
||||
}
|
||||
|
||||
void DebugAnalysisSettingsWidget::removeSymbolFile()
|
||||
{
|
||||
for (QListWidgetItem* item : m_ui.symbolFileList->selectedItems())
|
||||
delete item;
|
||||
QItemSelectionModel* selection_model = m_ui.symbolFileTable->selectionModel();
|
||||
if (!selection_model)
|
||||
return;
|
||||
|
||||
while (!selection_model->selectedIndexes().isEmpty())
|
||||
{
|
||||
QModelIndex index = selection_model->selectedIndexes().first();
|
||||
m_symbol_file_model->removeRow(index.row(), index.parent());
|
||||
}
|
||||
|
||||
saveSymbolFiles();
|
||||
updateEnabledStates();
|
||||
}
|
||||
|
||||
void DebugAnalysisSettingsWidget::saveSymbolFiles()
|
||||
@@ -380,17 +421,24 @@ void DebugAnalysisSettingsWidget::saveSymbolFiles()
|
||||
|
||||
sif->RemoveSection("Debugger/Analysis/ExtraSymbolFiles");
|
||||
|
||||
if (m_ui.symbolFileList->count() == 0)
|
||||
if (m_symbol_file_model->rowCount() == 0)
|
||||
return;
|
||||
|
||||
// Make new configuration entries.
|
||||
sif->SetIntValue("Debugger/Analysis/ExtraSymbolFiles", "Count", m_ui.symbolFileList->count());
|
||||
sif->SetIntValue("Debugger/Analysis/ExtraSymbolFiles", "Count", m_symbol_file_model->rowCount());
|
||||
|
||||
for (int i = 0; i < m_ui.symbolFileList->count(); i++)
|
||||
for (int i = 0; i < m_symbol_file_model->rowCount(); i++)
|
||||
{
|
||||
std::string section = "Debugger/Analysis/ExtraSymbolFiles/" + std::to_string(i);
|
||||
std::string path = m_ui.symbolFileList->item(i)->text().toStdString();
|
||||
sif->SetStringValue(section.c_str(), "Path", path.c_str());
|
||||
|
||||
if (QStandardItem* path_item = m_symbol_file_model->item(i, PATH_COLUMN))
|
||||
sif->SetStringValue(section.c_str(), "Path", path_item->text().toStdString().c_str());
|
||||
|
||||
if (QStandardItem* base_address_item = m_symbol_file_model->item(i, BASE_ADDRESS_COLUMN))
|
||||
sif->SetStringValue(section.c_str(), "BaseAddress", base_address_item->text().toStdString().c_str());
|
||||
|
||||
if (QStandardItem* condition_item = m_symbol_file_model->item(i, CONDITION_COLUMN))
|
||||
sif->SetStringValue(section.c_str(), "Condition", condition_item->text().toStdString().c_str());
|
||||
}
|
||||
|
||||
QtHost::SaveGameSettings(sif, true);
|
||||
@@ -423,5 +471,34 @@ void DebugAnalysisSettingsWidget::updateEnabledStates()
|
||||
m_ui.symbolSourceScrollArea->setEnabled(!m_ui.automaticallyClearSymbols->isChecked());
|
||||
m_ui.symbolSourceErrorMessage->setEnabled(!m_ui.automaticallyClearSymbols->isChecked());
|
||||
m_ui.demangleParameters->setEnabled(m_ui.demangleSymbols->isChecked());
|
||||
m_ui.removeSymbolFile->setEnabled(
|
||||
m_ui.symbolFileTable->selectionModel() && m_ui.symbolFileTable->selectionModel()->hasSelection());
|
||||
m_ui.customAddressRangeLineEdits->setEnabled(m_ui.customAddressRange->isChecked());
|
||||
}
|
||||
|
||||
std::string DebugAnalysisSettingsWidget::getStringSettingValue(
|
||||
const char* section, const char* key, const char* default_value)
|
||||
{
|
||||
if (m_dialog)
|
||||
return m_dialog->getEffectiveStringValue(section, key, default_value);
|
||||
|
||||
return Host::GetStringSettingValue(section, key, default_value);
|
||||
}
|
||||
|
||||
bool DebugAnalysisSettingsWidget::getBoolSettingValue(
|
||||
const char* section, const char* key, bool default_value)
|
||||
{
|
||||
if (m_dialog)
|
||||
return m_dialog->getEffectiveBoolValue(section, key, default_value);
|
||||
|
||||
return Host::GetBoolSettingValue(section, key, default_value);
|
||||
}
|
||||
|
||||
int DebugAnalysisSettingsWidget::getIntSettingValue(
|
||||
const char* section, const char* key, int default_value)
|
||||
{
|
||||
if (m_dialog)
|
||||
return m_dialog->getEffectiveIntValue(section, key, default_value);
|
||||
|
||||
return Host::GetIntSettingValue(section, key, default_value);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "Config.h"
|
||||
|
||||
#include <QtGui/QStandardItemModel>
|
||||
#include <QtWidgets/QDialog>
|
||||
|
||||
class SettingsWindow;
|
||||
@@ -16,7 +17,7 @@ class DebugAnalysisSettingsWidget : public QWidget
|
||||
|
||||
public:
|
||||
// Create a widget that will discard any settings changed after it is
|
||||
// closed, for use in the dialog opened by the "Reanalyze" button.
|
||||
// closed, for use in the dialog opened by the "Analyze" button.
|
||||
DebugAnalysisSettingsWidget(QWidget* parent = nullptr);
|
||||
|
||||
// Create a widget that will write back any settings changed to the config
|
||||
@@ -42,6 +43,10 @@ protected:
|
||||
|
||||
void updateEnabledStates();
|
||||
|
||||
std::string getStringSettingValue(const char* section, const char* key, const char* default_value = "");
|
||||
bool getBoolSettingValue(const char* section, const char* key, bool default_value = false);
|
||||
int getIntSettingValue(const char* section, const char* key, int default_value = 0);
|
||||
|
||||
struct SymbolSourceTemp
|
||||
{
|
||||
QCheckBox* check_box = nullptr;
|
||||
@@ -49,8 +54,18 @@ protected:
|
||||
bool modified_by_user = false;
|
||||
};
|
||||
|
||||
enum SymbolFileColumn
|
||||
{
|
||||
PATH_COLUMN = 0,
|
||||
BASE_ADDRESS_COLUMN = 1,
|
||||
CONDITION_COLUMN = 2,
|
||||
SYMBOL_FILE_COLUMN_COUNT = 3
|
||||
};
|
||||
|
||||
SettingsWindow* m_dialog = nullptr;
|
||||
std::map<std::string, SymbolSourceTemp> m_symbol_sources;
|
||||
|
||||
QStandardItemModel* m_symbol_file_model;
|
||||
|
||||
Ui::DebugAnalysisSettingsWidget m_ui;
|
||||
};
|
||||
|
||||
@@ -171,7 +171,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="symbolFileList">
|
||||
<widget class="QTableView" name="symbolFileTable">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
@@ -184,9 +184,27 @@
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<property name="textElideMode">
|
||||
<enum>Qt::ElideLeft</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="horizontalHeaderHighlightSections">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderStretchLastSection">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,7 @@
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
|
||||
#include "Achievements.h"
|
||||
#include "BuildVersion.h"
|
||||
#include "CDVD/CDVD.h"
|
||||
#include "Elfheader.h"
|
||||
#include "Host.h"
|
||||
@@ -16,7 +17,6 @@
|
||||
#include "Memory.h"
|
||||
#include "SaveState.h"
|
||||
#include "VMManager.h"
|
||||
#include "svnrev.h"
|
||||
#include "vtlb.h"
|
||||
|
||||
#include "common/Assertions.h"
|
||||
@@ -3039,7 +3039,7 @@ void Achievements::SwitchToRAIntegration()
|
||||
|
||||
void Achievements::RAIntegration::InitializeRAIntegration(void* main_window_handle)
|
||||
{
|
||||
RA_InitClient((HWND)main_window_handle, "PCSX2", GIT_TAG);
|
||||
RA_InitClient((HWND)main_window_handle, "PCSX2", BuildVersion::GitTag);
|
||||
RA_SetUserAgentDetail(Host::GetHTTPUserAgent().c_str());
|
||||
|
||||
RA_InstallSharedFunctions(RACallbackIsActive, RACallbackCauseUnpause, RACallbackCausePause, RACallbackRebuildMenu,
|
||||
|
||||
16
pcsx2/BuildVersion.cpp
Normal file
16
pcsx2/BuildVersion.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
|
||||
#include "svnrev.h"
|
||||
|
||||
namespace BuildVersion
|
||||
{
|
||||
const char* GitTag = GIT_TAG;
|
||||
bool GitTaggedCommit = GIT_TAGGED_COMMIT;
|
||||
int GitTagHi = GIT_TAG_HI;
|
||||
int GitTagMid = GIT_TAG_MID;
|
||||
int GitTagLo = GIT_TAG_LO;
|
||||
const char* GitRev = GIT_REV;
|
||||
const char* GitHash = GIT_HASH;
|
||||
const char* GitDate = GIT_DATE;
|
||||
} // namespace BuildVersion
|
||||
18
pcsx2/BuildVersion.h
Normal file
18
pcsx2/BuildVersion.h
Normal file
@@ -0,0 +1,18 @@
|
||||
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
|
||||
#pragma once
|
||||
|
||||
// This file provides the same information as svnrev.h except you don't need to
|
||||
// recompile each object file using it when said information is updated.
|
||||
namespace BuildVersion
|
||||
{
|
||||
extern const char* GitTag;
|
||||
extern bool GitTaggedCommit;
|
||||
extern int GitTagHi;
|
||||
extern int GitTagMid;
|
||||
extern int GitTagLo;
|
||||
extern const char* GitRev;
|
||||
extern const char* GitHash;
|
||||
extern const char* GitDate;
|
||||
} // namespace BuildVersion
|
||||
@@ -3013,6 +3013,20 @@ void cdvdWrite(u8 key, u8 rt)
|
||||
case 0x08:
|
||||
cdvdWrite08(rt);
|
||||
break;
|
||||
case 0x09:
|
||||
/*
|
||||
The register 0xC, 0xD, 0xE give back MSF of the current sector being read/played from the actual DSP hardware. They are named "where" registers : where0, where1, where2.
|
||||
They can be read anytime on hw as long as there is a valid disc and mode configured properly. Register 0x9 is where_select register which determines the mode for this registers. The mode must be set according to the used disc.
|
||||
0 = CDDA
|
||||
1 = CDROM
|
||||
2 = DVD
|
||||
|
||||
If no disc or invalid mode for disc type then those registers return 0. Only official usage so far is cdvdman reading those registers and waiting to sync while doing SubQ.
|
||||
Only logging writes different than 0 is enough.
|
||||
*/
|
||||
if (rt != 0)
|
||||
Console.Warning("8bit write to addr 0x1f402009 = 0x%x", rt);
|
||||
break;
|
||||
case 0x0A:
|
||||
cdvdWrite0A(rt);
|
||||
break;
|
||||
@@ -3035,7 +3049,7 @@ void cdvdWrite(u8 key, u8 rt)
|
||||
cdvdWrite3A(rt);
|
||||
break;
|
||||
default:
|
||||
Console.Warning("IOP Unknown 8bit write to addr 0x1f4020%x = 0x%x", key, rt);
|
||||
Console.Warning("IOP Unknown 8bit write to addr 0x1f4020%02x = 0x%x", key, rt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "common/ProgressCallback.h"
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include <array>
|
||||
#include <ctype.h>
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
@@ -55,7 +56,7 @@ static OutputIsoFile blockDumpFile;
|
||||
// Information about tracks on disc
|
||||
u8 strack;
|
||||
u8 etrack;
|
||||
cdvdTrack tracks[100];
|
||||
std::array<cdvdTrack, 100> tracks;
|
||||
|
||||
// Assertion check for CDVD != NULL (in devel and debug builds), because its handier than
|
||||
// relying on DEP exceptions -- and a little more reliable too.
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
class Error;
|
||||
class ProgressCallback;
|
||||
|
||||
typedef struct _cdvdTrackIndex
|
||||
struct cdvdTrackIndex
|
||||
{
|
||||
bool isPregap;
|
||||
u8 trackM; // current minute offset from first track (BCD encoded)
|
||||
@@ -20,9 +20,9 @@ typedef struct _cdvdTrackIndex
|
||||
u8 discS; // current sector location on the disc (BCD encoded)
|
||||
u8 discF; // current frame location on the disc (BCD encoded)
|
||||
|
||||
} cdvdTrackIndex;
|
||||
};
|
||||
|
||||
typedef struct _cdvdTrack
|
||||
struct cdvdTrack
|
||||
{
|
||||
u32 start_lba; // Starting lba of track, note that some formats will be missing 2 seconds, cue, bin
|
||||
u8 type; // Track Type
|
||||
@@ -36,10 +36,10 @@ typedef struct _cdvdTrack
|
||||
u8 discF; // current frame location on the disc (BCD encoded)
|
||||
|
||||
// 0 is pregap, 1 is data
|
||||
_cdvdTrackIndex index[2];
|
||||
} cdvdTrack;
|
||||
cdvdTrackIndex index[2];
|
||||
};
|
||||
|
||||
typedef struct _cdvdSubQ
|
||||
struct cdvdSubQ
|
||||
{
|
||||
u8 ctrl : 4; // control and adr bits
|
||||
u8 adr : 4; // control and adr bits, note that adr determines what SubQ info we're recieving.
|
||||
@@ -52,19 +52,27 @@ typedef struct _cdvdSubQ
|
||||
u8 discM; // current minute location on the disc (BCD encoded)
|
||||
u8 discS; // current sector location on the disc (BCD encoded)
|
||||
u8 discF; // current frame location on the disc (BCD encoded)
|
||||
} cdvdSubQ;
|
||||
};
|
||||
|
||||
typedef struct _cdvdTD
|
||||
struct cdvdTD
|
||||
{ // NOT bcd coded
|
||||
u32 lsn;
|
||||
u8 type;
|
||||
} cdvdTD;
|
||||
};
|
||||
|
||||
typedef struct _cdvdTN
|
||||
struct cdvdTN
|
||||
{
|
||||
u8 strack; //number of the first track (usually 1)
|
||||
u8 etrack; //number of the last track
|
||||
} cdvdTN;
|
||||
};
|
||||
|
||||
struct toc_entry
|
||||
{
|
||||
u32 lba;
|
||||
u8 track;
|
||||
u8 adr : 4;
|
||||
u8 control : 4;
|
||||
};
|
||||
|
||||
// SpindleCtrl Masks
|
||||
#define CDVD_SPINDLE_SPEED 0x7 // Speed ranges from 0-3 (1, 2, 3, 4x for DVD) and 0-5 (1, 2, 4, 12, 24x for CD)
|
||||
@@ -185,7 +193,7 @@ extern const CDVD_API CDVDapi_NoDisc;
|
||||
|
||||
extern u8 strack;
|
||||
extern u8 etrack;
|
||||
extern cdvdTrack tracks[100];
|
||||
extern std::array<cdvdTrack, 100> tracks;
|
||||
|
||||
extern void CDVDsys_ChangeSource(CDVD_SourceType type);
|
||||
extern void CDVDsys_SetFile(CDVD_SourceType srctype, std::string newfile);
|
||||
|
||||
@@ -54,7 +54,7 @@ static void lsn_to_msf(u8* minute, u8* second, u8* frame, u32 lsn)
|
||||
// TocStuff
|
||||
void cdvdParseTOC()
|
||||
{
|
||||
tracks[1].start_lba = 0;
|
||||
tracks.fill(cdvdTrack{});
|
||||
|
||||
if (!src->GetSectorCount())
|
||||
{
|
||||
@@ -76,35 +76,37 @@ void cdvdParseTOC()
|
||||
strack = 0xFF;
|
||||
etrack = 0;
|
||||
|
||||
int i = 0;
|
||||
|
||||
for (auto& entry : src->ReadTOC())
|
||||
{
|
||||
if (entry.track < 1 || entry.track > 99)
|
||||
const u8 track = entry.track;
|
||||
if (track < 1 || track >= tracks.size())
|
||||
{
|
||||
Console.Warning("CDVD: Invalid track index %u, ignoring\n", track);
|
||||
continue;
|
||||
strack = std::min(strack, entry.track);
|
||||
etrack = std::max(etrack, entry.track);
|
||||
tracks[i].start_lba = entry.lba;
|
||||
}
|
||||
strack = std::min(strack, track);
|
||||
etrack = std::max(etrack, track);
|
||||
tracks[track].start_lba = entry.lba;
|
||||
if ((entry.control & 0x0C) == 0x04)
|
||||
{
|
||||
std::array<u8, 2352> buffer;
|
||||
// Byte 15 of a raw CD data sector determines the track mode
|
||||
if (src->ReadSectors2352(entry.lba, 1, buffer.data()) && (buffer[15] & 3) == 2)
|
||||
{
|
||||
tracks[i].type = CDVD_MODE2_TRACK;
|
||||
tracks[track].type = CDVD_MODE2_TRACK;
|
||||
}
|
||||
else
|
||||
{
|
||||
tracks[i].type = CDVD_MODE1_TRACK;
|
||||
tracks[track].type = CDVD_MODE1_TRACK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tracks[i].type = CDVD_AUDIO_TRACK;
|
||||
tracks[track].type = CDVD_AUDIO_TRACK;
|
||||
}
|
||||
fprintf(stderr, "Track %u start sector: %u\n", entry.track, entry.lba);
|
||||
|
||||
i += 1;
|
||||
#ifdef PCSX2_DEBUG
|
||||
DevCon.WriteLn("cdvdParseTOC: Track %u: LBA %u, Type %u\n", track, tracks[track].start_lba, tracks[track].type);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +133,7 @@ static void keepAliveThread()
|
||||
std::unique_lock<std::mutex> guard(s_keepalive_lock);
|
||||
|
||||
while (!s_keepalive_cv.wait_for(guard, std::chrono::seconds(30),
|
||||
[]() { return !s_keepalive_is_open; }))
|
||||
[]() { return !s_keepalive_is_open; }))
|
||||
{
|
||||
|
||||
//printf(" * keepAliveThread: polling drive.\n");
|
||||
@@ -271,20 +273,28 @@ static s32 DISCreadSubQ(u32 lsn, cdvdSubQ* subq)
|
||||
|
||||
memset(subq, 0, sizeof(cdvdSubQ));
|
||||
|
||||
lsn_to_msf(&subq->discM, &subq->discS, &subq->discF, lsn + 150);
|
||||
|
||||
u8 i = strack;
|
||||
while (i < etrack && lsn >= tracks[i + 1].start_lba)
|
||||
++i;
|
||||
|
||||
lsn -= tracks[i].start_lba;
|
||||
|
||||
lsn_to_msf(&subq->trackM, &subq->trackS, &subq->trackF, lsn);
|
||||
|
||||
subq->ctrl = tracks[i].type;
|
||||
|
||||
// It's important to note that we do _not_ use the current MSF values
|
||||
// from the host's device. We use the MSF values from the lsn.
|
||||
// An easy way to test an implementation is to see if the OSDSYS
|
||||
// CD player can display the correct minute and second values.
|
||||
// From my testing, the IOCTL returns 0 for ctrl. This also breaks
|
||||
// the OSDSYS player. The only "safe" values to receive from the IOCTL
|
||||
// are ADR, trackNum and trackIndex.
|
||||
if (!src->ReadTrackSubQ(subq))
|
||||
{
|
||||
lsn_to_msf(&subq->discM, &subq->discS, &subq->discF, lsn + 150);
|
||||
|
||||
u8 i = strack;
|
||||
while (i < etrack && lsn >= tracks[i + 1].start_lba)
|
||||
++i;
|
||||
|
||||
lsn -= tracks[i].start_lba;
|
||||
|
||||
lsn_to_msf(&subq->trackM, &subq->trackS, &subq->trackF, lsn);
|
||||
|
||||
subq->adr = 1;
|
||||
subq->ctrl = tracks[i].type;
|
||||
subq->trackNum = i;
|
||||
subq->trackIndex = 1;
|
||||
}
|
||||
@@ -470,11 +480,13 @@ static s32 DISCgetTOC(void* toc)
|
||||
{
|
||||
err = DISCgetTD(i, &trackInfo);
|
||||
lba_to_msf(trackInfo.lsn, &min, &sec, &frm);
|
||||
tocBuff[i * 10 + 30] = trackInfo.type;
|
||||
tocBuff[i * 10 + 32] = err == -1 ? 0 : dec_to_bcd(i); //number
|
||||
tocBuff[i * 10 + 37] = dec_to_bcd(min);
|
||||
tocBuff[i * 10 + 38] = dec_to_bcd(sec);
|
||||
tocBuff[i * 10 + 39] = dec_to_bcd(frm);
|
||||
|
||||
const u8 tocIndex = i - diskInfo.strack;
|
||||
tocBuff[tocIndex * 10 + 30] = trackInfo.type;
|
||||
tocBuff[tocIndex * 10 + 32] = err == -1 ? 0 : dec_to_bcd(i); //number
|
||||
tocBuff[tocIndex * 10 + 37] = dec_to_bcd(min);
|
||||
tocBuff[tocIndex * 10 + 38] = dec_to_bcd(sec);
|
||||
tocBuff[tocIndex * 10 + 39] = dec_to_bcd(frm);
|
||||
fprintf(stderr, "Track %u: %u mins %u secs %u frames\n", i, min, sec, frm);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,14 +21,6 @@ class Error;
|
||||
extern int curDiskType;
|
||||
extern int curTrayStatus;
|
||||
|
||||
struct toc_entry
|
||||
{
|
||||
u32 lba;
|
||||
u8 track;
|
||||
u8 adr : 4;
|
||||
u8 control : 4;
|
||||
};
|
||||
|
||||
class IOCtlSrc
|
||||
{
|
||||
IOCtlSrc(const IOCtlSrc&) = delete;
|
||||
|
||||
@@ -18,6 +18,44 @@ static int pmode, cdtype;
|
||||
static s32 layer1start = -1;
|
||||
static bool layer1searched = false;
|
||||
|
||||
static void ISOParseTOC()
|
||||
{
|
||||
tracks.fill(cdvdTrack{});
|
||||
if (iso.GetType() != ISOTYPE_AUDIO)
|
||||
{
|
||||
strack = 1;
|
||||
etrack = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
strack = 0xFF;
|
||||
etrack = 0;
|
||||
// Audio CD
|
||||
for (const auto& entry : iso.ReadTOC())
|
||||
{
|
||||
const u8 track = entry.track;
|
||||
if (track < 1 || track >= tracks.size())
|
||||
{
|
||||
Console.Warning("CDVD: Invalid track index %u, ignoring\n", track);
|
||||
continue;
|
||||
}
|
||||
strack = std::min(strack, track);
|
||||
etrack = std::max(etrack, track);
|
||||
tracks[track].start_lba = entry.lba;
|
||||
|
||||
if ((entry.control & 0x0C) == 0x04)
|
||||
{
|
||||
Console.Warning("CDVD: Unsupported data track reading. Assuming MODE1?\n");
|
||||
tracks[track].type = CDVD_MODE1_TRACK;
|
||||
}
|
||||
else
|
||||
{
|
||||
tracks[track].type = CDVD_AUDIO_TRACK;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void ISOclose()
|
||||
{
|
||||
iso.Close();
|
||||
@@ -49,6 +87,8 @@ static bool ISOopen(std::string filename, Error* error)
|
||||
break;
|
||||
}
|
||||
|
||||
ISOParseTOC();
|
||||
|
||||
layer1start = -1;
|
||||
layer1searched = false;
|
||||
|
||||
@@ -60,34 +100,56 @@ static bool ISOprecache(ProgressCallback* progress, Error* error)
|
||||
return iso.Precache(progress, error);
|
||||
}
|
||||
|
||||
static void lsn_to_msf(u8* minute, u8* second, u8* frame, u32 lsn)
|
||||
{
|
||||
*frame = itob(lsn % 75);
|
||||
lsn /= 75;
|
||||
*second = itob(lsn % 60);
|
||||
lsn /= 60;
|
||||
*minute = itob(lsn % 100);
|
||||
}
|
||||
|
||||
static s32 ISOreadSubQ(u32 lsn, cdvdSubQ* subq)
|
||||
{
|
||||
// fake it
|
||||
u8 min, sec, frm;
|
||||
subq->ctrl = 4;
|
||||
subq->adr = 1;
|
||||
subq->trackNum = itob(1);
|
||||
subq->trackIndex = itob(1);
|
||||
|
||||
|
||||
lba_to_msf(lsn, &min, &sec, &frm);
|
||||
subq->trackM = itob(min);
|
||||
subq->trackS = itob(sec);
|
||||
subq->trackF = itob(frm);
|
||||
memset(subq, 0, sizeof(cdvdSubQ));
|
||||
|
||||
subq->pad = 0;
|
||||
lsn_to_msf(&subq->discM, &subq->discS, &subq->discF, lsn + 150);
|
||||
|
||||
lba_to_msf(lsn + (2 * 75), &min, &sec, &frm);
|
||||
subq->discM = itob(min);
|
||||
subq->discS = itob(sec);
|
||||
subq->discF = itob(frm);
|
||||
// FIXME: Verify this is correct for ISOTYPE_CD :S
|
||||
if (iso.GetType() != ISOTYPE_AUDIO && iso.GetType() != ISOTYPE_CD)
|
||||
{
|
||||
subq->ctrl = 4;
|
||||
subq->adr = 1;
|
||||
subq->trackNum = itob(1);
|
||||
subq->trackIndex = itob(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
u8 i = strack;
|
||||
while (i < etrack && lsn >= tracks[i + 1].start_lba)
|
||||
++i;
|
||||
|
||||
lsn -= tracks[i].start_lba;
|
||||
|
||||
subq->ctrl = 1;
|
||||
subq->adr = 1;
|
||||
subq->trackNum = i;
|
||||
subq->trackIndex = 1; // FIXME ???
|
||||
}
|
||||
|
||||
lsn_to_msf(&subq->trackM, &subq->trackS, &subq->trackF, lsn);
|
||||
|
||||
Console.Warning("CDVD: SubQ M %02x S %02x F %02x\n", subq->trackM, subq->trackS, subq->trackF);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static s32 ISOgetTN(cdvdTN* Buffer)
|
||||
{
|
||||
Buffer->strack = 1;
|
||||
Buffer->etrack = 1;
|
||||
Buffer->strack = strack;
|
||||
Buffer->etrack = etrack;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -97,13 +159,15 @@ static s32 ISOgetTD(u8 Track, cdvdTD* Buffer)
|
||||
if (Track == 0)
|
||||
{
|
||||
Buffer->lsn = iso.GetBlockCount();
|
||||
Buffer->type = 0;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Buffer->type = CDVD_MODE1_TRACK;
|
||||
Buffer->lsn = 0;
|
||||
}
|
||||
|
||||
|
||||
if (Track < strack || Track > etrack)
|
||||
return -1;
|
||||
|
||||
Buffer->lsn = tracks[Track].start_lba;
|
||||
Buffer->type = tracks[Track].type;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -299,11 +363,12 @@ static s32 ISOgetTOC(void* toc)
|
||||
{
|
||||
err = ISOgetTD(i, &trackInfo);
|
||||
lba_to_msf(trackInfo.lsn, &min, &sec, &frm);
|
||||
tocBuff[i * 10 + 30] = trackInfo.type;
|
||||
tocBuff[i * 10 + 32] = err == -1 ? 0 : itob(i); //number
|
||||
tocBuff[i * 10 + 37] = itob(min);
|
||||
tocBuff[i * 10 + 38] = itob(sec);
|
||||
tocBuff[i * 10 + 39] = itob(frm);
|
||||
const u8 tocIndex = i - diskInfo.strack;
|
||||
tocBuff[tocIndex * 10 + 30] = trackInfo.type;
|
||||
tocBuff[tocIndex * 10 + 32] = err == -1 ? 0 : itob(i); //number
|
||||
tocBuff[tocIndex * 10 + 37] = itob(min);
|
||||
tocBuff[tocIndex * 10 + 38] = itob(sec);
|
||||
tocBuff[tocIndex * 10 + 39] = itob(frm);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -176,8 +176,9 @@ bool ChdFileReader::Open2(std::string filename, Error* error)
|
||||
|
||||
// The file size in the header is incorrect, each track gets padded to a multiple of 4 frames.
|
||||
// (see chdman.cpp from MAME). Instead, we pull the real frame count from the TOC.
|
||||
std::vector<toc_entry> entries;
|
||||
u64 total_frames;
|
||||
if (ParseTOC(&total_frames))
|
||||
if (ParseTOC(&total_frames, entries))
|
||||
{
|
||||
file_size = total_frames * static_cast<u64>(chd_header->unitbytes);
|
||||
}
|
||||
@@ -216,6 +217,21 @@ bool ChdFileReader::Precache2(ProgressCallback* progress, Error* error)
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<toc_entry> ChdFileReader::ReadTOC()
|
||||
{
|
||||
u64 total_frames;
|
||||
std::vector<toc_entry> entries;
|
||||
if (ParseTOC(&total_frames, entries))
|
||||
{
|
||||
return entries;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.Warning("Failed to parse CHD TOC, file size may be incorrect.");
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
ThreadedFileReader::Chunk ChdFileReader::ChunkForOffset(u64 offset)
|
||||
{
|
||||
Chunk chunk = {0};
|
||||
@@ -261,11 +277,11 @@ u32 ChdFileReader::GetBlockCount() const
|
||||
return (file_size - m_dataoffset) / m_internalBlockSize;
|
||||
}
|
||||
|
||||
bool ChdFileReader::ParseTOC(u64* out_frame_count)
|
||||
bool ChdFileReader::ParseTOC(u64* out_frame_count, std::vector<toc_entry>& entries)
|
||||
{
|
||||
u64 total_frames = 0;
|
||||
int max_found_track = -1;
|
||||
|
||||
u64 total_gap_frames = 0;
|
||||
for (int search_index = 0;; search_index++)
|
||||
{
|
||||
char metadata_str[256];
|
||||
@@ -305,17 +321,28 @@ bool ChdFileReader::ParseTOC(u64* out_frame_count)
|
||||
}
|
||||
}
|
||||
|
||||
DevCon.WriteLn(fmt::format("CHD Track {}: frames:{} pregap:{} postgap:{} type:{} sub:{} pgtype:{} pgsub:{}",
|
||||
Console.WriteLn(fmt::format("CHD Track {}: frames:{} pregap:{} postgap:{} type:{} sub:{} pgtype:{} pgsub:{}",
|
||||
track_num, frames, pregap_frames, postgap_frames, type_str, subtype_str, pgtype_str, pgsub_str));
|
||||
|
||||
// PCSX2 doesn't currently support multiple tracks for CDs.
|
||||
if (track_num != 1)
|
||||
if (track_num != 0)
|
||||
{
|
||||
Console.Warning(fmt::format(" Ignoring track {} in CHD.", track_num, frames));
|
||||
continue;
|
||||
toc_entry entry{};
|
||||
entry.lba = static_cast<u32>(total_frames) - total_gap_frames;
|
||||
entry.track = static_cast<u8>(track_num);
|
||||
entry.adr = 1;
|
||||
entry.control = 0;
|
||||
|
||||
//FIXME: DATA track?
|
||||
if (strncmp(type_str, "AUDIO", 5) != 0)
|
||||
entry.control |= 0x04;
|
||||
|
||||
entries.push_back(entry);
|
||||
}
|
||||
|
||||
total_frames += static_cast<u64>(pregap_frames) + static_cast<u64>(frames) + static_cast<u64>(postgap_frames);
|
||||
// I have not found a CHD with an audio track with a postgap, consider that untested
|
||||
total_gap_frames += static_cast<u64>(pregap_frames) + static_cast<u64>(postgap_frames);
|
||||
total_frames += total_gap_frames + static_cast<u64>(frames);
|
||||
|
||||
max_found_track = std::max(max_found_track, track_num);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ public:
|
||||
|
||||
bool Precache2(ProgressCallback* progress, Error* error) override;
|
||||
|
||||
std::vector<toc_entry> ReadTOC() override;
|
||||
|
||||
Chunk ChunkForOffset(u64 offset) override;
|
||||
int ReadChunk(void* dst, s64 blockID) override;
|
||||
|
||||
@@ -26,7 +28,7 @@ public:
|
||||
uint GetBlockCount(void) const override;
|
||||
|
||||
private:
|
||||
bool ParseTOC(u64* out_frame_count);
|
||||
bool ParseTOC(u64* out_frame_count, std::vector<toc_entry>& entries);
|
||||
|
||||
chd_file* ChdFile = nullptr;
|
||||
u64 file_size = 0;
|
||||
|
||||
@@ -160,9 +160,31 @@ int InputIsoFile::FinishRead3(u8* dst, uint mode)
|
||||
dst[diff - 9] = 2;
|
||||
}
|
||||
|
||||
// Seems like CHD data ends up being the wrong endianess for audio
|
||||
// Confidence is about 50% on this one, but it seems to work
|
||||
// (CHD is the only file with a TOC anyways, so who cares about the other formats)
|
||||
if (m_type == ISOTYPE_AUDIO && mode == CDVD_MODE_2352)
|
||||
{
|
||||
for (int i = 0; i < 2352; i += 2)
|
||||
{
|
||||
std::swap(dst[diff + i], dst[diff + i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<toc_entry> InputIsoFile::ReadTOC() const
|
||||
{
|
||||
std::vector<toc_entry> toc;
|
||||
|
||||
if (m_type == ISOTYPE_ILLEGAL)
|
||||
return toc;
|
||||
|
||||
toc = m_reader->ReadTOC();
|
||||
return toc;
|
||||
}
|
||||
|
||||
InputIsoFile::InputIsoFile()
|
||||
{
|
||||
_init();
|
||||
@@ -271,7 +293,7 @@ bool InputIsoFile::tryIsoType(u32 size, u32 offset, u32 blockofs)
|
||||
// Returns true if the image is valid/known/supported, or false if not (type == ISOTYPE_ILLEGAL).
|
||||
bool InputIsoFile::Detect(bool readType)
|
||||
{
|
||||
m_type = ISOTYPE_ILLEGAL;
|
||||
m_type = ISOTYPE_ILLEGAL;
|
||||
|
||||
// First sanity check: no sane CD image has less than 16 sectors, since that's what
|
||||
// we need simply to contain a TOC. So if the file size is not large enough to
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CDVDcommon.h"
|
||||
#include "CDVD/CDVD.h"
|
||||
#include "CDVD/ThreadedFileReader.h"
|
||||
#include <memory>
|
||||
@@ -75,6 +76,8 @@ public:
|
||||
void BeginRead2(uint lsn);
|
||||
int FinishRead3(u8* dest, uint mode);
|
||||
|
||||
std::vector<toc_entry> ReadTOC() const;
|
||||
|
||||
protected:
|
||||
void _init();
|
||||
|
||||
|
||||
@@ -208,18 +208,8 @@ bool IOCtlSrc::ReadTrackSubQ(cdvdSubQ* subQ) const
|
||||
}
|
||||
|
||||
subQ->adr = osSubQ.cdsc_adr;
|
||||
subQ->ctrl = osSubQ.cdsc_ctrl;
|
||||
subQ->trackNum = osSubQ.cdsc_trk;
|
||||
subQ->trackIndex = osSubQ.cdsc_ind;
|
||||
|
||||
subQ->discM = osSubQ.cdsc_absaddr.msf.minute;
|
||||
subQ->discS = osSubQ.cdsc_absaddr.msf.second;
|
||||
subQ->discF = osSubQ.cdsc_absaddr.msf.frame;
|
||||
|
||||
subQ->trackM = osSubQ.cdsc_reladdr.msf.minute;
|
||||
subQ->trackS = osSubQ.cdsc_reladdr.msf.second;
|
||||
subQ->trackF = osSubQ.cdsc_reladdr.msf.frame;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -264,6 +264,12 @@ bool ThreadedFileReader::Precache2(ProgressCallback* progress, Error* error)
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<toc_entry> ThreadedFileReader::ReadTOC()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
bool ThreadedFileReader::CheckAvailableMemoryForPrecaching(u64 required_size, Error* error)
|
||||
{
|
||||
// Don't allow precaching to use more than 50% of system memory.
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "common/Pcsx2Defs.h"
|
||||
#include "CDVDcommon.h"
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
@@ -117,6 +118,7 @@ public:
|
||||
|
||||
bool Open(std::string filename, Error* error);
|
||||
bool Precache(ProgressCallback* progress, Error* error);
|
||||
virtual std::vector<toc_entry> ReadTOC();
|
||||
int ReadSync(void* pBuffer, u32 sector, u32 count);
|
||||
void BeginRead(void* pBuffer, u32 sector, u32 count);
|
||||
int FinishRead();
|
||||
|
||||
@@ -320,17 +320,8 @@ bool IOCtlSrc::ReadTrackSubQ(cdvdSubQ* subQ) const
|
||||
else
|
||||
{
|
||||
subQ->adr = osSubQ.CurrentPosition.ADR;
|
||||
subQ->ctrl = osSubQ.CurrentPosition.Control;
|
||||
subQ->trackNum = osSubQ.CurrentPosition.TrackNumber;
|
||||
subQ->trackIndex = osSubQ.CurrentPosition.IndexNumber;
|
||||
|
||||
subQ->trackM = osSubQ.CurrentPosition.TrackRelativeAddress[0];
|
||||
subQ->trackS = osSubQ.CurrentPosition.TrackRelativeAddress[1];
|
||||
subQ->trackF = osSubQ.CurrentPosition.TrackRelativeAddress[2];
|
||||
|
||||
subQ->discM = osSubQ.CurrentPosition.AbsoluteAddress[0];
|
||||
subQ->discS = osSubQ.CurrentPosition.AbsoluteAddress[1];
|
||||
subQ->discF = osSubQ.CurrentPosition.AbsoluteAddress[2];
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -54,6 +54,7 @@ endif(WIN32)
|
||||
# Main pcsx2 source
|
||||
set(pcsx2Sources
|
||||
Achievements.cpp
|
||||
BuildVersion.cpp
|
||||
Cache.cpp
|
||||
COP0.cpp
|
||||
COP2.cpp
|
||||
@@ -140,6 +141,7 @@ set(pcsx2Sources
|
||||
# Main pcsx2 header
|
||||
set(pcsx2Headers
|
||||
Achievements.h
|
||||
BuildVersion.h
|
||||
Cache.h
|
||||
Common.h
|
||||
Config.h
|
||||
@@ -988,8 +990,8 @@ set(pcsx2x86Sources
|
||||
x86/ix86-32/iR5900Shift.cpp
|
||||
x86/ix86-32/iR5900Templates.cpp
|
||||
x86/ix86-32/recVTLB.cpp
|
||||
x86/newVif_Dynarec.cpp
|
||||
x86/newVif_UnpackSSE.cpp
|
||||
x86/Vif_Dynarec.cpp
|
||||
x86/Vif_UnpackSSE.cpp
|
||||
)
|
||||
|
||||
# x86 headers
|
||||
@@ -1029,15 +1031,15 @@ set(pcsx2x86Headers
|
||||
x86/microVU_Tables.inl
|
||||
x86/microVU_Upper.inl
|
||||
x86/newVif.h
|
||||
x86/newVif_UnpackSSE.h
|
||||
x86/Vif_UnpackSSE.h
|
||||
x86/R5900_Profiler.h
|
||||
)
|
||||
|
||||
# ARM64
|
||||
set(pcsx2arm64Sources
|
||||
arm64/AsmHelpers.cpp
|
||||
arm64/newVif_Dynarec.cpp
|
||||
arm64/newVif_UnpackNEON.cpp
|
||||
arm64/Vif_Dynarec.cpp
|
||||
arm64/Vif_UnpackNEON.cpp
|
||||
arm64/RecStubs.cpp
|
||||
)
|
||||
|
||||
@@ -1225,6 +1227,10 @@ if (NOT APPLE)
|
||||
endif()
|
||||
|
||||
fixup_file_properties(PCSX2)
|
||||
# Directories like /usr/local/include, /opt/local/include, etc tend to include lots of headers from lots of libraries.
|
||||
# Possibly including libraries that we compiled versions of with the dependency build script.
|
||||
# To ensure the dependency build script's headers are preferred, push any directories that look like */local/include to the end.
|
||||
force_include_last(PCSX2_FLAGS "/(usr|local)/include/?$")
|
||||
|
||||
if (APPLE)
|
||||
find_library(METAL_LIBRARY Metal)
|
||||
|
||||
@@ -208,6 +208,8 @@ struct DebugSymbolSource
|
||||
struct DebugExtraSymbolFile
|
||||
{
|
||||
std::string Path;
|
||||
std::string BaseAddress;
|
||||
std::string Condition;
|
||||
|
||||
friend auto operator<=>(const DebugExtraSymbolFile& lhs, const DebugExtraSymbolFile& rhs) = default;
|
||||
};
|
||||
@@ -1103,8 +1105,8 @@ struct Pcsx2Config
|
||||
|
||||
DebugFunctionScanMode FunctionScanMode = DebugFunctionScanMode::SCAN_ELF;
|
||||
bool CustomFunctionScanRange = false;
|
||||
std::string FunctionScanStartAddress = "0";
|
||||
std::string FunctionScanEndAddress = "0";
|
||||
std::string FunctionScanStartAddress;
|
||||
std::string FunctionScanEndAddress;
|
||||
|
||||
bool GenerateFunctionHashes = true;
|
||||
|
||||
@@ -1276,7 +1278,7 @@ struct Pcsx2Config
|
||||
EnableGameFixes : 1, // enables automatic game fixes
|
||||
SaveStateOnShutdown : 1, // default value for saving state on shutdown
|
||||
EnableDiscordPresence : 1, // enables discord rich presence integration
|
||||
UseSavestateSelector: 1,
|
||||
UseSavestateSelector : 1,
|
||||
InhibitScreensaver : 1,
|
||||
BackupSavestate : 1,
|
||||
McdFolderAutoManage : 1,
|
||||
|
||||
@@ -91,8 +91,8 @@ namespace Sessions
|
||||
return;
|
||||
}
|
||||
|
||||
icmpEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if (icmpEvent == NULL)
|
||||
icmpEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
||||
if (icmpEvent == nullptr)
|
||||
{
|
||||
Console.Error("DEV9: ICMP: Failed to Create Event");
|
||||
IcmpCloseHandle(icmpFile);
|
||||
|
||||
@@ -169,7 +169,7 @@ namespace Sessions
|
||||
memcpy(recivedData->data.get(), buffer.get(), recived);
|
||||
|
||||
std::unique_ptr<TCP_Packet> iRet = CreateBasePacket(recivedData);
|
||||
IncrementMyNumber((u32)recived);
|
||||
IncrementMyNumber(static_cast<u32>(recived));
|
||||
|
||||
iRet->SetACK(true);
|
||||
iRet->SetPSH(true);
|
||||
|
||||
@@ -193,7 +193,7 @@ namespace Sessions
|
||||
#endif
|
||||
|
||||
|
||||
const int noDelay = true; // BOOL on Windows
|
||||
constexpr int noDelay = true; // BOOL on Windows
|
||||
ret = setsockopt(client, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<const char*>(&noDelay), sizeof(noDelay));
|
||||
|
||||
if (ret != 0)
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace Sessions
|
||||
return;
|
||||
}
|
||||
|
||||
const int reuseAddress = true; // BOOL on Windows
|
||||
constexpr int reuseAddress = true; // BOOL on Windows
|
||||
ret = setsockopt(client, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<const char*>(&reuseAddress), sizeof(reuseAddress));
|
||||
|
||||
if (ret == SOCKET_ERROR)
|
||||
@@ -76,7 +76,7 @@ namespace Sessions
|
||||
errno);
|
||||
#endif
|
||||
|
||||
const int broadcastEnable = true; // BOOL on Windows
|
||||
constexpr int broadcastEnable = true; // BOOL on Windows
|
||||
ret = setsockopt(client, SOL_SOCKET, SO_BROADCAST, reinterpret_cast<const char*>(&broadcastEnable), sizeof(broadcastEnable));
|
||||
|
||||
if (ret == SOCKET_ERROR)
|
||||
|
||||
@@ -225,7 +225,7 @@ namespace Sessions
|
||||
return false;
|
||||
}
|
||||
|
||||
const int reuseAddress = true; // BOOL on Windows
|
||||
constexpr int reuseAddress = true; // BOOL on Windows
|
||||
ret = setsockopt(client, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<const char*>(&reuseAddress), sizeof(reuseAddress));
|
||||
|
||||
if (ret == SOCKET_ERROR)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#define CARD_SIZE_ECC (1024 * BLOCK_SIZE_ECC)
|
||||
|
||||
|
||||
static u32 ctrl, cmd = (u32)-1, address, id, counter, addrbyte;
|
||||
static u32 ctrl, cmd = static_cast<u32>(-1), address, id, counter, addrbyte;
|
||||
static u8 data[PAGE_SIZE_ECC], file[CARD_SIZE_ECC];
|
||||
|
||||
static void xfromman_call20_calculateXors(unsigned char buffer[128], unsigned char blah[4]);
|
||||
|
||||
@@ -208,12 +208,12 @@ void NetAdapter::InspectSend(NetPacket* pkt)
|
||||
if (EmuConfig.DEV9.EthLogDNS || EmuConfig.DEV9.EthLogDHCP)
|
||||
{
|
||||
EthernetFrame frame(pkt);
|
||||
if (frame.protocol == (u16)EtherType::IPv4)
|
||||
if (frame.protocol == static_cast<u16>(EtherType::IPv4))
|
||||
{
|
||||
PayloadPtr* payload = static_cast<PayloadPtr*>(frame.GetPayload());
|
||||
IP_Packet ippkt(payload->data, payload->GetLength());
|
||||
|
||||
if (ippkt.protocol == (u16)IP_Type::UDP)
|
||||
if (ippkt.protocol == static_cast<u16>(IP_Type::UDP))
|
||||
{
|
||||
IP_PayloadPtr* ipPayload = static_cast<IP_PayloadPtr*>(ippkt.GetPayload());
|
||||
UDP_Packet udppkt(ipPayload->data, ipPayload->GetLength());
|
||||
@@ -240,12 +240,12 @@ void NetAdapter::InspectRecv(NetPacket* pkt)
|
||||
if (EmuConfig.DEV9.EthLogDNS || EmuConfig.DEV9.EthLogDHCP)
|
||||
{
|
||||
EthernetFrame frame(pkt);
|
||||
if (frame.protocol == (u16)EtherType::IPv4)
|
||||
if (frame.protocol == static_cast<u16>(EtherType::IPv4))
|
||||
{
|
||||
PayloadPtr* payload = static_cast<PayloadPtr*>(frame.GetPayload());
|
||||
IP_Packet ippkt(payload->data, payload->GetLength());
|
||||
|
||||
if (ippkt.protocol == (u16)IP_Type::UDP)
|
||||
if (ippkt.protocol == static_cast<u16>(IP_Type::UDP))
|
||||
{
|
||||
IP_PayloadPtr* ipPayload = static_cast<IP_PayloadPtr*>(ippkt.GetPayload());
|
||||
UDP_Packet udppkt(ipPayload->data, ipPayload->GetLength());
|
||||
@@ -350,7 +350,7 @@ bool NetAdapter::InternalServerRecv(NetPacket* pkt)
|
||||
EthernetFrame frame(ippkt);
|
||||
frame.sourceMAC = internalMAC;
|
||||
frame.destinationMAC = ps2MAC;
|
||||
frame.protocol = (u16)EtherType::IPv4;
|
||||
frame.protocol = static_cast<u16>(EtherType::IPv4);
|
||||
frame.WritePacket(pkt);
|
||||
InspectRecv(pkt);
|
||||
return true;
|
||||
@@ -365,7 +365,7 @@ bool NetAdapter::InternalServerRecv(NetPacket* pkt)
|
||||
EthernetFrame frame(ippkt);
|
||||
frame.sourceMAC = internalMAC;
|
||||
frame.destinationMAC = ps2MAC;
|
||||
frame.protocol = (u16)EtherType::IPv4;
|
||||
frame.protocol = static_cast<u16>(EtherType::IPv4);
|
||||
frame.WritePacket(pkt);
|
||||
InspectRecv(pkt);
|
||||
return true;
|
||||
@@ -377,12 +377,12 @@ bool NetAdapter::InternalServerRecv(NetPacket* pkt)
|
||||
bool NetAdapter::InternalServerSend(NetPacket* pkt)
|
||||
{
|
||||
EthernetFrame frame(pkt);
|
||||
if (frame.protocol == (u16)EtherType::IPv4)
|
||||
if (frame.protocol == static_cast<u16>(EtherType::IPv4))
|
||||
{
|
||||
PayloadPtr* payload = static_cast<PayloadPtr*>(frame.GetPayload());
|
||||
IP_Packet ippkt(payload->data, payload->GetLength());
|
||||
|
||||
if (ippkt.protocol == (u16)IP_Type::UDP)
|
||||
if (ippkt.protocol == static_cast<u16>(IP_Type::UDP))
|
||||
{
|
||||
IP_PayloadPtr* ipPayload = static_cast<IP_PayloadPtr*>(ippkt.GetPayload());
|
||||
UDP_Packet udppkt(ipPayload->data, ipPayload->GetLength());
|
||||
@@ -397,7 +397,7 @@ bool NetAdapter::InternalServerSend(NetPacket* pkt)
|
||||
|
||||
if (ippkt.destinationIP == internalIP)
|
||||
{
|
||||
if (ippkt.protocol == (u16)IP_Type::UDP)
|
||||
if (ippkt.protocol == static_cast<u16>(IP_Type::UDP))
|
||||
{
|
||||
ps2IP = ippkt.sourceIP;
|
||||
|
||||
|
||||
@@ -70,11 +70,11 @@ enum struct AdapterOptions : int
|
||||
|
||||
constexpr enum AdapterOptions operator|(const enum AdapterOptions selfValue, const enum AdapterOptions inValue)
|
||||
{
|
||||
return (enum AdapterOptions)(int(selfValue) | int(inValue));
|
||||
return static_cast<enum AdapterOptions>(static_cast<int>(selfValue) | static_cast<int>(inValue));
|
||||
}
|
||||
constexpr enum AdapterOptions operator&(const enum AdapterOptions selfValue, const enum AdapterOptions inValue)
|
||||
{
|
||||
return (enum AdapterOptions)(int(selfValue) & int(inValue));
|
||||
return static_cast<enum AdapterOptions>(static_cast<int>(selfValue) & static_cast<int>(inValue));
|
||||
}
|
||||
|
||||
class NetAdapter
|
||||
|
||||
@@ -136,7 +136,7 @@ bool PCAPAdapter::recv(NetPacket* pkt)
|
||||
pxAssert(header->len == header->caplen);
|
||||
|
||||
memcpy(pkt->buffer, pkt_data, header->len);
|
||||
pkt->size = (int)header->len;
|
||||
pkt->size = static_cast<int>(header->len);
|
||||
|
||||
if (!switched)
|
||||
SetMACBridgedRecv(pkt);
|
||||
@@ -339,7 +339,7 @@ bool PCAPAdapter::SetMACSwitchedFilter(MAC_Address mac)
|
||||
void PCAPAdapter::SetMACBridgedRecv(NetPacket* pkt)
|
||||
{
|
||||
EthernetFrameEditor frame(pkt);
|
||||
if (frame.GetProtocol() == (u16)EtherType::IPv4) // IP
|
||||
if (frame.GetProtocol() == static_cast<u16>(EtherType::IPv4)) // IP
|
||||
{
|
||||
// Compare DEST IP in IP with the PS2's IP, if they match, change DEST MAC to ps2MAC.
|
||||
PayloadPtr* payload = frame.GetPayload();
|
||||
@@ -347,7 +347,7 @@ void PCAPAdapter::SetMACBridgedRecv(NetPacket* pkt)
|
||||
if (ippkt.destinationIP == ps2IP)
|
||||
frame.SetDestinationMAC(ps2MAC);
|
||||
}
|
||||
if (frame.GetProtocol() == (u16)EtherType::ARP) // ARP
|
||||
if (frame.GetProtocol() == static_cast<u16>(EtherType::ARP)) // ARP
|
||||
{
|
||||
// Compare DEST IP in ARP with the PS2's IP, if they match, DEST MAC to ps2MAC on both ARP and ETH Packet headers.
|
||||
ARP_PacketEditor arpPkt(frame.GetPayload());
|
||||
@@ -362,13 +362,13 @@ void PCAPAdapter::SetMACBridgedRecv(NetPacket* pkt)
|
||||
void PCAPAdapter::SetMACBridgedSend(NetPacket* pkt)
|
||||
{
|
||||
EthernetFrameEditor frame(pkt);
|
||||
if (frame.GetProtocol() == (u16)EtherType::IPv4) // IP
|
||||
if (frame.GetProtocol() == static_cast<u16>(EtherType::IPv4)) // IP
|
||||
{
|
||||
PayloadPtr* payload = frame.GetPayload();
|
||||
IP_Packet ippkt(payload->data, payload->GetLength());
|
||||
ps2IP = ippkt.sourceIP;
|
||||
}
|
||||
if (frame.GetProtocol() == (u16)EtherType::ARP) // ARP
|
||||
if (frame.GetProtocol() == static_cast<u16>(EtherType::ARP)) // ARP
|
||||
{
|
||||
ARP_PacketEditor arpPkt(frame.GetPayload());
|
||||
ps2IP = *(IP_Address*)arpPkt.SenderProtocolAddress();
|
||||
|
||||
@@ -37,7 +37,6 @@ public:
|
||||
|
||||
private:
|
||||
bool InitPCAP(const std::string& adapter, bool promiscuous);
|
||||
void InitPCAPDumper();
|
||||
bool SetMACSwitchedFilter(PacketReader::MAC_Address mac);
|
||||
|
||||
void SetMACBridgedRecv(NetPacket* pkt);
|
||||
|
||||
@@ -302,16 +302,14 @@ void emac3_write(u32 addr)
|
||||
value |= SMAP_E3_PHY_OP_COMP;
|
||||
int reg = value & (SMAP_E3_PHY_REG_ADDR_MSK);
|
||||
u16 val = value >> 16;
|
||||
switch (reg)
|
||||
if (reg == SMAP_DsPHYTER_BMCR)
|
||||
{
|
||||
case SMAP_DsPHYTER_BMCR:
|
||||
if (val & SMAP_PHY_BMCR_RST)
|
||||
{
|
||||
ad_reset();
|
||||
}
|
||||
val &= ~SMAP_PHY_BMCR_RST;
|
||||
val |= 0x1;
|
||||
break;
|
||||
if (val & SMAP_PHY_BMCR_RST)
|
||||
{
|
||||
ad_reset();
|
||||
}
|
||||
val &= ~SMAP_PHY_BMCR_RST;
|
||||
val |= 0x1;
|
||||
}
|
||||
//DevCon.WriteLn("DEV9: phy_write %d: %x", reg, val);
|
||||
dev9.phyregs[reg] = val;
|
||||
|
||||
@@ -268,24 +268,24 @@ bool SocketAdapter::send(NetPacket* pkt)
|
||||
|
||||
switch (frame.protocol)
|
||||
{
|
||||
case (u16)EtherType::null:
|
||||
case static_cast<u16>(EtherType::null):
|
||||
case 0x0C00:
|
||||
//Packets with the above ethertypes get sent when the adapter is reset
|
||||
//Catch them here instead of printing an error
|
||||
return true;
|
||||
case (int)EtherType::IPv4:
|
||||
case static_cast<int>(EtherType::IPv4):
|
||||
{
|
||||
PayloadPtr* payload = static_cast<PayloadPtr*>(frame.GetPayload());
|
||||
IP_Packet ippkt(payload->data, payload->GetLength());
|
||||
|
||||
return SendIP(&ippkt);
|
||||
}
|
||||
case (u16)EtherType::ARP:
|
||||
case static_cast<u16>(EtherType::ARP):
|
||||
{
|
||||
PayloadPtr* payload = static_cast<PayloadPtr*>(frame.GetPayload());
|
||||
ARP_Packet arpPkt(payload->data, payload->GetLength());
|
||||
|
||||
if (arpPkt.protocol == (u16)EtherType::IPv4)
|
||||
if (arpPkt.protocol == static_cast<u16>(EtherType::IPv4))
|
||||
{
|
||||
if (arpPkt.op == 1) //ARP request
|
||||
{
|
||||
@@ -304,7 +304,7 @@ bool SocketAdapter::send(NetPacket* pkt)
|
||||
EthernetFrame* retARP = new EthernetFrame(arpRet);
|
||||
retARP->destinationMAC = ps2MAC;
|
||||
retARP->sourceMAC = internalMAC;
|
||||
retARP->protocol = (u16)EtherType::ARP;
|
||||
retARP->protocol = static_cast<u16>(EtherType::ARP);
|
||||
|
||||
vRecBuffer.Enqueue(retARP);
|
||||
}
|
||||
@@ -567,7 +567,7 @@ void SocketAdapter::HandleConnectionClosed(BaseSession* sender)
|
||||
|
||||
void SocketAdapter::HandleFixedPortClosed(BaseSession* sender)
|
||||
{
|
||||
ConnectionKey key = sender->key;
|
||||
const ConnectionKey key = sender->key;
|
||||
connections.Remove(key);
|
||||
fixedUDPPorts.Remove(key.ps2Port);
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@ struct BreakPointCond
|
||||
u32 Evaluate()
|
||||
{
|
||||
u64 result;
|
||||
if (!debug->parseExpression(expression, result) || result == 0)
|
||||
std::string error;
|
||||
if (!debug->parseExpression(expression, result, error) || result == 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -87,8 +87,7 @@ struct ConsoleLog : public LogBase
|
||||
// ConsoleLogFromVM
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Special console logger for Virtual Machine log sources, such as the EE and IOP console
|
||||
// writes (actual game developer messages and such). These logs do *not* automatically
|
||||
// append newlines, since the VM generates them manually; and they do *not* support printf
|
||||
// writes (actual game developer messages and such). These logs do *not* support printf
|
||||
// formatting, since anything coming over the EE/IOP consoles should be considered raw
|
||||
// string data. (otherwise %'s would get mis-interpreted).
|
||||
//
|
||||
@@ -102,22 +101,18 @@ public:
|
||||
{
|
||||
for (const char ch : msg)
|
||||
{
|
||||
if (ch == '\n')
|
||||
{
|
||||
if (!m_buffer.empty())
|
||||
{
|
||||
Console.WriteLn(conColor, m_buffer);
|
||||
m_buffer.clear();
|
||||
}
|
||||
}
|
||||
else if (ch < 0x20)
|
||||
{
|
||||
// Ignore control characters.
|
||||
// Otherwise you get fun bells going off.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ignore control characters.
|
||||
// Otherwise you get fun bells going off.
|
||||
if (ch < 0x20)
|
||||
continue;
|
||||
|
||||
if (ch != '\n')
|
||||
m_buffer.push_back(ch);
|
||||
|
||||
if (ch == '\n' || m_buffer.size() >= 4096)
|
||||
{
|
||||
Console.WriteLn(conColor, m_buffer);
|
||||
m_buffer.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,227 +34,6 @@ enum ReferenceIndexType
|
||||
REF_INDEX_VFPU = 0x10000,
|
||||
REF_INDEX_VFPU_INT = 0x20000,
|
||||
REF_INDEX_IS_FLOAT = REF_INDEX_FPU | REF_INDEX_VFPU,
|
||||
|
||||
};
|
||||
|
||||
|
||||
class MipsExpressionFunctions : public IExpressionFunctions
|
||||
{
|
||||
public:
|
||||
explicit MipsExpressionFunctions(DebugInterface* cpu, bool enumerateSymbols)
|
||||
: m_cpu(cpu)
|
||||
{
|
||||
if (!enumerateSymbols)
|
||||
return;
|
||||
|
||||
m_cpu->GetSymbolGuardian().Read([&](const ccc::SymbolDatabase& database) {
|
||||
for (const ccc::Function& function : database.functions)
|
||||
m_mangled_function_names_to_handles.emplace(function.mangled_name(), function.handle());
|
||||
|
||||
for (const ccc::GlobalVariable& global : database.global_variables)
|
||||
m_mangled_global_names_to_handles.emplace(global.mangled_name(), global.handle());
|
||||
});
|
||||
}
|
||||
|
||||
virtual bool parseReference(char* str, u64& referenceIndex)
|
||||
{
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
char reg[8];
|
||||
std::snprintf(reg, std::size(reg), "r%d", i);
|
||||
if (StringUtil::Strcasecmp(str, reg) == 0 || StringUtil::Strcasecmp(str, m_cpu->getRegisterName(0, i)) == 0)
|
||||
{
|
||||
referenceIndex = i;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::snprintf(reg, std::size(reg), "f%d", i);
|
||||
if (StringUtil::Strcasecmp(str, reg) == 0)
|
||||
{
|
||||
referenceIndex = i | REF_INDEX_FPU;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtil::Strcasecmp(str, "pc") == 0)
|
||||
{
|
||||
referenceIndex = REF_INDEX_PC;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (StringUtil::Strcasecmp(str, "hi") == 0)
|
||||
{
|
||||
referenceIndex = REF_INDEX_HI;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (StringUtil::Strcasecmp(str, "lo") == 0)
|
||||
{
|
||||
referenceIndex = REF_INDEX_LO;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (StringUtil::Strcasecmp(str, "target") == 0)
|
||||
{
|
||||
referenceIndex = REF_INDEX_OPTARGET;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (StringUtil::Strcasecmp(str, "load") == 0)
|
||||
{
|
||||
referenceIndex = REF_INDEX_OPLOAD;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (StringUtil::Strcasecmp(str, "store") == 0)
|
||||
{
|
||||
referenceIndex = REF_INDEX_OPSTORE;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool parseSymbol(char* str, u64& symbolValue)
|
||||
{
|
||||
bool success = false;
|
||||
m_cpu->GetSymbolGuardian().Read([&](const ccc::SymbolDatabase& database) {
|
||||
std::string name = str;
|
||||
|
||||
// Check for mangled function names.
|
||||
auto function_iterator = m_mangled_function_names_to_handles.find(name);
|
||||
if (function_iterator != m_mangled_function_names_to_handles.end())
|
||||
{
|
||||
const ccc::Function* function = database.functions.symbol_from_handle(function_iterator->second);
|
||||
if (function && function->address().valid())
|
||||
{
|
||||
symbolValue = function->address().value;
|
||||
success = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for mangled global variable names.
|
||||
auto global_iterator = m_mangled_global_names_to_handles.find(name);
|
||||
if (global_iterator != m_mangled_global_names_to_handles.end())
|
||||
{
|
||||
const ccc::GlobalVariable* global = database.global_variables.symbol_from_handle(global_iterator->second);
|
||||
if (global && global->address().valid())
|
||||
{
|
||||
symbolValue = global->address().value;
|
||||
success = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for regular unmangled names.
|
||||
const ccc::Symbol* symbol = database.symbol_with_name(name);
|
||||
if (symbol && symbol->address().valid())
|
||||
{
|
||||
symbolValue = symbol->address().value;
|
||||
success = true;
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
virtual u64 getReferenceValue(u64 referenceIndex)
|
||||
{
|
||||
if (referenceIndex < 32)
|
||||
return m_cpu->getRegister(0, referenceIndex)._u64[0];
|
||||
if (referenceIndex == REF_INDEX_PC)
|
||||
return m_cpu->getPC();
|
||||
if (referenceIndex == REF_INDEX_HI)
|
||||
return m_cpu->getHI()._u64[0];
|
||||
if (referenceIndex == REF_INDEX_LO)
|
||||
return m_cpu->getLO()._u64[0];
|
||||
if (referenceIndex & REF_INDEX_IS_OPSL)
|
||||
{
|
||||
const u32 OP = m_cpu->read32(m_cpu->getPC());
|
||||
const R5900::OPCODE& opcode = R5900::GetInstruction(OP);
|
||||
if (opcode.flags & IS_MEMORY)
|
||||
{
|
||||
// Fetch the address in the base register
|
||||
u32 target = cpuRegs.GPR.r[(OP >> 21) & 0x1F].UD[0];
|
||||
// Add the offset (lower 16 bits)
|
||||
target += static_cast<u16>(OP);
|
||||
|
||||
if (referenceIndex & REF_INDEX_OPTARGET)
|
||||
{
|
||||
return target;
|
||||
}
|
||||
else if (referenceIndex & REF_INDEX_OPLOAD)
|
||||
{
|
||||
return (opcode.flags & IS_LOAD) ? target : 0;
|
||||
}
|
||||
else if (referenceIndex & REF_INDEX_OPSTORE)
|
||||
{
|
||||
return (opcode.flags & IS_STORE) ? target : 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (referenceIndex & REF_INDEX_FPU)
|
||||
{
|
||||
return m_cpu->getRegister(EECAT_FPR, referenceIndex & 0x1F)._u64[0];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
virtual ExpressionType getReferenceType(u64 referenceIndex)
|
||||
{
|
||||
if (referenceIndex & REF_INDEX_IS_FLOAT)
|
||||
{
|
||||
return EXPR_TYPE_FLOAT;
|
||||
}
|
||||
return EXPR_TYPE_UINT;
|
||||
}
|
||||
|
||||
virtual bool getMemoryValue(u32 address, int size, u64& dest, std::string& error)
|
||||
{
|
||||
switch (size)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 8:
|
||||
break;
|
||||
default:
|
||||
error = StringUtil::StdStringFromFormat(
|
||||
TRANSLATE("ExpressionParser", "Invalid memory access size %d."), size);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (address % size)
|
||||
{
|
||||
error = TRANSLATE("ExpressionParser", "Invalid memory access (unaligned).");
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 1:
|
||||
dest = m_cpu->read8(address);
|
||||
break;
|
||||
case 2:
|
||||
dest = m_cpu->read16(address);
|
||||
break;
|
||||
case 4:
|
||||
dest = m_cpu->read32(address);
|
||||
break;
|
||||
case 8:
|
||||
dest = m_cpu->read64(address);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
DebugInterface* m_cpu;
|
||||
std::map<std::string, ccc::FunctionHandle> m_mangled_function_names_to_handles;
|
||||
std::map<std::string, ccc::GlobalVariableHandle> m_mangled_global_names_to_handles;
|
||||
};
|
||||
|
||||
//
|
||||
@@ -340,7 +119,7 @@ std::optional<u32> DebugInterface::getStackFrameSize(const ccc::Function& functi
|
||||
// The stack frame size isn't stored in the symbol table, so we try
|
||||
// to extract it from the code by checking for an instruction at the
|
||||
// start of the current function that is in the form of
|
||||
// "addui $sp, $sp, frame_size" instead.
|
||||
// "addiu $sp, $sp, frame_size" instead.
|
||||
|
||||
u32 instruction = read32(function.address().value);
|
||||
|
||||
@@ -354,29 +133,29 @@ std::optional<u32> DebugInterface::getStackFrameSize(const ccc::Function& functi
|
||||
return static_cast<u32>(stack_frame_size);
|
||||
}
|
||||
|
||||
bool DebugInterface::evaluateExpression(const char* expression, u64& dest)
|
||||
bool DebugInterface::evaluateExpression(const char* expression, u64& dest, std::string& error)
|
||||
{
|
||||
PostfixExpression postfix;
|
||||
|
||||
if (!initExpression(expression, postfix))
|
||||
if (!initExpression(expression, postfix, error))
|
||||
return false;
|
||||
|
||||
if (!parseExpression(postfix, dest))
|
||||
if (!parseExpression(postfix, dest, error))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DebugInterface::initExpression(const char* exp, PostfixExpression& dest)
|
||||
bool DebugInterface::initExpression(const char* exp, PostfixExpression& dest, std::string& error)
|
||||
{
|
||||
MipsExpressionFunctions funcs(this, true);
|
||||
return initPostfixExpression(exp, &funcs, dest);
|
||||
MipsExpressionFunctions funcs(this, nullptr, true);
|
||||
return initPostfixExpression(exp, &funcs, dest, error);
|
||||
}
|
||||
|
||||
bool DebugInterface::parseExpression(PostfixExpression& exp, u64& dest)
|
||||
bool DebugInterface::parseExpression(PostfixExpression& exp, u64& dest, std::string& error)
|
||||
{
|
||||
MipsExpressionFunctions funcs(this, false);
|
||||
return parsePostfixExpression(exp, &funcs, dest);
|
||||
MipsExpressionFunctions funcs(this, nullptr, false);
|
||||
return parsePostfixExpression(exp, &funcs, dest, error);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -904,12 +683,10 @@ std::vector<std::unique_ptr<BiosThread>> R5900DebugInterface::GetThreadList() co
|
||||
return getEEThreads();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// R3000DebugInterface
|
||||
//
|
||||
|
||||
|
||||
BreakPointCpu R3000DebugInterface::getCpuType()
|
||||
{
|
||||
return BREAKPOINT_IOP;
|
||||
@@ -1235,8 +1012,8 @@ ElfMemoryReader::ElfMemoryReader(const ccc::ElfFile& elf)
|
||||
|
||||
u32 ElfMemoryReader::read8(u32 address)
|
||||
{
|
||||
ccc::Result<u8> result = m_elf.get_object_virtual<u8>(address);
|
||||
if (!result.success())
|
||||
std::optional<u8> result = m_elf.get_object_virtual<u8>(address);
|
||||
if (!result.has_value())
|
||||
return 0;
|
||||
|
||||
return *result;
|
||||
@@ -1244,8 +1021,8 @@ u32 ElfMemoryReader::read8(u32 address)
|
||||
|
||||
u32 ElfMemoryReader::read8(u32 address, bool& valid)
|
||||
{
|
||||
ccc::Result<u8> result = m_elf.get_object_virtual<u8>(address);
|
||||
valid = result.success();
|
||||
std::optional<u8> result = m_elf.get_object_virtual<u8>(address);
|
||||
valid = result.has_value();
|
||||
if (!valid)
|
||||
return 0;
|
||||
|
||||
@@ -1254,8 +1031,8 @@ u32 ElfMemoryReader::read8(u32 address, bool& valid)
|
||||
|
||||
u32 ElfMemoryReader::read16(u32 address)
|
||||
{
|
||||
ccc::Result<u16> result = m_elf.get_object_virtual<u16>(address);
|
||||
if (!result.success())
|
||||
std::optional<u16> result = m_elf.get_object_virtual<u16>(address);
|
||||
if (!result.has_value())
|
||||
return 0;
|
||||
|
||||
return *result;
|
||||
@@ -1263,8 +1040,8 @@ u32 ElfMemoryReader::read16(u32 address)
|
||||
|
||||
u32 ElfMemoryReader::read16(u32 address, bool& valid)
|
||||
{
|
||||
ccc::Result<u16> result = m_elf.get_object_virtual<u16>(address);
|
||||
valid = result.success();
|
||||
std::optional<u16> result = m_elf.get_object_virtual<u16>(address);
|
||||
valid = result.has_value();
|
||||
if (!valid)
|
||||
return 0;
|
||||
|
||||
@@ -1273,8 +1050,8 @@ u32 ElfMemoryReader::read16(u32 address, bool& valid)
|
||||
|
||||
u32 ElfMemoryReader::read32(u32 address)
|
||||
{
|
||||
ccc::Result<u32> result = m_elf.get_object_virtual<u32>(address);
|
||||
if (!result.success())
|
||||
std::optional<u32> result = m_elf.get_object_virtual<u32>(address);
|
||||
if (!result.has_value())
|
||||
return 0;
|
||||
|
||||
return *result;
|
||||
@@ -1282,8 +1059,8 @@ u32 ElfMemoryReader::read32(u32 address)
|
||||
|
||||
u32 ElfMemoryReader::read32(u32 address, bool& valid)
|
||||
{
|
||||
ccc::Result<u32> result = m_elf.get_object_virtual<u32>(address);
|
||||
valid = result.success();
|
||||
std::optional<u32> result = m_elf.get_object_virtual<u32>(address);
|
||||
valid = result.has_value();
|
||||
if (!valid)
|
||||
return 0;
|
||||
|
||||
@@ -1292,8 +1069,8 @@ u32 ElfMemoryReader::read32(u32 address, bool& valid)
|
||||
|
||||
u64 ElfMemoryReader::read64(u32 address)
|
||||
{
|
||||
ccc::Result<u64> result = m_elf.get_object_virtual<u64>(address);
|
||||
if (!result.success())
|
||||
std::optional<u64> result = m_elf.get_object_virtual<u64>(address);
|
||||
if (!result.has_value())
|
||||
return 0;
|
||||
|
||||
return *result;
|
||||
@@ -1301,10 +1078,246 @@ u64 ElfMemoryReader::read64(u32 address)
|
||||
|
||||
u64 ElfMemoryReader::read64(u32 address, bool& valid)
|
||||
{
|
||||
ccc::Result<u64> result = m_elf.get_object_virtual<u64>(address);
|
||||
valid = result.success();
|
||||
std::optional<u64> result = m_elf.get_object_virtual<u64>(address);
|
||||
valid = result.has_value();
|
||||
if (!valid)
|
||||
return 0;
|
||||
|
||||
return *result;
|
||||
}
|
||||
|
||||
//
|
||||
// MipsExpressionFunctions
|
||||
//
|
||||
|
||||
MipsExpressionFunctions::MipsExpressionFunctions(
|
||||
DebugInterface* cpu, const ccc::SymbolDatabase* symbolDatabase, bool shouldEnumerateSymbols)
|
||||
: m_cpu(cpu)
|
||||
, m_database(symbolDatabase)
|
||||
{
|
||||
if (!shouldEnumerateSymbols)
|
||||
return;
|
||||
|
||||
if (symbolDatabase)
|
||||
{
|
||||
enumerateSymbols(*symbolDatabase);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cpu->GetSymbolGuardian().Read([&](const ccc::SymbolDatabase& database) {
|
||||
enumerateSymbols(database);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void MipsExpressionFunctions::enumerateSymbols(const ccc::SymbolDatabase& database)
|
||||
{
|
||||
// TODO: Add mangled symbol name maps to CCC and remove this.
|
||||
|
||||
for (const ccc::Function& function : database.functions)
|
||||
m_mangled_function_names_to_handles.emplace(function.mangled_name(), function.handle());
|
||||
|
||||
for (const ccc::GlobalVariable& global : database.global_variables)
|
||||
m_mangled_global_names_to_handles.emplace(global.mangled_name(), global.handle());
|
||||
}
|
||||
|
||||
bool MipsExpressionFunctions::parseReference(char* str, u64& referenceIndex)
|
||||
{
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
char reg[8];
|
||||
std::snprintf(reg, std::size(reg), "r%d", i);
|
||||
if (StringUtil::Strcasecmp(str, reg) == 0 || StringUtil::Strcasecmp(str, m_cpu->getRegisterName(0, i)) == 0)
|
||||
{
|
||||
referenceIndex = i;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::snprintf(reg, std::size(reg), "f%d", i);
|
||||
if (StringUtil::Strcasecmp(str, reg) == 0)
|
||||
{
|
||||
referenceIndex = i | REF_INDEX_FPU;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtil::Strcasecmp(str, "pc") == 0)
|
||||
{
|
||||
referenceIndex = REF_INDEX_PC;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (StringUtil::Strcasecmp(str, "hi") == 0)
|
||||
{
|
||||
referenceIndex = REF_INDEX_HI;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (StringUtil::Strcasecmp(str, "lo") == 0)
|
||||
{
|
||||
referenceIndex = REF_INDEX_LO;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (StringUtil::Strcasecmp(str, "target") == 0)
|
||||
{
|
||||
referenceIndex = REF_INDEX_OPTARGET;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (StringUtil::Strcasecmp(str, "load") == 0)
|
||||
{
|
||||
referenceIndex = REF_INDEX_OPLOAD;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (StringUtil::Strcasecmp(str, "store") == 0)
|
||||
{
|
||||
referenceIndex = REF_INDEX_OPSTORE;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MipsExpressionFunctions::parseSymbol(char* str, u64& symbolValue)
|
||||
{
|
||||
if (m_database)
|
||||
return parseSymbol(str, symbolValue, *m_database);
|
||||
|
||||
bool success = false;
|
||||
m_cpu->GetSymbolGuardian().Read([&](const ccc::SymbolDatabase& database) {
|
||||
success = parseSymbol(str, symbolValue, database);
|
||||
});
|
||||
return success;
|
||||
}
|
||||
|
||||
bool MipsExpressionFunctions::parseSymbol(char* str, u64& symbolValue, const ccc::SymbolDatabase& database)
|
||||
{
|
||||
std::string name = str;
|
||||
|
||||
// Check for mangled function names.
|
||||
auto function_iterator = m_mangled_function_names_to_handles.find(name);
|
||||
if (function_iterator != m_mangled_function_names_to_handles.end())
|
||||
{
|
||||
const ccc::Function* function = database.functions.symbol_from_handle(function_iterator->second);
|
||||
if (function && function->address().valid())
|
||||
{
|
||||
symbolValue = function->address().value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for mangled global variable names.
|
||||
auto global_iterator = m_mangled_global_names_to_handles.find(name);
|
||||
if (global_iterator != m_mangled_global_names_to_handles.end())
|
||||
{
|
||||
const ccc::GlobalVariable* global = database.global_variables.symbol_from_handle(global_iterator->second);
|
||||
if (global && global->address().valid())
|
||||
{
|
||||
symbolValue = global->address().value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for regular unmangled names.
|
||||
const ccc::Symbol* symbol = database.symbol_with_name(name);
|
||||
if (symbol && symbol->address().valid())
|
||||
{
|
||||
symbolValue = symbol->address().value;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
u64 MipsExpressionFunctions::getReferenceValue(u64 referenceIndex)
|
||||
{
|
||||
if (referenceIndex < 32)
|
||||
return m_cpu->getRegister(0, referenceIndex)._u64[0];
|
||||
if (referenceIndex == REF_INDEX_PC)
|
||||
return m_cpu->getPC();
|
||||
if (referenceIndex == REF_INDEX_HI)
|
||||
return m_cpu->getHI()._u64[0];
|
||||
if (referenceIndex == REF_INDEX_LO)
|
||||
return m_cpu->getLO()._u64[0];
|
||||
if (referenceIndex & REF_INDEX_IS_OPSL)
|
||||
{
|
||||
const u32 OP = m_cpu->read32(m_cpu->getPC());
|
||||
const R5900::OPCODE& opcode = R5900::GetInstruction(OP);
|
||||
if (opcode.flags & IS_MEMORY)
|
||||
{
|
||||
// Fetch the address in the base register
|
||||
u32 target = cpuRegs.GPR.r[(OP >> 21) & 0x1F].UD[0];
|
||||
// Add the offset (lower 16 bits)
|
||||
target += static_cast<u16>(OP);
|
||||
|
||||
if (referenceIndex & REF_INDEX_OPTARGET)
|
||||
{
|
||||
return target;
|
||||
}
|
||||
else if (referenceIndex & REF_INDEX_OPLOAD)
|
||||
{
|
||||
return (opcode.flags & IS_LOAD) ? target : 0;
|
||||
}
|
||||
else if (referenceIndex & REF_INDEX_OPSTORE)
|
||||
{
|
||||
return (opcode.flags & IS_STORE) ? target : 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (referenceIndex & REF_INDEX_FPU)
|
||||
{
|
||||
return m_cpu->getRegister(EECAT_FPR, referenceIndex & 0x1F)._u64[0];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
ExpressionType MipsExpressionFunctions::getReferenceType(u64 referenceIndex)
|
||||
{
|
||||
if (referenceIndex & REF_INDEX_IS_FLOAT)
|
||||
{
|
||||
return EXPR_TYPE_FLOAT;
|
||||
}
|
||||
return EXPR_TYPE_UINT;
|
||||
}
|
||||
|
||||
bool MipsExpressionFunctions::getMemoryValue(u32 address, int size, u64& dest, std::string& error)
|
||||
{
|
||||
switch (size)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 8:
|
||||
break;
|
||||
default:
|
||||
error = StringUtil::StdStringFromFormat(
|
||||
TRANSLATE("ExpressionParser", "Invalid memory access size %d."), size);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (address % size)
|
||||
{
|
||||
error = TRANSLATE("ExpressionParser", "Invalid memory access (unaligned).");
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 1:
|
||||
dest = m_cpu->read8(address);
|
||||
break;
|
||||
case 2:
|
||||
dest = m_cpu->read16(address);
|
||||
break;
|
||||
case 4:
|
||||
dest = m_cpu->read32(address);
|
||||
break;
|
||||
case 8:
|
||||
dest = m_cpu->read64(address);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
|
||||
#pragma once
|
||||
#include "DebugTools/BiosDebugData.h"
|
||||
#include "MemoryTypes.h"
|
||||
|
||||
#include "BiosDebugData.h"
|
||||
#include "ExpressionParser.h"
|
||||
#include "SymbolGuardian.h"
|
||||
#include "SymbolImporter.h"
|
||||
@@ -86,9 +86,9 @@ public:
|
||||
virtual SymbolImporter* GetSymbolImporter() const = 0;
|
||||
virtual std::vector<std::unique_ptr<BiosThread>> GetThreadList() const = 0;
|
||||
|
||||
bool evaluateExpression(const char* expression, u64& dest);
|
||||
bool initExpression(const char* exp, PostfixExpression& dest);
|
||||
bool parseExpression(PostfixExpression& exp, u64& dest);
|
||||
bool evaluateExpression(const char* expression, u64& dest, std::string& error);
|
||||
bool initExpression(const char* exp, PostfixExpression& dest, std::string& error);
|
||||
bool parseExpression(PostfixExpression& exp, u64& dest, std::string& error);
|
||||
bool isAlive();
|
||||
bool isCpuPaused();
|
||||
void pauseCpu();
|
||||
@@ -210,5 +210,26 @@ protected:
|
||||
const ccc::ElfFile& m_elf;
|
||||
};
|
||||
|
||||
class MipsExpressionFunctions : public IExpressionFunctions
|
||||
{
|
||||
public:
|
||||
MipsExpressionFunctions(
|
||||
DebugInterface* cpu, const ccc::SymbolDatabase* symbolDatabase, bool shouldEnumerateSymbols);
|
||||
|
||||
bool parseReference(char* str, u64& referenceIndex) override;
|
||||
bool parseSymbol(char* str, u64& symbolValue) override;
|
||||
u64 getReferenceValue(u64 referenceIndex) override;
|
||||
ExpressionType getReferenceType(u64 referenceIndex) override;
|
||||
bool getMemoryValue(u32 address, int size, u64& dest, std::string& error) override;
|
||||
|
||||
protected:
|
||||
void enumerateSymbols(const ccc::SymbolDatabase& database);
|
||||
bool parseSymbol(char* str, u64& symbolValue, const ccc::SymbolDatabase& database);
|
||||
DebugInterface* m_cpu;
|
||||
const ccc::SymbolDatabase* m_database;
|
||||
std::map<std::string, ccc::FunctionHandle> m_mangled_function_names_to_handles;
|
||||
std::map<std::string, ccc::GlobalVariableHandle> m_mangled_global_names_to_handles;
|
||||
};
|
||||
|
||||
extern R5900DebugInterface r5900Debug;
|
||||
extern R3000DebugInterface r3000Debug;
|
||||
|
||||
@@ -21,8 +21,6 @@ typedef enum {
|
||||
|
||||
typedef enum { EXCOMM_CONST, EXCOMM_CONST_FLOAT, EXCOMM_REF, EXCOMM_OP } ExpressionCommand;
|
||||
|
||||
static std::string expressionError;
|
||||
|
||||
typedef struct {
|
||||
char Name[4];
|
||||
unsigned char Priority;
|
||||
@@ -209,10 +207,8 @@ bool isAlphaNum(char c)
|
||||
c == '@' || c == '_' || c == '$' || c == '.');
|
||||
}
|
||||
|
||||
bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, PostfixExpression& dest)
|
||||
bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, PostfixExpression& dest, std::string& error)
|
||||
{
|
||||
expressionError.clear();
|
||||
|
||||
int infixPos = 0;
|
||||
int infixLen = (int)strlen(infix);
|
||||
ExpressionOpcodeType lastOpcode = EXOP_NONE;
|
||||
@@ -241,7 +237,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
|
||||
|
||||
if(subPos == sizeof(subStr) - 1)
|
||||
{
|
||||
expressionError = TRANSLATE("ExpressionParser", "Token too long.");
|
||||
error = TRANSLATE("ExpressionParser", "Token too long.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -251,14 +247,14 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
|
||||
isFloat = true;
|
||||
else if (!parseNumber(subStr,16,subPos,value))
|
||||
{
|
||||
expressionError = StringUtil::StdStringFromFormat(
|
||||
error = StringUtil::StdStringFromFormat(
|
||||
TRANSLATE("ExpressionParser", "Invalid number \"%s\"."), subStr);
|
||||
return false;
|
||||
}
|
||||
|
||||
dest.push_back(ExpressionPair(isFloat?EXCOMM_CONST_FLOAT:EXCOMM_CONST,value));
|
||||
lastOpcode = EXOP_NUMBER;
|
||||
} else if ((first >= 'a' && first <= 'z') || first == '@')
|
||||
} else if ((first >= 'a' && first <= 'z') || first == '@' || first == '_')
|
||||
{
|
||||
while (isAlphaNum(infix[infixPos]) && subPos < static_cast<int>(sizeof(subStr)) - 1)
|
||||
{
|
||||
@@ -268,7 +264,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
|
||||
|
||||
if(subPos == sizeof(subStr) - 1)
|
||||
{
|
||||
expressionError = TRANSLATE("ExpressionParser", "Token too long.");
|
||||
error = TRANSLATE("ExpressionParser", "Token too long.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -294,7 +290,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
|
||||
continue;
|
||||
}
|
||||
|
||||
expressionError = StringUtil::StdStringFromFormat(
|
||||
error = StringUtil::StdStringFromFormat(
|
||||
TRANSLATE("ExpressionParser", "Invalid symbol \"%s\"."), subStr);
|
||||
return false;
|
||||
} else {
|
||||
@@ -302,7 +298,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
|
||||
ExpressionOpcodeType type = getExpressionOpcode(&infix[infixPos],len,lastOpcode);
|
||||
if (type == EXOP_NONE)
|
||||
{
|
||||
expressionError = StringUtil::StdStringFromFormat(
|
||||
error = StringUtil::StdStringFromFormat(
|
||||
TRANSLATE("ExpressionParser", "Invalid operator at \"%s\"."), &infix[infixPos]);
|
||||
return false;
|
||||
}
|
||||
@@ -318,7 +314,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
|
||||
{
|
||||
if (opcodeStack.empty())
|
||||
{
|
||||
expressionError = TRANSLATE("ExpressionParser", "Closing parenthesis without opening one.");
|
||||
error = TRANSLATE("ExpressionParser", "Closing parenthesis without opening one.");
|
||||
return false;
|
||||
}
|
||||
ExpressionOpcodeType t = opcodeStack[opcodeStack.size()-1];
|
||||
@@ -332,7 +328,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
|
||||
{
|
||||
if (opcodeStack.empty())
|
||||
{
|
||||
expressionError = TRANSLATE("ExpressionParser", "Closing bracket without opening one.");
|
||||
error = TRANSLATE("ExpressionParser", "Closing bracket without opening one.");
|
||||
return false;
|
||||
}
|
||||
ExpressionOpcodeType t = opcodeStack[opcodeStack.size()-1];
|
||||
@@ -385,7 +381,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
|
||||
|
||||
if (t == EXOP_BRACKETL) // opening bracket without closing one
|
||||
{
|
||||
expressionError = TRANSLATE("ExpressionParser", "Parenthesis not closed.");
|
||||
error = TRANSLATE("ExpressionParser", "Parenthesis not closed.");
|
||||
return false;
|
||||
}
|
||||
dest.push_back(ExpressionPair(EXCOMM_OP,t));
|
||||
@@ -415,7 +411,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, u64& dest)
|
||||
bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, u64& dest, std::string& error)
|
||||
{
|
||||
size_t num = 0;
|
||||
u64 opcode;
|
||||
@@ -444,7 +440,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
|
||||
opcode = exp[num++].second;
|
||||
if (valueStack.size() < ExpressionOpcodes[opcode].args)
|
||||
{
|
||||
expressionError = TRANSLATE("ExpressionParser", "Not enough arguments.");
|
||||
error = TRANSLATE("ExpressionParser", "Not enough arguments.");
|
||||
return false;
|
||||
}
|
||||
for (int l = 0; l < ExpressionOpcodes[opcode].args; l++)
|
||||
@@ -459,12 +455,12 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
|
||||
case EXOP_MEMSIZE: // must be followed by EXOP_MEM
|
||||
if (exp[num++].second != EXOP_MEM)
|
||||
{
|
||||
expressionError = TRANSLATE("ExpressionParser", "Invalid memsize operator.");
|
||||
error = TRANSLATE("ExpressionParser", "Invalid memsize operator.");
|
||||
return false;
|
||||
}
|
||||
|
||||
u64 val;
|
||||
if(!funcs->getMemoryValue(arg[1],arg[0],val,expressionError))
|
||||
if(!funcs->getMemoryValue(arg[1],arg[0],val,error))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -473,7 +469,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
|
||||
case EXOP_MEM:
|
||||
{
|
||||
u64 val;
|
||||
if (!funcs->getMemoryValue(arg[0],4,val,expressionError))
|
||||
if (!funcs->getMemoryValue(arg[0],4,val,error))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -503,7 +499,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
|
||||
case EXOP_DIV: // a/b
|
||||
if (arg[0] == 0)
|
||||
{
|
||||
expressionError = TRANSLATE("ExpressionParser", "Division by zero.");
|
||||
error = TRANSLATE("ExpressionParser", "Division by zero.");
|
||||
return false;
|
||||
}
|
||||
if (useFloat)
|
||||
@@ -514,7 +510,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
|
||||
case EXOP_MOD: // a%b
|
||||
if (arg[0] == 0)
|
||||
{
|
||||
expressionError = TRANSLATE("ExpressionParser", "Modulo by zero.");
|
||||
error = TRANSLATE("ExpressionParser", "Modulo by zero.");
|
||||
return false;
|
||||
}
|
||||
valueStack.push_back(arg[1]%arg[0]);
|
||||
@@ -593,7 +589,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
|
||||
case EXOP_TERTELSE: // exp ? exp : exp, else muss zuerst kommen!
|
||||
if (exp[num++].second != EXOP_TERTIF)
|
||||
{
|
||||
expressionError = TRANSLATE("ExpressionParser", "Invalid tertiary operator.");
|
||||
error = TRANSLATE("ExpressionParser", "Invalid tertiary operator.");
|
||||
return false;
|
||||
}
|
||||
valueStack.push_back(arg[2]?arg[1]:arg[0]);
|
||||
@@ -608,17 +604,9 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parseExpression(char* exp, IExpressionFunctions* funcs, u64& dest)
|
||||
bool parseExpression(const char* exp, IExpressionFunctions* funcs, u64& dest, std::string& error)
|
||||
{
|
||||
PostfixExpression postfix;
|
||||
if (!initPostfixExpression(exp,funcs,postfix)) return false;
|
||||
return parsePostfixExpression(postfix,funcs,dest);
|
||||
}
|
||||
|
||||
const char* getExpressionError()
|
||||
{
|
||||
if (expressionError.empty())
|
||||
return TRANSLATE("ExpressionParser", "Invalid expression.");
|
||||
|
||||
return expressionError.c_str();
|
||||
if (!initPostfixExpression(exp,funcs,postfix,error)) return false;
|
||||
return parsePostfixExpression(postfix,funcs,dest,error);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ public:
|
||||
virtual bool getMemoryValue(u32 address, int size, u64& dest, std::string& error) = 0;
|
||||
};
|
||||
|
||||
bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, PostfixExpression& dest);
|
||||
bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, u64& dest);
|
||||
bool parseExpression(const char* exp, IExpressionFunctions* funcs, u64& dest);
|
||||
const char* getExpressionError();
|
||||
bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, PostfixExpression& dest, std::string& error);
|
||||
bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, u64& dest, std::string& error);
|
||||
bool parseExpression(const char* exp, IExpressionFunctions* funcs, u64& dest, std::string& error);
|
||||
|
||||
@@ -355,11 +355,12 @@ bool MipsCheckImmediate(const char* Source, DebugInterface* cpu, int& dest, int&
|
||||
RetLen = SourceLen;
|
||||
|
||||
PostfixExpression postfix;
|
||||
if (!cpu->initExpression(Buffer,postfix))
|
||||
std::string error;
|
||||
if (!cpu->initExpression(Buffer,postfix,error))
|
||||
return false;
|
||||
|
||||
u64 value;
|
||||
if (!cpu->parseExpression(postfix,value))
|
||||
if (!cpu->parseExpression(postfix,value,error))
|
||||
return false;
|
||||
|
||||
dest = (int) value;
|
||||
|
||||
@@ -212,11 +212,6 @@ void SymbolImporter::AnalyseElf(
|
||||
SymbolGuardian::GenerateFunctionHashes(temp_database, reader);
|
||||
}
|
||||
|
||||
if (m_interrupt_import_thread)
|
||||
return;
|
||||
|
||||
ScanForFunctions(temp_database, worker_symbol_file, options);
|
||||
|
||||
if (m_interrupt_import_thread)
|
||||
return;
|
||||
|
||||
@@ -227,6 +222,14 @@ void SymbolImporter::AnalyseElf(
|
||||
return;
|
||||
|
||||
database.merge_from(temp_database);
|
||||
|
||||
if (m_interrupt_import_thread)
|
||||
return;
|
||||
|
||||
// The function scanner has to be run on the main database so that
|
||||
// functions created before the importer was run are still
|
||||
// considered. Otherwise, duplicate functions will be created.
|
||||
ScanForFunctions(database, worker_symbol_file, options);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -276,13 +279,6 @@ void SymbolImporter::ImportSymbols(
|
||||
const std::map<std::string, ccc::DataTypeHandle>& builtin_types,
|
||||
const std::atomic_bool* interrupt)
|
||||
{
|
||||
ccc::DemanglerFunctions demangler;
|
||||
if (options.DemangleSymbols)
|
||||
{
|
||||
demangler.cplus_demangle = cplus_demangle;
|
||||
demangler.cplus_demangle_opname = cplus_demangle_opname;
|
||||
}
|
||||
|
||||
u32 importer_flags =
|
||||
ccc::NO_MEMBER_FUNCTIONS |
|
||||
ccc::NO_OPTIMIZED_OUT_FUNCTIONS |
|
||||
@@ -291,6 +287,13 @@ void SymbolImporter::ImportSymbols(
|
||||
if (options.DemangleParameters)
|
||||
importer_flags |= ccc::DEMANGLE_PARAMETERS;
|
||||
|
||||
ccc::DemanglerFunctions demangler;
|
||||
if (options.DemangleSymbols)
|
||||
{
|
||||
demangler.cplus_demangle = cplus_demangle;
|
||||
demangler.cplus_demangle_opname = cplus_demangle_opname;
|
||||
}
|
||||
|
||||
if (options.ImportSymbolsFromELF)
|
||||
{
|
||||
ccc::Result<std::vector<std::unique_ptr<ccc::SymbolTable>>> symbol_tables = elf.get_all_symbol_tables();
|
||||
@@ -301,7 +304,7 @@ void SymbolImporter::ImportSymbols(
|
||||
else
|
||||
{
|
||||
ccc::Result<ccc::ModuleHandle> module_handle = ccc::import_symbol_tables(
|
||||
database, elf.name(), *symbol_tables, importer_flags, demangler, interrupt);
|
||||
database, *symbol_tables, elf.name(), ccc::Address(), importer_flags, demangler, interrupt);
|
||||
if (!module_handle.success())
|
||||
{
|
||||
ccc::report_error(module_handle.error());
|
||||
@@ -311,7 +314,7 @@ void SymbolImporter::ImportSymbols(
|
||||
|
||||
if (!nocash_path.empty() && options.ImportSymFileFromDefaultLocation)
|
||||
{
|
||||
ccc::Result<bool> nocash_result = ImportNocashSymbols(database, nocash_path, builtin_types);
|
||||
ccc::Result<bool> nocash_result = ImportNocashSymbols(database, nocash_path, 0, builtin_types);
|
||||
if (!nocash_result.success())
|
||||
{
|
||||
Console.Error("Failed to import symbol file '%s': %s",
|
||||
@@ -319,14 +322,64 @@ void SymbolImporter::ImportSymbols(
|
||||
}
|
||||
}
|
||||
|
||||
ImportExtraSymbols(database, options, builtin_types, importer_flags, demangler, interrupt);
|
||||
|
||||
Console.WriteLn("Imported %d symbols.", database.symbol_count());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void SymbolImporter::ImportExtraSymbols(
|
||||
ccc::SymbolDatabase& database,
|
||||
const Pcsx2Config::DebugAnalysisOptions& options,
|
||||
const std::map<std::string, ccc::DataTypeHandle>& builtin_types,
|
||||
u32 importer_flags,
|
||||
const ccc::DemanglerFunctions& demangler,
|
||||
const std::atomic_bool* interrupt)
|
||||
{
|
||||
MipsExpressionFunctions expression_functions(&r5900Debug, &database, true);
|
||||
|
||||
for (const DebugExtraSymbolFile& extra_symbol_file : options.ExtraSymbolFiles)
|
||||
{
|
||||
if (*interrupt)
|
||||
return;
|
||||
|
||||
if (StringUtil::EndsWithNoCase(extra_symbol_file.Path, ".sym"))
|
||||
std::string path = Path::ToNativePath(extra_symbol_file.Path);
|
||||
if (!Path::IsAbsolute(path))
|
||||
path = Path::Combine(EmuFolders::GameSettings, path);
|
||||
|
||||
if (!extra_symbol_file.Condition.empty())
|
||||
{
|
||||
ccc::Result<bool> nocash_result = ImportNocashSymbols(database, extra_symbol_file.Path, builtin_types);
|
||||
u64 expression_result = 0;
|
||||
std::string error;
|
||||
if (!parseExpression(extra_symbol_file.Condition.c_str(), &expression_functions, expression_result, error))
|
||||
{
|
||||
Console.Error("Failed to evaluate condition expression '%s' while importing extra symbol file '%s': %s",
|
||||
extra_symbol_file.Condition.c_str(), path.c_str(), error.c_str());
|
||||
}
|
||||
|
||||
if (!expression_result)
|
||||
continue;
|
||||
}
|
||||
|
||||
ccc::Address base_address;
|
||||
if (!extra_symbol_file.BaseAddress.empty())
|
||||
{
|
||||
u64 expression_result = 0;
|
||||
std::string error;
|
||||
if (!parseExpression(extra_symbol_file.BaseAddress.c_str(), &expression_functions, expression_result, error))
|
||||
{
|
||||
Console.Error("Failed to evaluate base address expression '%s' while importing extra symbol file '%s': %s",
|
||||
extra_symbol_file.BaseAddress.c_str(), path.c_str(), error.c_str());
|
||||
}
|
||||
|
||||
base_address = static_cast<u32>(expression_result);
|
||||
}
|
||||
|
||||
if (StringUtil::EndsWithNoCase(path, ".sym"))
|
||||
{
|
||||
ccc::Result<bool> nocash_result = ImportNocashSymbols(
|
||||
database, path, base_address.get_or_zero(), builtin_types);
|
||||
if (!nocash_result.success())
|
||||
{
|
||||
Console.Error("Failed to import symbol file '%s': %s",
|
||||
@@ -334,29 +387,30 @@ void SymbolImporter::ImportSymbols(
|
||||
}
|
||||
|
||||
if (!*nocash_result)
|
||||
Console.Error("Cannot open symbol file '%s'.", extra_symbol_file.Path.c_str());
|
||||
Console.Error("Cannot open symbol file '%s'.", path.c_str());
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
Error error;
|
||||
std::optional<std::vector<u8>> image = FileSystem::ReadBinaryFile(extra_symbol_file.Path.c_str());
|
||||
std::optional<std::vector<u8>> image = FileSystem::ReadBinaryFile(path.c_str());
|
||||
if (!image.has_value())
|
||||
{
|
||||
Console.Error("Failed to read extra symbol file '%s'.", extra_symbol_file.Path.c_str());
|
||||
Console.Error("Failed to read extra symbol file '%s'.", path.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string file_name(Path::GetFileName(extra_symbol_file.Path));
|
||||
std::string file_name(Path::GetFileName(path));
|
||||
|
||||
ccc::Result<std::unique_ptr<ccc::SymbolFile>> symbol_file = ccc::parse_symbol_file(std::move(*image), file_name.c_str());
|
||||
ccc::Result<std::unique_ptr<ccc::SymbolFile>> symbol_file = ccc::parse_symbol_file(
|
||||
std::move(*image), file_name.c_str());
|
||||
if (!symbol_file.success())
|
||||
{
|
||||
ccc::report_error(symbol_file.error());
|
||||
continue;
|
||||
}
|
||||
|
||||
ccc::Result<std::vector<std::unique_ptr<ccc::SymbolTable>>> symbol_tables = (*symbol_file)->get_all_symbol_tables();
|
||||
ccc::Result<std::vector<std::unique_ptr<ccc::SymbolTable>>> symbol_tables =
|
||||
(*symbol_file)->get_all_symbol_tables();
|
||||
if (!symbol_tables.success())
|
||||
{
|
||||
ccc::report_error(symbol_tables.error());
|
||||
@@ -364,22 +418,19 @@ void SymbolImporter::ImportSymbols(
|
||||
}
|
||||
|
||||
ccc::Result<ccc::ModuleHandle> module_handle = ccc::import_symbol_tables(
|
||||
database, elf.name(), *symbol_tables, importer_flags, demangler, interrupt);
|
||||
database, *symbol_tables, (*symbol_file)->name(), base_address, importer_flags, demangler, interrupt);
|
||||
if (!module_handle.success())
|
||||
{
|
||||
ccc::report_error(module_handle.error());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLn("Imported %d symbols.", database.symbol_count());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ccc::Result<bool> SymbolImporter::ImportNocashSymbols(
|
||||
ccc::SymbolDatabase& database,
|
||||
const std::string& file_path,
|
||||
u32 base_address,
|
||||
const std::map<std::string, ccc::DataTypeHandle>& builtin_types)
|
||||
{
|
||||
auto file = FileSystem::OpenManagedCFile(file_path.c_str(), "r");
|
||||
@@ -405,6 +456,8 @@ ccc::Result<bool> SymbolImporter::ImportNocashSymbols(
|
||||
if (address == 0 && strcmp(value, "0") == 0)
|
||||
continue;
|
||||
|
||||
address += base_address;
|
||||
|
||||
if (value[0] == '.')
|
||||
{
|
||||
// data directives
|
||||
@@ -498,12 +551,32 @@ std::unique_ptr<ccc::ast::Node> SymbolImporter::GetBuiltInType(
|
||||
void SymbolImporter::ScanForFunctions(
|
||||
ccc::SymbolDatabase& database, const ccc::ElfSymbolFile& elf, const Pcsx2Config::DebugAnalysisOptions& options)
|
||||
{
|
||||
MipsExpressionFunctions expression_functions(&r5900Debug, &database, true);
|
||||
|
||||
u32 start_address = 0;
|
||||
u32 end_address = 0;
|
||||
if (options.CustomFunctionScanRange)
|
||||
{
|
||||
start_address = static_cast<u32>(std::stoull(options.FunctionScanStartAddress.c_str(), nullptr, 16));
|
||||
end_address = static_cast<u32>(std::stoull(options.FunctionScanEndAddress.c_str(), nullptr, 16));
|
||||
u64 expression_result = 0;
|
||||
std::string error;
|
||||
|
||||
if (!parseExpression(options.FunctionScanStartAddress.c_str(), &expression_functions, expression_result, error))
|
||||
{
|
||||
Console.Error("Failed to evaluate start address expression '%s' while scanning for functions: %s",
|
||||
options.FunctionScanStartAddress.c_str(), error.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
start_address = static_cast<u32>(expression_result);
|
||||
|
||||
if (!parseExpression(options.FunctionScanEndAddress.c_str(), &expression_functions, expression_result, error))
|
||||
{
|
||||
Console.Error("Failed to evaluate end address expression '%s' while scanning for functions: %s",
|
||||
options.FunctionScanEndAddress.c_str(), error.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
end_address = static_cast<u32>(expression_result);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -46,9 +46,18 @@ public:
|
||||
const std::map<std::string, ccc::DataTypeHandle>& builtin_types,
|
||||
const std::atomic_bool* interrupt);
|
||||
|
||||
static void ImportExtraSymbols(
|
||||
ccc::SymbolDatabase& database,
|
||||
const Pcsx2Config::DebugAnalysisOptions& options,
|
||||
const std::map<std::string, ccc::DataTypeHandle>& builtin_types,
|
||||
u32 importer_flags,
|
||||
const ccc::DemanglerFunctions& demangler,
|
||||
const std::atomic_bool* interrupt);
|
||||
|
||||
static ccc::Result<bool> ImportNocashSymbols(
|
||||
ccc::SymbolDatabase& database,
|
||||
const std::string& file_path,
|
||||
u32 base_address,
|
||||
const std::map<std::string, ccc::DataTypeHandle>& builtin_types);
|
||||
|
||||
static std::unique_ptr<ccc::ast::Node> GetBuiltInType(
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "GS/Renderers/Vulkan/VKShaderCache.h"
|
||||
#include "GS/Renderers/Vulkan/VKSwapChain.h"
|
||||
|
||||
#include "BuildVersion.h"
|
||||
#include "Host.h"
|
||||
|
||||
#include "common/Console.h"
|
||||
@@ -103,16 +104,15 @@ VkInstance GSDeviceVK::CreateVulkanInstance(const WindowInfo& wi, OptionalExtens
|
||||
if (!SelectInstanceExtensions(&enabled_extensions, wi, oe, enable_debug_utils))
|
||||
return VK_NULL_HANDLE;
|
||||
|
||||
// Remember to manually update this every release. We don't pull in svnrev.h here, because
|
||||
// it's only the major/minor version, and rebuilding the file every time something else changes
|
||||
// is unnecessary.
|
||||
VkApplicationInfo app_info = {};
|
||||
app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||
app_info.pNext = nullptr;
|
||||
app_info.pApplicationName = "PCSX2";
|
||||
app_info.applicationVersion = VK_MAKE_VERSION(1, 7, 0);
|
||||
app_info.applicationVersion = VK_MAKE_VERSION(
|
||||
BuildVersion::GitTagHi, BuildVersion::GitTagMid, BuildVersion::GitTagLo);
|
||||
app_info.pEngineName = "PCSX2";
|
||||
app_info.engineVersion = VK_MAKE_VERSION(1, 7, 0);
|
||||
app_info.engineVersion = VK_MAKE_VERSION(
|
||||
BuildVersion::GitTagHi, BuildVersion::GitTagMid, BuildVersion::GitTagLo);
|
||||
app_info.apiVersion = VK_API_VERSION_1_1;
|
||||
|
||||
VkInstanceCreateInfo instance_create_info = {};
|
||||
|
||||
@@ -108,13 +108,13 @@ static void FillPipelineCacheHeader(VK_PIPELINE_CACHE_HEADER* header)
|
||||
X(shaderc_compile_options_set_generate_debug_info) \
|
||||
X(shaderc_compile_options_set_optimization_level) \
|
||||
X(shaderc_compile_options_set_target_env) \
|
||||
X(shaderc_compilation_status_to_string) \
|
||||
X(shaderc_compile_into_spv) \
|
||||
X(shaderc_result_release) \
|
||||
X(shaderc_result_get_length) \
|
||||
X(shaderc_result_get_num_warnings) \
|
||||
X(shaderc_result_get_bytes) \
|
||||
X(shaderc_result_get_error_message)
|
||||
X(shaderc_result_get_error_message) \
|
||||
X(shaderc_result_get_compilation_status)
|
||||
|
||||
// TODO: NOT thread safe, yet.
|
||||
namespace dyn_shaderc
|
||||
@@ -205,6 +205,25 @@ static void DumpBadShader(std::string_view code, std::string_view errors)
|
||||
}
|
||||
}
|
||||
|
||||
static const char* compilation_status_to_string(shaderc_compilation_status status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
#define CASE(x) case shaderc_compilation_status_##x: return #x
|
||||
CASE(success);
|
||||
CASE(invalid_stage);
|
||||
CASE(compilation_error);
|
||||
CASE(internal_error);
|
||||
CASE(null_result_object);
|
||||
CASE(invalid_assembly);
|
||||
CASE(validation_error);
|
||||
CASE(transformation_error);
|
||||
CASE(configuration_error);
|
||||
#undef CASE
|
||||
}
|
||||
return "unknown_error";
|
||||
}
|
||||
|
||||
std::optional<VKShaderCache::SPIRVCodeVector> VKShaderCache::CompileShaderToSPV(u32 stage, std::string_view source, bool debug)
|
||||
{
|
||||
std::optional<VKShaderCache::SPIRVCodeVector> ret;
|
||||
@@ -216,21 +235,26 @@ std::optional<VKShaderCache::SPIRVCodeVector> VKShaderCache::CompileShaderToSPV(
|
||||
|
||||
dyn_shaderc::shaderc_compile_options_set_source_language(options, shaderc_source_language_glsl);
|
||||
dyn_shaderc::shaderc_compile_options_set_target_env(options, shaderc_target_env_vulkan, 0);
|
||||
#ifdef SHADERC_PCSX2_CUSTOM
|
||||
dyn_shaderc::shaderc_compile_options_set_generate_debug_info(options, debug,
|
||||
debug && GSDeviceVK::GetInstance()->GetOptionalExtensions().vk_khr_shader_non_semantic_info);
|
||||
#else
|
||||
if (debug)
|
||||
dyn_shaderc::shaderc_compile_options_set_generate_debug_info(options);
|
||||
#endif
|
||||
dyn_shaderc::shaderc_compile_options_set_optimization_level(
|
||||
options, debug ? shaderc_optimization_level_zero : shaderc_optimization_level_performance);
|
||||
|
||||
shaderc_compilation_result_t result;
|
||||
const shaderc_compilation_status status = dyn_shaderc::shaderc_compile_into_spv(
|
||||
const shaderc_compilation_result_t result = dyn_shaderc::shaderc_compile_into_spv(
|
||||
dyn_shaderc::s_compiler, source.data(), source.length(), static_cast<shaderc_shader_kind>(stage), "source",
|
||||
"main", options, &result);
|
||||
if (status != shaderc_compilation_status_success)
|
||||
"main", options);
|
||||
|
||||
shaderc_compilation_status status = shaderc_compilation_status_null_result_object;
|
||||
if (!result || (status = dyn_shaderc::shaderc_result_get_compilation_status(result)) != shaderc_compilation_status_success)
|
||||
{
|
||||
const std::string_view errors(result ? dyn_shaderc::shaderc_result_get_error_message(result) :
|
||||
"null result object");
|
||||
ERROR_LOG("Failed to compile shader to SPIR-V: {}\n{}",
|
||||
dyn_shaderc::shaderc_compilation_status_to_string(status), errors);
|
||||
const std::string_view errors(result ? dyn_shaderc::shaderc_result_get_error_message(result)
|
||||
: "null result object");
|
||||
ERROR_LOG("Failed to compile shader to SPIR-V: {}\n{}", compilation_status_to_string(status), errors);
|
||||
DumpBadShader(source, errors);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -623,7 +623,7 @@ void GameList::ScanDirectory(const char* path, bool recursive, bool only_cache,
|
||||
}
|
||||
|
||||
const std::string_view filename = Path::GetFileName(ffd.FileName);
|
||||
progress->SetFormattedStatusText(fmt::format(TRANSLATE_FS("GameList","Scanning {}..."), filename.data()).c_str());
|
||||
progress->SetStatusText(fmt::format(TRANSLATE_FS("GameList","Scanning {}..."), filename.data()).c_str());
|
||||
ScanFile(std::move(ffd.FileName), ffd.ModificationTime, lock, played_time_map, custom_attributes_ini);
|
||||
progress->SetProgressValue(files_scanned);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
|
||||
#include "BuildVersion.h"
|
||||
#include "GS.h"
|
||||
#include "GS/Renderers/HW/GSTextureReplacements.h"
|
||||
#include "Host.h"
|
||||
#include "LayeredSettingsInterface.h"
|
||||
#include "VMManager.h"
|
||||
#include "svnrev.h"
|
||||
|
||||
#include "common/Assertions.h"
|
||||
#include "common/CrashHandler.h"
|
||||
@@ -159,7 +159,7 @@ bool Host::ConfirmFormattedMessage(const std::string_view title, const char* for
|
||||
|
||||
std::string Host::GetHTTPUserAgent()
|
||||
{
|
||||
return fmt::format("PCSX2 " GIT_REV " ({})", GetOSVersionString());
|
||||
return fmt::format("PCSX2 {} ({})", BuildVersion::GitRev, GetOSVersionString());
|
||||
}
|
||||
|
||||
std::unique_lock<std::mutex> Host::GetSettingsLock()
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
|
||||
#include "BuildVersion.h"
|
||||
#include "CDVD/CDVDcommon.h"
|
||||
#include "GS/Renderers/Common/GSDevice.h"
|
||||
#include "GS/Renderers/Common/GSTexture.h"
|
||||
@@ -23,7 +24,6 @@
|
||||
#include "USB/USB.h"
|
||||
#include "VMManager.h"
|
||||
#include "ps2/BiosTools.h"
|
||||
#include "svnrev.h"
|
||||
|
||||
#include "common/Console.h"
|
||||
#include "common/Error.h"
|
||||
@@ -6633,7 +6633,7 @@ void FullscreenUI::DrawAboutWindow()
|
||||
"This allows you to play PS2 games on your PC, with many additional features and benefits."));
|
||||
ImGui::NewLine();
|
||||
|
||||
ImGui::TextWrapped(FSUI_CSTR("Version: %s"), GIT_REV);
|
||||
ImGui::TextWrapped(FSUI_CSTR("Version: %s"), BuildVersion::GitRev);
|
||||
ImGui::NewLine();
|
||||
|
||||
ImGui::TextWrapped("%s",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
|
||||
#include "BuildVersion.h"
|
||||
#include "Config.h"
|
||||
#include "Counters.h"
|
||||
#include "GS.h"
|
||||
@@ -24,7 +25,6 @@
|
||||
#include "SIO/Pad/PadBase.h"
|
||||
#include "USB/USB.h"
|
||||
#include "VMManager.h"
|
||||
#include "svnrev.h"
|
||||
#include "cpuinfo.h"
|
||||
|
||||
#include "common/BitUtils.h"
|
||||
@@ -170,7 +170,7 @@ __ri void ImGuiManager::DrawPerformanceOverlay(float& position_y, float scale, f
|
||||
|
||||
if (GSConfig.OsdShowVersion)
|
||||
{
|
||||
text.append_format("{}PCSX2 {}", first ? "" : " | ", GIT_REV);
|
||||
text.append_format("{}PCSX2 {}", first ? "" : " | ", BuildVersion::GitRev);
|
||||
}
|
||||
|
||||
if (!text.empty())
|
||||
@@ -246,6 +246,13 @@ __ri void ImGuiManager::DrawPerformanceOverlay(float& position_y, float scale, f
|
||||
FormatProcessorStat(text, PerformanceMetrics::GetGSThreadUsage(), PerformanceMetrics::GetGSThreadAverageTime());
|
||||
DRAW_LINE(fixed_font, text.c_str(), IM_COL32(255, 255, 255, 255));
|
||||
|
||||
if (THREAD_VU1)
|
||||
{
|
||||
text = "VU: ";
|
||||
FormatProcessorStat(text, PerformanceMetrics::GetVUThreadUsage(), PerformanceMetrics::GetVUThreadAverageTime());
|
||||
DRAW_LINE(fixed_font, text.c_str(), IM_COL32(255, 255, 255, 255));
|
||||
}
|
||||
|
||||
const u32 gs_sw_threads = PerformanceMetrics::GetGSSWThreadCount();
|
||||
for (u32 i = 0; i < gs_sw_threads; i++)
|
||||
{
|
||||
@@ -255,13 +262,6 @@ __ri void ImGuiManager::DrawPerformanceOverlay(float& position_y, float scale, f
|
||||
DRAW_LINE(fixed_font, text.c_str(), IM_COL32(255, 255, 255, 255));
|
||||
}
|
||||
|
||||
if (THREAD_VU1)
|
||||
{
|
||||
text = "VU: ";
|
||||
FormatProcessorStat(text, PerformanceMetrics::GetVUThreadUsage(), PerformanceMetrics::GetVUThreadAverageTime());
|
||||
DRAW_LINE(fixed_font, text.c_str(), IM_COL32(255, 255, 255, 255));
|
||||
}
|
||||
|
||||
if (GSCapture::IsCapturing())
|
||||
{
|
||||
text = "CAP: ";
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
|
||||
#include "BuildVersion.h"
|
||||
#include "Common.h"
|
||||
#include "Host.h"
|
||||
#include "Memory.h"
|
||||
#include "Elfheader.h"
|
||||
#include "PINE.h"
|
||||
#include "VMManager.h"
|
||||
#include "svnrev.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdio>
|
||||
@@ -306,7 +306,7 @@ bool PINEServer::Initialize(int slot)
|
||||
return false;
|
||||
}
|
||||
server.sun_family = AF_UNIX;
|
||||
strcpy(server.sun_path, m_socket_name.c_str());
|
||||
StringUtil::Strlcpy(server.sun_path, m_socket_name, sizeof(server.sun_path));
|
||||
|
||||
// we unlink the socket so that when releasing this thread the socket gets
|
||||
// freed even if we didn't close correctly the loop
|
||||
@@ -607,14 +607,12 @@ PINEServer::IPCBuffer PINEServer::ParseCommand(std::span<u8> buf, std::vector<u8
|
||||
{
|
||||
if (!VMManager::HasValidVM())
|
||||
goto error;
|
||||
|
||||
static constexpr const char* version = "PCSX2 " GIT_REV;
|
||||
static constexpr u32 size = sizeof(version) + 1;
|
||||
u32 size = strlen(BuildVersion::GitRev) + 7;
|
||||
if (!SafetyChecks(buf_cnt, 0, ret_cnt, size + 4, buf_size)) [[unlikely]]
|
||||
goto error;
|
||||
ToResultVector(ret_buffer, size, ret_cnt);
|
||||
ret_cnt += 4;
|
||||
memcpy(&ret_buffer[ret_cnt], version, size);
|
||||
snprintf(reinterpret_cast<char*>(&ret_buffer[ret_cnt]), size, "PCSX2 %s", BuildVersion::GitRev);
|
||||
ret_cnt += size;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1625,6 +1625,8 @@ void Pcsx2Config::DebugAnalysisOptions::LoadSave(SettingsWrapper& wrap)
|
||||
file = ExtraSymbolFiles[i];
|
||||
|
||||
SettingsWrapEntryEx(file.Path, "Path");
|
||||
SettingsWrapEntryEx(file.BaseAddress, "BaseAddress");
|
||||
SettingsWrapEntryEx(file.Condition, "Condition");
|
||||
|
||||
if (wrap.IsLoading())
|
||||
ExtraSymbolFiles.emplace_back(std::move(file));
|
||||
|
||||
@@ -3,13 +3,10 @@
|
||||
|
||||
#include "InputRecordingFile.h"
|
||||
|
||||
#include "BuildVersion.h"
|
||||
#include "Utilities/InputRecordingLogger.h"
|
||||
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/StringUtil.h"
|
||||
#include "DebugTools/Debug.h"
|
||||
#include "MemoryTypes.h"
|
||||
#include "svnrev.h"
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
@@ -23,7 +20,7 @@ void InputRecordingFile::InputRecordingFileHeader::init() noexcept
|
||||
|
||||
void InputRecordingFile::setEmulatorVersion()
|
||||
{
|
||||
StringUtil::Strlcpy(m_header.m_emulatorVersion, "PCSX2-" GIT_REV, sizeof(m_header.m_emulatorVersion));
|
||||
snprintf(m_header.m_emulatorVersion, sizeof(m_header.m_emulatorVersion), "PCSX2-%s", BuildVersion::GitRev);
|
||||
}
|
||||
|
||||
void InputRecordingFile::setAuthor(const std::string& _author)
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
#include "Host.h"
|
||||
#include "IconsPromptFont.h"
|
||||
|
||||
#include "svnrev.h"
|
||||
|
||||
#include "fmt/core.h"
|
||||
|
||||
#include <map>
|
||||
@@ -1075,4 +1073,4 @@ bool FileMcd_DeleteCard(const std::string_view name)
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
#include "ryml_std.hpp"
|
||||
#include "ryml.hpp"
|
||||
|
||||
#include "svnrev.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
@@ -2380,4 +2378,4 @@ bool FolderMemoryCardAggregator::ReIndex(uint slot, const bool enableFiltering,
|
||||
SetFiltering(enableFiltering);
|
||||
m_lastKnownFilter = filter;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -420,10 +420,11 @@ __forceinline void UpdateSpdifMode()
|
||||
{
|
||||
const int OPM = PlayMode;
|
||||
|
||||
if (Spdif.Out & 0x4 && SPU2::MsgToConsole()) // use 24/32bit PCM data streaming
|
||||
if (Spdif.Out & 0x4) // use 24/32bit PCM data streaming
|
||||
{
|
||||
PlayMode = 8;
|
||||
SPU2::ConLog("* SPU2: WARNING: Possibly CDDA mode set!\n");
|
||||
if (SPU2::MsgToConsole())
|
||||
SPU2::ConLog("* SPU2: WARNING: Possibly CDDA mode set!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
|
||||
#include "Achievements.h"
|
||||
#include "BuildVersion.h"
|
||||
#include "CDVD/CDVD.h"
|
||||
#include "COP0.h"
|
||||
#include "Cache.h"
|
||||
@@ -27,7 +28,6 @@
|
||||
#include "VMManager.h"
|
||||
#include "VUmicro.h"
|
||||
#include "ps2/BiosTools.h"
|
||||
#include "svnrev.h"
|
||||
|
||||
#include "common/Error.h"
|
||||
#include "common/FileSystem.h"
|
||||
@@ -972,11 +972,14 @@ static bool SaveState_AddToZip(zip_t* zf, ArchiveEntryList* srclist, SaveStateSc
|
||||
|
||||
VersionIndicator* vi = static_cast<VersionIndicator*>(std::malloc(sizeof(VersionIndicator)));
|
||||
vi->save_version = g_SaveVersion;
|
||||
#if GIT_TAGGED_COMMIT
|
||||
StringUtil::Strlcpy(vi->version, GIT_TAG, std::size(vi->version));
|
||||
#else
|
||||
StringUtil::Strlcpy(vi->version, "Unknown", std::size(vi->version));
|
||||
#endif
|
||||
if (BuildVersion::GitTaggedCommit)
|
||||
{
|
||||
StringUtil::Strlcpy(vi->version, BuildVersion::GitTag, std::size(vi->version));
|
||||
}
|
||||
else
|
||||
{
|
||||
StringUtil::Strlcpy(vi->version, "Unknown", std::size(vi->version));
|
||||
}
|
||||
|
||||
zip_source_t* const zs = zip_source_buffer(zf, vi, sizeof(*vi), 1);
|
||||
if (!zs)
|
||||
|
||||
@@ -34,10 +34,9 @@ namespace usb_eyetoy
|
||||
|
||||
HRESULT DirectShow::CallbackHandler::SampleCB(double time, IMediaSample* sample)
|
||||
{
|
||||
HRESULT hr;
|
||||
unsigned char* buffer;
|
||||
|
||||
hr = sample->GetPointer((BYTE**)&buffer);
|
||||
const HRESULT hr = sample->GetPointer((BYTE**)&buffer);
|
||||
if (hr != S_OK)
|
||||
return S_OK;
|
||||
|
||||
@@ -588,7 +587,7 @@ namespace usb_eyetoy
|
||||
{
|
||||
mpeg_mutex.lock();
|
||||
int len2 = mpeg_buffer.length;
|
||||
if ((unsigned int)len < mpeg_buffer.length)
|
||||
if (static_cast<size_t>(len) < mpeg_buffer.length)
|
||||
len2 = len;
|
||||
memcpy(buf, mpeg_buffer.start, len2);
|
||||
mpeg_buffer.length = 0;
|
||||
|
||||
@@ -26,8 +26,8 @@ namespace usb_eyetoy
|
||||
|
||||
std::unique_ptr<VideoDevice> videodev;
|
||||
USBDevice* mic;
|
||||
uint8_t regs[0xFF]; //OV519
|
||||
uint8_t i2c_regs[0xFF]; //OV764x
|
||||
u8 regs[0xFF]; //OV519
|
||||
u8 i2c_regs[0xFF]; //OV764x
|
||||
|
||||
int hw_camera_running;
|
||||
int frame_step;
|
||||
@@ -81,10 +81,10 @@ namespace usb_eyetoy
|
||||
}
|
||||
else if (s->hw_camera_running && s->subtype == TYPE_OV511P)
|
||||
{
|
||||
const int width = 320;
|
||||
const int height = 240;
|
||||
constexpr int width = 320;
|
||||
constexpr int height = 240;
|
||||
const FrameFormat format = format_yuv400;
|
||||
const int mirror = 0;
|
||||
constexpr int mirror = 0;
|
||||
Console.WriteLn(
|
||||
"EyeToy : eyetoy_open(); hw=%d, w=%d, h=%d, fmt=%d, mirr=%d", s->hw_camera_running, width, height, format, mirror);
|
||||
if (s->videodev->Open(width, height, format, mirror) != 0)
|
||||
@@ -111,7 +111,7 @@ namespace usb_eyetoy
|
||||
s->mic->klass.handle_reset(s->mic);
|
||||
}
|
||||
|
||||
static void webcam_handle_control_eyetoy(USBDevice* dev, USBPacket* p, int request, int value, int index, int length, uint8_t* data)
|
||||
static void webcam_handle_control_eyetoy(USBDevice* dev, USBPacket* p, int request, int value, int index, int length, u8* data)
|
||||
{
|
||||
EYETOYState* s = USB_CONTAINER_OF(dev, EYETOYState, dev);
|
||||
int ret = 0;
|
||||
@@ -172,9 +172,9 @@ namespace usb_eyetoy
|
||||
case R518_I2C_CTL:
|
||||
if (data[0] == 1) // Commit I2C write
|
||||
{
|
||||
//uint8_t reg = s->regs[s->regs[R51x_I2C_W_SID]];
|
||||
uint8_t reg = s->regs[R51x_I2C_SADDR_3];
|
||||
uint8_t val = s->regs[R51x_I2C_DATA];
|
||||
//u8 reg = s->regs[s->regs[R51x_I2C_W_SID]];
|
||||
const u8 reg = s->regs[R51x_I2C_SADDR_3];
|
||||
const u8 val = s->regs[R51x_I2C_DATA];
|
||||
if ((reg == 0x12) && (val & 0x80))
|
||||
{
|
||||
s->i2c_regs[0x12] = val & ~0x80; //or skip?
|
||||
@@ -194,7 +194,7 @@ namespace usb_eyetoy
|
||||
else if (s->regs[R518_I2C_CTL] == 0x03 && data[0] == 0x05)
|
||||
{
|
||||
//s->regs[s->regs[R51x_I2C_R_SID]] but seems to default to 0x43 (R51x_I2C_SADDR_2)
|
||||
uint8_t i2c_reg = s->regs[R51x_I2C_SADDR_2];
|
||||
const u8 i2c_reg = s->regs[R51x_I2C_SADDR_2];
|
||||
s->regs[R51x_I2C_DATA] = 0;
|
||||
|
||||
if (i2c_reg < sizeof(s->i2c_regs))
|
||||
@@ -218,7 +218,7 @@ namespace usb_eyetoy
|
||||
}
|
||||
}
|
||||
|
||||
static void webcam_handle_control_ov511p(USBDevice* dev, USBPacket* p, int request, int value, int index, int length, uint8_t* data)
|
||||
static void webcam_handle_control_ov511p(USBDevice* dev, USBPacket* p, int request, int value, int index, int length, u8* data)
|
||||
{
|
||||
EYETOYState* s = USB_CONTAINER_OF(dev, EYETOYState, dev);
|
||||
int ret = 0;
|
||||
@@ -242,8 +242,8 @@ namespace usb_eyetoy
|
||||
case R511_I2C_CTL:
|
||||
if (data[0] == 1)
|
||||
{
|
||||
uint8_t reg = s->regs[R51x_I2C_SADDR_3];
|
||||
uint8_t val = s->regs[R51x_I2C_DATA];
|
||||
u8 reg = s->regs[R51x_I2C_SADDR_3];
|
||||
const u8 val = s->regs[R51x_I2C_DATA];
|
||||
if (reg < sizeof(s->i2c_regs))
|
||||
{
|
||||
s->i2c_regs[reg] = val;
|
||||
@@ -251,7 +251,7 @@ namespace usb_eyetoy
|
||||
}
|
||||
else if (s->regs[R511_I2C_CTL] == 0x03 && data[0] == 0x05)
|
||||
{
|
||||
uint8_t i2c_reg = s->regs[R51x_I2C_SADDR_2];
|
||||
const u8 i2c_reg = s->regs[R51x_I2C_SADDR_2];
|
||||
s->regs[R51x_I2C_DATA] = 0;
|
||||
|
||||
if (i2c_reg < sizeof(s->i2c_regs))
|
||||
@@ -277,8 +277,8 @@ namespace usb_eyetoy
|
||||
static void webcam_handle_data_eyetoy(USBDevice* dev, USBPacket* p)
|
||||
{
|
||||
EYETOYState* s = USB_CONTAINER_OF(dev, EYETOYState, dev);
|
||||
static const unsigned int max_ep_size = 896;
|
||||
uint8_t devep = p->ep->nr;
|
||||
static constexpr unsigned int max_ep_size = 896;
|
||||
const u8 devep = p->ep->nr;
|
||||
|
||||
if (!s->hw_camera_running)
|
||||
{
|
||||
@@ -346,7 +346,7 @@ namespace usb_eyetoy
|
||||
static void webcam_handle_data_ov511p(USBDevice* dev, USBPacket* p)
|
||||
{
|
||||
EYETOYState* s = USB_CONTAINER_OF(dev, EYETOYState, dev);
|
||||
uint8_t devep = p->ep->nr;
|
||||
const u8 devep = p->ep->nr;
|
||||
|
||||
if (!s->hw_camera_running)
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
namespace usb_eyetoy
|
||||
{
|
||||
static const uint8_t eyetoy_dev_descriptor[] = {
|
||||
static const u8 eyetoy_dev_descriptor[] = {
|
||||
0x12, /* bLength */
|
||||
0x01, /* bDescriptorType */
|
||||
WBVAL(0x0110), /* bcdUSB */
|
||||
@@ -28,7 +28,7 @@ namespace usb_eyetoy
|
||||
0x01, /* bNumConfigurations */
|
||||
};
|
||||
|
||||
static const uint8_t eyetoy_config_descriptor[] = {
|
||||
static const u8 eyetoy_config_descriptor[] = {
|
||||
0x09, // bLength
|
||||
0x02, // bDescriptorType (Configuration)
|
||||
0xB4, 0x00, // wTotalLength 180
|
||||
@@ -215,7 +215,7 @@ namespace usb_eyetoy
|
||||
0x00, 0x00, // wLockDelay 0
|
||||
};
|
||||
|
||||
static const uint8_t ov511p_dev_descriptor[] = {
|
||||
static const u8 ov511p_dev_descriptor[] = {
|
||||
0x12, // bLength
|
||||
0x01, // bDescriptorType (Device)
|
||||
0x00, 0x01, // bcdUSB 1.00
|
||||
@@ -232,7 +232,7 @@ namespace usb_eyetoy
|
||||
0x01, // bNumConfigurations 1
|
||||
};
|
||||
|
||||
static const uint8_t ov511p_config_descriptor[] = {
|
||||
static const u8 ov511p_config_descriptor[] = {
|
||||
0x09, // bLength
|
||||
0x02, // bDescriptorType (Configuration)
|
||||
0x89, 0x00, // wTotalLength 137
|
||||
@@ -379,7 +379,7 @@ namespace usb_eyetoy
|
||||
0x01, // bInterval 1 (unit depends on device speed)
|
||||
};
|
||||
|
||||
static const uint8_t ov519_defaults[] = {
|
||||
static const u8 ov519_defaults[] = {
|
||||
0xc0, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x14, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x08, 0x98, 0xff, 0x00, 0x03, 0x00, 0x00, 0x1e, 0x01, 0xf1, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
@@ -398,7 +398,7 @@ namespace usb_eyetoy
|
||||
0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static const uint8_t ov7648_defaults[] = {
|
||||
static const u8 ov7648_defaults[] = {
|
||||
0x00, 0x84, 0x84, 0x84, 0x34, 0x3e, 0x80, 0x8c, 0x00, 0x00, 0x76, 0x48, 0x7b, 0x5b, 0x00, 0x98,
|
||||
0x57, 0x00, 0x14, 0xa3, 0x04, 0x00, 0x00, 0x1a, 0xba, 0x03, 0xf3, 0x00, 0x7f, 0xa2, 0x00, 0x01,
|
||||
0xc0, 0x80, 0x80, 0xde, 0x10, 0x8a, 0xa2, 0xe2, 0x20, 0x00, 0x00, 0x00, 0x88, 0x81, 0x00, 0x94,
|
||||
@@ -417,7 +417,7 @@ namespace usb_eyetoy
|
||||
0x75, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static const uint8_t ov511p_defaults[] = {
|
||||
static const u8 ov511p_defaults[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01, 0x27, 0x1d, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x4f, 0x1d, 0x00, 0x01, 0x01, 0x04,
|
||||
0x01, 0x01, 0x01, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
@@ -436,7 +436,7 @@ namespace usb_eyetoy
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static const uint8_t ov7620_defaults[] = {
|
||||
static const u8 ov7620_defaults[] = {
|
||||
0x00, 0x84, 0x84, 0x84, 0x34, 0x3e, 0x80, 0x8c, 0x00, 0x00, 0x76, 0x48, 0x7b, 0x5b, 0x00, 0x98,
|
||||
0x57, 0x00, 0x14, 0xa3, 0x04, 0x00, 0x00, 0x1a, 0xba, 0x03, 0xf3, 0x00, 0x7f, 0xa2, 0x00, 0x01,
|
||||
0xc0, 0x80, 0x80, 0xde, 0x10, 0x8a, 0xa2, 0xe2, 0x20, 0x00, 0x00, 0x00, 0x88, 0x81, 0x00, 0x94,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
|
||||
#include "Achievements.h"
|
||||
#include "BuildVersion.h"
|
||||
#include "CDVD/CDVD.h"
|
||||
#include "CDVD/IsoReader.h"
|
||||
#include "Counters.h"
|
||||
@@ -40,7 +41,6 @@
|
||||
#include "Vif_Dynarec.h"
|
||||
#include "VMManager.h"
|
||||
#include "ps2/BiosTools.h"
|
||||
#include "svnrev.h"
|
||||
|
||||
#include "common/Console.h"
|
||||
#include "common/Error.h"
|
||||
@@ -2490,7 +2490,7 @@ void LogGPUCapabilities()
|
||||
|
||||
void VMManager::LogCPUCapabilities()
|
||||
{
|
||||
Console.WriteLn(Color_StrongGreen, "PCSX2 " GIT_REV);
|
||||
Console.WriteLn(Color_StrongGreen, "PCSX2 %s", BuildVersion::GitRev);
|
||||
Console.WriteLnFmt("Savestate version: 0x{:x}\n", g_SaveVersion);
|
||||
Console.WriteLn();
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ bool _VIF0chain()
|
||||
}
|
||||
|
||||
pMem = (u32*)dmaGetAddr(vif0ch.madr, false);
|
||||
if (pMem == NULL)
|
||||
if (pMem == nullptr)
|
||||
{
|
||||
vif0.cmd = 0;
|
||||
vif0.tag.size = 0;
|
||||
|
||||
@@ -27,7 +27,7 @@ void vif1TransferToMemory()
|
||||
u128* pMem = (u128*)dmaGetAddr(vif1ch.madr, false);
|
||||
|
||||
// VIF from gsMemory
|
||||
if (pMem == NULL)
|
||||
if (pMem == nullptr)
|
||||
{ // Is vif0ptag empty?
|
||||
Console.WriteLn("Vif1 Tag BUSERR");
|
||||
dmacRegs.stat.BEIS = true; // Bus Error
|
||||
@@ -117,7 +117,7 @@ bool _VIF1chain()
|
||||
}
|
||||
|
||||
pMem = (u32*)dmaGetAddr(vif1ch.madr, !vif1ch.chcr.DIR);
|
||||
if (pMem == NULL)
|
||||
if (pMem == nullptr)
|
||||
{
|
||||
vif1.cmd = 0;
|
||||
vif1.tag.size = 0;
|
||||
@@ -305,8 +305,8 @@ __fi void vif1Interrupt()
|
||||
// from the GS then we handle that separately (KH2 for testing)
|
||||
if (vif1ch.chcr.DIR)
|
||||
{
|
||||
bool isDirect = (vif1.cmd & 0x7f) == 0x50;
|
||||
bool isDirectHL = (vif1.cmd & 0x7f) == 0x51;
|
||||
const bool isDirect = (vif1.cmd & 0x7f) == 0x50;
|
||||
const bool isDirectHL = (vif1.cmd & 0x7f) == 0x51;
|
||||
if ((isDirect && !gifUnit.CanDoPath2()) || (isDirectHL && !gifUnit.CanDoPath2HL()))
|
||||
{
|
||||
GUNIT_WARN("vif1Interrupt() - Waiting for Path 2 to be ready");
|
||||
|
||||
@@ -23,7 +23,7 @@ static u32 QWCinVIFMFIFO(u32 DrainADDR, u32 qwc)
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 limit = dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16;
|
||||
const u32 limit = dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16;
|
||||
//Drain is higher than SPR so it has looped round,
|
||||
//calculate from base to the SPR tag addr and what is left in the top of the ring
|
||||
ret = ((spr0ch.madr - dmacRegs.rbor.ADDR) + (limit - DrainADDR)) >> 4;
|
||||
@@ -35,8 +35,8 @@ static u32 QWCinVIFMFIFO(u32 DrainADDR, u32 qwc)
|
||||
}
|
||||
static __fi bool mfifoVIF1rbTransfer()
|
||||
{
|
||||
u32 msize = dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16;
|
||||
u32 mfifoqwc = std::min(QWCinVIFMFIFO(vif1ch.madr, vif1ch.qwc), vif1ch.qwc);
|
||||
const u32 msize = dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16;
|
||||
const u32 mfifoqwc = std::min(QWCinVIFMFIFO(vif1ch.madr, vif1ch.qwc), vif1ch.qwc);
|
||||
u32* src;
|
||||
bool ret;
|
||||
|
||||
@@ -49,7 +49,7 @@ static __fi bool mfifoVIF1rbTransfer()
|
||||
/* Check if the transfer should wrap around the ring buffer */
|
||||
if ((vif1ch.madr + (mfifoqwc << 4)) > (msize))
|
||||
{
|
||||
int s1 = ((msize)-vif1ch.madr) >> 2;
|
||||
const int s1 = ((msize)-vif1ch.madr) >> 2;
|
||||
|
||||
VIF_LOG("Split MFIFO");
|
||||
|
||||
@@ -57,7 +57,7 @@ static __fi bool mfifoVIF1rbTransfer()
|
||||
vif1ch.madr = qwctag(vif1ch.madr);
|
||||
|
||||
src = (u32*)PSM(vif1ch.madr);
|
||||
if (src == NULL)
|
||||
if (src == nullptr)
|
||||
return false;
|
||||
|
||||
if (vif1.irqoffset.enabled)
|
||||
@@ -75,7 +75,7 @@ static __fi bool mfifoVIF1rbTransfer()
|
||||
vif1ch.madr = qwctag(vif1ch.madr);
|
||||
|
||||
src = (u32*)PSM(vif1ch.madr);
|
||||
if (src == NULL)
|
||||
if (src == nullptr)
|
||||
return false;
|
||||
VIF1transfer(src, ((mfifoqwc << 2) - s1));
|
||||
}
|
||||
@@ -86,7 +86,7 @@ static __fi bool mfifoVIF1rbTransfer()
|
||||
|
||||
/* it doesn't, so just transfer 'qwc*4' words */
|
||||
src = (u32*)PSM(vif1ch.madr);
|
||||
if (src == NULL)
|
||||
if (src == nullptr)
|
||||
return false;
|
||||
|
||||
if (vif1.irqoffset.enabled)
|
||||
@@ -133,7 +133,7 @@ static __fi void mfifo_VIF1chain()
|
||||
|
||||
//No need to exit on non-mfifo as it is indirect anyway, so it can be transferring this while spr refills the mfifo
|
||||
|
||||
if (pMem == NULL)
|
||||
if (pMem == nullptr)
|
||||
return;
|
||||
|
||||
if (vif1.irqoffset.enabled)
|
||||
@@ -158,7 +158,7 @@ void mfifoVifMaskMem(int id)
|
||||
//DevCon.Warning("VIF MFIFO MADR below bottom of ring buffer, wrapping VIF MADR = %x Ring Bottom %x", vif1ch.madr, dmacRegs.rbor.ADDR);
|
||||
vif1ch.madr = qwctag(vif1ch.madr);
|
||||
}
|
||||
if (vif1ch.madr > (dmacRegs.rbor.ADDR + (u32)dmacRegs.rbsr.RMSK)) //Usual scenario is the tag is near the end (Front Mission 4)
|
||||
if (vif1ch.madr > (dmacRegs.rbor.ADDR + static_cast<u32>(dmacRegs.rbsr.RMSK))) //Usual scenario is the tag is near the end (Front Mission 4)
|
||||
{
|
||||
//DevCon.Warning("VIF MFIFO MADR outside top of ring buffer, wrapping VIF MADR = %x Ring Top %x", vif1ch.madr, (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK)+16);
|
||||
vif1ch.madr = qwctag(vif1ch.madr);
|
||||
@@ -281,8 +281,8 @@ void vifMFIFOInterrupt()
|
||||
|
||||
if (vif1ch.chcr.DIR)
|
||||
{
|
||||
bool isDirect = (vif1.cmd & 0x7f) == 0x50;
|
||||
bool isDirectHL = (vif1.cmd & 0x7f) == 0x51;
|
||||
const bool isDirect = (vif1.cmd & 0x7f) == 0x50;
|
||||
const bool isDirectHL = (vif1.cmd & 0x7f) == 0x51;
|
||||
if ((isDirect && !gifUnit.CanDoPath2()) || (isDirectHL && !gifUnit.CanDoPath2HL()))
|
||||
{
|
||||
GUNIT_WARN("vifMFIFOInterrupt() - Waiting for Path 2 to be ready");
|
||||
|
||||
@@ -109,7 +109,7 @@ static __fi void vuExecMicro(int idx, u32 addr, bool requires_wait)
|
||||
}
|
||||
|
||||
GetVifX.queued_program = true;
|
||||
if ((s32)addr == -1)
|
||||
if (static_cast<s32>(addr) == -1)
|
||||
GetVifX.queued_pc = addr;
|
||||
else
|
||||
GetVifX.queued_pc = addr & (idx ? 0x7ffu : 0x1ffu);
|
||||
@@ -144,7 +144,7 @@ __fi int _vifCode_Direct(int pass, const u8* data, bool isDirectHL)
|
||||
vif1Only();
|
||||
pass1
|
||||
{
|
||||
int vifImm = (u16)vif1Regs.code;
|
||||
const int vifImm = static_cast<u16>(vif1Regs.code);
|
||||
vif1.tag.size = vifImm ? (vifImm * 4) : (65536 * 4);
|
||||
vif1.pass = 1;
|
||||
return 1;
|
||||
@@ -152,9 +152,9 @@ __fi int _vifCode_Direct(int pass, const u8* data, bool isDirectHL)
|
||||
pass2
|
||||
{
|
||||
const char* name = isDirectHL ? "DirectHL" : "Direct";
|
||||
GIF_TRANSFER_TYPE tranType = isDirectHL ? GIF_TRANS_DIRECTHL : GIF_TRANS_DIRECT;
|
||||
uint size = std::min(vif1.vifpacketsize, vif1.tag.size) * 4; // Get size in bytes
|
||||
uint ret = gifUnit.TransferGSPacketData(tranType, (u8*)data, size);
|
||||
const GIF_TRANSFER_TYPE tranType = isDirectHL ? GIF_TRANS_DIRECTHL : GIF_TRANS_DIRECT;
|
||||
const uint size = std::min(vif1.vifpacketsize, vif1.tag.size) * 4; // Get size in bytes
|
||||
const uint ret = gifUnit.TransferGSPacketData(tranType, (u8*)data, size);
|
||||
|
||||
vif1.tag.size -= ret / 4; // Convert to u32's
|
||||
vif1Regs.stat.VGW = false;
|
||||
@@ -202,7 +202,7 @@ vifOp(vifCode_Flush)
|
||||
//vifStruct& vifX = GetVifX;
|
||||
pass1or2
|
||||
{
|
||||
bool p1or2 = (gifRegs.stat.APATH != 0 && gifRegs.stat.APATH != 3);
|
||||
const bool p1or2 = (gifRegs.stat.APATH != 0 && gifRegs.stat.APATH != 3);
|
||||
vif1Regs.stat.VGW = false;
|
||||
vifFlush(idx);
|
||||
if (gifUnit.checkPaths(1, 1, 0) || p1or2)
|
||||
@@ -234,7 +234,7 @@ vifOp(vifCode_FlushA)
|
||||
pass1or2
|
||||
{
|
||||
//Gif_Path& p3 = gifUnit.gifPath[GIF_PATH_3];
|
||||
u32 gifBusy = gifUnit.checkPaths(1, 1, 1) || (gifRegs.stat.APATH != 0);
|
||||
const u32 gifBusy = gifUnit.checkPaths(1, 1, 1) || (gifRegs.stat.APATH != 0);
|
||||
//bool doStall = false;
|
||||
vif1Regs.stat.VGW = false;
|
||||
vifFlush(idx);
|
||||
@@ -298,7 +298,7 @@ vifOp(vifCode_Mark)
|
||||
vifStruct& vifX = GetVifX;
|
||||
pass1
|
||||
{
|
||||
vifXRegs.mark = (u16)vifXRegs.code;
|
||||
vifXRegs.mark = static_cast<u16>(vifXRegs.code);
|
||||
vifXRegs.stat.MRK = true;
|
||||
vifX.cmd = 0;
|
||||
vifX.pass = 0;
|
||||
@@ -311,7 +311,7 @@ static __fi void _vifCode_MPG(int idx, u32 addr, const u32* data, int size)
|
||||
{
|
||||
VURegs& VUx = idx ? VU1 : VU0;
|
||||
vifStruct& vifX = GetVifX;
|
||||
u16 vuMemSize = idx ? 0x4000 : 0x1000;
|
||||
const u16 vuMemSize = idx ? 0x4000 : 0x1000;
|
||||
pxAssert(VUx.Micro);
|
||||
|
||||
vifExecQueue(idx);
|
||||
@@ -371,8 +371,8 @@ vifOp(vifCode_MPG)
|
||||
vifStruct& vifX = GetVifX;
|
||||
pass1
|
||||
{
|
||||
int vifNum = (u8)(vifXRegs.code >> 16);
|
||||
vifX.tag.addr = (u16)(vifXRegs.code << 3) & (idx ? 0x3fff : 0xfff);
|
||||
const int vifNum = static_cast<u8>(vifXRegs.code >> 16);
|
||||
vifX.tag.addr = static_cast<u16>(vifXRegs.code << 3) & (idx ? 0x3fff : 0xfff);
|
||||
vifX.tag.size = vifNum ? (vifNum * 2) : 512;
|
||||
vifFlush(idx);
|
||||
|
||||
@@ -406,7 +406,7 @@ vifOp(vifCode_MPG)
|
||||
//DevCon.Warning("Vif%d MPG Split Overflow full %x", idx, vifX.tag.addr + vifX.tag.size*4);
|
||||
}
|
||||
_vifCode_MPG(idx, vifX.tag.addr, data, vifX.tag.size);
|
||||
int ret = vifX.tag.size;
|
||||
const int ret = vifX.tag.size;
|
||||
vifX.tag.size = 0;
|
||||
vifX.cmd = 0;
|
||||
vifX.pass = 0;
|
||||
@@ -430,7 +430,7 @@ vifOp(vifCode_MSCAL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
vuExecMicro(idx, (u16)(vifXRegs.code), false);
|
||||
vuExecMicro(idx, static_cast<u16>(vifXRegs.code), false);
|
||||
vifX.cmd = 0;
|
||||
vifX.pass = 0;
|
||||
|
||||
@@ -455,7 +455,7 @@ vifOp(vifCode_MSCALF)
|
||||
{
|
||||
vifXRegs.stat.VGW = false;
|
||||
vifFlush(idx);
|
||||
if (u32 a = gifUnit.checkPaths(1, 1, 0))
|
||||
if (const u32 a = gifUnit.checkPaths(1, 1, 0))
|
||||
{
|
||||
GUNIT_WARN("Vif MSCALF: Stall! [%d,%d]", !!(a & 1), !!(a & 2));
|
||||
vif1Regs.stat.VGW = true;
|
||||
@@ -469,7 +469,7 @@ vifOp(vifCode_MSCALF)
|
||||
return 0;
|
||||
}
|
||||
|
||||
vuExecMicro(idx, (u16)(vifXRegs.code), true);
|
||||
vuExecMicro(idx, static_cast<u16>(vifXRegs.code), true);
|
||||
vifX.cmd = 0;
|
||||
vifX.pass = 0;
|
||||
vifExecQueue(idx);
|
||||
@@ -595,7 +595,7 @@ static __fi int _vifCode_STColRow(const u32* data, u32* pmem2)
|
||||
{
|
||||
vifStruct& vifX = GetVifX;
|
||||
|
||||
int ret = std::min(4 - vifX.tag.addr, vifX.vifpacketsize);
|
||||
const int ret = std::min(4 - vifX.tag.addr, vifX.vifpacketsize);
|
||||
pxAssume(vifX.tag.addr < 4);
|
||||
pxAssume(ret > 0);
|
||||
|
||||
@@ -641,7 +641,7 @@ vifOp(vifCode_STCol)
|
||||
}
|
||||
pass2
|
||||
{
|
||||
u32 ret = _vifCode_STColRow<idx>(data, &vifX.MaskCol._u32[vifX.tag.addr]);
|
||||
const u32 ret = _vifCode_STColRow<idx>(data, &vifX.MaskCol._u32[vifX.tag.addr]);
|
||||
if (idx && vifX.tag.size == 0)
|
||||
vu1Thread.WriteCol(vifX);
|
||||
return ret;
|
||||
@@ -662,7 +662,7 @@ vifOp(vifCode_STRow)
|
||||
}
|
||||
pass2
|
||||
{
|
||||
u32 ret = _vifCode_STColRow<idx>(data, &vifX.MaskRow._u32[vifX.tag.addr]);
|
||||
const u32 ret = _vifCode_STColRow<idx>(data, &vifX.MaskRow._u32[vifX.tag.addr]);
|
||||
if (idx && vifX.tag.size == 0)
|
||||
vu1Thread.WriteRow(vifX);
|
||||
return ret;
|
||||
@@ -676,8 +676,8 @@ vifOp(vifCode_STCycl)
|
||||
vifStruct& vifX = GetVifX;
|
||||
pass1
|
||||
{
|
||||
vifXRegs.cycle.cl = (u8)(vifXRegs.code);
|
||||
vifXRegs.cycle.wl = (u8)(vifXRegs.code >> 8);
|
||||
vifXRegs.cycle.cl = static_cast<u8>(vifXRegs.code);
|
||||
vifXRegs.cycle.wl = static_cast<u8>(vifXRegs.code >> 8);
|
||||
vifX.cmd = 0;
|
||||
vifX.pass = 0;
|
||||
}
|
||||
@@ -744,9 +744,9 @@ vifOp(vifCode_Unpack)
|
||||
{
|
||||
vifStruct& vifX = GetVifX;
|
||||
VIFregisters& vifRegs = vifXRegs;
|
||||
uint vl = vifX.cmd & 0x03;
|
||||
uint vn = (vifX.cmd >> 2) & 0x3;
|
||||
bool flg = (vifRegs.code >> 15) & 1;
|
||||
const uint vl = vifX.cmd & 0x03;
|
||||
const uint vn = (vifX.cmd >> 2) & 0x3;
|
||||
const bool flg = (vifRegs.code >> 15) & 1;
|
||||
static const char* const vntbl[] = {"S", "V2", "V3", "V4"};
|
||||
static const uint vltbl[] = {32, 16, 8, 5};
|
||||
|
||||
|
||||
@@ -43,4 +43,4 @@ alignas(16) extern nVifStruct nVif[2];
|
||||
alignas(16) extern nVifCall nVifUpk[(2 * 2 * 16) * 4]; // ([USN][Masking][Unpack Type]) [curCycle]
|
||||
alignas(16) extern u32 nVifMask[3][4][4]; // [MaskNumber][CycleNumber][Vector]
|
||||
|
||||
static constexpr bool newVifDynaRec = 1; // Use code in newVif_Dynarec.inl
|
||||
static constexpr bool newVifDynaRec = 1; // Use code in Vif_Dynarec.inl
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
|
||||
#include "arm64/newVif_UnpackNEON.h"
|
||||
#include "arm64/Vif_UnpackNEON.h"
|
||||
#include "arm64/AsmHelpers.h"
|
||||
#include "MTVU.h"
|
||||
|
||||
@@ -367,7 +367,9 @@ void VifUnpackNEON_Dynarec::ModUnpack(int upknum, bool PostOp)
|
||||
case 3:
|
||||
case 7:
|
||||
case 11:
|
||||
pxFailRel(fmt::format("Vpu/Vif - Invalid Unpack! [{}]", upknum).c_str());
|
||||
// TODO: Needs hardware testing.
|
||||
// Dynasty Warriors 5: Empire - Player 2 chose a character menu.
|
||||
Console.Warning("Vpu/Vif: Invalid Unpack %d", upknum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
|
||||
#include "newVif_UnpackNEON.h"
|
||||
#include "Vif_UnpackNEON.h"
|
||||
#include "common/Perf.h"
|
||||
|
||||
namespace a64 = vixl::aarch64;
|
||||
@@ -345,7 +345,9 @@ void VifUnpackNEON_Base::xUnpack(int upknum) const
|
||||
case 3:
|
||||
case 7:
|
||||
case 11:
|
||||
pxFailRel(fmt::format("Vpu/Vif - Invalid Unpack! [{}]", upknum).c_str());
|
||||
// TODO: Needs hardware testing.
|
||||
// Dynasty Warriors 5: Empire - Player 2 chose a character menu.
|
||||
Console.Warning("Vpu/Vif: Invalid Unpack %d", upknum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -117,10 +117,10 @@
|
||||
<ClCompile Include="arm64\AsmHelpers.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'!='ARM64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="arm64\newVif_Dynarec.cpp">
|
||||
<ClCompile Include="arm64\Vif_Dynarec.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'!='ARM64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="arm64\newVif_UnpackNEON.cpp">
|
||||
<ClCompile Include="arm64\Vif_UnpackNEON.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'!='ARM64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="arm64\RecStubs.cpp">
|
||||
@@ -419,6 +419,7 @@
|
||||
<ExcludedFromBuild Condition="'$(Platform)'!='x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ps2\BiosTools.cpp" />
|
||||
<ClCompile Include="BuildVersion.cpp" />
|
||||
<ClCompile Include="Counters.cpp" />
|
||||
<ClCompile Include="FiFo.cpp" />
|
||||
<ClCompile Include="Hw.cpp" />
|
||||
@@ -456,10 +457,10 @@
|
||||
<ClCompile Include="Vif_Codes.cpp" />
|
||||
<ClCompile Include="Vif_Transfer.cpp" />
|
||||
<ClCompile Include="Vif_Unpack.cpp" />
|
||||
<ClCompile Include="x86\newVif_Dynarec.cpp">
|
||||
<ClCompile Include="x86\Vif_Dynarec.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'!='x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="x86\newVif_UnpackSSE.cpp">
|
||||
<ClCompile Include="x86\Vif_UnpackSSE.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'!='x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SPR.cpp" />
|
||||
@@ -578,7 +579,7 @@
|
||||
<ClInclude Include="arm64\AsmHelpers.h">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'!='ARM64'">true</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="arm64\newVif_UnpackNEON.h">
|
||||
<ClInclude Include="arm64\Vif_UnpackNEON.h">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'!='ARM64'">true</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CDVD\BlockdumpFileReader.h" />
|
||||
@@ -865,6 +866,7 @@
|
||||
<ClInclude Include="Elfheader.h" />
|
||||
<ClInclude Include="CDVD\IsoFileFormats.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="BuildVersion.h" />
|
||||
<ClInclude Include="Common.h" />
|
||||
<ClInclude Include="Config.h" />
|
||||
<ClInclude Include="SaveState.h" />
|
||||
@@ -896,7 +898,7 @@
|
||||
<ClInclude Include="Vif_Dma.h" />
|
||||
<ClInclude Include="Vif_Unpack.h" />
|
||||
<ClInclude Include="x86\newVif.h" />
|
||||
<ClInclude Include="x86\newVif_UnpackSSE.h" />
|
||||
<ClInclude Include="x86\Vif_UnpackSSE.h" />
|
||||
<ClInclude Include="SPR.h" />
|
||||
<ClInclude Include="Gif.h" />
|
||||
<ClInclude Include="R5900.h" />
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user