mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-15 08:51:24 +00:00
- most of the summary screen is working
This commit is contained in:
parent
0dc6980e5c
commit
6d743ce921
21 changed files with 266 additions and 276 deletions
|
@ -1498,6 +1498,7 @@ DEFINE_FIELD_X(MapRecord, MapRecord, music)
|
|||
DEFINE_FIELD_X(MapRecord, MapRecord, cdSongId)
|
||||
DEFINE_FIELD_X(MapRecord, MapRecord, flags)
|
||||
DEFINE_FIELD_X(MapRecord, MapRecord, levelNumber)
|
||||
DEFINE_FIELD_X(MapRecord, MapRecord, cluster)
|
||||
DEFINE_FIELD_X(MapRecord, MapRecord, nextLevel)
|
||||
DEFINE_FIELD_X(MapRecord, MapRecord, nextSecret)
|
||||
//native readonly String messages[MAX_MESSAGES];
|
||||
|
|
|
@ -93,6 +93,28 @@ MapRecord *FindMapByLevelNum(int num)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// return a map whose cluster and map number matches.
|
||||
// if there's only one map with the given level number return that.
|
||||
MapRecord* FindMapByClusterAndLevelNum(int cluster, int num)
|
||||
{
|
||||
MapRecord* mr = nullptr;
|
||||
int mapfound = 0;
|
||||
for (auto& map : mapList)
|
||||
{
|
||||
if (map.levelNumber == num)
|
||||
{
|
||||
if (map.cluster == cluster) return ↦
|
||||
else
|
||||
{
|
||||
mr = ↦
|
||||
mapfound++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mapfound == 1) return mr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MapRecord *FindNextMap(MapRecord *thismap)
|
||||
{
|
||||
if (thismap->nextLevel != -1) return FindMapByLevelNum(thismap->nextLevel);
|
||||
|
|
|
@ -44,13 +44,8 @@ enum {
|
|||
MAX_MESSAGES = 32
|
||||
};
|
||||
|
||||
// Cutscene rules for maps are as follows:
|
||||
// * when an episode is started, the episode intro will play, if none is defined, the map's intro will play.
|
||||
// * when an episde is ended, the episode outro will play after the summary screen.
|
||||
// * when a map ends, its own outro scene will play before the summary screen, if none is defined, use the default map outro handler.
|
||||
// * when a new map starts after the summary screen, its own intro scene will play, if none is defined, use the default map intro handler.
|
||||
// * setting any of these fields to 'none' will override any default and play nothing, even if a default is set.
|
||||
class DObject;
|
||||
struct MapRecord;
|
||||
|
||||
struct CutsceneDef
|
||||
{
|
||||
|
@ -60,6 +55,7 @@ struct CutsceneDef
|
|||
int framespersec = 0; // only relevant for ANM.
|
||||
|
||||
void Create(DObject* runner);
|
||||
bool Create(DObject* runner, MapRecord* map);
|
||||
};
|
||||
|
||||
struct GlobalCutscenes
|
||||
|
@ -67,6 +63,7 @@ struct GlobalCutscenes
|
|||
CutsceneDef Intro;
|
||||
CutsceneDef DefaultMapIntro;
|
||||
CutsceneDef DefaultMapOutro;
|
||||
CutsceneDef SharewareEnd;
|
||||
FString MPSummaryScreen;
|
||||
FString SummaryScreen;
|
||||
};
|
||||
|
@ -159,6 +156,7 @@ bool SetMusicForMap(const char* mapname, const char* music, bool namehack = fals
|
|||
|
||||
MapRecord *FindMapByName(const char *nm);
|
||||
MapRecord *FindMapByLevelNum(int num);
|
||||
MapRecord* FindMapByClusterAndLevelNum(int clst, int num);
|
||||
MapRecord *FindNextMap(MapRecord *thismap);
|
||||
MapRecord* SetupUserMap(const char* boardfilename, const char *defaultmusic = nullptr);
|
||||
MapRecord* AllocateMap();
|
||||
|
|
|
@ -96,6 +96,10 @@ void parseDefineCutscene(FScanner& sc, FScriptPosition& pos)
|
|||
{
|
||||
parseCutscene(sc, globalCutscenes.DefaultMapOutro);
|
||||
}
|
||||
else if (sc.Compare("sharewareend")) // sets screens to be shown after the shareware version ends.
|
||||
{
|
||||
parseCutscene(sc, globalCutscenes.SharewareEnd);
|
||||
}
|
||||
else if (sc.Compare({ "episode", "volume", "cluster" }))
|
||||
{
|
||||
FScanner::SavedPos eblockend;
|
||||
|
|
|
@ -62,6 +62,7 @@ static PType* maprecordtype;
|
|||
static PType* summaryinfotype;
|
||||
static CompletionFunc completion;
|
||||
static int ticks;
|
||||
static SummaryInfo summaryinfo;
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
|
@ -133,6 +134,7 @@ void CallCreateFunction(const char* qname, DObject* runner)
|
|||
void CallCreateMapFunction(const char* qname, DObject* runner, MapRecord* map)
|
||||
{
|
||||
auto func = LookupFunction(qname);
|
||||
if (func->Proto->ArgumentTypes.Size() == 1) return CallCreateFunction(qname, runner); // accept functions without map parameter as well here.
|
||||
if (func->Proto->ArgumentTypes.Size() != 2) I_Error("Bad map-cutscene function %s. Must receive precisely two arguments.", qname);
|
||||
if (func->Proto->ArgumentTypes[0] != runnerclasstype && func->Proto->ArgumentTypes[1] != maprecordtype)
|
||||
I_Error("Bad cutscene function %s. Must receive ScreenJobRunner and MapRecord reference.", qname);
|
||||
|
@ -152,7 +154,8 @@ void CallCreateSummaryFunction(const char* qname, DObject* runner, MapRecord* ma
|
|||
if (func->Proto->ArgumentTypes.Size() != 3) I_Error("Bad map-cutscene function %s. Must receive precisely three arguments.", qname);
|
||||
if (func->Proto->ArgumentTypes[0] != runnerclasstype && func->Proto->ArgumentTypes[1] != maprecordtype && func->Proto->ArgumentTypes[2] != summaryinfotype)
|
||||
I_Error("Bad cutscene function %s. Must receive ScreenJobRunner, MapRecord and SummaryInfo reference.", qname);
|
||||
VMValue val[3] = { runner, map, info };
|
||||
summaryinfo = *info; // must be copied to a persistent location.
|
||||
VMValue val[3] = { runner, map, &summaryinfo };
|
||||
VMCall(func, val, 3, nullptr, 0);
|
||||
}
|
||||
|
||||
|
@ -209,27 +212,28 @@ void CutsceneDef::Create(DObject* runner)
|
|||
//
|
||||
//=============================================================================
|
||||
|
||||
bool StartCutscene(CutsceneDef& cs, int flags, CompletionFunc completion_)
|
||||
bool CutsceneDef::Create(DObject* runner, MapRecord* map)
|
||||
{
|
||||
if (cs.function.CompareNoCase("none") != 0)
|
||||
if (function.CompareNoCase("none") == 0)
|
||||
return true; // play nothing but return as being validated
|
||||
if (function.IsNotEmpty())
|
||||
{
|
||||
completion = completion_;
|
||||
runner = CreateRunner();
|
||||
GC::WriteBarrier(runner);
|
||||
cs.Create(runner);
|
||||
gameaction = (flags & SJ_BLOCKUI) ? ga_intro : ga_intermission;
|
||||
CallCreateMapFunction(function, runner, map);
|
||||
return true;
|
||||
}
|
||||
else if (video.IsNotEmpty())
|
||||
{
|
||||
AddGenericVideo(runner, video, sound, framespersec);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool StartCutscene(const char* s, int flags, CompletionFunc completion)
|
||||
{
|
||||
CutsceneDef def;
|
||||
def.function = s;
|
||||
return StartCutscene(def, 0, completion);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void DeleteScreenJob()
|
||||
{
|
||||
|
@ -245,6 +249,12 @@ void EndScreenJob()
|
|||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
bool ScreenJobResponder(event_t* ev)
|
||||
{
|
||||
if (ev->type == EV_KeyDown)
|
||||
|
@ -272,6 +282,12 @@ bool ScreenJobResponder(event_t* ev)
|
|||
return false;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
bool ScreenJobTick()
|
||||
{
|
||||
ticks++;
|
||||
|
@ -289,12 +305,19 @@ bool ScreenJobTick()
|
|||
return false;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void ScreenJobDraw()
|
||||
{
|
||||
double smoothratio = I_GetTimeFrac();
|
||||
|
||||
if (runner)
|
||||
{
|
||||
twod->ClearScreen();
|
||||
IFVIRTUALPTRNAME(runner, NAME_ScreenJobRunner, RunFrame)
|
||||
{
|
||||
VMValue parm[] = { runner, smoothratio };
|
||||
|
@ -303,6 +326,47 @@ void ScreenJobDraw()
|
|||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
bool StartCutscene(CutsceneDef& cs, int flags, const CompletionFunc& completion_)
|
||||
{
|
||||
if (cs.function.CompareNoCase("none") != 0)
|
||||
{
|
||||
completion = completion_;
|
||||
runner = CreateRunner();
|
||||
GC::WriteBarrier(runner);
|
||||
try
|
||||
{
|
||||
cs.Create(runner);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
runner->Destroy();
|
||||
runner = nullptr;
|
||||
throw;
|
||||
}
|
||||
gameaction = (flags & SJ_BLOCKUI) ? ga_intro : ga_intermission;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool StartCutscene(const char* s, int flags, const CompletionFunc& completion)
|
||||
{
|
||||
CutsceneDef def;
|
||||
def.function = s;
|
||||
return StartCutscene(def, 0, completion);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void PlayLogos(gameaction_t complete_ga, gameaction_t def_ga, bool stopmusic)
|
||||
{
|
||||
|
@ -318,6 +382,74 @@ void PlayLogos(gameaction_t complete_ga, gameaction_t def_ga, bool stopmusic)
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void ShowScoreboard(int numplayers, const CompletionFunc& completion_)
|
||||
{
|
||||
completion = completion_;
|
||||
runner = CreateRunner();
|
||||
GC::WriteBarrier(runner);
|
||||
|
||||
const char* qname = globalCutscenes.MPSummaryScreen;
|
||||
auto func = LookupFunction(qname);
|
||||
if (func->Proto->ArgumentTypes.Size() != 2) I_Error("Bad map-cutscene function %s. Must receive precisely two arguments.", qname);
|
||||
if (func->Proto->ArgumentTypes[0] != runnerclasstype && func->Proto->ArgumentTypes[1] != TypeSInt32)
|
||||
I_Error("Bad cutscene function %s. Must receive ScreenJobRunner reference and integer.", qname);
|
||||
VMValue val[2] = { runner, numplayers };
|
||||
VMCall(func, val, 2, nullptr, 0);
|
||||
|
||||
gameaction = ga_intermission;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void ShowIntermission(MapRecord* fromMap, MapRecord* toMap, SummaryInfo* info, CompletionFunc completion_)
|
||||
{
|
||||
completion = completion_;
|
||||
runner = CreateRunner();
|
||||
GC::WriteBarrier(runner);
|
||||
|
||||
// outro: first check the map's own outro.
|
||||
// if that is empty, check the cluster's outro
|
||||
// if that also fails, check the default outro
|
||||
|
||||
try
|
||||
{
|
||||
if (!fromMap->outro.Create(runner, fromMap))
|
||||
{
|
||||
auto& cluster = volumeList[fromMap->cluster - 1];
|
||||
if ((toMap == nullptr || toMap->cluster != fromMap->cluster) && !cluster.outro.Create(runner, fromMap))
|
||||
globalCutscenes.DefaultMapOutro.Create(runner, fromMap);
|
||||
}
|
||||
|
||||
CallCreateSummaryFunction(globalCutscenes.SummaryScreen, runner, fromMap, info);
|
||||
|
||||
if (toMap)
|
||||
{
|
||||
if (!toMap->intro.Create(runner, fromMap))
|
||||
globalCutscenes.DefaultMapIntro.Create(runner, fromMap);
|
||||
}
|
||||
else if (isShareware())
|
||||
{
|
||||
globalCutscenes.SharewareEnd.Create(runner);
|
||||
}
|
||||
gameaction = ga_intermission;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
runner->Destroy();
|
||||
runner = nullptr;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
CCMD(testcutscene)
|
||||
{
|
||||
|
@ -330,16 +462,19 @@ CCMD(testcutscene)
|
|||
{
|
||||
CutsceneDef def;
|
||||
def.function = argv[1];
|
||||
if (StartCutscene(def, 0, [](bool) { }))
|
||||
if (StartCutscene(def, 0, [](bool) {}))
|
||||
{
|
||||
C_HideConsole();
|
||||
}
|
||||
}
|
||||
catch (const CRecoverableError& err)
|
||||
{
|
||||
Printf("Unable to play cutscene\n");
|
||||
Printf(TEXTCOLOR_RED "Unable to play cutscene: %s\n", err.what());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Duke:
|
||||
if (!userConfig.nologo) fi.ShowLogo([](bool) { gameaction = ga_mainmenunostopsound; });
|
||||
|
|
|
@ -201,6 +201,10 @@ bool ScreenJobTick();
|
|||
void ScreenJobDraw();
|
||||
|
||||
struct CutsceneDef;
|
||||
bool StartCutscene(CutsceneDef& cs, int flags, CompletionFunc completion);
|
||||
bool StartCutscene(const char* s, int flags, CompletionFunc completion);
|
||||
struct MapRecord;
|
||||
struct SummaryInfo;
|
||||
bool StartCutscene(CutsceneDef& cs, int flags, const CompletionFunc& completion);
|
||||
bool StartCutscene(const char* s, int flags, const CompletionFunc& completion);
|
||||
void PlayLogos(gameaction_t complete_ga, gameaction_t def_ga, bool stopmusic);
|
||||
void ShowScoreboard(int numplayers, const CompletionFunc& completion_);
|
||||
void ShowIntermission(MapRecord* fromMap, MapRecord* toMap, SummaryInfo* info, CompletionFunc completion_);
|
||||
|
|
|
@ -131,60 +131,5 @@ void InitFonts_d()
|
|||
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// wrappers around DrawText to allow easier reuse of the old code.
|
||||
// The vertical displacements are to have the same positioning as with the original code.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void BigText(double x, double y, const char* text, int align = -1, double alpha = 1.)
|
||||
{
|
||||
if (align != -1)
|
||||
x -= BigFont->StringWidth(text) * (align == 0 ? 0.5 : 1);
|
||||
DrawText(twod, BigFont, CR_UNTRANSLATED, x, y - 12, text, DTA_FullscreenScale, FSMode_Fit320x200, DTA_Alpha, alpha, TAG_DONE);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void dobonus_d(int bonusonly, const CompletionFunc& completion)
|
||||
{
|
||||
#if 0
|
||||
TArray<DScreenJob*> jobs;
|
||||
|
||||
FX_StopAllSounds();
|
||||
|
||||
if (bonusonly < 0 && numplayers < 2 && ud.from_bonus == 0)
|
||||
{
|
||||
bonussequence_d(volfromlevelnum(currentLevel->levelNumber), jobs);
|
||||
}
|
||||
else
|
||||
Mus_Stop();
|
||||
|
||||
if (playerswhenstarted > 1 && ud.coop != 1)
|
||||
{
|
||||
jobs.Push(Create<DDukeMultiplayerBonusScreen>(playerswhenstarted));
|
||||
}
|
||||
else if (bonusonly <= 0 && ud.multimode <= 1)
|
||||
{
|
||||
jobs.Push(Create<DDukeLevelSummaryScreen>());
|
||||
}
|
||||
if (jobs.Size())
|
||||
{
|
||||
RunScreenJob(jobs, completion);
|
||||
}
|
||||
else if (completion) completion(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
void PrintPaused_d()
|
||||
{
|
||||
BigText(160, 100, GStrings("Game Paused"));
|
||||
}
|
||||
|
||||
|
||||
END_DUKE_NS
|
||||
|
|
|
@ -123,119 +123,5 @@ void InitFonts_r()
|
|||
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// wrappers around DrawText to allow easier reuse of the old code.
|
||||
// The vertical displacements are to have the same positioning as with the original code.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void BigText(double x, double y, const char* text, int align, double alpha = 1.)
|
||||
{
|
||||
//x *= 2.2; y *= 2.64;
|
||||
if (align != -1)
|
||||
x -= BigFont->StringWidth(text) * (align == 0 ? 0.2 : 0.4);
|
||||
DrawText(twod, BigFont, CR_UNTRANSLATED, x, y - 12, text, DTA_FullscreenScale, FSMode_Fit320x200, DTA_ScaleX, 0.4, DTA_ScaleY, 0.4, DTA_Alpha, alpha, TAG_DONE);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static void bonussequence_r(int num, TArray<DScreenJob*>& jobs)
|
||||
{
|
||||
static const AnimSound turdmov[] =
|
||||
{
|
||||
{ 1, 82 + 1 },
|
||||
{ -1, -1 }
|
||||
};
|
||||
|
||||
static const AnimSound rr_outro[] =
|
||||
{
|
||||
{ 1, 35 + 1 },
|
||||
{ -1, -1 }
|
||||
};
|
||||
|
||||
static const int framespeed[] = { 9, 9, 9 }; // same for all 3 anims
|
||||
|
||||
Mus_Stop();
|
||||
FX_StopAllSounds();
|
||||
|
||||
switch (num)
|
||||
{
|
||||
case 0:
|
||||
jobs.Push(PlayVideo("turdmov.anm", turdmov, framespeed));
|
||||
jobs.Push(Create<DImageScreen>(TENSCREEN));
|
||||
break;
|
||||
|
||||
case 1:
|
||||
jobs.Push(PlayVideo("rr_outro.anm", rr_outro, framespeed));
|
||||
jobs.Push(Create<DImageScreen>(TENSCREEN));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void dobonus_r(int bonusonly, const CompletionFunc& completion)
|
||||
{
|
||||
#if 0
|
||||
TArray<DScreenJob*> jobs;
|
||||
|
||||
FX_StopAllSounds();
|
||||
Mus_Stop();
|
||||
|
||||
if (bonusonly < 0 && !isRRRA() && numplayers < 2 && ud.from_bonus == 0)
|
||||
{
|
||||
int vol = volfromlevelnum(currentLevel->levelNumber);
|
||||
bonussequence_r(vol, jobs);
|
||||
}
|
||||
|
||||
if (playerswhenstarted > 1 && ud.coop != 1)
|
||||
{
|
||||
jobs.Push(Create<DRRMultiplayerBonusScreen>(playerswhenstarted));
|
||||
}
|
||||
else if (bonusonly <= 0 && ud.multimode <= 1)
|
||||
{
|
||||
if (isRRRA() && !(currentLevel->flags & MI_USERMAP) && currentLevel->levelNumber < 106) // fixme: The logic here is awful. Shift more control to the map records.
|
||||
{
|
||||
jobs.Push(Create<DRRLevelSummaryScreen>(true));
|
||||
int levnum = clamp((currentLevel->levelNumber / 100) * 7 + (currentLevel->levelNumber % 100), 0, 13);
|
||||
char fn[20];
|
||||
mysnprintf(fn, 20, "lvl%d.anm", levnum + 1);
|
||||
static const int framespeed[] = { 20, 20, 7200 }; // wait for one minute on the final frame so that the video doesn't stop before the user notices.
|
||||
jobs.Push(PlayVideo(fn, nullptr, framespeed));
|
||||
if (bonusonly < 0 && currentLevel->levelNumber > 100)
|
||||
{
|
||||
jobs.Push(Create<DRRRAEndOfGame>());
|
||||
}
|
||||
}
|
||||
else jobs.Push(Create<DRRLevelSummaryScreen>(false));
|
||||
}
|
||||
if (jobs.Size())
|
||||
RunScreenJob(jobs, completion);
|
||||
else if (completion) completion(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void PrintPaused_r()
|
||||
{
|
||||
BigText(160, 100, GStrings("Game Paused"), 0);
|
||||
}
|
||||
|
||||
|
||||
END_DUKE_NS
|
||||
|
|
|
@ -107,8 +107,6 @@ void animatesprites_r(int x, int y, int a, int smoothratio);
|
|||
|
||||
void InitFonts_d();
|
||||
void InitFonts_r();
|
||||
void PrintPaused_d();
|
||||
void PrintPaused_r();
|
||||
|
||||
|
||||
Dispatcher fi;
|
||||
|
@ -119,7 +117,6 @@ void SetDispatcher()
|
|||
{
|
||||
fi = {
|
||||
InitFonts_d,
|
||||
PrintPaused_d,
|
||||
|
||||
think_d,
|
||||
initactorflags_d,
|
||||
|
@ -165,7 +162,6 @@ void SetDispatcher()
|
|||
{
|
||||
fi = {
|
||||
InitFonts_r,
|
||||
PrintPaused_r,
|
||||
|
||||
think_r,
|
||||
initactorflags_r,
|
||||
|
|
|
@ -72,7 +72,6 @@ struct Dispatcher
|
|||
{
|
||||
// global stuff
|
||||
void (*InitFonts)();
|
||||
void (*PrintPaused)();
|
||||
|
||||
// sectors_?.cpp
|
||||
void (*think)();
|
||||
|
|
|
@ -208,8 +208,6 @@ void OffBoat(player_struct *pl);
|
|||
|
||||
void cameratext(DDukeActor* i);
|
||||
void dobonus(int bonusonly, const CompletionFunc& completion);
|
||||
void dobonus_d(int bonusonly, const CompletionFunc& completion);
|
||||
void dobonus_r(int bonusonly, const CompletionFunc& completion);
|
||||
|
||||
void drawoverlays(double smoothratio);
|
||||
void drawbackground(void);
|
||||
|
|
|
@ -92,13 +92,12 @@ static void endthegame(bool)
|
|||
|
||||
void GameInterface::ExitFromMenu()
|
||||
{
|
||||
#if 0
|
||||
// do we really need this scoreboard stuff here?
|
||||
auto runbonus = [=](auto completion)
|
||||
{
|
||||
// MP scoreboard
|
||||
if (playerswhenstarted > 1 && !ud.coop)
|
||||
{
|
||||
dobonus(1, completion);
|
||||
}
|
||||
if (playerswhenstarted > 1 && !ud.coop) ShowScoreboard(playerswhenstarted);
|
||||
else completion(false);
|
||||
};
|
||||
|
||||
|
@ -111,6 +110,11 @@ void GameInterface::ExitFromMenu()
|
|||
};
|
||||
|
||||
runbonus([=](bool aborted) { runtwoscreens(endthegame); });
|
||||
#else
|
||||
if (isShareware() && !isRR())
|
||||
StartCutscene("DukeCutscenes.BuildSharewareExit", 0, endthegame);
|
||||
else endthegame(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -208,7 +212,7 @@ void V_AddBlend (float r, float g, float b, float a, float v_blend[4])
|
|||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 'rest' in this case means everything not part of the 3D scene and its weapon sprite.
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
@ -297,7 +301,13 @@ void drawoverlays(double smoothratio)
|
|||
}
|
||||
|
||||
if (paused == 2)
|
||||
fi.PrintPaused();
|
||||
{
|
||||
double x = 160, y = 100;
|
||||
double scale = isRR() ? 0.4 : 1.;
|
||||
const char* text = GStrings("Game Paused");
|
||||
x -= BigFont->StringWidth(text) * 0.5 * scale;
|
||||
DrawText(twod, BigFont, CR_UNTRANSLATED, x, y - 12, text, DTA_FullscreenScale, FSMode_Fit320x200, DTA_ScaleX, scale, DTA_ScaleY, scale, TAG_DONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -342,18 +352,6 @@ void cameratext(DDukeActor *cam)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void dobonus(int bonusonly, const CompletionFunc& completion)
|
||||
{
|
||||
if (isRR()) dobonus_r(bonusonly, completion);
|
||||
else dobonus_d(bonusonly, completion);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
int startrts(int lumpNum, int localPlayer)
|
||||
{
|
||||
if (SoundEnabled() &&
|
||||
|
|
|
@ -244,7 +244,7 @@ static void DoUserDef(bool bSet, int lVar1, int lLabelID, int lVar2, DDukeActor*
|
|||
break;
|
||||
|
||||
case USERDEFS_VOLUME_NUMBER:
|
||||
if (!bSet) SetGameVarID(lVar2, volfromlevelnum(currentLevel->levelNumber), sActor, sPlayer);
|
||||
if (!bSet) SetGameVarID(lVar2, currentLevel->cluster-1, sActor, sPlayer);
|
||||
break;
|
||||
|
||||
case USERDEFS_MARKER:
|
||||
|
@ -3572,7 +3572,7 @@ int ParseState::parse(void)
|
|||
{
|
||||
insptr++;
|
||||
int music_select = *insptr++;
|
||||
auto level = FindMapByLevelNum(levelnum(currentLevel->levelNumber, music_select));
|
||||
auto level = FindMapByLevelNum(levelnum(currentLevel->cluster, music_select));
|
||||
if (level) S_PlayLevelMusic(level);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1040,29 +1040,32 @@ bool setnextmap(bool checksecretexit)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void exitlevel(MapRecord *nextlevel)
|
||||
void exitlevel(MapRecord* nextlevel)
|
||||
{
|
||||
bool endofgame = nextlevel == nullptr;
|
||||
STAT_Update(endofgame);
|
||||
StopCommentary();
|
||||
|
||||
dobonus(endofgame? -1 : 0, [=](bool)
|
||||
{
|
||||
SummaryInfo info{};
|
||||
|
||||
// Clear potentially loaded per-map ART only after the bonus screens.
|
||||
artClearMapArt();
|
||||
gameaction = ga_level;
|
||||
ud.eog = false;
|
||||
if (endofgame)
|
||||
info.kills = ps[0].actors_killed;
|
||||
info.maxkills = ps[0].max_actors_killed;
|
||||
info.secrets = ps[0].secret_rooms;
|
||||
info.maxsecrets = ps[0].max_secret_rooms;
|
||||
info.time = ps[0].player_par;
|
||||
info.endofgame = endofgame;
|
||||
Mus_Stop();
|
||||
|
||||
if (playerswhenstarted > 1 && ud.coop != 1)
|
||||
{
|
||||
// MP scoreboard
|
||||
ShowScoreboard(playerswhenstarted, [=](bool)
|
||||
{
|
||||
if (ud.multimode < 2)
|
||||
{
|
||||
if (isShareware())
|
||||
StartCutscene("DukeCutscenes.BuildSharewareOrder", 0, [](bool) { gameaction = ga_startup; });
|
||||
else gameaction = ga_startup;
|
||||
return;
|
||||
}
|
||||
else
|
||||
// Clear potentially loaded per-map ART only after the bonus screens.
|
||||
artClearMapArt();
|
||||
gameaction = ga_level;
|
||||
ud.eog = false;
|
||||
if (endofgame)
|
||||
{
|
||||
auto nextlevel = FindMapByLevelNum(0);
|
||||
if (!nextlevel)
|
||||
|
@ -1072,11 +1075,22 @@ void exitlevel(MapRecord *nextlevel)
|
|||
}
|
||||
else gameaction = ga_nextlevel;
|
||||
}
|
||||
}
|
||||
else
|
||||
gameaction = ga_nextlevel;
|
||||
else
|
||||
gameaction = ga_nextlevel;
|
||||
|
||||
});
|
||||
}
|
||||
else if (ud.multimode <= 1)
|
||||
{
|
||||
// SP cutscene + summary
|
||||
ShowIntermission(currentLevel, nextlevel, &info, [=](bool)
|
||||
{
|
||||
// Clear potentially loaded per-map ART only after the bonus screens.
|
||||
artClearMapArt();
|
||||
ud.eog = false;
|
||||
gameaction = endofgame? ga_startup : ga_nextlevel;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -49,5 +49,11 @@ definecutscene episode 5
|
|||
}
|
||||
}
|
||||
|
||||
definecutscene sharewareend
|
||||
{
|
||||
function DukeCutscenes.BuildSharewareEnd
|
||||
}
|
||||
|
||||
definecutscene summary DukeCutscenes.BuildSPSummary
|
||||
definecutscene mpsummary DukeCutscenes.BuildMPSummary
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Cutscene definitions for Duke
|
||||
// Cutscene definitions for RR
|
||||
|
||||
definecutscene intro
|
||||
{
|
||||
|
@ -24,3 +24,4 @@ definecutscene episode 2
|
|||
|
||||
definecutscene summary RRCutscenes.BuildSPSummary
|
||||
definecutscene mpsummary DukeCutscenes.BuildMPSummary // identical with Duke's
|
||||
definecutscene mapintro RRCutscenes.BuildMapIntro // this plays the 'travel' animation.
|
||||
|
|
|
@ -64,6 +64,7 @@ struct Duke native
|
|||
fsmode = FSMode_Fit640x400;
|
||||
}
|
||||
if (align != -1) x -= SmallFont.StringWidth(t) * (align == 0 ? 0.5 : 1);
|
||||
if (shade) Console.Printf("%s: shade = %d", t, shade);
|
||||
Screen.DrawText(SmallFont, Font.CR_UNDEFINED, x, y + 2, t, DTA_FullscreenScale, fsmode, DTA_TranslationIndex, Translation.MakeID(Translation_Remap, trans), DTA_Color, Raze.shadeToLight(shade));
|
||||
}
|
||||
|
||||
|
|
|
@ -216,8 +216,7 @@ class DukeCutscenes // Note: must be class, not struct, otherwise we cannot easi
|
|||
|
||||
static void BuildSPSummary(ScreenJobRunner runner, MapRecord map, SummaryInfo stats)
|
||||
{
|
||||
let screen = SummaryScreenBase(new("DukeLevelSummaryScreen").Init());
|
||||
if (screen) screen.SetParameters(map, stats);
|
||||
let screen = new("DukeLevelSummaryScreen").Init(map, stats);
|
||||
runner.Append(screen);
|
||||
}
|
||||
|
||||
|
@ -235,11 +234,11 @@ class DukeCutscenes // Note: must be class, not struct, otherwise we cannot easi
|
|||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static void BuildSharewareOrder(ScreenJobRunner runner)
|
||||
static void BuildSharewareEnd(ScreenJobRunner runner)
|
||||
{
|
||||
runner.Append(ImageScreen.CreateNamed("ORDERING"));
|
||||
runner.Append(ImageScreen.CreateNamed("ORDERING1"));
|
||||
|
@ -339,10 +338,7 @@ class RRCutscenes
|
|||
|
||||
static void BuildSPSummary(ScreenJobRunner runner, MapRecord map, SummaryInfo stats)
|
||||
{
|
||||
let sumscreen = new("RRLevelSummaryScreen").Init(!Raze.isRRRA() || stats.endOfGame);
|
||||
let sumscreens = SummaryScreenBase(sumscreen);
|
||||
if (sumscreens) sumscreens.SetParameters(map, stats);
|
||||
runner.Append(sumscreen);
|
||||
runner.Append(new("RRLevelSummaryScreen").Init(map, stats, !Raze.isRRRA() || stats.endOfGame));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -57,7 +57,6 @@ class DRealmsScreen : SkippableScreenJob
|
|||
let tex = TexMan.CheckForTexture("DREALMS");
|
||||
int translation = TexMan.UseGamePalette(tex)? Translation.MakeID(Translation_BasePalette, Duke.DREALMSPAL) : 0;
|
||||
|
||||
screen.ClearScreen();
|
||||
screen.DrawTexture(tex, true, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_TranslationIndex, translation, DTA_LegacyRenderStyle, STYLE_Normal);
|
||||
}
|
||||
}
|
||||
|
@ -119,8 +118,6 @@ class DukeTitleScreen : SkippableScreenJob
|
|||
int clock = (ticks + smoothratio) * 120 / GameTicRate;
|
||||
int etrans = Translation.MakeID(Translation_BasePalette, Duke.TITLEPAL);
|
||||
|
||||
screen.ClearScreen();
|
||||
|
||||
// Only translate if the image depends on the global palette.
|
||||
let tex = TexMan.CheckForTexture("BETASCREEN");
|
||||
int trans = TexMan.UseGamePalette(tex)? etrans : 0;
|
||||
|
@ -256,7 +253,6 @@ class Episode1End1 : SkippableScreenJob
|
|||
{
|
||||
int etrans = Translation.MakeID(Translation_BasePalette, Duke.ENDINGPAL);
|
||||
|
||||
screen.ClearScreen();
|
||||
let tex = TexMan.CheckForTexture("VICTORY1");
|
||||
int trans = TexMan.UseGamePalette(tex)? etrans : 0;
|
||||
screen.DrawTexture(tex, false, 0, 50, DTA_FullscreenScale, FSMode_Fit320x200, DTA_TranslationIndex, trans, DTA_LegacyRenderStyle, STYLE_Normal, DTA_TopLeft, true);
|
||||
|
@ -411,7 +407,6 @@ class Episode4Text : SkippableScreenJob
|
|||
|
||||
override void Draw(double sm)
|
||||
{
|
||||
Screen.ClearScreen();
|
||||
Duke.BigText(160, 60, "$Thanks to all our", 0);
|
||||
Duke.BigText(160, 60 + 16, "$fans for giving", 0);
|
||||
Duke.BigText(160, 60 + 16 + 16, "$us big heads.", 0);
|
||||
|
@ -474,7 +469,6 @@ class DukeMultiplayerBonusScreen : SkippableScreenJob
|
|||
|
||||
String tempbuf;
|
||||
int currentclock = int((ticks + smoothratio) * 120 / GameTicRate);
|
||||
Screen.ClearScreen();
|
||||
Screen.DrawTexture(TexMan.CheckForTexture("MENUSCREEN"), false, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_Color, 0xff808080, DTA_LegacyRenderStyle, STYLE_Normal);
|
||||
Screen.DrawTexture(TexMan.CheckForTexture("INGAMEDUKETHREEDEE"), true, 160, 34, DTA_FullscreenScale, FSMode_Fit320x200, DTA_CenterOffsetRel, true, DTA_ScaleX, titlescale, DTA_ScaleY, titlescale);
|
||||
if (Raze.isPlutoPak()) Screen.DrawTexture(TexMan.CheckForTexture("MENUPLUTOPAKSPRITE"), true, 260, 36, DTA_FullscreenScale, FSMode_Fit320x200, DTA_CenterOffsetRel, true);
|
||||
|
@ -581,11 +575,12 @@ class DukeLevelSummaryScreen : SummaryScreenBase
|
|||
|
||||
}
|
||||
|
||||
ScreenJob Init()
|
||||
ScreenJob Init(MapRecord m, SummaryInfo s)
|
||||
{
|
||||
Super.Init(fadein | fadeout);
|
||||
int vol = level.volumeNum();
|
||||
String basetex = vol == 1? "BONUSSCREEN2" : "BONUSSCREEN";
|
||||
SetParameters(m, s);
|
||||
int vol = level.cluster;
|
||||
String basetex = vol == 2? "BONUSSCREEN2" : "BONUSSCREEN";
|
||||
texBg = TexMan.CheckForTexture(basetex);
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
|
@ -737,10 +732,9 @@ class DukeLevelSummaryScreen : SummaryScreenBase
|
|||
|
||||
override void Draw(double sr)
|
||||
{
|
||||
Screen.ClearScreen();
|
||||
Screen.DrawTexture(texBg, true, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_LegacyRenderStyle, STYLE_Normal);
|
||||
|
||||
Duke.GameText(160, 190, "$PRESSKEY", 8 - int(sin(ticks * 12 / GameTicRate) * 8), 0);
|
||||
Duke.GameText(160, 190, "$PRESSKEY", 8 - (sin(ticks * 4) * 8), 0);
|
||||
|
||||
if (displaystate & printTimeText)
|
||||
{
|
||||
|
@ -785,15 +779,15 @@ class DukeLevelSummaryScreen : SummaryScreenBase
|
|||
}
|
||||
}
|
||||
|
||||
if (lastmapname) Duke.BigText(160, 20 - 6, lastmapname);
|
||||
Duke.BigText(160, 36 - 6, "$Completed");
|
||||
if (lastmapname) Duke.BigText(160, 20 - 6, lastmapname, 0);
|
||||
Duke.BigText(160, 36 - 6, "$Completed", 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// TBD: fold this into DukeLevelSummaryScreen?
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
@ -819,9 +813,10 @@ class RRLevelSummaryScreen : SummaryScreenBase
|
|||
|
||||
}
|
||||
|
||||
ScreenJob Init(bool dofadeout = true)
|
||||
ScreenJob Init(MapRecord m, SummaryInfo s, bool dofadeout = true)
|
||||
{
|
||||
Super.Init(dofadeout? (fadein | fadeout) : fadein);
|
||||
SetParameters(m, s);
|
||||
String s;
|
||||
if (level.flags & MapRecord.USERMAP)
|
||||
s = "BONUSPIC01";
|
||||
|
@ -968,11 +963,10 @@ class RRLevelSummaryScreen : SummaryScreenBase
|
|||
|
||||
override void Draw(double sr)
|
||||
{
|
||||
Screen.ClearScreen();
|
||||
Screen.DrawTexture(texBg, true, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_LegacyRenderStyle, STYLE_Normal);
|
||||
|
||||
if (lastmapname) Duke.BigText(80, 16, lastmapname, -1);
|
||||
Duke.BigText(15, 192, "$PRESSKEY", -1);
|
||||
if (lastmapname) Duke.BigText(80, 16, lastmapname, 0, 0);
|
||||
Duke.BigText(15, 192, "$PRESSKEY", 0, 0);
|
||||
|
||||
if (displaystate & printTimeText)
|
||||
{
|
||||
|
@ -1044,7 +1038,6 @@ class DukeLoadScreen : ScreenJob
|
|||
|
||||
override void Draw(double sr)
|
||||
{
|
||||
Screen.ClearScreen();
|
||||
Screen.DrawTexture(TexMan.CheckForTexture("LOADSCREEN"), false, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_LegacyRenderStyle, STYLE_Normal);
|
||||
|
||||
if (!Raze.IsRR())
|
||||
|
|
|
@ -64,6 +64,7 @@ struct MapRecord native
|
|||
native readonly int cdSongId;
|
||||
native readonly int flags;
|
||||
native readonly int levelNumber;
|
||||
native readonly int cluster;
|
||||
|
||||
// The rest is only used by Blood
|
||||
native readonly int nextLevel;
|
||||
|
@ -81,10 +82,6 @@ struct MapRecord native
|
|||
if (name == "") return labelName;
|
||||
return name;
|
||||
}
|
||||
int volumeNum()
|
||||
{
|
||||
return levelNumber / 1000;
|
||||
}
|
||||
}
|
||||
|
||||
struct SummaryInfo native
|
||||
|
|
|
@ -121,7 +121,6 @@ class BlackScreen : ScreenJob
|
|||
override void Draw(double smooth)
|
||||
{
|
||||
cleared = true;
|
||||
Screen.ClearScreen();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,7 +179,6 @@ class ImageScreen : SkippableScreenJob
|
|||
|
||||
override void Draw(double smooth)
|
||||
{
|
||||
Screen.ClearScreen();
|
||||
if (texid.IsValid()) Screen.DrawTexture(texid, true, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_LegacyRenderStyle, STYLE_Normal, DTA_TranslationIndex, trans);
|
||||
cleared = true;
|
||||
}
|
||||
|
@ -392,7 +390,6 @@ class ScreenJobRunner : Object
|
|||
{
|
||||
if (jobs.Size() == 0)
|
||||
{
|
||||
screen.ClearScreen();
|
||||
return 1;
|
||||
}
|
||||
int x = index >= jobs.Size()? jobs.Size()-1 : index;
|
||||
|
@ -498,7 +495,6 @@ class ScreenJobRunner : Object
|
|||
if (actionState == State_Clear)
|
||||
{
|
||||
actionState = State_Run;
|
||||
Screen.ClearScreen();
|
||||
}
|
||||
else if (actionState == State_Run)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue