- transitioned Exhumed to the new main loop.

Fixed #301
This commit is contained in:
Christoph Oelckers 2020-09-02 22:55:57 +02:00
parent b1a3080671
commit b49e050baf
13 changed files with 191 additions and 179 deletions

View file

@ -863,13 +863,8 @@ int RunGame()
enginePostInit(); // This must not be done earlier! enginePostInit(); // This must not be done earlier!
videoInit(); videoInit();
// Duke has transitioned to the new main loop, the other games haven't yet. D_CheckNetGame();
if (!(g_gameType & (GAMEFLAG_PSEXHUMED))) MainLoop();
{
D_CheckNetGame();
MainLoop();
}
else app_loop();
return 0; // this is never reached. app_loop only exits via exception. return 0; // this is never reached. app_loop only exits via exception.
} }

View file

@ -223,11 +223,5 @@ enum AM_Mode
extern int automapMode; extern int automapMode;
extern bool automapFollow; extern bool automapFollow;
extern bool sendPause; extern bool sendPause;
extern int gameclock;
extern uint64_t gameclockstart;
extern int lastTic; extern int lastTic;
inline void updateGameClock()
{
gameclock = static_cast<int>((I_GetTimeNS() - gameclockstart) * 120 / 1'000'000'000);
}

View file

@ -194,7 +194,6 @@ static void GameTicker()
case GS_LEVEL: case GS_LEVEL:
gameupdatetime.Reset(); gameupdatetime.Reset();
gameupdatetime.Clock(); gameupdatetime.Clock();
updateGameClock();
gi->Ticker(); gi->Ticker();
gameupdatetime.Unclock(); gameupdatetime.Unclock();
break; break;
@ -249,7 +248,6 @@ void Display()
twod->Clear(); twod->Clear();
twod->SetSize(screen->GetWidth(), screen->GetHeight()); twod->SetSize(screen->GetWidth(), screen->GetHeight());
twodpsp.SetSize(screen->GetWidth(), screen->GetHeight()); twodpsp.SetSize(screen->GetWidth(), screen->GetHeight());
updateGameClock();
gi->Render(); gi->Render();
DrawFullscreenBlends(); DrawFullscreenBlends();
} }

View file

@ -30,18 +30,12 @@ BEGIN_PS_NS
void resettiming() void resettiming()
{ {
gameclock = 0;
lastTic = -1; lastTic = -1;
} }
void doTileLoad(int i) void doTileLoad(int i)
{ {
tileLoad(i);
#ifdef USE_OPENGL
if (r_precache) PrecacheHardwareTextures(i); if (r_precache) PrecacheHardwareTextures(i);
#endif
} }
void precache() void precache()

View file

