mirror of
https://github.com/ZDoom/raze-gles.git
synced 2025-01-15 12:10:53 +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 "blood.h"
|
||||||
#include "choke.h"
|
#include "choke.h"
|
||||||
#include "controls.h"
|
#include "controls.h"
|
||||||
#include "credits.h"
|
|
||||||
#include "dude.h"
|
#include "dude.h"
|
||||||
#include "endgame.h"
|
#include "endgame.h"
|
||||||
#include "eventq.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 "raze_sound.h"
|
||||||
#include "nnexts.h"
|
#include "nnexts.h"
|
||||||
#include "secrets.h"
|
#include "secrets.h"
|
||||||
|
#include "gamestate.h"
|
||||||
|
#include "screenjob.h"
|
||||||
|
|
||||||
BEGIN_BLD_NS
|
BEGIN_BLD_NS
|
||||||
|
|
||||||
|
|
||||||
INPUT_MODE gInputMode;
|
|
||||||
|
|
||||||
#ifdef USE_QHEAP
|
|
||||||
unsigned int nMaxAlloc = 0x4000000;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char bAddUserMap = false;
|
char bAddUserMap = false;
|
||||||
bool bNoDemo = false;
|
bool bNoDemo = false;
|
||||||
bool bQuickStart = true;
|
bool bQuickStart = true;
|
||||||
|
@ -80,8 +75,6 @@ short BloodVersion = 0x115;
|
||||||
|
|
||||||
int gNetPlayers;
|
int gNetPlayers;
|
||||||
|
|
||||||
char *pUserTiles = NULL;
|
|
||||||
|
|
||||||
int gChokeCounter = 0;
|
int gChokeCounter = 0;
|
||||||
|
|
||||||
double g_gameUpdateTime, g_gameUpdateAndDrawTime;
|
double g_gameUpdateTime, g_gameUpdateAndDrawTime;
|
||||||
|
@ -131,21 +124,9 @@ enum gametokens
|
||||||
|
|
||||||
int blood_globalflags;
|
int blood_globalflags;
|
||||||
|
|
||||||
void ShutDown(void)
|
|
||||||
{
|
|
||||||
if (!in3dmode())
|
|
||||||
return;
|
|
||||||
netDeinitialize();
|
|
||||||
//sndTerm();
|
|
||||||
sfxTerm();
|
|
||||||
// PORT_TODO: Check argument
|
|
||||||
DO_FREE_AND_NULL(pUserTiles);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QuitGame(void)
|
void QuitGame(void)
|
||||||
{
|
{
|
||||||
ShutDown();
|
throw CExitEvent(0);
|
||||||
Bexit(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrecacheDude(spritetype *pSprite)
|
void PrecacheDude(spritetype *pSprite)
|
||||||
|
@ -412,8 +393,6 @@ void StartLevel(GAMEOPTIONS *gameOptions)
|
||||||
if (gEpisodeInfo[gGameOptions.nEpisode].cutALevel == gGameOptions.nLevel
|
if (gEpisodeInfo[gGameOptions.nEpisode].cutALevel == gGameOptions.nLevel
|
||||||
&& gEpisodeInfo[gGameOptions.nEpisode].at8f08)
|
&& gEpisodeInfo[gGameOptions.nEpisode].at8f08)
|
||||||
gGameOptions.uGameFlags |= 4;
|
gGameOptions.uGameFlags |= 4;
|
||||||
if ((gGameOptions.uGameFlags&4))
|
|
||||||
levelPlayIntroScene(gGameOptions.nEpisode);
|
|
||||||
|
|
||||||
///////
|
///////
|
||||||
gGameOptions.weaponsV10x = gWeaponsV10x;
|
gGameOptions.weaponsV10x = gWeaponsV10x;
|
||||||
|
@ -455,11 +434,10 @@ void StartLevel(GAMEOPTIONS *gameOptions)
|
||||||
enginecompatibility_mode = ENGINECOMPATIBILITY_19960925;//bVanilla;
|
enginecompatibility_mode = ENGINECOMPATIBILITY_19960925;//bVanilla;
|
||||||
memset(xsprite,0,sizeof(xsprite));
|
memset(xsprite,0,sizeof(xsprite));
|
||||||
memset(sprite,0,kMaxSprites*sizeof(spritetype));
|
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))
|
if (dbLoadMap(gameOptions->zLevelName,(int*)&startpos.x,(int*)&startpos.y,(int*)&startpos.z,&startang,&startsectnum,(unsigned int*)&gameOptions->uMapCRC))
|
||||||
{
|
{
|
||||||
gQuitGame = true;
|
I_Error("Unable to load map");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
currentLevel = &mapList[gGameOptions.nEpisode * kMaxLevels + gGameOptions.nLevel];
|
currentLevel = &mapList[gGameOptions.nEpisode * kMaxLevels + gGameOptions.nLevel];
|
||||||
SECRET_SetMapName(currentLevel->DisplayName(), currentLevel->name);
|
SECRET_SetMapName(currentLevel->DisplayName(), currentLevel->name);
|
||||||
|
@ -571,7 +549,6 @@ void StartLevel(GAMEOPTIONS *gameOptions)
|
||||||
gFrame = 0;
|
gFrame = 0;
|
||||||
gChokeCounter = 0;
|
gChokeCounter = 0;
|
||||||
M_ClearMenus();
|
M_ClearMenus();
|
||||||
levelTryPlayMusicOrNothing(gGameOptions.nEpisode, gGameOptions.nLevel);
|
|
||||||
// viewSetMessage("");
|
// viewSetMessage("");
|
||||||
viewSetErrorMessage("");
|
viewSetErrorMessage("");
|
||||||
viewResizeView(gViewSize);
|
viewResizeView(gViewSize);
|
||||||
|
@ -580,40 +557,9 @@ void StartLevel(GAMEOPTIONS *gameOptions)
|
||||||
netWaitForEveryone(0);
|
netWaitForEveryone(0);
|
||||||
totalclock = 0;
|
totalclock = 0;
|
||||||
paused = 0;
|
paused = 0;
|
||||||
gGameStarted = 1;
|
|
||||||
ready2send = 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)
|
void LocalKeys(void)
|
||||||
{
|
{
|
||||||
|
@ -778,22 +724,33 @@ void ProcessFrame(void)
|
||||||
netMasterUpdate();
|
netMasterUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Mus_Fade(4000);
|
|
||||||
seqKillAll();
|
seqKillAll();
|
||||||
if (gGameOptions.uGameFlags&2)
|
if (gGameOptions.uGameFlags&2)
|
||||||
{
|
{
|
||||||
STAT_Update(true);
|
STAT_Update(true);
|
||||||
if (gGameOptions.nGameType == 0)
|
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)
|
if (gGameOptions.uGameFlags&8)
|
||||||
levelPlayEndScene(gGameOptions.nEpisode);
|
{
|
||||||
|
levelPlayEndScene(gGameOptions.nEpisode, completion);
|
||||||
M_StartControlPanel(false);
|
}
|
||||||
M_SetMenu(NAME_CreditsMenu);
|
else completion(false);
|
||||||
}
|
}
|
||||||
gGameOptions.uGameFlags &= ~3;
|
else
|
||||||
gRestartGame = 1;
|
{
|
||||||
gQuitGame = 1;
|
gGameOptions.uGameFlags &= ~3;
|
||||||
|
gRestartGame = 1;
|
||||||
|
gQuitGame = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -876,13 +833,12 @@ static const char* actions[] = {
|
||||||
"Jetpack"
|
"Jetpack"
|
||||||
};
|
};
|
||||||
|
|
||||||
int GameInterface::app_main()
|
static void app_init()
|
||||||
{
|
{
|
||||||
|
|
||||||
buttonMap.SetButtons(actions, NUM_ACTIONS);
|
buttonMap.SetButtons(actions, NUM_ACTIONS);
|
||||||
memcpy(&gGameOptions, &gSingleGameOptions, sizeof(GAMEOPTIONS));
|
memcpy(&gGameOptions, &gSingleGameOptions, sizeof(GAMEOPTIONS));
|
||||||
gGameOptions.nMonsterSettings = !userConfig.nomonsters;
|
gGameOptions.nMonsterSettings = !userConfig.nomonsters;
|
||||||
bQuickStart = userConfig.nologo;
|
bQuickStart = userConfig.nologo;
|
||||||
ReadAllRFS();
|
ReadAllRFS();
|
||||||
|
|
||||||
HookReplaceFunctions();
|
HookReplaceFunctions();
|
||||||
|
@ -891,29 +847,20 @@ int GameInterface::app_main()
|
||||||
engineInit();
|
engineInit();
|
||||||
|
|
||||||
Printf("Loading tiles\n");
|
Printf("Loading tiles\n");
|
||||||
if (pUserTiles)
|
if (!tileInit(0, NULL))
|
||||||
{
|
I_FatalError("TILES###.ART files not found");
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
levelLoadDefaults();
|
levelLoadDefaults();
|
||||||
|
|
||||||
loaddefinitionsfile(BLOODWIDESCREENDEF);
|
loaddefinitionsfile(BLOODWIDESCREENDEF);
|
||||||
loaddefinitions_game(BLOODWIDESCREENDEF, FALSE);
|
loaddefinitions_game(BLOODWIDESCREENDEF, FALSE);
|
||||||
|
|
||||||
const char *defsfile = G_DefFile();
|
const char* defsfile = G_DefFile();
|
||||||
uint32_t stime = timerGetTicks();
|
uint32_t stime = timerGetTicks();
|
||||||
if (!loaddefinitionsfile(defsfile))
|
if (!loaddefinitionsfile(defsfile))
|
||||||
{
|
{
|
||||||
uint32_t etime = timerGetTicks();
|
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);
|
loaddefinitions_game(defsfile, FALSE);
|
||||||
powerupInit();
|
powerupInit();
|
||||||
|
@ -931,11 +878,10 @@ int GameInterface::app_main()
|
||||||
ctrlInit();
|
ctrlInit();
|
||||||
timerInit(120);
|
timerInit(120);
|
||||||
timerSetCallback(ClockStrobe);
|
timerSetCallback(ClockStrobe);
|
||||||
// PORT-TODO: CD audio init
|
|
||||||
|
|
||||||
Printf("Initializing network users\n");
|
Printf("Initializing network users\n");
|
||||||
netInitialize(true);
|
netInitialize(true);
|
||||||
videoInit();
|
videoInit();
|
||||||
hud_size.Callback();
|
hud_size.Callback();
|
||||||
Printf("Initializing sound system\n");
|
Printf("Initializing sound system\n");
|
||||||
sndInit();
|
sndInit();
|
||||||
|
@ -948,18 +894,17 @@ int GameInterface::app_main()
|
||||||
gStartNewGame = 1;
|
gStartNewGame = 1;
|
||||||
}
|
}
|
||||||
videoSetViewableArea(0, 0, xdim - 1, ydim - 1);
|
videoSetViewableArea(0, 0, xdim - 1, ydim - 1);
|
||||||
bool playvideo = !bQuickStart;
|
|
||||||
|
|
||||||
if (playvideo)
|
|
||||||
credLogosDos();
|
|
||||||
|
|
||||||
UpdateDacs(0, true);
|
UpdateDacs(0, true);
|
||||||
|
}
|
||||||
|
|
||||||
RESTART:
|
static void gameInit()
|
||||||
|
{
|
||||||
|
//RESTART:
|
||||||
sub_79760();
|
sub_79760();
|
||||||
gViewIndex = myconnectindex;
|
gViewIndex = myconnectindex;
|
||||||
gMe = gView = &gPlayer[myconnectindex];
|
gMe = gView = &gPlayer[myconnectindex];
|
||||||
netBroadcastPlayerInfo(myconnectindex);
|
netBroadcastPlayerInfo(myconnectindex);
|
||||||
|
#if 0
|
||||||
Printf("Waiting for network players!\n");
|
Printf("Waiting for network players!\n");
|
||||||
netWaitForEveryone(0);
|
netWaitForEveryone(0);
|
||||||
if (gRestartGame)
|
if (gRestartGame)
|
||||||
|
@ -971,134 +916,94 @@ RESTART:
|
||||||
netResetToSinglePlayer();
|
netResetToSinglePlayer();
|
||||||
goto RESTART;
|
goto RESTART;
|
||||||
}
|
}
|
||||||
UpdateNetworkMenus();
|
#endif
|
||||||
|
UpdateNetworkMenus();
|
||||||
gQuitGame = 0;
|
gQuitGame = 0;
|
||||||
gRestartGame = 0;
|
gRestartGame = 0;
|
||||||
if (gGameOptions.nGameType > 0)
|
if (gGameOptions.nGameType > 0)
|
||||||
{
|
{
|
||||||
inputState.ClearAllInput();
|
inputState.ClearAllInput();
|
||||||
}
|
}
|
||||||
if (!bAddUserMap && !gGameStarted)
|
|
||||||
{
|
}
|
||||||
M_StartControlPanel(false);
|
|
||||||
M_SetMenu(NAME_Mainmenu);
|
static void gameTicker()
|
||||||
}
|
{
|
||||||
ready2send = 1;
|
bool gameUpdate = false;
|
||||||
while (!gQuitGame)
|
double const gameUpdateStartTime = timerGetHiTicks();
|
||||||
|
while (gPredictTail < gNetFifoHead[myconnectindex] && !paused)
|
||||||
{
|
{
|
||||||
bool bDraw;
|
viewUpdatePrediction(&gFifoInput[gPredictTail & 255][myconnectindex]);
|
||||||
D_ProcessEvents();
|
}
|
||||||
if (gGameStarted) // gGameStarted: gameState == GS_LEVEL
|
if (numplayers == 1)
|
||||||
{
|
gBufferJitter = 0;
|
||||||
char gameUpdate = false;
|
while (totalclock >= gNetFifoClock && ready2send)
|
||||||
double const gameUpdateStartTime = timerGetHiTicks();
|
{
|
||||||
while (gPredictTail < gNetFifoHead[myconnectindex] && !paused)
|
gNetInput = gInput;
|
||||||
{
|
gInput = {};
|
||||||
viewUpdatePrediction(&gFifoInput[gPredictTail&255][myconnectindex]);
|
netGetInput();
|
||||||
}
|
gNetFifoClock += 4;
|
||||||
if (numplayers == 1)
|
while (gNetFifoHead[myconnectindex] - gNetFifoTail > gBufferJitter && !gStartNewGame && !gQuitGame)
|
||||||
gBufferJitter = 0;
|
{
|
||||||
while (totalclock >= gNetFifoClock && ready2send)
|
int i;
|
||||||
{
|
for (i = connecthead; i >= 0; i = connectpoint2[i])
|
||||||
gNetInput = gInput;
|
if (gNetFifoHead[i] == gNetFifoTail)
|
||||||
gInput = {};
|
break;
|
||||||
netGetInput();
|
if (i >= 0)
|
||||||
gNetFifoClock += 4;
|
break;
|
||||||
while (gNetFifoHead[myconnectindex]-gNetFifoTail > gBufferJitter && !gStartNewGame && !gQuitGame)
|
//faketimerhandler();
|
||||||
{
|
ProcessFrame();
|
||||||
int i;
|
gameUpdate = true;
|
||||||
for (i = connecthead; i >= 0; i = connectpoint2[i])
|
}
|
||||||
if (gNetFifoHead[i] == gNetFifoTail)
|
}
|
||||||
break;
|
if (gameUpdate)
|
||||||
if (i >= 0)
|
{
|
||||||
break;
|
g_gameUpdateTime = timerGetHiTicks() - gameUpdateStartTime;
|
||||||
//faketimerhandler();
|
if (g_gameUpdateAvgTime < 0.f)
|
||||||
ProcessFrame();
|
g_gameUpdateAvgTime = g_gameUpdateTime;
|
||||||
gameUpdate = true;
|
g_gameUpdateAvgTime = ((GAMEUPDATEAVGTIMENUMSAMPLES - 1.f) * g_gameUpdateAvgTime + g_gameUpdateTime) / ((float)GAMEUPDATEAVGTIMENUMSAMPLES);
|
||||||
}
|
}
|
||||||
}
|
if (gQuitRequest && gQuitGame)
|
||||||
if (gameUpdate)
|
videoClearScreen(0);
|
||||||
{
|
else
|
||||||
g_gameUpdateTime = timerGetHiTicks() - gameUpdateStartTime;
|
{
|
||||||
if (g_gameUpdateAvgTime < 0.f)
|
netCheckSync();
|
||||||
g_gameUpdateAvgTime = g_gameUpdateTime;
|
viewDrawScreen();
|
||||||
g_gameUpdateAvgTime = ((GAMEUPDATEAVGTIMENUMSAMPLES-1.f)*g_gameUpdateAvgTime+g_gameUpdateTime)/((float) GAMEUPDATEAVGTIMENUMSAMPLES);
|
g_gameUpdateAndDrawTime = g_beforeSwapTime/* timerGetHiTicks()*/ - gameUpdateStartTime;
|
||||||
}
|
}
|
||||||
bDraw = G_FPSLimit() != 0;
|
}
|
||||||
if (gQuitRequest && gQuitGame)
|
|
||||||
videoClearScreen(0);
|
static void drawBackground()
|
||||||
else
|
{
|
||||||
{
|
twod->ClearScreen();
|
||||||
netCheckSync();
|
rotatesprite(160 << 16, 100 << 16, 65536, 0, 2518, 0, 0, 0x4a, 0, 0, xdim - 1, ydim - 1);
|
||||||
if (bDraw)
|
if (gQuitRequest && !gQuitGame)
|
||||||
{
|
netBroadcastMyLogoff(gQuitRequest == 2);
|
||||||
viewDrawScreen();
|
}
|
||||||
g_gameUpdateAndDrawTime = g_beforeSwapTime/* timerGetHiTicks()*/ - gameUpdateStartTime;
|
|
||||||
}
|
static void commonTicker(bool &playvideo)
|
||||||
}
|
{
|
||||||
}
|
if (TestBitString(gotpic, 2342))
|
||||||
else // gameState == GS_DEMOSCREEN
|
{
|
||||||
{
|
FireProcess();
|
||||||
// Menu background
|
ClearBitString(gotpic, 2342);
|
||||||
bDraw = G_FPSLimit() != 0;
|
}
|
||||||
if (bDraw)
|
if (gStartNewGame)
|
||||||
{
|
{
|
||||||
twod->ClearScreen();
|
StartLevel(&gGameOptions);
|
||||||
rotatesprite(160<<16,100<<16,65536,0,2518,0,0,0x4a,0,0,xdim-1,ydim-1);
|
|
||||||
}
|
auto completion = [](bool = false)
|
||||||
if (gQuitRequest && !gQuitGame)
|
{
|
||||||
netBroadcastMyLogoff(gQuitRequest == 2);
|
levelTryPlayMusicOrNothing(gGameOptions.nEpisode, gGameOptions.nLevel);
|
||||||
}
|
gamestate = GS_LEVEL;
|
||||||
if (bDraw)
|
};
|
||||||
{
|
|
||||||
gameHandleEvents();
|
if ((gGameOptions.uGameFlags & 4))
|
||||||
inputState.SetBindsEnabled(gInputMode == kInputGame);
|
levelPlayIntroScene(gGameOptions.nEpisode, completion);
|
||||||
switch (gInputMode)
|
else
|
||||||
{
|
completion(false);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ready2send = 0;
|
|
||||||
if (gRestartGame)
|
if (gRestartGame)
|
||||||
{
|
{
|
||||||
Mus_Stop();
|
Mus_Stop();
|
||||||
|
@ -1106,21 +1011,70 @@ RESTART:
|
||||||
gQuitGame = 0;
|
gQuitGame = 0;
|
||||||
gQuitRequest = 0;
|
gQuitRequest = 0;
|
||||||
gRestartGame = 0;
|
gRestartGame = 0;
|
||||||
gGameStarted = 0;
|
levelSetupOptions(0, 0);
|
||||||
levelSetupOptions(0,0);
|
|
||||||
|
|
||||||
|
|
||||||
if (gGameOptions.nGameType != 0)
|
if (gGameOptions.nGameType != 0)
|
||||||
{
|
{
|
||||||
videoSetViewableArea(0,0,xdim-1,ydim-1);
|
playvideo = !bQuickStart;
|
||||||
playvideo = !bQuickStart;
|
|
||||||
}
|
}
|
||||||
else playvideo = false;
|
else playvideo = false;
|
||||||
|
gamestate = GS_STARTUP;
|
||||||
goto RESTART;
|
|
||||||
}
|
}
|
||||||
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1449,7 +1403,7 @@ extern IniFile* BloodINI;
|
||||||
void GameInterface::FreeGameData()
|
void GameInterface::FreeGameData()
|
||||||
{
|
{
|
||||||
if (BloodINI) delete BloodINI;
|
if (BloodINI) delete BloodINI;
|
||||||
ShutDown();
|
netDeinitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameInterface::UpdateScreenSize()
|
void GameInterface::UpdateScreenSize()
|
||||||
|
|
|
@ -106,13 +106,6 @@ struct INICHAIN {
|
||||||
extern INICHAIN *pINIChain;
|
extern INICHAIN *pINIChain;
|
||||||
|
|
||||||
|
|
||||||
enum INPUT_MODE {
|
|
||||||
kInputGame = 0,
|
|
||||||
kInputMessage,
|
|
||||||
kInputEndGame,
|
|
||||||
};
|
|
||||||
|
|
||||||
extern INPUT_MODE gInputMode;
|
|
||||||
extern short BloodVersion;
|
extern short BloodVersion;
|
||||||
extern int gNetPlayers;
|
extern int gNetPlayers;
|
||||||
extern bool gRestartGame;
|
extern bool gRestartGame;
|
||||||
|
|
|
@ -35,6 +35,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
#include "map2d.h"
|
#include "map2d.h"
|
||||||
#include "view.h"
|
#include "view.h"
|
||||||
#include "d_event.h"
|
#include "d_event.h"
|
||||||
|
#include "gamestate.h"
|
||||||
|
|
||||||
BEGIN_BLD_NS
|
BEGIN_BLD_NS
|
||||||
|
|
||||||
|
@ -83,7 +84,7 @@ void ctrlGetInput(void)
|
||||||
|
|
||||||
auto scaleAdjustmentToInterval = [=](double x) { return x * kTicsPerSec / (1000.0 / elapsedInputTicks); };
|
auto scaleAdjustmentToInterval = [=](double x) { return x * kTicsPerSec / (1000.0 / elapsedInputTicks); };
|
||||||
|
|
||||||
if (!gGameStarted || gInputMode != kInputGame)
|
if (gamestate != GS_LEVEL || System_WantGuiCapture())
|
||||||
{
|
{
|
||||||
gInput = {};
|
gInput = {};
|
||||||
CONTROL_GetInput(&info);
|
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
|
END_BLD_NS
|
||||||
|
|
|
@ -37,212 +37,113 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
#include "../glbackend/glbackend.h"
|
#include "../glbackend/glbackend.h"
|
||||||
#include "raze_sound.h"
|
#include "raze_sound.h"
|
||||||
#include "v_2ddrawer.h"
|
#include "v_2ddrawer.h"
|
||||||
|
#include "screenjob.h"
|
||||||
|
#include "gamestate.h"
|
||||||
|
#include "seq.h"
|
||||||
|
#include "menu.h"
|
||||||
|
|
||||||
BEGIN_BLD_NS
|
BEGIN_BLD_NS
|
||||||
|
|
||||||
char exitCredits = 0;
|
|
||||||
|
|
||||||
char Wait(int nTicks)
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void playlogos()
|
||||||
{
|
{
|
||||||
totalclock = 0;
|
JobDesc jobs[6];
|
||||||
while (totalclock < nTicks)
|
int job = 0;
|
||||||
{
|
static AnimSound logosound[] =
|
||||||
gameHandleEvents();
|
{
|
||||||
auto key = inputState.keyGetScan();
|
{ 1, -1 },
|
||||||
if (key)
|
{ -1, -1 },
|
||||||
{
|
{ 1, -1 },
|
||||||
if (key == sc_Escape) // sc_Escape
|
{ -1,-1 }
|
||||||
exitCredits = 1;
|
};
|
||||||
return 0;
|
|
||||||
}
|
if (logosound[0].soundnum == -1)
|
||||||
}
|
{
|
||||||
return 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 levelPlayEndScene(int nEpisode, CompletionFunc completion)
|
||||||
|
|
||||||
void credLogosDos(void)
|
|
||||||
{
|
{
|
||||||
char bShift = inputState.ShiftPressed();
|
gGameOptions.uGameFlags &= ~8;
|
||||||
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);
|
|
||||||
Mus_Stop();
|
Mus_Stop();
|
||||||
|
sndKillAllSounds();
|
||||||
int nScale;
|
sfxKillAllSounds();
|
||||||
int nStat;
|
ambKillAll();
|
||||||
|
seqKillAll();
|
||||||
if (nWidth <= 320 && nHeight <= 200)
|
EPISODEINFO *pEpisode = &gEpisodeInfo[nEpisode];
|
||||||
{
|
playSmk(pEpisode->at8f98, pEpisode->at90c0, pEpisode->at902c, completion);
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
END_BLD_NS
|
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 "c_bind.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
|
#include "gamestate.h"
|
||||||
|
|
||||||
bool ShowOptionMenu();
|
bool ShowOptionMenu();
|
||||||
|
|
||||||
|
@ -247,7 +248,7 @@ void GameInterface::MenuClosed()
|
||||||
|
|
||||||
bool GameInterface::CanSave()
|
bool GameInterface::CanSave()
|
||||||
{
|
{
|
||||||
return (gGameStarted && gPlayer[myconnectindex].pXSprite->health != 0);
|
return (gamestate == GS_LEVEL && gPlayer[myconnectindex].pXSprite->health != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameInterface::StartGame(FNewGameStartup& gs)
|
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 "messages.h"
|
||||||
#include "statistics.h"
|
#include "statistics.h"
|
||||||
#include "gstrings.h"
|
#include "gstrings.h"
|
||||||
|
#include "gamestate.h"
|
||||||
#include "raze_sound.h"
|
#include "raze_sound.h"
|
||||||
|
|
||||||
BEGIN_BLD_NS
|
BEGIN_BLD_NS
|
||||||
|
@ -86,8 +87,7 @@ void CEndGameMgr::ProcessKeys(void)
|
||||||
//}
|
//}
|
||||||
//else
|
//else
|
||||||
{
|
{
|
||||||
char ch = inputState.keyGetScan();
|
if (!inputState.CheckAllInput())
|
||||||
if (!ch)
|
|
||||||
return;
|
return;
|
||||||
if (gGameOptions.nGameType > 0 || numplayers > 1)
|
if (gGameOptions.nGameType > 0 || numplayers > 1)
|
||||||
netWaitForEveryone(0);
|
netWaitForEveryone(0);
|
||||||
|
@ -99,8 +99,7 @@ extern void EndLevel(void);
|
||||||
|
|
||||||
void CEndGameMgr::Setup(void)
|
void CEndGameMgr::Setup(void)
|
||||||
{
|
{
|
||||||
at1 = gInputMode;
|
gamestate = GS_FINALE;
|
||||||
gInputMode = kInputEndGame;
|
|
||||||
at0 = 1;
|
at0 = 1;
|
||||||
STAT_Update(false);
|
STAT_Update(false);
|
||||||
EndLevel();
|
EndLevel();
|
||||||
|
@ -119,7 +118,6 @@ void CEndGameMgr::Finish(void)
|
||||||
gInitialNetPlayers = numplayers;
|
gInitialNetPlayers = numplayers;
|
||||||
soundEngine->StopAllChannels();
|
soundEngine->StopAllChannels();
|
||||||
gStartNewGame = 1;
|
gStartNewGame = 1;
|
||||||
gInputMode = (INPUT_MODE)at1;
|
|
||||||
at0 = 0;
|
at0 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
#include "blood.h"
|
#include "blood.h"
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "credits.h"
|
|
||||||
#include "endgame.h"
|
#include "endgame.h"
|
||||||
#include "inifile.h"
|
#include "inifile.h"
|
||||||
#include "levels.h"
|
#include "levels.h"
|
||||||
|
@ -56,7 +55,6 @@ EPISODEINFO gEpisodeInfo[kMaxEpisodes+1];
|
||||||
int gSkill = 2;
|
int gSkill = 2;
|
||||||
int gEpisodeCount;
|
int gEpisodeCount;
|
||||||
int gNextLevel;
|
int gNextLevel;
|
||||||
bool gGameStarted;
|
|
||||||
|
|
||||||
int gLevelTime;
|
int gLevelTime;
|
||||||
|
|
||||||
|
@ -83,35 +81,6 @@ void levelOverrideINI(const char *pzIni)
|
||||||
strcpy(BloodIniFile, 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)
|
void levelClearSecrets(void)
|
||||||
{
|
{
|
||||||
gSecretMgr.Clear();
|
gSecretMgr.Clear();
|
||||||
|
@ -412,14 +381,12 @@ void LevelsLoadSave::Load(void)
|
||||||
{
|
{
|
||||||
Read(&gNextLevel, sizeof(gNextLevel));
|
Read(&gNextLevel, sizeof(gNextLevel));
|
||||||
Read(&gGameOptions, sizeof(gGameOptions));
|
Read(&gGameOptions, sizeof(gGameOptions));
|
||||||
Read(&gGameStarted, sizeof(gGameStarted));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LevelsLoadSave::Save(void)
|
void LevelsLoadSave::Save(void)
|
||||||
{
|
{
|
||||||
Write(&gNextLevel, sizeof(gNextLevel));
|
Write(&gNextLevel, sizeof(gNextLevel));
|
||||||
Write(&gGameOptions, sizeof(gGameOptions));
|
Write(&gGameOptions, sizeof(gGameOptions));
|
||||||
Write(&gGameStarted, sizeof(gGameStarted));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LevelsLoadSaveConstruct(void)
|
void LevelsLoadSaveConstruct(void)
|
||||||
|
|
|
@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "screenjob.h"
|
||||||
#include "common_game.h"
|
#include "common_game.h"
|
||||||
#include "inifile.h"
|
#include "inifile.h"
|
||||||
#include "mapinfo.h"
|
#include "mapinfo.h"
|
||||||
|
@ -98,8 +99,8 @@ extern int gLevelTime;
|
||||||
|
|
||||||
void levelInitINI(const char *pzIni);
|
void levelInitINI(const char *pzIni);
|
||||||
void levelOverrideINI(const char *pzIni);
|
void levelOverrideINI(const char *pzIni);
|
||||||
void levelPlayIntroScene(int nEpisode);
|
void levelPlayIntroScene(int nEpisode, CompletionFunc completion);
|
||||||
void levelPlayEndScene(int nEpisode);
|
void levelPlayEndScene(int nEpisode, CompletionFunc completion);
|
||||||
void levelSetupSecret(int nCount);
|
void levelSetupSecret(int nCount);
|
||||||
void levelTriggerSecret(int nSecret);
|
void levelTriggerSecret(int nSecret);
|
||||||
void CheckSectionAbend(const char *pzSection);
|
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 "savegamehelp.h"
|
||||||
#include "raze_music.h"
|
#include "raze_music.h"
|
||||||
#include "mapinfo.h"
|
#include "mapinfo.h"
|
||||||
|
#include "gamestate.h"
|
||||||
|
|
||||||
#include "aistate.h"
|
#include "aistate.h"
|
||||||
#include "aiunicult.h"
|
#include "aiunicult.h"
|
||||||
|
@ -480,7 +481,7 @@ bool GameInterface::LoadGame(FSaveGameNode* node)
|
||||||
sfxKillAllSounds();
|
sfxKillAllSounds();
|
||||||
ambKillAll();
|
ambKillAll();
|
||||||
seqKillAll();
|
seqKillAll();
|
||||||
if (!gGameStarted)
|
if (gamestate != GS_LEVEL)
|
||||||
{
|
{
|
||||||
memset(xsprite, 0, sizeof(xsprite));
|
memset(xsprite, 0, sizeof(xsprite));
|
||||||
}
|
}
|
||||||
|
@ -524,7 +525,7 @@ bool GameInterface::LoadGame(FSaveGameNode* node)
|
||||||
else
|
else
|
||||||
gGameMessageMgr.Clear();
|
gGameMessageMgr.Clear();
|
||||||
viewSetErrorMessage("");
|
viewSetErrorMessage("");
|
||||||
if (!gGameStarted)
|
if (gamestate != GS_LEVEL)
|
||||||
{
|
{
|
||||||
netWaitForEveryone(0);
|
netWaitForEveryone(0);
|
||||||
memset(gPlayerReady, 0, sizeof(gPlayerReady));
|
memset(gPlayerReady, 0, sizeof(gPlayerReady));
|
||||||
|
@ -534,7 +535,7 @@ bool GameInterface::LoadGame(FSaveGameNode* node)
|
||||||
gFrameRate = 0;
|
gFrameRate = 0;
|
||||||
totalclock = 0;
|
totalclock = 0;
|
||||||
paused = 0;
|
paused = 0;
|
||||||
gGameStarted = 1;
|
gamestate = GS_LEVEL;
|
||||||
bVanilla = false;
|
bVanilla = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -337,7 +337,7 @@ void CGameMessageMgr::Display(void)
|
||||||
{
|
{
|
||||||
if (VanillaMode())
|
if (VanillaMode())
|
||||||
{
|
{
|
||||||
if (numberOfDisplayedMessages && this->state && gInputMode != kInputMessage)
|
if (numberOfDisplayedMessages && this->state)
|
||||||
{
|
{
|
||||||
int initialNrOfDisplayedMsgs = numberOfDisplayedMessages;
|
int initialNrOfDisplayedMsgs = numberOfDisplayedMessages;
|
||||||
int initialMessagesIndex = messagesIndex;
|
int initialMessagesIndex = messagesIndex;
|
||||||
|
@ -368,7 +368,7 @@ void CGameMessageMgr::Display(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (this->state && gInputMode != kInputMessage)
|
if (this->state)
|
||||||
{
|
{
|
||||||
messageStruct* currentMessages[kMessageLogSize];
|
messageStruct* currentMessages[kMessageLogSize];
|
||||||
int currentMessagesCount = 0;
|
int currentMessagesCount = 0;
|
||||||
|
@ -500,7 +500,6 @@ void CPlayerMsg::Clear(void)
|
||||||
void CPlayerMsg::Term(void)
|
void CPlayerMsg::Term(void)
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
gInputMode = kInputGame;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerMsg::Draw(void)
|
void CPlayerMsg::Draw(void)
|
||||||
|
|
|
@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
BEGIN_BLD_NS
|
BEGIN_BLD_NS
|
||||||
|
|
||||||
|
void playlogos();
|
||||||
void *ResReadLine(char *buffer, unsigned int nBytes, void **pRes);
|
void *ResReadLine(char *buffer, unsigned int nBytes, void **pRes);
|
||||||
unsigned int qrand(void);
|
unsigned int qrand(void);
|
||||||
int wrand(void);
|
int wrand(void);
|
||||||
|
|
|
@ -37,6 +37,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
#include "view.h"
|
#include "view.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
|
#include "gamestate.h"
|
||||||
|
|
||||||
extern bool gHaveNetworking;
|
extern bool gHaveNetworking;
|
||||||
|
|
||||||
|
@ -1326,7 +1327,7 @@ void netPlayerQuit(int nPlayer)
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
sprintf(buffer, "%s left the game with %d frags.", gProfile[nPlayer].name, gPlayer[nPlayer].fragCount);
|
sprintf(buffer, "%s left the game with %d frags.", gProfile[nPlayer].name, gPlayer[nPlayer].fragCount);
|
||||||
viewSetMessage(buffer);
|
viewSetMessage(buffer);
|
||||||
if (gGameStarted)
|
if (gamestate == GS_LEVEL)
|
||||||
{
|
{
|
||||||
seqKill(3, gPlayer[nPlayer].pSprite->extra);
|
seqKill(3, gPlayer[nPlayer].pSprite->extra);
|
||||||
actPostSprite(gPlayer[nPlayer].nSprite, kStatFree);
|
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 "sound.h"
|
||||||
#include "view.h"
|
#include "view.h"
|
||||||
#include "mapinfo.h"
|
#include "mapinfo.h"
|
||||||
|
#include "gamestate.h"
|
||||||
|
|
||||||
BEGIN_BLD_NS
|
BEGIN_BLD_NS
|
||||||
|
|
||||||
|
@ -89,7 +90,7 @@ static int osdcmd_map(CCmdFuncPtr parm)
|
||||||
|
|
||||||
static int osdcmd_give(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");
|
Printf("give: Cannot give while dead or not in a single-player game.\n");
|
||||||
return CCMD_OK;
|
return CCMD_OK;
|
||||||
|
@ -149,7 +150,7 @@ static int osdcmd_give(CCmdFuncPtr parm)
|
||||||
static int osdcmd_god(CCmdFuncPtr UNUSED(parm))
|
static int osdcmd_god(CCmdFuncPtr UNUSED(parm))
|
||||||
{
|
{
|
||||||
UNREFERENCED_CONST_PARAMETER(parm);
|
UNREFERENCED_CONST_PARAMETER(parm);
|
||||||
if (numplayers == 1 && gGameStarted)
|
if (numplayers == 1 && gamestate == GS_LEVEL)
|
||||||
{
|
{
|
||||||
SetGodMode(!gMe->godMode);
|
SetGodMode(!gMe->godMode);
|
||||||
gCheatMgr.m_bPlayerCheated = true;
|
gCheatMgr.m_bPlayerCheated = true;
|
||||||
|
@ -164,7 +165,7 @@ static int osdcmd_noclip(CCmdFuncPtr UNUSED(parm))
|
||||||
{
|
{
|
||||||
UNREFERENCED_CONST_PARAMETER(parm);
|
UNREFERENCED_CONST_PARAMETER(parm);
|
||||||
|
|
||||||
if (numplayers == 1 && gGameStarted)
|
if (numplayers == 1 && gamestate == GS_LEVEL)
|
||||||
{
|
{
|
||||||
SetClipMode(!gNoClip);
|
SetClipMode(!gNoClip);
|
||||||
gCheatMgr.m_bPlayerCheated = true;
|
gCheatMgr.m_bPlayerCheated = true;
|
||||||
|
|
|
@ -225,12 +225,6 @@ void Mus_Stop()
|
||||||
S_StopMusic(true);
|
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)
|
void Mus_SetPaused(bool on)
|
||||||
{
|
{
|
||||||
if (on) S_PauseMusic();
|
if (on) S_PauseMusic();
|
||||||
|
|
|
@ -13,7 +13,6 @@ void Mus_UpdateMusic();
|
||||||
int Mus_Play(const char *mapname, const char *fn, bool loop);
|
int Mus_Play(const char *mapname, const char *fn, bool loop);
|
||||||
void Mus_Stop();
|
void Mus_Stop();
|
||||||
bool Mus_IsPlaying();
|
bool Mus_IsPlaying();
|
||||||
void Mus_Fade(double seconds);
|
|
||||||
void Mus_SetPaused(bool on);
|
void Mus_SetPaused(bool on);
|
||||||
void Mus_ResumeSaved();
|
void Mus_ResumeSaved();
|
||||||
FString G_SetupFilenameBasedMusic(const char* fileName, const char *defaultfn);
|
FString G_SetupFilenameBasedMusic(const char* fileName, const char *defaultfn);
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "gamestate.h"
|
#include "gamestate.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "raze_sound.h"
|
#include "raze_sound.h"
|
||||||
|
#include "SmackerDecoder.h"
|
||||||
#include "movie/playmve.h"
|
#include "movie/playmve.h"
|
||||||
#include "gamecontrol.h"
|
#include "gamecontrol.h"
|
||||||
|
|
||||||
|
@ -52,6 +53,14 @@
|
||||||
IMPLEMENT_CLASS(DScreenJob, true, false)
|
IMPLEMENT_CLASS(DScreenJob, true, false)
|
||||||
IMPLEMENT_CLASS(DImageScreen, 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();
|
twod->ClearScreen();
|
||||||
DrawTexture(twod, tex, 0, 0, DTA_FullscreenEx, 3, DTA_LegacyRenderStyle, STYLE_Normal, TAG_DONE);
|
DrawTexture(twod, tex, 0, 0, DTA_FullscreenEx, 3, DTA_LegacyRenderStyle, STYLE_Normal, TAG_DONE);
|
||||||
// Only end after having faded out.
|
// 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);
|
auto fr = fileSystem.OpenFileReader(filename);
|
||||||
if (!fr.isOpen())
|
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);
|
Printf("%s: Unable to open video\n", filename);
|
||||||
return nothing();
|
return nothing();
|
||||||
}
|
}
|
||||||
|
@ -243,13 +356,21 @@ DScreenJob* PlayVideo(const char* filename, const AnimSound* ans, const int* fra
|
||||||
{
|
{
|
||||||
Printf("%s: invalid ANM file.\n", filename);
|
Printf("%s: invalid ANM file.\n", filename);
|
||||||
anm->Destroy();
|
anm->Destroy();
|
||||||
return nothing();
|
return nothing();
|
||||||
}
|
}
|
||||||
return anm;
|
return anm;
|
||||||
}
|
}
|
||||||
else if (!memcmp(id, "SMK2", 4))
|
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))
|
else if (!memcmp(id, "Interplay MVE File", 18))
|
||||||
{
|
{
|
||||||
|
@ -317,7 +438,6 @@ public:
|
||||||
{
|
{
|
||||||
for (auto& job : jobs)
|
for (auto& job : jobs)
|
||||||
{
|
{
|
||||||
job.job->Destroy();
|
|
||||||
job.job->ObjectFlags |= OF_YesReallyDelete;
|
job.job->ObjectFlags |= OF_YesReallyDelete;
|
||||||
delete job.job;
|
delete job.job;
|
||||||
}
|
}
|
||||||
|
@ -326,9 +446,17 @@ public:
|
||||||
|
|
||||||
void AdvanceJob(bool skip)
|
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++;
|
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;
|
actionState = clearbefore ? State_Clear : State_Run;
|
||||||
if (index < jobs.Size()) screenfade = jobs[index].job->fadestyle & DScreenJob::fadein ? 0.f : 1.f;
|
if (index < jobs.Size()) screenfade = jobs[index].job->fadestyle & DScreenJob::fadein ? 0.f : 1.f;
|
||||||
startTime = -1;
|
startTime = -1;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include "dobject.h"
|
#include "dobject.h"
|
||||||
|
#include "v_2ddrawer.h"
|
||||||
|
|
||||||
using CompletionFunc = std::function<void(bool)>;
|
using CompletionFunc = std::function<void(bool)>;
|
||||||
struct JobDesc;
|
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
|
class DImageScreen : public DScreenJob
|
||||||
{
|
{
|
||||||
DECLARE_CLASS(DImageScreen, DScreenJob)
|
DECLARE_CLASS(DImageScreen, DScreenJob)
|
||||||
|
|
||||||
int tilenum = -1;
|
int tilenum = -1;
|
||||||
|
int waittime; // in ms.
|
||||||
FGameTexture* tex = nullptr;
|
FGameTexture* tex = nullptr;
|
||||||
|
|
||||||
public:
|
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;
|
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;
|
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
|
class DEpisode3End : public DImageScreen
|
||||||
{
|
{
|
||||||
int sound = 0;
|
int sound = 0;
|
||||||
|
|
Loading…
Reference in a new issue