Domain correction from playtest: hand-fed eggs are a developer shortcut - a mission only ends on a console command, so the clock hits 00:00 and counts up forever. Even single-player games need a console marshal. RPL4CONSOLE is that console. Like the real one it lives on its own thread: it owns the mission clock and raises the stop request at the selected length; the app-manager per-frame hook (new gPerFrameHook seam in APPMGR, called while the application global is live - the loop condition NULLs it on exit, which ate the first attempt) executes the engine-safe part, dispatching the same StopMissionMessage TeslaConsole sent. Final scores flow in through a new RP-layer sink (gConsoleScoreSink in RPCNSL): RPPlayer feeds it the same score it sends a real console at mission end. It also inherits the launcher role: the application tears down after a stop (arcade pods were relaunched per mission by TeslaLauncher), so WinMain respawns the process when the console ended the mission, landing back on the race-setup screen. L4NetworkManager grows FeedLocalEgg (the single-user egg-inject path, callable mid-session) for the future in-process loop. Verified end to end: menu -> 3:00 race -> stop dispatched exactly on time -> final score collected (host 1 = 4113) -> process respawned with the front end up. -egg runs stay unmarshaled (the dev shortcut). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
288 lines
5.0 KiB
C++
288 lines
5.0 KiB
C++
#pragma once
|
|
|
|
#if defined(MAC)
|
|
#include "NetworkEndpoint.h"
|
|
#include "Participant.h"
|
|
#else
|
|
#include "..\munga\console.h"
|
|
#endif
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~ Console Message IDs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
enum
|
|
{
|
|
ConsolePlayerVTVScoredMessageID = 2,
|
|
ConsolePlayerVTVKilledMessageID = 3,
|
|
ConsolePlayerVTVBoosterMessageID = 4,
|
|
ConsolePlayerVTVScoreUpdateMessageID = 5,
|
|
ConsolePlayerVTVDamagedMessageID = 6
|
|
};
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~ Local console sink ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// When an in-process console marshals the game (RP412 single player),
|
|
// this points at its final-score intake; the player's mission-ending
|
|
// path feeds it the same score it sends a real console. NULL when no
|
|
// local console is present.
|
|
extern void (*gConsoleScoreSink)(int player_host_ID, int final_score);
|
|
|
|
//~~~~~~~~~~~~~~~~~~ ConsolePlayerVTVScoredMessage ~~~~~~~~~~~~~~~~~~~
|
|
#ifdef MAC
|
|
#pragma options align=mac68k4byte
|
|
class ConsolePlayerVTVScoredMessage:
|
|
public NetworkEndpoint::Message
|
|
{
|
|
public:
|
|
ConsolePlayerVTVScoredMessage(HostID player_host_ID);
|
|
|
|
long
|
|
GetPlayerHostID()
|
|
{return playerHostID.value();}
|
|
|
|
private:
|
|
HostID
|
|
playerHostID;
|
|
};
|
|
#pragma options align=reset
|
|
#else
|
|
class ConsolePlayerVTVScoredMessage:
|
|
public NetworkClient::Message
|
|
{
|
|
public:
|
|
ConsolePlayerVTVScoredMessage(HostID player_host_ID);
|
|
|
|
HostID
|
|
GetPlayerHostID()
|
|
{return playerHostID;}
|
|
|
|
private:
|
|
HostID
|
|
playerHostID;
|
|
};
|
|
#endif
|
|
|
|
//~~~~~~~~~~~~~~~~~~ ConsolePlayerVTVKilledMessage ~~~~~~~~~~~~~~~~~~~
|
|
#ifdef MAC
|
|
#pragma options align=mac68k4byte
|
|
class ConsolePlayerVTVKilledMessage:
|
|
public NetworkEndpoint::Message
|
|
{
|
|
public:
|
|
ConsolePlayerVTVKilledMessage(
|
|
HostID player_host_ID,
|
|
HostID killer_host_ID
|
|
);
|
|
|
|
long
|
|
GetPlayerHostID()
|
|
{return playerHostID.value();}
|
|
long
|
|
GetKillerHostID()
|
|
{return killerHostID.value();}
|
|
|
|
private:
|
|
HostID
|
|
playerHostID;
|
|
HostID
|
|
killerHostID;
|
|
};
|
|
#pragma options align=reset
|
|
#else
|
|
class ConsolePlayerVTVKilledMessage:
|
|
public NetworkClient::Message
|
|
{
|
|
public:
|
|
ConsolePlayerVTVKilledMessage(
|
|
HostID player_host_ID,
|
|
HostID killer_host_ID
|
|
);
|
|
|
|
HostID
|
|
GetPlayerHostID()
|
|
{return playerHostID;}
|
|
HostID
|
|
GetKillerHostID()
|
|
{return killerHostID;}
|
|
|
|
private:
|
|
HostID
|
|
playerHostID,
|
|
killerHostID;
|
|
};
|
|
#endif
|
|
|
|
//~~~~~~~~~~~~~~~~~~ ConsolePlayerVTVBoosterMessage ~~~~~~~~~~~~~~~~~~~
|
|
#ifdef MAC
|
|
#pragma options align=mac68k4byte
|
|
class ConsolePlayerVTVBoosterMessage:
|
|
public NetworkEndpoint::Message
|
|
{
|
|
public:
|
|
ConsolePlayerVTVBoosterMessage(
|
|
HostID player_host_ID,
|
|
LEDWORD booster_on
|
|
);
|
|
|
|
long
|
|
GetPlayerHostID()
|
|
{return playerHostID.value();}
|
|
long
|
|
GetBoosterOn()
|
|
{return boosterOn.value();}
|
|
|
|
private:
|
|
HostID
|
|
playerHostID;
|
|
LEDWORD
|
|
boosterOn;
|
|
};
|
|
#pragma options align=reset
|
|
#else
|
|
class ConsolePlayerVTVBoosterMessage:
|
|
public NetworkClient::Message
|
|
{
|
|
public:
|
|
ConsolePlayerVTVBoosterMessage(
|
|
HostID player_host_ID,
|
|
int booster_on
|
|
);
|
|
|
|
HostID
|
|
GetPlayerHostID()
|
|
{return playerHostID;}
|
|
int
|
|
GetBoosterOn()
|
|
{return boosterOn;}
|
|
|
|
private:
|
|
HostID
|
|
playerHostID;
|
|
int
|
|
boosterOn;
|
|
};
|
|
#endif
|
|
|
|
//~~~~~~~~~~~~~~~~~~ ConsolePlayerVTVScoreUpdateMessage ~~~~~~~~~~~~~~~~~~~
|
|
#ifdef MAC
|
|
#pragma options align=mac68k4byte
|
|
class ConsolePlayerVTVScoreUpdateMessage:
|
|
public NetworkEndpoint::Message
|
|
{
|
|
public:
|
|
ConsolePlayerVTVScoreUpdateMessage(
|
|
HostID player_host_ID,
|
|
LEDWORD score
|
|
);
|
|
|
|
long
|
|
GetPlayerHostID()
|
|
{return playerHostID.value();}
|
|
long
|
|
GetPlayerScore()
|
|
{return playerScore.value();}
|
|
|
|
private:
|
|
HostID
|
|
playerHostID;
|
|
LEDWORD
|
|
playerScore;
|
|
};
|
|
#pragma options align=reset
|
|
#else
|
|
class ConsolePlayerVTVScoreUpdateMessage:
|
|
public NetworkClient::Message
|
|
{
|
|
public:
|
|
ConsolePlayerVTVScoreUpdateMessage(
|
|
HostID player_host_ID,
|
|
int score
|
|
);
|
|
|
|
HostID
|
|
GetPlayerHostID()
|
|
{return playerHostID;}
|
|
int
|
|
GetPlayerScore()
|
|
{return playerScore;}
|
|
|
|
private:
|
|
HostID
|
|
playerHostID;
|
|
int
|
|
playerScore;
|
|
};
|
|
#endif
|
|
|
|
//~~~~~~~~~~~~~~~~~~ ConsolePlayerVTVDamagedMessage ~~~~~~~~~~~~~~~~~~~
|
|
#ifdef MAC
|
|
#pragma options align=mac68k4byte
|
|
class ConsolePlayerVTVDamagedMessage:
|
|
public NetworkEndpoint::Message
|
|
{
|
|
public:
|
|
ConsolePlayerVTVDamagedMessage(
|
|
HostID player_host_ID,
|
|
HostID damager_host_ID,
|
|
LEDWORD loss,
|
|
LEDWORD points_transfered
|
|
);
|
|
|
|
long
|
|
GetPlayerHostID()
|
|
{return playerHostID.value();}
|
|
long
|
|
GetDamagerHostID()
|
|
{return damagerHostID.value();}
|
|
long
|
|
GetDamageLoss()
|
|
{return damageLoss.value();}
|
|
long
|
|
GetPointsTransfered()
|
|
{return pointsTransfered.value();}
|
|
|
|
private:
|
|
HostID
|
|
playerHostID;
|
|
HostID
|
|
damagerHostID;
|
|
LEDWORD
|
|
damageLoss;
|
|
LEDWORD
|
|
pointsTransfered;
|
|
};
|
|
#pragma options align=reset
|
|
#else
|
|
class ConsolePlayerVTVDamagedMessage:
|
|
public NetworkClient::Message
|
|
{
|
|
public:
|
|
ConsolePlayerVTVDamagedMessage(
|
|
HostID player_host_ID,
|
|
HostID damager_host_ID,
|
|
int loss,
|
|
int points_transfered
|
|
);
|
|
|
|
HostID
|
|
GetPlayerHostID()
|
|
{return playerHostID;}
|
|
HostID
|
|
GetDamagerHostID()
|
|
{return damagerHostID;}
|
|
int
|
|
GetDamageLoss()
|
|
{return damageLoss;}
|
|
int
|
|
GetPointsTransfered()
|
|
{return pointsTransfered;}
|
|
|
|
private:
|
|
HostID
|
|
playerHostID;
|
|
HostID
|
|
damagerHostID;
|
|
int
|
|
damageLoss;
|
|
int
|
|
pointsTransfered;
|
|
};
|
|
#endif
|