AutoFrameSkip: Graphics option to reduce lag by slow

Skips drawing every second frame if drawing the previous frame was too slow
Setting is controlled by game host
Default: on

Imported from Clonk Rage

From e6e680f49ac50a352e9a051ee21622e7f00648b6 Mon Sep 17 00:00:00 2001
From: sven2 <sven2@786b8e90-9c09-0410-89a9-bccc6ef1e79b>
Date: Sat, 21 Sep 2013 21:34:44 +0000
Subject: [PATCH] + AutoFrameSkip: Graphics option to reduce lag by slow
 clients in network games

git-svn-id: https://www.clonk.de:83/svn/clonk/stable@14501 786b8e90-9c09-0410-89a9-bccc6ef1e79b
heavy-resources
Julius Michaelis 2014-04-03 14:53:12 +02:00
parent 405fc4f841
commit e5b7ef5b80
9 changed files with 47 additions and 19 deletions

View File

@ -173,6 +173,7 @@ IDS_CTL_TROUBLE=Problembehebung
IDS_CTL_UPDATE=&Update
IDS_CTL_USEOTHERSERVER=anderen Internetserver verwenden
IDS_CTL_WON=gewonnen
IDS_DESC_AUTOFRAMESKIP=Überspringt automatisch Grafikframes, wenn das Spiel stockt.
IDS_DESC_AUTOMATICUPDATES=Prüft beim Programmstart einmal pro Tag, ob Updates für die installierte Version verfügbar sind.
IDS_DESC_CHANGESTHEWAYCONTROLDATAI=Legt fest, wie Steuerungsdaten in Netzwerkspielen zwischen Client-Rechnern ausgetauscht werden.
IDS_DESC_CHECKONLINEFORNEWVERSIONS=Sucht online nach Updates für diese Version.
@ -507,6 +508,7 @@ IDS_MNU_VIEWPORT=Sichtfenster
IDS_MSG_ALLOWSYOUTOJOINADIFFERENT=Erlaubt die Auswahl eines anderen Teams.
IDS_MSG_ANTIALIASING_DESC=FSAA (MultiSampling)-Level einstellen
IDS_MSG_ANUPDATETOVERSIONISAVAILA=Ein neues Update ist verfügbar. Soll das Update heruntergeladen und installiert werden?
+IDS_MSG_AUTOFRAMESKIP=Automatischer Frameskip
IDS_MSG_AUTOWINDOWED=Automagisch
IDS_MSG_BACKTOPLAYERDLG=Zurück zur Spielerauswahl.
IDS_MSG_CANNOTSTARTSCENARIO=Start nicht möglich.

View File

@ -173,6 +173,7 @@ IDS_CTL_TROUBLE=Troubleshooting
IDS_CTL_UPDATE=&Update
IDS_CTL_USEOTHERSERVER=Use alternate internet server
IDS_CTL_WON=won
IDS_DESC_AUTOFRAMESKIP=Automatically skips graphics frames if the game is lagging.
IDS_DESC_AUTOMATICUPDATES=With this option enabled, the program will automatically check for updates once a day at program start.
IDS_DESC_CHANGESTHEWAYCONTROLDATAI=Changes the way control data is exchanged between network clients.
IDS_DESC_CHECKONLINEFORNEWVERSIONS=Check online for new versions.
@ -507,6 +508,7 @@ IDS_MNU_VIEWPORT=Viewport
IDS_MSG_ALLOWSYOUTOJOINADIFFERENT=Allows you to join a different team.
IDS_MSG_ANTIALIASING_DESC=Set FSAA (MultiSampling) level
IDS_MSG_ANUPDATETOVERSIONISAVAILA=A new update is available. Do you want to download and install this update?
IDS_MSG_AUTOFRAMESKIP=Automatic frame skip
IDS_MSG_AUTOWINDOWED=Automatic
IDS_MSG_BACKTOPLAYERDLG=Back to player selection.
IDS_MSG_CANNOTSTARTSCENARIO=Cannot start scenario.

