From 7932f4cc00fc9323793bc14c56658e420ce7ff71 Mon Sep 17 00:00:00 2001 From: Nathan Fulton Date: Sat, 29 Apr 2017 22:36:41 -0400 Subject: [PATCH] Implement FPS cap --- game/event.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++++-- game/game.cpp | 1 + game/ht.h | 11 ++++++---- 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/game/event.cpp b/game/event.cpp index dc30665..aea8b41 100644 --- a/game/event.cpp +++ b/game/event.cpp @@ -3,6 +3,7 @@ namespace wi { EventMgr gevm; +long gcmsNextPaint = 0; EventMgr::EventMgr() { @@ -139,6 +140,24 @@ bool EventMgr::GetEvent(Event *pevt, long ctWait, bool fCheckPaints) #else { #endif + // Ensure that the skipped paint will be painted before sleeping kctForever + + if ((m_wfRedraw & kfRedrawPaintSkipped) && ctWait == -1) { + + // Convert next paint to ticks + + long ctNextPaint = (gcmsNextPaint / 10); + + // Adjust wait time to next possible paint + + tCurrent = gtimm.GetTickCount(); + ctElapsed = tCurrent - tStart; + ctWait = ctElapsed + ctNextPaint; + + m_wfRedraw &= ~kfRedrawPaintSkipped; + m_wfRedraw |= kfRedrawDirty; + } + // Get the event from the host. The host doesn't coalesce // messages, but does mark messages has being coalesce // candidates, based on what was in the queue when the post @@ -258,8 +277,16 @@ bool EventMgr::GetEvent(Event *pevt, long ctWait, bool fCheckPaints) } else { m_wfRedraw &= ~(kfRedrawDirty | kfRedrawBeforeTimer | kfRedrawBeforeInput); } - pevt->eType = gamePaintEvent; - return true; + + // Is it within the max fps rate? + + if (CheckPaintFPS()) { + m_wfRedraw &= ~kfRedrawPaintSkipped; + pevt->eType = gamePaintEvent; + return true; + } else { + m_wfRedraw |= kfRedrawPaintSkipped; + } } // If the user timeout expired, return timeout @@ -388,6 +415,32 @@ bool EventMgr::QueryPenHistory(int nPen, long ms, Point *ppt) return true; } + +bool EventMgr::CheckPaintFPS() +{ + long cmsCurrent = HostGetMillisecondCount(); + + // First time through? + + if (gcmsNextPaint == 0) { + gcmsNextPaint = cmsCurrent + gcmsDisplayUpdate; + return true; + } else if (cmsCurrent >= gcmsNextPaint) { + + // Is cmsCurrent is way ahead? This can occur after sleeping + + if (cmsCurrent >= gcmsNextPaint + gcmsDisplayUpdate * 5) { + gcmsNextPaint = cmsCurrent + gcmsDisplayUpdate; + } else { + gcmsNextPaint += gcmsDisplayUpdate; + } + return true; + } + + // There hasn't been enough time since the last draw + + return false; +} void EventMgr::Init() { diff --git a/game/game.cpp b/game/game.cpp index 2961a00..9969db1 100644 --- a/game/game.cpp +++ b/game/game.cpp @@ -71,6 +71,7 @@ bool gfMultiplayer; bool gfIgnoreBluetoothWarning; SpriteManager *gpsprm; TexAtlasMgr *gptam; +int gcmsDisplayUpdate = 8; // mimimum ms to elapse between paints #ifdef STRESS bool gfStress = false; diff --git a/game/ht.h b/game/ht.h index 09fc47e..dbf2b32 100644 --- a/game/ht.h +++ b/game/ht.h @@ -1792,10 +1792,11 @@ enum { #define kcevtPostMax 20 -#define kfRedrawDirty 1 -#define kfRedrawMax 2 -#define kfRedrawBeforeTimer 4 -#define kfRedrawBeforeInput 8 +#define kfRedrawDirty 0x01 +#define kfRedrawMax 0x02 +#define kfRedrawBeforeTimer 0x04 +#define kfRedrawBeforeInput 0x08 +#define kfRedrawPaintSkipped 0x10 struct FlickVector { int GetMagnitude() { @@ -1848,6 +1849,7 @@ public: } private: + bool CheckPaintFPS() secEventMgr; void UpdatePenHistory(Event *pevt) secEventMgr; bool QueryPenHistory(int nPen, long t, Point *ppt); @@ -8534,6 +8536,7 @@ extern int gnMPPos; extern char *gpszDataDir; extern bool gfIgnoreBluetoothWarning; extern TexAtlasMgr *gptam; +extern int gcmsDisplayUpdate; inline Color GetColor(int iclr) { return gaclrFixed[iclr];