diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp index e2596964..aa6a0653 100644 --- a/src/audio/AudioManager.cpp +++ b/src/audio/AudioManager.cpp @@ -440,6 +440,9 @@ cAudioManager::IsAudioInitialised() const void cAudioManager::ServiceSoundEffects() { +#ifdef FIX_BUGS + if(CTimer::GetLogicalFramesPassed() != 0) +#endif m_bFifthFrameFlag = (m_FrameCounter++ % 5) == 0; if (m_nUserPause && !m_nPreviousUserPause) { for (int32 i = 0; i < NUM_CHANNELS; i++) @@ -793,9 +796,9 @@ cAudioManager::AddReleasingSounds() } if (!toProcess[i]) { if (sample.m_nCounter <= 255 || !sample.m_nLoopsRemaining) { - if (!sample.m_nReleasingVolumeDivider) + if (sample.m_nReleasingVolumeDivider == 0) continue; - if (!sample.m_nLoopCount) { + if (sample.m_nLoopCount == 0) { if (sample.m_nVolumeChange == -1) { sample.m_nVolumeChange = sample.m_nVolume / sample.m_nReleasingVolumeDivider; if (sample.m_nVolumeChange <= 0) @@ -807,6 +810,9 @@ cAudioManager::AddReleasingSounds() } sample.m_nVolume -= sample.m_nVolumeChange; } +#ifdef FIX_BUGS + if(CTimer::GetLogicalFramesPassed() != 0) +#endif --sample.m_nReleasingVolumeDivider; if (m_bFifthFrameFlag) { if (sample.m_nReleasingVolumeModificator < 20) diff --git a/src/audio/MusicManager.cpp b/src/audio/MusicManager.cpp index 1494334b..5a176005 100644 --- a/src/audio/MusicManager.cpp +++ b/src/audio/MusicManager.cpp @@ -1332,7 +1332,11 @@ cMusicManager::DisplayRadioStationName() } else { if (cDisplay == 0) return; +#ifdef FIX_BUGS + cDisplay -= CTimer::GetLogicalFramesPassed(); +#else cDisplay--; +#endif } CFont::SetJustifyOff(); diff --git a/src/audio/PolRadio.cpp b/src/audio/PolRadio.cpp index 30756d94..ce0e9a6d 100644 --- a/src/audio/PolRadio.cpp +++ b/src/audio/PolRadio.cpp @@ -137,7 +137,11 @@ cAudioManager::ServicePoliceRadio() if (!crimeReport) { if (wantedLevel != 0) { if (nLastSeen != 0) +#ifdef FIX_BUGS + nLastSeen -= CTimer::GetLogicalFramesPassed(); +#else --nLastSeen; +#endif else { nLastSeen = m_anRandomTable[1] % 1000 + 2000; SetupSuspectLastSeenReport(); @@ -176,7 +180,11 @@ cAudioManager::ServicePoliceRadioChannel(uint8 wantedLevel) } if (m_sPoliceRadioQueue.policeChannelTimer == 0) bChannelOpen = FALSE; if (cWait) { +#ifdef FIX_BUGS + cWait -= CTimer::GetLogicalFramesPassed(); +#else --cWait; +#endif return; } if (g_nMissionAudioSfx != NO_SAMPLE && !bChannelOpen) { diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index 798c1d8b..2160d8ce 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -181,7 +181,7 @@ const char* FrontendFilenames[][2] = { #ifdef XBOX_MESSAGE_SCREEN bool CMenuManager::m_bDialogOpen = false; uint32 CMenuManager::m_nDialogHideTimer = 0; -PauseModeTime CMenuManager::m_nDialogHideTimerPauseMode = 0; +uint32 CMenuManager::m_nDialogHideTimerPauseMode = 0; bool CMenuManager::m_bSaveWasSuccessful = false; wchar* CMenuManager::m_pDialogText = nil; #endif @@ -750,7 +750,7 @@ CMenuManager::DisplayHelperText(char *text) return; // there was a unused static bool - static PauseModeTime LastFlash = 0; + static uint32 LastFlash = 0; int32 alpha = 255; CFont::SetRightJustifyOn(); @@ -1425,7 +1425,7 @@ CMenuManager::DrawStandardMenus(bool activeScreen) } } - static PauseModeTime lastBlendChange = 0; + static uint32 lastBlendChange = 0; if (m_nOptionHighlightTransitionBlend <= 255) { static uint32 blendChangeCounter = 0; if (CTimer::GetTimeInMillisecondsPauseMode() - lastBlendChange > 20 @@ -1928,7 +1928,7 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 CFont::PrintString(nextX, nextY, seperator); nextX += CFont::GetStringWidth(seperator, true) + bindingMargin; } - static PauseModeTime lastWaitingTextFlash = 0; + static uint32 lastWaitingTextFlash = 0; if (CTimer::GetTimeInMillisecondsPauseMode() - lastWaitingTextFlash > 150) { showWaitingText = !showWaitingText; lastWaitingTextFlash = CTimer::GetTimeInMillisecondsPauseMode(); @@ -1993,7 +1993,7 @@ CMenuManager::DrawControllerScreenExtraText(int yStart, int xStart, int lineHeig CFont::PrintString(nextX, MENU_Y(yStart), TheText.Get("FEC_IBT")); nextX = CFont::GetStringWidth(TheText.Get("FEC_IBT"), true) + spacing + nextX; } - static PauseModeTime lastStateChange = 0; + static uint32 lastStateChange = 0; if (CTimer::GetTimeInMillisecondsPauseMode() - lastStateChange > 150) { waitingTextVisible = !waitingTextVisible; lastStateChange = CTimer::GetTimeInMillisecondsPauseMode(); @@ -2377,7 +2377,7 @@ CMenuManager::DrawBackground(bool transitionCall) m_nOptionHighlightTransitionBlend = 0; } - static PauseModeTime LastFade = 0; + static uint32 LastFade = 0; if (m_nMenuFadeAlpha < 255) { static uint8 forceFadeInCounter = 0; @@ -2448,7 +2448,7 @@ CMenuManager::DrawBackground(bool transitionCall) } if (m_ShowEmptyBindingError) { - static PauseModeTime lastBindingError = CTimer::GetTimeInMillisecondsPauseMode(); + static uint32 lastBindingError = CTimer::GetTimeInMillisecondsPauseMode(); static bool bindingErrorShown = false; if (bindingErrorShown) { lastBindingError = CTimer::GetTimeInMillisecondsPauseMode(); @@ -3332,7 +3332,7 @@ CMenuManager::PrintStats() else CFont::SetScale(MENU_X(0.37f), MENU_Y(0.75f)); - static PauseModeTime lastCheck = 0; + static uint32 lastCheck = 0; if (CTimer::GetTimeInMillisecondsPauseMode() - lastCheck > 40) { @@ -3473,7 +3473,7 @@ CMenuManager::AdditionalOptionInput(bool &goBack) switch (m_nCurrScreen) { case MENUPAGE_MAP: { - static PauseModeTime lastMapTick = 0; + static uint32 lastMapTick = 0; // FIX: All those macros were hardcoded values originally. @@ -3802,7 +3802,7 @@ CMenuManager::ExportStats() void CMenuManager::PrintRadioSelector(void) { - static PauseModeTime lastRadioChange = 0; + static uint32 lastRadioChange = 0; CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(418.f), MENU_Y(MENURADIO_SELECTOR_START_Y + MENURADIO_SELECTOR_HEIGHT), MENU_X_LEFT_ALIGNED(228.f), MENU_Y(MENURADIO_SELECTOR_START_Y + MENURADIO_SELECTOR_HEIGHT), @@ -3925,7 +3925,7 @@ CMenuManager::PrintRadioSelector(void) #endif static bool radioChangeRequested = false; - static PauseModeTime lastScrollCheck = 0; + static uint32 lastScrollCheck = 0; if (CTimer::GetTimeInMillisecondsPauseMode() - lastScrollCheck > 17) { if (m_ScrollRadioBy == 1) { if (m_LeftMostRadioX > MENU_X_LEFT_ALIGNED(MENURADIO_ICON_FIRST_X - MENURADIO_ICON_SIZE)) { @@ -4009,7 +4009,7 @@ CMenuManager::ProcessList(bool &optionSelected, bool &goBack) field_159 = false; } - static PauseModeTime lastTimeClickedScrollButton = 0; + static uint32 lastTimeClickedScrollButton = 0; if (CTimer::GetTimeInMillisecondsPauseMode() - lastTimeClickedScrollButton >= 200) { m_bPressedPgUpOnList = false; @@ -4395,7 +4395,7 @@ CMenuManager::UserInput(void) int curAction = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action; if (CPad::GetPad(0)->GetLeft() || CPad::GetPad(0)->GetPedWalkLeftRight() < 0 || CPad::GetPad(0)->GetDPadLeft()) { - static PauseModeTime lastSliderDecrease = 0; + static uint32 lastSliderDecrease = 0; if (CTimer::GetTimeInMillisecondsPauseMode() - lastSliderDecrease > 150) { if (curAction == MENUACTION_BRIGHTNESS || curAction == MENUACTION_MUSICVOLUME || curAction == MENUACTION_SFXVOLUME || curAction == MENUACTION_RADIO || @@ -4406,7 +4406,7 @@ CMenuManager::UserInput(void) lastSliderDecrease = CTimer::GetTimeInMillisecondsPauseMode(); } } else if (CPad::GetPad(0)->GetRight() || CPad::GetPad(0)->GetPedWalkLeftRight() > 0 || CPad::GetPad(0)->GetDPadRight()) { - static PauseModeTime lastSliderIncrease = 0; + static uint32 lastSliderIncrease = 0; if (CTimer::GetTimeInMillisecondsPauseMode() - lastSliderIncrease > 150) { if (curAction == MENUACTION_BRIGHTNESS || curAction == MENUACTION_MUSICVOLUME || curAction == MENUACTION_SFXVOLUME || curAction == MENUACTION_RADIO || @@ -5396,7 +5396,7 @@ CMenuManager::ProcessFileActions() { #ifdef XBOX_MESSAGE_SCREEN if (m_bDialogOpen && DialogTextCmp("FESZ_WR")) { - PauseModeTime startTime = CTimer::GetTimeInMillisecondsPauseMode(); + uint32 startTime = CTimer::GetTimeInMillisecondsPauseMode(); int8 SaveSlot = PcSaveHelper.SaveSlot(m_nCurrSaveSlot); PcSaveHelper.PopulateSlotInfo(); @@ -5654,13 +5654,13 @@ CMenuManager::DrawQuitGameScreen(void) #endif #ifndef MUCH_SHORTER_OUTRO_SCREEN - static PauseModeTime lastTickIncrease = 0; + static uint32 lastTickIncrease = 0; if (alpha == 255 && CTimer::GetTimeInMillisecondsPauseMode() - lastTickIncrease > 10) { exitSignalTimer++; lastTickIncrease = CTimer::GetTimeInMillisecondsPauseMode(); } #else - static PauseModeTime firstTick = CTimer::GetTimeInMillisecondsPauseMode(); + static uint32 firstTick = CTimer::GetTimeInMillisecondsPauseMode(); if (alpha == 255 && CTimer::GetTimeInMillisecondsPauseMode() - firstTick > 750) { exitSignalTimer = 150; } diff --git a/src/core/Frontend.h b/src/core/Frontend.h index 112ea7ad..b4e70613 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -735,7 +735,7 @@ public: #ifdef XBOX_MESSAGE_SCREEN static uint32 m_nDialogHideTimer; - static PauseModeTime m_nDialogHideTimerPauseMode; + static uint32 m_nDialogHideTimerPauseMode; static bool m_bDialogOpen; static wchar *m_pDialogText; static bool m_bSaveWasSuccessful; diff --git a/src/core/Radar.cpp b/src/core/Radar.cpp index ec3335fa..fadca215 100644 --- a/src/core/Radar.cpp +++ b/src/core/Radar.cpp @@ -1382,7 +1382,7 @@ CRadar::InitFrontEndMap() void CRadar::DrawYouAreHereSprite(float x, float y) { - static PauseModeTime lastChange = 0; + static uint32 lastChange = 0; static bool show = true; if (show) { @@ -1582,7 +1582,7 @@ void CRadar::DrawLegend(int32 x, int32 y, int32 sprite) { if (sprite < 0) { - static PauseModeTime lastChange = 0; + static uint32 lastChange = 0; static int8 blipMode = 0; CRGBA color; diff --git a/src/core/Timer.cpp b/src/core/Timer.cpp index 5ebe3f53..ac897da6 100644 --- a/src/core/Timer.cpp +++ b/src/core/Timer.cpp @@ -8,7 +8,7 @@ #include "SpecialFX.h" uint32 CTimer::m_snTimeInMilliseconds; -PauseModeTime CTimer::m_snTimeInMillisecondsPauseMode = 1; +uint32 CTimer::m_snTimeInMillisecondsPauseMode = 1; uint32 CTimer::m_snTimeInMillisecondsNonClipped; uint32 CTimer::m_snPreviousTimeInMilliseconds; @@ -17,7 +17,11 @@ float CTimer::ms_fTimeScale; float CTimer::ms_fTimeStep; float CTimer::ms_fTimeStepNonClipped; bool CTimer::m_UserPause; -bool CTimer::m_CodePause; +bool CTimer::m_CodePause; +#ifdef FIX_BUGS +uint32 CTimer::m_LogicalFrameCounter; +uint32 CTimer::m_LogicalFramesPassed; +#endif uint32 _nCyclesPerMS = 1; @@ -35,10 +39,6 @@ RsTimerType suspendPcTimer; uint32 suspendDepth; -#ifdef FIX_HIGH_FPS_BUGS_ON_FRONTEND -double frameTime; -#endif - void CTimer::Initialise(void) { debug("Initialising CTimer...\n"); @@ -51,6 +51,10 @@ void CTimer::Initialise(void) m_snTimeInMillisecondsNonClipped = 0; m_snPreviousTimeInMilliseconds = 0; m_snTimeInMilliseconds = 1; +#ifdef FIX_BUGS + m_LogicalFrameCounter = 0; + m_LogicalFramesPassed = 0; +#endif #ifdef _WIN32 LARGE_INTEGER perfFreq; @@ -83,7 +87,13 @@ void CTimer::Shutdown(void) } void CTimer::Update(void) -{ +{ +#ifdef FIX_BUGS + static double frameTimeLogical = 0.0; + static double frameTimeFraction = 0.0; + static double frameTimeFractionScaled = 0.0; +#endif + m_snPreviousTimeInMilliseconds = m_snTimeInMilliseconds; #ifdef _WIN32 @@ -98,22 +108,43 @@ void CTimer::Update(void) float updInCyclesScaled = GetIsPaused() ? updInCycles : updInCycles * ms_fTimeScale; - // We need that real frame time to fix transparent menu bug. -#ifndef FIX_HIGH_FPS_BUGS_ON_FRONTEND - double -#endif - frameTime = updInCyclesScaled / (double)_nCyclesPerMS; + double frameTime = updInCyclesScaled / (double)_nCyclesPerMS; +#ifdef FIX_BUGS + // count frames as if we're running at 30 fps + m_LogicalFramesPassed = 0; + frameTimeLogical += ((double)updInCycles / (double)_nCyclesPerMS); + while (frameTimeLogical >= 1000.0 / 30.0) { + frameTimeLogical -= 1000.0 / 30.0; + m_LogicalFramesPassed++; + } + m_LogicalFrameCounter += m_LogicalFramesPassed; + + frameTimeFraction += (double)updInCycles / (double)_nCyclesPerMS; + frameTimeFractionScaled += frameTime; + + m_snTimeInMillisecondsPauseMode += uint32(frameTimeFraction); +#else m_snTimeInMillisecondsPauseMode = m_snTimeInMillisecondsPauseMode + frameTime; +#endif if ( GetIsPaused() ) ms_fTimeStep = 0.0f; else { +#ifdef FIX_BUGS + m_snTimeInMilliseconds += uint32(frameTimeFractionScaled); + m_snTimeInMillisecondsNonClipped += uint32(frameTimeFractionScaled); +#else m_snTimeInMilliseconds = m_snTimeInMilliseconds + frameTime; m_snTimeInMillisecondsNonClipped = m_snTimeInMillisecondsNonClipped + frameTime; +#endif ms_fTimeStep = frameTime / 1000.0f * 50.0f; } +#ifdef FIX_BUGS + frameTimeFraction -= uint32(frameTimeFraction); + frameTimeFractionScaled -= uint32(frameTimeFractionScaled); +#endif } else #endif @@ -122,22 +153,39 @@ void CTimer::Update(void) RsTimerType updInMs = timer - oldPcTimer; - // We need that real frame time to fix transparent menu bug. -#ifndef FIX_HIGH_FPS_BUGS_ON_FRONTEND - double -#endif - frameTime = (double)updInMs * ms_fTimeScale; + double frameTime = (double)updInMs * ms_fTimeScale; oldPcTimer = timer; - + +#ifdef FIX_BUGS + // count frames as if we're running at 30 fps + m_LogicalFramesPassed = 0; + frameTimeLogical += (double)updInMs; + while(frameTimeLogical >= 1000.0 / 30.0) { + frameTimeLogical -= 1000.0 / 30.0; + m_LogicalFramesPassed++; + } + m_LogicalFrameCounter += m_LogicalFramesPassed; + + frameTimeFraction += (double)updInMs; + frameTimeFractionScaled += frameTime; + + m_snTimeInMillisecondsPauseMode += uint32(frameTimeFraction); +#else m_snTimeInMillisecondsPauseMode = m_snTimeInMillisecondsPauseMode + frameTime; - +#endif + if ( GetIsPaused() ) ms_fTimeStep = 0.0f; else { +#ifdef FIX_BUGS + m_snTimeInMilliseconds += uint32(frameTimeFractionScaled); + m_snTimeInMillisecondsNonClipped += uint32(frameTimeFractionScaled); +#else m_snTimeInMilliseconds = m_snTimeInMilliseconds + frameTime; m_snTimeInMillisecondsNonClipped = m_snTimeInMillisecondsNonClipped + frameTime; +#endif ms_fTimeStep = frameTime / 1000.0f * 50.0f; } } diff --git a/src/core/Timer.h b/src/core/Timer.h index 53591c4f..819bd30c 100644 --- a/src/core/Timer.h +++ b/src/core/Timer.h @@ -1,22 +1,20 @@ #pragma once -#ifdef FIX_HIGH_FPS_BUGS_ON_FRONTEND -#define PauseModeTime double -#else -#define PauseModeTime uint32 -#endif - class CTimer { static uint32 m_snTimeInMilliseconds; - static PauseModeTime m_snTimeInMillisecondsPauseMode; + static uint32 m_snTimeInMillisecondsPauseMode; static uint32 m_snTimeInMillisecondsNonClipped; static uint32 m_snPreviousTimeInMilliseconds; static uint32 m_FrameCounter; static float ms_fTimeScale; static float ms_fTimeStep; static float ms_fTimeStepNonClipped; +#ifdef FIX_BUGS + static uint32 m_LogicalFrameCounter; + static uint32 m_LogicalFramesPassed; +#endif public: static bool m_UserPause; static bool m_CodePause; @@ -35,7 +33,7 @@ public: static void SetTimeInMilliseconds(uint32 t) { m_snTimeInMilliseconds = t; } static uint32 GetTimeInMillisecondsNonClipped(void) { return m_snTimeInMillisecondsNonClipped; } static void SetTimeInMillisecondsNonClipped(uint32 t) { m_snTimeInMillisecondsNonClipped = t; } - static PauseModeTime GetTimeInMillisecondsPauseMode(void) { return m_snTimeInMillisecondsPauseMode; } + static uint32 GetTimeInMillisecondsPauseMode(void) { return m_snTimeInMillisecondsPauseMode; } static void SetTimeInMillisecondsPauseMode(uint32 t) { m_snTimeInMillisecondsPauseMode = t; } static uint32 GetPreviousTimeInMilliseconds(void) { return m_snPreviousTimeInMilliseconds; } static void SetPreviousTimeInMilliseconds(uint32 t) { m_snPreviousTimeInMilliseconds = t; } @@ -67,9 +65,7 @@ public: #ifdef FIX_BUGS static float GetDefaultTimeStep(void) { return 50.0f / 30.0f; } static float GetTimeStepFix(void) { return GetTimeStep() / GetDefaultTimeStep(); } + static uint32 GetLogicalFrameCounter(void) { return m_LogicalFrameCounter; } + static uint32 GetLogicalFramesPassed(void) { return m_LogicalFramesPassed; } #endif }; - -#ifdef FIX_HIGH_FPS_BUGS_ON_FRONTEND -extern double frameTime; -#endif diff --git a/src/core/main.cpp b/src/core/main.cpp index 90efdb62..4902c156 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -1131,8 +1131,11 @@ DisplayGameDebugText() #endif // #ifdef DRAW_GAME_VERSION_TEXT FrameSamples++; -#ifdef FIX_HIGH_FPS_BUGS_ON_FRONTEND - FramesPerSecondCounter += frameTime / 1000.f; // convert to seconds +#ifdef FIX_BUGS + // this is inaccurate with over 1000 fps + static uint32 PreviousTimeInMillisecondsPauseMode = 0; + FramesPerSecondCounter += (CTimer::GetTimeInMillisecondsPauseMode() - PreviousTimeInMillisecondsPauseMode) / 1000.0f; // convert to seconds + PreviousTimeInMillisecondsPauseMode = CTimer::GetTimeInMillisecondsPauseMode(); FramesPerSecond = FrameSamples / FramesPerSecondCounter; #else FramesPerSecondCounter += 1000.0f / CTimer::GetTimeStepNonClippedInMilliseconds();