- reduce stack memory usage by refactoring game into states

This commit is contained in:
Ilya Shurumov 2021-04-14 22:27:06 +06:00
parent acf4291916
commit 12c44bf17a
12 changed files with 384 additions and 266 deletions

View File

@ -34,14 +34,12 @@ POLYCOORD polycoords[6] =
void ShowHiresScreens(char **names, int delay, int wait) void ShowHiresScreens(char **names, int delay, int wait)
{ {
int timedelay; int timedelay;
char *filename; char* filename;
filename = *names; filename = *names;
do { while (filename)
if (!filename) {
return;
FadeInHiresScreen(filename); FadeInHiresScreen(filename);
timedelay = delay-1; timedelay = delay-1;
@ -59,7 +57,7 @@ void ShowHiresScreens(char **names, int delay, int wait)
FadeOutHiresScreen(); FadeOutHiresScreen();
filename = *(++names); filename = *(++names);
} while (true); }
} }
// [D] [T] // [D] [T]

View File

@ -1,8 +1,6 @@
#include "driver2.h" #include "driver2.h"
#include "glaunch.h" #include "glaunch.h"
#include "system.h" #include "system.h"
#include "main.h" #include "main.h"
#include "E3stuff.h" #include "E3stuff.h"
@ -13,9 +11,9 @@
#include "gamesnd.h" #include "gamesnd.h"
#include "camera.h" #include "camera.h"
#include "fmvplay.h" #include "fmvplay.h"
#include "state.h"
#include "Frontend/FEmain.h" #include "Frontend/FEmain.h"
#include "LIBETC.H" #include "LIBETC.H"
#include "STRINGS.H" #include "STRINGS.H"
@ -116,13 +114,26 @@ int gFurthestMission = 0;
int gWantNight = 0; int gWantNight = 0;
// [D] [T] int gOldVibrationMode;
void GameStart(void) int gSurvivalCopSettingsBackup;
{ ACTIVE_CHEATS gCheatsBackup;
int oldVibrationMode;
int SurvivalCopSettingsBackup;
ACTIVE_CHEATS CheatsBackup;
void RestoreGameVars()
{
#ifdef CUTSCENE_RECORDER
extern int gCutsceneAsReplay;
gCutsceneAsReplay = 0;
#endif
gLoadedReplay = 0;
gVibration = gOldVibrationMode;
gCopDifficultyLevel = gSurvivalCopSettingsBackup;
ActiveCheats = gCheatsBackup;
}
// [D] [T]
void State_GameStart(void* param)
{
if (GameType != GAME_CONTINUEMISSION && if (GameType != GAME_CONTINUEMISSION &&
GameType != GAME_MISSION && GameType != GAME_MISSION &&
GameType != GAME_REPLAYMISSION) GameType != GAME_REPLAYMISSION)
@ -133,17 +144,17 @@ void GameStart(void)
DrawSync(0); DrawSync(0);
VSync(0); VSync(0);
FreeXM();
SsSetSerialVol(0, 0, 0);
gInFrontend = 0; gInFrontend = 0;
AttractMode = 0; AttractMode = 0;
FreeXM();
SsSetSerialVol(0, 0, 0);
SurvivalCopSettingsBackup = gCopDifficultyLevel;
CheatsBackup = ActiveCheats;
NewLevel = 1; NewLevel = 1;
gOldVibrationMode = gVibration;
gSurvivalCopSettingsBackup = gCopDifficultyLevel;
gCheatsBackup = ActiveCheats;
switch (GameType) switch (GameType)
{ {
case GAME_MISSION: case GAME_MISSION:
@ -158,35 +169,28 @@ void GameStart(void)
gCurrentMissionNumber += GameLevel * 2 + gWantNight + gSubGameNumber * 440; gCurrentMissionNumber += GameLevel * 2 + gWantNight + gSubGameNumber * 440;
LaunchGame(); SetState(STATE_GAMELAUNCH);
break; break;
case GAME_IDLEDEMO: case GAME_IDLEDEMO:
oldVibrationMode = gVibration;
if (LoadAttractReplay(gCurrentMissionNumber)) if (LoadAttractReplay(gCurrentMissionNumber))
{ {
gVibration = 0; gVibration = 0;
CurrentGameMode = GAMEMODE_DEMO; CurrentGameMode = GAMEMODE_DEMO;
gLoadedReplay = 1; gLoadedReplay = 1;
LaunchGame(); SetState(STATE_GAMELAUNCH);
gLoadedReplay = 0;
gVibration = oldVibrationMode;
gCopDifficultyLevel = SurvivalCopSettingsBackup;
ActiveCheats = CheatsBackup;
} }
break; break;
case GAME_PURSUIT: case GAME_PURSUIT:
gCurrentMissionNumber = 70 + GameLevel * 8 + gWantNight * 4 + gSubGameNumber; gCurrentMissionNumber = 70 + GameLevel * 8 + gWantNight * 4 + gSubGameNumber;
LaunchGame(); SetState(STATE_GAMELAUNCH);
break; break;
case GAME_GETAWAY: case GAME_GETAWAY:
gCurrentMissionNumber = 102 + GameLevel * 8 + gWantNight * 4 + gSubGameNumber; gCurrentMissionNumber = 102 + GameLevel * 8 + gWantNight * 4 + gSubGameNumber;
LaunchGame(); SetState(STATE_GAMELAUNCH);
break; break;
case GAME_GATERACE: case GAME_GATERACE:
@ -196,7 +200,8 @@ void GameStart(void)
gCurrentMissionNumber = 164; gCurrentMissionNumber = 164;
gCurrentMissionNumber += GameLevel * 8 + gWantNight * 4 + gSubGameNumber; gCurrentMissionNumber += GameLevel * 8 + gWantNight * 4 + gSubGameNumber;
LaunchGame(); SetState(STATE_GAMELAUNCH);
break; break;
case GAME_CHECKPOINT: case GAME_CHECKPOINT:
if (NumPlayers == 1) if (NumPlayers == 1)
@ -205,12 +210,12 @@ void GameStart(void)
gCurrentMissionNumber = 228; gCurrentMissionNumber = 228;
gCurrentMissionNumber += GameLevel * 8 + gWantNight * 4 + gSubGameNumber; gCurrentMissionNumber += GameLevel * 8 + gWantNight * 4 + gSubGameNumber;
LaunchGame(); SetState(STATE_GAMELAUNCH);
break; break;
case GAME_TRAILBLAZER: case GAME_TRAILBLAZER:
gCurrentMissionNumber = GameLevel * 8 + 260 + gWantNight * 4 + gSubGameNumber; gCurrentMissionNumber = GameLevel * 8 + 260 + gWantNight * 4 + gSubGameNumber;
LaunchGame(); SetState(STATE_GAMELAUNCH);
break; break;
case GAME_SURVIVAL: case GAME_SURVIVAL:
@ -223,28 +228,25 @@ void GameStart(void)
gCurrentMissionNumber += GameLevel * 8 + gWantNight * 4 + gSubGameNumber; gCurrentMissionNumber += GameLevel * 8 + gWantNight * 4 + gSubGameNumber;
LaunchGame(); SetState(STATE_GAMELAUNCH);
gCopDifficultyLevel = SurvivalCopSettingsBackup;
break; break;
case GAME_REPLAYMISSION: case GAME_REPLAYMISSION:
GameType = GAME_MISSION; GameType = GAME_MISSION;
if (FindMissionLadderPos(gCurrentMissionNumber) != 0) if (FindMissionLadderPos(gCurrentMissionNumber))
RunMissionLadder(0); RunMissionLadder(0);
GameType = GAME_REPLAYMISSION; //GameType = GAME_REPLAYMISSION;
break; break;
case GAME_COPSANDROBBERS: case GAME_COPSANDROBBERS:
gCurrentMissionNumber = 420 + GameLevel * 8 + gWantNight * 4 + gSubGameNumber; gCurrentMissionNumber = 420 + GameLevel * 8 + gWantNight * 4 + gSubGameNumber;
LaunchGame(); SetState(STATE_GAMELAUNCH);
break; break;
case GAME_CAPTURETHEFLAG: case GAME_CAPTURETHEFLAG:
gCurrentMissionNumber = 352 + GameLevel * 8 + gSubGameNumber; gCurrentMissionNumber = 352 + GameLevel * 8 + gSubGameNumber;
LaunchGame(); SetState(STATE_GAMELAUNCH);
break; break;
case GAME_SECRET: case GAME_SECRET:
@ -254,7 +256,7 @@ void GameStart(void)
gCurrentMissionNumber = 484; gCurrentMissionNumber = 484;
gCurrentMissionNumber += gWantNight + gSubGameNumber; gCurrentMissionNumber += gWantNight + gSubGameNumber;
LaunchGame(); SetState(STATE_GAMELAUNCH);
break; break;
case GAME_CONTINUEMISSION: case GAME_CONTINUEMISSION:
@ -267,33 +269,30 @@ void GameStart(void)
gLoadedReplay = 1; gLoadedReplay = 1;
GameType = StoredGameType; GameType = StoredGameType;
LaunchGame(); SetState(STATE_GAMELAUNCH);
gLoadedReplay = 0;
gCopDifficultyLevel = SurvivalCopSettingsBackup;
ActiveCheats = CheatsBackup;
break; break;
} }
wantedCar[1] = -1;
wantedCar[0] = -1;
// [A]
wantedWeather = -1;
wantedTimeOfDay = -1;
gHaveStoredData = 0;
ReInitFrontend();
} }
void State_InitFrontEnd(void* param)
{
if ((int)param)
{
InitFrontendDisplay();
InitFrontend();
}
else
ReInitFrontend();
SetState(STATE_FRONTEND);
}
// [D] [T] // [D] [T]
void StartRender(int renderNum) void State_FMVPlay(void* param)
{ {
PlayFMV(renderNum); PlayFMV((int)param);
ReInitFrontend(); SetState(STATE_INITFRONTEND);
} }
// [D] [T] // [D] [T]
@ -304,6 +303,14 @@ void ReInitFrontend(void)
old_camera_change = 0; old_camera_change = 0;
camera_change = 0; camera_change = 0;
wantedCar[1] = -1;
wantedCar[0] = -1;
wantedWeather = -1;
wantedTimeOfDay = -1;
gHaveStoredData = 0;
EnableDisplay(); EnableDisplay();
DrawSync(0); DrawSync(0);
VSync(0); VSync(0);
@ -325,6 +332,8 @@ void ReInitFrontend(void)
Loadfile("FRONTEND.BIN", 0x801C0000); Loadfile("FRONTEND.BIN", 0x801C0000);
#endif // PSX #endif // PSX
// switch to state STATE_INITFRONTEND
SetFEDrawMode(); SetFEDrawMode();
DrawSync(0); DrawSync(0);
EnableDisplay(); EnableDisplay();
@ -333,8 +342,10 @@ void ReInitFrontend(void)
ClearImage(&rect, 0, 0, 0); ClearImage(&rect, 0, 0, 0);
DrawSync(0); DrawSync(0);
LoadFrontendScreens(1); LoadFrontendScreens(1);
ReInitScreens(); ReInitScreens();
DrawSync(0); DrawSync(0);
VSync(0); VSync(0);
@ -343,20 +354,18 @@ void ReInitFrontend(void)
SetDispMask(1); SetDispMask(1);
//LoadedLevel = 0xff;
bRedrawFrontend = 1; bRedrawFrontend = 1;
} }
// [D] [T] void State_MissionLadder(void* param)
void RunMissionLadder(int newgame)
{ {
bool quit; int quit;
int newgame;
MISSION_STEP* CurrentStep; MISSION_STEP* CurrentStep;
RENDER_ARGS RenderArgs; RENDER_ARGS RenderArgs;
quit = false; newgame = (int)param;
if (newgame != 0) quit = 0;
gMissionLadderPos = 0;
RenderArgs.nRenders = 0; RenderArgs.nRenders = 0;
CurrentStep = MissionLadder + gMissionLadderPos; CurrentStep = MissionLadder + gMissionLadderPos;
@ -401,8 +410,6 @@ void RunMissionLadder(int newgame)
SetPleaseWait(NULL); SetPleaseWait(NULL);
} }
gMissionLadderPos = CurrentStep - MissionLadder;
if (CurrentStep->flags == 2) if (CurrentStep->flags == 2)
{ {
if (RenderArgs.nRenders != 0) if (RenderArgs.nRenders != 0)
@ -414,17 +421,20 @@ void RunMissionLadder(int newgame)
SetPleaseWait(NULL); SetPleaseWait(NULL);
gCurrentMissionNumber = CurrentStep->data; gCurrentMissionNumber = CurrentStep->data;
LaunchGame();
SetState(STATE_GAMELAUNCH);
quit = 1;
/*
if (WantedGameMode == GAMEMODE_NEXTMISSION) if (WantedGameMode == GAMEMODE_NEXTMISSION)
{ {
if (gFurthestMission < gCurrentMissionNumber) if (gCurrentMissionNumber > gFurthestMission)
gFurthestMission = gCurrentMissionNumber; gFurthestMission = gCurrentMissionNumber;
} }
else else
{ {
quit = true; quit = 1;
} }*/
} }
else if (CurrentStep->flags == 1) else if (CurrentStep->flags == 1)
{ {
@ -446,14 +456,25 @@ void RunMissionLadder(int newgame)
SetPleaseWait(NULL); SetPleaseWait(NULL);
quit = true; quit = 1;
AvailableCheats.cheat5 = true; AvailableCheats.cheat5 = true;
} }
CurrentStep++; CurrentStep++;
gMissionLadderPos = CurrentStep - MissionLadder;
} while (!quit); } while (!quit);
} }
// [D] [T]
void RunMissionLadder(int newgame)
{
if (newgame)
gMissionLadderPos = 0;
SetState(STATE_LADDER, (void*)newgame);
}
// [D] [T] // [D] [T]
void GetRandomChase(void) void GetRandomChase(void)
{ {
@ -504,7 +525,6 @@ int FindPrevMissionFromLadderPos(int pos)
return 0; return 0;
} }
int fakeOtherPlayer = 0;
int gMissionCompletionState = 0; int gMissionCompletionState = 0;
char NoPlayerControl = 0; char NoPlayerControl = 0;
@ -517,13 +537,12 @@ MISSION_DATA MissionStartData;
MISSION_DATA MissionEndData; MISSION_DATA MissionEndData;
// [D] [T] // [D] [T]
void LaunchGame(void) void State_LaunchGame(void* param)
{ {
int quit; int quit;
RECT16 rect{ 0, 0, 512, 512 };
// STATE_GAMELAUNCH
fakeOtherPlayer = 0;
ResetGraph(1); ResetGraph(1);
SetVideoMode(video_mode); SetVideoMode(video_mode);
@ -542,98 +561,119 @@ void LaunchGame(void)
AttractMode = 0; AttractMode = 0;
NoPlayerControl = 1; NoPlayerControl = 1;
} }
else if (CurrentGameMode == GAMEMODE_REPLAY)
{
AttractMode = 0;
NoPlayerControl = 1;
quick_replay = 1;
}
else if (CurrentGameMode == GAMEMODE_DEMO)
{
AttractMode = 1;
NoPlayerControl = 1;
}
else else
{ {
AttractMode = 0; AttractMode = 0;
NoPlayerControl = 0; NoPlayerControl = 0;
if (CurrentGameMode < GAMEMODE_NEXTMISSION)
{
if (CurrentGameMode == GAMEMODE_REPLAY)
{
AttractMode = 0;
NoPlayerControl = 1;
quick_replay = 1;
}
}
else if (CurrentGameMode == GAMEMODE_DEMO)
{
AttractMode = 1;
NoPlayerControl = 1;
}
} }
AutoDirect = 0; AutoDirect = 0;
NewLevel = 1; NewLevel = 1;
quit = 0; // switch to STATE_GAMEINIT
SetState(STATE_GAMEINIT);
}
do { // [A] state function
GameInit(); void State_GameComplete(void* param)
GameLoop(); {
GameStates nextState;
int stateParam;
RECT16 rect;
switch (WantedGameMode) // restart is default
nextState = STATE_GAMEINIT;
stateParam = 0;
switch (WantedGameMode)
{
case GAMEMODE_NORMAL:
case GAMEMODE_QUIT:
case GAMEMODE_DEMO:
{ {
case GAMEMODE_NORMAL: FadeScreen(255);
case GAMEMODE_QUIT: nextState = STATE_INITFRONTEND;
case GAMEMODE_DEMO: break;
{
FadeScreen(255);
quit = 1;
break;
}
case GAMEMODE_RESTART:
{
FadeScreen(255);
NoPlayerControl = 0;
quick_replay = 0;
AutoDirect = 0;
WantedGameMode = GAMEMODE_NORMAL;
NewLevel = 0;
GetRandomChase();
break;
}
case GAMEMODE_REPLAY:
case GAMEMODE_DIRECTOR:
{
if (CurrentGameMode < GAMEMODE_NEXTMISSION)
FadeScreen(255);
NoPlayerControl = 1;
AutoDirect = (WantedGameMode == GAMEMODE_REPLAY);
quick_replay = (WantedGameMode == GAMEMODE_REPLAY);
NewLevel = 0;
break;
}
case GAMEMODE_NEXTMISSION:
{
MissionStartData = MissionEndData;
gHaveStoredData = 1;
FadeScreen(255);
quit = 1;
NoPlayerControl = 0;
quick_replay = 0;
AutoDirect = 0;
}
} }
case GAMEMODE_RESTART:
{
FadeScreen(255);
CurrentGameMode = WantedGameMode; NoPlayerControl = 0;
} while (!quit); quick_replay = 0;
AutoDirect = 0;
WantedGameMode = GAMEMODE_NORMAL;
NewLevel = 0;
lead_car = 0; GetRandomChase();
NoPlayerControl = 0;
SetDispMask(0);
EnableDisplay();
ClearImage(&rect, 0, 0, 0); break;
}
case GAMEMODE_REPLAY:
case GAMEMODE_DIRECTOR:
{
if (CurrentGameMode < GAMEMODE_NEXTMISSION)
FadeScreen(255);
DrawSync(0); NoPlayerControl = 1;
SetDispMask(1); AutoDirect = (WantedGameMode == GAMEMODE_REPLAY);
quick_replay = (WantedGameMode == GAMEMODE_REPLAY);
NewLevel = 0;
break;
}
case GAMEMODE_NEXTMISSION:
{
MissionStartData = MissionEndData;
gHaveStoredData = 1;
FadeScreen(255);
if(GameType == GAME_MISSION)
{
nextState = STATE_LADDER;
stateParam = 2; // don't do recap
}
else
nextState = STATE_INITFRONTEND;
NoPlayerControl = 0;
quick_replay = 0;
AutoDirect = 0;
}
}
CurrentGameMode = WantedGameMode;
SetState(nextState, (void*)stateParam);
if(nextState == STATE_INITFRONTEND)
{
RestoreGameVars();
lead_car = 0;
NoPlayerControl = 0;
SetDispMask(0);
EnableDisplay();
setRECT(&rect, 0, 0, 512, 512);
ClearImage(&rect, 0, 0, 0);
DrawSync(0);
SetDispMask(1);
}
} }
// [D] [T] // [D] [T]

View File

@ -33,9 +33,13 @@ extern int quick_replay;
extern MISSION_DATA MissionStartData; extern MISSION_DATA MissionStartData;
extern MISSION_DATA MissionEndData; extern MISSION_DATA MissionEndData;
extern void GameStart(); // 0x00052A28 extern void State_InitFrontEnd(void* param);
extern void State_GameStart(void* param); // 0x00052A28
extern void State_GameComplete(void* param);
extern void State_MissionLadder(void* param);
extern void State_LaunchGame(void* param); // 0x000532B8
extern void StartRender(int renderNum); // 0x000536B0 extern void State_FMVPlay(void* param); // 0x000536B0
extern void ReInitFrontend(); // 0x00052E98 extern void ReInitFrontend(); // 0x00052E98
@ -45,8 +49,6 @@ extern void GetRandomChase(); // 0x000535D8
extern int FindPrevMissionFromLadderPos(int pos); // 0x000536D8 extern int FindPrevMissionFromLadderPos(int pos); // 0x000536D8
extern void LaunchGame(); // 0x000532B8
extern int FindMissionLadderPos(int mission); // 0x00053740 extern int FindMissionLadderPos(int mission); // 0x00053740

View File

@ -402,7 +402,8 @@ void GlobalTimeStep(void)
{ {
RKstep = 0; RKstep = 0;
for (RKstep = 0; RKstep < 2; RKstep++) { for (RKstep = 0; RKstep < 2; RKstep++)
{
for (i = 0; i < num_active_cars; i++) for (i = 0; i < num_active_cars; i++)
{ {
cp = active_car_list[i]; cp = active_car_list[i];

View File

@ -429,13 +429,13 @@ void DrawFadePoly(void)
// [D] [T] // [D] [T]
void DisplayMissionTitle(void) void DisplayMissionTitle(void)
{ {
if (bWantFade != 0 && CameraCnt == 1) if (bWantFade && CameraCnt == 1)
{ {
bWantFade = 0; bWantFade = 0;
bMissionTitleFade = CameraCnt; bMissionTitleFade = CameraCnt;
} }
if (bMissionTitleFade != 0 && pauseflag == 0) if (bMissionTitleFade && !pauseflag)
{ {
fadeVal -= 6; fadeVal -= 6;

View File

@ -68,6 +68,7 @@
#include "STRINGS.H" #include "STRINGS.H"
#include "INLINE_C.H" #include "INLINE_C.H"
#include "state.h"
int levelstartpos[8][4] = { int levelstartpos[8][4] = {
{ 4785, -1024, -223340, 0}, { 4785, -1024, -223340, 0},
@ -468,7 +469,7 @@ void LoadGameLevel(void)
} }
// [D] [T] // [D] [T]
void GameInit(void) void State_GameInit(void* param)
{ {
STREAM_SOURCE* plStart; STREAM_SOURCE* plStart;
int i, musicType; int i, musicType;
@ -653,8 +654,7 @@ void GameInit(void)
InitDrivingGames(); InitDrivingGames();
InitThrownBombs(); InitThrownBombs();
i = 0; for (i = 0; i < numPlayersToCreate; i++)
while (i < numPlayersToCreate)
{ {
plStart = PlayerStartInfo[i]; plStart = PlayerStartInfo[i];
padid = -i; padid = -i;
@ -680,8 +680,6 @@ void GameInit(void)
car_data[i].ap.needsDenting = 1; car_data[i].ap.needsDenting = 1;
} }
i++;
} }
// FIXME: need to change streams properly // FIXME: need to change streams properly
@ -744,11 +742,8 @@ void GameInit(void)
if (gTimeOfDay == 2) if (gTimeOfDay == 2)
{ {
i = 0; for ( i = 0; i < MAX_CARS; i++)
do {
lightsOnDelay[i] = (i * 11); lightsOnDelay[i] = (i * 11);
i++;
} while (i < MAX_CARS);
} }
tracking_car = 1; tracking_car = 1;
@ -796,6 +791,9 @@ void GameInit(void)
} }
xa_timeout = 0; xa_timeout = 0;
// switch to STATE_GAMELOOP
SetState(STATE_GAMELOOP);
} }
extern short paddp; extern short paddp;
@ -1291,7 +1289,7 @@ void StepSim(void)
} }
// [D] [T] // [D] [T]
void GameLoop(void) void State_GameLoop(void* param)
{ {
int i; int i;
static POLY_FT3 buffer[2]; static POLY_FT3 buffer[2];
@ -1362,6 +1360,7 @@ void GameLoop(void)
DrawPrim(null); DrawPrim(null);
DrawSync(0); DrawSync(0);
} }
CheckForPause(); CheckForPause();
} }
@ -1375,11 +1374,14 @@ void GameLoop(void)
StopAllChannels(); StopAllChannels();
FreeXM(); FreeXM();
if (XAPrepared() != 0) if (XAPrepared())
{ {
StopXA(); StopXA();
UnprepareXA(); UnprepareXA();
} }
// switch to STATE_GAMECOMPLETE
SetState(STATE_GAMECOMPLETE);
} }
// [D] [T] // [D] [T]
@ -1772,6 +1774,8 @@ void SsSetSerialVol(short s_num, short voll, short volr)
SpuSetCommonAttr(&attr); SpuSetCommonAttr(&attr);
} }
//-------------------------------------------
#ifndef PSX #ifndef PSX
#include <SDL_messagebox.h> #include <SDL_messagebox.h>
void PrintCommandLineArguments() void PrintCommandLineArguments()
@ -1909,11 +1913,11 @@ int redriver2_main(int argc, char** argv)
// initializes sound system // initializes sound system
LoadSoundBankDynamic(NULL, 0, 0); LoadSoundBankDynamic(NULL, 0, 0);
// load frontend bank
LoadBankFromLump(1, 0);
InitialiseScoreTables(); InitialiseScoreTables();
// by default go to frontend
SetState(STATE_INITFRONTEND, (void*)1);
#ifndef PSX #ifndef PSX
LoadCurrentProfile(); LoadCurrentProfile();
@ -2007,7 +2011,7 @@ int redriver2_main(int argc, char** argv)
i++; i++;
GameType = GAME_TAKEADRIVE; GameType = GAME_TAKEADRIVE;
LaunchGame(); SetState(STATE_GAMELAUNCH);
} }
#endif // _DEBUG_OPTIONS #endif // _DEBUG_OPTIONS
else if (!strcmp(argv[i], "-replay")) else if (!strcmp(argv[i], "-replay"))
@ -2041,10 +2045,8 @@ int redriver2_main(int argc, char** argv)
{ {
CurrentGameMode = GAMEMODE_REPLAY; CurrentGameMode = GAMEMODE_REPLAY;
gLoadedReplay = 1; gLoadedReplay = 1;
LaunchGame(); SetState(STATE_GAMELAUNCH);
gLoadedReplay = 0;
} }
else else
{ {
@ -2081,8 +2083,7 @@ int redriver2_main(int argc, char** argv)
} }
#endif // PSX #endif // PSX
// now run the frontend DoStateLoop();
DoFrontEnd();
#ifndef PSX #ifndef PSX
SaveCurrentProfile(); SaveCurrentProfile();
@ -2104,7 +2105,7 @@ void FadeScreen(int end_value)
do { do {
RenderGame(); RenderGame();
} while (FadingScreen != 0); } while (FadingScreen);
DrawSync(0); DrawSync(0);
SetDispMask(0); SetDispMask(0);

View File

@ -30,10 +30,12 @@ extern int ObjectDrawnCounter;
extern int Havana3DLevelDraw; extern int Havana3DLevelDraw;
extern void SsSetSerialVol(short s_num, short voll, short volr); // TEMPORARY extern void SsSetSerialVol(short s_num, short voll, short volr); // TEMPORARY
extern void GameInit(); // 0x00059330
extern void State_GameInit(void* param); // 0x00059330
extern void State_GameLoop(void* param); // 0x0005A8DC
extern void StepSim(); // 0x00059A44 extern void StepSim(); // 0x00059A44
extern void GameLoop(); // 0x0005A8DC
extern void StepGame(); // 0x0005AB28 extern void StepGame(); // 0x0005AB28
extern void DrawGame(); // 0x0005C458 extern void DrawGame(); // 0x0005C458

View File

@ -10,10 +10,12 @@
#include "director.h" #include "director.h"
#include "camera.h" #include "camera.h"
#include "civ_ai.h" #include "civ_ai.h"
#include "state.h"
#include "STRINGS.H" #include "STRINGS.H"
#include "RAND.H" #include "RAND.H"
char AnalogueUnpack[16] = { char AnalogueUnpack[16] = {
0, -51, -63, -75, -87, -99, -111, -123, 0, -51, -63, -75, -87, -99, -111, -123,
0, 51, 63, 75, 87, 99, 111, 123 0, 51, 63, 75, 87, 99, 111, 123
@ -363,10 +365,7 @@ void LoadCutsceneRecorder(char* configFilename)
CameraCnt = 0; CameraCnt = 0;
ini_free(config); ini_free(config);
LaunchGame(); SetState(STATE_GAMELAUNCH);
gLoadedReplay = 0;
gCutsceneAsReplay = 0;
} }
#endif // CUTSCENE_RECORDER #endif // CUTSCENE_RECORDER

View File

@ -0,0 +1,45 @@
#include "driver2.h"
#include "state.h"
#include "main.h"
#include "glaunch.h"
#include "Frontend/FEmain.h"
//-------------------------------------------
typedef void (*StateFn)(void*);
StateFn gStates[] = {
NULL,
State_InitFrontEnd,
State_FrontEnd,
State_GameStart,
State_LaunchGame,
State_MissionLadder,
State_GameInit,
State_GameLoop,
State_GameComplete,
State_FMVPlay,
};
GameStates gCurrentState = STATE_NONE;
void* gCurrentStateParam = NULL;
// the main loop of the game
void DoStateLoop()
{
do
{
StateFn stateFn = gStates[gCurrentState];
if (!stateFn)
break;
stateFn(gCurrentStateParam);
} while (true);
}
void SetState(GameStates newState, void* param)
{
gCurrentState = newState;
gCurrentStateParam = param;
}

View File

@ -0,0 +1,19 @@
enum GameStates
{
STATE_NONE = 0,
STATE_INITFRONTEND,
STATE_FRONTEND,
STATE_GAMESTART,
STATE_GAMELAUNCH, // launch single game
STATE_LADDER, // launch a mission ladder
STATE_GAMEINIT,
STATE_GAMELOOP,
STATE_GAMECOMPLETE,
STATE_FMVPLAY,
};
// changes the state
extern void SetState(GameStates newState, void* param = NULL);
// does the state loop
extern void DoStateLoop();

View File

@ -20,9 +20,10 @@
#include "C/debris.h" #include "C/debris.h"
#include "C/E3stuff.h" #include "C/E3stuff.h"
#include "C/fmvplay.h" #include "C/fmvplay.h"
#include "C/gamesnd.h"
#include "C/scores.h" #include "C/scores.h"
#include "C/loadsave.h" #include "C/loadsave.h"
#include "C/state.h"
struct PSXBUTTON struct PSXBUTTON
@ -499,11 +500,11 @@ void SetVariable(int var)
{ {
StoredGameType = GameType; StoredGameType = GameType;
GameType = GAME_LOADEDREPLAY; GameType = GAME_LOADEDREPLAY;
GameStart(); SetState(STATE_GAMESTART);
} }
else else
{ {
ReInitFrontend(); SetState(STATE_INITFRONTEND);
} }
} }
else else
@ -511,7 +512,7 @@ void SetVariable(int var)
// [A] load configuration // [A] load configuration
LoadCurrentProfile(); LoadCurrentProfile();
ReInitFrontend(); SetState(STATE_INITFRONTEND);
SetMasterVolume(gMasterVolume); SetMasterVolume(gMasterVolume);
SetXMVolume(gMusicVolume); SetXMVolume(gMusicVolume);
} }
@ -532,7 +533,7 @@ void SetVariable(int var)
if(LoadCurrentGame()) if(LoadCurrentGame())
{ {
GameType = GAME_CONTINUEMISSION; GameType = GAME_CONTINUEMISSION;
GameStart(); SetState(STATE_GAMESTART);
} }
} }
@ -1388,7 +1389,7 @@ int HandleKeyPress(void)
ScreenNames[ScreenDepth] = pCurrButton->Name; ScreenNames[ScreenDepth] = pCurrButton->Name;
GameStart(); SetState(STATE_GAMESTART);
} }
break; break;
case 4: case 4:
@ -1605,7 +1606,7 @@ void SetFEDrawMode(void)
PutDrawEnv(&current->draw); PutDrawEnv(&current->draw);
} }
// [A] - was inlined in DoFrontEnd // [A] - was inlined in State_FrontEnd
void InitFrontend(void) void InitFrontend(void)
{ {
FEInitCdIcon(); FEInitCdIcon();
@ -1622,10 +1623,13 @@ void InitFrontend(void)
SetupBackgroundPolys(); SetupBackgroundPolys();
SetupScreenSprts(&PsxScreens[0]); SetupScreenSprts(&PsxScreens[0]);
// load frontend bank
LoadBankFromLump(SOUND_BANK_SFX, 0);
} }
// [A] - was inlined in DoFrontEnd // [A] - was inlined in State_FrontEnd
void InitDisplay(void) void InitFrontendDisplay(void)
{ {
SetDispMask(0); SetDispMask(0);
ResetGraph(0); ResetGraph(0);
@ -1653,73 +1657,73 @@ void InitDisplay(void)
} }
// [D] [T] // [D] [T]
void DoFrontEnd(void) void State_FrontEnd(void* param)
{ {
InitFrontend(); PadChecks();
InitDisplay();
do if (currPlayer == 2)
{ {
PadChecks(); if (Pads[1].type < 2)
if (currPlayer == 2) {
if (Pads[1].type < 2) {
feNewPad = ((feNewPad & 0x10) != 0) ? 0x10 : 0;
}
else {
feNewPad = Pads[1].mapnew;
}
}
if (HandleKeyPress())
{ {
if (pNewScreen != NULL) feNewPad = ((feNewPad & 0x10) != 0) ? 0x10 : 0;
{
SetupScreenSprts(pNewScreen);
bRedrawFrontend = 1;
}
} }
else
{
feNewPad = Pads[1].mapnew;
}
}
if (HandleKeyPress())
{
if (pNewScreen != NULL)
{
SetupScreenSprts(pNewScreen);
bRedrawFrontend = 1;
}
}
#ifndef PSX #ifndef PSX
DrawScreen(pCurrScreen); DrawScreen(pCurrScreen);
#else #else
if (bRedrawFrontend) if (bRedrawFrontend)
{ {
DrawScreen(pCurrScreen); DrawScreen(pCurrScreen);
EndFrame(); EndFrame();
NewSelection(0); NewSelection(0);
bRedrawFrontend = 0; bRedrawFrontend = 0;
} }
#endif #endif
if ((VSync(-1) - idle_timer) > 1800) if ((VSync(-1) - idle_timer) > 1800)
{
if (ScreenDepth == 0)
{ {
if (ScreenDepth == 0) GameType = GAME_IDLEDEMO;
{
GameType = GAME_IDLEDEMO;
gCurrentMissionNumber = gIdleReplay + 400; gCurrentMissionNumber = gIdleReplay + 400;
if (++gIdleReplay == 4) if (++gIdleReplay == 4)
gIdleReplay = 0; gIdleReplay = 0;
pScreenStack[0] = pCurrScreen; pScreenStack[0] = pCurrScreen;
pButtonStack[0] = pCurrButton; pButtonStack[0] = pCurrButton;
ScreenNames[0] = pCurrButton->Name; ScreenNames[0] = pCurrButton->Name;
GameStart(); SetState(STATE_GAMESTART);
pCurrScreen = pScreenStack[0]; pCurrScreen = pScreenStack[0];
bRedrawFrontend = 1; bRedrawFrontend = 1;
ScreenDepth = 0; // fail-safe? ScreenDepth = 0; // fail-safe?
}
idle_timer = VSync(-1);
} }
} while (bQuitToSystem != 2);
idle_timer = VSync(-1);
}
if(bQuitToSystem == 2)
SetState(STATE_NONE);
} }
// [D] [T] // [D] [T]
@ -2281,7 +2285,8 @@ int MissionSelectScreen(int bSetup)
LoadBackgroundFile("DATA\\CITYBACK.RAW"); LoadBackgroundFile("DATA\\CITYBACK.RAW");
} }
if (feVariableSave[0] != -1) { if (feVariableSave[0] != -1)
{
currMission = feVariableSave[0]; currMission = feVariableSave[0];
currSelIndex = feVariableSave[1]; currSelIndex = feVariableSave[1];
currCity = feVariableSave[2]; currCity = feVariableSave[2];
@ -2675,9 +2680,9 @@ int CutSceneSelectScreen(int bSetup)
feVariableSave[0] = cutSelection; feVariableSave[0] = cutSelection;
ScreenNames[ScreenDepth] = pCurrButton->Name; ScreenNames[ScreenDepth] = pCurrButton->Name;
StartRender(feVariableSave[0] + CutAmountsTotal[feVariableSave[1]] + 1); SetState(STATE_FMVPLAY, (void*)(feVariableSave[0] + CutAmountsTotal[feVariableSave[1]] + 1));
return 0; return 1;
} }
if (cutSelection == CutAmounts[currCity + 1] - 1 || cutUnlock[gFurthestMission] <= cutSelection + CutAmountsTotal[currCity] + 1) if (cutSelection == CutAmounts[currCity + 1] - 1 || cutUnlock[gFurthestMission] <= cutSelection + CutAmountsTotal[currCity] + 1)
@ -2818,11 +2823,7 @@ int CutSceneCitySelectScreen(int bSetup)
lastCity = -1; lastCity = -1;
lastCutCity = GameLevel; lastCutCity = GameLevel;
if (GameLevel != 4) if (GameLevel == 4)
{
lastCity = -1;
}
else
{ {
bReturnToMain = 0; bReturnToMain = 0;
@ -2833,7 +2834,12 @@ int CutSceneCitySelectScreen(int bSetup)
feVariableSave[0] = currCity; feVariableSave[0] = currCity;
StartRender(0x60); SetState(STATE_FMVPLAY, (void*)96);
return 1;
}
else
{
lastCity = -1;
} }
return 0; return 0;
@ -3764,11 +3770,11 @@ int UserReplaySelectScreen(int bSetup)
{ {
StoredGameType = GameType; StoredGameType = GameType;
GameType = GAME_LOADEDREPLAY; GameType = GAME_LOADEDREPLAY;
GameStart(); SetState(STATE_GAMESTART);
} }
else else
{ {
ReInitFrontend(); SetState(STATE_INITFRONTEND);
} }
} }
} }
@ -3900,7 +3906,8 @@ int DemoScreen(int bSetup)
gWantNight = 0; gWantNight = 0;
gSubGameNumber = 0; gSubGameNumber = 0;
GameStart(); SetState(STATE_GAMESTART);
return 0; return 0;
} }

View File

@ -4,7 +4,11 @@
extern int gInFrontend; extern int gInFrontend;
extern int bRedrawFrontend; extern int bRedrawFrontend;
extern void DoFrontEnd(); // 0x001C296C extern void InitFrontendDisplay();
extern void InitFrontend();
extern void State_FrontEnd(void* param); // 0x001C296C
extern void SetFEDrawMode(); extern void SetFEDrawMode();
extern void LoadFrontendScreens(int full); extern void LoadFrontendScreens(int full);
extern void ReInitScreens(); extern void ReInitScreens();