Use different reply delays for various DI commands.
Fixes issue 5983.
This commit is contained in:
parent
95d08db46f
commit
a11827cdf0
|
@ -84,6 +84,8 @@ static ipc_msg_queue reply_queue; // arm -> ppc
|
|||
|
||||
static int enque_reply;
|
||||
|
||||
static u64 last_reply_time;
|
||||
|
||||
void EnqueReplyCallback(u64 userdata, int)
|
||||
{
|
||||
reply_queue.push_back(userdata);
|
||||
|
@ -163,6 +165,7 @@ void Reset(bool _bHard)
|
|||
}
|
||||
request_queue.clear();
|
||||
reply_queue.clear();
|
||||
last_reply_time = 0;
|
||||
}
|
||||
|
||||
void Shutdown()
|
||||
|
@ -246,6 +249,7 @@ void DoState(PointerWrap &p)
|
|||
{
|
||||
p.Do(request_queue);
|
||||
p.Do(reply_queue);
|
||||
p.Do(last_reply_time);
|
||||
|
||||
TDeviceMap::const_iterator itr;
|
||||
|
||||
|
@ -518,8 +522,18 @@ void ExecuteCommand(u32 _Address)
|
|||
|
||||
if (CmdSuccess)
|
||||
{
|
||||
// Ensure replies happen in order, fairly ugly
|
||||
// Without this, tons of games fail now that DI commads have different reply delays
|
||||
int reply_delay = pDevice ? pDevice->GetCmdDelay(_Address) : 0;
|
||||
|
||||
const s64 ticks_til_last_reply = last_reply_time - CoreTiming::GetTicks();
|
||||
|
||||
if (ticks_til_last_reply > 0)
|
||||
reply_delay = ticks_til_last_reply;
|
||||
|
||||
last_reply_time = CoreTiming::GetTicks() + reply_delay;
|
||||
|
||||
// Generate a reply to the IPC command
|
||||
int const reply_delay = pDevice ? pDevice->GetCmdDelay(_Address) : 0;
|
||||
EnqReply(_Address, reply_delay);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -462,8 +462,43 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
|
|||
return 1;
|
||||
}
|
||||
|
||||
int CWII_IPC_HLE_Device_di::GetCmdDelay(u32)
|
||||
int CWII_IPC_HLE_Device_di::GetCmdDelay(u32 _CommandAddress)
|
||||
{
|
||||
// Less than ~1/150th of a second hangs Oregon Trail at "loading wheel".
|
||||
return SystemTimers::GetTicksPerSecond() / 100;
|
||||
}
|
||||
u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10);
|
||||
u32 Command = Memory::Read_U32(BufferIn) >> 24;
|
||||
|
||||
// Hacks below
|
||||
|
||||
switch (Command)
|
||||
{
|
||||
case DVDLowRead:
|
||||
case DVDLowUnencryptedRead:
|
||||
{
|
||||
u32 const Size = Memory::Read_U32(BufferIn + 0x04);
|
||||
// Delay depends on size of read, that makes sense, right?
|
||||
// More than ~1150K "bytes / sec" hangs NSMBWii on boot.
|
||||
// Less than ~800K "bytes / sec" hangs DKCR randomly.
|
||||
return SystemTimers::GetTicksPerSecond() / 975000 * Size;
|
||||
break;
|
||||
}
|
||||
|
||||
case DVDLowClearCoverInterrupt:
|
||||
// Less than ~1/155th of a second hangs Oregon Trail at "loading wheel".
|
||||
// More than ~1/140th of a second hangs Resident Evil Archives: Resident Evil Zero.
|
||||
return SystemTimers::GetTicksPerSecond() / 146;
|
||||
break;
|
||||
|
||||
// case DVDLowAudioBufferConfig:
|
||||
// case DVDLowInquiry:
|
||||
// case DVDLowReadDiskID:
|
||||
// case DVDLowWaitForCoverClose:
|
||||
// case DVDLowGetCoverReg:
|
||||
// case DVDLowGetCoverStatus:
|
||||
// case DVDLowReset:
|
||||
// case DVDLowClosePartition:
|
||||
default:
|
||||
// ranom numbers here!
|
||||
return SystemTimers::GetTicksPerSecond() / 1500;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ static Common::Event g_compressAndDumpStateSyncEvent;
|
|||
static std::thread g_save_thread;
|
||||
|
||||
// Don't forget to increase this after doing changes on the savestate system
|
||||
static const u32 STATE_VERSION = 11;
|
||||
static const u32 STATE_VERSION = 12;
|
||||
|
||||
struct StateHeader
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue