The podium hold asks whether there is a podium

RP412PODIUM=0 promises "straight to the results" and delivered eleven
seconds of black screen first: the winners' circle hold was applied
unconditionally at the buzzer, and the timer never asked whether there
was a stand to hold the mission open FOR. Found by the -egg harness,
which could reach the end of a race unattended and noticed the promise
not being kept.

With the podium off, the hold now stands aside and the base 3-second
race fade runs the show. With it on, RP412PODIUMHOLD tunes the length
(1-60 seconds, default the same 11 as always) - eleven seconds of one
parked pod is a long look in single player, and that is now a choice
rather than a constant. The decision point logs which path it took and
the value it applied, verified all three ways:

  podium off - the race fade stands (3s) and the results come straight up
  holding the mission open 5s for the stand
  holding the mission open 11s for the stand

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-08-09 22:04:18 -05:00
co-authored by Claude Fable 5
parent c479cd48e9
commit 67d57452ba
2 changed files with 53 additions and 2 deletions
+47 -2
View File
@@ -19,7 +19,40 @@
// fade; the rest is the podium. Kept under the +30s LightsOut post so that
// never fires while the stand is up.
//
const Scalar winnersCircleHoldTime = 11.0f;
// RP412PODIUMHOLD tunes it, and RP412PODIUM=0 declines it entirely: that
// option promises "straight to the results", and it used to get the full
// eleven seconds against a black screen anyway, because this timer never
// asked whether there was a podium to hold the mission open FOR. Zero
// here means "do not override the base fade" - the stock 3 seconds.
//
static Scalar
WinnersCircleHoldTime()
{
static Scalar
hold = (Scalar) -1;
if (hold < (Scalar) 0)
{
const char *podium = getenv("RP412PODIUM");
if (podium != NULL && atoi(podium) == 0)
{
hold = (Scalar) 0;
}
else
{
const char *setting = getenv("RP412PODIUMHOLD");
hold = (setting != NULL) ? (Scalar) atof(setting) : (Scalar) 11;
//
// Under a second cuts into the race's own fade-out, and a
// minute is a stuck-looking screen; both read as bugs, not
// choices.
//
if (hold < (Scalar) 1) hold = (Scalar) 1;
if (hold > (Scalar) 60) hold = (Scalar) 60;
}
}
return hold;
}
//#############################################################################
//######################## RPPlayer__StatusMessage ######################
@@ -214,7 +247,19 @@ void
//
if (application->GetApplicationState() == Application::EndingMission)
{
fadeTimeRemaining = winnersCircleHoldTime;
Scalar hold = WinnersCircleHoldTime();
if (hold > (Scalar) 0)
{
fadeTimeRemaining = hold;
DEBUG_STREAM << "WinnersCircle: holding the mission open "
<< hold << "s for the stand\n" << std::flush;
}
else
{
DEBUG_STREAM << "WinnersCircle: podium off - the race fade "
<< "stands (" << fadeTimeRemaining << "s) and the results "
<< "come straight up\n" << std::flush;
}
}
Check_Fpu();
}
+6
View File
@@ -190,6 +190,12 @@ namespace
"#RP412PODIUMFADEIN=0.45\n"
"#RP412PODIUMCAM=1\n"
"\n"
"# How long the podium holds before the results screen, in seconds\n"
"# (1-60). The stand is worth a look but eleven seconds of one parked\n"
"# pod is a long look in single player. With RP412PODIUM=0 there is no\n"
"# hold at all - straight to the results, as that option promises.\n"
"#RP412PODIUMHOLD=11\n"
"\n"
"# Override the game length the menu picked, in seconds. The shortest the\n"
"# menu offers is 3:00, which is a long wait when what you are testing is\n"
"# what happens at the buzzer. Unset = use the menu's choice.\n"