Compare commits

..

48 Commits

Author SHA1 Message Date
Ty Lamontagne
37555e3048 CDVD | CHD: Account for pre/post gap offsets when filling TOC
This will fix discs with tracks with both an INDEX 00 and INDEX 01
2024-11-27 15:55:11 -05:00
Ty Lamontagne
d8f18a3318 CDVD: Byte swap hack. CHD CD audio with OSDSYS is working 2024-11-27 15:54:56 -05:00
Ty Lamontagne
47a732d0fe CDVD: CHD cue support for audio CDs
experimental and will blow out your ears
2024-11-27 15:25:59 -05:00
Ty Lamontagne
4eae1b7127 Deps: Fix zlib patch hash 2024-11-27 15:13:57 -05:00
TellowKrinkle
a71ea9917a Vulkan: Re-add shaderc status strings to error messages 2024-11-27 14:57:16 -05:00
KamFretoZ
500e2c43b1 Shaderc: Make non-semantic debug optional
Don't you hate it when you come up with more ideas just minutes AFTER the PR has been merged?
2024-11-27 14:57:16 -05:00
KamFretoZ
e6a4cee86c CI: Ensure dependency cache key reflects all state 2024-11-27 14:57:16 -05:00
Dreadmoth
5a94f6819d GameDB: Champions of Norrath & Champions: Return to Arms (PAL) (#11976)
Add Half Pixel Offset Special (Texture) and Round Sprite Half to Champions of Norrath.
Add Show Overscan to Champions of Norrath and Champions: Return to Arms.
2024-11-27 17:39:40 +01:00
chaoticgd
132e3e507d 3rdparty/ccc: Fix some bounds checks and other error handling logic 2024-11-27 17:37:36 +01:00
chaoticgd
ffa06fbb09 3rdparty/ccc: Make CCC_ASSERT macro call abort instead of exit 2024-11-27 17:37:36 +01:00
TheLastRar
028e6cd8a8 CDVD: Fix DevCon log typo 2024-11-26 19:09:07 -05:00
chaoticgd
719063e996 Console: Limit buffer size in ConsoleLogFromVM::Write 2024-11-26 22:44:00 +01:00
PCSX2 Bot
5d40f36fa8 [ci skip] Qt: Update Base Translation. 2024-11-26 19:33:00 +01:00
PCSX2 Bot
31ffcfc920 PAD: Update to latest controller database. 2024-11-25 17:06:11 +01:00
Ty Lamontagne
c9642b70f6 CDVD: Only take ADR and track index/num from host IOCTL SUBQ
Fixes the OSDSYS CD player minute:second counter
2024-11-25 10:02:23 -05:00
Ty Lamontagne
849fa57bf6 CDVD: Adjust register logging 2024-11-25 10:02:23 -05:00
Ty Lamontagne
2c95ef76f1 CDVD: Minor cleanup and fix off-by-one TOC filling issue 2024-11-25 10:02:23 -05:00
Ty Lamontagne
4d9cb885b2 CDVD: Use disc track indexes for our track array. 2024-11-25 10:02:23 -05:00
Ty Lamontagne
e375f98f7a CDVD: Fix OSDSYS Audio CD regression.
There is still an existing issue with the tracks.
2024-11-25 10:02:23 -05:00
lightningterror
1b80f3aea2 Vif: Cleanup code a bit.
Const, casts, nullptr.
2024-11-25 14:02:59 +01:00
Jordan
b0496645f1 GameDB: Various fixes (#12030)
Fixes texture flickering in mission screens on PTO IV Pacific Theater of Operations and corrupted textures banding lighting in levels and bloom misalignment in MOH European Assault.
2024-11-24 19:39:05 +01:00
lightningterror
235cb13647 Vif: Replace some asserts with logs.
The conditions need hardware testing.
Use logs instead so the games don't crash and are still playable.
2024-11-23 13:13:19 +01:00
lightningterror
504dd9f513 Vif: Rename/remove new prefix from files. 2024-11-23 13:13:19 +01:00
Ty Lamontagne
e3fedf1676 QT: Use SetStatusText instead of passing a formatted string as a fmt
This caused crashes when file names had percent signs in them because we passed the file name as the format to SetFormattedStatusText. I opted to continue to use fmt for consistency.
2024-11-22 19:28:55 -05:00
lightningterror
f113a51783 DEV9: Code cleanup.
Casts, constants, unused functions, switch cases.
2024-11-23 00:21:41 +01:00
chaoticgd
f69d5835b8 PINE: Fix stack buffer overflow for long XDG_RUNTIME_DIR paths 2024-11-22 14:10:32 -05:00
PCSX2 Bot
8e8277c0c9 [ci skip] Qt: Update Base Translation. 2024-11-21 01:42:41 +01:00
secondsabre
c6c4eaf31c GameDB: Atelier Iris (SLUS-21113) fixes (#12021) 2024-11-20 15:33:34 -05:00
KamFretoZ
6324722b65 Qt: Add Volume indicator to verbose status 2024-11-20 15:56:15 +01:00
KamFretoZ
efd8c9ec69 OSD: Move VU stats above SW threads. 2024-11-20 15:56:15 +01:00
TellowKrinkle
9858aa1aa5 CMake: Try to put /usr/local/include last 2024-11-18 02:22:30 -06:00
PCSX2 Bot
256a946f96 [ci skip] Qt: Update Base Translation. 2024-11-17 14:43:32 +01:00
chaoticgd
a507964f33 Debugger: Generate a name map for label symbols 2024-11-16 11:50:19 -05:00
chaoticgd
7584a6bb29 Debugger: Allow symbols starting with an underscore in expressions 2024-11-16 11:50:19 -05:00
chaoticgd
ce6103be30 Debugger: Improve function scanner performance for unmapped addresses 2024-11-16 11:50:19 -05:00
chaoticgd
9da4459ab3 Debugger: Run the function scanner on the main symbol database 2024-11-16 11:50:19 -05:00
chaoticgd
3b9b9a84cd Debugger: Use expressions for the function scanner address range 2024-11-16 11:50:19 -05:00
chaoticgd
cce0ae4369 Debugger: Allow loading symbols conditionally and with a base address 2024-11-16 11:50:19 -05:00
chaoticgd
efb43ac7f9 Debugger: Make the expression parser thread safe 2024-11-16 11:50:19 -05:00
lightningterror
8132a8a7f8 USB: Cleanup eyetoy code a bit.
Types, casts, consts.
2024-11-15 15:58:23 +01:00
PCSX2 Bot
9c753cb692 [ci skip] Qt: Update Base Translation. 2024-11-15 14:26:08 +01:00
Berylskid
514e6675c4 GameDB: Fix Enemies Stuck in Armored Core Nine Breaker 2024-11-14 11:22:00 -05:00
Chromaryu
18454fd5d0 GameDB: Add TexInRT on SLPM-62482 2024-11-14 11:20:03 -05:00
chaoticgd
eeb919325e Misc: Minimise the amount of work done when svnrev.h is updated 2024-11-12 09:14:39 -05:00
Julien Reichardt
959be142ed Deps: Update Flatpak dependencies 2024-11-12 08:36:52 -05:00
PCSX2 Bot
42be91d48d PAD: Update to latest controller database. 2024-11-11 14:20:57 -05:00
Bobby Smith
908f916656 GameDB: NBA 2K6 fix hangs on PAL version 2024-11-11 11:52:44 -05:00
Ty Lamontagne
5441c7ed59 Debugger: Use native separators when using external symbol files 2024-11-06 17:06:37 -05:00
104 changed files with 1787 additions and 1472 deletions

View File

@@ -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' }}

View File

@@ -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'

View File

@@ -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'

View File

@@ -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

View File

@@ -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": [

View File

@@ -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",

View File

@@ -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

View File

@@ -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

View File

@@ -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'

View File

@@ -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;
}
}

View File

@@ -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()));
}

View File

@@ -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());
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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; }

View File

@@ -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;

View File

@@ -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();

View File

@@ -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);

View File

@@ -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)

View File

@@ -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]))

View File

@@ -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"

View File

@@ -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,

View File

@@ -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()

View File

@@ -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')
{

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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"

View File

@@ -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()

View File

@@ -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);
}

View File

@@ -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;
};

View File

@@ -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

View File

@@ -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
View 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
View 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

View File

@@ -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;
}
}

View File

@@ -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.

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -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.

View File

@@ -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();

View File

@@ -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;

View File

@@ -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)

View File

@@ -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,

View File

@@ -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);

View File

@@ -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);

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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]);

View File

@@ -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;

View File

@@ -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

View File

@@ -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();

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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();
}
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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
{

View File

@@ -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(

View File

@@ -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 = {};

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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()

View File

@@ -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",

View File

@@ -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: ";

View File

@@ -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;
}

View File

@@ -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));

View 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)

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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;

View File

@@ -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)
{

View File

@@ -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,

View File

@@ -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();

View File

@@ -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;

View File

@@ -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");

View File

@@ -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");

View File

@@ -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};

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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