CDROM: Add randomness to repeated seek times
I hate it, but it fixes lockups in Dino Crisis 2, and probably other games with dodgy code too. Also Simple 1500 Series Vol. 57 - The Meiro.
This commit is contained in:
parent
2f5c4d819e
commit
6f25cf31a7
|
@ -25,6 +25,7 @@
|
|||
#include "common/gsvector.h"
|
||||
#include "common/heap_array.h"
|
||||
#include "common/log.h"
|
||||
#include "common/xorshift_prng.h"
|
||||
|
||||
#include "fmt/format.h"
|
||||
#include "imgui.h"
|
||||
|
@ -52,6 +53,7 @@ enum : u32
|
|||
XA_RESAMPLE_RING_BUFFER_SIZE = 32,
|
||||
XA_RESAMPLE_ZIGZAG_TABLE_SIZE = 29,
|
||||
XA_RESAMPLE_NUM_ZIGZAG_TABLES = 7,
|
||||
PRNG_SEED = 0x4B435544u,
|
||||
|
||||
PARAM_FIFO_SIZE = 16,
|
||||
RESPONSE_FIFO_SIZE = 16,
|
||||
|
@ -460,6 +462,8 @@ struct CDROMState
|
|||
InlineFIFOQueue<u8, RESPONSE_FIFO_SIZE> response_fifo;
|
||||
InlineFIFOQueue<u8, RESPONSE_FIFO_SIZE> async_response_fifo;
|
||||
|
||||
XorShift128PlusPlus prng;
|
||||
|
||||
std::array<SectorBuffer, NUM_SECTOR_BUFFERS> sector_buffers;
|
||||
u32 current_read_sector_buffer = 0;
|
||||
u32 current_write_sector_buffer = 0;
|
||||
|
@ -608,6 +612,7 @@ void CDROM::Reset()
|
|||
s_state.param_fifo.Clear();
|
||||
s_state.response_fifo.Clear();
|
||||
s_state.async_response_fifo.Clear();
|
||||
s_state.prng.Reset(PRNG_SEED);
|
||||
|
||||
UpdateStatusRegister();
|
||||
|
||||
|
@ -758,6 +763,11 @@ bool CDROM::DoState(StateWrapper& sw)
|
|||
sw.Do(&s_state.response_fifo);
|
||||
sw.Do(&s_state.async_response_fifo);
|
||||
|
||||
if (sw.GetVersion() >= 79)
|
||||
sw.DoPOD(s_state.prng.GetMutableStatePtr());
|
||||
else
|
||||
s_state.prng.Reset(PRNG_SEED);
|
||||
|
||||
if (sw.GetVersion() < 65)
|
||||
{
|
||||
// Skip over the "copied out data", we don't care about it.
|
||||
|
@ -1637,6 +1647,12 @@ TickCount CDROM::GetTicksForSeek(CDImage::LBA new_lba, bool ignore_speed_change)
|
|||
seek_type = (new_lba > current_lba) ? "sled forward" : "sled backward";
|
||||
}
|
||||
|
||||
// I hate this so much. There's some games that are extremely timing sensitive in their disc code, and if we return
|
||||
// the same seek times repeatedly, end up locking up in an infinite loop. e.g. Resident Evil, Dino Crisis, etc.
|
||||
// Add some randomness to timing if we detect them repeatedly seeking, otherwise don't. This somewhat simulates how
|
||||
// the real hardware behaves, by adding an additional 0.5-1ms to every seek.
|
||||
ticks += s_state.prng.NextRange<u32>(System::MASTER_CLOCK / 2000, System::MASTER_CLOCK / 1000);
|
||||
|
||||
if (g_settings.cdrom_seek_speedup > 1)
|
||||
ticks = std::max<u32>(ticks / g_settings.cdrom_seek_speedup, MIN_SEEK_TICKS);
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "common/types.h"
|
||||
|
||||
static constexpr u32 SAVE_STATE_MAGIC = 0x43435544;
|
||||
static constexpr u32 SAVE_STATE_VERSION = 78;
|
||||
static constexpr u32 SAVE_STATE_VERSION = 79;
|
||||
static constexpr u32 SAVE_STATE_MINIMUM_VERSION = 42;
|
||||
|
||||
static_assert(SAVE_STATE_VERSION >= SAVE_STATE_MINIMUM_VERSION);
|
||||
|
|
Loading…
Reference in New Issue