From a3cfafcd12bdfb51e14e129cf82e55a9cd66a4e5 Mon Sep 17 00:00:00 2001 From: ayuanx Date: Fri, 8 Jan 2010 21:57:31 +0000 Subject: [PATCH] 1. Expanded Framelimit range from 20 to 120 in case someone wants to run a little faster than full speed but still controllable not like wild OFF. 2. Fixed a bug (for Win 32bit) that reports "No possible memory base pointer found!" even when there IS valid memory base found. 3. Made Metroid Prime 2 (maybe also other games) boot PS: There is definitely some initialization problem with Dolphin (not found exact location yet), which prevents Metroid Prime 2 from first time booting (If you boot some other GC game first, stop it, then MP2 can boot without problem). So I added an instant BP hack that can make MP2 boot even at first time. And I've tested all my games to guarantee it won't break any game that already boots before this hack. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4795 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Common/Src/MemArena.cpp | 5 +-- Source/Core/Core/Src/ConfigManager.cpp | 2 +- Source/Core/Core/Src/ConfigManager.h | 2 +- Source/Core/Core/Src/Core.cpp | 25 +++++++------- Source/Core/Core/Src/HW/VideoInterface.cpp | 18 +++++----- Source/Core/DolphinWX/Src/ConfigMain.cpp | 18 +++------- Source/Core/DolphinWX/Src/Frame.cpp | 6 ++-- .../Core/VideoCommon/Src/CommandProcessor.cpp | 33 ++++++++++--------- Source/Core/VideoCommon/Src/Fifo.cpp | 4 ++- 9 files changed, 56 insertions(+), 57 deletions(-) diff --git a/Source/Core/Common/Src/MemArena.cpp b/Source/Core/Common/Src/MemArena.cpp index 42fd97d886..9d918243a2 100644 --- a/Source/Core/Common/Src/MemArena.cpp +++ b/Source/Core/Common/Src/MemArena.cpp @@ -244,12 +244,13 @@ u8 *MemoryMap_Setup(const MemoryView *views, int num_views, u32 flags, MemArena u32 max_base_addr = 0x7FFF0000 - 0x31000000; u8 *base = NULL; int base_attempts = 1; - for (u32 base_addr = 0; base_addr < max_base_addr; base_addr += 0x40000) + for (u32 base_addr = 0x40000; base_addr < max_base_addr; base_addr += 0x40000) { base = (u8 *)base_addr; if (Memory_TryBase(base, views, num_views, flags, arena)) { INFO_LOG(MEMMAP, "Found valid memory base at %p after %i tries.", base, base_attempts); + base_attempts = 0; break; } base_attempts++; @@ -266,7 +267,7 @@ u8 *MemoryMap_Setup(const MemoryView *views, int num_views, u32 flags, MemArena #endif #endif - if (!base) + if (base_attempts) PanicAlert("No possible memory base pointer found!"); return base; } diff --git a/Source/Core/Core/Src/ConfigManager.cpp b/Source/Core/Core/Src/ConfigManager.cpp index 4eecb7c4e7..c6c08922e5 100644 --- a/Source/Core/Core/Src/ConfigManager.cpp +++ b/Source/Core/Core/Src/ConfigManager.cpp @@ -231,7 +231,7 @@ void SConfig::LoadSettings() ini.Get("Core", "RunCompareServer", &m_LocalCoreStartupParameter.bRunCompareServer, false); ini.Get("Core", "RunCompareClient", &m_LocalCoreStartupParameter.bRunCompareClient, false); ini.Get("Core", "TLBHack", &m_LocalCoreStartupParameter.iTLBHack, 0); - ini.Get("Core", "FrameLimit", &m_Framelimit, 0); // auto frame limit by default + ini.Get("Core", "FrameLimit", &m_Framelimit, 1); // auto frame limit by default // Plugins ini.Get("Core", "GFXPlugin", &m_LocalCoreStartupParameter.m_strVideoPlugin, m_DefaultGFXPlugin.c_str()); diff --git a/Source/Core/Core/Src/ConfigManager.h b/Source/Core/Core/Src/ConfigManager.h index daad5aa2e8..efa097b2f5 100644 --- a/Source/Core/Core/Src/ConfigManager.h +++ b/Source/Core/Core/Src/ConfigManager.h @@ -67,7 +67,7 @@ struct SConfig // interface language INTERFACE_LANGUAGE m_InterfaceLanguage; // framelimit choose - u32 m_Framelimit; + int m_Framelimit; // other interface settings bool m_InterfaceToolbar; bool m_InterfaceStatusbar; diff --git a/Source/Core/Core/Src/Core.cpp b/Source/Core/Core/Src/Core.cpp index 5360e6db03..806c93bce1 100644 --- a/Source/Core/Core/Src/Core.cpp +++ b/Source/Core/Core/Src/Core.cpp @@ -592,16 +592,17 @@ void ScreenShot() // This should only be called from VI void VideoThrottle() { - u32 TargetVPS = (SConfig::GetInstance().m_Framelimit > 1) ? SConfig::GetInstance().m_Framelimit * 5 + u32 TargetVPS = (SConfig::GetInstance().m_Framelimit > 1) ? SConfig::GetInstance().m_Framelimit * 10 : VideoInterface::TargetRefreshRate; // When frame limit is NOT off - if (SConfig::GetInstance().m_Framelimit != 1) + if (SConfig::GetInstance().m_Framelimit) { - u32 frametime = DrawnVideo * 2 * 1000 / TargetVPS; + // a full screen scan consists of 2 fields + u32 frametime = DrawnVideo * 2 * 1000 / TargetVPS; while ((u32)Timer.GetTimeDifference() < frametime) - //Common::YieldCPU(); - Common::SleepCurrentThread(1); + Common::YieldCPU(); + //Common::SleepCurrentThread(1); } // Update info per second @@ -612,10 +613,10 @@ void VideoThrottle() u32 FPS = Common::AtomicLoad(DrawnFrame) * 1000 / ElapseTime; u32 VPS = DrawnVideo * 2 * 1000 / ElapseTime; - u32 Speed = VPS * 100 / TargetVPS; + u32 Speed = VPS * 100 / VideoInterface::TargetRefreshRate; // Settings are shown the same for both extended and summary info - std::string SSettings = StringFromFormat("Core: %s %s", + std::string SSettings = StringFromFormat("%s %s", #if defined(JITTEST) && JITTEST #ifdef _M_IX86 _CoreParameter.bUseJIT ? "JIT32IL" : "Int32", @@ -661,7 +662,7 @@ void VideoThrottle() #endif // This is our final "frame counter" string - std::string SMessage = StringFromFormat(" %s | %s", SSettings.c_str(), SFPS.c_str()); + std::string SMessage = StringFromFormat("%s | %s", SSettings.c_str(), SFPS.c_str()); // Show message if (g_pUpdateFPSDisplay != NULL) @@ -674,8 +675,10 @@ void VideoThrottle() Common::AtomicStore(DrawnFrame, 0); DrawnVideo = 0; } - - DrawnVideo++; + else + { + DrawnVideo++; + } } // Executed from GPU thread @@ -683,7 +686,7 @@ void VideoThrottle() // depending on the framelimit set bool report_slow(int skipped) { - u32 TargetFPS = (SConfig::GetInstance().m_Framelimit > 1) ? SConfig::GetInstance().m_Framelimit * 5 + u32 TargetFPS = (SConfig::GetInstance().m_Framelimit > 1) ? SConfig::GetInstance().m_Framelimit * 10 : VideoInterface::TargetRefreshRate; u32 frames = Common::AtomicLoad(DrawnFrame); bool fps_slow = (Timer.GetTimeDifference() < (frames + skipped) * 1000 / TargetFPS) ? false : true; diff --git a/Source/Core/Core/Src/HW/VideoInterface.cpp b/Source/Core/Core/Src/HW/VideoInterface.cpp index ce5e797739..f9891a3bbd 100644 --- a/Source/Core/Core/Src/HW/VideoInterface.cpp +++ b/Source/Core/Core/Src/HW/VideoInterface.cpp @@ -211,7 +211,7 @@ union UVIInterruptRegister unsigned : 1; unsigned IR_MASK : 1; // Interrupt Enable Bit unsigned : 2; - unsigned IR_INT : 1; // Interrupt Status (1=Active) (Write to clear) + unsigned IR_INT : 1; // Interrupt Status (1=Active) (Read to clear) }; }; @@ -547,6 +547,8 @@ void Read16(u16& _uReturnValue, const u32 _iAddress) // RETRACE STUFF ... case VI_PRERETRACE_HI: _uReturnValue = m_InterruptRegister[0].Hi; + m_InterruptRegister[0].IR_INT = 0; + UpdateInterrupts(); return; case VI_PRERETRACE_LO: _uReturnValue = m_InterruptRegister[0].Lo; @@ -554,6 +556,8 @@ void Read16(u16& _uReturnValue, const u32 _iAddress) case VI_POSTRETRACE_HI: _uReturnValue = m_InterruptRegister[1].Hi; + m_InterruptRegister[1].IR_INT = 0; + UpdateInterrupts(); return; case VI_POSTRETRACE_LO: _uReturnValue = m_InterruptRegister[1].Lo; @@ -561,6 +565,8 @@ void Read16(u16& _uReturnValue, const u32 _iAddress) case VI_DISPLAY_INTERRUPT_2_HI: _uReturnValue = m_InterruptRegister[2].Hi; + m_InterruptRegister[2].IR_INT = 0; + UpdateInterrupts(); return; case VI_DISPLAY_INTERRUPT_2_LO: _uReturnValue = m_InterruptRegister[2].Lo; @@ -568,6 +574,8 @@ void Read16(u16& _uReturnValue, const u32 _iAddress) case VI_DISPLAY_INTERRUPT_3_HI: _uReturnValue = m_InterruptRegister[3].Hi; + m_InterruptRegister[3].IR_INT = 0; + UpdateInterrupts(); return; case VI_DISPLAY_INTERRUPT_3_LO: _uReturnValue = m_InterruptRegister[3].Lo; @@ -795,8 +803,6 @@ void Write16(const u16 _iValue, const u32 _iAddress) // RETRACE STUFF ... case VI_PRERETRACE_HI: m_InterruptRegister[0].Hi = _iValue; - m_InterruptRegister[0].IR_INT = 0; - UpdateInterrupts(); break; case VI_PRERETRACE_LO: m_InterruptRegister[0].Lo = _iValue; @@ -804,8 +810,6 @@ void Write16(const u16 _iValue, const u32 _iAddress) case VI_POSTRETRACE_HI: m_InterruptRegister[1].Hi = _iValue; - m_InterruptRegister[1].IR_INT = 0; - UpdateInterrupts(); break; case VI_POSTRETRACE_LO: m_InterruptRegister[1].Lo = _iValue; @@ -813,8 +817,6 @@ void Write16(const u16 _iValue, const u32 _iAddress) case VI_DISPLAY_INTERRUPT_2_HI: m_InterruptRegister[2].Hi = _iValue; - m_InterruptRegister[2].IR_INT = 0; - UpdateInterrupts(); break; case VI_DISPLAY_INTERRUPT_2_LO: m_InterruptRegister[2].Lo = _iValue; @@ -822,8 +824,6 @@ void Write16(const u16 _iValue, const u32 _iAddress) case VI_DISPLAY_INTERRUPT_3_HI: m_InterruptRegister[3].Hi = _iValue; - m_InterruptRegister[3].IR_INT = 0; - UpdateInterrupts(); break; case VI_DISPLAY_INTERRUPT_3_LO: m_InterruptRegister[3].Lo = _iValue; diff --git a/Source/Core/DolphinWX/Src/ConfigMain.cpp b/Source/Core/DolphinWX/Src/ConfigMain.cpp index ed901689b2..81b544ae97 100644 --- a/Source/Core/DolphinWX/Src/ConfigMain.cpp +++ b/Source/Core/DolphinWX/Src/ConfigMain.cpp @@ -176,19 +176,10 @@ void CConfigMain::CreateGUIControls() // GUI arrayStringFor_InterfaceLang = arrayStringFor_GCSystemLang; // Framelimit - arrayStringFor_Framelimit.Add(wxT("auto")); - arrayStringFor_Framelimit.Add(wxT("off")); - arrayStringFor_Framelimit.Add(wxT("10")); - arrayStringFor_Framelimit.Add(wxT("15")); - arrayStringFor_Framelimit.Add(wxT("20")); - arrayStringFor_Framelimit.Add(wxT("25")); - arrayStringFor_Framelimit.Add(wxT("30")); - arrayStringFor_Framelimit.Add(wxT("35")); - arrayStringFor_Framelimit.Add(wxT("40")); - arrayStringFor_Framelimit.Add(wxT("45")); - arrayStringFor_Framelimit.Add(wxT("50")); - arrayStringFor_Framelimit.Add(wxT("55")); - arrayStringFor_Framelimit.Add(wxT("60")); + arrayStringFor_Framelimit.Add(wxT("Off")); + arrayStringFor_Framelimit.Add(wxT("Auto")); + for (int i = 20; i <= 120; i+=10) // from 20 to 120 + arrayStringFor_Framelimit.Add(wxString::Format(wxT("%i"), i)); // Create the notebook and pages Notebook = new wxNotebook(this, ID_NOTEBOOK, wxDefaultPosition, wxDefaultSize); @@ -219,6 +210,7 @@ void CConfigMain::CreateGUIControls() // Framelimit wxStaticText *FramelimitText = new wxStaticText(GeneralPage, ID_FRAMELIMIT_TEXT, wxT("Framelimit :"), wxDefaultPosition, wxDefaultSize); Framelimit = new wxChoice(GeneralPage, ID_FRAMELIMIT, wxDefaultPosition, wxDefaultSize, arrayStringFor_Framelimit, 0, wxDefaultValidator); + Framelimit->SetToolTip(wxT("If you set Framelimit higher than game full speed (NTSC:60, PAL:50),\nyou also have to disable Audio Throttle in DSP to make it effective.")); Framelimit->SetSelection(SConfig::GetInstance().m_Framelimit); // Core Settings - Advanced diff --git a/Source/Core/DolphinWX/Src/Frame.cpp b/Source/Core/DolphinWX/Src/Frame.cpp index a13ad43315..37b75ac0ae 100644 --- a/Source/Core/DolphinWX/Src/Frame.cpp +++ b/Source/Core/DolphinWX/Src/Frame.cpp @@ -243,10 +243,7 @@ EVT_MENU(IDM_IMPORTSAVE, CFrame::OnImportSave) EVT_MENU(IDM_CHEATS, CFrame::OnShow_CheatsWindow) EVT_MENU(IDM_CHANGEDISC, CFrame::OnChangeDisc) EVT_MENU(IDM_LOAD_WII_MENU, CFrame::OnLoadWiiMenu) -EVT_MENU(IDM_CONNECT_WIIMOTE1, CFrame::OnConnectWiimote) -EVT_MENU(IDM_CONNECT_WIIMOTE2, CFrame::OnConnectWiimote) -EVT_MENU(IDM_CONNECT_WIIMOTE3, CFrame::OnConnectWiimote) -EVT_MENU(IDM_CONNECT_WIIMOTE4, CFrame::OnConnectWiimote) + EVT_MENU(IDM_TOGGLE_FULLSCREEN, CFrame::OnToggleFullscreen) EVT_MENU(IDM_TOGGLE_DUALCORE, CFrame::OnToggleDualCore) EVT_MENU(IDM_TOGGLE_SKIPIDLE, CFrame::OnToggleSkipIdle) @@ -274,6 +271,7 @@ EVT_MENU_RANGE(IDM_LOADSLOT1, IDM_LOADSLOT8, CFrame::OnLoadState) EVT_MENU_RANGE(IDM_SAVESLOT1, IDM_SAVESLOT8, CFrame::OnSaveState) EVT_MENU_RANGE(IDM_FRAMESKIP0, IDM_FRAMESKIP9, CFrame::OnFrameSkip) EVT_MENU_RANGE(IDM_DRIVE1, IDM_DRIVE24, CFrame::OnBootDrive) +EVT_MENU_RANGE(IDM_CONNECT_WIIMOTE1, IDM_CONNECT_WIIMOTE4, CFrame::OnConnectWiimote) // Other EVT_ACTIVATE(CFrame::OnActive) diff --git a/Source/Core/VideoCommon/Src/CommandProcessor.cpp b/Source/Core/VideoCommon/Src/CommandProcessor.cpp index 27a5b0ea27..edcc0dc763 100644 --- a/Source/Core/VideoCommon/Src/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/Src/CommandProcessor.cpp @@ -172,7 +172,7 @@ void Shutdown() void Read16(u16& _rReturnValue, const u32 _Address) { - DEBUG_LOG(COMMANDPROCESSOR, "(r): 0x%08x", _Address); + INFO_LOG(COMMANDPROCESSOR, "(r): 0x%08x", _Address); switch (_Address & 0xFFF) { case STATUS_REGISTER: @@ -185,12 +185,6 @@ void Read16(u16& _rReturnValue, const u32 _Address) //m_CPStatusReg.ReadIdle = 1; //m_CPStatusReg.CommandIdle = 1; - m_CPStatusReg.Breakpoint = fifo.bFF_Breakpoint; - _rReturnValue = m_CPStatusReg.Hex; - - // Clear on read - UpdateInterrupts(false); - DEBUG_LOG(COMMANDPROCESSOR, "(r) status: iBP %s | fReadIdle %s | fCmdIdle %s | iOvF %s | iUndF %s" , m_CPStatusReg.Breakpoint ? "ON" : "OFF" , m_CPStatusReg.ReadIdle ? "ON" : "OFF" @@ -199,6 +193,9 @@ void Read16(u16& _rReturnValue, const u32 _Address) , m_CPStatusReg.UnderflowLoWatermark ? "ON" : "OFF" ); + _rReturnValue = m_CPStatusReg.Hex; + // Clear on read + UpdateInterrupts(false); return; case CTRL_REGISTER: _rReturnValue = m_CPCtrlReg.Hex; return; @@ -331,7 +328,7 @@ void Read16(u16& _rReturnValue, const u32 _Address) case CLKS_PER_VTX_OUT: _rReturnValue = 4; //Number of clocks per vertex.. TODO: Calculate properly - WARN_LOG(COMMANDPROCESSOR, "Read from CLKS_PER_VTX_OUT: %04x", _rReturnValue); + DEBUG_LOG(COMMANDPROCESSOR, "Read from CLKS_PER_VTX_OUT: %04x", _rReturnValue); return; //add all the other regs here? are they ever read? default: @@ -411,9 +408,14 @@ void Write16(const u16 _Value, const u32 _Address) { // Clear old BP and initiate new BP Common::AtomicStore(fifo.bFF_Breakpoint, 0); + // AyuanX: The following is a hack + // There is definitely some initialization problem with Dolphin (not found exact location yet) + // Which prevents Metroid Prime 2 from first time booting (If you boot some other GC game first then MP2 can boot) + // But somehow this instant BP hack can make MP2 boot even at first time + UpdateInterrupts(true); } - DEBUG_LOG(COMMANDPROCESSOR,"\t write to CTRL_REGISTER : %04x", _Value); + INFO_LOG(COMMANDPROCESSOR,"\t write to CTRL_REGISTER : %04x", _Value); DEBUG_LOG(COMMANDPROCESSOR, "\t GPREAD %s | LINK %s | BP %s || Init %s | OvF %s | UndF %s" , fifo.bFF_GPReadEnable ? "ON" : "OFF" , fifo.bFF_GPLinkEnable ? "ON" : "OFF" @@ -425,11 +427,6 @@ void Write16(const u16 _Value, const u32 _Address) } break; - case PERF_SELECT: - // Seems to select which set of perf registers should be exposed. - DEBUG_LOG(COMMANDPROCESSOR, "write to PERF_SELECT: %04x", _Value); - break; - case CLEAR_REGISTER: // We don't care since we don't implement Watermark //m_CPClearReg.Hex = 0; @@ -438,6 +435,11 @@ void Write16(const u16 _Value, const u32 _Address) DEBUG_LOG(COMMANDPROCESSOR,"\t write to CLEAR_REGISTER : %04x", _Value); break; + case PERF_SELECT: + // Seems to select which set of perf registers should be exposed. + DEBUG_LOG(COMMANDPROCESSOR, "write to PERF_SELECT: %04x", _Value); + break; + // Fifo Registers case FIFO_TOKEN_REGISTER: m_tokenReg = _Value; @@ -726,7 +728,8 @@ void UpdateFifoRegister() void UpdateInterrupts(bool active) { - DEBUG_LOG(COMMANDPROCESSOR, "Fifo Breakpoint Interrupt: %s", (active)? "Asserted" : "Deasserted"); + INFO_LOG(COMMANDPROCESSOR, "Fifo Breakpoint Interrupt: %s", (active)? "Asserted" : "Deasserted"); + m_CPStatusReg.Breakpoint = active; g_VideoInitialize.pSetInterrupt(INT_CAUSE_CP, active); } diff --git a/Source/Core/VideoCommon/Src/Fifo.cpp b/Source/Core/VideoCommon/Src/Fifo.cpp index 172d6095fa..c01a9d94b3 100644 --- a/Source/Core/VideoCommon/Src/Fifo.cpp +++ b/Source/Core/VideoCommon/Src/Fifo.cpp @@ -169,7 +169,9 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize) ) { Common::AtomicStore(_fifo.bFF_Breakpoint, 1); - CommandProcessor::UpdateInterruptsFromVideoPlugin(true); + // Replaced by instant BP hack + // TODO: figure out why the correct trigger method doesn't work for MP2 + //CommandProcessor::UpdateInterruptsFromVideoPlugin(true); break; } distToSend = 32;