View File

@ -114,6 +114,7 @@ void C4ConfigGraphics::CompileFunc(StdCompiler *pComp)
pComp->Value(mkNamingAdapt(NoOffscreenBlits, "NoOffscreenBlits", 1 ));
pComp->Value(mkNamingAdapt(ClipManuallyE, "ClipManuallyE", 1 ));
pComp->Value(mkNamingAdapt(MultiSampling, "MultiSampling", 4 ));
pComp->Value(mkNamingAdapt(AutoFrameSkip, "AutoFrameSkip", true ));
}
void C4ConfigSound::CompileFunc(StdCompiler *pComp)

View File

@ -117,6 +117,7 @@ public:
int32_t ClipManuallyE; // do manual clipping in the easy cases
int32_t NoOffscreenBlits; // if set, all blits to non-primary-surfaces are emulated
int32_t MultiSampling; // multisampling samples
int32_t AutoFrameSkip; // if true, gfx frames are skipped when they would slow down the game
void CompileFunc(StdCompiler *pComp);
};

View File

@ -452,6 +452,9 @@ bool C4GameParameters::Load(C4Group &hGroup, C4Scenario *pScenario, const char *
// network game?
IsNetworkGame = Game.NetworkActive;
// Auto frame skip by options
AutoFrameSkip = ::Config.Graphics.AutoFrameSkip;
}
@ -505,9 +508,10 @@ void C4GameParameters::CompileFunc(StdCompiler *pComp, C4Scenario *pScenario)
pComp->Value(mkNamingAdapt(AllowDebug, "AllowDebug", true));
pComp->Value(mkNamingAdapt(IsNetworkGame, "IsNetworkGame", false));
pComp->Value(mkNamingAdapt(ControlRate, "ControlRate", -1));
pComp->Value(mkNamingAdapt(AutoFrameSkip, "AutoFrameSkip", false));
pComp->Value(mkNamingAdapt(Rules, "Rules", !pScenario ? C4IDList() : pScenario->Game.Rules));
pComp->Value(mkNamingAdapt(Goals, "Goals", !pScenario ? C4IDList() : pScenario->Game.Goals));
pComp->Value(mkNamingAdapt(League, "League", StdStrBuf()));
pComp->Value(mkNamingAdapt(League, "League", StdStrBuf()));
// These values are either stored separately (see Load/Save) or
// don't make sense for savegames.

View File

@ -115,6 +115,9 @@ public:
// Control rate
int32_t ControlRate;
// Automatic frame skip enabled for this game?
bool AutoFrameSkip;
// Allow debug mode?
bool AllowDebug;

View File

