From 01acd59357774ceb81f6e8df8dc691bf093dc90e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 3 Jan 2025 20:55:26 +0100 Subject: [PATCH 1/4] CwCheats: Avoid logspam with some bad cheats. Tag cheat structs with names (sometimes useful for debugging). --- Core/CwCheat.cpp | 40 ++++++++++++++++++++++++++-------------- Core/CwCheat.h | 1 + 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/Core/CwCheat.cpp b/Core/CwCheat.cpp index a8731ba7a2..3215d41330 100644 --- a/Core/CwCheat.cpp +++ b/Core/CwCheat.cpp @@ -126,8 +126,8 @@ bool CheatFileParser::Parse() { void CheatFileParser::Flush() { if (!pendingLines_.empty()) { + cheats_.push_back({ codeFormat_, lastCheatInfo_.name, pendingLines_ }); FlushCheatInfo(); - cheats_.push_back({ codeFormat_, pendingLines_ }); pendingLines_.clear(); } codeFormat_ = CheatCodeFormat::UNDEFINED; @@ -1161,28 +1161,40 @@ void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat, switch (type) { case 0: // 8 bit write - InvalidateICache(base + op.pointerCommands.offset, 1); - Memory::Write_U8((u8)val, base + op.pointerCommands.offset); + if (Memory::IsValidAddress(base + op.pointerCommands.offset)) { + InvalidateICache(base + op.pointerCommands.offset, 1); + Memory::WriteUnchecked_U8((u8)val, base + op.pointerCommands.offset); + } break; case 1: // 16-bit write - InvalidateICache(base + op.pointerCommands.offset, 2); - Memory::Write_U16((u16)val, base + op.pointerCommands.offset); + if (Memory::IsValidAddress(base + op.pointerCommands.offset)) { + InvalidateICache(base + op.pointerCommands.offset, 2); + Memory::WriteUnchecked_U16((u16)val, base + op.pointerCommands.offset); + } break; case 2: // 32-bit write - InvalidateICache(base + op.pointerCommands.offset, 4); - Memory::Write_U32((u32)val, base + op.pointerCommands.offset); + if (Memory::IsValidAddress(base + op.pointerCommands.offset)) { + InvalidateICache(base + op.pointerCommands.offset, 4); + Memory::WriteUnchecked_U32((u32)val, base + op.pointerCommands.offset); + } break; case 3: // 8 bit inverse write - InvalidateICache(base - op.pointerCommands.offset, 1); - Memory::Write_U8((u8)val, base - op.pointerCommands.offset); + if (Memory::IsValidAddress(base - op.pointerCommands.offset)) { + InvalidateICache(base - op.pointerCommands.offset, 1); + Memory::WriteUnchecked_U8((u8)val, base - op.pointerCommands.offset); + } break; case 4: // 16-bit inverse write - InvalidateICache(base - op.pointerCommands.offset, 2); - Memory::Write_U16((u16)val, base - op.pointerCommands.offset); + if (Memory::IsValidAddress(base - op.pointerCommands.offset)) { + InvalidateICache(base - op.pointerCommands.offset, 2); + Memory::WriteUnchecked_U16((u16)val, base - op.pointerCommands.offset); + } break; case 5: // 32-bit inverse write - InvalidateICache(base - op.pointerCommands.offset, 4); - Memory::Write_U32((u32)val, base - op.pointerCommands.offset); + if (Memory::IsValidAddress(base - op.pointerCommands.offset)) { + InvalidateICache(base - op.pointerCommands.offset, 4); + Memory::WriteUnchecked_U32((u32)val, base - op.pointerCommands.offset); + } break; case -1: // Operation already performed, nothing to do break; @@ -1200,7 +1212,7 @@ void CWCheatEngine::Run() { return; } - for (CheatCode cheat : cheats_) { + for (const CheatCode &cheat : cheats_) { // InterpretNextOp and ExecuteOp move i. for (size_t i = 0; i < cheat.lines.size(); ) { CheatOperation op = InterpretNextOp(cheat, i); diff --git a/Core/CwCheat.h b/Core/CwCheat.h index a012054eae..2ac7e71542 100644 --- a/Core/CwCheat.h +++ b/Core/CwCheat.h @@ -32,6 +32,7 @@ enum class CheatCodeFormat { struct CheatCode { CheatCodeFormat fmt; + std::string name; std::vector lines; }; From b6fde72f52038eae1f250f5fa4c00b9e15c7c4f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 3 Jan 2025 21:01:51 +0100 Subject: [PATCH 2/4] CwCheat: Avoid instruction cache invalidations on reads. Not needed. --- Core/CwCheat.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/Core/CwCheat.cpp b/Core/CwCheat.cpp index 3215d41330..62dcac6d62 100644 --- a/Core/CwCheat.cpp +++ b/Core/CwCheat.cpp @@ -820,8 +820,6 @@ void CWCheatEngine::ApplyMemoryOperator(const CheatOperation &op, uint32_t(*oper bool CWCheatEngine::TestIf(const CheatOperation &op, bool(*oper)(int, int)) { if (Memory::IsValidRange(op.addr, op.sz)) { - InvalidateICache(op.addr, op.sz); - int memoryValue = 0; if (op.sz == 1) memoryValue = (int)Memory::Read_U8(op.addr); @@ -837,9 +835,6 @@ bool CWCheatEngine::TestIf(const CheatOperation &op, bool(*oper)(int, int)) { bool CWCheatEngine::TestIfAddr(const CheatOperation &op, bool(*oper)(int, int)) { if (Memory::IsValidRange(op.addr, op.sz) && Memory::IsValidRange(op.ifAddrTypes.compareAddr, op.sz)) { - InvalidateICache(op.addr, op.sz); - InvalidateICache(op.addr, op.ifAddrTypes.compareAddr); - int memoryValue1 = 0; int memoryValue2 = 0; if (op.sz == 1) { @@ -932,7 +927,6 @@ void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat, case CheatOp::CopyBytesFrom: if (Memory::IsValidRange(op.addr, op.val) && Memory::IsValidRange(op.copyBytesFrom.destAddr, op.val)) { - InvalidateICache(op.addr, op.val); InvalidateICache(op.copyBytesFrom.destAddr, op.val); Memory::Memcpy(op.copyBytesFrom.destAddr, op.addr, op.val, "CwCheat"); @@ -1009,7 +1003,6 @@ void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat, case CheatOp::Assert: if (Memory::IsValidRange(op.addr, 4)) { - InvalidateICache(op.addr, 4); if (Memory::Read_U32(op.addr) != op.val) { i = cheat.lines.size(); } @@ -1099,7 +1092,6 @@ void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat, case CheatOp::CwCheatPointerCommands: { - InvalidateICache(op.addr + op.pointerCommands.baseOffset, 4); u32 base = Memory::Read_U32(op.addr + op.pointerCommands.baseOffset); u32 val = op.val; int type = op.pointerCommands.type; @@ -1108,12 +1100,10 @@ void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat, switch (line.part1 >> 28) { case 0x1: // type copy byte { - InvalidateICache(op.addr, 4); u32 srcAddr = Memory::Read_U32(op.addr) + op.pointerCommands.offset; u32 dstAddr = Memory::Read_U32(op.addr + op.pointerCommands.baseOffset) + (line.part1 & 0x0FFFFFFF); if (Memory::IsValidRange(dstAddr, val) && Memory::IsValidRange(srcAddr, val)) { InvalidateICache(dstAddr, val); - InvalidateICache(srcAddr, val); Memory::Memcpy(dstAddr, srcAddr, val, "CwCheat"); } // Don't perform any further action. @@ -1128,7 +1118,6 @@ void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat, if ((line.part1 >> 28) == 0x3) { walkOffset = -walkOffset; } - InvalidateICache(base + walkOffset, 4); base = Memory::Read_U32(base + walkOffset); switch (line.part2 >> 28) { case 0x2: @@ -1137,7 +1126,6 @@ void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat, if ((line.part2 >> 28) == 0x3) { walkOffset = -walkOffset; } - InvalidateICache(base + walkOffset, 4); base = Memory::Read_U32(base + walkOffset); break; From 74817c779d65d0a1fba3b9e219bd772a7bc358dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 3 Jan 2025 21:05:04 +0100 Subject: [PATCH 3/4] CwCheat: Don't double-check already checked memory pointers --- Core/CwCheat.cpp | 50 ++++++++++++++++++++++++------------------------ Core/CwCheat.h | 6 +++--- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/Core/CwCheat.cpp b/Core/CwCheat.cpp index 62dcac6d62..35ce7d5f43 100644 --- a/Core/CwCheat.cpp +++ b/Core/CwCheat.cpp @@ -810,42 +810,42 @@ void CWCheatEngine::ApplyMemoryOperator(const CheatOperation &op, uint32_t(*oper if (Memory::IsValidRange(op.addr, op.sz)) { InvalidateICache(op.addr, op.sz); if (op.sz == 1) - Memory::Write_U8((u8)oper(Memory::Read_U8(op.addr), op.val), op.addr); + Memory::WriteUnchecked_U8((u8)oper(Memory::ReadUnchecked_U8(op.addr), op.val), op.addr); else if (op.sz == 2) - Memory::Write_U16((u16)oper(Memory::Read_U16(op.addr), op.val),op. addr); + Memory::WriteUnchecked_U16((u16)oper(Memory::ReadUnchecked_U16(op.addr), op.val),op. addr); else if (op.sz == 4) - Memory::Write_U32((u32)oper(Memory::Read_U32(op.addr), op.val), op.addr); + Memory::WriteUnchecked_U32((u32)oper(Memory::ReadUnchecked_U32(op.addr), op.val), op.addr); } } -bool CWCheatEngine::TestIf(const CheatOperation &op, bool(*oper)(int, int)) { +bool CWCheatEngine::TestIf(const CheatOperation &op, bool(*oper)(int, int)) const { if (Memory::IsValidRange(op.addr, op.sz)) { int memoryValue = 0; if (op.sz == 1) - memoryValue = (int)Memory::Read_U8(op.addr); + memoryValue = (int)Memory::ReadUnchecked_U8(op.addr); else if (op.sz == 2) - memoryValue = (int)Memory::Read_U16(op.addr); + memoryValue = (int)Memory::ReadUnchecked_U16(op.addr); else if (op.sz == 4) - memoryValue = (int)Memory::Read_U32(op.addr); + memoryValue = (int)Memory::ReadUnchecked_U32(op.addr); return oper(memoryValue, (int)op.val); } return false; } -bool CWCheatEngine::TestIfAddr(const CheatOperation &op, bool(*oper)(int, int)) { +bool CWCheatEngine::TestIfAddr(const CheatOperation &op, bool(*oper)(int, int)) const { if (Memory::IsValidRange(op.addr, op.sz) && Memory::IsValidRange(op.ifAddrTypes.compareAddr, op.sz)) { int memoryValue1 = 0; int memoryValue2 = 0; if (op.sz == 1) { - memoryValue1 = (int)Memory::Read_U8(op.addr); - memoryValue2 = (int)Memory::Read_U8(op.ifAddrTypes.compareAddr); + memoryValue1 = (int)Memory::ReadUnchecked_U8(op.addr); + memoryValue2 = (int)Memory::ReadUnchecked_U8(op.ifAddrTypes.compareAddr); } else if (op.sz == 2) { - memoryValue1 = (int)Memory::Read_U16(op.addr); - memoryValue2 = (int)Memory::Read_U16(op.ifAddrTypes.compareAddr); + memoryValue1 = (int)Memory::ReadUnchecked_U16(op.addr); + memoryValue2 = (int)Memory::ReadUnchecked_U16(op.ifAddrTypes.compareAddr); } else if (op.sz == 4) { - memoryValue1 = (int)Memory::Read_U32(op.addr); - memoryValue2 = (int)Memory::Read_U32(op.ifAddrTypes.compareAddr); + memoryValue1 = (int)Memory::ReadUnchecked_U32(op.addr); + memoryValue2 = (int)Memory::ReadUnchecked_U32(op.ifAddrTypes.compareAddr); } return oper(memoryValue1, memoryValue2); @@ -866,11 +866,11 @@ void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat, if (Memory::IsValidRange(op.addr, op.sz)) { InvalidateICache(op.addr, op.sz); if (op.sz == 1) - Memory::Write_U8((u8)op.val, op.addr); + Memory::WriteUnchecked_U8((u8)op.val, op.addr); else if (op.sz == 2) - Memory::Write_U16((u16)op.val, op.addr); + Memory::WriteUnchecked_U16((u16)op.val, op.addr); else if (op.sz == 4) - Memory::Write_U32((u32)op.val, op.addr); + Memory::WriteUnchecked_U32((u32)op.val, op.addr); } break; @@ -913,11 +913,11 @@ void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat, for (uint32_t a = 0; a < op.multiWrite.count; a++) { if (Memory::IsValidAddress(addr)) { if (op.sz == 1) - Memory::Write_U8((u8)data, addr); + Memory::WriteUnchecked_U8((u8)data, addr); else if (op.sz == 2) - Memory::Write_U16((u16)data, addr); + Memory::WriteUnchecked_U16((u16)data, addr); else if (op.sz == 4) - Memory::Write_U32((u32)data, addr); + Memory::WriteUnchecked_U32((u32)data, addr); } addr += op.multiWrite.step; data += op.multiWrite.add; @@ -946,15 +946,15 @@ void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat, case CheatOp::VibrationFromMemory: if (Memory::IsValidRange(op.addr, 8)) { - uint16_t checkLeftVibration = Memory::Read_U16(op.addr); - uint16_t checkRightVibration = Memory::Read_U16(op.addr + 0x2); + uint16_t checkLeftVibration = Memory::ReadUnchecked_U16(op.addr); + uint16_t checkRightVibration = Memory::ReadUnchecked_U16(op.addr + 0x2); if (checkLeftVibration > 0) { SetLeftVibration(checkLeftVibration); - SetVibrationLeftDropout(Memory::Read_U8(op.addr + 0x4)); + SetVibrationLeftDropout(Memory::ReadUnchecked_U8(op.addr + 0x4)); } if (checkRightVibration > 0) { SetRightVibration(checkRightVibration); - SetVibrationRightDropout(Memory::Read_U8(op.addr + 0x6)); + SetVibrationRightDropout(Memory::ReadUnchecked_U8(op.addr + 0x6)); } } break; @@ -1003,7 +1003,7 @@ void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat, case CheatOp::Assert: if (Memory::IsValidRange(op.addr, 4)) { - if (Memory::Read_U32(op.addr) != op.val) { + if (Memory::ReadUnchecked_U32(op.addr) != op.val) { i = cheat.lines.size(); } } diff --git a/Core/CwCheat.h b/Core/CwCheat.h index 2ac7e71542..4c210f1fc2 100644 --- a/Core/CwCheat.h +++ b/Core/CwCheat.h @@ -62,9 +62,9 @@ private: CheatOperation InterpretNextTempAR(const CheatCode &cheat, size_t &i); void ExecuteOp(const CheatOperation &op, const CheatCode &cheat, size_t &i); - void ApplyMemoryOperator(const CheatOperation &op, uint32_t(*oper)(uint32_t, uint32_t)); - bool TestIf(const CheatOperation &op, bool(*oper)(int a, int b)); - bool TestIfAddr(const CheatOperation &op, bool(*oper)(int a, int b)); + inline void ApplyMemoryOperator(const CheatOperation &op, uint32_t(*oper)(uint32_t, uint32_t)); + inline bool TestIf(const CheatOperation &op, bool(*oper)(int a, int b)) const; + inline bool TestIfAddr(const CheatOperation &op, bool(*oper)(int a, int b)) const; std::vector cheats_; std::string gameID_; From 083543cc146f9abce2f99a9a8cca96f42e2731e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 3 Jan 2025 21:14:22 +0100 Subject: [PATCH 4/4] Unrelated logging improvement --- Core/HLE/sceAtrac.cpp | 2 +- ext/at3_standalone/atrac3.cpp | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Core/HLE/sceAtrac.cpp b/Core/HLE/sceAtrac.cpp index f4d99f6313..bfb508fa70 100644 --- a/Core/HLE/sceAtrac.cpp +++ b/Core/HLE/sceAtrac.cpp @@ -945,7 +945,7 @@ static int sceAtracLowLevelInitDecoder(int atracID, u32 paramsAddr) { } } if (!found) { - ERROR_LOG_REPORT(Log::ME, "AT3 header map lacks entry for bpf: %i channels: %i", atrac->GetTrack().BytesPerFrame(), atrac->GetTrack().channels); + WARN_LOG_REPORT_ONCE(at3headermap, Log::ME, "AT3 header map lacks entry for bpf: %i channels: %i", atrac->GetTrack().BytesPerFrame(), atrac->GetTrack().channels); // TODO: Should we return an error code for these values? } } diff --git a/ext/at3_standalone/atrac3.cpp b/ext/at3_standalone/atrac3.cpp index 6c1afcb166..fd143a9ad6 100644 --- a/ext/at3_standalone/atrac3.cpp +++ b/ext/at3_standalone/atrac3.cpp @@ -577,13 +577,15 @@ static int decode_channel_sound_unit(ATRAC3Context *q, GetBitContext *gb, GainBlock *gain2 = &snd->gain_block[1 - snd->gc_blk_switch]; if (coding_mode == JOINT_STEREO && channel_num == 1) { - if (get_bits(gb, 2) != 3) { - av_log(AV_LOG_ERROR,"JS mono Sound Unit id != 3."); + int bits = get_bits(gb, 2); + if (bits != 3) { + av_log(AV_LOG_ERROR,"Joint Stereo mono Sound Unit id %d != 3.", bits); return AVERROR_INVALIDDATA; } } else { - if (get_bits(gb, 6) != 0x28) { - av_log(AV_LOG_ERROR,"Sound Unit id != 0x28."); + int bits = get_bits(gb, 6); + if (bits != 0x28) { + av_log(AV_LOG_ERROR, "Sound Unit id %02x != 0x28.", bits); return AVERROR_INVALIDDATA; } }