New Credits

This commit is contained in:
Sal 2024-01-28 23:31:30 +00:00 committed by Oni
parent b323c6bdb7
commit 3958c15dfe
24 changed files with 1441 additions and 421 deletions

View file

@ -158,6 +158,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
k_tally.cpp
k_bans.cpp
k_endcam.cpp
k_credits.cpp
music.cpp
music_manager.cpp
)

View file

@ -1447,7 +1447,7 @@ static void CL_LoadReceivedSavegame(boolean reloading)
paused = false;
demo.playback = false;
demo.title = false;
demo.attract = DEMO_ATTRACT_OFF;
titlemapinaction = false;
tutorialchallenge = TUTORIALSKIP_NONE;
automapactive = false;
@ -2424,7 +2424,7 @@ static void Command_connect(void)
return;
}
if (Playing() || demo.title)
if (Playing() || demo.attract)
{
CONS_Printf(M_GetText("You cannot connect while in a game. End this game first.\n"));
return;
@ -6597,15 +6597,22 @@ void NetUpdate(void)
nowtime = I_GetTime();
realtics = nowtime - gametime;
if (realtics <= 0) // nothing new to update
return;
if (realtics > 5)
if (!demo.playback && g_fast_forward > 0)
{
if (server)
realtics = 1;
else
realtics = 5;
realtics = 1;
}
else
{
if (realtics <= 0) // nothing new to update
return;
if (realtics > 5)
{
if (server)
realtics = 1;
else
realtics = 5;
}
}
#ifdef DEDICATEDIDLETIME

View file

@ -89,6 +89,7 @@
#include "music.h"
#include "k_dialogue.h"
#include "k_bans.h"
#include "k_credits.h"
#ifdef HWRENDER
#include "hardware/hw_main.h" // 3D View Rendering
@ -144,9 +145,11 @@ static char *startuppwads[MAX_WADFILES];
boolean devparm = false; // started game with -devparm
boolean singletics = false; // timedemo
boolean g_singletics = false; // timedemo
boolean lastdraw = false;
tic_t g_fast_forward = 0;
postimg_t postimgtype[MAXSPLITSCREENPLAYERS];
INT32 postimgparam[MAXSPLITSCREENPLAYERS];
@ -630,6 +633,15 @@ static bool D_Display(void)
V_DrawCustomFadeScreen(((levelfadecol == 0) ? "FADEMAP1" : "FADEMAP0"), 31-(lt_fade*2));
}
if (demo.attract == DEMO_ATTRACT_CREDITS)
{
INT32 val = F_CreditsDemoExitFade();
if (val >= 0)
{
V_DrawCustomFadeScreen("FADEMAP0", val);
}
}
VID_DisplaySoftwareScreen();
}
@ -950,7 +962,7 @@ void D_SRB2Loop(void)
rendertimefrac_unpaused = FRACUNIT;
}
if ((interp || doDisplay) && !frameskip)
if ((interp || doDisplay) && !frameskip && g_fast_forward == 0)
{
if (!renderisnewtic)
P_ResetInterpHudRandSeed(false);
@ -1077,7 +1089,7 @@ void D_ClearState(void)
memset(displayplayers, 0, sizeof(displayplayers));
memset(g_localplayers, 0, sizeof g_localplayers);
consoleplayer = 0;
demo.title = false;
demo.attract = DEMO_ATTRACT_OFF;
G_SetGametype(GT_RACE); // SRB2kart
paused = false;
@ -1610,6 +1622,9 @@ void D_SRB2Main(void)
#endif //ifndef DEVELOP
mainwads++; // shaders.pk3
// Load credits_def lump
F_LoadCreditsDefinitions();
// Do it before P_InitMapData because PNG patch
// conversion sometimes needs the palette
V_ReloadPalette();

View file

@ -3539,10 +3539,10 @@ void readmaincfg(MYFILE *f, boolean mainfile)
}
else if (fastcmp(word, "CREDITSCUTSCENE"))
{
creditscutscene = (UINT8)get_number(word2);
g_credits_cutscene = (UINT8)get_number(word2);
// range check, you morons.
if (creditscutscene > 128)
creditscutscene = 128;
if (g_credits_cutscene > 128)
g_credits_cutscene = 128;
}
else if (fastcmp(word, "USESEAL"))
{

View file

@ -154,7 +154,7 @@ static void DRPC_HandleJoin(const char *secret)
char *ip = DRPC_XORIPString(secret);
CONS_Printf("Connecting to %s via Discord\n", ip);
M_ClearMenus(true); //Don't have menus open during connection screen
if (demo.playback && demo.title)
if (demo.playback && demo.attract)
G_CheckDemoStatus(); //Stop the title demo, so that the connect command doesn't error if a demo is playing
COM_BufAddText(va("connect \"%s\"\n", ip));
free(ip);
@ -482,7 +482,7 @@ void DRPC_UpdatePresence(void)
// Offline info
if (Playing())
discordPresence.state = "Offline";
else if (demo.playback && !demo.title)
else if (demo.playback && !demo.attract)
discordPresence.state = "Watching Replay";
else
discordPresence.state = "Menu";
@ -507,7 +507,7 @@ void DRPC_UpdatePresence(void)
}
if ((gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) // Map info
&& !(demo.playback && demo.title))
&& !(demo.playback && demo.attract))
{
#ifdef USEMAPIMG
if ((gamemap >= 1 && gamemap <= 60) // supported race maps

View file

@ -786,7 +786,7 @@ extern INT32 wantedreduce;
extern INT32 wantedfrequency;
extern UINT8 introtoplay;
extern UINT8 creditscutscene;
extern UINT8 g_credits_cutscene;
extern UINT8 useSeal;
extern UINT8 use1upSound;
@ -914,7 +914,10 @@ extern INT16 wipetypepre;
extern INT16 wipetypepost;
// debug flag to cancel adaptiveness
extern boolean singletics;
extern boolean g_singletics;
extern tic_t g_fast_forward;
#define singletics (g_singletics == true || g_fast_forward > 0)
// =============
// Netgame stuff

View file

@ -48,6 +48,7 @@
#include "k_menu.h"
#include "k_grandprix.h"
#include "music.h"
#include "k_credits.h"
// Stage of animation:
// 0 = text, 1 = art screen
@ -59,7 +60,6 @@ boolean titlemapinaction = false;
static INT32 timetonext; // Delay between screen changes
static tic_t animtimer; // Used for some animation timings
static tic_t credbgtimer; // Credits background
static tic_t stoptimer;
@ -579,346 +579,6 @@ boolean F_IntroResponder(event_t *event)
return true;
}
// =========
// CREDITS
// =========
static const char *credits[] = {
"\1Dr. Robotnik's Ring Racers",
"\1Credits",
"",
"\1Game Design",
"Sally \"TehRealSalt\" Cochenour",
"Jeffery \"Chromatian\" Scott",
"\"VelocitOni\"",
"",
"\1Lead Programming",
"Sally \"TehRealSalt\" Cochenour",
"Vivian \"toaster\" Grannell",
"Sean \"Sryder\" Ryder",
"Ehab \"wolfs\" Saeed",
"\"ZarroTsu\"",
"",
"\1Support Programming",
"Colette \"fickleheart\" Bordelon",
"James R.",
"\"Lat\'\"",
"\"Monster Iestyn\"",
"\"Shuffle\"",
"\"SteelT\"",
"",
"\1Lead Artists",
"Desmond \"Blade\" DesJardins",
"\"VelocitOni\"",
"",
"\1Support Artists",
"Sally \"TehRealSalt\" Cochenour",
"Sherman \"CoatRack\" DesJardins",
"\"DrTapeworm\"",
"Jesse \"Jeck Jims\" Emerick",
"Wesley \"Charyb\" Gillebaard",
"Vivian \"toaster\" Grannell",
"James \"SeventhSentinel\" Hall",
"\"Lat\'\"",
"\"Tyrannosaur Chao\"",
"\"ZarroTsu\"",
"",
"\1External Artists",
"\"1-Up Mason\"",
"\"Chengi\"",
"\"Chrispy\"",
"\"DirkTheHusky\"",
"\"LJSTAR\"",
"\"MotorRoach\"",
"\"Nev3r\"",
"\"rairai104n\"",
"\"Ritz\"",
"\"Rob\"",
"\"SmithyGNC\"",
"\"Snu\"",
"\"Spherallic\"",
"\"TelosTurntable\"",
"\"VAdaPEGA\"",
"\"Virt\"",
"\"Voltrix\"",
"",
"\1Sound Design",
"James \"SeventhSentinel\" Hall",
"Sonic Team",
"\"VAdaPEGA\"",
"\"VelocitOni\"",
"",
"\1Music",
"\"DrTapeworm\"",
"Wesley \"Charyb\" Gillebaard",
"James \"SeventhSentinel\" Hall",
"",
"\1Lead Level Design",
"\"Blitz-T\"",
"Sally \"TehRealSalt\" Cochenour",
"Desmond \"Blade\" DesJardins",
"Jeffery \"Chromatian\" Scott",
"\"Tyrannosaur Chao\"",
"",
"\1Support Level Design",
"\"Chaos Zero 64\"",
"\"D00D64\"",
"\"DrTapeworm\"",
"Paul \"Boinciel\" Clempson",
"Sherman \"CoatRack\" DesJardins",
"Colette \"fickleheart\" Bordelon",
"Vivian \"toaster\" Grannell",
"\"Gunla\"",
"James \"SeventhSentinel\" Hall",
"\"Lat\'\"",
"\"MK\"",
"\"Ninferno\"",
"Sean \"Sryder\" Ryder",
"\"Ryuspark\"",
"\"Simsmagic\"",
"\"SP47\"",
"\"TG\"",
"\"Victor Rush Turbo\"",
"\"ZarroTsu\"",
"",
"\1Testing",
"\"CyberIF\"",
"\"Dani\"",
"Karol \"Fooruman\" D""\x1E""browski", // Dąbrowski, <Sryder> accents in srb2 :ytho:
"\"VirtAnderson\"",
"",
"\1Special Thanks",
"SEGA",
"Sonic Team",
"SRB2 & Sonic Team Jr. (www.srb2.org)",
"\"Chaos Zero 64\"",
"",
"\1Produced By",
"Kart Krew",
"",
"\1In Memory of",
"\"Tyler52\"",
"",
"",
"\1Thank you ",
"\1for playing! ",
NULL
};
#define CREDITS_LEFT 8
#define CREDITS_RIGHT ((BASEVIDWIDTH) - 8)
static struct {
UINT32 x, y;
const char *patch;
UINT8 colorize;
} credits_pics[] = {
// We don't have time to be fancy, let's just colorize some item sprites :V
{224, 80+(200* 1), "K_ITJAWZ", SKINCOLOR_CREAMSICLE},
{224, 80+(200* 2), "K_ITSPB", SKINCOLOR_GARDEN},
{224, 80+(200* 3), "K_ITBANA", SKINCOLOR_LILAC},
{224, 80+(200* 4), "K_ITHYUD", SKINCOLOR_DREAM},
{224, 80+(200* 5), "K_ITBHOG", SKINCOLOR_TANGERINE},
{224, 80+(200* 6), "K_ITSHRK", SKINCOLOR_JAWZ},
{224, 80+(200* 7), "K_ITSHOE", SKINCOLOR_MINT},
{224, 80+(200* 8), "K_ITGROW", SKINCOLOR_RUBY},
{224, 80+(200* 9), "K_ITPOGO", SKINCOLOR_SAPPHIRE},
{224, 80+(200*10), "K_ITRSHE", SKINCOLOR_YELLOW},
{224, 80+(200*11), "K_ITORB4", SKINCOLOR_DUSK},
{224, 80+(200*12), "K_ITEGGM", SKINCOLOR_GREEN},
{224, 80+(200*13), "K_ITMINE", SKINCOLOR_BRONZE},
{224, 80+(200*14), "K_ITTHNS", SKINCOLOR_RASPBERRY},
{224, 80+(200*15), "K_ITINV1", SKINCOLOR_GREY},
// This Tyler52 gag is troublesome
// Alignment should be ((spaces+1 * 100) + (headers+1 * 38) + (lines * 15))
// Current max image spacing: (200*17)
{112, (15*100)+(17*38)+(88*15), "TYLER52", SKINCOLOR_NONE}
};
#undef CREDITS_LEFT
#undef CREDITS_RIGHT
static UINT32 credits_height = 0;
static const UINT8 credits_numpics = sizeof(credits_pics)/sizeof(credits_pics[0]) - 1;
void F_StartCredits(void)
{
G_SetGamestate(GS_CREDITS);
// Just in case they're open ... somehow
M_ClearMenus(true);
if (creditscutscene)
{
F_StartCustomCutscene(creditscutscene - 1, false, false);
return;
}
gameaction = ga_nothing;
paused = false;
CON_ToggleOff();
Music_StopAll();
S_StopSounds();
Music_Play("credits");
finalecount = 0;
animtimer = 0;
timetonext = 2*TICRATE;
keypressed = false;
}
void F_CreditDrawer(void)
{
UINT16 i;
fixed_t y = (80<<FRACBITS) - (animtimer<<FRACBITS>>1);
//V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
// Draw background
V_DrawSciencePatch(0, 0 - FixedMul(32<<FRACBITS, FixedDiv(credbgtimer%TICRATE, TICRATE)), V_SNAPTOTOP, W_CachePatchName("CREDTILE", PU_CACHE), FRACUNIT);
V_DrawSciencePatch(0, 0 - FixedMul(40<<FRACBITS, FixedDiv(credbgtimer%(TICRATE/2), (TICRATE/2))), V_SNAPTOTOP, W_CachePatchName("CREDZIGZ", PU_CACHE), FRACUNIT);
V_DrawSciencePatch(320<<FRACBITS, 0 - FixedMul(40<<FRACBITS, FixedDiv(credbgtimer%(TICRATE/2), (TICRATE/2))), V_SNAPTOTOP|V_FLIP, W_CachePatchName("CREDZIGZ", PU_CACHE), FRACUNIT);
// Draw pictures
for (i = 0; i < credits_numpics; i++)
{
UINT8 *colormap = NULL;
fixed_t sc = FRACUNIT>>1;
if (credits_pics[i].colorize != SKINCOLOR_NONE)
{
colormap = R_GetTranslationColormap(TC_RAINBOW, credits_pics[i].colorize, GTC_MENUCACHE);
sc = FRACUNIT; // quick hack so I don't have to add another field to credits_pics
}
V_DrawFixedPatch(credits_pics[i].x<<FRACBITS, (credits_pics[i].y<<FRACBITS) - 4*(animtimer<<FRACBITS)/5, sc, 0, W_CachePatchName(credits_pics[i].patch, PU_CACHE), colormap);
}
// Draw credits text on top
for (i = 0; credits[i]; i++)
{
switch(credits[i][0])
{
case 0:
y += 80<<FRACBITS;
break;
case 1:
if (y>>FRACBITS > -20)
V_DrawCreditString((160 - (V_CreditStringWidth(&credits[i][1])>>1))<<FRACBITS, y, 0, &credits[i][1]);
y += 30<<FRACBITS;
break;
case 2:
if (y>>FRACBITS > -10)
V_DrawStringAtFixed((BASEVIDWIDTH-V_StringWidth(&credits[i][1], V_YELLOWMAP))<<FRACBITS>>1, y, V_YELLOWMAP, &credits[i][1]);
y += 12<<FRACBITS;
break;
default:
if (y>>FRACBITS > -10)
V_DrawStringAtFixed(32<<FRACBITS, y, 0, credits[i]);
y += 12<<FRACBITS;
break;
}
if (((y>>FRACBITS) * vid.dupy) > vid.height)
break;
}
if (finalecount)
{
Y_DrawIntermissionButton(-1, (timetonext ? 5*TICRATE : TICRATE) - finalecount);
}
else
{
Y_DrawIntermissionButton(timetonext, 0);
}
}
void F_CreditTicker(void)
{
// "Simulate" the drawing of the credits so that dedicated mode doesn't get stuck
UINT16 i;
fixed_t y = (80<<FRACBITS) - (animtimer<<FRACBITS>>1);
// Calculate credits height to display art properly
if (credits_height == 0)
{
for (i = 0; credits[i]; i++)
{
switch(credits[i][0])
{
case 0: credits_height += 80; break;
case 1: credits_height += 30; break;
default: credits_height += 12; break;
}
}
credits_height = 131*credits_height/80; // account for scroll speeds. This is a guess now, so you may need to update this if you change the credits length.
}
// Draw credits text on top
for (i = 0; credits[i]; i++)
{
switch(credits[i][0])
{
case 0: y += 80<<FRACBITS; break;
case 1: y += 30<<FRACBITS; break;
default: y += 12<<FRACBITS; break;
}
if (FixedMul(y,vid.dupy) > vid.height)
break;
}
if (timetonext)
timetonext--;
else
animtimer++;
credbgtimer++;
// Do this here rather than in the drawer you doofus! (this is why dedicated mode broke at credits)
const boolean reachedbottom = (!credits[i] && y <= 120<<FRACBITS);
if (reachedbottom && !timetonext)
{
timetonext = 5*TICRATE;
}
if (finalecount)
{
if (--finalecount == 0)
{
F_StartGameEvaluation();
}
return;
}
if (reachedbottom)
{
finalecount = 5*TICRATE;
// You watched all the credits? What a trooper!
gamedata->everfinishedcredits = true;
if (M_UpdateUnlockablesAndExtraEmblems(true, true))
G_SaveGameData();
}
else if (timetonext)
;
/*else if (!(gamedata->timesBeaten) && !(netgame || multiplayer) && !cht_debug)
;*/
else if (!menuactive && M_MenuConfirmPressed(0))
{
finalecount = TICRATE;
if (netgame
&& (server || IsPlayerAdmin(consoleplayer))
)
{
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
return;
}
}
}
// ============
// EVALUATION
// ============
@ -1925,14 +1585,14 @@ void F_TitleScreenTicker(boolean run)
strlcpy(dname, lumpname, sizeof(dname));
loadreplay:
demo.title = true;
demo.attract = DEMO_ATTRACT_TITLE;
demo.ignorefiles = true;
demo.loadfiles = false;
G_DoPlayDemo(dname);
}
}
void F_TitleDemoTicker(void)
void F_AttractDemoTicker(void)
{
keypressed = false;
}
@ -2058,7 +1718,7 @@ void F_EndCutScene(void)
}
else
{
if (cutnum == creditscutscene-1)
if (cutnum == g_credits_cutscene-1)
F_StartGameEvaluation();
else if (cutnum == introtoplay-1)
D_StartTitle();

View file

@ -35,7 +35,7 @@ boolean F_CutsceneResponder(event_t *ev);
void F_IntroTicker(void);
void F_TitleScreenTicker(boolean run);
void F_CutsceneTicker(void);
void F_TitleDemoTicker(void);
void F_AttractDemoTicker(void);
void F_TextPromptTicker(void);
// Called by main loop.
@ -51,9 +51,6 @@ void F_GameEvaluationDrawer(void);
void F_StartGameEvaluation(void);
void F_GameEvaluationTicker(void);
void F_CreditTicker(void);
void F_CreditDrawer(void);
void F_VersionDrawer(void);
void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean resetplayer);
@ -71,7 +68,6 @@ void F_StartGameEnd(void);
void F_StartIntro(void);
void F_StartTitleScreen(void);
void F_StartEnding(void);
void F_StartCredits(void);
extern INT32 finalecount;
extern INT32 titlescrollxspeed;

View file

@ -55,6 +55,7 @@
#include "k_color.h"
#include "k_follower.h"
#include "k_vote.h"
#include "k_credits.h"
boolean nodrawers; // for comparative timing purposes
boolean noblit; // for comparative timing purposes
@ -3301,7 +3302,7 @@ void G_DoPlayDemo(const char *defdemoname)
numlaps = READUINT8(demobuf.p);
if (demo.title) // Titledemos should always play and ought to always be compatible with whatever wadlist is running.
if (demo.attract) // Attract demos should always play and ought to always be compatible with whatever wadlist is running.
G_SkipDemoExtraFiles(&demobuf.p);
else if (demo.loadfiles)
G_LoadDemoExtraFiles(&demobuf.p);
@ -3614,7 +3615,7 @@ void G_DoPlayDemo(const char *defdemoname)
splitscreen = 0;
if (demo.title)
if (demo.attract == DEMO_ATTRACT_TITLE)
{
splitscreen = M_RandomKey(6)-1;
splitscreen = min(min(3, numslots-1), splitscreen); // Bias toward 1p and 4p views
@ -4020,7 +4021,7 @@ void G_TimeDemo(const char *name)
if (cv_vidwait.value)
CV_Set(&cv_vidwait, "0");
demo.timing = true;
singletics = true;
g_singletics = true;
framecount = 0;
demostarttime = I_GetTime();
G_DeferedPlayDemo(name);
@ -4218,7 +4219,7 @@ void G_StopDemo(void)
demobuf.buffer = NULL;
demo.playback = false;
demo.timing = false;
singletics = false;
g_singletics = false;
{
UINT8 i;
@ -4260,7 +4261,7 @@ boolean G_CheckDemoStatus(void)
if (demo.quitafterplaying)
I_Quit();
if (multiplayer && !demo.title)
if (multiplayer && !demo.attract)
G_FinishExitLevel();
else
{
@ -4270,6 +4271,8 @@ boolean G_CheckDemoStatus(void)
COM_ImmedExecute("quit");
else if (modeattacking)
M_EndModeAttackRun();
else if (demo.attract == DEMO_ATTRACT_CREDITS)
F_ContinueCredits();
else
D_StartTitle();
}

View file

@ -43,7 +43,7 @@ struct demovars_s {
char titlename[65];
boolean recording, playback, timing;
UINT16 version; // Current file format of the demo being played
boolean title; // Title Screen demo can be cancelled by any key
UINT8 attract; // Attract demo can be cancelled by any key
boolean rewinding; // Rewind in progress
boolean loadfiles, ignorefiles; // Demo file loading options
@ -209,6 +209,13 @@ boolean G_DemoTitleResponder(event_t *ev);
boolean G_CheckDemoTitleEntry(void);
typedef enum
{
DEMO_ATTRACT_OFF = 0,
DEMO_ATTRACT_TITLE,
DEMO_ATTRACT_CREDITS
} demoAttractMode_t;
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -72,6 +72,7 @@
#include "music.h"
#include "k_roulette.h"
#include "k_objects.h"
#include "k_credits.h"
#ifdef HAVE_DISCORDRPC
#include "discord.h"
@ -271,7 +272,7 @@ UINT8 use1upSound = 0;
UINT8 maxXtraLife = 2; // Max extra lives from rings
UINT8 introtoplay;
UINT8 creditscutscene;
UINT8 g_credits_cutscene;
UINT8 useSeal = 1;
tic_t racecountdown, exitcountdown, musiccountdown; // for racing
@ -1284,6 +1285,10 @@ void G_PreLevelTitleCard(void)
//
boolean G_IsTitleCardAvailable(void)
{
// Don't show for attract demos
if (demo.attract)
return false;
// Overwrites all other title card exceptions.
if (K_CheckBossIntro() == true)
return true;
@ -1316,10 +1321,26 @@ boolean G_Responder(event_t *ev)
{
//INT32 i;
// any other key pops up menu if in demos
if (gameaction == ga_nothing && !demo.quitafterplaying &&
((demo.playback && !modeattacking && !demo.title && !multiplayer) || gamestate == GS_TITLESCREEN))
if (demo.playback && demo.attract)
{
if (demo.attract == DEMO_ATTRACT_TITLE)
{
// Title demo uses intro responder
if (F_IntroResponder(ev))
{
// stop the title demo
G_CheckDemoStatus();
return true;
}
}
return false;
}
else if (gameaction == ga_nothing
&& !demo.quitafterplaying
&& ((demo.playback && !modeattacking && !multiplayer) || gamestate == GS_TITLESCREEN))
{
// any other key pops up menu if in demos
if (ev->type == ev_keydown
|| (ev->type == ev_gamepad_axis && ev->data1 >= JOYANALOGS
&& ((abs(ev->data2) > JOYAXISRANGE/2
@ -1333,17 +1354,7 @@ boolean G_Responder(event_t *ev)
M_StartControlPanel();
return true;
}
return false;
}
else if (demo.playback && demo.title)
{
// Title demo uses intro responder
if (F_IntroResponder(ev))
{
// stop the title demo
G_CheckDemoStatus();
return true;
}
return false;
}
@ -1861,8 +1872,8 @@ void G_Ticker(boolean run)
switch (gamestate)
{
case GS_LEVEL:
if (demo.title)
F_TitleDemoTicker();
if (demo.attract)
F_AttractDemoTicker();
P_Ticker(run); // tic the game
F_TextPromptTicker();
AM_Ticker();
@ -1985,6 +1996,16 @@ void G_Ticker(boolean run)
K_TickMidVote();
}
if (g_fast_forward == 0 && demo.attract == DEMO_ATTRACT_CREDITS)
{
F_TickCreditsDemoExit();
}
if (g_fast_forward > 0)
{
g_fast_forward--;
}
}
}

1182
src/k_credits.cpp Normal file

File diff suppressed because it is too large Load diff

43
src/k_credits.h Normal file
View file

@ -0,0 +1,43 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) by Sally "TehRealSalt" Cochenour
// Copyright (C) by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file k_credits.h
/// \brief Grand Prix podium cutscene
#ifndef __K_CREDITS__
#define __K_CREDITS__
#include "doomtype.h"
#include "d_event.h"
#ifdef __cplusplus
extern "C" {
#endif
void F_LoadCreditsDefinitions(void);
void F_CreditsReset(void);
void F_StartCredits(void);
void F_ContinueCredits(void);
void F_TickCreditsDemoExit(void);
INT32 F_CreditsDemoExitFade(void);
void F_CreditTicker(void);
void F_CreditDrawer(void);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // __K_CREDITS__

View file

@ -5259,6 +5259,11 @@ static void K_drawChallengerScreen(void)
static void K_drawLapStartAnim(void)
{
if (demo.attract == DEMO_ATTRACT_CREDITS)
{
return;
}
// This is an EVEN MORE insanely complicated animation.
const UINT8 t = stplyr->karthud[khud_lapanimation];
const UINT8 progress = 80 - t;
@ -5928,7 +5933,7 @@ void K_drawKartHUD(void)
K_drawEmeraldWin(false);
}
if (!demo.title)
if (!demo.attract)
{
// Draw the CHECK indicator before the other items, so it's overlapped by everything else
if (LUA_HudEnabled(hud_check)) // delete lua when?
@ -5952,7 +5957,7 @@ void K_drawKartHUD(void)
K_drawKartMinimap();
}
if (demo.title)
if (demo.attract)
;
else if (gametype == GT_TUTORIAL)
{
@ -6002,19 +6007,22 @@ void K_drawKartHUD(void)
if (!stplyr->spectator && !freecam) // Bottom of the screen elements, don't need in spectate mode
{
if (demo.title) // Draw title logo instead in demo.titles
if (demo.attract)
{
INT32 x = BASEVIDWIDTH - 8, y = BASEVIDHEIGHT-8, snapflags = V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_SLIDEIN;
patch_t *pat = static_cast<patch_t*>(W_CachePatchName((cv_alttitle.value ? "MTSJUMPR1" : "MTSBUMPR1"), PU_CACHE));
if (r_splitscreen == 3)
if (demo.attract == DEMO_ATTRACT_TITLE) // Draw logo on title screen demos
{
x = BASEVIDWIDTH/2;
y = BASEVIDHEIGHT/2;
snapflags = 0;
}
INT32 x = BASEVIDWIDTH - 8, y = BASEVIDHEIGHT-8, snapflags = V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_SLIDEIN;
patch_t *pat = static_cast<patch_t*>(W_CachePatchName((cv_alttitle.value ? "MTSJUMPR1" : "MTSBUMPR1"), PU_CACHE));
V_DrawScaledPatch(x-(SHORT(pat->width)), y-(SHORT(pat->height)), snapflags, pat);
if (r_splitscreen == 3)
{
x = BASEVIDWIDTH/2;
y = BASEVIDHEIGHT/2;
snapflags = 0;
}
V_DrawScaledPatch(x-(SHORT(pat->width)), y-(SHORT(pat->height)), snapflags, pat);
}
}
else
{

View file

@ -270,7 +270,7 @@ boolean M_Responder(event_t *ev)
boolean menuKeyJustChanged = false;
if (dedicated
|| (demo.playback && demo.title)
|| (demo.playback && demo.attract)
|| M_GamestateCanOpenMenu() == false)
{
return false;

View file

@ -82,6 +82,8 @@ static struct podiumData_s
cupheader_t *cup;
boolean fastForward;
char header[64];
void Init(void);
@ -92,6 +94,8 @@ static struct podiumData_s
void podiumData_s::Init(void)
{
fastForward = false;
if (grandprixinfo.cup != nullptr)
{
rank = grandprixinfo.rank;
@ -117,7 +121,7 @@ void podiumData_s::Init(void)
memset(&rank, 0, sizeof(gpRank_t));
rank.skin = players[consoleplayer].skin;
rank.numPlayers = 1; //M_RandomRange(1, MAXSPLITSCREENPLAYERS);
rank.numPlayers = std::clamp<UINT8>(M_RandomRange(0, MAXSPLITSCREENPLAYERS + 1), 1, MAXSPLITSCREENPLAYERS);
rank.totalPlayers = K_GetGPPlayerCount(rank.numPlayers);
rank.position = M_RandomRange(1, 4);
@ -473,6 +477,23 @@ void podiumData_s::Draw(void)
.colormap(bestHuman->skin, static_cast<skincolornum_t>(bestHuman->skincolor))
.patch(faceprefix[bestHuman->skin][FACE_WANTED]);
UINT32 continuesColor = 0;
if (rank.continuesUsed == 0)
{
continuesColor = V_YELLOWMAP;
}
else if (rank.continuesUsed > 2)
{
continuesColor = V_REDMAP;
}
drawer_winner
.xy(64, 18)
.flags(continuesColor)
.font(srb2::Draw::Font::kThin)
.text(va("Continues used ... %d", rank.continuesUsed));
if (cup != nullptr)
{
srb2::Draw drawer_trophy = drawer.xy(272, 10);
@ -993,6 +1014,7 @@ void K_FinishCeremony(void)
}
g_podiumData.ranking = true;
g_fast_forward = 0;
}
/*--------------------------------------------------
@ -1116,6 +1138,34 @@ void K_CeremonyTicker(boolean run)
if (g_podiumData.ranking == false)
{
if (run == true)
{
if (g_podiumData.fastForward == true)
{
if (g_fast_forward == 0)
{
// Possibly an infinite loop, finalize even if we're still in the middle of the cutscene.
K_FinishCeremony();
}
}
else
{
if (menuactive == false && M_MenuConfirmPressed(0) == true)
{
if (!netgame)
{
constexpr tic_t kSkipToTime = 60 * TICRATE;
if (kSkipToTime > leveltime)
{
g_fast_forward = kSkipToTime - leveltime;
}
}
g_podiumData.fastForward = true;
}
}
}
return;
}

View file

@ -1357,7 +1357,7 @@ void M_StartMovie(moviemode_t mode)
}
#endif
//singletics = (moviemode != MM_OFF);
//g_singletics = (moviemode != MM_OFF);
#endif
}

View file

@ -7,6 +7,7 @@
#include "../m_cheat.h"
#include "../s_sound.h"
#include "../f_finale.h"
#include "../k_credits.h"
static void M_Credits(INT32 choice)
{

View file

@ -8,6 +8,7 @@
#include "../../r_main.h" // R_ExecuteSetViewSize
#include "../../p_local.h" // P_InitCameraCmd
#include "../../d_main.h" // D_StartTitle
#include "../../k_credits.h"
static void M_PlaybackTick(void);
@ -58,10 +59,14 @@ void M_EndModeAttackRun(void)
modeattacking = ATTACKING_NONE; // Kept until now because of Command_ExitGame_f
if (demo.title == true)
if (demo.attract == DEMO_ATTRACT_TITLE)
{
D_StartTitle();
}
else if (demo.attract == DEMO_ATTRACT_CREDITS)
{
F_ContinueCredits();
}
else
{
D_ClearState();

View file

@ -8259,11 +8259,16 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
P_InitLevelSettings();
if (!demo.title)
if (demo.attract != DEMO_ATTRACT_TITLE)
{
Music_Stop("title");
}
if (demo.attract != DEMO_ATTRACT_CREDITS)
{
Music_Stop("credits");
}
for (i = 0; i <= r_splitscreen; i++)
postimgtype[i] = postimg_none;
@ -8378,7 +8383,11 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
FixedDiv((F_GetWipeLength(wipedefs[wipe_level_toblack])-2)*NEWTICRATERATIO, NEWTICRATE), MUSICRATE));
#endif
if (K_PodiumSequence())
if (demo.attract)
{
; // Leave the music alone! We're already playing what we want!
}
else if (K_PodiumSequence())
{
// mapmusrng is set by local player position in K_ResetCeremony
P_LoadLevelMusic();

View file

@ -1075,7 +1075,10 @@ void P_Ticker(boolean run)
}
}
timeinmap++;
if (g_fast_forward == 0)
{
timeinmap++;
}
if (G_GametypeHasTeams())
P_DoTeamStuff();

View file

@ -68,6 +68,7 @@
#include "k_tally.h"
#include "k_objects.h"
#include "k_endcam.h"
#include "k_credits.h"
#ifdef HWRENDER
#include "hardware/hw_light.h"
@ -3190,7 +3191,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
mo = player->mo;
if (P_MobjIsFrozen(mo) || player->playerstate == PST_DEAD)
if (P_MobjIsFrozen(mo) || player->playerstate == PST_DEAD || F_CreditsDemoExitFade() >= 0)
{
// Do not move the camera while in hitlag!
// The camera zooming out after you got hit makes it hard to focus on the vibration.
@ -4003,6 +4004,11 @@ DoABarrelRoll (player_t *player)
fixed_t smoothing;
if (player->exiting || F_CreditsDemoExitFade() >= 0)
{
return;
}
if (player->loop.radius)
{
return;
@ -4014,11 +4020,6 @@ DoABarrelRoll (player_t *player)
return;
}
if (player->exiting)
{
return;
}
slope = InvAngle(R_GetPitchRollAngle(player->mo, player));
if (AbsAngle(slope) < ANGLE_11hh)

View file

@ -249,7 +249,8 @@ boolean S_SoundDisabled(void)
{
return (
sound_disabled ||
( window_notinfocus && ! (cv_bgaudio.value & 2) )
( window_notinfocus && ! (cv_bgaudio.value & 2) ) ||
(g_fast_forward > 0)
);
}
@ -1227,6 +1228,10 @@ void S_AttemptToRestoreMusic(void)
case GS_MENU:
M_PlayMenuJam();
break;
case GS_CREDITS:
Music_Loop("credits", true);
Music_Play("credits");
break;
default:
break;
}

View file

@ -749,7 +749,7 @@ patch_t *ST_getRoundPicture(boolean small)
//
void ST_runTitleCard(void)
{
boolean run = !(paused || P_AutoPause());
boolean run = !(paused || P_AutoPause() || g_fast_forward > 0);
INT32 auxticker;
boolean doroundicon = (ST_getRoundPicture(false) != NULL);
@ -1246,7 +1246,7 @@ static void ST_overlayDrawer(void)
{
if (cv_showviewpointtext.value)
{
if (!demo.title && !P_IsLocalPlayer(stplyr) && !camera[viewnum].freecam)
if (!demo.attract && !P_IsLocalPlayer(stplyr) && !camera[viewnum].freecam)
{
if (!r_splitscreen)
{