From b49e050baf0012331e05aa4aa184174dec2bec4e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 2 Sep 2020 22:55:57 +0200 Subject: [PATCH] - transitioned Exhumed to the new main loop. Fixed #301 --- source/core/gamecontrol.cpp | 9 +- source/core/gamecontrol.h | 6 - source/core/mainloop.cpp | 2 - source/exhumed/src/enginesubs.cpp | 6 - source/exhumed/src/exhumed.cpp | 244 ++++++++++++++++-------------- source/exhumed/src/exhumed.h | 7 +- source/exhumed/src/gameloop.cpp | 52 ++++--- source/exhumed/src/input.cpp | 6 + source/exhumed/src/map.cpp | 2 +- source/exhumed/src/object.cpp | 12 +- source/exhumed/src/ramses.cpp | 16 +- source/exhumed/src/sound.cpp | 2 +- source/exhumed/src/status.cpp | 6 +- 13 files changed, 191 insertions(+), 179 deletions(-) diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index 57b2faf54..0f9397995 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -863,13 +863,8 @@ int RunGame() enginePostInit(); // This must not be done earlier! videoInit(); - // Duke has transitioned to the new main loop, the other games haven't yet. - if (!(g_gameType & (GAMEFLAG_PSEXHUMED))) - { - D_CheckNetGame(); - MainLoop(); - } - else app_loop(); + D_CheckNetGame(); + MainLoop(); return 0; // this is never reached. app_loop only exits via exception. } diff --git a/source/core/gamecontrol.h b/source/core/gamecontrol.h index 213a88ed6..bae8b8f18 100644 --- a/source/core/gamecontrol.h +++ b/source/core/gamecontrol.h @@ -223,11 +223,5 @@ enum AM_Mode extern int automapMode; extern bool automapFollow; extern bool sendPause; -extern int gameclock; -extern uint64_t gameclockstart; extern int lastTic; -inline void updateGameClock() -{ - gameclock = static_cast((I_GetTimeNS() - gameclockstart) * 120 / 1'000'000'000); -} diff --git a/source/core/mainloop.cpp b/source/core/mainloop.cpp index 3fbda02b3..6302a7b30 100644 --- a/source/core/mainloop.cpp +++ b/source/core/mainloop.cpp @@ -194,7 +194,6 @@ static void GameTicker() case GS_LEVEL: gameupdatetime.Reset(); gameupdatetime.Clock(); - updateGameClock(); gi->Ticker(); gameupdatetime.Unclock(); break; @@ -249,7 +248,6 @@ void Display() twod->Clear(); twod->SetSize(screen->GetWidth(), screen->GetHeight()); twodpsp.SetSize(screen->GetWidth(), screen->GetHeight()); - updateGameClock(); gi->Render(); DrawFullscreenBlends(); } diff --git a/source/exhumed/src/enginesubs.cpp b/source/exhumed/src/enginesubs.cpp index c4c68f87d..e896bd2be 100644 --- a/source/exhumed/src/enginesubs.cpp +++ b/source/exhumed/src/enginesubs.cpp @@ -30,18 +30,12 @@ BEGIN_PS_NS void resettiming() { - gameclock = 0; lastTic = -1; } void doTileLoad(int i) { - tileLoad(i); - -#ifdef USE_OPENGL if (r_precache) PrecacheHardwareTextures(i); -#endif - } void precache() diff --git a/source/exhumed/src/exhumed.cpp b/source/exhumed/src/exhumed.cpp index 363e95890..0b3e20a87 100644 --- a/source/exhumed/src/exhumed.cpp +++ b/source/exhumed/src/exhumed.cpp @@ -373,6 +373,8 @@ double calc_smoothratio() return I_GetTimeFrac() * MaxSmoothRatio; } +void CheckProgression(); + void GameMove(void) { FixPalette(); @@ -444,10 +446,133 @@ static int SelectAltWeapon(int weap2) 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() { int const currentTic = I_GetTime(); - gameclock = I_GetBuildTime(); if (paused) { @@ -461,122 +586,7 @@ void GameTicker() while (!EndLevel && currentTic - lastTic >= 1) { lastTic = currentTic; - - 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(); + gi->Ticker(); } gameupdatetime.Unclock(); diff --git a/source/exhumed/src/exhumed.h b/source/exhumed/src/exhumed.h index 6b135b192..aecf2f65f 100644 --- a/source/exhumed/src/exhumed.h +++ b/source/exhumed/src/exhumed.h @@ -197,7 +197,7 @@ public: void ComputeCinemaText(); void ReadyCinemaText(uint16_t nVal); void DisplayText(); - bool AdvanceCinemaText(int gameclock); + bool AdvanceCinemaText(int clock); }; @@ -250,6 +250,11 @@ struct GameInterface : ::GameInterface void QuitToTitle() override; void UpdateSounds() override; void ErrorCleanup() override; + void Ticker() override; + void DrawBackground() override; + void Render() override; + void GetInput(InputPacket* packet) override; + void Startup() override; ::GameStats getStats() override; }; diff --git a/source/exhumed/src/gameloop.cpp b/source/exhumed/src/gameloop.cpp index 2ff76975d..5f74e9fd3 100644 --- a/source/exhumed/src/gameloop.cpp +++ b/source/exhumed/src/gameloop.cpp @@ -50,6 +50,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_PS_NS +void CheckProgression(); + short nBestLevel; static int32_t nonsharedtimer; @@ -114,8 +116,9 @@ static void showmap(short nLevel, short nLevelNew, short nLevelBest, TArrayUpdateSounds(); - 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() { again: @@ -263,31 +288,16 @@ void GameInterface::RunGameFrame() { default: 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; case GS_MENUSCREEN: case GS_FULLCONSOLE: - drawmenubackground(); + gi->DrawBackground(); break; case GS_LEVEL: GameLoop(); - GameDisplay(); + gi->Render(); break; case GS_INTERMISSION: diff --git a/source/exhumed/src/input.cpp b/source/exhumed/src/input.cpp index 61625477e..bd221d719 100644 --- a/source/exhumed/src/input.cpp +++ b/source/exhumed/src/input.cpp @@ -325,4 +325,10 @@ void PlayerInterruptKeys(bool after) } +void GameInterface::GetInput(InputPacket* packet) +{ + PlayerInterruptKeys(packet == nullptr); + if (packet) *packet = localInput; +} + END_PS_NS diff --git a/source/exhumed/src/map.cpp b/source/exhumed/src/map.cpp index 72c4fd99c..852495b02 100644 --- a/source/exhumed/src/map.cpp +++ b/source/exhumed/src/map.cpp @@ -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 (pSprite->xvel > 16 && pPlayer->on_ground) - i = APLAYERTOP+(((int32_t) gameclock>>4)&3); + i = APLAYERTOP+(((int32_t) leveltime>>4)&3); else i = APLAYERTOP; diff --git a/source/exhumed/src/object.cpp b/source/exhumed/src/object.cpp index a342e9e12..73183e2d9 100644 --- a/source/exhumed/src/object.cpp +++ b/source/exhumed/src/object.cpp @@ -1492,7 +1492,7 @@ void DimLights() void DoFinale() { static int dword_96788 = 0; - static int dword_1542FC = 0; + static int nextstage = 0; if (!lFinaleStart) return; @@ -1529,20 +1529,20 @@ void DoFinale() { StopLocalSound(); PlayLocalSound(StaticSound[kSound76], 0); - dword_1542FC = gameclock + 120; + nextstage = leveltime + 120; nFinaleStage++; } } else if (nFinaleStage <= 2) { - if (gameclock >= dword_1542FC) + if (leveltime >= nextstage) { PlayLocalSound(StaticSound[kSound77], 0); nFinaleStage++; - dword_1542FC = gameclock + 360; + nextstage = leveltime + 360; } } - else if (nFinaleStage == 3 && gameclock >= dword_1542FC) + else if (nFinaleStage == 3 && leveltime >= nextstage) { EndLevel = true; } @@ -1706,7 +1706,7 @@ void ExplodeEnergyBlock(int nSprite) else { nFinaleSpr = nSprite; - lFinaleStart = gameclock; + lFinaleStart = leveltime; if (!lFinaleStart) { lFinaleStart = lFinaleStart + 1; diff --git a/source/exhumed/src/ramses.cpp b/source/exhumed/src/ramses.cpp index 5560ec0cb..ba973ce1f 100644 --- a/source/exhumed/src/ramses.cpp +++ b/source/exhumed/src/ramses.cpp @@ -127,7 +127,7 @@ void InitSpiritHead() sprite[nSpiritSprite].cstat &= 0x7FFF; - nHeadTimeStart = gameclock; + nHeadTimeStart = leveltime; memset(Worktile, TRANSPARENT_INDEX, WorktileSize); TileFiles.InvalidateTile(kTileRamsesWorkTile); @@ -152,8 +152,8 @@ void InitSpiritHead() StartSwirlies(); sprintf(filename, "LEV%d.PUP", currentLevel->levelNumber); - lNextStateChange = gameclock; - lHeadStartClock = gameclock; + lNextStateChange = leveltime; + lHeadStartClock = leveltime; auto headfd = fileSystem.OpenFileReader(filename); if (!headfd.isOpen()) @@ -219,7 +219,7 @@ int DoSpiritHead() if (nHeadStage < 2 || nHeadStage != 5) { - nPixelsToShow = (gameclock - nHeadTimeStart) * 15; + nPixelsToShow = (leveltime - nHeadTimeStart) * 15; if (nPixelsToShow > nPixels) { nPixelsToShow = nPixels; @@ -242,10 +242,10 @@ int DoSpiritHead() if (!nHeadStage) { - if ((gameclock - nHeadTimeStart) > 480) + if ((leveltime - nHeadTimeStart) > 480) { nHeadStage = 1; - nHeadTimeStart = gameclock + 480; + nHeadTimeStart = leveltime + 480; } for (int i = 0; i < nPixelsToShow; i++) @@ -426,7 +426,7 @@ int DoSpiritHead() Worktile[kSpiritX + ecx] = pixelval[i]; } - if ((gameclock - lHeadStartClock) > 600) + if ((leveltime - lHeadStartClock) > 600) { CopyHeadToWorkTile(kTileRamsesGold); } @@ -467,7 +467,7 @@ int DoSpiritHead() } else { - if (lNextStateChange <= gameclock) + if (lNextStateChange <= leveltime) { if (nPupData) { diff --git a/source/exhumed/src/sound.cpp b/source/exhumed/src/sound.cpp index 557167338..75890ad70 100644 --- a/source/exhumed/src/sound.cpp +++ b/source/exhumed/src/sound.cpp @@ -450,7 +450,7 @@ void EXSoundEngine::CalcPosVel(int type, const void* source, const float pt[3], else if (type == SOURCE_Swirly) { 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->Z = fcampos.Z + 256 * sin(phase); } diff --git a/source/exhumed/src/status.cpp b/source/exhumed/src/status.cpp index 0ed9a049c..d1b8ea95e 100644 --- a/source/exhumed/src/status.cpp +++ b/source/exhumed/src/status.cpp @@ -631,7 +631,7 @@ private: int shade; - if (gameclock / kTimerTicks & 1) { + if (leveltime / kTimerTicks & 1) { shade = -100; } else { @@ -649,14 +649,14 @@ private: if (word_9AD54[i] == nScore) { int v9 = dword_9AD64[i]; - if (v9 && v9 <= gameclock) { + if (v9 && v9 <= leveltime) { dword_9AD64[i] = 0; } } else { 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);