@ -373,6 +373,8 @@ double calc_smoothratio()
return I_GetTimeFrac() * MaxSmoothRatio; return I_GetTimeFrac() * MaxSmoothRatio;
} }
void CheckProgression();
void GameMove(void) void GameMove(void)
{ {
FixPalette(); FixPalette();
@ -444,10 +446,133 @@ static int SelectAltWeapon(int weap2)
return 0; return 0;
} }
void GameInterface::Ticker()
{
if (!paused)
{
nPlayerDAng += localInput.q16avel;
inita &= kAngleMask;
for (int i = 0; i < 4; i++)
{
lPlayerXVel += localInput.fvel * Cos(inita) + localInput.svel * Sin(inita);
lPlayerYVel += localInput.fvel * Sin(inita) - localInput.svel * Cos(inita);
lPlayerXVel -= (lPlayerXVel >> 5) + (lPlayerXVel >> 6);
lPlayerYVel -= (lPlayerYVel >> 5) + (lPlayerYVel >> 6);
}
int weap2 = localInput.getNewWeapon();
if (weap2 == WeaponSel_Next)
{
weap2 = SelectNextWeapon(weap2);
}
else if (weap2 == WeaponSel_Prev)
{
weap2 = SelectPrevWeapon(weap2);
}
else if (weap2 == WeaponSel_Alt)
{
weap2 = SelectAltWeapon(weap2);
}
if (localInput.actions & SB_INVPREV)
{
int nItem = nPlayerItem[nLocalPlayer];
int i;
for (i = 6; i > 0; i--)
{
nItem--;
if (nItem < 0) nItem = 5;
if (PlayerList[nLocalPlayer].items[nItem] != 0)
break;
}
if (i > 0) SetPlayerItem(nLocalPlayer, nItem);
}
if (localInput.actions & SB_INVNEXT)
{
int nItem = nPlayerItem[nLocalPlayer];
int i;
for (i = 6; i > 0; i--)
{
nItem++;
if (nItem == 6) nItem = 0;
if (PlayerList[nLocalPlayer].items[nItem] != 0)
break;
}
if (i > 0) SetPlayerItem(nLocalPlayer, nItem);
}
if (localInput.actions & SB_INVUSE)
{
if (nPlayerItem[nLocalPlayer] != -1)
{
localInput.setItemUsed(nPlayerItem[nLocalPlayer]);
}
}
for (int i = 0; i < 6; i++)
{
if (localInput.isItemUsed(i))
{
localInput.clearItemUsed(i);
if (PlayerList[nLocalPlayer].items[i] > 0)
{
if (nItemMagic[i] <= PlayerList[nLocalPlayer].nMagic)
{
sPlayerInput[nLocalPlayer].nItem = i;
break;
}
}
}
}
if (localInput.actions & SB_CENTERVIEW)
{
bLockPan = false;
bPlayerPan = false;
//PlayerList[nLocalPlayer].q16horiz = IntToFixed(92);
nDestVertPan[nLocalPlayer] = IntToFixed(92);
}
if (localInput.actions & SB_TURNAROUND)
{
// todo
}
sPlayerInput[nLocalPlayer].xVel = lPlayerXVel;
sPlayerInput[nLocalPlayer].yVel = lPlayerYVel;
// make weapon selection persist until it gets used up.
sPlayerInput[nLocalPlayer].buttons = lLocalCodes;
int weap = sPlayerInput[nLocalPlayer].getNewWeapon();
sPlayerInput[nLocalPlayer].actions = localInput.actions;
if (weap2 <= 0 || weap2 > 7) sPlayerInput[nLocalPlayer].SetNewWeapon(weap);
sPlayerInput[nLocalPlayer].nTarget = besttarget;
Ra[nLocalPlayer].nTarget = besttarget;
lLocalCodes = 0;
nPlayerDAng = 0;
sPlayerInput[nLocalPlayer].horizon = PlayerList[nLocalPlayer].q16horiz;
leveltime++;
GameMove();
r_NoInterpolate = false;
}
else r_NoInterpolate = true;
CheckProgression(); // todo: Get rid of this.
}
void GameTicker() void GameTicker()
{ {
int const currentTic = I_GetTime(); int const currentTic = I_GetTime();
gameclock = I_GetBuildTime();
if (paused) if (paused)
{ {
@ -461,122 +586,7 @@ void GameTicker()
while (!EndLevel && currentTic - lastTic >= 1) while (!EndLevel && currentTic - lastTic >= 1)
{ {
lastTic = currentTic; lastTic = currentTic;
gi->Ticker();
PlayerInterruptKeys(false);
nPlayerDAng += localInput.q16avel;
inita &= kAngleMask;
for (int i = 0; i < 4; i++)
{
lPlayerXVel += localInput.fvel * Cos(inita) + localInput.svel * Sin(inita);
lPlayerYVel += localInput.fvel * Sin(inita) - localInput.svel * Cos(inita);
lPlayerXVel -= (lPlayerXVel >> 5) + (lPlayerXVel >> 6);
lPlayerYVel -= (lPlayerYVel >> 5) + (lPlayerYVel >> 6);
}
int weap2 = localInput.getNewWeapon();
if (weap2 == WeaponSel_Next)
{
weap2 = SelectNextWeapon(weap2);
}
else if (weap2 == WeaponSel_Prev)
{
weap2 = SelectPrevWeapon(weap2);
}
else if (weap2 == WeaponSel_Alt)
{
weap2 = SelectAltWeapon(weap2);
}
if (localInput.actions & SB_INVPREV)
{
int nItem = nPlayerItem[nLocalPlayer];
int i;
for (i = 6; i > 0; i--)
{
nItem--;
if (nItem < 0) nItem = 5;
if (PlayerList[nLocalPlayer].items[nItem] != 0)
break;
}
if (i > 0) SetPlayerItem(nLocalPlayer, nItem);
}
if (localInput.actions & SB_INVNEXT)
{
int nItem = nPlayerItem[nLocalPlayer];
int i;
for (i = 6; i > 0; i--)
{
nItem++;
if (nItem == 6) nItem = 0;
if (PlayerList[nLocalPlayer].items[nItem] != 0)
break;
}
if (i > 0) SetPlayerItem(nLocalPlayer, nItem);
}
if (localInput.actions & SB_INVUSE)
{
if (nPlayerItem[nLocalPlayer] != -1)
{
localInput.setItemUsed(nPlayerItem[nLocalPlayer]);
}
}
for (int i = 0; i < 6; i++)
{
if (localInput.isItemUsed(i))
{
localInput.clearItemUsed(i);
if (PlayerList[nLocalPlayer].items[i] > 0)
{
if (nItemMagic[i] <= PlayerList[nLocalPlayer].nMagic)
{
sPlayerInput[nLocalPlayer].nItem = i;
break;
}
}
}
}
if (localInput.actions & SB_CENTERVIEW)
{
bLockPan = false;
bPlayerPan = false;
//PlayerList[nLocalPlayer].q16horiz = IntToFixed(92);
nDestVertPan[nLocalPlayer] = IntToFixed(92);
}
if (localInput.actions & SB_TURNAROUND)
{
// todo
}
sPlayerInput[nLocalPlayer].xVel = lPlayerXVel;
sPlayerInput[nLocalPlayer].yVel = lPlayerYVel;
// make weapon selection persist until it gets used up.
sPlayerInput[nLocalPlayer].buttons = lLocalCodes;
int weap = sPlayerInput[nLocalPlayer].getNewWeapon();
sPlayerInput[nLocalPlayer].actions = localInput.actions;
if (weap2 <= 0 || weap2 > 7) sPlayerInput[nLocalPlayer].SetNewWeapon(weap);
sPlayerInput[nLocalPlayer].nTarget = besttarget;
Ra[nLocalPlayer].nTarget = besttarget;
lLocalCodes = 0;
nPlayerDAng = 0;
sPlayerInput[nLocalPlayer].horizon = PlayerList[nLocalPlayer].q16horiz;
leveltime++;
GameMove();
} }
gameupdatetime.Unclock(); gameupdatetime.Unclock();

View file

@ -197,7 +197,7 @@ public:
void ComputeCinemaText(); void ComputeCinemaText();
void ReadyCinemaText(uint16_t nVal); void ReadyCinemaText(uint16_t nVal);
void DisplayText(); void DisplayText();
bool AdvanceCinemaText(int gameclock); bool AdvanceCinemaText(int clock);
}; };
@ -250,6 +250,11 @@ struct GameInterface : ::GameInterface
void QuitToTitle() override; void QuitToTitle() override;
void UpdateSounds() override; void UpdateSounds() override;
void ErrorCleanup() override; void ErrorCleanup() override;
void Ticker() override;
void DrawBackground() override;
void Render() override;
void GetInput(InputPacket* packet) override;
void Startup() override;
::GameStats getStats() override; ::GameStats getStats() override;
}; };

View file

@ -50,6 +50,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
BEGIN_PS_NS BEGIN_PS_NS
void CheckProgression();
short nBestLevel; short nBestLevel;
static int32_t nonsharedtimer; static int32_t nonsharedtimer;
@ -114,8 +116,9 @@ static void showmap(short nLevel, short nLevelNew, short nLevelBest, TArray<JobD
} }
static void GameDisplay(void) void GameInterface::Render()
{ {
CheckKeys2();
drawtime.Reset(); drawtime.Reset();
drawtime.Clock(); drawtime.Clock();
@ -142,8 +145,9 @@ static void GameDisplay(void)
// //
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckProgression();
void drawmenubackground() void GameInterface::DrawBackground()
{ {
auto nLogoTile = EXHUMED ? kExhumedLogo : kPowerslaveLogo; auto nLogoTile = EXHUMED ? kExhumedLogo : kPowerslaveLogo;
int dword_9AB5F = (I_GetBuildTime() / 16) & 3; int dword_9AB5F = (I_GetBuildTime() / 16) & 3;
@ -157,7 +161,7 @@ void drawmenubackground()
// draw the fire urn/lamp thingies // draw the fire urn/lamp thingies
DrawRel(kTile3512 + dword_9AB5F, 50, 150, 32); DrawRel(kTile3512 + dword_9AB5F, 50, 150, 32);
DrawRel(kTile3512 + ((dword_9AB5F + 2) & 3), 270, 150, 32); DrawRel(kTile3512 + ((dword_9AB5F + 2) & 3), 270, 150, 32);
CheckProgression();
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -251,10 +255,31 @@ void GameLoop()
GameTicker(); GameTicker();
PlayerInterruptKeys(true); PlayerInterruptKeys(true);
gi->UpdateSounds(); gi->UpdateSounds();
CheckKeys2();
} }
void GameInterface::Startup()
{
resettiming();
GameAction = -1;
EndLevel = false;
if (userConfig.CommandMap.IsNotEmpty())
{
/*
auto map = FindMapByName(userConfig.CommandMap);
if (map) GameAction = map->levelNumber;
userConfig.CommandMap = "";
goto again;
*/
}
else
{
DoTitle([](bool) { startmainmenu(); });
}
}
void GameInterface::RunGameFrame() void GameInterface::RunGameFrame()
{ {
again: again:
@ -263,31 +288,16 @@ void GameInterface::RunGameFrame()
{ {
default: default:
case GS_STARTUP: case GS_STARTUP:
resettiming();
GameAction = -1;
EndLevel = false;
if (userConfig.CommandMap.IsNotEmpty())
{
auto map = FindMapByName(userConfig.CommandMap);
if (map) GameAction = map->levelNumber;
userConfig.CommandMap = "";
goto again;
}
else
{
DoTitle([](bool) { startmainmenu(); });
}
break; break;
case GS_MENUSCREEN: case GS_MENUSCREEN:
case GS_FULLCONSOLE: case GS_FULLCONSOLE:
drawmenubackground(); gi->DrawBackground();
break; break;
case GS_LEVEL: case GS_LEVEL:
GameLoop(); GameLoop();
GameDisplay(); gi->Render();
break; break;
case GS_INTERMISSION: case GS_INTERMISSION:

View file

@ -325,4 +325,10 @@ void PlayerInterruptKeys(bool after)
} }
void GameInterface::GetInput(InputPacket* packet)
{
PlayerInterruptKeys(packet == nullptr);
if (packet) *packet = localInput;
}
END_PS_NS END_PS_NS

View file

@ -434,7 +434,7 @@ static void G_DrawOverheadMap(int32_t cposx, int32_t cposy, int32_t czoom, int16
if (p == screenpeek || GTFLAGS(GAMETYPE_OTHERPLAYERSINMAP)) if (p == screenpeek || GTFLAGS(GAMETYPE_OTHERPLAYERSINMAP))
{ {
if (pSprite->xvel > 16 && pPlayer->on_ground) if (pSprite->xvel > 16 && pPlayer->on_ground)
i = APLAYERTOP+(((int32_t) gameclock>>4)&3); i = APLAYERTOP+(((int32_t) leveltime>>4)&3);
else else
i = APLAYERTOP; i = APLAYERTOP;

View file

@ -1492,7 +1492,7 @@ void DimLights()
void DoFinale() void DoFinale()
{ {
static int dword_96788 = 0; static int dword_96788 = 0;
static int dword_1542FC = 0; static int nextstage = 0;
if (!lFinaleStart) if (!lFinaleStart)
return; return;
@ -1529,20 +1529,20 @@ void DoFinale()
{ {
StopLocalSound(); StopLocalSound();
PlayLocalSound(StaticSound[kSound76], 0); PlayLocalSound(StaticSound[kSound76], 0);
dword_1542FC = gameclock + 120; nextstage = leveltime + 120;
nFinaleStage++; nFinaleStage++;
} }
} }
else if (nFinaleStage <= 2) else if (nFinaleStage <= 2)
{ {
if (gameclock >= dword_1542FC) if (leveltime >= nextstage)
{ {
PlayLocalSound(StaticSound[kSound77], 0); PlayLocalSound(StaticSound[kSound77], 0);
nFinaleStage++; nFinaleStage++;
dword_1542FC = gameclock + 360; nextstage = leveltime + 360;
} }
} }
else if (nFinaleStage == 3 && gameclock >= dword_1542FC) else if (nFinaleStage == 3 && leveltime >= nextstage)
{ {
EndLevel = true; EndLevel = true;
} }
@ -1706,7 +1706,7 @@ void ExplodeEnergyBlock(int nSprite)
else else
{ {
nFinaleSpr = nSprite; nFinaleSpr = nSprite;
lFinaleStart = gameclock; lFinaleStart = leveltime;
if (!lFinaleStart) { if (!lFinaleStart) {
lFinaleStart = lFinaleStart + 1; lFinaleStart = lFinaleStart + 1;

View file

@ -127,7 +127,7 @@ void InitSpiritHead()
sprite[nSpiritSprite].cstat &= 0x7FFF; sprite[nSpiritSprite].cstat &= 0x7FFF;
nHeadTimeStart = gameclock; nHeadTimeStart = leveltime;
memset(Worktile, TRANSPARENT_INDEX, WorktileSize); memset(Worktile, TRANSPARENT_INDEX, WorktileSize);
TileFiles.InvalidateTile(kTileRamsesWorkTile); TileFiles.InvalidateTile(kTileRamsesWorkTile);
@ -152,8 +152,8 @@ void InitSpiritHead()
StartSwirlies(); StartSwirlies();
sprintf(filename, "LEV%d.PUP", currentLevel->levelNumber); sprintf(filename, "LEV%d.PUP", currentLevel->levelNumber);
lNextStateChange = gameclock; lNextStateChange = leveltime;
lHeadStartClock = gameclock; lHeadStartClock = leveltime;
auto headfd = fileSystem.OpenFileReader(filename); auto headfd = fileSystem.OpenFileReader(filename);
if (!headfd.isOpen()) if (!headfd.isOpen())
@ -219,7 +219,7 @@ int DoSpiritHead()
if (nHeadStage < 2 || nHeadStage != 5) if (nHeadStage < 2 || nHeadStage != 5)
{ {
nPixelsToShow = (gameclock - nHeadTimeStart) * 15; nPixelsToShow = (leveltime - nHeadTimeStart) * 15;
if (nPixelsToShow > nPixels) { if (nPixelsToShow > nPixels) {
nPixelsToShow = nPixels; nPixelsToShow = nPixels;
@ -242,10 +242,10 @@ int DoSpiritHead()
if (!nHeadStage) if (!nHeadStage)
{ {
if ((gameclock - nHeadTimeStart) > 480) if ((leveltime - nHeadTimeStart) > 480)
{ {
nHeadStage = 1; nHeadStage = 1;
nHeadTimeStart = gameclock + 480; nHeadTimeStart = leveltime + 480;
} }
for (int i = 0; i < nPixelsToShow; i++) for (int i = 0; i < nPixelsToShow; i++)
@ -426,7 +426,7 @@ int DoSpiritHead()
Worktile[kSpiritX + ecx] = pixelval[i]; Worktile[kSpiritX + ecx] = pixelval[i];
} }
if ((gameclock - lHeadStartClock) > 600) if ((leveltime - lHeadStartClock) > 600)
{ {
CopyHeadToWorkTile(kTileRamsesGold); CopyHeadToWorkTile(kTileRamsesGold);
} }
@ -467,7 +467,7 @@ int DoSpiritHead()
} }
else else
{ {
if (lNextStateChange <= gameclock) if (lNextStateChange <= leveltime)
{ {
if (nPupData) if (nPupData)
{ {

View file

@ -450,7 +450,7 @@ void EXSoundEngine::CalcPosVel(int type, const void* source, const float pt[3],
else if (type == SOURCE_Swirly) else if (type == SOURCE_Swirly)
{ {
int which = *(int*)source; int which = *(int*)source;
float phase = (gameclock << (4 + which)) * (M_PI / 1024); float phase = (leveltime << (4 + which)) * (M_PI / 1024);
pos->X = fcampos.X + 256 * cos(phase); pos->X = fcampos.X + 256 * cos(phase);
pos->Z = fcampos.Z + 256 * sin(phase); pos->Z = fcampos.Z + 256 * sin(phase);
} }

View file

@ -631,7 +631,7 @@ private:
int shade; int shade;
if (gameclock / kTimerTicks & 1) { if (leveltime / kTimerTicks & 1) {
shade = -100; shade = -100;
} }
else { else {
@ -649,14 +649,14 @@ private:
if (word_9AD54[i] == nScore) if (word_9AD54[i] == nScore)
{ {
int v9 = dword_9AD64[i]; int v9 = dword_9AD64[i];
if (v9 && v9 <= gameclock) { if (v9 && v9 <= leveltime) {
dword_9AD64[i] = 0; dword_9AD64[i] = 0;
} }
} }
else else
{ {
word_9AD54[i] = nScore; word_9AD54[i] = nScore;
dword_9AD64[i] = gameclock + 30; dword_9AD64[i] = leveltime + 30;
} }
DrawGraphic(tileGetTexture(nTile), x, 7, DI_ITEM_CENTER, 1, -1, -1, 1, 1); DrawGraphic(tileGetTexture(nTile), x, 7, DI_ITEM_CENTER, 1, -1, -1, 1, 1);