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
This commit is contained in:
skidau 2010-10-11 12:38:17 +00:00
parent 7797b9d753
commit 7733b84bc1
8 changed files with 49 additions and 4 deletions

View File

@ -294,6 +294,7 @@ void SConfig::LoadSettings()
ini.Get("Core", "MMU", &m_LocalCoreStartupParameter.bMMU, false); ini.Get("Core", "MMU", &m_LocalCoreStartupParameter.bMMU, false);
ini.Get("Core", "TLBHack", &m_LocalCoreStartupParameter.iTLBHack, 0); ini.Get("Core", "TLBHack", &m_LocalCoreStartupParameter.iTLBHack, 0);
ini.Get("Core", "AlternateRFI", &m_LocalCoreStartupParameter.bAlternateRFI, false); 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", "BAT", &m_LocalCoreStartupParameter.bMMUBAT, false);
ini.Get("Core", "FrameLimit", &m_Framelimit, 1); // auto frame limit by default ini.Get("Core", "FrameLimit", &m_Framelimit, 1); // auto frame limit by default
ini.Get("Core", "UseFPS", &b_UseFPS, false); // use vps as default ini.Get("Core", "UseFPS", &b_UseFPS, false); // use vps as default

View File

@ -49,6 +49,7 @@ SCoreStartupParameter::SCoreStartupParameter()
bMergeBlocks(false), bMergeBlocks(false),
bRunCompareServer(false), bRunCompareClient(false), bRunCompareServer(false), bRunCompareClient(false),
bMMU(false), bMMUBAT(false), iTLBHack(0), bAlternateRFI(false), bMMU(false), bMMUBAT(false), iTLBHack(0), bAlternateRFI(false),
bEmulateDiscSpeed(false),
SelectedLanguage(0), bWii(false), SelectedLanguage(0), bWii(false),
bConfirmStop(false), bHideCursor(false), bConfirmStop(false), bHideCursor(false),
bAutoHideCursor(false), bUsePanicHandlers(true), bAutoHideCursor(false), bUsePanicHandlers(true),
@ -75,6 +76,7 @@ void SCoreStartupParameter::LoadDefaults()
bMMUBAT = false; bMMUBAT = false;
iTLBHack = 0; iTLBHack = 0;
bAlternateRFI = false; bAlternateRFI = false;
bEmulateDiscSpeed = false;
bMergeBlocks = false; bMergeBlocks = false;
SelectedLanguage = 0; SelectedLanguage = 0;
bWii = false; bWii = false;

View File

@ -83,6 +83,7 @@ struct SCoreStartupParameter
bool bMMUBAT; bool bMMUBAT;
int iTLBHack; int iTLBHack;
bool bAlternateRFI; bool bAlternateRFI;
bool bEmulateDiscSpeed;
int SelectedLanguage; int SelectedLanguage;

View File

