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 int enque_reply;
|
||||||
|
|
||||||
|
static u64 last_reply_time;
|
||||||
|
|
||||||
void EnqueReplyCallback(u64 userdata, int)
|
void EnqueReplyCallback(u64 userdata, int)
|
||||||
{
|
{
|
||||||
reply_queue.push_back(userdata);
|
reply_queue.push_back(userdata);
|
||||||
|
@ -163,6 +165,7 @@ void Reset(bool _bHard)
|
||||||
}
|
}
|
||||||
request_queue.clear();
|
request_queue.clear();
|
||||||
reply_queue.clear();
|
reply_queue.clear();
|
||||||
|
last_reply_time = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shutdown()
|
void Shutdown()
|
||||||
|
@ -246,6 +249,7 @@ void DoState(PointerWrap &p)
|
||||||
{
|
{
|
||||||
p.Do(request_queue);
|
p.Do(request_queue);
|
||||||
p.Do(reply_queue);
|
p.Do(reply_queue);
|
||||||
|
p.Do(last_reply_time);
|
||||||
|
|
||||||
TDeviceMap::const_iterator itr;
|
TDeviceMap::const_iterator itr;
|
||||||
|
|
||||||
|
@ -518,8 +522,18 @@ void ExecuteCommand(u32 _Address)
|
||||||
|
|
||||||
if (CmdSuccess)
|
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
|
// Generate a reply to the IPC command
|
||||||
int const reply_delay = pDevice ? pDevice->GetCmdDelay(_Address) : 0;
|
|
||||||
EnqReply(_Address, reply_delay);
|
EnqReply(_Address, reply_delay);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -462,8 +462,43 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
|
||||||
return 1;
|
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".
|
u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10);
|
||||||
return SystemTimers::GetTicksPerSecond() / 100;
|
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;
|
static std::thread g_save_thread;
|
||||||
|
|
||||||
// Don't forget to increase this after doing changes on the savestate system
|
// 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
|
struct StateHeader
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue