Skip to content

Commit

Permalink
Merge pull request #19801 from hrydgard/cheat-engine-perf-fixes
Browse files Browse the repository at this point in the history
CwCheat engine perf fixes
  • Loading branch information
hrydgard authored Jan 3, 2025
2 parents 1481dee + 083543c commit 82fa82b
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 59 deletions.
102 changes: 51 additions & 51 deletions Core/CwCheat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -810,47 +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)) {
InvalidateICache(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)) {
InvalidateICache(op.addr, op.sz);
InvalidateICache(op.addr, op.ifAddrTypes.compareAddr);

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);
Expand All @@ -871,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;

Expand Down Expand Up @@ -918,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;
Expand All @@ -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");
Expand All @@ -952,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;
Expand Down Expand Up @@ -1009,8 +1003,7 @@ 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) {
if (Memory::ReadUnchecked_U32(op.addr) != op.val) {
i = cheat.lines.size();
}
}
Expand Down Expand Up @@ -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;
Expand All @@ -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.
Expand All @@ -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:
Expand All @@ -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;

Expand All @@ -1161,28 +1149,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;
Expand All @@ -1200,7 +1200,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);
Expand Down
7 changes: 4 additions & 3 deletions Core/CwCheat.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ enum class CheatCodeFormat {

struct CheatCode {
CheatCodeFormat fmt;
std::string name;
std::vector<CheatLine> lines;
};

Expand Down Expand Up @@ -61,9 +62,9 @@ class CWCheatEngine {
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<CheatCode> cheats_;
std::string gameID_;
Expand Down
2 changes: 1 addition & 1 deletion Core/HLE/sceAtrac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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?
}
}
Expand Down
10 changes: 6 additions & 4 deletions ext/at3_standalone/atrac3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down

0 comments on commit 82fa82b

Please sign in to comment.