diff --git a/Source/Core/Core/Src/ConfigManager.cpp b/Source/Core/Core/Src/ConfigManager.cpp index a97c325251..d611200252 100644 --- a/Source/Core/Core/Src/ConfigManager.cpp +++ b/Source/Core/Core/Src/ConfigManager.cpp @@ -121,6 +121,7 @@ void SConfig::SaveSettings() ini.Set("Display", "RenderWindowYPos", m_LocalCoreStartupParameter.iRenderWindowYPos); ini.Set("Display", "RenderWindowWidth", m_LocalCoreStartupParameter.iRenderWindowWidth); ini.Set("Display", "RenderWindowHeight", m_LocalCoreStartupParameter.iRenderWindowHeight); + ini.Set("Display", "ProgressiveScan", m_LocalCoreStartupParameter.bProgressive); // Game List Control ini.Set("GameList", "ListDrives", m_ListDrives); @@ -243,6 +244,7 @@ void SConfig::LoadSettings() ini.Get("Display", "RenderWindowYPos", &m_LocalCoreStartupParameter.iRenderWindowYPos, 0); ini.Get("Display", "RenderWindowWidth", &m_LocalCoreStartupParameter.iRenderWindowWidth, 640); ini.Get("Display", "RenderWindowHeight", &m_LocalCoreStartupParameter.iRenderWindowHeight, 480); + ini.Get("Display", "ProgressiveScan", &m_LocalCoreStartupParameter.bProgressive, false); // Game List Control ini.Get("GameList", "ListDrives", &m_ListDrives, false); diff --git a/Source/Core/Core/Src/CoreParameter.cpp b/Source/Core/Core/Src/CoreParameter.cpp index 8a712f798e..68f2392252 100644 --- a/Source/Core/Core/Src/CoreParameter.cpp +++ b/Source/Core/Core/Src/CoreParameter.cpp @@ -56,6 +56,7 @@ SCoreStartupParameter::SCoreStartupParameter() iRenderWindowXPos(0), iRenderWindowYPos(0), iRenderWindowWidth(640), iRenderWindowHeight(480), bFullscreen(false), bRenderToMain(false), + bProgressive(false), iTheme(0), iPosX(100), iPosY(100), iWidth(800), iHeight(600) { diff --git a/Source/Core/Core/Src/CoreParameter.h b/Source/Core/Core/Src/CoreParameter.h index 03c8f4e6f6..ca7cd6196e 100644 --- a/Source/Core/Core/Src/CoreParameter.h +++ b/Source/Core/Core/Src/CoreParameter.h @@ -101,6 +101,7 @@ struct SCoreStartupParameter int iRenderWindowXPos, iRenderWindowYPos; int iRenderWindowWidth, iRenderWindowHeight; bool bFullscreen, bRenderToMain; + bool bProgressive; int iTheme; int iPosX, iPosY, iWidth, iHeight; diff --git a/Source/Core/Core/Src/HW/SystemTimers.cpp b/Source/Core/Core/Src/HW/SystemTimers.cpp index bd67d8bb92..99d209ad69 100644 --- a/Source/Core/Core/Src/HW/SystemTimers.cpp +++ b/Source/Core/Core/Src/HW/SystemTimers.cpp @@ -182,7 +182,7 @@ void IPC_HLE_UpdateCallback(u64 userdata, int cyclesLate) void VICallback(u64 userdata, int cyclesLate) { VideoInterface::Update(); - CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame() - cyclesLate, et_VI); + CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerLine() - cyclesLate, et_VI); } void SICallback(u64 userdata, int cyclesLate) @@ -278,7 +278,7 @@ void Init() // This is the biggest question mark. AI_PERIOD = GetTicksPerSecond() / 80; - // System internal sample rate is fixed at 32KHz + // System internal sample rate is fixed at 32KHz * 4 (16bit Stereo) / 32 bytes DMA AUDIO_DMA_PERIOD = CPU_CORE_CLOCK / (32000 * 4 / 32); Common::Timer::IncreaseResolution(); @@ -301,7 +301,7 @@ void Init() et_PatchEngine = CoreTiming::RegisterEvent("PatchEngine", PatchEngineCallback); CoreTiming::ScheduleEvent(AI_PERIOD, et_AI); - CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame(), et_VI); + CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerLine(), et_VI); CoreTiming::ScheduleEvent(DSP_PERIOD, et_DSP); CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame(), et_SI); CoreTiming::ScheduleEvent(AUDIO_DMA_PERIOD, et_AudioDMA); diff --git a/Source/Core/Core/Src/HW/VideoInterface.cpp b/Source/Core/Core/Src/HW/VideoInterface.cpp index 96f58ceff4..422c76e547 100644 --- a/Source/Core/Core/Src/HW/VideoInterface.cpp +++ b/Source/Core/Core/Src/HW/VideoInterface.cpp @@ -145,17 +145,18 @@ void Preset(bool _bNTSC) m_VBeamPos = 1; // 54MHz, capable of progressive scan - m_Clock = 1; + m_Clock = Core::g_CoreStartupParameter.bProgressive?1:0; // Say component cable is plugged - m_DTVStatus = 1; + m_DTVStatus = Core::g_CoreStartupParameter.bProgressive?1:0; UpdateParameters(); } void SetRegionReg(char _region) { - m_DTVStatus = _region | (m_DTVStatus & 1); + if (Core::g_CoreStartupParameter.bProgressive) + m_DTVStatus = _region | (m_DTVStatus & 1); } void Init() @@ -280,6 +281,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; @@ -287,6 +290,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; @@ -294,6 +299,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; @@ -301,6 +308,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; @@ -528,7 +537,6 @@ void Write16(const u16 _iValue, const u32 _iAddress) // RETRACE STUFF ... case VI_PRERETRACE_HI: m_InterruptRegister[0].Hi = _iValue; - UpdateInterrupts(); break; case VI_PRERETRACE_LO: m_InterruptRegister[0].Lo = _iValue; @@ -536,7 +544,6 @@ void Write16(const u16 _iValue, const u32 _iAddress) case VI_POSTRETRACE_HI: m_InterruptRegister[1].Hi = _iValue; - UpdateInterrupts(); break; case VI_POSTRETRACE_LO: m_InterruptRegister[1].Lo = _iValue; @@ -544,7 +551,6 @@ void Write16(const u16 _iValue, const u32 _iAddress) case VI_DISPLAY_INTERRUPT_2_HI: m_InterruptRegister[2].Hi = _iValue; - UpdateInterrupts(); break; case VI_DISPLAY_INTERRUPT_2_LO: m_InterruptRegister[2].Lo = _iValue; @@ -552,7 +558,6 @@ void Write16(const u16 _iValue, const u32 _iAddress) case VI_DISPLAY_INTERRUPT_3_HI: m_InterruptRegister[3].Hi = _iValue; - UpdateInterrupts(); break; case VI_DISPLAY_INTERRUPT_3_LO: m_InterruptRegister[3].Lo = _iValue; @@ -717,23 +722,19 @@ void UpdateParameters() case 0: // NTSC case 2: // PAL-M TargetRefreshRate = NTSC_FIELD_RATE; - // AyuanX: Some games are pretty sensitive to this value - // So we have to make it run a little faster to prevent potential time out - TicksPerFrame = SystemTimers::GetTicksPerSecond() / (NTSC_FIELD_RATE + 1); - s_lineCount = m_DisplayControlRegister.NIN ? NTSC_LINE_COUNT : (NTSC_LINE_COUNT+1)/2; - //s_upperFieldBegin = NTSC_UPPER_BEGIN; - //s_lowerFieldBegin = NTSC_LOWER_BEGIN; - break; + TicksPerFrame = SystemTimers::GetTicksPerSecond() / (NTSC_FIELD_RATE / 2); + s_lineCount = NTSC_LINE_COUNT; + s_upperFieldBegin = NTSC_UPPER_BEGIN; + s_lowerFieldBegin = NTSC_LOWER_BEGIN; + break; case 1: // PAL TargetRefreshRate = PAL_FIELD_RATE; - // AyuanX: Some games are pretty sensitive to this value - // So we have to make it run a little faster to prevent potential time out - TicksPerFrame = SystemTimers::GetTicksPerSecond() / (PAL_FIELD_RATE + 1); - s_lineCount = m_DisplayControlRegister.NIN ? PAL_LINE_COUNT : (PAL_LINE_COUNT+1)/2; - //s_upperFieldBegin = PAL_UPPER_BEGIN; - //s_lowerFieldBegin = PAL_LOWER_BEGIN; - break; + TicksPerFrame = SystemTimers::GetTicksPerSecond() / (PAL_FIELD_RATE / 2); + s_lineCount = PAL_LINE_COUNT; + s_upperFieldBegin = PAL_UPPER_BEGIN; + s_lowerFieldBegin = PAL_LOWER_BEGIN; + break; case 3: // Debug PanicAlert("Debug video mode not implemented"); @@ -748,9 +749,13 @@ void UpdateParameters() int GetTicksPerLine() { if (s_lineCount == 0) - return 100000; + { + return 1; + } else - return TicksPerFrame / s_lineCount; + { + return TicksPerFrame / (s_lineCount * 2); + } } int GetTicksPerFrame() @@ -781,35 +786,56 @@ static void BeginField(FieldType field) video->Video_BeginField(xfbAddr, field, fbWidth, fbHeight); } -/* static void EndField() { Common::PluginVideo* video = CPluginManager::GetInstance().GetVideo(); if (video->IsValid()) + { video->Video_EndField(); + Core::VideoThrottle(); + } } -*/ -// AyuanX: No need to update per scan line, update per frame is good enough, and faster // Purpose: Send VI interrupt when triggered -// Run when: When a frame is scaned (progressive/interlace) +// Run when: When a frame is scanned (progressive/interlace) void Update() { - u16 NewVBeamPos; + u16 NewVBeamPos = 0; + if (m_DisplayControlRegister.NIN) { // Progressive NewVBeamPos = s_lineCount + 1; + BeginField(FIELD_PROGRESSIVE); } - else if (m_VBeamPos == s_lineCount) + else if (m_VBeamPos == s_upperFieldBegin) { // Interlace Upper NewVBeamPos = s_lineCount * 2; + BeginField(FIELD_UPPER); } - else + else if (m_VBeamPos == s_lowerFieldBegin) { // Interlace Lower NewVBeamPos = s_lineCount; + BeginField(FIELD_LOWER); + } + + if (m_DisplayControlRegister.NIN) + { + // Progressive + if (m_VBeamPos == s_lineCount) + EndField(); + } + else if (m_VBeamPos == s_upperFieldBegin + m_VerticalTimingRegister.ACV) + { + // Interlace Upper. Do not EndField (swapBuffer) at the end of the upper field. + //EndField(); + } + else if (m_VBeamPos == s_lowerFieldBegin + m_VerticalTimingRegister.ACV) + { + // Interlace Lower + EndField(); } for (int i = 0; i < 4; i++) @@ -818,63 +844,11 @@ void Update() m_InterruptRegister[i].IR_INT = 1; } UpdateInterrupts(); - - if (m_DisplayControlRegister.NIN) - { - // Progressive - BeginField(FIELD_PROGRESSIVE); - } - else if (m_VBeamPos == s_lineCount) - { - // Interlace Upper - BeginField(FIELD_UPPER); - } - else - { - // Interlace Lower - BeginField(FIELD_LOWER); - } - m_VBeamPos = (NewVBeamPos > s_lineCount) ? 1 : NewVBeamPos; - - - Core::VideoThrottle(); + if (++m_VBeamPos > s_lineCount) + { + m_VBeamPos = (NewVBeamPos > s_lineCount) ? 1 : NewVBeamPos; + } } -/* -// Purpose: Send VI interrupt when triggered -// Run when: When a line is scaned -void Update() -{ - - // TODO: What's the correct behavior for progressive mode? - if (m_VBeamPos == s_upperFieldBegin + m_VerticalTimingRegister.ACV) - EndField(); - else if (m_VBeamPos == s_lowerFieldBegin + m_VerticalTimingRegister.ACV) - EndField(); - - - if (++m_VBeamPos > s_lineCount) - { - m_VBeamPos = 1; - // Apply video throttle whenever a full screen scan finishes - Core::VideoThrottle(); - } - - for (int i = 0; i < 4; ++i) - { - if (m_InterruptRegister[i].VCT == m_VBeamPos) - m_InterruptRegister[i].IR_INT = 1; - } - UpdateInterrupts(); - - - if (m_VBeamPos == s_upperFieldBegin) - BeginField(m_DisplayControlRegister.NIN ? FIELD_PROGRESSIVE : FIELD_UPPER); - else if (m_VBeamPos == s_lowerFieldBegin) - BeginField(m_DisplayControlRegister.NIN ? FIELD_PROGRESSIVE : FIELD_LOWER); - -} -*/ - } // namespace diff --git a/Source/Core/DolphinWX/Src/ConfigMain.cpp b/Source/Core/DolphinWX/Src/ConfigMain.cpp index d14b486ca5..83a2d611fb 100644 --- a/Source/Core/DolphinWX/Src/ConfigMain.cpp +++ b/Source/Core/DolphinWX/Src/ConfigMain.cpp @@ -1039,6 +1039,7 @@ void CConfigMain::WiiSettingsChanged(wxCommandEvent& event) break; case ID_WII_IPL_PGS: SConfig::GetInstance().m_SYSCONF->SetData("IPL.PGS", WiiProgressiveScan->IsChecked()); + SConfig::GetInstance().m_LocalCoreStartupParameter.bProgressive = WiiProgressiveScan->IsChecked(); break; case ID_WII_IPL_E60: SConfig::GetInstance().m_SYSCONF->SetData("IPL.E60", WiiEuRGB60->IsChecked()); diff --git a/Source/Core/DolphinWX/Src/ISOProperties.cpp b/Source/Core/DolphinWX/Src/ISOProperties.cpp index ef5da260d8..5f427e77d0 100644 --- a/Source/Core/DolphinWX/Src/ISOProperties.cpp +++ b/Source/Core/DolphinWX/Src/ISOProperties.cpp @@ -863,7 +863,7 @@ void CISOProperties::LoadGameConfig() else BlockMerging->Set3StateValue(wxCHK_UNDETERMINED); - if (GameIni.Get("Wii", "ProgressiveScan", &bTemp)) + if (GameIni.Get("Display", "ProgressiveScan", &bTemp)) EnableProgressiveScan->Set3StateValue((wxCheckBoxState)bTemp); else EnableProgressiveScan->Set3StateValue(wxCHK_UNDETERMINED); @@ -980,9 +980,9 @@ bool CISOProperties::SaveGameConfig() GameIni.Set("Core", "BlockMerging", BlockMerging->Get3StateValue()); if (EnableProgressiveScan->Get3StateValue() == wxCHK_UNDETERMINED) - GameIni.DeleteKey("Wii", "ProgressiveScan"); + GameIni.DeleteKey("Display", "ProgressiveScan"); else - GameIni.Set("Wii", "ProgressiveScan", EnableProgressiveScan->Get3StateValue()); + GameIni.Set("Display", "ProgressiveScan", EnableProgressiveScan->Get3StateValue()); if (EnableWideScreen->Get3StateValue() == wxCHK_UNDETERMINED) GameIni.DeleteKey("Wii", "Widescreen"); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp index 6a800f557c..a67d0853f5 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp @@ -357,26 +357,22 @@ void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight) { if (s_PluginInitialized && g_ActiveConfig.bUseXFB) { - if (g_VideoInitialize.bOnThread) - { - while (Common::AtomicLoadAcquire(s_swapRequested) && !s_FifoShuttingDown) - //Common::SleepCurrentThread(1); - Common::YieldCPU(); - } - else + if (!g_VideoInitialize.bOnThread) VideoFifo_CheckSwapRequest(); s_beginFieldArgs.xfbAddr = xfbAddr; s_beginFieldArgs.field = field; s_beginFieldArgs.fbWidth = fbWidth; s_beginFieldArgs.fbHeight = fbHeight; - - Common::AtomicStoreRelease(s_swapRequested, TRUE); } } // Run from the CPU thread (from VideoInterface.cpp) void Video_EndField() { + if (s_PluginInitialized) + { + Common::AtomicStoreRelease(s_swapRequested, TRUE); + } } void Video_AddMessage(const char* pstr, u32 milliseconds) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp index 0f83984783..b25f1482b6 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp @@ -387,26 +387,22 @@ void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight) { if (s_PluginInitialized && g_ActiveConfig.bUseXFB) { - if (g_VideoInitialize.bOnThread) - { - while (Common::AtomicLoadAcquire(s_swapRequested) && !s_FifoShuttingDown) - //Common::SleepCurrentThread(1); - Common::YieldCPU(); - } - else + if (!g_VideoInitialize.bOnThread) VideoFifo_CheckSwapRequest(); s_beginFieldArgs.xfbAddr = xfbAddr; s_beginFieldArgs.field = field; s_beginFieldArgs.fbWidth = fbWidth; s_beginFieldArgs.fbHeight = fbHeight; - - Common::AtomicStoreRelease(s_swapRequested, TRUE); } } // Run from the CPU thread (from VideoInterface.cpp) void Video_EndField() { + if (s_PluginInitialized) + { + Common::AtomicStoreRelease(s_swapRequested, TRUE); + } } void Video_AddMessage(const char* pstr, u32 milliseconds)