From 7733b84bc134e3aeeeb47a89521dd00e8b122754 Mon Sep 17 00:00:00 2001 From: skidau Date: Mon, 11 Oct 2010 12:38:17 +0000 Subject: [PATCH] Added a game option to emulate the disc transfer rate. This is needed for some games like Mario Golf and Fire Emblem: Path of Radiance. Fixes issue 1992. Fixes issue 2519. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6268 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/ConfigManager.cpp | 1 + Source/Core/Core/Src/CoreParameter.cpp | 2 ++ Source/Core/Core/Src/CoreParameter.h | 1 + Source/Core/Core/Src/HW/DVDInterface.cpp | 31 +++++++++++++++++++-- Source/Core/Core/Src/LuaInterface.cpp | 1 + Source/Core/DolphinWX/Src/BootManager.cpp | 1 + Source/Core/DolphinWX/Src/ISOProperties.cpp | 13 +++++++++ Source/Core/DolphinWX/Src/ISOProperties.h | 3 +- 8 files changed, 49 insertions(+), 4 deletions(-) diff --git a/Source/Core/Core/Src/ConfigManager.cpp b/Source/Core/Core/Src/ConfigManager.cpp index ada79dfa67..b8982b822d 100644 --- a/Source/Core/Core/Src/ConfigManager.cpp +++ b/Source/Core/Core/Src/ConfigManager.cpp @@ -294,6 +294,7 @@ void SConfig::LoadSettings() ini.Get("Core", "MMU", &m_LocalCoreStartupParameter.bMMU, false); ini.Get("Core", "TLBHack", &m_LocalCoreStartupParameter.iTLBHack, 0); ini.Get("Core", "AlternateRFI", &m_LocalCoreStartupParameter.bAlternateRFI, false); + ini.Get("Core", "EmulateDiscSpeed", &m_LocalCoreStartupParameter.bEmulateDiscSpeed, false); ini.Get("Core", "BAT", &m_LocalCoreStartupParameter.bMMUBAT, false); ini.Get("Core", "FrameLimit", &m_Framelimit, 1); // auto frame limit by default ini.Get("Core", "UseFPS", &b_UseFPS, false); // use vps as default diff --git a/Source/Core/Core/Src/CoreParameter.cpp b/Source/Core/Core/Src/CoreParameter.cpp index b3377523f5..6ee991eb71 100644 --- a/Source/Core/Core/Src/CoreParameter.cpp +++ b/Source/Core/Core/Src/CoreParameter.cpp @@ -49,6 +49,7 @@ SCoreStartupParameter::SCoreStartupParameter() bMergeBlocks(false), bRunCompareServer(false), bRunCompareClient(false), bMMU(false), bMMUBAT(false), iTLBHack(0), bAlternateRFI(false), + bEmulateDiscSpeed(false), SelectedLanguage(0), bWii(false), bConfirmStop(false), bHideCursor(false), bAutoHideCursor(false), bUsePanicHandlers(true), @@ -75,6 +76,7 @@ void SCoreStartupParameter::LoadDefaults() bMMUBAT = false; iTLBHack = 0; bAlternateRFI = false; + bEmulateDiscSpeed = false; bMergeBlocks = false; SelectedLanguage = 0; bWii = false; diff --git a/Source/Core/Core/Src/CoreParameter.h b/Source/Core/Core/Src/CoreParameter.h index 04879eb552..44e78a31af 100644 --- a/Source/Core/Core/Src/CoreParameter.h +++ b/Source/Core/Core/Src/CoreParameter.h @@ -83,6 +83,7 @@ struct SCoreStartupParameter bool bMMUBAT; int iTLBHack; bool bAlternateRFI; + bool bEmulateDiscSpeed; int SelectedLanguage; diff --git a/Source/Core/Core/Src/HW/DVDInterface.cpp b/Source/Core/Core/Src/HW/DVDInterface.cpp index e64645051e..d11fd8c3af 100644 --- a/Source/Core/Core/Src/HW/DVDInterface.cpp +++ b/Source/Core/Core/Src/HW/DVDInterface.cpp @@ -19,6 +19,7 @@ #include "ChunkFile.h" #include "../ConfigManager.h" #include "../CoreTiming.h" +#include "../HW/SystemTimers.h" #include "StreamADPCM.h" // Core #include "DVDInterface.h" @@ -28,6 +29,9 @@ #include "Memmap.h" #include "../VolumeHandler.h" +// Disc transfer rate measured in bytes per second +#define DISC_TRANSFER_RATE (3125 * 1024) + namespace DVDInterface { @@ -151,7 +155,7 @@ union UDICR { u32 TSTART : 1; // w:1 start r:0 ready u32 DMA : 1; // 1: DMA Mode 0: Immediate Mode (can only do Access Register Command) - u32 RW : 1; // 0: Read Command (DVD to Memory) 1: Write COmmand (Memory to DVD) + u32 RW : 1; // 0: Read Command (DVD to Memory) 1: Write Command (Memory to DVD) u32 : 29; }; }; @@ -200,6 +204,7 @@ static u32 AudioLength; u32 g_ErrorCode = 0; bool g_bDiscInside = false; bool g_bStream = false; +int tc = 0; // GC-AM only static unsigned char media_buffer[0x40]; @@ -209,8 +214,10 @@ static unsigned char media_buffer[0x40]; Common::CriticalSection dvdread_section; static int ejectDisc; -void EjectDiscCallback(u64 userdata, int cyclesLate); static int insertDisc; +static int executeDVD; + +void EjectDiscCallback(u64 userdata, int cyclesLate); void InsertDiscCallback(u64 userdata, int cyclesLate); void UpdateInterrupts(); @@ -237,6 +244,12 @@ void DoState(PointerWrap &p) p.Do(g_bDiscInside); } +void TransferComplete(u64 userdata, int cyclesLate) +{ + if (m_DICR.TSTART) + ExecuteCommand(m_DICR); +} + void Init() { m_DISR.Hex = 0; @@ -257,6 +270,8 @@ void Init() ejectDisc = CoreTiming::RegisterEvent("EjectDisc", EjectDiscCallback); insertDisc = CoreTiming::RegisterEvent("InsertDisc", InsertDiscCallback); + + tc = CoreTiming::RegisterEvent("TransferComplete", TransferComplete); } void Shutdown() @@ -445,7 +460,17 @@ void Write32(const u32 _iValue, const u32 _iAddress) { m_DICR.Hex = _iValue & 7; if (m_DICR.TSTART) - ExecuteCommand(m_DICR); + { + if (SConfig::GetInstance().m_LocalCoreStartupParameter.bEmulateDiscSpeed) + { + u64 ticksUntilTC = m_DILENGTH.Length * (SystemTimers::GetTicksPerSecond() / DISC_TRANSFER_RATE); + CoreTiming::ScheduleEvent(ticksUntilTC, tc); + } + else + { + ExecuteCommand(m_DICR); + } + } } break; diff --git a/Source/Core/Core/Src/LuaInterface.cpp b/Source/Core/Core/Src/LuaInterface.cpp index 502260a89f..74d91d59d8 100644 --- a/Source/Core/Core/Src/LuaInterface.cpp +++ b/Source/Core/Core/Src/LuaInterface.cpp @@ -2801,6 +2801,7 @@ DEFINE_LUA_FUNCTION(emulua_loadrom, "filename") game_ini.Get("Core", "BAT", &StartUp.bMMUBAT, StartUp.bMMUBAT); game_ini.Get("Core", "TLBHack", &StartUp.iTLBHack, StartUp.iTLBHack); game_ini.Get("Core", "AlternateRFI", &StartUp.bAlternateRFI, StartUp.bAlternateRFI); + game_ini.Get("Core", "EmulateDiscSpeed", &StartUp.bEmulateDiscSpeed, StartUp.bEmulateDiscSpeed); // Wii settings if (StartUp.bWii) { diff --git a/Source/Core/DolphinWX/Src/BootManager.cpp b/Source/Core/DolphinWX/Src/BootManager.cpp index 5797939dac..d339b23de0 100644 --- a/Source/Core/DolphinWX/Src/BootManager.cpp +++ b/Source/Core/DolphinWX/Src/BootManager.cpp @@ -110,6 +110,7 @@ bool BootCore(const std::string& _rFilename) game_ini.Get("Core", "BAT", &StartUp.bMMUBAT, StartUp.bMMUBAT); game_ini.Get("Core", "TLBHack", &StartUp.iTLBHack, StartUp.iTLBHack); game_ini.Get("Core", "AlternateRFI", &StartUp.bAlternateRFI, StartUp.bAlternateRFI); + game_ini.Get("Core", "EmulateDiscSpeed", &StartUp.bEmulateDiscSpeed, StartUp.bEmulateDiscSpeed); game_ini.Get("Core", "BlockMerging", &StartUp.bMergeBlocks, StartUp.bMergeBlocks); // Wii settings if (StartUp.bWii) diff --git a/Source/Core/DolphinWX/Src/ISOProperties.cpp b/Source/Core/DolphinWX/Src/ISOProperties.cpp index 898f621fca..51dd3599e9 100644 --- a/Source/Core/DolphinWX/Src/ISOProperties.cpp +++ b/Source/Core/DolphinWX/Src/ISOProperties.cpp @@ -301,6 +301,8 @@ void CISOProperties::CreateGUIControls(bool IsWad) TLBHack->SetToolTip(wxT("Fast version of the MMU. Does not work for every game.")); AlternateRFI = new wxCheckBox(m_GameConfig, ID_RFI, _("Alternate RFI"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator); AlternateRFI->SetToolTip(wxT("If a game hangs, works only in the Interpreter or Dolphin crashes, this option may fix the game.")); + EmulateDiscSpeed = new wxCheckBox(m_GameConfig, ID_DISCSPEED, _("Emulate Disc Transfer Rate"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator); + EmulateDiscSpeed->SetToolTip(wxT("Emulate the speed of the disc drive. Needed for some games. (ON = Compatible, OFF = Fast)")); BlockMerging = new wxCheckBox(m_GameConfig, ID_MERGEBLOCKS, _("Enable Block Merging"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator); // Wii Console @@ -365,6 +367,7 @@ void CISOProperties::CreateGUIControls(bool IsWad) sbCoreOverrides->Add(MMUBAT, 0, wxEXPAND|wxLEFT, 5); sbCoreOverrides->Add(TLBHack, 0, wxEXPAND|wxLEFT, 5); sbCoreOverrides->Add(AlternateRFI, 0, wxEXPAND|wxLEFT, 5); + sbCoreOverrides->Add(EmulateDiscSpeed, 0, wxEXPAND|wxLEFT, 5); sbCoreOverrides->Add(BlockMerging, 0, wxEXPAND|wxLEFT, 5); sbWiiOverrides->Add(EnableProgressiveScan, 0, wxEXPAND|wxLEFT, 5); sbWiiOverrides->Add(EnableWideScreen, 0, wxEXPAND|wxLEFT, 5); @@ -850,6 +853,11 @@ void CISOProperties::LoadGameConfig() else AlternateRFI->Set3StateValue(wxCHK_UNDETERMINED); + if (GameIni.Get("Core", "EmulateDiscSpeed", &bTemp)) + EmulateDiscSpeed->Set3StateValue((wxCheckBoxState)bTemp); + else + EmulateDiscSpeed->Set3StateValue(wxCHK_UNDETERMINED); + if (GameIni.Get("Core", "BlockMerging", &bTemp)) BlockMerging->Set3StateValue((wxCheckBoxState)bTemp); else @@ -961,6 +969,11 @@ bool CISOProperties::SaveGameConfig() else GameIni.Set("Core", "AlternateRFI", AlternateRFI->Get3StateValue()); + if (EmulateDiscSpeed->Get3StateValue() == wxCHK_UNDETERMINED) + GameIni.DeleteKey("Core", "EmulateDiscSpeed"); + else + GameIni.Set("Core", "EmulateDiscSpeed", EmulateDiscSpeed->Get3StateValue()); + if (BlockMerging->Get3StateValue() == wxCHK_UNDETERMINED) GameIni.DeleteKey("Core", "BlockMerging"); else diff --git a/Source/Core/DolphinWX/Src/ISOProperties.h b/Source/Core/DolphinWX/Src/ISOProperties.h index e3f040a542..e6d9bddd38 100644 --- a/Source/Core/DolphinWX/Src/ISOProperties.h +++ b/Source/Core/DolphinWX/Src/ISOProperties.h @@ -85,7 +85,7 @@ class CISOProperties : public wxDialog wxStaticText *OverrideText; // Core wxCheckBox *CPUThread, *SkipIdle, *MMU, *MMUBAT, *TLBHack; - wxCheckBox *AlternateRFI, *BlockMerging; + wxCheckBox *AlternateRFI, *EmulateDiscSpeed, *BlockMerging; // Wii wxCheckBox *EnableProgressiveScan, *EnableWideScreen; // Video @@ -170,6 +170,7 @@ class CISOProperties : public wxDialog ID_MMUBAT, ID_TLBHACK, ID_RFI, + ID_DISCSPEED, ID_MERGEBLOCKS, ID_FORCEFILTERING, ID_EFBCOPYDISABLE,