mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-27 20:20:40 +00:00
- refactored Blood's main loop.
* moved Smacker video playing code into the backend, so now all games can play all supported video formats * logos and level intro/exit videos use ScreenJob
This commit is contained in:
parent
0958bccade
commit
347ed51036
19 changed files with 444 additions and 549 deletions
|
@ -34,7 +34,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include "blood.h"
|
||||
#include "choke.h"
|
||||
#include "controls.h"
|
||||
#include "credits.h"
|
||||
#include "dude.h"
|
||||
#include "endgame.h"
|
||||
#include "eventq.h"
|
||||
|
@ -59,16 +58,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include "raze_sound.h"
|
||||
#include "nnexts.h"
|
||||
#include "secrets.h"
|
||||
#include "gamestate.h"
|
||||
#include "screenjob.h"
|
||||
|
||||
BEGIN_BLD_NS
|
||||
|
||||
|
||||
INPUT_MODE gInputMode;
|
||||
|
||||
#ifdef USE_QHEAP
|
||||
unsigned int nMaxAlloc = 0x4000000;
|
||||
#endif
|
||||
|
||||
char bAddUserMap = false;
|
||||
bool bNoDemo = false;
|
||||
bool bQuickStart = true;
|
||||
|
@ -80,8 +75,6 @@ short BloodVersion = 0x115;
|
|||
|
||||
int gNetPlayers;
|
||||
|
||||
char *pUserTiles = NULL;
|
||||
|
||||
int gChokeCounter = 0;
|
||||
|
||||
double g_gameUpdateTime, g_gameUpdateAndDrawTime;
|
||||
|
@ -131,21 +124,9 @@ enum gametokens
|
|||
|
||||
int blood_globalflags;
|
||||
|
||||
void ShutDown(void)
|
||||
{
|
||||
if (!in3dmode())
|
||||
return;
|
||||
netDeinitialize();
|
||||
//sndTerm();
|
||||
sfxTerm();
|
||||
// PORT_TODO: Check argument
|
||||
DO_FREE_AND_NULL(pUserTiles);
|
||||
}
|
||||
|
||||
void QuitGame(void)
|
||||
{
|
||||
ShutDown();
|
||||
Bexit(0);
|
||||
throw CExitEvent(0);
|
||||
}
|
||||
|
||||
void PrecacheDude(spritetype *pSprite)
|
||||
|
@ -412,8 +393,6 @@ void StartLevel(GAMEOPTIONS *gameOptions)
|
|||
if (gEpisodeInfo[gGameOptions.nEpisode].cutALevel == gGameOptions.nLevel
|
||||
&& gEpisodeInfo[gGameOptions.nEpisode].at8f08)
|
||||
gGameOptions.uGameFlags |= 4;
|
||||
if ((gGameOptions.uGameFlags&4))
|
||||
levelPlayIntroScene(gGameOptions.nEpisode);
|
||||
|
||||
///////
|
||||
gGameOptions.weaponsV10x = gWeaponsV10x;
|
||||
|
@ -455,11 +434,10 @@ void StartLevel(GAMEOPTIONS *gameOptions)
|
|||
enginecompatibility_mode = ENGINECOMPATIBILITY_19960925;//bVanilla;
|
||||
memset(xsprite,0,sizeof(xsprite));
|
||||
memset(sprite,0,kMaxSprites*sizeof(spritetype));
|
||||
drawLoadingScreen();
|
||||
//drawLoadingScreen();
|
||||
if (dbLoadMap(gameOptions->zLevelName,(int*)&startpos.x,(int*)&startpos.y,(int*)&startpos.z,&startang,&startsectnum,(unsigned int*)&gameOptions->uMapCRC))
|
||||
{
|
||||
gQuitGame = true;
|
||||
return;
|
||||
I_Error("Unable to load map");
|
||||
}
|
||||
currentLevel = &mapList[gGameOptions.nEpisode * kMaxLevels + gGameOptions.nLevel];
|
||||
SECRET_SetMapName(currentLevel->DisplayName(), currentLevel->name);
|
||||
|
@ -571,7 +549,6 @@ void StartLevel(GAMEOPTIONS *gameOptions)
|
|||
gFrame = 0;
|
||||
gChokeCounter = 0;
|
||||
M_ClearMenus();
|
||||
levelTryPlayMusicOrNothing(gGameOptions.nEpisode, gGameOptions.nLevel);
|
||||
// viewSetMessage("");
|
||||
viewSetErrorMessage("");
|
||||
viewResizeView(gViewSize);
|
||||
|
@ -580,40 +557,9 @@ void StartLevel(GAMEOPTIONS *gameOptions)
|
|||
netWaitForEveryone(0);
|
||||
totalclock = 0;
|
||||
paused = 0;
|
||||
gGameStarted = 1;
|
||||
ready2send = 1;
|
||||
}
|
||||
|
||||
void StartNetworkLevel(void)
|
||||
{
|
||||
if (!(gGameOptions.uGameFlags&1))
|
||||
{
|
||||
gGameOptions.nEpisode = gPacketStartGame.episodeId;
|
||||
gGameOptions.nLevel = gPacketStartGame.levelId;
|
||||
gGameOptions.nGameType = gPacketStartGame.gameType;
|
||||
gGameOptions.nDifficulty = gPacketStartGame.difficulty;
|
||||
gGameOptions.nMonsterSettings = gPacketStartGame.monsterSettings;
|
||||
gGameOptions.nWeaponSettings = gPacketStartGame.weaponSettings;
|
||||
gGameOptions.nItemSettings = gPacketStartGame.itemSettings;
|
||||
gGameOptions.nRespawnSettings = gPacketStartGame.respawnSettings;
|
||||
gGameOptions.bFriendlyFire = gPacketStartGame.bFriendlyFire;
|
||||
gGameOptions.bKeepKeysOnRespawn = gPacketStartGame.bKeepKeysOnRespawn;
|
||||
|
||||
///////
|
||||
gGameOptions.weaponsV10x = gPacketStartGame.weaponsV10x;
|
||||
///////
|
||||
|
||||
gBlueFlagDropped = false;
|
||||
gRedFlagDropped = false;
|
||||
|
||||
if (gPacketStartGame.userMap)
|
||||
levelAddUserMap(gPacketStartGame.userMapName);
|
||||
else
|
||||
levelSetupOptions(gGameOptions.nEpisode, gGameOptions.nLevel);
|
||||
}
|
||||
StartLevel(&gGameOptions);
|
||||
}
|
||||
|
||||
|
||||
void LocalKeys(void)
|
||||
{
|
||||
|
@ -778,22 +724,33 @@ void ProcessFrame(void)
|
|||
netMasterUpdate();
|
||||
}
|
||||
}
|
||||
Mus_Fade(4000);
|
||||
seqKillAll();
|
||||
if (gGameOptions.uGameFlags&2)
|
||||
{
|
||||
STAT_Update(true);
|
||||
if (gGameOptions.nGameType == 0)
|
||||
{
|
||||
auto completion = [] (bool) {
|
||||
gamestate = GS_DEMOSCREEN;
|
||||
M_StartControlPanel(false);
|
||||
M_SetMenu(NAME_CreditsMenu);
|
||||
gGameOptions.uGameFlags &= ~3;
|
||||
gRestartGame = 1;
|
||||
gQuitGame = 1;
|
||||
};
|
||||
|
||||
if (gGameOptions.uGameFlags&8)
|
||||
levelPlayEndScene(gGameOptions.nEpisode);
|
||||
|
||||
M_StartControlPanel(false);
|
||||
M_SetMenu(NAME_CreditsMenu);
|
||||
{
|
||||
levelPlayEndScene(gGameOptions.nEpisode, completion);
|
||||
}
|
||||
else completion(false);
|
||||
}
|
||||
gGameOptions.uGameFlags &= ~3;
|
||||
gRestartGame = 1;
|
||||
gQuitGame = 1;
|
||||
else
|
||||
{
|
||||
gGameOptions.uGameFlags &= ~3;
|
||||
gRestartGame = 1;
|
||||
gQuitGame = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -876,13 +833,12 @@ static const char* actions[] = {
|
|||
"Jetpack"
|
||||
};
|
||||
|
||||
int GameInterface::app_main()
|
||||
static void app_init()
|
||||
{
|
||||
|
||||
buttonMap.SetButtons(actions, NUM_ACTIONS);
|
||||
memcpy(&gGameOptions, &gSingleGameOptions, sizeof(GAMEOPTIONS));
|
||||
gGameOptions.nMonsterSettings = !userConfig.nomonsters;
|
||||
bQuickStart = userConfig.nologo;
|
||||
gGameOptions.nMonsterSettings = !userConfig.nomonsters;
|
||||
bQuickStart = userConfig.nologo;
|
||||
ReadAllRFS();
|
||||
|
||||
HookReplaceFunctions();
|
||||
|
@ -891,29 +847,20 @@ int GameInterface::app_main()
|
|||
engineInit();
|
||||
|
||||
Printf("Loading tiles\n");
|
||||
if (pUserTiles)
|
||||
{
|
||||
FStringf buffer("%s%%03i.ART", pUserTiles);
|
||||
if (!tileInit(0,buffer))
|
||||
ThrowError("User specified ART files not found");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!tileInit(0,NULL))
|
||||
ThrowError("TILES###.ART files not found");
|
||||
}
|
||||
if (!tileInit(0, NULL))
|
||||
I_FatalError("TILES###.ART files not found");
|
||||
|
||||
levelLoadDefaults();
|
||||
|
||||
loaddefinitionsfile(BLOODWIDESCREENDEF);
|
||||
loaddefinitions_game(BLOODWIDESCREENDEF, FALSE);
|
||||
|
||||
const char *defsfile = G_DefFile();
|
||||
const char* defsfile = G_DefFile();
|
||||
uint32_t stime = timerGetTicks();
|
||||
if (!loaddefinitionsfile(defsfile))
|
||||
{
|
||||
uint32_t etime = timerGetTicks();
|
||||
Printf("Definitions file \"%s\" loaded in %d ms.\n", defsfile, etime-stime);
|
||||
Printf("Definitions file \"%s\" loaded in %d ms.\n", defsfile, etime - stime);
|
||||
}
|
||||
loaddefinitions_game(defsfile, FALSE);
|
||||
powerupInit();
|
||||
|
@ -931,11 +878,10 @@ int GameInterface::app_main()
|
|||
ctrlInit();
|
||||
timerInit(120);
|
||||
timerSetCallback(ClockStrobe);
|
||||
// PORT-TODO: CD audio init
|
||||
|
||||
Printf("Initializing network users\n");
|
||||
netInitialize(true);
|
||||
videoInit();
|
||||
videoInit();
|
||||
hud_size.Callback();
|
||||
Printf("Initializing sound system\n");
|
||||
sndInit();
|
||||
|
@ -948,18 +894,17 @@ int GameInterface::app_main()
|
|||
gStartNewGame = 1;
|
||||
}
|
||||
videoSetViewableArea(0, 0, xdim - 1, ydim - 1);
|
||||
bool playvideo = !bQuickStart;
|
||||
|
||||
if (playvideo)
|
||||
credLogosDos();
|
||||
|
||||
UpdateDacs(0, true);
|
||||
}
|
||||
|
||||
RESTART:
|
||||
static void gameInit()
|
||||
{
|
||||
//RESTART:
|
||||
sub_79760();
|
||||
gViewIndex = myconnectindex;
|
||||
gMe = gView = &gPlayer[myconnectindex];
|
||||
netBroadcastPlayerInfo(myconnectindex);
|
||||
#if 0
|
||||
Printf("Waiting for network players!\n");
|
||||
netWaitForEveryone(0);
|
||||
if (gRestartGame)
|
||||
|
@ -971,134 +916,94 @@ RESTART:
|
|||
netResetToSinglePlayer();
|
||||
goto RESTART;
|
||||
}
|
||||
UpdateNetworkMenus();
|
||||
#endif
|
||||
UpdateNetworkMenus();
|
||||
gQuitGame = 0;
|
||||
gRestartGame = 0;
|
||||
if (gGameOptions.nGameType > 0)
|
||||
{
|
||||
inputState.ClearAllInput();
|
||||
}
|
||||
if (!bAddUserMap && !gGameStarted)
|
||||
{
|
||||
M_StartControlPanel(false);
|
||||
M_SetMenu(NAME_Mainmenu);
|
||||
}
|
||||
ready2send = 1;
|
||||
while (!gQuitGame)
|
||||
|
||||
}
|
||||
|
||||
static void gameTicker()
|
||||
{
|
||||
bool gameUpdate = false;
|
||||
double const gameUpdateStartTime = timerGetHiTicks();
|
||||
while (gPredictTail < gNetFifoHead[myconnectindex] && !paused)
|
||||
{
|
||||
bool bDraw;
|
||||
D_ProcessEvents();
|
||||
if (gGameStarted) // gGameStarted: gameState == GS_LEVEL
|
||||
{
|
||||
char gameUpdate = false;
|
||||
double const gameUpdateStartTime = timerGetHiTicks();
|
||||
while (gPredictTail < gNetFifoHead[myconnectindex] && !paused)
|
||||
{
|
||||
viewUpdatePrediction(&gFifoInput[gPredictTail&255][myconnectindex]);
|
||||
}
|
||||
if (numplayers == 1)
|
||||
gBufferJitter = 0;
|
||||
while (totalclock >= gNetFifoClock && ready2send)
|
||||
{
|
||||
gNetInput = gInput;
|
||||
gInput = {};
|
||||
netGetInput();
|
||||
gNetFifoClock += 4;
|
||||
while (gNetFifoHead[myconnectindex]-gNetFifoTail > gBufferJitter && !gStartNewGame && !gQuitGame)
|
||||
{
|
||||
int i;
|
||||
for (i = connecthead; i >= 0; i = connectpoint2[i])
|
||||
if (gNetFifoHead[i] == gNetFifoTail)
|
||||
break;
|
||||
if (i >= 0)
|
||||
break;
|
||||
//faketimerhandler();
|
||||
ProcessFrame();
|
||||
gameUpdate = true;
|
||||
}
|
||||
}
|
||||
if (gameUpdate)
|
||||
{
|
||||
g_gameUpdateTime = timerGetHiTicks() - gameUpdateStartTime;
|
||||
if (g_gameUpdateAvgTime < 0.f)
|
||||
g_gameUpdateAvgTime = g_gameUpdateTime;
|
||||
g_gameUpdateAvgTime = ((GAMEUPDATEAVGTIMENUMSAMPLES-1.f)*g_gameUpdateAvgTime+g_gameUpdateTime)/((float) GAMEUPDATEAVGTIMENUMSAMPLES);
|
||||
}
|
||||
bDraw = G_FPSLimit() != 0;
|
||||
if (gQuitRequest && gQuitGame)
|
||||
videoClearScreen(0);
|
||||
else
|
||||
{
|
||||
netCheckSync();
|
||||
if (bDraw)
|
||||
{
|
||||
viewDrawScreen();
|
||||
g_gameUpdateAndDrawTime = g_beforeSwapTime/* timerGetHiTicks()*/ - gameUpdateStartTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // gameState == GS_DEMOSCREEN
|
||||
{
|
||||
// Menu background
|
||||
bDraw = G_FPSLimit() != 0;
|
||||
if (bDraw)
|
||||
{
|
||||
twod->ClearScreen();
|
||||
rotatesprite(160<<16,100<<16,65536,0,2518,0,0,0x4a,0,0,xdim-1,ydim-1);
|
||||
}
|
||||
if (gQuitRequest && !gQuitGame)
|
||||
netBroadcastMyLogoff(gQuitRequest == 2);
|
||||
}
|
||||
if (bDraw)
|
||||
{
|
||||
gameHandleEvents();
|
||||
inputState.SetBindsEnabled(gInputMode == kInputGame);
|
||||
switch (gInputMode)
|
||||
{
|
||||
case kInputGame:
|
||||
LocalKeys();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (gQuitGame)
|
||||
continue;
|
||||
|
||||
C_RunDelayedCommands();
|
||||
|
||||
ctrlGetInput();
|
||||
|
||||
switch (gInputMode)
|
||||
{
|
||||
case kInputMessage:
|
||||
gPlayerMsg.ProcessKeys();
|
||||
gPlayerMsg.Draw();
|
||||
break;
|
||||
case kInputEndGame:
|
||||
gEndGameMgr.ProcessKeys();
|
||||
gEndGameMgr.Draw();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
videoNextPage();
|
||||
}
|
||||
if (TestBitString(gotpic, 2342))
|
||||
{
|
||||
FireProcess();
|
||||
ClearBitString(gotpic, 2342);
|
||||
}
|
||||
//if (byte_148e29 && gStartNewGame)
|
||||
//{
|
||||
// gStartNewGame = 0;
|
||||
// gQuitGame = 1;
|
||||
//}
|
||||
if (gStartNewGame)
|
||||
{
|
||||
StartLevel(&gGameOptions);
|
||||
}
|
||||
viewUpdatePrediction(&gFifoInput[gPredictTail & 255][myconnectindex]);
|
||||
}
|
||||
if (numplayers == 1)
|
||||
gBufferJitter = 0;
|
||||
while (totalclock >= gNetFifoClock && ready2send)
|
||||
{
|
||||
gNetInput = gInput;
|
||||
gInput = {};
|
||||
netGetInput();
|
||||
gNetFifoClock += 4;
|
||||
while (gNetFifoHead[myconnectindex] - gNetFifoTail > gBufferJitter && !gStartNewGame && !gQuitGame)
|
||||
{
|
||||
int i;
|
||||
for (i = connecthead; i >= 0; i = connectpoint2[i])
|
||||
if (gNetFifoHead[i] == gNetFifoTail)
|
||||
break;
|
||||
if (i >= 0)
|
||||
break;
|
||||
//faketimerhandler();
|
||||
ProcessFrame();
|
||||
gameUpdate = true;
|
||||
}
|
||||
}
|
||||
if (gameUpdate)
|
||||
{
|
||||
g_gameUpdateTime = timerGetHiTicks() - gameUpdateStartTime;
|
||||
if (g_gameUpdateAvgTime < 0.f)
|
||||
g_gameUpdateAvgTime = g_gameUpdateTime;
|
||||
g_gameUpdateAvgTime = ((GAMEUPDATEAVGTIMENUMSAMPLES - 1.f) * g_gameUpdateAvgTime + g_gameUpdateTime) / ((float)GAMEUPDATEAVGTIMENUMSAMPLES);
|
||||
}
|
||||
if (gQuitRequest && gQuitGame)
|
||||
videoClearScreen(0);
|
||||
else
|
||||
{
|
||||
netCheckSync();
|
||||
viewDrawScreen();
|
||||
g_gameUpdateAndDrawTime = g_beforeSwapTime/* timerGetHiTicks()*/ - gameUpdateStartTime;
|
||||
}
|
||||
}
|
||||
|
||||
static void drawBackground()
|
||||
{
|
||||
twod->ClearScreen();
|
||||
rotatesprite(160 << 16, 100 << 16, 65536, 0, 2518, 0, 0, 0x4a, 0, 0, xdim - 1, ydim - 1);
|
||||
if (gQuitRequest && !gQuitGame)
|
||||
netBroadcastMyLogoff(gQuitRequest == 2);
|
||||
}
|
||||
|
||||
static void commonTicker(bool &playvideo)
|
||||
{
|
||||
if (TestBitString(gotpic, 2342))
|
||||
{
|
||||
FireProcess();
|
||||
ClearBitString(gotpic, 2342);
|
||||
}
|
||||
if (gStartNewGame)
|
||||
{
|
||||
StartLevel(&gGameOptions);
|
||||
|
||||
auto completion = [](bool = false)
|
||||
{
|
||||
levelTryPlayMusicOrNothing(gGameOptions.nEpisode, gGameOptions.nLevel);
|
||||
gamestate = GS_LEVEL;
|
||||
};
|
||||
|
||||
if ((gGameOptions.uGameFlags & 4))
|
||||
levelPlayIntroScene(gGameOptions.nEpisode, completion);
|
||||
else
|
||||
completion(false);
|
||||
|
||||
}
|
||||
ready2send = 0;
|
||||
if (gRestartGame)
|
||||
{
|
||||
Mus_Stop();
|
||||
|
@ -1106,21 +1011,70 @@ RESTART:
|
|||
gQuitGame = 0;
|
||||
gQuitRequest = 0;
|
||||
gRestartGame = 0;
|
||||
gGameStarted = 0;
|
||||
levelSetupOptions(0,0);
|
||||
levelSetupOptions(0, 0);
|
||||
|
||||
|
||||
|
||||
if (gGameOptions.nGameType != 0)
|
||||
{
|
||||
videoSetViewableArea(0,0,xdim-1,ydim-1);
|
||||
playvideo = !bQuickStart;
|
||||
playvideo = !bQuickStart;
|
||||
}
|
||||
else playvideo = false;
|
||||
|
||||
goto RESTART;
|
||||
else playvideo = false;
|
||||
gamestate = GS_STARTUP;
|
||||
}
|
||||
ShutDown();
|
||||
}
|
||||
|
||||
int GameInterface::app_main()
|
||||
{
|
||||
|
||||
app_init();
|
||||
gamestate = GS_STARTUP;
|
||||
bool playvideo = !bQuickStart;
|
||||
while (true)
|
||||
{
|
||||
if (gamestate == GS_STARTUP) gameInit();
|
||||
|
||||
commonTicker(playvideo);
|
||||
gameHandleEvents();
|
||||
D_ProcessEvents();
|
||||
ctrlGetInput();
|
||||
|
||||
switch (gamestate)
|
||||
{
|
||||
default:
|
||||
case GS_STARTUP:
|
||||
if (playvideo) playlogos();
|
||||
else
|
||||
{
|
||||
gamestate = GS_DEMOSCREEN;
|
||||
M_StartControlPanel(false);
|
||||
M_SetMenu(NAME_Mainmenu);
|
||||
}
|
||||
break;
|
||||
|
||||
case GS_DEMOSCREEN:
|
||||
drawBackground();
|
||||
break;
|
||||
|
||||
case GS_INTRO:
|
||||
case GS_INTERMISSION:
|
||||
RunScreenJobFrame(); // This handles continuation through its completion callback.
|
||||
break;
|
||||
|
||||
case GS_LEVEL:
|
||||
gameTicker();
|
||||
LocalKeys();
|
||||
break;
|
||||
|
||||
case GS_FINALE:
|
||||
gEndGameMgr.ProcessKeys();
|
||||
gEndGameMgr.Draw();
|
||||
break;
|
||||
}
|
||||
|
||||
videoNextPage();
|
||||
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1449,7 +1403,7 @@ extern IniFile* BloodINI;
|
|||
void GameInterface::FreeGameData()
|
||||
{
|
||||
if (BloodINI) delete BloodINI;
|
||||
ShutDown();
|
||||
netDeinitialize();
|
||||
}
|
||||
|
||||
void GameInterface::UpdateScreenSize()
|
||||
|
|
|
@ -106,13 +106,6 @@ struct INICHAIN {
|
|||
extern INICHAIN *pINIChain;
|
||||
|
||||
|
||||
enum INPUT_MODE {
|
||||
kInputGame = 0,
|
||||
kInputMessage,
|
||||
kInputEndGame,
|
||||
};
|
||||
|
||||
extern INPUT_MODE gInputMode;
|
||||
extern short BloodVersion;
|
||||
extern int gNetPlayers;
|
||||
extern bool gRestartGame;
|
||||
|
|
|
@ -35,6 +35,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include "map2d.h"
|
||||
#include "view.h"
|
||||
#include "d_event.h"
|
||||
#include "gamestate.h"
|
||||
|
||||
BEGIN_BLD_NS
|
||||
|
||||
|
@ -83,7 +84,7 @@ void ctrlGetInput(void)
|
|||
|
||||
auto scaleAdjustmentToInterval = [=](double x) { return x * kTicsPerSec / (1000.0 / elapsedInputTicks); };
|
||||
|
||||
if (!gGameStarted || gInputMode != kInputGame)
|
||||
if (gamestate != GS_LEVEL || System_WantGuiCapture())
|
||||
{
|
||||
gInput = {};
|
||||
CONTROL_GetInput(&info);
|
||||
|
@ -414,15 +415,4 @@ void ctrlGetInput(void)
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (gGameStarted && gInputMode != kInputMessage
|
||||
&& buttonMap.ButtonDown(gamefunc_SendMessage))
|
||||
{
|
||||
buttonMap.ClearButton(gamefunc_SendMessage);
|
||||
inputState.keyFlushScans();
|
||||
gInputMode = kInputMessage;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
END_BLD_NS
|
||||
|
|
|
@ -37,212 +37,113 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include "../glbackend/glbackend.h"
|
||||
#include "raze_sound.h"
|
||||
#include "v_2ddrawer.h"
|
||||
#include "screenjob.h"
|
||||
#include "gamestate.h"
|
||||
#include "seq.h"
|
||||
#include "menu.h"
|
||||
|
||||
BEGIN_BLD_NS
|
||||
|
||||
char exitCredits = 0;
|
||||
|
||||
char Wait(int nTicks)
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void playlogos()
|
||||
{
|
||||
totalclock = 0;
|
||||
while (totalclock < nTicks)
|
||||
{
|
||||
gameHandleEvents();
|
||||
auto key = inputState.keyGetScan();
|
||||
if (key)
|
||||
{
|
||||
if (key == sc_Escape) // sc_Escape
|
||||
exitCredits = 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
JobDesc jobs[6];
|
||||
int job = 0;
|
||||
static AnimSound logosound[] =
|
||||
{
|
||||
{ 1, -1 },
|
||||
{ -1, -1 },
|
||||
{ 1, -1 },
|
||||
{ -1,-1 }
|
||||
};
|
||||
|
||||
if (logosound[0].soundnum == -1)
|
||||
{
|
||||
logosound[0].soundnum = S_FindSound("logo.wav");
|
||||
logosound[2].soundnum = S_FindSound("gt.wav");
|
||||
}
|
||||
|
||||
|
||||
if (fileSystem.FindFile("logo.smk"))
|
||||
{
|
||||
jobs[job++] = { PlayVideo("logo.smk", &logosound[0], 0) };
|
||||
}
|
||||
else
|
||||
{
|
||||
jobs[job++] = { Create<DBlackScreen>(1), []() { sndStartSample("THUNDER2", 128, -1); }};
|
||||
jobs[job++] = { Create<DImageScreen>(2050) };
|
||||
}
|
||||
if (fileSystem.FindFile("gti.smk"))
|
||||
{
|
||||
jobs[job++] = { PlayVideo("gti.smk", &logosound[2], 0) };
|
||||
}
|
||||
else
|
||||
{
|
||||
jobs[job++] = { Create<DBlackScreen>(1), []() { sndStartSample("THUNDER2", 128, -1); }};
|
||||
jobs[job++] = { Create<DImageScreen>(2052) };
|
||||
}
|
||||
jobs[job++] = { Create<DBlackScreen>(1), []() { sndPlaySpecialMusicOrNothing(MUS_INTRO); sndStartSample("THUNDER2", 128, -1); }};
|
||||
jobs[job++] = { Create<DImageScreen>(2518, DScreenJob::fadein) };
|
||||
|
||||
RunScreenJob(jobs, job, [](bool) {
|
||||
gamestate = GS_DEMOSCREEN;
|
||||
M_StartControlPanel(false);
|
||||
M_SetMenu(NAME_Mainmenu);
|
||||
}, true, true);
|
||||
}
|
||||
|
||||
char DoFade(char r, char g, char b, int nTicks)
|
||||
void playSmk(const char *smk, const char *wav, int wavid, CompletionFunc func)
|
||||
{
|
||||
return 1;
|
||||
JobDesc jobs{};
|
||||
static AnimSound smksound[] =
|
||||
{
|
||||
{ 1, -1 },
|
||||
{ -1, -1 },
|
||||
};
|
||||
int id = S_FindSoundByResID(wavid);
|
||||
if (id <= 0)
|
||||
{
|
||||
FString wavv = wav;
|
||||
FixPathSeperator(wavv);
|
||||
id = S_FindSound(wavv);
|
||||
}
|
||||
FString smkk = smk;
|
||||
FixPathSeperator(smkk);
|
||||
smksound[0].soundnum = id;
|
||||
jobs.job = PlayVideo(smkk, smksound, nullptr);
|
||||
RunScreenJob(&jobs, 1, func);
|
||||
}
|
||||
|
||||
char DoUnFade(int nTicks)
|
||||
void levelPlayIntroScene(int nEpisode, CompletionFunc completion)
|
||||
{
|
||||
return 1;
|
||||
gGameOptions.uGameFlags &= ~4;
|
||||
Mus_Stop();
|
||||
sndKillAllSounds();
|
||||
sfxKillAllSounds();
|
||||
ambKillAll();
|
||||
seqKillAll();
|
||||
EPISODEINFO *pEpisode = &gEpisodeInfo[nEpisode];
|
||||
playSmk(pEpisode->at8f08, pEpisode->at9030, pEpisode->at9028, completion);
|
||||
}
|
||||
|
||||
void credPlaySmk(const char* _pzSMK, const char* _pzWAV, int nWav);
|
||||
|
||||
void credLogosDos(void)
|
||||
void levelPlayEndScene(int nEpisode, CompletionFunc completion)
|
||||
{
|
||||
char bShift = inputState.ShiftPressed();
|
||||
videoSetViewableArea(0, 0, xdim-1, ydim-1);
|
||||
DoUnFade(1);
|
||||
if (bShift)
|
||||
return;
|
||||
{
|
||||
if (fileSystem.FindFile("logo.smk"))
|
||||
{
|
||||
credPlaySmk("logo.smk", "logo.wav", -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
twod->ClearScreen();
|
||||
rotatesprite(160<<16, 100<<16, 65536, 0, 2050, 0, 0, 0x4a, 0, 0, xdim-1, ydim-1);
|
||||
sndStartSample("THUNDER2", 128, -1);
|
||||
videoNextPage();
|
||||
if (!Wait(360))
|
||||
return;
|
||||
if (!DoFade(0, 0, 0, 60))
|
||||
return;
|
||||
}
|
||||
if (fileSystem.FindFile("gti.smk"))
|
||||
{
|
||||
credPlaySmk("gti.smk", "gt.wav", -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
twod->ClearScreen();
|
||||
rotatesprite(160<<16, 100<<16, 65536, 0, 2052, 0, 0, 0x0a, 0, 0, xdim-1, ydim-1);
|
||||
videoNextPage();
|
||||
DoUnFade(1);
|
||||
sndStartSample("THUNDER2", 128, -1);
|
||||
if (!Wait(360))
|
||||
return;
|
||||
}
|
||||
}
|
||||
sndPlaySpecialMusicOrNothing(MUS_INTRO);
|
||||
sndStartSample("THUNDER2", 128, -1);
|
||||
if (!DoFade(0, 0, 0, 60))
|
||||
return;
|
||||
twod->ClearScreen();
|
||||
videoNextPage();
|
||||
if (!DoUnFade(1))
|
||||
return;
|
||||
twod->ClearScreen();
|
||||
rotatesprite(160<<16, 100<<16, 65536, 0, 2518, 0, 0, 0x4a, 0, 0, xdim-1, ydim-1);
|
||||
videoNextPage();
|
||||
Wait(360);
|
||||
//Mus_Fade(4000);
|
||||
}
|
||||
|
||||
void credReset(void)
|
||||
{
|
||||
twod->ClearScreen();
|
||||
videoNextPage();
|
||||
DoFade(0,0,0,1);
|
||||
DoUnFade(1);
|
||||
}
|
||||
|
||||
bool credKOpen4Load(FString &pzFile)
|
||||
{
|
||||
int nLen = strlen(pzFile);
|
||||
FixPathSeperator(pzFile);
|
||||
auto nHandle = fileSystem.FindFile(pzFile);
|
||||
if (nHandle < 0)
|
||||
{
|
||||
// Strip the drive letter and retry.
|
||||
if (nLen >= 3 && isalpha(pzFile[0]) && pzFile[1] == ':' && pzFile[2] == '/')
|
||||
{
|
||||
pzFile = pzFile.Mid(3);
|
||||
nHandle = fileSystem.FindFile(pzFile);
|
||||
}
|
||||
}
|
||||
return nHandle;
|
||||
}
|
||||
|
||||
void credPlaySmk(const char *_pzSMK, const char *_pzWAV, int nWav)
|
||||
{
|
||||
if (!_pzSMK || !*_pzSMK)
|
||||
return;
|
||||
FString pzSMK = _pzSMK;
|
||||
FString pzWAV = _pzWAV;
|
||||
auto nHandleSMK = credKOpen4Load(pzSMK);
|
||||
if (!nHandleSMK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
SmackerHandle hSMK = Smacker_Open(pzSMK);
|
||||
if (!hSMK.isValid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
uint32_t nWidth, nHeight;
|
||||
Smacker_GetFrameSize(hSMK, nWidth, nHeight);
|
||||
uint8_t palette[768];
|
||||
AnimTextures animtex;
|
||||
TArray<uint8_t> pFrame(nWidth * nHeight + std::max(nWidth, nHeight), true);
|
||||
animtex.SetSize(AnimTexture::Paletted, nWidth, nHeight);
|
||||
int nFrameRate = Smacker_GetFrameRate(hSMK);
|
||||
int nFrames = Smacker_GetNumFrames(hSMK);
|
||||
|
||||
Smacker_GetPalette(hSMK, palette);
|
||||
gGameOptions.uGameFlags &= ~8;
|
||||
Mus_Stop();
|
||||
|
||||
int nScale;
|
||||
int nStat;
|
||||
|
||||
if (nWidth <= 320 && nHeight <= 200)
|
||||
{
|
||||
if ((nWidth / (nHeight * 1.2f)) > (1.f * xdim / ydim))
|
||||
nScale = divscale16(320 * xdim * 3, nWidth * ydim * 4);
|
||||
else
|
||||
nScale = divscale16(200, nHeight);
|
||||
nStat = 2 | 8 | 64;
|
||||
}
|
||||
else
|
||||
{
|
||||
// DOS Blood v1.11: 320x240, 320x320, 640x400, and 640x480 SMKs all display 1:1 and centered in a 640x480 viewport
|
||||
int num = scale(65536, ydim << 2, xdim * 3);
|
||||
int div = (max(nHeight, 240 + 1u) + 239) / 240;
|
||||
nScale = num / div;
|
||||
nStat = 2 | 8 | 64 | 1024;
|
||||
renderSetAspect(viewingrange, 65536);
|
||||
}
|
||||
|
||||
|
||||
if (nWav > 0)
|
||||
sndStartWavID(nWav, 255);
|
||||
else
|
||||
{
|
||||
auto nHandleWAV = credKOpen4Load(pzWAV);
|
||||
if (nHandleWAV)
|
||||
{
|
||||
sndStartWavDisk(pzWAV, 255);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gameHandleEvents();
|
||||
ClockTicks nStartTime = totalclock;
|
||||
|
||||
inputState.ClearAllInput();
|
||||
|
||||
int nFrame = 0;
|
||||
hw_int_useindexedcolortextures = false;
|
||||
do
|
||||
{
|
||||
gameHandleEvents();
|
||||
if (scale((int)(totalclock-nStartTime), nFrameRate, kTicRate) < nFrame)
|
||||
continue;
|
||||
|
||||
if (inputState.CheckAllInput())
|
||||
break;
|
||||
|
||||
twod->ClearScreen();
|
||||
Smacker_GetPalette(hSMK, palette);
|
||||
Smacker_GetFrame(hSMK, pFrame.Data());
|
||||
animtex.SetFrame(palette, pFrame.Data());
|
||||
rotatesprite_fs(160<<16, 100<<16, nScale, 0, -1, 0, 0, nStat, animtex.GetFrame());
|
||||
|
||||
videoNextPage();
|
||||
|
||||
nFrame++;
|
||||
Smacker_GetNextFrame(hSMK);
|
||||
} while(nFrame < nFrames);
|
||||
hw_int_useindexedcolortextures = hw_useindexedcolortextures;
|
||||
|
||||
Smacker_Close(hSMK);
|
||||
inputState.ClearAllInput();
|
||||
soundEngine->StopAllChannels();
|
||||
sndKillAllSounds();
|
||||
sfxKillAllSounds();
|
||||
ambKillAll();
|
||||
seqKillAll();
|
||||
EPISODEINFO *pEpisode = &gEpisodeInfo[nEpisode];
|
||||
playSmk(pEpisode->at8f98, pEpisode->at90c0, pEpisode->at902c, completion);
|
||||
}
|
||||
|
||||
|
||||
|
||||
END_BLD_NS
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||
Copyright (C) 2019 Nuke.YKT
|
||||
|
||||
This file is part of NBlood.
|
||||
|
||||
NBlood is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
BEGIN_BLD_NS
|
||||
|
||||
void credLogosDos(void);
|
||||
void credReset(void);
|
||||
void credPlaySmk(const char *pzSMK, const char *pzWAV, int nWAV);
|
||||
|
||||
END_BLD_NS
|
|
@ -37,6 +37,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include "c_bind.h"
|
||||
#include "menu.h"
|
||||
#include "sound.h"
|
||||
#include "gamestate.h"
|
||||
|
||||
bool ShowOptionMenu();
|
||||
|
||||
|
@ -247,7 +248,7 @@ void GameInterface::MenuClosed()
|
|||
|
||||
bool GameInterface::CanSave()
|
||||
{
|
||||
return (gGameStarted && gPlayer[myconnectindex].pXSprite->health != 0);
|
||||
return (gamestate == GS_LEVEL && gPlayer[myconnectindex].pXSprite->health != 0);
|
||||
}
|
||||
|
||||
void GameInterface::StartGame(FNewGameStartup& gs)
|
||||
|
|
|
@ -39,6 +39,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include "messages.h"
|
||||
#include "statistics.h"
|
||||
#include "gstrings.h"
|
||||
#include "gamestate.h"
|
||||
#include "raze_sound.h"
|
||||
|
||||
BEGIN_BLD_NS
|
||||
|
@ -86,8 +87,7 @@ void CEndGameMgr::ProcessKeys(void)
|
|||
//}
|
||||
//else
|
||||
{
|
||||
char ch = inputState.keyGetScan();
|
||||
if (!ch)
|
||||
if (!inputState.CheckAllInput())
|
||||
return;
|
||||
if (gGameOptions.nGameType > 0 || numplayers > 1)
|
||||
netWaitForEveryone(0);
|
||||
|
@ -99,8 +99,7 @@ extern void EndLevel(void);
|
|||
|
||||
void CEndGameMgr::Setup(void)
|
||||
{
|
||||
at1 = gInputMode;
|
||||
gInputMode = kInputEndGame;
|
||||
gamestate = GS_FINALE;
|
||||
at0 = 1;
|
||||
STAT_Update(false);
|
||||
EndLevel();
|
||||
|
@ -119,7 +118,6 @@ void CEndGameMgr::Finish(void)
|
|||
gInitialNetPlayers = numplayers;
|
||||
soundEngine->StopAllChannels();
|
||||
gStartNewGame = 1;
|
||||
gInputMode = (INPUT_MODE)at1;
|
||||
at0 = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
|
||||
#include "blood.h"
|
||||
#include "globals.h"
|
||||
#include "credits.h"
|
||||
#include "endgame.h"
|
||||
#include "inifile.h"
|
||||
#include "levels.h"
|
||||
|
@ -56,7 +55,6 @@ EPISODEINFO gEpisodeInfo[kMaxEpisodes+1];
|
|||
int gSkill = 2;
|
||||
int gEpisodeCount;
|
||||
int gNextLevel;
|
||||
bool gGameStarted;
|
||||
|
||||
int gLevelTime;
|
||||
|
||||
|
@ -83,35 +81,6 @@ void levelOverrideINI(const char *pzIni)
|
|||
strcpy(BloodIniFile, pzIni);
|
||||
}
|
||||
|
||||
void levelPlayIntroScene(int nEpisode)
|
||||
{
|
||||
gGameOptions.uGameFlags &= ~4;
|
||||
Mus_SetPaused(true);
|
||||
sndKillAllSounds();
|
||||
sfxKillAllSounds();
|
||||
ambKillAll();
|
||||
seqKillAll();
|
||||
EPISODEINFO *pEpisode = &gEpisodeInfo[nEpisode];
|
||||
credPlaySmk(pEpisode->at8f08, pEpisode->at9030, pEpisode->at9028);
|
||||
viewResizeView(gViewSize);
|
||||
credReset();
|
||||
Mus_SetPaused(false);
|
||||
}
|
||||
|
||||
void levelPlayEndScene(int nEpisode)
|
||||
{
|
||||
gGameOptions.uGameFlags &= ~8;
|
||||
Mus_Stop();
|
||||
sndKillAllSounds();
|
||||
sfxKillAllSounds();
|
||||
ambKillAll();
|
||||
seqKillAll();
|
||||
EPISODEINFO *pEpisode = &gEpisodeInfo[nEpisode];
|
||||
credPlaySmk(pEpisode->at8f98, pEpisode->at90c0, pEpisode->at902c);
|
||||
viewResizeView(gViewSize);
|
||||
credReset();
|
||||
}
|
||||
|
||||
void levelClearSecrets(void)
|
||||
{
|
||||
gSecretMgr.Clear();
|
||||
|
@ -412,14 +381,12 @@ void LevelsLoadSave::Load(void)
|
|||
{
|
||||
Read(&gNextLevel, sizeof(gNextLevel));
|
||||
Read(&gGameOptions, sizeof(gGameOptions));
|
||||
Read(&gGameStarted, sizeof(gGameStarted));
|
||||
}
|
||||
|
||||
void LevelsLoadSave::Save(void)
|
||||
{
|
||||
Write(&gNextLevel, sizeof(gNextLevel));
|
||||
Write(&gGameOptions, sizeof(gGameOptions));
|
||||
Write(&gGameStarted, sizeof(gGameStarted));
|
||||
}
|
||||
|
||||
void LevelsLoadSaveConstruct(void)
|
||||
|
|
|
@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
*/
|
||||
//-------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#include "screenjob.h"
|
||||
#include "common_game.h"
|
||||
#include "inifile.h"
|
||||
#include "mapinfo.h"
|
||||
|
@ -98,8 +99,8 @@ extern int gLevelTime;
|
|||
|
||||
void levelInitINI(const char *pzIni);
|
||||
void levelOverrideINI(const char *pzIni);
|
||||
void levelPlayIntroScene(int nEpisode);
|
||||
void levelPlayEndScene(int nEpisode);
|
||||
void levelPlayIntroScene(int nEpisode, CompletionFunc completion);
|
||||
void levelPlayEndScene(int nEpisode, CompletionFunc completion);
|
||||
void levelSetupSecret(int nCount);
|
||||
void levelTriggerSecret(int nSecret);
|
||||
void CheckSectionAbend(const char *pzSection);
|
||||
|
|
|
@ -44,6 +44,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include "savegamehelp.h"
|
||||
#include "raze_music.h"
|
||||
#include "mapinfo.h"
|
||||
#include "gamestate.h"
|
||||
|
||||
#include "aistate.h"
|
||||
#include "aiunicult.h"
|
||||
|
@ -480,7 +481,7 @@ bool GameInterface::LoadGame(FSaveGameNode* node)
|
|||
sfxKillAllSounds();
|
||||
ambKillAll();
|
||||
seqKillAll();
|
||||
if (!gGameStarted)
|
||||
if (gamestate != GS_LEVEL)
|
||||
{
|
||||
memset(xsprite, 0, sizeof(xsprite));
|
||||
}
|
||||
|
@ -524,7 +525,7 @@ bool GameInterface::LoadGame(FSaveGameNode* node)
|
|||
else
|
||||
gGameMessageMgr.Clear();
|
||||
viewSetErrorMessage("");
|
||||
if (!gGameStarted)
|
||||
if (gamestate != GS_LEVEL)
|
||||
{
|
||||
netWaitForEveryone(0);
|
||||
memset(gPlayerReady, 0, sizeof(gPlayerReady));
|
||||
|
@ -534,7 +535,7 @@ bool GameInterface::LoadGame(FSaveGameNode* node)
|
|||
gFrameRate = 0;
|
||||
totalclock = 0;
|
||||
paused = 0;
|
||||
gGameStarted = 1;
|
||||
gamestate = GS_LEVEL;
|
||||
bVanilla = false;
|
||||
|
||||
|
||||
|
|
|
@ -337,7 +337,7 @@ void CGameMessageMgr::Display(void)
|
|||
{
|
||||
if (VanillaMode())
|
||||
{
|
||||
if (numberOfDisplayedMessages && this->state && gInputMode != kInputMessage)
|
||||
if (numberOfDisplayedMessages && this->state)
|
||||
{
|
||||
int initialNrOfDisplayedMsgs = numberOfDisplayedMessages;
|
||||
int initialMessagesIndex = messagesIndex;
|
||||
|
@ -368,7 +368,7 @@ void CGameMessageMgr::Display(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (this->state && gInputMode != kInputMessage)
|
||||
if (this->state)
|
||||
{
|
||||
messageStruct* currentMessages[kMessageLogSize];
|
||||
int currentMessagesCount = 0;
|
||||
|
@ -500,7 +500,6 @@ void CPlayerMsg::Clear(void)
|
|||
void CPlayerMsg::Term(void)
|
||||
{
|
||||
Clear();
|
||||
gInputMode = kInputGame;
|
||||
}
|
||||
|
||||
void CPlayerMsg::Draw(void)
|
||||
|
|
|
@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
|
||||
BEGIN_BLD_NS
|
||||
|
||||
void playlogos();
|
||||
void *ResReadLine(char *buffer, unsigned int nBytes, void **pRes);
|
||||
unsigned int qrand(void);
|
||||
int wrand(void);
|
||||
|
|
|
@ -37,6 +37,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include "sound.h"
|
||||
#include "view.h"
|
||||
#include "menu.h"
|
||||
#include "gamestate.h"
|
||||
|
||||
extern bool gHaveNetworking;
|
||||
|
||||
|
@ -1326,7 +1327,7 @@ void netPlayerQuit(int nPlayer)
|
|||
char buffer[128];
|
||||
sprintf(buffer, "%s left the game with %d frags.", gProfile[nPlayer].name, gPlayer[nPlayer].fragCount);
|
||||
viewSetMessage(buffer);
|
||||
if (gGameStarted)
|
||||
if (gamestate == GS_LEVEL)
|
||||
{
|
||||
seqKill(3, gPlayer[nPlayer].pSprite->extra);
|
||||
actPostSprite(gPlayer[nPlayer].nSprite, kStatFree);
|
||||
|
|
|
@ -37,6 +37,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include "sound.h"
|
||||
#include "view.h"
|
||||
#include "mapinfo.h"
|
||||
#include "gamestate.h"
|
||||
|
||||
BEGIN_BLD_NS
|
||||
|
||||
|
@ -89,7 +90,7 @@ static int osdcmd_map(CCmdFuncPtr parm)
|
|||
|
||||
static int osdcmd_give(CCmdFuncPtr parm)
|
||||
{
|
||||
if (numplayers != 1 || !gGameStarted || gMe->pXSprite->health == 0)
|
||||
if (numplayers != 1 || gamestate != GS_LEVEL|| gMe->pXSprite->health == 0)
|
||||
{
|
||||
Printf("give: Cannot give while dead or not in a single-player game.\n");
|
||||
return CCMD_OK;
|
||||
|
@ -149,7 +150,7 @@ static int osdcmd_give(CCmdFuncPtr parm)
|
|||
static int osdcmd_god(CCmdFuncPtr UNUSED(parm))
|
||||
{
|
||||
UNREFERENCED_CONST_PARAMETER(parm);
|
||||
if (numplayers == 1 && gGameStarted)
|
||||
if (numplayers == 1 && gamestate == GS_LEVEL)
|
||||
{
|
||||
SetGodMode(!gMe->godMode);
|
||||
gCheatMgr.m_bPlayerCheated = true;
|
||||
|
@ -164,7 +165,7 @@ static int osdcmd_noclip(CCmdFuncPtr UNUSED(parm))
|
|||
{
|
||||
UNREFERENCED_CONST_PARAMETER(parm);
|
||||
|
||||
if (numplayers == 1 && gGameStarted)
|
||||
if (numplayers == 1 && gamestate == GS_LEVEL)
|
||||
{
|
||||
SetClipMode(!gNoClip);
|
||||
gCheatMgr.m_bPlayerCheated = true;
|
||||
|
|
|
@ -225,12 +225,6 @@ void Mus_Stop()
|
|||
S_StopMusic(true);
|
||||
}
|
||||
|
||||
void Mus_Fade(double seconds)
|
||||
{
|
||||
// Todo: Blood uses this, but the streamer cannot currently fade the volume.
|
||||
Mus_Stop();
|
||||
}
|
||||
|
||||
void Mus_SetPaused(bool on)
|
||||
{
|
||||
if (on) S_PauseMusic();
|
||||
|
|
|
@ -13,7 +13,6 @@ void Mus_UpdateMusic();
|
|||
int Mus_Play(const char *mapname, const char *fn, bool loop);
|
||||
void Mus_Stop();
|
||||
bool Mus_IsPlaying();
|
||||
void Mus_Fade(double seconds);
|
||||
void Mus_SetPaused(bool on);
|
||||
void Mus_ResumeSaved();
|
||||
FString G_SetupFilenameBasedMusic(const char* fileName, const char *defaultfn);
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "gamestate.h"
|
||||
#include "menu.h"
|
||||
#include "raze_sound.h"
|
||||
#include "SmackerDecoder.h"
|
||||
#include "movie/playmve.h"
|
||||
#include "gamecontrol.h"
|
||||
|
||||
|
@ -52,6 +53,14 @@
|
|||
IMPLEMENT_CLASS(DScreenJob, true, false)
|
||||
IMPLEMENT_CLASS(DImageScreen, true, false)
|
||||
|
||||
|
||||
int DBlackScreen::Frame(uint64_t clock, bool skiprequest)
|
||||
{
|
||||
int span = int(clock / 1'000'000);
|
||||
twod->ClearScreen();
|
||||
return span < wait ? 1 : -1;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
|
@ -69,7 +78,7 @@ int DImageScreen::Frame(uint64_t clock, bool skiprequest)
|
|||
twod->ClearScreen();
|
||||
DrawTexture(twod, tex, 0, 0, DTA_FullscreenEx, 3, DTA_LegacyRenderStyle, STYLE_Normal, TAG_DONE);
|
||||
// Only end after having faded out.
|
||||
return skiprequest ? -1 : 1;
|
||||
return skiprequest ? -1 : span > waittime? 0 : 1;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -212,6 +221,103 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
class DSmkPlayer : public DScreenJob
|
||||
{
|
||||
SmackerHandle hSMK{};
|
||||
uint32_t nWidth, nHeight;
|
||||
uint8_t palette[768];
|
||||
AnimTextures animtex;
|
||||
TArray<uint8_t> pFrame;
|
||||
int nFrameRate;
|
||||
int nFrames;
|
||||
bool fullscreenScale;
|
||||
uint64_t nFrameNs;
|
||||
int nFrame = 0;
|
||||
const AnimSound* animSnd;
|
||||
FString filename;
|
||||
|
||||
public:
|
||||
bool isvalid() { return hSMK.isValid; }
|
||||
|
||||
DSmkPlayer(const char *fn, const AnimSound* ans, bool fixedviewport)
|
||||
{
|
||||
hSMK = Smacker_Open(fn);
|
||||
if (!hSMK.isValid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Smacker_GetFrameSize(hSMK, nWidth, nHeight);
|
||||
pFrame.Resize(nWidth * nHeight + std::max(nWidth, nHeight));
|
||||
nFrameRate = Smacker_GetFrameRate(hSMK);
|
||||
nFrameNs = 1'000'000'000 / nFrameRate;
|
||||
nFrames = Smacker_GetNumFrames(hSMK);
|
||||
Smacker_GetPalette(hSMK, palette);
|
||||
fullscreenScale = (!fixedviewport || (nWidth <= 320 && nHeight <= 200) || nWidth >= 640 || nHeight >= 480);
|
||||
animSnd = ans;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
int Frame(uint64_t clock, bool skiprequest) override
|
||||
{
|
||||
int frame = clock / nFrameNs;
|
||||
|
||||
if (clock == 0)
|
||||
{
|
||||
animtex.SetSize(AnimTexture::Paletted, nWidth, nHeight);
|
||||
}
|
||||
twod->ClearScreen();
|
||||
if (frame > nFrame)
|
||||
{
|
||||
Smacker_GetPalette(hSMK, palette);
|
||||
Smacker_GetFrame(hSMK, pFrame.Data());
|
||||
animtex.SetFrame(palette, pFrame.Data());
|
||||
}
|
||||
if (fullscreenScale)
|
||||
{
|
||||
DrawTexture(twod, animtex.GetFrame(), 0, 0, DTA_FullscreenEx, 3, TAG_DONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawTexture(twod, animtex.GetFrame(), 320, 240, DTA_VirtualWidth, 640, DTA_VirtualHeight, 480, DTA_CenterOffset, true, TAG_DONE);
|
||||
}
|
||||
if (frame > nFrame)
|
||||
{
|
||||
nFrame++;
|
||||
Smacker_GetNextFrame(hSMK);
|
||||
for (int i = 0; animSnd[i].framenum >= 0; i++)
|
||||
{
|
||||
if (animSnd[i].framenum == nFrame)
|
||||
{
|
||||
int sound = animSnd[i].soundnum;
|
||||
if (sound == -1)
|
||||
soundEngine->StopAllChannels();
|
||||
else
|
||||
soundEngine->StartSound(SOURCE_None, nullptr, nullptr, CHAN_AUTO, CHANF_UI, sound, 1.f, ATTN_NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return skiprequest ? -1 : nFrame < nFrames ? 1 : 0;
|
||||
}
|
||||
|
||||
void OnDestroy() override
|
||||
{
|
||||
Smacker_Close(hSMK);
|
||||
soundEngine->StopAllChannels();
|
||||
}
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
|
@ -228,6 +334,13 @@ DScreenJob* PlayVideo(const char* filename, const AnimSound* ans, const int* fra
|
|||
auto fr = fileSystem.OpenFileReader(filename);
|
||||
if (!fr.isOpen())
|
||||
{
|
||||
int nLen = strlen(filename);
|
||||
// Strip the drive letter and retry.
|
||||
if (nLen >= 3 && isalpha(filename[0]) && filename[1] == ':' && filename[2] == '/')
|
||||
{
|
||||
filename += 3;
|
||||
fr = fileSystem.OpenFileReader(filename);
|
||||
}
|
||||
Printf("%s: Unable to open video\n", filename);
|
||||
return nothing();
|
||||
}
|
||||
|
@ -243,13 +356,21 @@ DScreenJob* PlayVideo(const char* filename, const AnimSound* ans, const int* fra
|
|||
{
|
||||
Printf("%s: invalid ANM file.\n", filename);
|
||||
anm->Destroy();
|
||||
return nothing();
|
||||
return nothing();
|
||||
}
|
||||
return anm;
|
||||
}
|
||||
else if (!memcmp(id, "SMK2", 4))
|
||||
{
|
||||
// todo
|
||||
fr.Close();
|
||||
auto anm = Create<DSmkPlayer>(filename, ans, true); // Fixme: Handle Blood's video scaling behavior more intelligently.
|
||||
if (!anm->isvalid())
|
||||
{
|
||||
Printf("%s: invalid SMK file.\n", filename);
|
||||
anm->Destroy();
|
||||
return nothing();
|
||||
}
|
||||
return anm;
|
||||
}
|
||||
else if (!memcmp(id, "Interplay MVE File", 18))
|
||||
{
|
||||
|
@ -317,7 +438,6 @@ public:
|
|||
{
|
||||
for (auto& job : jobs)
|
||||
{
|
||||
job.job->Destroy();
|
||||
job.job->ObjectFlags |= OF_YesReallyDelete;
|
||||
delete job.job;
|
||||
}
|
||||
|
@ -326,9 +446,17 @@ public:
|
|||
|
||||
void AdvanceJob(bool skip)
|
||||
{
|
||||
if (index >= 0 && jobs[index].postAction) jobs[index].postAction();
|
||||
if (index >= 0)
|
||||
{
|
||||
if (jobs[index].postAction) jobs[index].postAction();
|
||||
jobs[index].job->Destroy();
|
||||
}
|
||||
index++;
|
||||
while (index < jobs.Size() && (jobs[index].job == nullptr || (skip && jobs[index].ignoreifskipped))) index++;
|
||||
while (index < jobs.Size() && (jobs[index].job == nullptr || (skip && jobs[index].ignoreifskipped)))
|
||||
{
|
||||
if (jobs[index].job != nullptr) jobs[index].job->Destroy();
|
||||
index++;
|
||||
}
|
||||
actionState = clearbefore ? State_Clear : State_Run;
|
||||
if (index < jobs.Size()) screenfade = jobs[index].job->fadestyle & DScreenJob::fadein ? 0.f : 1.f;
|
||||
startTime = -1;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
#include <functional>
|
||||
#include "dobject.h"
|
||||
#include "v_2ddrawer.h"
|
||||
|
||||
using CompletionFunc = std::function<void(bool)>;
|
||||
struct JobDesc;
|
||||
|
@ -47,20 +48,36 @@ public:
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
class DBlackScreen : public DScreenJob
|
||||
{
|
||||
int wait;
|
||||
|
||||
public:
|
||||
DBlackScreen(int w) : wait(w) {}
|
||||
int Frame(uint64_t clock, bool skiprequest) override;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
class DImageScreen : public DScreenJob
|
||||
{
|
||||
DECLARE_CLASS(DImageScreen, DScreenJob)
|
||||
|
||||
int tilenum = -1;
|
||||
int waittime; // in ms.
|
||||
FGameTexture* tex = nullptr;
|
||||
|
||||
public:
|
||||
DImageScreen(FGameTexture* tile, int fade = DScreenJob::fadein | DScreenJob::fadeout) : DScreenJob(fade)
|
||||
DImageScreen(FGameTexture* tile, int fade = DScreenJob::fadein | DScreenJob::fadeout, int wait = 3000) : DScreenJob(fade), waittime(wait)
|
||||
{
|
||||
tex = tile;
|
||||
}
|
||||
|
||||
DImageScreen(int tile, int fade = DScreenJob::fadein | DScreenJob::fadeout) : DScreenJob(fade)
|
||||
DImageScreen(int tile, int fade = DScreenJob::fadein | DScreenJob::fadeout, int wait = 3000) : DScreenJob(fade), waittime(wait)
|
||||
{
|
||||
tilenum = tile;
|
||||
}
|
||||
|
|
|
@ -373,26 +373,6 @@ public:
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
class DBlackScreen : public DScreenJob
|
||||
{
|
||||
int wait;
|
||||
|
||||
public:
|
||||
DBlackScreen(int w) : wait(w) {}
|
||||
int Frame(uint64_t clock, bool skiprequest)
|
||||
{
|
||||
int span = int(clock / 1'000'000);
|
||||
twod->ClearScreen();
|
||||
return span < wait ? 1 : -1;
|
||||
}
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
class DEpisode3End : public DImageScreen
|
||||
{
|
||||
int sound = 0;
|
||||
|
|
Loading…
Reference in a new issue