- most of the summary screen is working

This commit is contained in:
Christoph Oelckers 2021-04-28 00:51:28 +02:00
parent 0dc6980e5c
commit 6d743ce921
21 changed files with 266 additions and 276 deletions

View file

@ -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];

View file

@ -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);

View file

@ -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();

View file

@ -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;

View file

@ -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; });

View file

@ -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_);

View file

@ -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

View file

@ -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

View file

@ -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,

View file

@ -72,7 +72,6 @@ struct Dispatcher
{
// global stuff
void (*InitFonts)();
void (*PrintPaused)();
// sectors_?.cpp
void (*think)();

View file

@ -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);

View file

@ -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() &&

View file

@ -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;
}

View file

@ -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;
});
}
}

View file

@ -49,5 +49,11 @@ definecutscene episode 5
}
}
definecutscene sharewareend
{
function DukeCutscenes.BuildSharewareEnd
}
definecutscene summary DukeCutscenes.BuildSPSummary
definecutscene mpsummary DukeCutscenes.BuildMPSummary

View file

@ -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.

View file

@ -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));
}

View file

@ -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));
}
//---------------------------------------------------------------------------

View file

@ -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())

View file

@ -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

View file

@ -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)
{