mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-04-10 21:44:28 +00:00
DSP: New non-threaded mode for the LLE plugin, with some idle skipping enabled. Use Dolphin Main config to set it. Some minor optimization and some spelling fixes.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2937 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
5dbdc4e6cf
commit
8c3bb3796b
@ -63,7 +63,7 @@ void SConfig::SaveSettings()
|
|||||||
ini.Set("General", tmp, m_ISOFolder[i]);
|
ini.Set("General", tmp, m_ISOFolder[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ini.Set("General", "RecersiveGCMPaths", m_RecersiveISOFolder);
|
ini.Set("General", "RecersiveGCMPaths", m_RecursiveISOFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -87,6 +87,7 @@ void SConfig::SaveSettings()
|
|||||||
ini.Set("Core", "HLEBios", m_LocalCoreStartupParameter.bHLEBios);
|
ini.Set("Core", "HLEBios", m_LocalCoreStartupParameter.bHLEBios);
|
||||||
ini.Set("Core", "UseDynarec", m_LocalCoreStartupParameter.bUseJIT);
|
ini.Set("Core", "UseDynarec", m_LocalCoreStartupParameter.bUseJIT);
|
||||||
ini.Set("Core", "UseDualCore", m_LocalCoreStartupParameter.bUseDualCore);
|
ini.Set("Core", "UseDualCore", m_LocalCoreStartupParameter.bUseDualCore);
|
||||||
|
ini.Set("Core", "DSPThread", m_LocalCoreStartupParameter.bDSPThread);
|
||||||
ini.Set("Core", "SkipIdle", m_LocalCoreStartupParameter.bSkipIdle);
|
ini.Set("Core", "SkipIdle", m_LocalCoreStartupParameter.bSkipIdle);
|
||||||
ini.Set("Core", "LockThreads", m_LocalCoreStartupParameter.bLockThreads);
|
ini.Set("Core", "LockThreads", m_LocalCoreStartupParameter.bLockThreads);
|
||||||
ini.Set("Core", "DefaultGCM", m_LocalCoreStartupParameter.m_strDefaultGCM);
|
ini.Set("Core", "DefaultGCM", m_LocalCoreStartupParameter.m_strDefaultGCM);
|
||||||
@ -168,7 +169,7 @@ void SConfig::LoadSettings()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ini.Get("General", "RecersiveGCMPaths", &m_RecersiveISOFolder, false);
|
ini.Get("General", "RecersiveGCMPaths", &m_RecursiveISOFolder, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -188,11 +189,12 @@ void SConfig::LoadSettings()
|
|||||||
ini.Get("Interface", "ShowConsole", &m_InterfaceConsole, false);
|
ini.Get("Interface", "ShowConsole", &m_InterfaceConsole, false);
|
||||||
|
|
||||||
// Core
|
// Core
|
||||||
ini.Get("Core", "HLEBios", &m_LocalCoreStartupParameter.bHLEBios, true);
|
ini.Get("Core", "HLEBios", &m_LocalCoreStartupParameter.bHLEBios, true);
|
||||||
ini.Get("Core", "UseDynarec", &m_LocalCoreStartupParameter.bUseJIT, true);
|
ini.Get("Core", "UseDynarec", &m_LocalCoreStartupParameter.bUseJIT, true);
|
||||||
ini.Get("Core", "UseDualCore", &m_LocalCoreStartupParameter.bUseDualCore, false);
|
ini.Get("Core", "DSPThread", &m_LocalCoreStartupParameter.bDSPThread, true);
|
||||||
ini.Get("Core", "SkipIdle", &m_LocalCoreStartupParameter.bSkipIdle, true);
|
ini.Get("Core", "UseDualCore", &m_LocalCoreStartupParameter.bUseDualCore, false);
|
||||||
ini.Get("Core", "LockThreads", &m_LocalCoreStartupParameter.bLockThreads, true);
|
ini.Get("Core", "SkipIdle", &m_LocalCoreStartupParameter.bSkipIdle, true);
|
||||||
|
ini.Get("Core", "LockThreads", &m_LocalCoreStartupParameter.bLockThreads, true);
|
||||||
ini.Get("Core", "DefaultGCM", &m_LocalCoreStartupParameter.m_strDefaultGCM);
|
ini.Get("Core", "DefaultGCM", &m_LocalCoreStartupParameter.m_strDefaultGCM);
|
||||||
ini.Get("Core", "DVDRoot", &m_LocalCoreStartupParameter.m_strDVDRoot);
|
ini.Get("Core", "DVDRoot", &m_LocalCoreStartupParameter.m_strDVDRoot);
|
||||||
ini.Get("Core", "OptimizeQuantizers", &m_LocalCoreStartupParameter.bOptimizeQuantizers, true);
|
ini.Get("Core", "OptimizeQuantizers", &m_LocalCoreStartupParameter.bOptimizeQuantizers, true);
|
||||||
|
@ -50,8 +50,8 @@ struct SConfig
|
|||||||
std::string m_LastFilename;
|
std::string m_LastFilename;
|
||||||
|
|
||||||
// gcm folder
|
// gcm folder
|
||||||
std::vector<std::string>m_ISOFolder;
|
std::vector<std::string> m_ISOFolder;
|
||||||
bool m_RecersiveISOFolder;
|
bool m_RecursiveISOFolder;
|
||||||
|
|
||||||
SCoreStartupParameter m_LocalCoreStartupParameter;
|
SCoreStartupParameter m_LocalCoreStartupParameter;
|
||||||
|
|
||||||
|
@ -414,6 +414,7 @@ THREAD_RETURN EmuThread(void *pArg)
|
|||||||
dspInit.pGetAudioStreaming = AudioInterface::Callback_GetStreaming;
|
dspInit.pGetAudioStreaming = AudioInterface::Callback_GetStreaming;
|
||||||
dspInit.pEmulatorState = (int *)PowerPC::GetStatePtr();
|
dspInit.pEmulatorState = (int *)PowerPC::GetStatePtr();
|
||||||
dspInit.bWii = _CoreParameter.bWii;
|
dspInit.bWii = _CoreParameter.bWii;
|
||||||
|
dspInit.bOnThread = _CoreParameter.bDSPThread;
|
||||||
// May be needed for Stop and Start
|
// May be needed for Stop and Start
|
||||||
#ifdef SETUP_FREE_DSP_PLUGIN_ON_BOOT
|
#ifdef SETUP_FREE_DSP_PLUGIN_ON_BOOT
|
||||||
Plugins.FreeDSP();
|
Plugins.FreeDSP();
|
||||||
|
@ -41,6 +41,7 @@ void SCoreStartupParameter::LoadDefaults()
|
|||||||
bUseDualCore = false;
|
bUseDualCore = false;
|
||||||
bSkipIdle = false;
|
bSkipIdle = false;
|
||||||
bRunCompareServer = false;
|
bRunCompareServer = false;
|
||||||
|
bDSPThread = true;
|
||||||
bLockThreads = true;
|
bLockThreads = true;
|
||||||
bWii = false;
|
bWii = false;
|
||||||
SelectedLanguage = 0;
|
SelectedLanguage = 0;
|
||||||
|
@ -57,6 +57,7 @@ struct SCoreStartupParameter
|
|||||||
bool bJITBranchOff;
|
bool bJITBranchOff;
|
||||||
|
|
||||||
bool bUseDualCore;
|
bool bUseDualCore;
|
||||||
|
bool bDSPThread;
|
||||||
bool bSkipIdle;
|
bool bSkipIdle;
|
||||||
bool bNTSC;
|
bool bNTSC;
|
||||||
bool bHLEBios;
|
bool bHLEBios;
|
||||||
|
@ -210,7 +210,7 @@ void DecrementerCallback(u64 userdata, int cyclesLate)
|
|||||||
void DecrementerSet()
|
void DecrementerSet()
|
||||||
{
|
{
|
||||||
u32 decValue = PowerPC::ppcState.spr[SPR_DEC];
|
u32 decValue = PowerPC::ppcState.spr[SPR_DEC];
|
||||||
fakeDec = decValue*TIMER_RATIO;
|
fakeDec = decValue * TIMER_RATIO;
|
||||||
CoreTiming::RemoveEvent(et_Dec);
|
CoreTiming::RemoveEvent(et_Dec);
|
||||||
CoreTiming::ScheduleEvent(decValue * TIMER_RATIO, et_Dec);
|
CoreTiming::ScheduleEvent(decValue * TIMER_RATIO, et_Dec);
|
||||||
}
|
}
|
||||||
@ -221,8 +221,8 @@ void AdvanceCallback(int cyclesExecuted)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
fakeDec -= cyclesExecuted;
|
fakeDec -= cyclesExecuted;
|
||||||
u64 timebase_ticks = CoreTiming::GetTicks() / TIMER_RATIO; //works since we are little endian and TL comes first :)
|
u64 timebase_ticks = CoreTiming::GetTicks() / TIMER_RATIO;
|
||||||
*(u64*)&TL = timebase_ticks + startTimeBaseTicks;
|
*(u64*)&TL = timebase_ticks + startTimeBaseTicks; //works since we are little endian and TL comes first :)
|
||||||
if (fakeDec >= 0)
|
if (fakeDec >= 0)
|
||||||
PowerPC::ppcState.spr[SPR_DEC] = (u32)fakeDec / TIMER_RATIO;
|
PowerPC::ppcState.spr[SPR_DEC] = (u32)fakeDec / TIMER_RATIO;
|
||||||
}
|
}
|
||||||
@ -243,10 +243,15 @@ void Init()
|
|||||||
CPU_CORE_CLOCK = 729000000u;
|
CPU_CORE_CLOCK = 729000000u;
|
||||||
VI_PERIOD = GetTicksPerSecond() / (60*120);
|
VI_PERIOD = GetTicksPerSecond() / (60*120);
|
||||||
SI_PERIOD = GetTicksPerSecond() / 60; // once a frame is good for controllers
|
SI_PERIOD = GetTicksPerSecond() / 60; // once a frame is good for controllers
|
||||||
|
|
||||||
// These are the big question marks IMHO :)
|
if (!Core::GetStartupParameter().bDSPThread) {
|
||||||
|
DSP_PERIOD = 12000; // TO BE TWEAKED
|
||||||
|
} else {
|
||||||
|
DSP_PERIOD = (int)(GetTicksPerSecond() * 0.003f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is the biggest question mark.
|
||||||
AI_PERIOD = GetTicksPerSecond() / 80;
|
AI_PERIOD = GetTicksPerSecond() / 80;
|
||||||
DSP_PERIOD = (int)(GetTicksPerSecond() * 0.003f);
|
|
||||||
|
|
||||||
IPC_HLE_PERIOD = (int)(GetTicksPerSecond() * 0.003f);
|
IPC_HLE_PERIOD = (int)(GetTicksPerSecond() * 0.003f);
|
||||||
}
|
}
|
||||||
@ -255,10 +260,15 @@ void Init()
|
|||||||
CPU_CORE_CLOCK = 486000000;
|
CPU_CORE_CLOCK = 486000000;
|
||||||
VI_PERIOD = GetTicksPerSecond() / (60*120);
|
VI_PERIOD = GetTicksPerSecond() / (60*120);
|
||||||
SI_PERIOD = GetTicksPerSecond() / 60; // once a frame is good for controllers
|
SI_PERIOD = GetTicksPerSecond() / 60; // once a frame is good for controllers
|
||||||
|
|
||||||
// These are the big question marks IMHO :)
|
if (!Core::GetStartupParameter().bDSPThread) {
|
||||||
|
DSP_PERIOD = 12000; // TO BE TWEAKED
|
||||||
|
} else {
|
||||||
|
DSP_PERIOD = (int)(GetTicksPerSecond() * 0.005f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is the biggest question mark.
|
||||||
AI_PERIOD = GetTicksPerSecond() / 80;
|
AI_PERIOD = GetTicksPerSecond() / 80;
|
||||||
DSP_PERIOD = (int)(GetTicksPerSecond() * 0.005f);
|
|
||||||
}
|
}
|
||||||
Common::Timer::IncreaseResolution();
|
Common::Timer::IncreaseResolution();
|
||||||
// store and convert localtime at boot to timebase ticks
|
// store and convert localtime at boot to timebase ticks
|
||||||
|
@ -49,6 +49,7 @@ EVT_CHOICE(ID_INTERFACE_LANG, CConfigMain::CoreSettingsChanged)
|
|||||||
EVT_CHECKBOX(ID_ALLWAYS_HLEBIOS, CConfigMain::CoreSettingsChanged)
|
EVT_CHECKBOX(ID_ALLWAYS_HLEBIOS, CConfigMain::CoreSettingsChanged)
|
||||||
EVT_CHECKBOX(ID_USEDYNAREC, CConfigMain::CoreSettingsChanged)
|
EVT_CHECKBOX(ID_USEDYNAREC, CConfigMain::CoreSettingsChanged)
|
||||||
EVT_CHECKBOX(ID_USEDUALCORE, CConfigMain::CoreSettingsChanged)
|
EVT_CHECKBOX(ID_USEDUALCORE, CConfigMain::CoreSettingsChanged)
|
||||||
|
EVT_CHECKBOX(ID_DSPTHREAD, CConfigMain::CoreSettingsChanged)
|
||||||
EVT_CHECKBOX(ID_LOCKTHREADS, CConfigMain::CoreSettingsChanged)
|
EVT_CHECKBOX(ID_LOCKTHREADS, CConfigMain::CoreSettingsChanged)
|
||||||
EVT_CHECKBOX(ID_OPTIMIZEQUANTIZERS, CConfigMain::CoreSettingsChanged)
|
EVT_CHECKBOX(ID_OPTIMIZEQUANTIZERS, CConfigMain::CoreSettingsChanged)
|
||||||
EVT_CHECKBOX(ID_IDLESKIP, CConfigMain::CoreSettingsChanged)
|
EVT_CHECKBOX(ID_IDLESKIP, CConfigMain::CoreSettingsChanged)
|
||||||
@ -131,7 +132,7 @@ void CConfigMain::UpdateGUI()
|
|||||||
if(Core::GetState() != Core::CORE_UNINITIALIZED)
|
if(Core::GetState() != Core::CORE_UNINITIALIZED)
|
||||||
{
|
{
|
||||||
// Disable the Core stuff on GeneralPage
|
// Disable the Core stuff on GeneralPage
|
||||||
AllwaysHLEBIOS->Disable();
|
AlwaysUseHLEBIOS->Disable();
|
||||||
UseDynaRec->Disable();
|
UseDynaRec->Disable();
|
||||||
UseDualCore->Disable();
|
UseDualCore->Disable();
|
||||||
LockThreads->Disable();
|
LockThreads->Disable();
|
||||||
@ -182,13 +183,15 @@ void CConfigMain::CreateGUIControls()
|
|||||||
// Core Settings - Basic
|
// Core Settings - Basic
|
||||||
UseDualCore = new wxCheckBox(GeneralPage, ID_USEDUALCORE, wxT("Enable Dual Core"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
UseDualCore = new wxCheckBox(GeneralPage, ID_USEDUALCORE, wxT("Enable Dual Core"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
UseDualCore->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bUseDualCore);
|
UseDualCore->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bUseDualCore);
|
||||||
|
DSPThread = new wxCheckBox(GeneralPage, ID_DSPTHREAD, wxT("LLE DSP on thread"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
|
DSPThread->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bDSPThread);
|
||||||
SkipIdle = new wxCheckBox(GeneralPage, ID_IDLESKIP, wxT("Enable Idle Skipping"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
SkipIdle = new wxCheckBox(GeneralPage, ID_IDLESKIP, wxT("Enable Idle Skipping"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
SkipIdle->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle);
|
SkipIdle->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle);
|
||||||
EnableCheats = new wxCheckBox(GeneralPage, ID_ENABLECHEATS, wxT("Enable Cheats"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
EnableCheats = new wxCheckBox(GeneralPage, ID_ENABLECHEATS, wxT("Enable Cheats"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
EnableCheats->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableCheats);
|
EnableCheats->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableCheats);
|
||||||
// Core Settings - Advanced
|
// Core Settings - Advanced
|
||||||
AllwaysHLEBIOS = new wxCheckBox(GeneralPage, ID_ALLWAYS_HLEBIOS, wxT("HLE the BIOS all the time"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
AlwaysUseHLEBIOS = new wxCheckBox(GeneralPage, ID_ALLWAYS_HLEBIOS, wxT("HLE the BIOS all the time"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
AllwaysHLEBIOS->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bHLEBios);
|
AlwaysUseHLEBIOS->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bHLEBios);
|
||||||
UseDynaRec = new wxCheckBox(GeneralPage, ID_USEDYNAREC, wxT("Enable the JIT dynarec"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
UseDynaRec = new wxCheckBox(GeneralPage, ID_USEDYNAREC, wxT("Enable the JIT dynarec"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
UseDynaRec->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bUseJIT);
|
UseDynaRec->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bUseJIT);
|
||||||
LockThreads = new wxCheckBox(GeneralPage, ID_LOCKTHREADS, wxT("Lock threads to cores"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
LockThreads = new wxCheckBox(GeneralPage, ID_LOCKTHREADS, wxT("Lock threads to cores"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
@ -260,10 +263,11 @@ void CConfigMain::CreateGUIControls()
|
|||||||
sCore = new wxBoxSizer(wxHORIZONTAL);
|
sCore = new wxBoxSizer(wxHORIZONTAL);
|
||||||
sbBasic = new wxStaticBoxSizer(wxVERTICAL, GeneralPage, wxT("Basic Settings"));
|
sbBasic = new wxStaticBoxSizer(wxVERTICAL, GeneralPage, wxT("Basic Settings"));
|
||||||
sbBasic->Add(UseDualCore, 0, wxALL, 5);
|
sbBasic->Add(UseDualCore, 0, wxALL, 5);
|
||||||
|
sbBasic->Add(DSPThread, 0, wxALL, 5);
|
||||||
sbBasic->Add(SkipIdle, 0, wxALL, 5);
|
sbBasic->Add(SkipIdle, 0, wxALL, 5);
|
||||||
sbBasic->Add(EnableCheats, 0, wxALL, 5);
|
sbBasic->Add(EnableCheats, 0, wxALL, 5);
|
||||||
sbAdvanced = new wxStaticBoxSizer(wxVERTICAL, GeneralPage, wxT("Advanced Settings"));
|
sbAdvanced = new wxStaticBoxSizer(wxVERTICAL, GeneralPage, wxT("Advanced Settings"));
|
||||||
sbAdvanced->Add(AllwaysHLEBIOS, 0, wxALL, 5);
|
sbAdvanced->Add(AlwaysUseHLEBIOS, 0, wxALL, 5);
|
||||||
sbAdvanced->Add(UseDynaRec, 0, wxALL, 5);
|
sbAdvanced->Add(UseDynaRec, 0, wxALL, 5);
|
||||||
sbAdvanced->Add(LockThreads, 0, wxALL, 5);
|
sbAdvanced->Add(LockThreads, 0, wxALL, 5);
|
||||||
sbAdvanced->Add(OptimizeQuantizers, 0, wxALL, 5);
|
sbAdvanced->Add(OptimizeQuantizers, 0, wxALL, 5);
|
||||||
@ -443,7 +447,7 @@ void CConfigMain::CreateGUIControls()
|
|||||||
RemoveISOPath = new wxButton(PathsPage, ID_REMOVEISOPATH, wxT("Remove"), wxDefaultPosition, wxDefaultSize, 0);
|
RemoveISOPath = new wxButton(PathsPage, ID_REMOVEISOPATH, wxT("Remove"), wxDefaultPosition, wxDefaultSize, 0);
|
||||||
RemoveISOPath->Enable(false);
|
RemoveISOPath->Enable(false);
|
||||||
RecersiveISOPath = new wxCheckBox(PathsPage, ID_RECERSIVEISOPATH, wxT("Search Subfolders"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
RecersiveISOPath = new wxCheckBox(PathsPage, ID_RECERSIVEISOPATH, wxT("Search Subfolders"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
RecersiveISOPath->SetValue(SConfig::GetInstance().m_RecersiveISOFolder);
|
RecersiveISOPath->SetValue(SConfig::GetInstance().m_RecursiveISOFolder);
|
||||||
DefaultISOText = new wxStaticText(PathsPage, ID_DEFAULTISO_TEXT, wxT("Default ISO:"), wxDefaultPosition, wxDefaultSize);
|
DefaultISOText = new wxStaticText(PathsPage, ID_DEFAULTISO_TEXT, wxT("Default ISO:"), wxDefaultPosition, wxDefaultSize);
|
||||||
DefaultISO = new wxFilePickerCtrl(PathsPage, ID_DEFAULTISO, wxEmptyString, wxT("Choose a default ISO:"),
|
DefaultISO = new wxFilePickerCtrl(PathsPage, ID_DEFAULTISO, wxEmptyString, wxT("Choose a default ISO:"),
|
||||||
wxString::Format(wxT("All GC/Wii images (gcm, iso, gcz)|*.gcm;*.iso;*.gcz|All files (%s)|%s"), wxFileSelectorDefaultWildcardStr, wxFileSelectorDefaultWildcardStr),
|
wxString::Format(wxT("All GC/Wii images (gcm, iso, gcz)|*.gcm;*.iso;*.gcz|All files (%s)|%s"), wxFileSelectorDefaultWildcardStr, wxFileSelectorDefaultWildcardStr),
|
||||||
@ -611,7 +615,7 @@ void CConfigMain::CoreSettingsChanged(wxCommandEvent& event)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ID_ALLWAYS_HLEBIOS: // Core
|
case ID_ALLWAYS_HLEBIOS: // Core
|
||||||
SConfig::GetInstance().m_LocalCoreStartupParameter.bHLEBios = AllwaysHLEBIOS->IsChecked();
|
SConfig::GetInstance().m_LocalCoreStartupParameter.bHLEBios = AlwaysUseHLEBIOS->IsChecked();
|
||||||
break;
|
break;
|
||||||
case ID_USEDYNAREC:
|
case ID_USEDYNAREC:
|
||||||
SConfig::GetInstance().m_LocalCoreStartupParameter.bUseJIT = UseDynaRec->IsChecked();
|
SConfig::GetInstance().m_LocalCoreStartupParameter.bUseJIT = UseDynaRec->IsChecked();
|
||||||
@ -619,6 +623,9 @@ void CConfigMain::CoreSettingsChanged(wxCommandEvent& event)
|
|||||||
case ID_USEDUALCORE:
|
case ID_USEDUALCORE:
|
||||||
SConfig::GetInstance().m_LocalCoreStartupParameter.bUseDualCore = UseDualCore->IsChecked();
|
SConfig::GetInstance().m_LocalCoreStartupParameter.bUseDualCore = UseDualCore->IsChecked();
|
||||||
break;
|
break;
|
||||||
|
case ID_DSPTHREAD:
|
||||||
|
SConfig::GetInstance().m_LocalCoreStartupParameter.bDSPThread = DSPThread->IsChecked();
|
||||||
|
break;
|
||||||
case ID_LOCKTHREADS:
|
case ID_LOCKTHREADS:
|
||||||
SConfig::GetInstance().m_LocalCoreStartupParameter.bLockThreads = LockThreads->IsChecked();
|
SConfig::GetInstance().m_LocalCoreStartupParameter.bLockThreads = LockThreads->IsChecked();
|
||||||
break;
|
break;
|
||||||
@ -843,7 +850,7 @@ void CConfigMain::AddRemoveISOPaths(wxCommandEvent& event)
|
|||||||
|
|
||||||
void CConfigMain::RecursiveDirectoryChanged(wxCommandEvent& WXUNUSED (event))
|
void CConfigMain::RecursiveDirectoryChanged(wxCommandEvent& WXUNUSED (event))
|
||||||
{
|
{
|
||||||
SConfig::GetInstance().m_RecersiveISOFolder = RecersiveISOPath->IsChecked();
|
SConfig::GetInstance().m_RecursiveISOFolder = RecersiveISOPath->IsChecked();
|
||||||
bRefreshList = true;
|
bRefreshList = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,9 +60,10 @@ class CConfigMain
|
|||||||
|
|
||||||
wxBoxSizer* sCore;
|
wxBoxSizer* sCore;
|
||||||
wxStaticBoxSizer* sbBasic, *sbAdvanced, *sbInterface;
|
wxStaticBoxSizer* sbBasic, *sbAdvanced, *sbInterface;
|
||||||
wxCheckBox* AllwaysHLEBIOS;
|
wxCheckBox* AlwaysUseHLEBIOS;
|
||||||
wxCheckBox* UseDynaRec;
|
wxCheckBox* UseDynaRec;
|
||||||
wxCheckBox* UseDualCore;
|
wxCheckBox* UseDualCore;
|
||||||
|
wxCheckBox* DSPThread;
|
||||||
wxCheckBox* LockThreads;
|
wxCheckBox* LockThreads;
|
||||||
wxCheckBox* OptimizeQuantizers;
|
wxCheckBox* OptimizeQuantizers;
|
||||||
wxCheckBox* SkipIdle;
|
wxCheckBox* SkipIdle;
|
||||||
@ -213,6 +214,7 @@ class CConfigMain
|
|||||||
ID_ALLWAYS_HLEBIOS,
|
ID_ALLWAYS_HLEBIOS,
|
||||||
ID_USEDYNAREC,
|
ID_USEDYNAREC,
|
||||||
ID_USEDUALCORE,
|
ID_USEDUALCORE,
|
||||||
|
ID_DSPTHREAD,
|
||||||
ID_LOCKTHREADS,
|
ID_LOCKTHREADS,
|
||||||
ID_OPTIMIZEQUANTIZERS,
|
ID_OPTIMIZEQUANTIZERS,
|
||||||
ID_IDLESKIP,
|
ID_IDLESKIP,
|
||||||
|
@ -375,7 +375,7 @@ void CGameListCtrl::ScanForISOs()
|
|||||||
m_ISOFiles.clear();
|
m_ISOFiles.clear();
|
||||||
CFileSearch::XStringVector Directories(SConfig::GetInstance().m_ISOFolder);
|
CFileSearch::XStringVector Directories(SConfig::GetInstance().m_ISOFolder);
|
||||||
|
|
||||||
if (SConfig::GetInstance().m_RecersiveISOFolder)
|
if (SConfig::GetInstance().m_RecursiveISOFolder)
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < Directories.size(); i++)
|
for (u32 i = 0; i < Directories.size(); i++)
|
||||||
{
|
{
|
||||||
|
@ -30,6 +30,7 @@ typedef struct
|
|||||||
TAudioGetStreaming pGetAudioStreaming;
|
TAudioGetStreaming pGetAudioStreaming;
|
||||||
int *pEmulatorState;
|
int *pEmulatorState;
|
||||||
bool bWii;
|
bool bWii;
|
||||||
|
bool bOnThread;
|
||||||
} DSPInitialize;
|
} DSPInitialize;
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
namespace DSPAnalyzer {
|
namespace DSPAnalyzer {
|
||||||
|
|
||||||
// Holds data about all instructions in RAM.
|
// Holds data about all instructions in RAM.
|
||||||
u8 inst_flags[ISPACE];
|
u8 code_flags[ISPACE];
|
||||||
|
|
||||||
// Good candidates for idle skipping is mail wait loops. If we're time slicing
|
// Good candidates for idle skipping is mail wait loops. If we're time slicing
|
||||||
// between the main CPU and the DSP, if the DSP runs into one of these, it might
|
// between the main CPU and the DSP, if the DSP runs into one of these, it might
|
||||||
@ -39,24 +39,24 @@ const u16 idle_skip_sigs[NUM_IDLE_SIGS][MAX_IDLE_SIG_SIZE + 1] =
|
|||||||
{ 0x26fc, // LRS $30, @DMBH
|
{ 0x26fc, // LRS $30, @DMBH
|
||||||
0x02c0, 0x8000, // ANDCF $30, #0x8000
|
0x02c0, 0x8000, // ANDCF $30, #0x8000
|
||||||
0x029d, 0xFFFF, // JLZ 0x027a
|
0x029d, 0xFFFF, // JLZ 0x027a
|
||||||
0x02df, 0 }, // RET
|
0, 0 }, // RET
|
||||||
{ 0x27fc, // LRS $31, @DMBH
|
{ 0x27fc, // LRS $31, @DMBH
|
||||||
0x03c0, 0x8000, // ANDCF $31, #0x8000
|
0x03c0, 0x8000, // ANDCF $31, #0x8000
|
||||||
0x029d, 0xFFFF, // JLZ 0x027a
|
0x029d, 0xFFFF, // JLZ 0x027a
|
||||||
0x02df, 0 }, // RET
|
0, 0 }, // RET
|
||||||
{ 0x26fe, // LRS $30, @CMBH
|
{ 0x26fe, // LRS $30, @CMBH
|
||||||
0x02c0, 0x8000, // ANDCF $30, #0x8000
|
0x02c0, 0x8000, // ANDCF $30, #0x8000
|
||||||
0x029c, 0xFFFF, // JLNZ 0x0280
|
0x029c, 0xFFFF, // JLNZ 0x0280
|
||||||
0x02df, 0 }, // RET
|
0, 0 }, // RET
|
||||||
{ 0x27fe, // LRS $31, @CMBH
|
{ 0x27fe, // LRS $31, @CMBH
|
||||||
0x03c0, 0x8000, // ANDCF $31, #0x8000
|
0x03c0, 0x8000, // ANDCF $31, #0x8000
|
||||||
0x029c, 0xFFFF, // JLNZ 0x0280
|
0x029c, 0xFFFF, // JLNZ 0x0280
|
||||||
0x02df, 0 }, // RET
|
0, 0 }, // RET
|
||||||
};
|
};
|
||||||
|
|
||||||
void Reset()
|
void Reset()
|
||||||
{
|
{
|
||||||
memset(inst_flags, 0, sizeof(inst_flags));
|
memset(code_flags, 0, sizeof(code_flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnalyzeRange(int start_addr, int end_addr)
|
void AnalyzeRange(int start_addr, int end_addr)
|
||||||
@ -76,7 +76,7 @@ void AnalyzeRange(int start_addr, int end_addr)
|
|||||||
addr++;
|
addr++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
inst_flags[addr] |= CODE_START_OF_INST;
|
code_flags[addr] |= CODE_START_OF_INST;
|
||||||
addr += opcode->size;
|
addr += opcode->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ void AnalyzeRange(int start_addr, int end_addr)
|
|||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
NOTICE_LOG(DSPLLE, "Idle skip location found at %02x", addr);
|
NOTICE_LOG(DSPLLE, "Idle skip location found at %02x", addr);
|
||||||
inst_flags[addr] |= CODE_IDLE_SKIP;
|
code_flags[addr] |= CODE_IDLE_SKIP;
|
||||||
// TODO: actually use this flag somewhere.
|
// TODO: actually use this flag somewhere.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -395,14 +395,3 @@ void InitInstructionTable()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComputeInstruction(const UDSPInstruction& inst)
|
|
||||||
{
|
|
||||||
if (prologueTable[inst.hex])
|
|
||||||
prologueTable[inst.hex](inst);
|
|
||||||
|
|
||||||
opTable[inst.hex](inst);
|
|
||||||
|
|
||||||
if (epilogueTable[inst.hex])
|
|
||||||
epilogueTable[inst.hex](inst);
|
|
||||||
}
|
|
||||||
|
@ -113,10 +113,21 @@ extern const u32 opcodes_ext_size;
|
|||||||
extern u8 opSize[OPTABLE_SIZE];
|
extern u8 opSize[OPTABLE_SIZE];
|
||||||
|
|
||||||
extern dspInstFunc opTable[];
|
extern dspInstFunc opTable[];
|
||||||
|
extern dspInstFunc prologueTable[OPTABLE_SIZE];
|
||||||
|
extern dspInstFunc epilogueTable[OPTABLE_SIZE];
|
||||||
|
|
||||||
void InitInstructionTable();
|
void InitInstructionTable();
|
||||||
|
|
||||||
void ComputeInstruction(const UDSPInstruction& inst);
|
inline void ExecuteInstruction(const UDSPInstruction& inst)
|
||||||
|
{
|
||||||
|
// TODO: Move the prologuetable calls into the relevant instructions themselves.
|
||||||
|
// Better not do things like this until things work correctly though.
|
||||||
|
if (prologueTable[inst.hex])
|
||||||
|
prologueTable[inst.hex](inst);
|
||||||
|
opTable[inst.hex](inst);
|
||||||
|
if (epilogueTable[inst.hex])
|
||||||
|
epilogueTable[inst.hex](inst);
|
||||||
|
}
|
||||||
|
|
||||||
// This one's pretty slow, try to use it only at init or seldomly.
|
// This one's pretty slow, try to use it only at init or seldomly.
|
||||||
// returns NULL if no matching instruction.
|
// returns NULL if no matching instruction.
|
||||||
|
@ -38,8 +38,7 @@
|
|||||||
|
|
||||||
SDSP g_dsp;
|
SDSP g_dsp;
|
||||||
|
|
||||||
bool gdsp_running;
|
volatile u32 gdsp_running;
|
||||||
extern volatile u32 dsp_running;
|
|
||||||
|
|
||||||
static bool cr_halt = true;
|
static bool cr_halt = true;
|
||||||
static bool cr_external_int = false;
|
static bool cr_external_int = false;
|
||||||
@ -231,14 +230,14 @@ void gdsp_step()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
u16 opc = dsp_fetch_code();
|
u16 opc = dsp_fetch_code();
|
||||||
ComputeInstruction(UDSPInstruction(opc));
|
ExecuteInstruction(UDSPInstruction(opc));
|
||||||
|
|
||||||
u16& rLoopCounter = g_dsp.r[DSP_REG_ST0 + 3];
|
|
||||||
|
|
||||||
|
// Handle looping hardware.
|
||||||
|
u16& rLoopCounter = g_dsp.r[DSP_REG_ST3];
|
||||||
if (rLoopCounter > 0)
|
if (rLoopCounter > 0)
|
||||||
{
|
{
|
||||||
const u16& rCallAddress = g_dsp.r[DSP_REG_ST0 + 0];
|
const u16 rCallAddress = g_dsp.r[DSP_REG_ST0];
|
||||||
const u16& rLoopAddress = g_dsp.r[DSP_REG_ST0 + 2];
|
const u16 rLoopAddress = g_dsp.r[DSP_REG_ST2];
|
||||||
|
|
||||||
if (g_dsp.pc == (rLoopAddress + 1))
|
if (g_dsp.pc == (rLoopAddress + 1))
|
||||||
{
|
{
|
||||||
@ -292,15 +291,14 @@ void gdsp_step()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Used by thread mode.
|
||||||
bool gdsp_run()
|
void gdsp_run()
|
||||||
{
|
{
|
||||||
gdsp_running = true;
|
gdsp_running = true;
|
||||||
|
|
||||||
while (!cr_halt)
|
while (!cr_halt)
|
||||||
{
|
{
|
||||||
// Are we running?
|
// Are we running?
|
||||||
if(*g_dspInitialize.pEmulatorState)
|
if (*g_dspInitialize.pEmulatorState)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
gdsp_step();
|
gdsp_step();
|
||||||
@ -308,9 +306,41 @@ bool gdsp_run()
|
|||||||
if (!gdsp_running)
|
if (!gdsp_running)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
gdsp_running = false;
|
gdsp_running = false;
|
||||||
return true;
|
}
|
||||||
|
|
||||||
|
// Used by non-thread mode.
|
||||||
|
void gdsp_run_cycles(int cycles)
|
||||||
|
{
|
||||||
|
// First, let's run a few cycles with no idle skipping so that things can progress a bit.
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
if (cr_halt)
|
||||||
|
return;
|
||||||
|
gdsp_step();
|
||||||
|
cycles--;
|
||||||
|
}
|
||||||
|
// Next, let's run a few cycles with idle skipping, so that we can skip loops.
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
if (cr_halt)
|
||||||
|
return;
|
||||||
|
if (DSPAnalyzer::code_flags[g_dsp.pc] & DSPAnalyzer::CODE_IDLE_SKIP)
|
||||||
|
return;
|
||||||
|
gdsp_step();
|
||||||
|
cycles--;
|
||||||
|
}
|
||||||
|
// Now, run the rest of the block without idle skipping. It might trip into a
|
||||||
|
// idle loop and if so we waste some time here. Might be beneficial to slice even further.
|
||||||
|
while (cycles > 0)
|
||||||
|
{
|
||||||
|
if (cr_halt)
|
||||||
|
return;
|
||||||
|
gdsp_step();
|
||||||
|
cycles--;
|
||||||
|
// We don't bother directly supporting pause - if the main emu pauses,
|
||||||
|
// it just won't call this function anymore.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gdsp_stop()
|
void gdsp_stop()
|
||||||
|
@ -103,11 +103,11 @@ bool gdsp_load_coef(const char *fname);
|
|||||||
|
|
||||||
|
|
||||||
// steps through DSP code, returns false if error occured
|
// steps through DSP code, returns false if error occured
|
||||||
void gdsp_step(void);
|
void gdsp_step();
|
||||||
void gdsp_loop_step();
|
void gdsp_loop_step();
|
||||||
bool gdsp_run(void);
|
void gdsp_run();
|
||||||
bool gdsp_runx(u16 cnt);
|
void gdsp_run_cycles(int cycles);
|
||||||
void gdsp_stop(void);
|
void gdsp_stop();
|
||||||
|
|
||||||
void gdsp_write_cr(u16 val);
|
void gdsp_write_cr(u16 val);
|
||||||
u16 gdsp_read_cr(void);
|
u16 gdsp_read_cr(void);
|
||||||
|
@ -116,12 +116,12 @@ void GetDllInfo(PLUGIN_INFO* _PluginInfo)
|
|||||||
_PluginInfo->Type = PLUGIN_TYPE_DSP;
|
_PluginInfo->Type = PLUGIN_TYPE_DSP;
|
||||||
|
|
||||||
#ifdef DEBUGFAST
|
#ifdef DEBUGFAST
|
||||||
sprintf(_PluginInfo->Name, "Dolphin DSP-LLE-Testing Plugin (DebugFast)");
|
sprintf(_PluginInfo->Name, "Dolphin DSP-LLE Plugin (DebugFast)");
|
||||||
#else
|
#else
|
||||||
#ifndef _DEBUG
|
#ifndef _DEBUG
|
||||||
sprintf(_PluginInfo->Name, "Dolphin DSP-LLE-Testing Plugin");
|
sprintf(_PluginInfo->Name, "Dolphin DSP-LLE Plugin");
|
||||||
#else
|
#else
|
||||||
sprintf(_PluginInfo->Name, "Dolphin DSP-LLE-Testing Plugin (Debug)");
|
sprintf(_PluginInfo->Name, "Dolphin DSP-LLE Plugin (Debug)");
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -176,11 +176,7 @@ THREAD_RETURN dsp_thread(void* lpParameter)
|
|||||||
{
|
{
|
||||||
while (bIsRunning)
|
while (bIsRunning)
|
||||||
{
|
{
|
||||||
if (!gdsp_run())
|
gdsp_run();
|
||||||
{
|
|
||||||
ERROR_LOG(AUDIO, "DSP Halt");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -225,7 +221,8 @@ void Initialize(void *init)
|
|||||||
PanicAlert("Failed loading DSP COEF from " DSP_COEF_FILE);
|
PanicAlert("Failed loading DSP COEF from " DSP_COEF_FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bCanWork) {
|
if (!bCanWork)
|
||||||
|
{
|
||||||
gdsp_shutdown();
|
gdsp_shutdown();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -234,7 +231,10 @@ void Initialize(void *init)
|
|||||||
|
|
||||||
InitInstructionTable();
|
InitInstructionTable();
|
||||||
|
|
||||||
g_hDSPThread = new Common::Thread(dsp_thread, NULL);
|
if (g_dspInitialize.bOnThread)
|
||||||
|
{
|
||||||
|
g_hDSPThread = new Common::Thread(dsp_thread, NULL);
|
||||||
|
}
|
||||||
soundStream = AudioCommon::InitSoundStream();
|
soundStream = AudioCommon::InitSoundStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,8 +242,11 @@ void DSP_StopSoundStream()
|
|||||||
{
|
{
|
||||||
gdsp_stop();
|
gdsp_stop();
|
||||||
bIsRunning = false;
|
bIsRunning = false;
|
||||||
delete g_hDSPThread;
|
if (g_dspInitialize.bOnThread)
|
||||||
g_hDSPThread = NULL;
|
{
|
||||||
|
delete g_hDSPThread;
|
||||||
|
g_hDSPThread = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shutdown()
|
void Shutdown()
|
||||||
@ -330,13 +333,22 @@ void DSP_WriteMailboxLow(bool _CPUMailbox, u16 _uLowMail)
|
|||||||
|
|
||||||
void DSP_Update(int cycles)
|
void DSP_Update(int cycles)
|
||||||
{
|
{
|
||||||
soundStream->Update();
|
// This gets called VERY OFTEN. The soundstream update might be expensive so only do it 200 times per second or something.
|
||||||
|
const int cycles_between_ss_update = 80000000 / 200;
|
||||||
|
static int cycle_count = 0;
|
||||||
|
cycle_count += cycles;
|
||||||
|
if (cycle_count > cycles_between_ss_update)
|
||||||
|
{
|
||||||
|
while (cycle_count > cycles_between_ss_update)
|
||||||
|
cycle_count -= cycles_between_ss_update;
|
||||||
|
soundStream->Update();
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
// If we're not on a thread, run cycles here.
|
||||||
// TODO fix? dunno how we should handle debug thread or whatever
|
if (!g_dspInitialize.bOnThread)
|
||||||
// if (m_DebuggerFrame->CanDoStep())
|
{
|
||||||
// gdsp_runx(100); // cycles
|
gdsp_run_cycles(cycles);
|
||||||
#endif
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSP_SendAIBuffer(unsigned int address, int sample_rate)
|
void DSP_SendAIBuffer(unsigned int address, int sample_rate)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user