@ -19,6 +19,7 @@
#include "ChunkFile.h" #include "ChunkFile.h"
#include "../ConfigManager.h" #include "../ConfigManager.h"
#include "../CoreTiming.h" #include "../CoreTiming.h"
#include "../HW/SystemTimers.h"
#include "StreamADPCM.h" // Core #include "StreamADPCM.h" // Core
#include "DVDInterface.h" #include "DVDInterface.h"
@ -28,6 +29,9 @@
#include "Memmap.h" #include "Memmap.h"
#include "../VolumeHandler.h" #include "../VolumeHandler.h"
// Disc transfer rate measured in bytes per second
#define DISC_TRANSFER_RATE (3125 * 1024)
namespace DVDInterface namespace DVDInterface
{ {
@ -151,7 +155,7 @@ union UDICR
{ {
u32 TSTART : 1; // w:1 start r:0 ready 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 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; u32 : 29;
}; };
}; };
@ -200,6 +204,7 @@ static u32 AudioLength;
u32 g_ErrorCode = 0; u32 g_ErrorCode = 0;
bool g_bDiscInside = false; bool g_bDiscInside = false;
bool g_bStream = false; bool g_bStream = false;
int tc = 0;
// GC-AM only // GC-AM only
static unsigned char media_buffer[0x40]; static unsigned char media_buffer[0x40];
@ -209,8 +214,10 @@ static unsigned char media_buffer[0x40];
Common::CriticalSection dvdread_section; Common::CriticalSection dvdread_section;
static int ejectDisc; static int ejectDisc;
void EjectDiscCallback(u64 userdata, int cyclesLate);
static int insertDisc; static int insertDisc;
static int executeDVD;
void EjectDiscCallback(u64 userdata, int cyclesLate);
void InsertDiscCallback(u64 userdata, int cyclesLate); void InsertDiscCallback(u64 userdata, int cyclesLate);
void UpdateInterrupts(); void UpdateInterrupts();
@ -237,6 +244,12 @@ void DoState(PointerWrap &p)
p.Do(g_bDiscInside); p.Do(g_bDiscInside);
} }
void TransferComplete(u64 userdata, int cyclesLate)
{
if (m_DICR.TSTART)
ExecuteCommand(m_DICR);
}
void Init() void Init()
{ {
m_DISR.Hex = 0; m_DISR.Hex = 0;
@ -257,6 +270,8 @@ void Init()
ejectDisc = CoreTiming::RegisterEvent("EjectDisc", EjectDiscCallback); ejectDisc = CoreTiming::RegisterEvent("EjectDisc", EjectDiscCallback);
insertDisc = CoreTiming::RegisterEvent("InsertDisc", InsertDiscCallback); insertDisc = CoreTiming::RegisterEvent("InsertDisc", InsertDiscCallback);
tc = CoreTiming::RegisterEvent("TransferComplete", TransferComplete);
} }
void Shutdown() void Shutdown()
@ -445,7 +460,17 @@ void Write32(const u32 _iValue, const u32 _iAddress)
{ {
m_DICR.Hex = _iValue & 7; m_DICR.Hex = _iValue & 7;
if (m_DICR.TSTART) 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; break;

View File

@ -2801,6 +2801,7 @@ DEFINE_LUA_FUNCTION(emulua_loadrom, "filename")
game_ini.Get("Core", "BAT", &StartUp.bMMUBAT, StartUp.bMMUBAT); game_ini.Get("Core", "BAT", &StartUp.bMMUBAT, StartUp.bMMUBAT);
game_ini.Get("Core", "TLBHack", &StartUp.iTLBHack, StartUp.iTLBHack); game_ini.Get("Core", "TLBHack", &StartUp.iTLBHack, StartUp.iTLBHack);
game_ini.Get("Core", "AlternateRFI", &StartUp.bAlternateRFI, StartUp.bAlternateRFI); game_ini.Get("Core", "AlternateRFI", &StartUp.bAlternateRFI, StartUp.bAlternateRFI);
game_ini.Get("Core", "EmulateDiscSpeed", &StartUp.bEmulateDiscSpeed, StartUp.bEmulateDiscSpeed);
// Wii settings // Wii settings
if (StartUp.bWii) if (StartUp.bWii)
{ {

View File

@ -110,6 +110,7 @@ bool BootCore(const std::string& _rFilename)
game_ini.Get("Core", "BAT", &StartUp.bMMUBAT, StartUp.bMMUBAT); game_ini.Get("Core", "BAT", &StartUp.bMMUBAT, StartUp.bMMUBAT);
game_ini.Get("Core", "TLBHack", &StartUp.iTLBHack, StartUp.iTLBHack); game_ini.Get("Core", "TLBHack", &StartUp.iTLBHack, StartUp.iTLBHack);
game_ini.Get("Core", "AlternateRFI", &StartUp.bAlternateRFI, StartUp.bAlternateRFI); 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); game_ini.Get("Core", "BlockMerging", &StartUp.bMergeBlocks, StartUp.bMergeBlocks);
// Wii settings // Wii settings
if (StartUp.bWii) if (StartUp.bWii)

View File

@ -301,6 +301,8 @@ void CISOProperties::CreateGUIControls(bool IsWad)
TLBHack->SetToolTip(wxT("Fast version of the MMU. Does not work for every game.")); 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 = 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.")); 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); BlockMerging = new wxCheckBox(m_GameConfig, ID_MERGEBLOCKS, _("Enable Block Merging"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
// Wii Console // Wii Console
@ -365,6 +367,7 @@ void CISOProperties::CreateGUIControls(bool IsWad)
sbCoreOverrides->Add(MMUBAT, 0, wxEXPAND|wxLEFT, 5); sbCoreOverrides->Add(MMUBAT, 0, wxEXPAND|wxLEFT, 5);
sbCoreOverrides->Add(TLBHack, 0, wxEXPAND|wxLEFT, 5); sbCoreOverrides->Add(TLBHack, 0, wxEXPAND|wxLEFT, 5);
sbCoreOverrides->Add(AlternateRFI, 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); sbCoreOverrides->Add(BlockMerging, 0, wxEXPAND|wxLEFT, 5);
sbWiiOverrides->Add(EnableProgressiveScan, 0, wxEXPAND|wxLEFT, 5); sbWiiOverrides->Add(EnableProgressiveScan, 0, wxEXPAND|wxLEFT, 5);
sbWiiOverrides->Add(EnableWideScreen, 0, wxEXPAND|wxLEFT, 5); sbWiiOverrides->Add(EnableWideScreen, 0, wxEXPAND|wxLEFT, 5);
@ -850,6 +853,11 @@ void CISOProperties::LoadGameConfig()
else else
AlternateRFI->Set3StateValue(wxCHK_UNDETERMINED); 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)) if (GameIni.Get("Core", "BlockMerging", &bTemp))
BlockMerging->Set3StateValue((wxCheckBoxState)bTemp); BlockMerging->Set3StateValue((wxCheckBoxState)bTemp);
else else
@ -961,6 +969,11 @@ bool CISOProperties::SaveGameConfig()
else else
GameIni.Set("Core", "AlternateRFI", AlternateRFI->Get3StateValue()); 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) if (BlockMerging->Get3StateValue() == wxCHK_UNDETERMINED)
GameIni.DeleteKey("Core", "BlockMerging"); GameIni.DeleteKey("Core", "BlockMerging");
else else

View File

@ -85,7 +85,7 @@ class CISOProperties : public wxDialog
wxStaticText *OverrideText; wxStaticText *OverrideText;
// Core // Core
wxCheckBox *CPUThread, *SkipIdle, *MMU, *MMUBAT, *TLBHack; wxCheckBox *CPUThread, *SkipIdle, *MMU, *MMUBAT, *TLBHack;
wxCheckBox *AlternateRFI, *BlockMerging; wxCheckBox *AlternateRFI, *EmulateDiscSpeed, *BlockMerging;
// Wii // Wii
wxCheckBox *EnableProgressiveScan, *EnableWideScreen; wxCheckBox *EnableProgressiveScan, *EnableWideScreen;
// Video // Video
@ -170,6 +170,7 @@ class CISOProperties : public wxDialog
ID_MMUBAT, ID_MMUBAT,
ID_TLBHACK, ID_TLBHACK,
ID_RFI, ID_RFI,
ID_DISCSPEED,
ID_MERGEBLOCKS, ID_MERGEBLOCKS,
ID_FORCEFILTERING, ID_FORCEFILTERING,
ID_EFBCOPYDISABLE, ID_EFBCOPYDISABLE,