mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-11-12 23:54:37 +00:00
- scriptified Exhumed's 2D content (minus the programmatic textures.)
This commit is contained in:
parent
5b54e9c1ad
commit
4069a5096a
27 changed files with 1522 additions and 1257 deletions
|
@ -550,7 +550,21 @@ DEFINE_ACTION_FUNCTION_NATIVE(FStringStruct, ToDouble, StringToDbl)
|
||||||
ACTION_RETURN_FLOAT(self->ToDouble());
|
ACTION_RETURN_FLOAT(self->ToDouble());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void StringSplit(FString *self, TArray<FString> *tokens, const FString &delimiter, int keepEmpty)
|
static void StringSubst(FString *self, const FString &substr, const FString& replc)
|
||||||
|
{
|
||||||
|
self->Substitute(substr, replc);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION_NATIVE(FStringStruct, Substitute, StringSubst)
|
||||||
|
{
|
||||||
|
PARAM_SELF_STRUCT_PROLOGUE(FString);
|
||||||
|
PARAM_STRING(substr);
|
||||||
|
PARAM_STRING(replc);
|
||||||
|
StringSubst(self, substr, replc);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void StringSplit(FString* self, TArray<FString>* tokens, const FString& delimiter, int keepEmpty)
|
||||||
{
|
{
|
||||||
self->Split(*tokens, delimiter, static_cast<FString::EmptyTokenType>(keepEmpty));
|
self->Split(*tokens, delimiter, static_cast<FString::EmptyTokenType>(keepEmpty));
|
||||||
}
|
}
|
||||||
|
|
|
@ -881,6 +881,13 @@ DEFINE_ACTION_FUNCTION(FKeyBindings, GetAllKeysForCommand)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(FKeyBindings, GetBinding)
|
||||||
|
{
|
||||||
|
PARAM_SELF_STRUCT_PROLOGUE(FKeyBindings);
|
||||||
|
PARAM_INT(key);
|
||||||
|
ACTION_RETURN_STRING(self->GetBinding(key));
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(FKeyBindings, UnbindACommand)
|
DEFINE_ACTION_FUNCTION(FKeyBindings, UnbindACommand)
|
||||||
{
|
{
|
||||||
PARAM_SELF_STRUCT_PROLOGUE(FKeyBindings);
|
PARAM_SELF_STRUCT_PROLOGUE(FKeyBindings);
|
||||||
|
@ -928,6 +935,7 @@ DEFINE_GLOBAL_NAMED(mus_playing, musplaying);
|
||||||
DEFINE_FIELD_X(MusPlayingInfo, MusPlayingInfo, name);
|
DEFINE_FIELD_X(MusPlayingInfo, MusPlayingInfo, name);
|
||||||
DEFINE_FIELD_X(MusPlayingInfo, MusPlayingInfo, baseorder);
|
DEFINE_FIELD_X(MusPlayingInfo, MusPlayingInfo, baseorder);
|
||||||
DEFINE_FIELD_X(MusPlayingInfo, MusPlayingInfo, loop);
|
DEFINE_FIELD_X(MusPlayingInfo, MusPlayingInfo, loop);
|
||||||
|
DEFINE_FIELD_X(MusPlayingInfo, MusPlayingInfo, handle);
|
||||||
|
|
||||||
DEFINE_GLOBAL_NAMED(PClass::AllClasses, AllClasses)
|
DEFINE_GLOBAL_NAMED(PClass::AllClasses, AllClasses)
|
||||||
DEFINE_GLOBAL(Bindings)
|
DEFINE_GLOBAL(Bindings)
|
||||||
|
|
|
@ -69,11 +69,11 @@ constexpr double BAngToDegree = 360. / 2048.;
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
inline int32_t bsin(const int ang, const int8_t shift = 0)
|
inline int bsin(const int ang, const int shift = 0)
|
||||||
{
|
{
|
||||||
return shift < 0 ? sintable[ang & 2047] >> abs(shift) : sintable[ang & 2047] << shift;
|
return shift < 0 ? sintable[ang & 2047] >> abs(shift) : sintable[ang & 2047] << shift;
|
||||||
}
|
}
|
||||||
inline double bsinf(const double ang, const int8_t shift = 0)
|
inline double bsinf(const double ang, const int shift = 0)
|
||||||
{
|
{
|
||||||
return g_sin(ang * BAngRadian) * (shift >= -SINSHIFT ? uint64_t(1) << (SINSHIFT + shift) : 1. / (uint64_t(1) << abs(SINSHIFT + shift)));
|
return g_sin(ang * BAngRadian) * (shift >= -SINSHIFT ? uint64_t(1) << (SINSHIFT + shift) : 1. / (uint64_t(1) << abs(SINSHIFT + shift)));
|
||||||
}
|
}
|
||||||
|
@ -85,11 +85,11 @@ inline double bsinf(const double ang, const int8_t shift = 0)
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
inline int32_t bcos(const int ang, const int8_t shift = 0)
|
inline int bcos(const int ang, const int shift = 0)
|
||||||
{
|
{
|
||||||
return shift < 0 ? sintable[(ang + 512) & 2047] >> abs(shift) : sintable[(ang + 512) & 2047] << shift;
|
return shift < 0 ? sintable[(ang + 512) & 2047] >> abs(shift) : sintable[(ang + 512) & 2047] << shift;
|
||||||
}
|
}
|
||||||
inline double bcosf(const double ang, const int8_t shift = 0)
|
inline double bcosf(const double ang, const int shift = 0)
|
||||||
{
|
{
|
||||||
return g_cos(ang * BAngRadian) * (shift >= -SINSHIFT ? uint64_t(1) << (SINSHIFT + shift) : 1. / (uint64_t(1) << abs(SINSHIFT + shift)));
|
return g_cos(ang * BAngRadian) * (shift >= -SINSHIFT ? uint64_t(1) << (SINSHIFT + shift) : 1. / (uint64_t(1) << abs(SINSHIFT + shift)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -555,7 +555,7 @@ int GameMain()
|
||||||
I_ShowFatalError(err.what());
|
I_ShowFatalError(err.what());
|
||||||
r = -1;
|
r = -1;
|
||||||
}
|
}
|
||||||
DeleteScreenJob();
|
//DeleteScreenJob();
|
||||||
DeinitMenus();
|
DeinitMenus();
|
||||||
if (StatusBar) StatusBar->Destroy();
|
if (StatusBar) StatusBar->Destroy();
|
||||||
StatusBar = nullptr;
|
StatusBar = nullptr;
|
||||||
|
@ -1479,6 +1479,22 @@ DEFINE_ACTION_FUNCTION(_Raze, PlayerName)
|
||||||
ACTION_RETURN_STRING(unsigned(index) >= MAXPLAYERS ? "" : PlayerName(index));
|
ACTION_RETURN_STRING(unsigned(index) >= MAXPLAYERS ? "" : PlayerName(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION_NATIVE(_Raze, bsin, bsin)
|
||||||
|
{
|
||||||
|
PARAM_PROLOGUE;
|
||||||
|
PARAM_INT(v);
|
||||||
|
PARAM_INT(shift);
|
||||||
|
ACTION_RETURN_INT(bsin(v, shift));
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION_NATIVE(_Raze, bcos, bcos)
|
||||||
|
{
|
||||||
|
PARAM_PROLOGUE;
|
||||||
|
PARAM_INT(v);
|
||||||
|
PARAM_INT(shift);
|
||||||
|
ACTION_RETURN_INT(bcos(v, shift));
|
||||||
|
}
|
||||||
|
|
||||||
extern bool demoplayback;
|
extern bool demoplayback;
|
||||||
DEFINE_GLOBAL(multiplayer)
|
DEFINE_GLOBAL(multiplayer)
|
||||||
DEFINE_GLOBAL(netgame)
|
DEFINE_GLOBAL(netgame)
|
||||||
|
|
|
@ -136,7 +136,9 @@ bool newGameStarted;
|
||||||
void NewGame(MapRecord* map, int skill, bool ns = false)
|
void NewGame(MapRecord* map, int skill, bool ns = false)
|
||||||
{
|
{
|
||||||
newGameStarted = true;
|
newGameStarted = true;
|
||||||
ShowIntermission(nullptr, map, nullptr, [=](bool) { gi->NewGame(map, skill, ns); });
|
ShowIntermission(nullptr, map, nullptr, [=](bool) {
|
||||||
|
gi->NewGame(map, skill, ns);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -148,15 +148,18 @@ void CallCreateMapFunction(const char* qname, DObject* runner, MapRecord* map)
|
||||||
//
|
//
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
void CallCreateSummaryFunction(const char* qname, DObject* runner, MapRecord* map, SummaryInfo* info)
|
void CallCreateSummaryFunction(const char* qname, DObject* runner, MapRecord* map, SummaryInfo* info, MapRecord* map2)
|
||||||
{
|
{
|
||||||
auto func = LookupFunction(qname);
|
auto func = LookupFunction(qname);
|
||||||
if (func->Proto->ArgumentTypes.Size() != 3) I_Error("Bad map-cutscene function %s. Must receive precisely three arguments.", qname);
|
auto s = func->Proto->ArgumentTypes.Size();
|
||||||
if (func->Proto->ArgumentTypes[0] != runnerclasstype && func->Proto->ArgumentTypes[1] != maprecordtype && func->Proto->ArgumentTypes[2] != summaryinfotype)
|
auto at = func->Proto->ArgumentTypes.Data();
|
||||||
I_Error("Bad cutscene function %s. Must receive ScreenJobRunner, MapRecord and SummaryInfo reference.", qname);
|
if (s != 3 && s != 4) I_Error("Bad map-cutscene function %s. Must receive precisely three or four arguments.", qname);
|
||||||
summaryinfo = *info; // must be copied to a persistent location.
|
if (at[0] != runnerclasstype && at[1] != maprecordtype && at[2] != summaryinfotype && (s == 3 || at[3] == maprecordtype))
|
||||||
VMValue val[3] = { runner, map, &summaryinfo };
|
I_Error("Bad cutscene function %s. Must receive ScreenJobRunner, MapRecord and SummaryInfo reference,", qname);
|
||||||
VMCall(func, val, 3, nullptr, 0);
|
if (info) summaryinfo = *info; // must be copied to a persistent location.
|
||||||
|
else summaryinfo = {};
|
||||||
|
VMValue val[] = { runner, map, &summaryinfo, map2 };
|
||||||
|
VMCall(func, val, s, nullptr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
@ -480,8 +483,9 @@ void ShowIntermission(MapRecord* fromMap, MapRecord* toMap, SummaryInfo* info, C
|
||||||
globalCutscenes.DefaultMapOutro.Create(runner, fromMap, !!toMap);
|
globalCutscenes.DefaultMapOutro.Create(runner, fromMap, !!toMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
CallCreateSummaryFunction(globalCutscenes.SummaryScreen, runner, fromMap, info);
|
|
||||||
}
|
}
|
||||||
|
if (fromMap || (g_gameType & GAMEFLAG_PSEXHUMED))
|
||||||
|
CallCreateSummaryFunction(globalCutscenes.SummaryScreen, runner, fromMap, info, toMap);
|
||||||
|
|
||||||
if (toMap)
|
if (toMap)
|
||||||
{
|
{
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -90,12 +90,6 @@ END_PS_NS
|
||||||
|
|
||||||
using namespace Exhumed;
|
using namespace Exhumed;
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(_ListMenuItemExhumedPlasma, Draw)
|
|
||||||
{
|
|
||||||
menu_DoPlasma();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(_ListMenuItemExhumedLogo, Draw)
|
DEFINE_ACTION_FUNCTION(_ListMenuItemExhumedLogo, Draw)
|
||||||
{
|
{
|
||||||
auto nLogoTile = GameLogo();
|
auto nLogoTile = GameLogo();
|
||||||
|
|
|
@ -244,6 +244,15 @@ double calc_smoothratio()
|
||||||
return I_GetTimeFrac() * MaxSmoothRatio;
|
return I_GetTimeFrac() * MaxSmoothRatio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DoGameOverScene(bool finallevel)
|
||||||
|
{
|
||||||
|
// todo: make these customizable later.
|
||||||
|
StartCutscene(finallevel ? "ExhumedCutscenes.BuildCinemaLose" : "ExhumedCutscenes.BuildGameoverScene", 0, [](bool)
|
||||||
|
{
|
||||||
|
gameaction = ga_mainmenu;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void GameMove(void)
|
void GameMove(void)
|
||||||
{
|
{
|
||||||
FixPalette();
|
FixPalette();
|
||||||
|
@ -646,7 +655,6 @@ void SerializeState(FSerializer& arc)
|
||||||
("bsnakecam", bSnakeCam)
|
("bsnakecam", bSnakeCam)
|
||||||
("slipmode", bSlipMode)
|
("slipmode", bSlipMode)
|
||||||
("PlayClock", PlayClock)
|
("PlayClock", PlayClock)
|
||||||
("cinemaseen", nCinemaSeen)
|
|
||||||
("spiritsprite", nSpiritSprite)
|
("spiritsprite", nSpiritSprite)
|
||||||
.EndObject();
|
.EndObject();
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ void DoSpiritHead();
|
||||||
|
|
||||||
void CheckKeys2();
|
void CheckKeys2();
|
||||||
void GameTicker();
|
void GameTicker();
|
||||||
void InitLevel(int);
|
void InitLevel(MapRecord*);
|
||||||
void InitNewGame();
|
void InitNewGame();
|
||||||
|
|
||||||
int showmap(short nLevel, short nLevelNew, short nLevelBest);
|
int showmap(short nLevel, short nLevelNew, short nLevelBest);
|
||||||
|
@ -124,7 +124,6 @@ extern short nCurBodyNum;
|
||||||
extern short nBodyTotal;
|
extern short nBodyTotal;
|
||||||
|
|
||||||
extern short bSnakeCam;
|
extern short bSnakeCam;
|
||||||
extern uint8_t nCinemaSeen;
|
|
||||||
|
|
||||||
extern short nButtonColor;
|
extern short nButtonColor;
|
||||||
|
|
||||||
|
@ -152,11 +151,6 @@ extern short bDoFlashes;
|
||||||
|
|
||||||
extern int bVanilla;
|
extern int bVanilla;
|
||||||
|
|
||||||
inline int PublisherLogo()
|
|
||||||
{
|
|
||||||
return (g_gameType & GAMEFLAG_EXHUMED) ? kTileBMGLogo : kTilePIELogo;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int GameLogo()
|
inline int GameLogo()
|
||||||
{
|
{
|
||||||
return (g_gameType & GAMEFLAG_EXHUMED) ? kExhumedLogo : kPowerslaveLogo;
|
return (g_gameType & GAMEFLAG_EXHUMED) ? kExhumedLogo : kPowerslaveLogo;
|
||||||
|
@ -198,6 +192,7 @@ public:
|
||||||
void DisplayText();
|
void DisplayText();
|
||||||
bool AdvanceCinemaText(double clock);
|
bool AdvanceCinemaText(double clock);
|
||||||
void SetPalette(int pal) { currentCinemaPalette = pal; }
|
void SetPalette(int pal) { currentCinemaPalette = pal; }
|
||||||
|
void Create(const FString& text, int pal);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -49,13 +49,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
#include "automap.h"
|
#include "automap.h"
|
||||||
#include "raze_music.h"
|
#include "raze_music.h"
|
||||||
#include "v_draw.h"
|
#include "v_draw.h"
|
||||||
|
#include "vm.h"
|
||||||
|
|
||||||
BEGIN_PS_NS
|
BEGIN_PS_NS
|
||||||
|
|
||||||
short nBestLevel;
|
short nBestLevel;
|
||||||
|
|
||||||
extern uint8_t nCinemaSeen;
|
|
||||||
|
|
||||||
void RunCinemaScene(int num);
|
void RunCinemaScene(int num);
|
||||||
void GameMove(void);
|
void GameMove(void);
|
||||||
void DrawClock();
|
void DrawClock();
|
||||||
|
@ -116,33 +115,87 @@ void GameInterface::DrawBackground()
|
||||||
|
|
||||||
void GameInterface::NextLevel(MapRecord *map, int skill)
|
void GameInterface::NextLevel(MapRecord *map, int skill)
|
||||||
{
|
{
|
||||||
InitLevel(map->levelNumber);
|
InitLevel(map);
|
||||||
|
|
||||||
if (map->levelNumber > nBestLevel)
|
if (map->levelNumber >= nBestLevel)
|
||||||
{
|
{
|
||||||
nBestLevel = selectedlevelnew;
|
nBestLevel = map->levelNumber - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (map->levelNumber == 11) nCinemaSeen |= 2;
|
|
||||||
STAT_NewLevel(currentLevel->labelName);
|
STAT_NewLevel(currentLevel->labelName);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Intermission(MapRecord* from_map, MapRecord* to_map);
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
void GameInterface::NewGame(MapRecord *map, int skill, bool frommenu)
|
void GameInterface::NewGame(MapRecord *map, int skill, bool frommenu)
|
||||||
{
|
{
|
||||||
// start a new game on the given level
|
// start a new game on the given level
|
||||||
InitNewGame();
|
InitNewGame();
|
||||||
if (map->levelNumber == 1) STAT_StartNewGame("Exhumed", 1);
|
InitLevel(map);
|
||||||
Intermission(nullptr, map);
|
gameaction = ga_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameInterface::LevelCompleted(MapRecord *map, int skill)
|
int selectedlevelnew;
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(DMapScreen, SetNextLevel)
|
||||||
|
{
|
||||||
|
PARAM_PROLOGUE;
|
||||||
|
PARAM_INT(v);
|
||||||
|
selectedlevelnew = v;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameInterface::LevelCompleted(MapRecord *to_map, int skill)
|
||||||
{
|
{
|
||||||
Mus_Stop();
|
Mus_Stop();
|
||||||
if (currentLevel->levelNumber == 0) gameaction = ga_mainmenu;
|
if (currentLevel->levelNumber == 0)
|
||||||
Intermission(currentLevel, map);
|
{
|
||||||
|
gameaction = ga_mainmenu;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
StopAllSounds();
|
||||||
|
bCamera = false;
|
||||||
|
automapMode = am_off;
|
||||||
|
|
||||||
|
STAT_Update(to_map == nullptr);
|
||||||
|
if (to_map)
|
||||||
|
{
|
||||||
|
if (to_map->levelNumber > nBestLevel) nBestLevel = to_map->levelNumber - 1;
|
||||||
|
|
||||||
|
if (to_map->levelNumber == 20) nPlayerLives[0] = 0;
|
||||||
|
if (to_map->levelNumber == 0) // skip all intermission stuff when going to the training map.
|
||||||
|
{
|
||||||
|
gameaction = ga_nextlevel;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SummaryInfo info{};
|
||||||
|
info.kills = nCreaturesKilled;
|
||||||
|
info.maxkills = nCreaturesTotal;
|
||||||
|
info.supersecrets = nBestLevel;
|
||||||
|
info.time = PlayClock * GameTicRate / 120;
|
||||||
|
selectedlevelnew = to_map->levelNumber;
|
||||||
|
ShowIntermission(currentLevel, to_map, &info, [=](bool)
|
||||||
|
{
|
||||||
|
if (!to_map) gameaction = ga_startup; // this was the end of the game
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (to_map->levelNumber != selectedlevelnew)
|
||||||
|
{
|
||||||
|
// User can switch destination on the scrolling map.
|
||||||
|
g_nextmap = FindMapByLevelNum(selectedlevelnew);
|
||||||
|
STAT_Cancel();
|
||||||
|
}
|
||||||
|
gameaction = ga_nextlevel;
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
|
@ -66,9 +66,9 @@ uint8_t bIsVersion6 = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t LoadLevel(int nMap)
|
uint8_t LoadLevel(MapRecord* map)
|
||||||
{
|
{
|
||||||
if (nMap == kMap20)
|
if (map->levelNumber == kMap20)
|
||||||
{
|
{
|
||||||
lCountDown = 81000;
|
lCountDown = 81000;
|
||||||
nAlarmTicks = 30;
|
nAlarmTicks = 30;
|
||||||
|
@ -116,12 +116,12 @@ uint8_t LoadLevel(int nMap)
|
||||||
InitItems();
|
InitItems();
|
||||||
InitInput();
|
InitInput();
|
||||||
|
|
||||||
if (nMap == kMap20) {
|
if (map->levelNumber == kMap20) {
|
||||||
InitEnergyTile();
|
InitEnergyTile();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nMap > 15)
|
if (map->levelNumber > 15)
|
||||||
{
|
{
|
||||||
nSwitchSound = 35;
|
nSwitchSound = 35;
|
||||||
nStoneSound = 23;
|
nStoneSound = 23;
|
||||||
|
@ -136,10 +136,6 @@ uint8_t LoadLevel(int nMap)
|
||||||
nStopSound = 66;
|
nStopSound = 66;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nMap < 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3_t startPos;
|
vec3_t startPos;
|
||||||
engineLoadBoard(currentLevel->fileName, 0, &startPos, &inita, &initsect);
|
engineLoadBoard(currentLevel->fileName, 0, &startPos, &inita, &initsect);
|
||||||
initx = startPos.x;
|
initx = startPos.x;
|
||||||
|
@ -172,12 +168,12 @@ uint8_t LoadLevel(int nMap)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitLevel(int level) // todo: use a map record
|
void InitLevel(MapRecord* map)
|
||||||
{
|
{
|
||||||
StopCD();
|
StopCD();
|
||||||
currentLevel = FindMapByLevelNum(level);
|
currentLevel = map;
|
||||||
if (!LoadLevel(level)) {
|
if (!LoadLevel(map)) {
|
||||||
I_Error("Can't load level %d...\n", level);
|
I_Error("Cannot load %s...\n", map->fileName.GetChars());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < nTotalPlayers; i++)
|
for (int i = 0; i < nTotalPlayers; i++)
|
||||||
|
@ -200,7 +196,7 @@ void InitLevel(int level) // todo: use a map record
|
||||||
|
|
||||||
RefreshStatus();
|
RefreshStatus();
|
||||||
|
|
||||||
int nTrack = level;
|
int nTrack = map->levelNumber;
|
||||||
if (nTrack != 0) nTrack--;
|
if (nTrack != 0) nTrack--;
|
||||||
|
|
||||||
playCDtrack((nTrack % 8) + 11, true);
|
playCDtrack((nTrack % 8) + 11, true);
|
||||||
|
@ -210,7 +206,6 @@ void InitLevel(int level) // todo: use a map record
|
||||||
void InitNewGame()
|
void InitNewGame()
|
||||||
{
|
{
|
||||||
bCamera = false;
|
bCamera = false;
|
||||||
nCinemaSeen = 0;
|
|
||||||
PlayerCount = 0;
|
PlayerCount = 0;
|
||||||
|
|
||||||
for (int i = 0; i < nTotalPlayers; i++)
|
for (int i = 0; i < nTotalPlayers; i++)
|
||||||
|
|
|
@ -43,8 +43,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
BEGIN_PS_NS
|
BEGIN_PS_NS
|
||||||
|
|
||||||
|
|
||||||
uint8_t nCinemaSeen;
|
|
||||||
|
|
||||||
uint8_t energytile[66 * 66] = {0};
|
uint8_t energytile[66 * 66] = {0};
|
||||||
|
|
||||||
uint8_t *cur;
|
uint8_t *cur;
|
||||||
|
|
|
@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
#include "s_music.h"
|
#include "s_music.h"
|
||||||
#include "screenjob.h"
|
#include "screenjob.h"
|
||||||
#include "v_draw.h"
|
#include "v_draw.h"
|
||||||
|
#include "vm.h"
|
||||||
|
|
||||||
BEGIN_PS_NS
|
BEGIN_PS_NS
|
||||||
|
|
||||||
|
@ -63,9 +64,34 @@ class LMFPlayer
|
||||||
AudioData audio{};
|
AudioData audio{};
|
||||||
AnimTextures animtex;
|
AnimTextures animtex;
|
||||||
|
|
||||||
|
FileReader fp;
|
||||||
|
|
||||||
int nFrame = 0;
|
int nFrame = 0;
|
||||||
|
|
||||||
|
uint64_t nextclock = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
LMFPlayer(const char *filename)
|
||||||
|
{
|
||||||
|
fp = fileSystem.OpenFileReader(filename);
|
||||||
|
Open(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Frame(uint64_t clock)
|
||||||
|
{
|
||||||
|
if (clock >= nextclock)
|
||||||
|
{
|
||||||
|
nextclock += 100'000'000;
|
||||||
|
if (ReadFrame(fp) == 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int ReadFrame(FileReader& fp)
|
int ReadFrame(FileReader& fp)
|
||||||
{
|
{
|
||||||
nFrame++;
|
nFrame++;
|
||||||
|
@ -188,107 +214,56 @@ public:
|
||||||
S_StopCustomStream(stream);
|
S_StopCustomStream(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimTextures& animTex()
|
FTextureID GetTexture()
|
||||||
{
|
{
|
||||||
return animtex;
|
return animtex.GetFrameID();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 0
|
int IdentifyLMF(const FString* fn)
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
class DLmfPlayer : public DSkippableScreenJob
|
|
||||||
{
|
{
|
||||||
LMFPlayer decoder;
|
auto fp = fileSystem.OpenFileReader(*fn);
|
||||||
double angle = 1536;
|
if (!fp.isOpen()) return false;
|
||||||
double z = 0;
|
|
||||||
uint64_t nextclock = 0, lastclock = 0;
|
|
||||||
FileReader fp;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
DLmfPlayer(FileReader& fr)
|
|
||||||
{
|
|
||||||
decoder.Open(fr);
|
|
||||||
lastclock = 0;
|
|
||||||
nextclock = 0;
|
|
||||||
fp = std::move(fr);
|
|
||||||
pausable = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void Draw(double smoothratio) override
|
|
||||||
{
|
|
||||||
uint64_t clock = (ticks + smoothratio) * 1'000'000'000. / GameTicRate;
|
|
||||||
if (clock >= nextclock)
|
|
||||||
{
|
|
||||||
nextclock += 100'000'000;
|
|
||||||
if (decoder.ReadFrame(fp) == 0)
|
|
||||||
{
|
|
||||||
state = finished;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
double duration = (clock - lastclock) * double(120. / 8'000'000'000);
|
|
||||||
if (z < 65536) { // Zoom - normal zoom is 65536.
|
|
||||||
z += 2048 * duration;
|
|
||||||
}
|
|
||||||
if (z > 65536) z = 65536;
|
|
||||||
if (angle != 0) {
|
|
||||||
angle += 16. * duration;
|
|
||||||
if (angle >= 2048) {
|
|
||||||
angle = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
twod->ClearScreen();
|
|
||||||
DrawTexture(twod, decoder.animTex().GetFrame(), 160, 100, DTA_FullscreenScale, FSMode_Fit320x200,
|
|
||||||
DTA_CenterOffset, true, DTA_FlipY, true, DTA_ScaleX, z / 65536., DTA_ScaleY, z / 65536., DTA_Rotate, (-angle - 512) * BAngToDegree, TAG_DONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
lastclock = clock;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnDestroy() override
|
|
||||||
{
|
|
||||||
decoder.Close();
|
|
||||||
fp.Close();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DScreenJob* PlayMovie(const char* fileName)
|
|
||||||
{
|
|
||||||
// clear keys
|
|
||||||
|
|
||||||
auto fp = fileSystem.OpenFileReader(fileName);
|
|
||||||
if (!fp.isOpen())
|
|
||||||
{
|
|
||||||
return Create<DBlackScreen>(1);
|
|
||||||
}
|
|
||||||
char buffer[4];
|
char buffer[4];
|
||||||
fp.Read(buffer, 4);
|
fp.Read(buffer, 4);
|
||||||
if (memcmp(buffer, "LMF ", 4))
|
return (0 == memcmp(buffer, "LMF ", 4));
|
||||||
{
|
|
||||||
fp.Close();
|
|
||||||
// Allpw replacement with more modern formats.
|
|
||||||
return PlayVideo(fileName);
|
|
||||||
}
|
|
||||||
fp.Seek(0, FileReader::SeekSet);
|
|
||||||
return Create<DLmfPlayer>(fp);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
DEFINE_ACTION_FUNCTION(_LMFDecoder, Create)
|
||||||
|
{
|
||||||
|
PARAM_PROLOGUE;
|
||||||
|
PARAM_STRING(fn);
|
||||||
|
ACTION_RETURN_POINTER(new LMFPlayer(fn));
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION_NATIVE(_LMFDecoder, Identify, IdentifyLMF)
|
||||||
|
{
|
||||||
|
PARAM_PROLOGUE;
|
||||||
|
PARAM_STRING(fn);
|
||||||
|
ACTION_RETURN_BOOL(IdentifyLMF(&fn));
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(_LMFDecoder, Frame)
|
||||||
|
{
|
||||||
|
PARAM_SELF_STRUCT_PROLOGUE(LMFPlayer);
|
||||||
|
PARAM_FLOAT(clock);
|
||||||
|
ACTION_RETURN_BOOL(self->Frame(uint64_t(clock)));
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(_LMFDecoder, GetTexture)
|
||||||
|
{
|
||||||
|
PARAM_SELF_STRUCT_PROLOGUE(LMFPlayer);
|
||||||
|
ACTION_RETURN_INT(self->GetTexture().GetIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(_LMFDecoder, Close)
|
||||||
|
{
|
||||||
|
PARAM_SELF_STRUCT_PROLOGUE(LMFPlayer);
|
||||||
|
self->Close();
|
||||||
|
delete self;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
END_PS_NS
|
END_PS_NS
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
x(SkullJaw, 3437)
|
||||||
x(PowerslaveLogo, 3442)
|
x(PowerslaveLogo, 3442)
|
||||||
x(MenuNewGameTile, 3460)
|
x(MenuNewGameTile, 3460)
|
||||||
x(MenuLoadGameTile, 3461)
|
x(MenuLoadGameTile, 3461)
|
||||||
|
@ -6,6 +7,7 @@ x(MenuSoundFxTile, 3466)
|
||||||
x(MenuCursorTile, 3468)
|
x(MenuCursorTile, 3468)
|
||||||
x(MenuBlank, 3469)
|
x(MenuBlank, 3469)
|
||||||
x(SkullHead, 3582)
|
x(SkullHead, 3582)
|
||||||
|
x(SkullJaw2, 3583)
|
||||||
x(ExhumedLogo, 3592)
|
x(ExhumedLogo, 3592)
|
||||||
x(Energy1, 3604)
|
x(Energy1, 3604)
|
||||||
x(Energy2, 3605)
|
x(Energy2, 3605)
|
||||||
|
@ -27,4 +29,100 @@ x(ClockSymbol15, 3620)
|
||||||
x(ClockSymbol16, 3621)
|
x(ClockSymbol16, 3621)
|
||||||
x(TileLoboLaptop, 3623)
|
x(TileLoboLaptop, 3623)
|
||||||
x(TileBMGLogo, 3368)
|
x(TileBMGLogo, 3368)
|
||||||
|
x(LobotomyLogo, 3348)
|
||||||
x(TilePIELogo, 3349)
|
x(TilePIELogo, 3349)
|
||||||
|
x(Gameover, 3591)
|
||||||
|
|
||||||
|
x(MapPlaque1_01, 3376)
|
||||||
|
x(MapPlaque1_02, 3378)
|
||||||
|
x(MapPlaque1_03, 3380)
|
||||||
|
x(MapPlaque1_04, 3382)
|
||||||
|
x(MapPlaque1_05, 3384)
|
||||||
|
x(MapPlaque1_06, 3371)
|
||||||
|
x(MapPlaque1_07, 3387)
|
||||||
|
x(MapPlaque1_08, 3389)
|
||||||
|
x(MapPlaque1_09, 3391)
|
||||||
|
x(MapPlaque1_10, 3409)
|
||||||
|
x(MapPlaque1_11, 3393)
|
||||||
|
x(MapPlaque1_12, 3395)
|
||||||
|
x(MapPlaque1_13, 3397)
|
||||||
|
x(MapPlaque1_14, 3399)
|
||||||
|
x(MapPlaque1_15, 3401)
|
||||||
|
x(MapPlaque1_16, 3403)
|
||||||
|
x(MapPlaque1_17, 3405)
|
||||||
|
x(MapPlaque1_18, 3407)
|
||||||
|
x(MapPlaque1_19, 3412)
|
||||||
|
x(MapPlaque1_20, 3415)
|
||||||
|
|
||||||
|
x(MapPlaque2_01, 3377)
|
||||||
|
x(MapPlaque2_02, 3379)
|
||||||
|
x(MapPlaque2_03, 3381)
|
||||||
|
x(MapPlaque2_04, 3383)
|
||||||
|
x(MapPlaque2_05, 3385)
|
||||||
|
x(MapPlaque2_06, 3386)
|
||||||
|
x(MapPlaque2_07, 3388)
|
||||||
|
x(MapPlaque2_08, 3390)
|
||||||
|
x(MapPlaque2_09, 3392)
|
||||||
|
x(MapPlaque2_10, 3410)
|
||||||
|
x(MapPlaque2_11, 3394)
|
||||||
|
x(MapPlaque2_12, 3396)
|
||||||
|
x(MapPlaque2_13, 3398)
|
||||||
|
x(MapPlaque2_14, 3400)
|
||||||
|
x(MapPlaque2_15, 3402)
|
||||||
|
x(MapPlaque2_16, 3404)
|
||||||
|
x(MapPlaque2_17, 3406)
|
||||||
|
x(MapPlaque2_18, 3408)
|
||||||
|
x(MapPlaque2_19, 3413)
|
||||||
|
x(MapPlaque2_20, 3416)
|
||||||
|
|
||||||
|
x(MapPlaqueText_01, 3411)
|
||||||
|
x(MapPlaqueText_02, 3414)
|
||||||
|
x(MapPlaqueText_03, 3417)
|
||||||
|
x(MapPlaqueText_04, 3420)
|
||||||
|
x(MapPlaqueText_05, 3423)
|
||||||
|
x(MapPlaqueText_06, 3426)
|
||||||
|
x(MapPlaqueText_07, 3429)
|
||||||
|
x(MapPlaqueText_08, 3432)
|
||||||
|
x(MapPlaqueText_09, 3435)
|
||||||
|
x(MapPlaqueText_10, 3418)
|
||||||
|
x(MapPlaqueText_11, 3438)
|
||||||
|
x(MapPlaqueText_12, 3441)
|
||||||
|
x(MapPlaqueText_13, 3444)
|
||||||
|
x(MapPlaqueText_14, 3447)
|
||||||
|
x(MapPlaqueText_15, 3450)
|
||||||
|
x(MapPlaqueText_16, 3453)
|
||||||
|
x(MapPlaqueText_17, 3456)
|
||||||
|
x(MapPlaqueText_18, 3459)
|
||||||
|
x(MapPlaqueText_19, 3419)
|
||||||
|
x(MapPlaqueText_20, 3421)
|
||||||
|
|
||||||
|
x(MapFire_11, 3484)
|
||||||
|
x(MapFire_12, 3485)
|
||||||
|
x(MapFire_13, 3486)
|
||||||
|
x(MapFire_14, 3487)
|
||||||
|
x(MapFire_21, 3488)
|
||||||
|
x(MapFire_22, 3489)
|
||||||
|
x(MapFire_23, 3490)
|
||||||
|
x(MapFire_24, 3491)
|
||||||
|
x(MapFire_31, 3492)
|
||||||
|
x(MapFire_32, 3493)
|
||||||
|
x(MapFire_33, 3494)
|
||||||
|
x(MapFire_34, 3495)
|
||||||
|
|
||||||
|
x(MapBG01, 3353)
|
||||||
|
x(MapBG02, 3354)
|
||||||
|
x(MapBG03, 3355)
|
||||||
|
x(MapBG04, 3356)
|
||||||
|
x(MapBG05, 3357)
|
||||||
|
x(MapBG06, 3358)
|
||||||
|
x(MapBG07, 3359)
|
||||||
|
x(MapBG08, 3360)
|
||||||
|
x(MapBG09, 3361)
|
||||||
|
x(MapBG10, 3362)
|
||||||
|
|
||||||
|
x(TileCinema5, 3449)
|
||||||
|
x(TileCinema10, 3451)
|
||||||
|
x(TileCinema11, 3454)
|
||||||
|
x(TileCinema15, 3446)
|
||||||
|
x(TileCinemaLose, 3445)
|
||||||
|
x(TileCinema20, 3448)
|
||||||
|
|
|
@ -29,136 +29,10 @@ kTileStatusBar = 657,
|
||||||
kTile985 = 985,
|
kTile985 = 985,
|
||||||
kTile986 = 986,
|
kTile986 = 986,
|
||||||
kTile3000 = 3000,
|
kTile3000 = 3000,
|
||||||
kTile3117 = 3117,
|
kQueenChunk = 3117,
|
||||||
kTile3126 = 3126,
|
kTile3126 = 3126,
|
||||||
kTile3353 = 3353,
|
|
||||||
kTile3370 = 3370,
|
|
||||||
kTile3371 = 3371,
|
|
||||||
kTile3372 = 3372,
|
|
||||||
kTile3373 = 3373,
|
|
||||||
kTile3374 = 3374,
|
|
||||||
kTile3375 = 3375,
|
|
||||||
kTile3376 = 3376,
|
|
||||||
kTile3377 = 3377,
|
|
||||||
kTile3378 = 3378,
|
|
||||||
kTile3379 = 3379,
|
|
||||||
kTile3380 = 3380,
|
|
||||||
kTile3381 = 3381,
|
|
||||||
kTile3382 = 3382,
|
|
||||||
kTile3383 = 3383,
|
|
||||||
kTile3384 = 3384,
|
|
||||||
kTile3385 = 3385,
|
|
||||||
kTile3386 = 3386,
|
|
||||||
kTile3387 = 3387,
|
|
||||||
kTile3388 = 3388,
|
|
||||||
kTile3389 = 3389,
|
|
||||||
kTile3390 = 3390,
|
|
||||||
kTile3391 = 3391,
|
|
||||||
kTile3392 = 3392,
|
|
||||||
kTile3393 = 3393,
|
|
||||||
kTile3394 = 3394,
|
|
||||||
kTile3395 = 3395,
|
|
||||||
kTile3396 = 3396,
|
|
||||||
kTile3397 = 3397,
|
|
||||||
kTile3398 = 3398,
|
|
||||||
kTile3399 = 3399,
|
|
||||||
kTile3400 = 3400,
|
|
||||||
kTile3401 = 3401,
|
|
||||||
kTile3402 = 3402,
|
|
||||||
kTile3403 = 3403,
|
|
||||||
kTile3404 = 3404,
|
|
||||||
kTile3405 = 3405,
|
|
||||||
kTile3406 = 3406,
|
|
||||||
kTile3407 = 3407,
|
|
||||||
kTile3408 = 3408,
|
|
||||||
kTile3409 = 3409,
|
|
||||||
kTile3410 = 3410,
|
|
||||||
kTile3411 = 3411,
|
|
||||||
kTile3412 = 3412,
|
|
||||||
kTile3413 = 3413,
|
|
||||||
kTile3414 = 3414,
|
|
||||||
kTile3415 = 3415,
|
|
||||||
kTile3416 = 3416,
|
|
||||||
kTile3417 = 3417,
|
|
||||||
kTile3418 = 3418,
|
|
||||||
kTile3419 = 3419,
|
|
||||||
kTile3420 = 3420,
|
|
||||||
kTile3421 = 3421,
|
|
||||||
kTile3422 = 3422,
|
|
||||||
kTile3423 = 3423,
|
|
||||||
kTile3424 = 3424,
|
|
||||||
kTile3425 = 3425,
|
|
||||||
kTile3426 = 3426,
|
|
||||||
kTile3427 = 3427,
|
|
||||||
kTile3428 = 3428,
|
|
||||||
kTile3429 = 3429,
|
|
||||||
kTile3430 = 3430,
|
|
||||||
kTile3431 = 3431,
|
|
||||||
kTile3432 = 3432,
|
|
||||||
kTile3433 = 3433,
|
|
||||||
kTile3434 = 3434,
|
|
||||||
kTile3435 = 3435,
|
|
||||||
kTile3436 = 3436,
|
|
||||||
kSkullJaw = 3437,
|
|
||||||
kTile3438 = 3438,
|
|
||||||
kTile3439 = 3439,
|
|
||||||
kTile3440 = 3440,
|
|
||||||
kTile3441 = 3441,
|
|
||||||
kTile3443 = 3443,
|
|
||||||
kTile3444 = 3444,
|
|
||||||
kTile3445 = 3445,
|
|
||||||
kTile3446 = 3446,
|
|
||||||
kTile3447 = 3447,
|
|
||||||
kTile3448 = 3448,
|
|
||||||
kTile3449 = 3449,
|
|
||||||
kTile3450 = 3450,
|
|
||||||
kTile3451 = 3451,
|
|
||||||
kTile3452 = 3452,
|
|
||||||
kTile3453 = 3453,
|
|
||||||
kTile3454 = 3454,
|
|
||||||
kTile3455 = 3455,
|
|
||||||
kTile3456 = 3456,
|
|
||||||
kTile3457 = 3457,
|
|
||||||
kTile3458 = 3458,
|
|
||||||
kTile3459 = 3459,
|
|
||||||
kTile3462 = 3462,
|
|
||||||
kTile3463 = 3463,
|
|
||||||
kTile3464 = 3464,
|
|
||||||
kTile3467 = 3467,
|
|
||||||
kTile3470 = 3470,
|
|
||||||
kTile3471 = 3471,
|
|
||||||
kTile3472 = 3472,
|
|
||||||
kTile3473 = 3473,
|
|
||||||
kTile3474 = 3474,
|
|
||||||
kTile3475 = 3475,
|
|
||||||
kTile3476 = 3476,
|
|
||||||
kTile3477 = 3477,
|
|
||||||
kTile3478 = 3478,
|
|
||||||
kTile3479 = 3479,
|
|
||||||
kTile3480 = 3480,
|
|
||||||
kTile3481 = 3481,
|
|
||||||
kTile3482 = 3482,
|
|
||||||
kTile3483 = 3483,
|
|
||||||
kTile3484 = 3484,
|
|
||||||
kTile3485 = 3485,
|
|
||||||
kTile3486 = 3486,
|
|
||||||
kTile3487 = 3487,
|
|
||||||
kTile3488 = 3488,
|
|
||||||
kTile3489 = 3489,
|
|
||||||
kTile3490 = 3490,
|
|
||||||
kTile3491 = 3491,
|
|
||||||
kTile3492 = 3492,
|
|
||||||
kTile3493 = 3493,
|
|
||||||
kTile3494 = 3494,
|
|
||||||
kTile3495 = 3495,
|
|
||||||
kTile3496 = 3496,
|
|
||||||
kTile3497 = 3497,
|
|
||||||
kTile3498 = 3498,
|
|
||||||
kTile3499 = 3499,
|
|
||||||
kTile3512 = 3512,
|
kTile3512 = 3512,
|
||||||
kTile3571 = 3571,
|
kTile3571 = 3571,
|
||||||
kTile3583 = 3583,
|
|
||||||
kTile3591 = 3591,
|
|
||||||
kTile3593 = 3593,
|
kTile3593 = 3593,
|
||||||
kTile3603 = 3603,
|
kTile3603 = 3603,
|
||||||
kTile4092 = 4092,
|
kTile4092 = 4092,
|
||||||
|
|
|
@ -1445,7 +1445,7 @@ void FuncQueen(int a, int nDamage, int nRun)
|
||||||
{
|
{
|
||||||
short nChunkSprite = BuildCreatureChunk(nSprite, seq_GetSeqPicnum(kSeqQueen, 57, 0)) & 0xFFFF;
|
short nChunkSprite = BuildCreatureChunk(nSprite, seq_GetSeqPicnum(kSeqQueen, 57, 0)) & 0xFFFF;
|
||||||
|
|
||||||
sprite[nChunkSprite].picnum = kTile3117 + (i % 3);
|
sprite[nChunkSprite].picnum = kQueenChunk + (i % 3);
|
||||||
sprite[nChunkSprite].xrepeat = 100;
|
sprite[nChunkSprite].xrepeat = 100;
|
||||||
sprite[nChunkSprite].yrepeat = 100;
|
sprite[nChunkSprite].yrepeat = 100;
|
||||||
}
|
}
|
||||||
|
|
|
@ -800,4 +800,35 @@ void PlayGameOverSound(void)
|
||||||
PlayLocalSound(StaticSound[kSoundJonLaugh2], 0, false, CHANF_UI);
|
PlayLocalSound(StaticSound[kSoundJonLaugh2], 0, false, CHANF_UI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(_Exhumed, PlayLocalSound)
|
||||||
|
{
|
||||||
|
PARAM_PROLOGUE;
|
||||||
|
PARAM_INT(snd);
|
||||||
|
PARAM_INT(pitch);
|
||||||
|
PARAM_BOOL(unatt);
|
||||||
|
PARAM_INT(flags);
|
||||||
|
PlayLocalSound(StaticSound[snd], pitch, unatt, EChanFlags::FromInt(flags));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION_NATIVE(_Exhumed, StopLocalSound, StopLocalSound)
|
||||||
|
{
|
||||||
|
StopLocalSound();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(_Exhumed, LocalSoundPlaying)
|
||||||
|
{
|
||||||
|
ACTION_RETURN_BOOL(soundEngine->IsSourcePlayingSomething(SOURCE_None, nullptr, CHAN_AUTO, -1));
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(_Exhumed, PlayCDTrack)
|
||||||
|
{
|
||||||
|
PARAM_PROLOGUE;
|
||||||
|
PARAM_INT(track);
|
||||||
|
PARAM_BOOL(loop);
|
||||||
|
playCDtrack(track, loop);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
END_PS_NS
|
END_PS_NS
|
||||||
|
|
71
wadsrc/static/filter/exhumed/engine/engine.def
Normal file
71
wadsrc/static/filter/exhumed/engine/engine.def
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
// Cutscene definitions for Duke
|
||||||
|
|
||||||
|
definecutscene intro
|
||||||
|
{
|
||||||
|
function ExhumedCutscenes.BuildIntro
|
||||||
|
}
|
||||||
|
|
||||||
|
definecutscene map lev5
|
||||||
|
{
|
||||||
|
intro
|
||||||
|
{
|
||||||
|
function ExhumedCutscenes.BuildCinemaBefore5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
definecutscene map lev10
|
||||||
|
{
|
||||||
|
outro
|
||||||
|
{
|
||||||
|
function ExhumedCutscenes.BuildCinemaAfter10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
definecutscene map lev11
|
||||||
|
{
|
||||||
|
intro
|
||||||
|
{
|
||||||
|
function ExhumedCutscenes.BuildCinemaBefore11
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
definecutscene map lev15
|
||||||
|
{
|
||||||
|
outro
|
||||||
|
{
|
||||||
|
function ExhumedCutscenes.BuildCinemaAfter15
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
definecutscene map lev20
|
||||||
|
{
|
||||||
|
intro
|
||||||
|
{
|
||||||
|
function ExhumedCutscenes.BuildCinemaBefore20
|
||||||
|
}
|
||||||
|
outro
|
||||||
|
{
|
||||||
|
function ExhumedCutscenes.BuildCinemaAfter20
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
definecutscene gameover
|
||||||
|
{
|
||||||
|
function ExhumedCutscenes.BuildGameoverScene
|
||||||
|
}
|
||||||
|
|
||||||
|
definecutscene lose
|
||||||
|
{
|
||||||
|
function ExhumedCutscenes.BuildCinemaLose
|
||||||
|
}
|
||||||
|
|
||||||
|
definecutscene loading
|
||||||
|
{
|
||||||
|
function DukeCutscenes.BuildLoading
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
definecutscene summary ExhumedCutscenes.BuildMap
|
||||||
|
//definecutscene mpsummary DukeCutscenes.BuildMPSummary
|
||||||
|
|
|
@ -39,4 +39,6 @@ version "4.3"
|
||||||
#include "zscript/games/sw/swgame.zs"
|
#include "zscript/games/sw/swgame.zs"
|
||||||
#include "zscript/games/sw/ui/menu.zs"
|
#include "zscript/games/sw/ui/menu.zs"
|
||||||
#include "zscript/games/sw/ui/screens.zs"
|
#include "zscript/games/sw/ui/screens.zs"
|
||||||
|
#include "zscript/games/exhumed/exhumedgame.zs"
|
||||||
#include "zscript/games/exhumed/ui/menu.zs"
|
#include "zscript/games/exhumed/ui/menu.zs"
|
||||||
|
#include "zscript/games/exhumed/ui/screens.zs"
|
||||||
|
|
|
@ -187,6 +187,8 @@ struct MusPlayingInfo native
|
||||||
native String name;
|
native String name;
|
||||||
native int baseorder;
|
native int baseorder;
|
||||||
native bool loop;
|
native bool loop;
|
||||||
|
native voidptr handle;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TexMan
|
struct TexMan
|
||||||
|
@ -662,6 +664,7 @@ struct StringStruct native
|
||||||
native void DeleteLastCharacter();
|
native void DeleteLastCharacter();
|
||||||
native int CodePointCount() const;
|
native int CodePointCount() const;
|
||||||
native int, int GetNextCodePoint(int position) const;
|
native int, int GetNextCodePoint(int position) const;
|
||||||
|
native void Substitute(String str, String replace);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Translation version("2.4")
|
struct Translation version("2.4")
|
||||||
|
|
|
@ -120,6 +120,21 @@ struct InputEvent native play version("2.4")
|
||||||
Key_F12 = 0x58, // DIK_F12
|
Key_F12 = 0x58, // DIK_F12
|
||||||
Key_Grave = 0x29, // DIK_GRAVE
|
Key_Grave = 0x29, // DIK_GRAVE
|
||||||
|
|
||||||
|
KEY_kpad_1 = 0x4f,
|
||||||
|
KEY_kpad_2 = 0x50,
|
||||||
|
KEY_kpad_3 = 0x51,
|
||||||
|
KEY_kpad_4 = 0x4b,
|
||||||
|
KEY_kpad_5 = 0x4c,
|
||||||
|
KEY_kpad_6 = 0x4d,
|
||||||
|
KEY_kpad_7 = 0x47,
|
||||||
|
KEY_kpad_8 = 0x48,
|
||||||
|
KEY_kpad_9 = 0x49,
|
||||||
|
KEY_kpad_0 = 0x52,
|
||||||
|
KEY_kpad_Minus = 0x4a,
|
||||||
|
KEY_kpad_Plus = 0x4e,
|
||||||
|
KEY_kpad_Period = 0x53,
|
||||||
|
|
||||||
|
|
||||||
Key_Backspace = 0x0e, // DIK_BACK
|
Key_Backspace = 0x0e, // DIK_BACK
|
||||||
|
|
||||||
Key_Equals = 0x0d, // DIK_EQUALS
|
Key_Equals = 0x0d, // DIK_EQUALS
|
||||||
|
|
|
@ -40,6 +40,7 @@ struct KeyBindings native version("2.4")
|
||||||
|
|
||||||
native int, int GetKeysForCommand(String cmd);
|
native int, int GetKeysForCommand(String cmd);
|
||||||
native void GetAllKeysForCommand(out array<int> list, String cmd);
|
native void GetAllKeysForCommand(out array<int> list, String cmd);
|
||||||
|
native String GetBinding(int key);
|
||||||
|
|
||||||
native void SetBind(int key, String cmd);
|
native void SetBind(int key, String cmd);
|
||||||
native void UnbindACommand (String str);
|
native void UnbindACommand (String str);
|
||||||
|
|
104
wadsrc/static/zscript/games/exhumed/exhumedgame.zs
Normal file
104
wadsrc/static/zscript/games/exhumed/exhumedgame.zs
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
|
||||||
|
|
||||||
|
struct Exhumed native
|
||||||
|
{
|
||||||
|
native static void PlayLocalSound(int snd, int pitch, bool b, int chanf);
|
||||||
|
native static void StopLocalSound();
|
||||||
|
native static bool LocalSoundPlaying();
|
||||||
|
native static void playCDTrack(int track, bool looped);
|
||||||
|
native static void DrawPlasma();
|
||||||
|
|
||||||
|
|
||||||
|
static void DrawAbs(String img, int x, int y, int shade = 0)
|
||||||
|
{
|
||||||
|
Screen.DrawTexture(TexMan.CheckForTexture(img, TexMan.Type_Any), false, x, y, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TopLeft, true, DTA_Color, Raze.shadeToLight(shade));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DRawRel(String img, int x, int y, int shade = 0)
|
||||||
|
{
|
||||||
|
let tex = TexMan.CheckForTexture(img, TexMan.Type_Any);
|
||||||
|
if (!tex.IsValid()) return;
|
||||||
|
let size = TexMan.GetScaledSize(tex);
|
||||||
|
let offs = TexMan.GetScaledOffset(tex);
|
||||||
|
// The integer truncation here is important. Old Build versions were bugged here.
|
||||||
|
x -= (int(size.x) >> 1) + int(offs.x);
|
||||||
|
y -= (int(size.y) >> 1) + int(offs.y);
|
||||||
|
Screen.DrawTexture(tex, false, x, y, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TopLeft, true, DTA_Color, Raze.shadeToLight(shade));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct ExhumedSnd native
|
||||||
|
{
|
||||||
|
enum ESounds
|
||||||
|
{
|
||||||
|
kSound0 = 0,
|
||||||
|
kSound1,
|
||||||
|
kSound2,
|
||||||
|
kSound3,
|
||||||
|
kSound4,
|
||||||
|
kSound5,
|
||||||
|
kSound6,
|
||||||
|
kSound7,
|
||||||
|
kSound8,
|
||||||
|
kSound9,
|
||||||
|
kSoundItemSpecial,
|
||||||
|
kSound11,
|
||||||
|
kSoundTorchOn,
|
||||||
|
kSound13,
|
||||||
|
kSound14,
|
||||||
|
kSound15,
|
||||||
|
kSound16,
|
||||||
|
kSound17,
|
||||||
|
kSound18,
|
||||||
|
kSound19,
|
||||||
|
kSound20,
|
||||||
|
kSound21,
|
||||||
|
kSound22,
|
||||||
|
kSound23,
|
||||||
|
kSound24,
|
||||||
|
kSound25,
|
||||||
|
kSound26,
|
||||||
|
kSound27,
|
||||||
|
kSoundJonLaugh2,
|
||||||
|
kSound29,
|
||||||
|
kSound30,
|
||||||
|
kSound31,
|
||||||
|
kSound32,
|
||||||
|
kSound33,
|
||||||
|
kSound34,
|
||||||
|
kSound35,
|
||||||
|
kSound36,
|
||||||
|
kSound38 = 38,
|
||||||
|
kSound39,
|
||||||
|
kSound40,
|
||||||
|
kSound41,
|
||||||
|
kSound42,
|
||||||
|
kSound43,
|
||||||
|
kSound47 = 47,
|
||||||
|
kSound48 = 48,
|
||||||
|
kSoundQTail = 50,
|
||||||
|
kSound52 = 52,
|
||||||
|
kSoundTauntStart = 53,
|
||||||
|
kSoundJonFDie = 60,
|
||||||
|
kSound61,
|
||||||
|
kSound62,
|
||||||
|
kSound63,
|
||||||
|
kSound64,
|
||||||
|
kSound65,
|
||||||
|
kSound66,
|
||||||
|
kSoundMana1,
|
||||||
|
kSoundMana2,
|
||||||
|
kSoundAmmoPickup,
|
||||||
|
kSound70,
|
||||||
|
kSound71,
|
||||||
|
kSound72,
|
||||||
|
kSoundAlarm,
|
||||||
|
kSound74,
|
||||||
|
kSound75,
|
||||||
|
kSound76,
|
||||||
|
kSound77,
|
||||||
|
kSound78,
|
||||||
|
kSound79,
|
||||||
|
}
|
||||||
|
}
|
|
@ -50,7 +50,10 @@ class ListMenuItemExhumedPlasma : ListMenuItem
|
||||||
Super.Init(0, 0);
|
Super.Init(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
native override void Draw(bool selected, ListMenuDescriptor desc);
|
override void Draw(bool selected, ListMenuDescriptor desc)
|
||||||
|
{
|
||||||
|
Exhumed.DrawPlasma();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ListMenuItemExhumedLogo : ListMenuItem
|
class ListMenuItemExhumedLogo : ListMenuItem
|
||||||
|
|
927
wadsrc/static/zscript/games/exhumed/ui/screens.zs
Normal file
927
wadsrc/static/zscript/games/exhumed/ui/screens.zs
Normal file
|
@ -0,0 +1,927 @@
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||||
|
Copyright (C) 2019 sirlemonhead, Nuke.YKT
|
||||||
|
Copyright (C) 2020-2021 Christoph Oelckers
|
||||||
|
This file is part of Raze.
|
||||||
|
PCExhumed 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.
|
||||||
|
*/
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct LMFDecoder native
|
||||||
|
{
|
||||||
|
static native bool Identify(String fn);
|
||||||
|
static native LMFDecoder Create(String fn);
|
||||||
|
native bool Frame(double clock);
|
||||||
|
native TextureID GetTexture();
|
||||||
|
native void Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class LmfPlayer : SkippableScreenJob
|
||||||
|
{
|
||||||
|
LMFDecoder decoder;
|
||||||
|
double nextclock;
|
||||||
|
String fn;
|
||||||
|
|
||||||
|
ScreenJob Init(String filename)
|
||||||
|
{
|
||||||
|
fn = filename;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
override void Start()
|
||||||
|
{
|
||||||
|
decoder = LMFDecoder.Create(fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
override void Draw(double smoothratio)
|
||||||
|
{
|
||||||
|
double clock = (ticks + smoothratio) * 1000000000. / GameTicRate;
|
||||||
|
if (clock >= nextclock)
|
||||||
|
{
|
||||||
|
if (decoder.Frame(clock))
|
||||||
|
{
|
||||||
|
jobstate = finished;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double duration = clock * (120. / 8000000000.);
|
||||||
|
double z = 2048 * duration;
|
||||||
|
if (z > 65536) z = 65536;
|
||||||
|
|
||||||
|
double angle = 1536. + 16. * duration;
|
||||||
|
if (angle >= 2048.) angle = 0.;
|
||||||
|
|
||||||
|
Screen.DrawTexture(decoder.getTexture(), false, 160, 100, DTA_FullscreenScale, FSMode_Fit320x200,
|
||||||
|
DTA_CenterOffset, true, DTA_FlipY, true, DTA_ScaleX, z / 65536., DTA_ScaleY, z / 65536., DTA_Rotate, (-angle - 512) * (360. / 2048.));
|
||||||
|
}
|
||||||
|
|
||||||
|
override void OnDestroy()
|
||||||
|
{
|
||||||
|
decoder.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class LobotomyScreen : ImageScreen
|
||||||
|
{
|
||||||
|
ScreenJob Init(String texname, int fade)
|
||||||
|
{
|
||||||
|
Super.InitNamed(texname, fade);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
override void OnSkip()
|
||||||
|
{
|
||||||
|
Exhumed.StopLocalSound();
|
||||||
|
}
|
||||||
|
|
||||||
|
override void Start()
|
||||||
|
{
|
||||||
|
Exhumed.PlayLocalSound(ExhumedSnd.kSoundJonLaugh2, 7000, false, CHANF_UI);
|
||||||
|
}
|
||||||
|
|
||||||
|
override void OnTick()
|
||||||
|
{
|
||||||
|
Super.OnTick();
|
||||||
|
if (jobstate == finished) Exhumed.StopLocalSound();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
class MainTitle : SkippableScreenJob
|
||||||
|
{
|
||||||
|
String a, b;
|
||||||
|
int mystate;
|
||||||
|
int duration;
|
||||||
|
int var_4;
|
||||||
|
int esi;
|
||||||
|
int nCount;
|
||||||
|
int starttime;
|
||||||
|
static const short skullDurations[] = { 6, 25, 43, 50, 68, 78, 101, 111, 134, 158, 173, 230, 600 };
|
||||||
|
|
||||||
|
ScreenJob Init()
|
||||||
|
{
|
||||||
|
Super.Init(fadein);
|
||||||
|
a = StringTable.Localize("$TXT_EX_COPYRIGHT1");
|
||||||
|
b = StringTable.Localize("$TXT_EX_COPYRIGHT2");
|
||||||
|
duration = skullDurations[0];
|
||||||
|
esi = 130;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
override void Start()
|
||||||
|
{
|
||||||
|
Exhumed.PlayLocalSound(59, 0, true, CHANF_UI);
|
||||||
|
Exhumed.playCDtrack(19, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
override void OnTick()
|
||||||
|
{
|
||||||
|
int ticker = ticks * 120 / GameTicRate;
|
||||||
|
if (ticks > 1 && mystate == 0 && !Exhumed.LocalSoundPlaying())
|
||||||
|
{
|
||||||
|
if (random(0, 15))
|
||||||
|
Exhumed.PlayLocalSound(ExhumedSnd.kSoundJonLaugh2, 0, false, CHANF_UI);
|
||||||
|
else
|
||||||
|
Exhumed.PlayLocalSound(61, 0, false, CHANF_UI);
|
||||||
|
mystate = 1;
|
||||||
|
starttime = ticker;
|
||||||
|
}
|
||||||
|
if (mystate == 1)
|
||||||
|
{
|
||||||
|
if (ticker > duration)
|
||||||
|
{
|
||||||
|
nCount++;
|
||||||
|
if (nCount > 12)
|
||||||
|
{
|
||||||
|
jobstate = finished;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
duration = starttime + skullDurations[nCount];
|
||||||
|
var_4 = var_4 == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override void Draw(double sr)
|
||||||
|
{
|
||||||
|
Exhumed.DrawPlasma();
|
||||||
|
Exhumed.DrawRel("SkullHead", 160, 100);
|
||||||
|
if (mystate == 0)
|
||||||
|
{
|
||||||
|
Exhumed.DrawRel("SkullJaw", 161, 130);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int nStringWidth = SmallFont.StringWidth(a);
|
||||||
|
Screen.DrawText(SmallFont, Font.CR_UNTRANSLATED, 160 - nStringWidth / 2, 200 - 24, a, DTA_FullscreenScale, FSMode_Fit320x200);
|
||||||
|
nStringWidth = SmallFont.StringWidth(b);
|
||||||
|
Screen.DrawText(SmallFont, Font.CR_UNTRANSLATED, 160 - nStringWidth / 2, 200 - 16, b, DTA_FullscreenScale, FSMode_Fit320x200);
|
||||||
|
|
||||||
|
|
||||||
|
String nTile = "SkullJaw";
|
||||||
|
|
||||||
|
if (var_4)
|
||||||
|
{
|
||||||
|
if (esi >= 135) nTile = "SkullJaw2";
|
||||||
|
else esi += 5;
|
||||||
|
}
|
||||||
|
else if (esi <= 130) esi = 130;
|
||||||
|
else esi -= 2;
|
||||||
|
|
||||||
|
int y;
|
||||||
|
|
||||||
|
if (nTile == "SkullJaw2")
|
||||||
|
{
|
||||||
|
y = 131;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
y = esi;
|
||||||
|
if (y > 135) y = 135;
|
||||||
|
}
|
||||||
|
|
||||||
|
Exhumed.DrawRel(nTile, 161, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class MapScreen : ScreenJob
|
||||||
|
{
|
||||||
|
static const int MapLevelOffsets[] = { 0, 50, 10, 20, 0, 45, -20, 20, 5, 0, -10, 10, 30, -20, 0, 20, 0, 0, 0, 0 };
|
||||||
|
static const int MapPlaqueX[] = { 100, 230, 180, 10, 210, 10, 10, 140, 30, 200, 145, 80, 15, 220, 190, 20, 220, 20, 200, 20 };
|
||||||
|
static const int MapPlaqueY[] = { 170, 10, 125, 95, 160, 110, 50, 0, 20, 150, 170, 80, 0, 35, 40, 130, 160, 10, 10, 10 };
|
||||||
|
static const int MapPlaqueTextX[] = { 18, 18, 18, 18, 18, 18, 18, 18, 18, 20, 18, 18, 18, 18, 18, 19, 18, 18, 18, 19 };
|
||||||
|
static const int MapPlaqueTextY[] = { 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 6, 6, 5, 6, 6, 6, 6, 6, 5, 4 };
|
||||||
|
|
||||||
|
static const int FireTilesX[] = { 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1 };
|
||||||
|
static const int FireTilesY[] = { 3, 0, 3, 0, 0, 0, 1, 1, 2, 0, 2, 0 };
|
||||||
|
|
||||||
|
static const int MapLevelFires[] = {
|
||||||
|
3, 0, 107, 95 , 1, 58, 140 , 2, 28, 38 ,
|
||||||
|
3, 2, 240, 0 , 0, 237, 32 , 1, 200, 30 ,
|
||||||
|
2, 2, 250, 57 , 0, 250, 43 , 2, 200, 70 ,
|
||||||
|
2, 1, 82, 59 , 2, 84, 16 , 0, 10, 95 ,
|
||||||
|
2, 2, 237, 50 , 1, 215, 42 , 1, 210, 50 ,
|
||||||
|
3, 0, 40, 7 , 1, 75, 6 , 2, 100, 10 ,
|
||||||
|
3, 0, 58, 61 , 1, 85, 80 , 2, 111, 63 ,
|
||||||
|
3, 0, 260, 65 , 1, 228, 0 , 2, 259, 15 ,
|
||||||
|
2, 0, 81, 38 , 2, 58, 38 , 2, 30, 20 ,
|
||||||
|
3, 0, 259, 49 , 1, 248, 76 , 2, 290, 65 ,
|
||||||
|
3, 2, 227, 66 , 0, 224, 98 , 1, 277, 30 ,
|
||||||
|
2, 0, 100, 10 , 2, 48, 76 , 2, 80, 80 ,
|
||||||
|
3, 0, 17, 2 , 1, 29, 49 , 2, 53, 28 ,
|
||||||
|
3, 0, 266, 42 , 1, 283, 99 , 2, 243, 108 ,
|
||||||
|
2, 0, 238, 19 , 2, 240, 92 , 2, 190, 40 ,
|
||||||
|
2, 0, 27, 0 , 1, 70, 40 , 0, 20, 130 ,
|
||||||
|
3, 0, 275, 65 , 1, 235, 8 , 2, 274, 6 ,
|
||||||
|
3, 0, 75, 45 , 1, 152, 105 , 2, 24, 68 ,
|
||||||
|
3, 0, 290, 25 , 1, 225, 63 , 2, 260, 110 ,
|
||||||
|
0, 1, 20, 10 , 1, 20, 10 , 1, 20, 10
|
||||||
|
};
|
||||||
|
|
||||||
|
const FIRE_SIZE = 10;
|
||||||
|
const FIRE_TYPE = 1;
|
||||||
|
const FIRE_XOFS = 2;
|
||||||
|
const FIRE_YOFS = 3;
|
||||||
|
const FIRE_ELEMENT_SIZE = 3;
|
||||||
|
|
||||||
|
int x;
|
||||||
|
int delta;
|
||||||
|
int nIdleSeconds;
|
||||||
|
|
||||||
|
int curYPos, destYPos;
|
||||||
|
int nLevel, nLevelNew, nLevelBest;
|
||||||
|
|
||||||
|
native static void SetNextLevel(int num);
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ScreenJob Init(int oldlevel, int newlevel, int maxlevel)
|
||||||
|
{
|
||||||
|
Super.Init(fadein|fadeout);
|
||||||
|
nLevel = oldlevel - 1;
|
||||||
|
nLevelNew = newlevel - 1;
|
||||||
|
nLevelBest = min(maxlevel, 19) - 1;
|
||||||
|
curYPos = MapLevelOffsets[nLevel] + (200 * (nLevel / 2));
|
||||||
|
destYPos = MapLevelOffsets[nLevelNew] + (200 * (nLevelNew / 2));
|
||||||
|
if (curYPos < destYPos) delta = 2;
|
||||||
|
else if (curYPos > destYPos) delta = -2;
|
||||||
|
// Trim smoke in widescreen
|
||||||
|
/*
|
||||||
|
vec2_t mapwinxy1 = windowxy1, mapwinxy2 = windowxy2;
|
||||||
|
int32_t width = mapwinxy2.x - mapwinxy1.x + 1, height = mapwinxy2.y - mapwinxy1.y + 1;
|
||||||
|
if (3 * width > 4 * height)
|
||||||
|
{
|
||||||
|
mapwinxy1.x += (width - 4 * height / 3) / 2;
|
||||||
|
mapwinxy2.x -= (width - 4 * height / 3) / 2;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
override bool OnEvent(InputEvent ev)
|
||||||
|
{
|
||||||
|
if (ev.type == InputEvent.Type_KeyDown)
|
||||||
|
{
|
||||||
|
int key = ev.KeyScan;
|
||||||
|
let binding = Bindings.GetBinding(key);
|
||||||
|
if (key == InputEvent.KEY_UPARROW || key == InputEvent.KEY_PAD_DPAD_UP || key == InputEvent.Key_kpad_8 || binding ~== "+move_forward")
|
||||||
|
{
|
||||||
|
if (curYPos == destYPos && nLevelNew <= nLevelBest)
|
||||||
|
{
|
||||||
|
nLevelNew++;
|
||||||
|
SetNextLevel(nLevelNew + 1);
|
||||||
|
destYPos = MapLevelOffsets[nLevelNew] + (200 * (nLevelNew / 2));
|
||||||
|
|
||||||
|
if (curYPos <= destYPos) delta = 2;
|
||||||
|
else delta = -2;
|
||||||
|
nIdleSeconds = 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == InputEvent.KEY_DOWNARROW || key == InputEvent.KEY_PAD_DPAD_DOWN || key == InputEvent.Key_kpad_2 || binding ~== "+move_backward")
|
||||||
|
{
|
||||||
|
if (curYPos == destYPos && nLevelNew > 0)
|
||||||
|
{
|
||||||
|
nLevelNew--;
|
||||||
|
SetNextLevel(nLevelNew + 1);
|
||||||
|
destYPos = MapLevelOffsets[nLevelNew] + (200 * (nLevelNew / 2));
|
||||||
|
|
||||||
|
if (curYPos <= destYPos) delta = 2;
|
||||||
|
else delta = -2;
|
||||||
|
nIdleSeconds = 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!Raze.specialKeyEvent(ev)) jobstate = skipped;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
override void OnTick()
|
||||||
|
{
|
||||||
|
if (curYPos != destYPos)
|
||||||
|
{
|
||||||
|
// scroll the map every couple of ms
|
||||||
|
curYPos += delta;
|
||||||
|
|
||||||
|
if ((curYPos > destYPos && delta > 0) || (curYPos < destYPos && delta < 0))
|
||||||
|
curYPos = destYPos;
|
||||||
|
|
||||||
|
nIdleSeconds = 0;
|
||||||
|
}
|
||||||
|
else nIdleSeconds++;
|
||||||
|
if (nIdleSeconds > 300) jobstate = finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
override void Draw(double smoothratio)
|
||||||
|
{
|
||||||
|
int currentclock = int((ticks + smoothratio) * 120 / GameTicRate);
|
||||||
|
|
||||||
|
int tileY = curYPos;
|
||||||
|
|
||||||
|
// Draw the background screens
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
let tex = String.Format("MapBG%02d", i+1);
|
||||||
|
Exhumed.DrawAbs(tex, x, tileY);
|
||||||
|
tileY -= 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for each level - drawing the 'level completed' on-fire smoke markers
|
||||||
|
for (int i = 0; i < 20; i++)
|
||||||
|
{
|
||||||
|
int screenY = (i >> 1) * -200;
|
||||||
|
|
||||||
|
if (nLevelBest >= i) // check if the player has finished this level
|
||||||
|
{
|
||||||
|
for (int j = 0; j < MapLevelFires[i * FIRE_SIZE]; j++)
|
||||||
|
{
|
||||||
|
int nFireFrame = ((currentclock >> 4) & 3);
|
||||||
|
int elem = i * FIRE_SIZE + FIRE_ELEMENT_SIZE * j;
|
||||||
|
int nFireType = MapLevelFires[elem + FIRE_TYPE];
|
||||||
|
int x = MapLevelFires[elem + FIRE_XOFS];
|
||||||
|
int y = MapLevelFires[elem + FIRE_YOFS];
|
||||||
|
|
||||||
|
String nTile = String.Format("MAPFIRE_%d%d", nFireType+1, nFireFrame+1);
|
||||||
|
int smokeX = x + FireTilesX[nFireType*3 + nFireFrame];
|
||||||
|
int smokeY = y + FireTilesY[nFireType*3 + nFireFrame] + curYPos + screenY;
|
||||||
|
|
||||||
|
// Use rotatesprite to trim smoke in widescreen
|
||||||
|
Exhumed.DrawAbs(nTile, smokeX, smokeY);
|
||||||
|
// Todo: mask out the sides of the screen if the background is not widescreen.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int t = (((currentclock & 16) >> 4));
|
||||||
|
|
||||||
|
String nTile = String.Format("MapPlaque%d_%02d", t+1, i+1);
|
||||||
|
|
||||||
|
int nameX = mapPlaqueX[i];
|
||||||
|
int nameY = mapPlaqueY[i] + curYPos + screenY;
|
||||||
|
|
||||||
|
// Draw level name plaque
|
||||||
|
Exhumed.DrawAbs(nTile, nameX, nameY);
|
||||||
|
|
||||||
|
int shade = 96;
|
||||||
|
|
||||||
|
if (nLevelNew == i)
|
||||||
|
{
|
||||||
|
shade = (Raze.bsin(16 * currentclock) + 31) >> 8;
|
||||||
|
}
|
||||||
|
else if (nLevelBest >= i)
|
||||||
|
{
|
||||||
|
shade = 31;
|
||||||
|
}
|
||||||
|
|
||||||
|
int textY = nameY + MapPlaqueTextY[i];
|
||||||
|
int textX = nameX + MapPlaqueTextX[i];
|
||||||
|
nTile = String.Format("MapPlaqueText_%02d", i+1);
|
||||||
|
|
||||||
|
// draw the text, alternating between red and black
|
||||||
|
Exhumed.DrawAbs(nTile, textX, textY, shade);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class TextOverlay
|
||||||
|
{
|
||||||
|
int nHeight;
|
||||||
|
double nCrawlY;
|
||||||
|
int palette;
|
||||||
|
BrokenLines screentext;
|
||||||
|
|
||||||
|
void Init(String text, int pal)
|
||||||
|
{
|
||||||
|
screentext = SmallFont.BreakLines(StringTable.Localize(text), 320);
|
||||||
|
nCrawlY = 199;
|
||||||
|
nHeight = screentext.Count() * 10;
|
||||||
|
palette = pal;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayText()
|
||||||
|
{
|
||||||
|
if (nHeight + nCrawlY > 0)
|
||||||
|
{
|
||||||
|
double y = nCrawlY;
|
||||||
|
for (int i = 0; i < screentext.Count() && y <= 199; i++)
|
||||||
|
{
|
||||||
|
if (y >= -10)
|
||||||
|
{
|
||||||
|
int x = 160 - screenText.StringWidth(i)/2;
|
||||||
|
Screen.DrawText(SmallFont, Font.CR_UNDEFINED, x, y, screentext.StringAt(i), DTA_FullscreenScale, FSMode_Fit320x200, DTA_TranslationIndex, palette);
|
||||||
|
}
|
||||||
|
y += 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AdvanceCinemaText(double clock)
|
||||||
|
{
|
||||||
|
if (nHeight + nCrawlY > 0 || musplaying.handle)
|
||||||
|
{
|
||||||
|
nCrawlY = 199 - clock / 15.;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// cinema (this has been stripped off all game logic that was still in here)
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class Cinema : SkippableScreenJob
|
||||||
|
{
|
||||||
|
TextOverlay textov;
|
||||||
|
TextureID cinematile;
|
||||||
|
int currentCinemaPalette;
|
||||||
|
int cdtrack;
|
||||||
|
int palette;
|
||||||
|
bool done;
|
||||||
|
|
||||||
|
ScreenJob Init(String bgTexture, String text, int pal, int cdtrk)
|
||||||
|
{
|
||||||
|
Super.Init(fadein|fadeout);
|
||||||
|
cinematile = TexMan.CheckForTexture(bgTexture, TexMan.Type_Any);
|
||||||
|
textov = new("TextOverlay");
|
||||||
|
palette = Translation.MakeID(Translation_BasePalette, pal);
|
||||||
|
textov.Init(text, palette);
|
||||||
|
cdtrack = cdtrk;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
override void Start()
|
||||||
|
{
|
||||||
|
Raze.StopAllSounds();
|
||||||
|
if (cdtrack != -1)
|
||||||
|
{
|
||||||
|
Exhumed.playCDtrack(cdtrack, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override void OnTick()
|
||||||
|
{
|
||||||
|
if (done) jobstate = finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
override void Draw(double smoothratio)
|
||||||
|
{
|
||||||
|
Screen.DrawTexture(cinematile, false, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_TranslationIndex, palette);
|
||||||
|
textov.DisplayText();
|
||||||
|
done = textov.AdvanceCinemaText((ticks + smoothratio) * (120. / GameTicRate));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class LastLevelCinema : ScreenJob
|
||||||
|
{
|
||||||
|
int var_24;
|
||||||
|
int var_28;
|
||||||
|
|
||||||
|
int ebp;
|
||||||
|
int phase;
|
||||||
|
int nextclock;
|
||||||
|
uint nStringTypeOn, nCharTypeOn;
|
||||||
|
int screencnt;
|
||||||
|
bool skiprequest;
|
||||||
|
|
||||||
|
BrokenLines screentext;
|
||||||
|
Font printFont;
|
||||||
|
TextureID tex;
|
||||||
|
|
||||||
|
ScreenJob Init()
|
||||||
|
{
|
||||||
|
Super.Init(fadein | fadeout);
|
||||||
|
var_24 = 16;
|
||||||
|
var_28 = 12;
|
||||||
|
nextclock = 4;
|
||||||
|
let p = StringTable.Localize("REQUIRED_CHARACTERS", false);
|
||||||
|
if (p == "REQUIRED_CHARACTERS") printFont = SmallFont2;
|
||||||
|
else printFont = ConFont;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
native static TextureID DoStatic(int a, int b);
|
||||||
|
native static TextureID UndoStatic();
|
||||||
|
|
||||||
|
void Phase1()
|
||||||
|
{
|
||||||
|
if (var_24 >= 116)
|
||||||
|
{
|
||||||
|
if (var_28 < 192)
|
||||||
|
var_28 += 20;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var_24 += 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
tex = DoStatic(var_28, var_24);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InitPhase2()
|
||||||
|
{
|
||||||
|
let label = StringTable.Localize(String.Format("$TXT_EX_LASTLEVEL%d", screencnt + 1));
|
||||||
|
screentext = printFont.BreakLines(label, 320);
|
||||||
|
if (screentext.Count() == 0) return false;
|
||||||
|
|
||||||
|
nStringTypeOn = 0;
|
||||||
|
nCharTypeOn = 0;
|
||||||
|
|
||||||
|
ebp = screentext.Count() * 4; // half height of the entire text
|
||||||
|
ebp = 81 - ebp; // offset from the screen's center.
|
||||||
|
tex = UndoStatic();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Phase3()
|
||||||
|
{
|
||||||
|
tex = DoStatic(var_28, var_24);
|
||||||
|
|
||||||
|
if (var_28 > 20)
|
||||||
|
{
|
||||||
|
var_28 -= 20;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (var_24 > 20)
|
||||||
|
{
|
||||||
|
var_24 -= 20;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayPhase2()
|
||||||
|
{
|
||||||
|
int yy = ebp;
|
||||||
|
|
||||||
|
// for international content, use the generic 8x8 font. The original one is too small for expansion.
|
||||||
|
if (printFont == ConFont)
|
||||||
|
{
|
||||||
|
yy *= 2;
|
||||||
|
for (int i = 0; i < nStringTypeOn; i++, yy += 10) Screen.DrawText(ConFont, Font.CR_GREEN, 140, yy, screentext.StringAt(i), DTA_FullscreenScale, FSMode_Fit640x400);
|
||||||
|
Screen.DrawText(ConFont, Font.CR_GREEN, 140, yy, screentext.StringAt(nStringTypeOn), DTA_FullscreenScale, FSMode_Fit640x400, DTA_TextLen, nCharTypeOn);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < nStringTypeOn; i++, yy += 8) Screen.DrawText(SmallFont2, Font.CR_UNTRANSLATED, 70, yy, screentext.StringAt(i), DTA_FullscreenScale, FSMode_Fit320x200);
|
||||||
|
Screen.DrawText(SmallFont2, Font.CR_UNTRANSLATED, 70, yy, screentext.StringAt(nStringTypeOn), DTA_FullscreenScale, FSMode_Fit320x200, DTA_TextLen, nCharTypeOn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override bool OnEvent(InputEvent ev)
|
||||||
|
{
|
||||||
|
if (ev.type == InputEvent.Type_KeyDown && !Raze.specialKeyEvent(ev)) skiprequest = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
override void Start()
|
||||||
|
{
|
||||||
|
Exhumed.PlayLocalSound(ExhumedSnd.kSound75, 0, false, CHANF_UI);
|
||||||
|
phase = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
override void OnTick()
|
||||||
|
{
|
||||||
|
switch (phase)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
Phase1();
|
||||||
|
if (skiprequest || ticks >= nextclock)
|
||||||
|
{
|
||||||
|
InitPhase2();
|
||||||
|
phase = 2;
|
||||||
|
skiprequest = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
let text = screenText.StringAt(nStringTypeOn);
|
||||||
|
int chr;
|
||||||
|
[chr,nCharTypeOn] = text.GetNextCodePoint(nCharTypeOn);
|
||||||
|
|
||||||
|
if (chr == 0)
|
||||||
|
{
|
||||||
|
nCharTypeOn = 0;
|
||||||
|
nStringTypeOn++;
|
||||||
|
if (nStringTypeOn >= screentext.Count())
|
||||||
|
{
|
||||||
|
nextclock = (GameTicRate * (screentext.Count() + 2)) + ticks;
|
||||||
|
phase = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nCharTypeOn++;
|
||||||
|
if (chr != 32) Exhumed.PlayLocalSound(ExhumedSnd.kSound71, 0, false, CHANF_UI);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skiprequest)
|
||||||
|
{
|
||||||
|
nextclock = (GameTicRate * (screentext.Count() + 2)) + ticks;
|
||||||
|
phase = 4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
if (ticks >= nextclock || skiprequest)
|
||||||
|
{
|
||||||
|
Exhumed.PlayLocalSound(ExhumedSnd.kSound75, 0, false, CHANF_UI);
|
||||||
|
phase = 4;
|
||||||
|
nextclock = ticks + 60;
|
||||||
|
skiprequest = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
if (ticks >= nextclock)
|
||||||
|
{
|
||||||
|
skiprequest |= !Phase3();
|
||||||
|
}
|
||||||
|
if (skiprequest)
|
||||||
|
{
|
||||||
|
// Go to the next text page.
|
||||||
|
if (screencnt != 2)
|
||||||
|
{
|
||||||
|
screencnt++;
|
||||||
|
nextclock = ticks + 60;
|
||||||
|
skiprequest = 0;
|
||||||
|
phase = 1;
|
||||||
|
}
|
||||||
|
else jobstate = finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skiprequest)
|
||||||
|
{
|
||||||
|
jobstate = finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override void Draw(double sm)
|
||||||
|
{
|
||||||
|
Screen.DrawTexture(tex, false, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43);
|
||||||
|
if (phase == 2 || phase == 3) DisplayPhase2();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Credits roll
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class ExCredits : ScreenJob
|
||||||
|
{
|
||||||
|
Array<String> credits;
|
||||||
|
Array<String> pagelines;
|
||||||
|
int page;
|
||||||
|
int pagetime;
|
||||||
|
bool skiprequest;
|
||||||
|
|
||||||
|
ScreenJob Init()
|
||||||
|
{
|
||||||
|
Super.Init();
|
||||||
|
String text;
|
||||||
|
int lump = Wads.CheckNumForFullName("credits.txt");
|
||||||
|
if (lump > -1) text = Wads.ReadLump(lump);
|
||||||
|
text.Substitute("\r", "");
|
||||||
|
text.Split(credits, "\n\n");
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
override bool OnEvent(InputEvent ev)
|
||||||
|
{
|
||||||
|
if (ev.type == InputEvent.Type_KeyDown && !Raze.specialKeyEvent(ev)) skiprequest = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
override void Start()
|
||||||
|
{
|
||||||
|
if (credits.Size() == 0)
|
||||||
|
{
|
||||||
|
jobstate = finished;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Exhumed.playCDtrack(19, false);
|
||||||
|
pagetime = 0;
|
||||||
|
page = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
override void OnTick()
|
||||||
|
{
|
||||||
|
if (ticks >= pagetime || skiprequest)
|
||||||
|
{
|
||||||
|
page++;
|
||||||
|
if (page < credits.Size())
|
||||||
|
credits[page].Split(pagelines, "\n");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (skiprequest || !musplaying.handle)
|
||||||
|
{
|
||||||
|
jobstate = finished;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pagelines.Clear();
|
||||||
|
}
|
||||||
|
pagetime = ticks + 60; //
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override void Draw(double smoothratio)
|
||||||
|
{
|
||||||
|
int y = 100 - ((10 * (pagelines.Size() - 1)) / 2);
|
||||||
|
|
||||||
|
for (int i = 0; i < pagelines.Size(); i++)
|
||||||
|
{
|
||||||
|
int ptime = clamp((pagetime - ticks - smoothratio) * 1000 / GameTicRate, 0, 2000); // in milliseconds
|
||||||
|
int light;
|
||||||
|
|
||||||
|
if (ptime < 255) light = ptime;
|
||||||
|
else if (ptime > 2000 - 255) light = 2000 - ptime;
|
||||||
|
else light = 255;
|
||||||
|
|
||||||
|
let colr = Color(light, light, light);
|
||||||
|
|
||||||
|
int nStringWidth = SmallFont.StringWidth(pagelines[i]);
|
||||||
|
Screen.DrawText(SmallFont, Font.CR_UNTRANSLATED, 160 - nStringWidth / 2, y, pagelines[i], DTA_FullscreenScale, FSMode_Fit320x200, DTA_Color, colr);
|
||||||
|
y += 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ExhumedCutscenes
|
||||||
|
{
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static void BuildIntro(ScreenJobRunner runner)
|
||||||
|
{
|
||||||
|
let logo = (gameinfo.gameType & GAMEFLAG_EXHUMED) ? "TileBMGLogo" : "TilePIELogo";
|
||||||
|
runner.Append(ImageScreen.CreateNamed(logo, ScreenJob.fadein | ScreenJob.fadeout));
|
||||||
|
runner.Append(new("LobotomyScreen").Init("LobotomyLogo", ScreenJob.fadein | ScreenJob.fadeout));
|
||||||
|
if (LMFDecoder.Identify("book.mov")) runner.Append(new("LMFPlayer").Init("book.mov"));
|
||||||
|
else runner.Append(MoviePlayerJob.Create("book.mov", 0));
|
||||||
|
runner.Append(new("MainTitle").Init());
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static void BuildMap(ScreenJobRunner runner, MapRecord frommap, SummaryInfo info, MapRecord tomap)
|
||||||
|
{
|
||||||
|
// This is only defined for the regular levels.
|
||||||
|
int frommapnum = frommap == null? 1 : frommap.levelNumber;
|
||||||
|
if (fromMapnum < 1 || fromMapNum > 20 || tomap == null || tomap.levelNumber < 1 || tomap.levelNumber > 20) return;
|
||||||
|
|
||||||
|
// hijack the super secret info in the summary info to convey the max. map because we won't need that field for its real purpose.
|
||||||
|
runner.Append(new("MapScreen").Init(fromMapNum, toMap.levelNumber, info.supersecrets));
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This removes all the insanity the original setup had with these.
|
||||||
|
// Simplicity rules!
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static void BuildCinemaBefore5(ScreenJobRunner runner)
|
||||||
|
{
|
||||||
|
runner.Append(new("Cinema").Init("TileCinema5", "$TXT_EX_CINEMA2", 3, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BuildCinemaAfter10(ScreenJobRunner runner)
|
||||||
|
{
|
||||||
|
runner.Append(new("Cinema").Init("TileCinema10", "$TXT_EX_CINEMA4", 5, 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BuildCinemaBefore11(ScreenJobRunner runner)
|
||||||
|
{
|
||||||
|
runner.Append(new("Cinema").Init("TileCinema11", "$TXT_EX_CINEMA3", 1, 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BuildCinemaAfter15(ScreenJobRunner runner)
|
||||||
|
{
|
||||||
|
runner.Append(new("Cinema").Init("TileCinema15", "$TXT_EX_CINEMA6", 7, 6));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BuildCinemaBefore20(ScreenJobRunner runner)
|
||||||
|
{
|
||||||
|
runner.Append(new("LastLevelCinema").Init());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BuildCinemaAfter20(ScreenJobRunner runner)
|
||||||
|
{
|
||||||
|
runner.Append(new("Cinema").Init("TileCinema20", "$TXT_EX_CINEMA8", 6, 8));
|
||||||
|
runner.Append(new("ExCredits").Init());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BuildCinemaLose(ScreenJobRunner runner)
|
||||||
|
{
|
||||||
|
runner.Append(new("Cinema").Init("TileCinemaLose", "$TXT_EX_CINEMA7", 4, 7));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// player died
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void BuildGameOverScene(ScreenJobRunner runner, MapRecord map)
|
||||||
|
{
|
||||||
|
Raze.StopMusic();
|
||||||
|
Exhumed.PlayLocalSound(ExhumedSnd.kSoundJonLaugh2, 0, false, CHANF_UI);
|
||||||
|
runner.Append(ImageScreen.CreateNamed("Gameover", ScreenJob.fadein | ScreenJob.fadeout, 0x7fffffff, Translation.MakeID(Translation_BasePalette, 16)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -111,6 +111,8 @@ struct Raze
|
||||||
native static bool MusicEnabled();
|
native static bool MusicEnabled();
|
||||||
native static String PlayerName(int i);
|
native static String PlayerName(int i);
|
||||||
native static double GetTimeFrac();
|
native static double GetTimeFrac();
|
||||||
|
native static int bsin(int angle, int shift = 0);
|
||||||
|
native static int bcos(int angle, int shift = 0);
|
||||||
|
|
||||||
static bool specialKeyEvent(InputEvent ev)
|
static bool specialKeyEvent(InputEvent ev)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue