sh4: limit penalty cycles to first 3 mem ops

Fixes choppy video in Dynamite Cop! and Resident Evil 2 intros.
Fixes desync between character and background in UFC championship intro.
Fixes Dino Crisis (JP) desync between video and subtitles.
Fixes South Park Rally boot freeze with one controller and 2 vmus.
Add cheats for Dave Mirra BMX to fix main loop timing.
Issue #1034
This commit is contained in:
Flyinghead 2023-10-16 14:39:15 +02:00
parent c58ae4daac
commit e894d4df5c
2 changed files with 56 additions and 9 deletions

View File

@ -481,6 +481,19 @@ void CheatManager::reset(const std::string& gameId)
else if (gameId == "MKG TKOB 2 KOR VER1.000-") // mushik2k
setMushikingCheats(0x706084);
}
else if (gameId == "T-8120N") // Dave Mirra BMX (US)
{
setActive(true);
cheats.emplace_back(Cheat::Type::setValue, "fix main loop time", true, 32, 0x0030b8cc, 0x42040000); // 33.0 ms
cheats.back().builtIn = true;
}
else if (gameId == "T8120D 50") // Dave Mirra BMX (EU)
{
setActive(true);
cheats.emplace_back(Cheat::Type::setValue, "fix main loop time", true, 32, 0x003011cc, 0x42200000); // 40.0 ms
cheats.back().builtIn = true;
}
}
if (config::WidescreenGameHacks)
{

View File

@ -53,15 +53,47 @@ public:
sh4_opcodelistentry *opcode = OpDesc[op];
int cycles = 0;
#ifndef STRICT_MODE
if (opcode->ex_type == 2 || opcode->ex_type == 3
|| opcode->ex_type == 5 || opcode->ex_type == 6 || opcode->ex_type == 7
// cache mgmt || opcode->ex_type == 10 || opcode->ex_type == 11
|| opcode->ex_type == 12
|| opcode->ex_type == 17 || opcode->ex_type == 18 || opcode->ex_type == 19
|| opcode->ex_type == 22 || opcode->ex_type == 23 || opcode->ex_type == 25
|| opcode->ex_type == 27 || opcode->ex_type == 29 || opcode->ex_type == 31
|| opcode->ex_type == 33 || opcode->ex_type == 35)
static const bool isMemOp[45] {
false,
false,
true, // all mem moves, ldtlb, sts.l FPUL/FPSCR, @-Rn, lds.l @Rn+,FPUL
true, // gbr-based load/store
false,
true, // tst.b #<imm8>, @(R0,GBR)
true, // and/or/xor.b #<imm8>, @(R0,GBR)
true, // tas.b @Rn
false,
false,
false,
false,
true, // movca.l R0, @Rn
false,
false,
false,
false,
true, // ldc.l @Rn+, VBR/SPC/SSR/Rn_Bank/DBR
true, // ldc.l @Rn+, GBR/SGR
true, // ldc.l @Rn+, SR
false,
false,
true, // stc.l DBR/SR/GBR/VBR/SSR/SPC/Rn_Bank, @-Rn
true, // stc.l SGR, @-Rn
false,
true, // lds.l @Rn+, PR
false,
true, // sts.l PR, @-Rn
false,
true, // lds.l @Rn+, MACH/MACL
false,
true, // sts.l MACH/MACL, @-Rn
false,
true, // lds.l @Rn+,FPSCR
false,
true, // mac.wl @Rm+,@Rn+
};
if (isMemOp[opcode->ex_type])
{
if (++memOps < 4)
cycles = mmu_enabled() ? 5 : 2;
}
// TODO only for mem read?
@ -86,6 +118,7 @@ public:
void reset()
{
lastUnit = CO;
memOps = 0;
}
static u64 now() {
@ -108,6 +141,7 @@ private:
sh4_eu lastUnit = CO;
const int cpuRatio;
int memOps = 0;
};
extern Sh4Cycles sh4cycles;