@ -681,7 +681,6 @@ void C4Application::GameTick()
// Game
if (Game.IsRunning)
Game.Execute();
Game.DoSkipFrame = false;
// Sound
SoundSystem.Execute();
// Gamepad
@ -693,15 +692,13 @@ void C4Application::GameTick()
void C4Application::Draw()
{
// Graphics
if (!Game.DoSkipFrame)
{
// Fullscreen mode
if (!isEditor)
FullScreen.Execute();
// Console mode
else
Console.Execute();
}
// Fullscreen mode
if (!isEditor)
FullScreen.Execute();
// Console mode
else
Console.Execute();
}
void C4Application::SetGameTickDelay(int iDelay)
@ -836,26 +833,28 @@ bool C4Application::FullScreenMode()
C4ApplicationGameTimer::C4ApplicationGameTimer()
: CStdMultimediaTimerProc(26),
tLastGameTick(C4TimeMilliseconds::NegativeInfinity), iGameTickDelay(0)
tLastGameTick(C4TimeMilliseconds::NegativeInfinity), iGameTickDelay(28), iExtraGameTickDelay(0)
{
}
void C4ApplicationGameTimer::SetGameTickDelay(uint32_t iDelay)
{
// Remember delay
iGameTickDelay = iDelay;
// Smaller than minimum refresh delay?
if (iDelay < uint32_t(Config.Graphics.MaxRefreshDelay))
{
// Set critical timer
SetDelay(iDelay);
// No additional breaking needed
iGameTickDelay = 0;
iExtraGameTickDelay = 0;
}
else
{
// Set critical timer
SetDelay(Config.Graphics.MaxRefreshDelay);
// Slow down game tick
iGameTickDelay = iDelay;
iExtraGameTickDelay = iDelay;
}
}
@ -865,9 +864,9 @@ bool C4ApplicationGameTimer::Execute(int iTimeout, pollfd *)
if (!CheckAndReset()) return true;
C4TimeMilliseconds tNow = C4TimeMilliseconds::Now();
// Execute
if (tNow >= tLastGameTick + iGameTickDelay || Game.GameGo)
if (tNow >= tLastGameTick + iExtraGameTickDelay || Game.GameGo)
{
if(iGameTickDelay)
if (iGameTickDelay)
tLastGameTick += iGameTickDelay;
else
tLastGameTick = tNow;
@ -878,8 +877,18 @@ bool C4ApplicationGameTimer::Execute(int iTimeout, pollfd *)
Application.GameTick();
}
// Draw always
Application.Draw();
// Draw
if (!Game.DoSkipFrame)
{
C4TimeMilliseconds tPreGfxTime = C4TimeMilliseconds::Now();
Application.Draw();
// Automatic frame skip if graphics are slowing down the game (skip max. every 2nd frame)
Game.DoSkipFrame = Game.Parameters.AutoFrameSkip && (tPreGfxTime + iGameTickDelay < C4TimeMilliseconds::Now());
} else {
Game.DoSkipFrame=false;
}
return true;
}

View File

@ -110,6 +110,7 @@ public:
private:
C4TimeMilliseconds tLastGameTick;
unsigned int iGameTickDelay;
unsigned int iExtraGameTickDelay;
public:
void SetGameTickDelay(uint32_t iDelay);

View File

@ -834,7 +834,7 @@ C4StartupOptionsDlg::C4StartupOptionsDlg() : C4StartupDlg(LoadResStrNoAmp("IDS_D
pCombo->SetText(GetWindowedName());
pGroupResolution->AddElement(pCombo);
// --subgroup options
iNumGfxOptions = 4, iOpt=0;
iNumGfxOptions = 5, iOpt=0;
C4GUI::GroupBox *pGroupOptions = new C4GUI::GroupBox(caSheetGraphics.GetGridCell(0,2,1,2));
pGroupOptions->SetTitle(LoadResStrNoAmp("IDS_DLG_OPTIONS"));
pGroupOptions->SetFont(pUseFont);
@ -881,6 +881,11 @@ C4StartupOptionsDlg::C4StartupOptionsDlg() : C4StartupDlg(LoadResStrNoAmp("IDS_D
pCheck->SetToolTip(LoadResStr("IDS_MSG_HIGHRESLANDSCAPE_DESC"));
pCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled);
pGroupOptions->AddElement(pCheck);
// automatic gfx frame skip
pCheck = new BoolConfig(caGroupOptions.GetGridCell(0,1,iOpt++,iNumGfxOptions,-1,iCheckHgt,true), LoadResStr("IDS_MSG_AUTOFRAMESKIP"), NULL, &Config.Graphics.AutoFrameSkip);
pCheck->SetToolTip(LoadResStr("IDS_DESC_AUTOFRAMESKIP"));
pCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled);
pGroupOptions->AddElement(pCheck);
// --subgroup effects
C4GUI::GroupBox *pGroupEffects = new C4GUI::GroupBox(caSheetGraphics.GetGridCell(1,2,1,2));
pGroupEffects->SetTitle(LoadResStrNoAmp("IDS_CTL_SMOKE"));