- transitioned Duke to the new main loop.

Everything compiles, but hasn't been tested. Doing a safety commit first.
This commit is contained in:
Christoph Oelckers 2020-08-30 12:02:32 +02:00
parent 0c455acaa2
commit d59284c96b
15 changed files with 89 additions and 345 deletions

View file

@ -1972,6 +1972,12 @@ void Net_SkipCommand (int type, uint8_t **stream)
#endif
}
void Net_ClearFifo(void)
{
// Q: Do we need this?
}
// This was taken out of shared_hud, because UI code shouldn't do low level calculations that may change if the backing implementation changes.
int Net_GetLatency(int *ld, int *ad)
{

View file

@ -55,6 +55,8 @@ void Net_ClearBuffers ();
bool D_CheckNetGame(void);
void Net_ClearFifo(void);
// Netgame stuff (buffers and pointers, i.e. indices).

View file

@ -101,7 +101,7 @@ int lastTic;
int automapMode;
bool automapFollow;
extern int pauseext;
extern bool pauseext;
CCMD(togglemap)
{
@ -863,7 +863,13 @@ int RunGame()
SetupGameButtons();
gi->app_init();
app_loop();
// Duke has transitioned to the new main loop, the other games haven't yet.
if (g_gameType & GAMEFLAG_DUKE | GAMEFLAG_RRALL | GAMEFLAG_NAM | GAMEFLAG_NAPALM | GAMEFLAG_WW2GI)
{
D_CheckNetGame();
MainLoop();
}
else app_loop();
return 0; // this is never reached. app_loop only exits via exception.
}
@ -1246,3 +1252,18 @@ CCMD(taunt)
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void startmainmenu()
{
gamestate = GS_MENUSCREEN;
M_StartControlPanel(false);
M_SetMenu(NAME_Mainmenu);
FX_StopAllSounds();
}

View file

@ -8,12 +8,14 @@
#include "tarray.h"
#include "name.h"
#include "memarena.h"
#include "stats.h"
extern FString currentGame;
extern FString LumpFilter;
class FArgs;
extern bool GUICapture;
extern bool AppActive;
extern cycle_t drawtime, actortime, thinktime, gameupdatetime;
extern FMemArena dump; // this is for memory blocks than cannot be deallocated without some huge effort. Put them in here so that they do not register on shutdown.
@ -46,6 +48,7 @@ void CONFIG_ReadCombatMacros();
int32_t CONFIG_GetMapBestTime(char const* const mapname, uint8_t const* const mapmd4);
int CONFIG_SetMapBestTime(uint8_t const* const mapmd4, int32_t tm);
int GameMain();
void startmainmenu();
struct UserConfig
{

View file

@ -60,7 +60,6 @@ struct GameInterface
virtual ~GameInterface() {}
virtual bool GenerateSavePic() { return false; }
virtual void app_init() = 0;
virtual void RunGameFrame() = 0;
virtual void clearlocalinputstate() {}
virtual void UpdateScreenSize() {}
virtual void FreeGameData() {}
@ -101,6 +100,8 @@ struct GameInterface
virtual void Ticker() {}
virtual int GetPlayerChecksum(int pnum) { return 0x12345678 + pnum; }
virtual void RunGameFrame() {} // this must go away once things are done.
};

View file

@ -81,6 +81,7 @@
#include "v_video.h"
#include "glbackend/glbackend.h"
#include "palette.h"
#include "build.h"
CVAR(Bool, vid_activeinbackground, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CVAR(Bool, r_ticstability, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
@ -183,11 +184,15 @@ static void GameTicker()
{
default:
case GS_STARTUP:
artClearMapArt();
gi->Startup();
break;
case GS_LEVEL:
gameupdatetime.Reset();
gameupdatetime.Clock();
gi->Ticker();
gameupdatetime.Unclock();
break;
case GS_MENUSCREEN:
@ -371,7 +376,10 @@ void TryRunTics (void)
gi->Predict(myconnectindex);
#endif
}
gi->GetInput(nullptr);
if (!cl_syncinput)
{
gi->GetInput(nullptr);
}
return;
}

View file

@ -89,7 +89,6 @@ void CheckKeys2();
void GameTicker();
void InitLevel(int);
void InitNewGame();
void startmainmenu();
int showmap(short nLevel, short nLevelNew, short nLevelBest);
void menu_DoPlasma();

View file

@ -136,20 +136,6 @@ static void GameDisplay(void)
//
//---------------------------------------------------------------------------
void startmainmenu()
{
gamestate = GS_MENUSCREEN;
M_StartControlPanel(false);
M_SetMenu(NAME_Mainmenu);
StopAllSounds();
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void drawmenubackground()
{
auto nLogoTile = EXHUMED ? kExhumedLogo : kPowerslaveLogo;

View file

@ -361,8 +361,7 @@ void GameInterface::DrawPlayerSprite(const DVector2& origin, bool onteam)
void GameInterface::QuitToTitle()
{
ps[myconnectindex].gm = MODE_DEMO;
artClearMapArt();
gamestate = GS_STARTUP;
}
END_DUKE_NS

View file

@ -22,8 +22,6 @@
#include "stats.h"
#include "binaryangle.h"
extern cycle_t drawtime, actortime, thinktime, gameupdatetime;
BEGIN_DUKE_NS
extern FFont* IndexFont;
@ -33,7 +31,6 @@ struct GameInterface : public ::GameInterface
{
const char* Name() override { return "Duke"; }
void app_init() override;
void RunGameFrame() override;
void clearlocalinputstate() override;
bool GenerateSavePic() override;
void PlayHudSound() override;

View file

@ -193,7 +193,6 @@ void resetinventory(int pn);
void resetplayerstats(int pn);
void resetweapons(int pn);
void resetprestat(int snum, int g);
void clearfifo(void);
void prelevel_common(int g);
void cacheit_d();
void cacheit_r();
@ -234,7 +233,6 @@ void apply_seasick(player_struct* p, double scalefactor);
void calcviewpitch(player_struct* p, double factor);
void sethorizon(int snum, ESyncBits actions, double factor, fixed_t adjustment);
bool movementBlocked(int snum);
void startmainmenu();
void loadcons();
void updateinterpolations();

View file

@ -175,7 +175,7 @@ void FTA(int q, struct player_struct* p)
//
//==========================================================================
void drawbackground(void)
void GameInterface::DrawBackground()
{
twod->ClearScreen();
auto tex = tileGetTexture(TILE_MENUSCREEN);

View file

@ -38,149 +38,14 @@ Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au)
BEGIN_DUKE_NS
//---------------------------------------------------------------------------
//
// abstract the queue's implementation
// All access to the input queues should go through this function interface.
//
//---------------------------------------------------------------------------
static InputPacket inputfifo[MOVEFIFOSIZ][MAXPLAYERS];
static int movefifoend[MAXPLAYERS];
static int movefifoplc;
static int bufferjitter;
void clearfifo(void)
{
memset(&inputfifo, 0, sizeof(inputfifo));
memset(sync, 0, sizeof(sync));
}
static inline void GetNextInput()
{
for (int i = connecthead; i >= 0; i = connectpoint2[i])
memcpy(&sync[i], &inputfifo[movefifoplc & (MOVEFIFOSIZ - 1)][i], sizeof(InputPacket));
movefifoplc++;
}
static void advancequeue(int myconnectindex)
{
movefifoend[myconnectindex]++;
}
static InputPacket& nextinput(int myconnectindex)
{
return inputfifo[movefifoend[myconnectindex] & (MOVEFIFOSIZ - 1)][myconnectindex];
}
bool shouldprocessinput(int myconnectindex)
{
if (movefifoend[myconnectindex] - movefifoplc > bufferjitter)
{
int i;
for (i = connecthead; i >= 0; i = connectpoint2[i])
if (movefifoplc == movefifoend[i]) return false;
if (i >= 0) return false;
return true;
}
return false;
}
static void fakedomovethings()
{
// prediction
}
static void fakedomovethingscorrect()
{
// unprediction
}
void prediction()
{
#if 0
// We currently have no net code driving this.
if (numplayers > 1)
while (fakemovefifoplc < movefifoend[myconnectindex]) fakedomovethings();
getpackets();
#endif
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
/*
void mploadsave()
{
for(int i=connecthead;i>=0;i=connectpoint2[i])
if( sync[i].bits&(1<<17) )
{
multiflag = 2;
multiwhat = (sync[i].bits>>18)&1;
multipos = (unsigned) (sync[i].bits>>19)&15;
multiwho = i;
if( multiwhat )
{
saveplayer( multipos );
multiflag = 0;
if(multiwho != myconnectindex)
{
strcpy(&fta_quotes[122],&ud.user_name[multiwho][0]);
strcat(&fta_quotes[122]," SAVED A MULTIPLAYER GAME");
FTA(122,&ps[myconnectindex]);
}
else
{
strcpy(&fta_quotes[122],"MULTIPLAYER GAME SAVED");
FTA(122,&ps[myconnectindex]);
}
break;
}
else
{
// waitforeverybody();
j = loadplayer( multipos );
multiflag = 0;
if(j == 0 && !isRR())
{
if(multiwho != myconnectindex)
{
strcpy(&fta_quotes[122],&ud.user_name[multiwho][0]);
strcat(&fta_quotes[122]," LOADED A MULTIPLAYER GAME");
FTA(122,&ps[myconnectindex]);
}
else
{
strcpy(&fta_quotes[122],"MULTIPLAYER GAME LOADED");
FTA(122,&ps[myconnectindex]);
}
return 1;
}
}
}
}
*/
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
int domovethings()
void GameInterface::Ticker()
{
int i;
// mplpadsave();
ud.camerasprite = -1;
if (earthquaketime > 0) earthquaketime--;
@ -192,51 +57,15 @@ int domovethings()
}
everyothertime++;
GetNextInput();
updateinterpolations();
#if 0
j = -1;
for (i = connecthead; i >= 0; i = connectpoint2[i])
{
if (PlayerInput(i, SKB_GAMEQUIT))
{
if (i == myconnectindex) gameexitfrommenu();
if (screenpeek == i)
{
screenpeek = connectpoint2[i];
if (screenpeek < 0) screenpeek = connecthead;
}
if (i == connecthead) connecthead = connectpoint2[connecthead];
else connectpoint2[j] = connectpoint2[i];
numplayers--;
ud.multimode--;
//closedemowrite();
if (numplayers < 2 && !isRR())
S_PlaySound(GENERIC_AMBIENCE17, CHAN_AUTO, CHANF_UI);
Printf(PRINT_NOTIFY, "%s is history!", ud.user_name[i]);
quickkill(&ps[i]);
deletesprite(ps[i].i);
}
else j = i;
}
#endif
//if(ud.recstat == 1) record();
if (playrunning())
{
global_random = krand();
movedummyplayers();//ST 13
}
for (i = connecthead; i >= 0; i = connectpoint2[i])
for (int i = connecthead; i >= 0; i = connectpoint2[i])
{
if (playrunning())
{
@ -258,8 +87,6 @@ int domovethings()
fi.think();
}
fakedomovethingscorrect();
if ((everyothertime & 1) == 0)
{
fi.animatewalls();
@ -269,80 +96,11 @@ int domovethings()
if (isRR() && ud.recstat == 0 && ud.multimode < 2)
dotorch();
return 0;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void GameTicker()
{
if (ps[myconnectindex].gm == MODE_DEMO)
{
M_ClearMenus();
gamestate = GS_STARTUP;
return;
}
//Net_GetPackets();
gameupdatetime.Reset();
gameupdatetime.Clock();
int const currentTic = I_GetTime();
gameclock = I_GetBuildTime() - gameclockstart;
while (playrunning() && currentTic - lastTic >= 1)
{
lastTic = currentTic;
auto& input = nextinput(myconnectindex);
gi->GetInput(&input);
advancequeue(myconnectindex);
if (playrunning())
{
prediction();
if (numplayers < 2) bufferjitter = 0;
while (shouldprocessinput(myconnectindex))
{
if (domovethings()) break;
}
}
}
gameupdatetime.Unclock();
if (ps[myconnectindex].gm & (MODE_EOL | MODE_RESTART))
{
exitlevel();
}
if (!cl_syncinput)
{
gi->GetInput(nullptr);
}
nonsharedkeys();
gi->UpdateSounds();
drawtime.Reset();
drawtime.Clock();
videoSetBrightness(thunder_brightness);
double const smoothRatio = playrunning() ? I_GetTimeFrac() * MaxSmoothRatio : MaxSmoothRatio;
displayrooms(screenpeek, smoothRatio);
drawoverlays(smoothRatio);
drawtime.Unclock();
if (ps[myconnectindex].gm == MODE_DEMO)
{
gamestate = GS_STARTUP;
}
nonsharedkeys();
}
//---------------------------------------------------------------------------
@ -351,14 +109,6 @@ void GameTicker()
//
//---------------------------------------------------------------------------
void startmainmenu()
{
gamestate = GS_MENUSCREEN;
M_StartControlPanel(false);
M_SetMenu(NAME_Mainmenu);
FX_StopAllSounds();
}
void resetGameClock()
{
I_SetFrameTime();
@ -367,33 +117,6 @@ void resetGameClock()
cloudclock = 0;
}
static void Startup()
{
resetGameClock();
ps[myconnectindex].ftq = 0;
if (userConfig.CommandMap.IsNotEmpty())
{
auto maprecord = FindMapByName(userConfig.CommandMap);
userConfig.CommandMap = "";
if (maprecord)
{
ud.m_respawn_monsters = ud.m_player_skill == 4;
for (int i = 0; i != -1; i = connectpoint2[i])
{
resetweapons(i);
resetinventory(i);
}
startnewgame(maprecord, /*userConfig.skill*/2);
}
}
else
{
fi.ShowLogo([](bool) { startmainmenu(); });
}
}
//---------------------------------------------------------------------------
//
//
@ -402,47 +125,48 @@ static void Startup()
void GameInterface::Startup()
{
resetGameClock();
ps[myconnectindex].ftq = 0;
}
void GameInterface::DrawBackground()
{
}
void GameInterface::Render()
{
}
void GameInterface::Ticker()
{
}
void GameInterface::RunGameFrame()
{
switch (gamestate)
if (userConfig.CommandMap.IsNotEmpty())
{
default:
case GS_STARTUP:
Startup();
break;
case GS_MENUSCREEN:
case GS_FULLCONSOLE:
drawbackground();
break;
case GS_LEVEL:
GameTicker();
break;
case GS_INTERMISSION:
case GS_INTRO:
RunScreenJobFrame();
break;
auto maprecord = FindMapByName(userConfig.CommandMap);
userConfig.CommandMap = "";
if (maprecord)
{
ud.m_respawn_monsters = ud.m_player_skill == 4;
for (int i = 0; i != -1; i = connectpoint2[i])
{
resetweapons(i);
resetinventory(i);
}
startnewgame(maprecord, /*userConfig.skill*/2);
}
}
else
{
fi.ShowLogo([](bool) { startmainmenu(); });
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void GameInterface::Render()
{
drawtime.Reset();
drawtime.Clock();
videoSetBrightness(thunder_brightness);
double const smoothRatio = playrunning() ? I_GetTimeFrac() * MaxSmoothRatio : MaxSmoothRatio;
displayrooms(screenpeek, smoothRatio);
drawoverlays(smoothRatio);
drawtime.Unclock();
}
END_DUKE_NS

View file

@ -1013,7 +1013,7 @@ int enterlevel(MapRecord *mi, int gamemode)
global_random = 0;
ud.last_level = currentLevel->levelNumber;
clearfifo();
Net_ClearFifo();
for (int i=numinterpolations-1; i>=0; i--) bakipos[i] = *curipos[i];
ps[myconnectindex].over_shoulder_on = 0;
clearfrags();

View file

@ -520,7 +520,7 @@ void GameInterface::SerializeGameState(FSerializer& arc)
recreateinterpolations();
show_shareware = 0;
everyothertime = 0;
clearfifo();
Net_ClearFifo();
// should be unnecessary with the sounds getting serialized as well.
#if 0