From af44163a4a05d39ae8662b9172fb3b518b6545e2 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Thu, 3 Dec 2020 15:56:49 -0800 Subject: [PATCH] Support for additional spawn points in Take-A-Ride. - Added REPLAY_EXTRA_DATA to store necessary information - Setup macros for spawn point stuff so PSX version isn't affected - Fixed 'Player 2' text bug - Custom location selected using L1/R1 on car select screen --- src_rebuild/GAME/C/GLAUNCH.C | 1 + src_rebuild/GAME/C/MAIN.C | 218 +++++++++++++++++++++++++++-- src_rebuild/GAME/C/MAIN.H | 4 + src_rebuild/GAME/C/MISSION.C | 30 ++-- src_rebuild/GAME/C/MISSION.H | 1 + src_rebuild/GAME/C/REPLAYS.C | 50 +++++++ src_rebuild/GAME/DR2LIMITS.H | 7 + src_rebuild/GAME/DR2TYPES.H | 17 +++ src_rebuild/GAME/FRONTEND/FEMAIN.C | 54 ++++++- 9 files changed, 352 insertions(+), 30 deletions(-) diff --git a/src_rebuild/GAME/C/GLAUNCH.C b/src_rebuild/GAME/C/GLAUNCH.C index a4755506..d5c04a5c 100644 --- a/src_rebuild/GAME/C/GLAUNCH.C +++ b/src_rebuild/GAME/C/GLAUNCH.C @@ -307,6 +307,7 @@ void GameStart(void) // [A] wantedWeather = -1; wantedTimeOfDay = -1; + wantedStartPos = -1; gHaveStoredData = 0; diff --git a/src_rebuild/GAME/C/MAIN.C b/src_rebuild/GAME/C/MAIN.C index 6ae46d24..e6feebbc 100644 --- a/src_rebuild/GAME/C/MAIN.C +++ b/src_rebuild/GAME/C/MAIN.C @@ -72,16 +72,197 @@ int scr_z = 0; -int levelstartpos[8][4] = { - { 0x12B1, 0xFFFFFC00, 0xFFFC9794, 0}, - { 0xFFFC74AC, 0x800, 0xFFFC6961, 0}, - { 0x383CB, 0xFFFFFC00, 0xABE1E, 0}, - { 0x165EF, 0xFFFFFC00, 0xFFFAB3D9, 0}, - { 0x24548, 0x1813, 0xFFFE4A80, 0}, - { 0xFFFD67F0, 0x1813, 0x58228, 0}, - { 0xFFFFD6FC, 0xFFFFE7ED, 0xFFFFA980, 0}, - { 0xFFFFDCDD, 0xFFFFE7ED, 0xF8A7, 0}, +#ifndef PSX +char *levelstartnames[8][NUM_START_POINTS] = { + // + // Chicago + // + { + "Downtown", + "Greektown", + "Chinatown", + "Safehouse", + }, + // + // Havana + // + { + NULL, + NULL, + NULL, + NULL, + }, + // + // Vegas + // + { + NULL, + NULL, + NULL, + NULL, + }, + // + // Rio + // + { + NULL, + NULL, + NULL, + NULL, + }, + // + // ??? + // + { + NULL, + NULL, + NULL, + NULL, + }, + // + // ??? + // + { + NULL, + NULL, + NULL, + NULL, + }, + // + // ??? + // + { + NULL, + NULL, + NULL, + NULL, + }, + // + // ??? + // + { + NULL, + NULL, + NULL, + NULL, + }, }; +#endif + +#ifndef PSX +#define BEGIN_SPAWN_POINTS { +#define END_SPAWN_POINTS }, +#define SPAWN_POINT(...) { __VA_ARGS__ }, +#define DEFAULT_SPAWN(...) SPAWN_POINT(__VA_ARGS__) +#else +#define BEGIN_SPAWN_POINTS +#define END_SPAWN_POINTS +#define SPAWN_POINT(...) +#define DEFAULT_SPAWN(...) { __VA_ARGS__ }, +#endif +LONGVECTOR levelstartpos[8][NUM_START_POINTS + 1] = { + // + // Chicago + // + BEGIN_SPAWN_POINTS + //SPAWN_POINT(-64840, -1024, -161500, 0) // Downtown car park + //SPAWN_POINT(6216, 0, -222456, 0) // Grant Park (default) + + SPAWN_POINT(-95500, 1024, -40225, 0) // Downtown + SPAWN_POINT(-299895, 1024, -122195, 0) // Greektown + SPAWN_POINT(-95980, 0, -501540, 0) // Chinatown + SPAWN_POINT(16800, -1144, 142075, 0) // Safehouse + + DEFAULT_SPAWN(4785, -1024, -223340, 0) + END_SPAWN_POINTS + // + // Havana + // + BEGIN_SPAWN_POINTS + SPAWN_POINT(-232276, 2048, -235167, 0) // TODO + SPAWN_POINT(-232276, 2048, -235167, 0) // TODO + SPAWN_POINT(-232276, 2048, -235167, 0) // TODO + SPAWN_POINT(-232276, 2048, -235167, 0) // TODO + + DEFAULT_SPAWN(-232276, 2048, -235167, 0) + END_SPAWN_POINTS + // + // Vegas + // + BEGIN_SPAWN_POINTS + SPAWN_POINT(230347, -1024, 704030, 0) // TODO + SPAWN_POINT(230347, -1024, 704030, 0) // TODO + SPAWN_POINT(230347, -1024, 704030, 0) // TODO + SPAWN_POINT(230347, -1024, 704030, 0) // TODO + + DEFAULT_SPAWN(230347, -1024, 704030, 0) + END_SPAWN_POINTS + // + // Rio + // + BEGIN_SPAWN_POINTS + SPAWN_POINT(91631, -1024, -347175, 0) // TODO + SPAWN_POINT(91631, -1024, -347175, 0) // TODO + SPAWN_POINT(91631, -1024, -347175, 0) // TODO + SPAWN_POINT(91631, -1024, -347175, 0) // TODO + + DEFAULT_SPAWN(91631, -1024, -347175, 0) + END_SPAWN_POINTS + // + // ??? + // + BEGIN_SPAWN_POINTS + SPAWN_POINT(148808, 6163, -112000, 0) // TODO + SPAWN_POINT(148808, 6163, -112000, 0) // TODO + SPAWN_POINT(148808, 6163, -112000, 0) // TODO + SPAWN_POINT(148808, 6163, -112000, 0) // TODO + + DEFAULT_SPAWN(148808, 6163, -112000, 0) + END_SPAWN_POINTS + // + // ??? + // + BEGIN_SPAWN_POINTS + SPAWN_POINT(-170000, 6163, 361000, 0) // TODO + SPAWN_POINT(-170000, 6163, 361000, 0) // TODO + SPAWN_POINT(-170000, 6163, 361000, 0) // TODO + SPAWN_POINT(-170000, 6163, 361000, 0) // TODO + + DEFAULT_SPAWN(-170000, 6163, 361000, 0) + END_SPAWN_POINTS + // + // ??? + // + BEGIN_SPAWN_POINTS + SPAWN_POINT(-10500, -6163, -22144, 0) // TODO + SPAWN_POINT(-10500, -6163, -22144, 0) // TODO + SPAWN_POINT(-10500, -6163, -22144, 0) // TODO + SPAWN_POINT(-10500, -6163, -22144, 0) // TODO + + DEFAULT_SPAWN(-10500, -6163, -22144, 0) + END_SPAWN_POINTS + // + // ??? + // + BEGIN_SPAWN_POINTS + SPAWN_POINT(-8995, -6163, 63655, 0) // TODO + SPAWN_POINT(-8995, -6163, 63655, 0) // TODO + SPAWN_POINT(-8995, -6163, 63655, 0) // TODO + SPAWN_POINT(-8995, -6163, 63655, 0) // TODO + + DEFAULT_SPAWN(-8995, -6163, 63655, 0) + END_SPAWN_POINTS +}; + +#ifndef PSX +char * GetLevelStartName(int level, int startpos) +{ + if (startpos == -1) + return "Default"; + + return (startpos < NUM_START_POINTS) ? levelstartnames[level][startpos] : NULL; +} +#endif XZPAIR gStartPos = { 0 }; @@ -3262,6 +3443,13 @@ void InitGameVariables(void) ClearMem((char*)&lightsOnDelay, sizeof(lightsOnDelay)); + int startpos = 0; + + if (NumPlayers == 2) + startpos = NUM_START_POINTS; // fallback to default + else if (wantedStartPos != -1) + startpos = wantedStartPos; + PlayerStartInfo[0] = &ReplayStreams[0].SourceType; #ifdef CUTSCENE_RECORDER @@ -3277,11 +3465,11 @@ void InitGameVariables(void) PlayerStartInfo[0]->controlType = CONTROL_TYPE_PLAYER; PlayerStartInfo[0]->flags = 0; - PlayerStartInfo[0]->rotation = levelstartpos[GameLevel][1]; + PlayerStartInfo[0]->rotation = levelstartpos[GameLevel][startpos][1]; PlayerStartInfo[0]->position.vy = 0; - PlayerStartInfo[0]->position.vx = levelstartpos[GameLevel][0]; - PlayerStartInfo[0]->position.vz = levelstartpos[GameLevel][2]; + PlayerStartInfo[0]->position.vx = levelstartpos[GameLevel][startpos][0]; + PlayerStartInfo[0]->position.vz = levelstartpos[GameLevel][startpos][2]; numPlayersToCreate = 1; @@ -3296,11 +3484,11 @@ void InitGameVariables(void) PlayerStartInfo[1]->controlType = CONTROL_TYPE_PLAYER; PlayerStartInfo[1]->flags = 0; - PlayerStartInfo[1]->rotation = levelstartpos[GameLevel][1]; + PlayerStartInfo[1]->rotation = levelstartpos[GameLevel][startpos][1]; PlayerStartInfo[1]->position.vy = 0; - PlayerStartInfo[1]->position.vx = levelstartpos[GameLevel][0] + 600; - PlayerStartInfo[1]->position.vz = levelstartpos[GameLevel][2]; + PlayerStartInfo[1]->position.vx = levelstartpos[GameLevel][startpos][0] + 600; + PlayerStartInfo[1]->position.vz = levelstartpos[GameLevel][startpos][2]; numPlayersToCreate = NumPlayers; } diff --git a/src_rebuild/GAME/C/MAIN.H b/src_rebuild/GAME/C/MAIN.H index c25eef79..41583a73 100644 --- a/src_rebuild/GAME/C/MAIN.H +++ b/src_rebuild/GAME/C/MAIN.H @@ -29,6 +29,10 @@ extern int DawnCount; extern int ObjectDrawnValue; extern int ObjectDrawnCounter; +#ifndef PSX +extern char * GetLevelStartName(int level, int startpos); +#endif + extern void SsSetSerialVol(short s_num, short voll, short volr); // TEMPORARY typedef void(*occlFunc)(int *comp_val); diff --git a/src_rebuild/GAME/C/MISSION.C b/src_rebuild/GAME/C/MISSION.C index bd30c11a..c4bf1792 100644 --- a/src_rebuild/GAME/C/MISSION.C +++ b/src_rebuild/GAME/C/MISSION.C @@ -193,6 +193,7 @@ int wantedCar[2] = { -1, -1 }; // [A] int wantedTimeOfDay = -1; int wantedWeather = -1; +int wantedStartPos = -1; MS_TARGET* MissionTargets; unsigned long* MissionScript; @@ -502,11 +503,14 @@ void LoadMission(int missionnum) if (gCutsceneAsReplay == 0) #endif { - PlayerStartInfo[0]->rotation = MissionHeader->playerStartRotation; + if (wantedStartPos == -1) + { + PlayerStartInfo[0]->rotation = MissionHeader->playerStartRotation; - PlayerStartInfo[0]->position.vx = MissionHeader->playerStartPosition.x; - PlayerStartInfo[0]->position.vz = MissionHeader->playerStartPosition.y; - + PlayerStartInfo[0]->position.vx = MissionHeader->playerStartPosition.x; + PlayerStartInfo[0]->position.vz = MissionHeader->playerStartPosition.y; + } + #ifdef DEBUG_OPTIONS if(gStartPos.x != 0 && gStartPos.z != 0) { @@ -3592,15 +3596,15 @@ void PreProcessTargets(void) { PlayerStartInfo[1] = &ReplayStreams[1].SourceType; - ReplayStreams[1].SourceType.type = 1; - ReplayStreams[1].SourceType.position.vx = target->data[3]; - ReplayStreams[1].SourceType.position.vy = 0; - ReplayStreams[1].SourceType.position.vz = target->data[4]; - ReplayStreams[1].SourceType.rotation = target->data[5]; - ReplayStreams[1].SourceType.model = target->data[7]; - ReplayStreams[1].SourceType.palette = target->data[8]; - ReplayStreams[1].SourceType.controlType = CONTROL_TYPE_PLAYER; - ReplayStreams[1].SourceType.flags = 0; + PlayerStartInfo[1]->type = 1; + PlayerStartInfo[1]->position.vx = target->data[3]; + PlayerStartInfo[1]->position.vy = 0; + PlayerStartInfo[1]->position.vz = target->data[4]; + PlayerStartInfo[1]->rotation = target->data[5]; + PlayerStartInfo[1]->model = target->data[7]; + PlayerStartInfo[1]->palette = target->data[8]; + PlayerStartInfo[1]->controlType = CONTROL_TYPE_PLAYER; + PlayerStartInfo[1]->flags = 0; if (target->data[9] & 3) target->data[11] = -1; diff --git a/src_rebuild/GAME/C/MISSION.H b/src_rebuild/GAME/C/MISSION.H index c472c776..b525d241 100644 --- a/src_rebuild/GAME/C/MISSION.H +++ b/src_rebuild/GAME/C/MISSION.H @@ -65,6 +65,7 @@ extern MR_MISSION Mission; extern int wantedCar[2]; extern int wantedTimeOfDay; extern int wantedWeather; +extern int wantedStartPos; extern int multiplayerregions[4]; extern int MaxPlayerDamage[2]; diff --git a/src_rebuild/GAME/C/REPLAYS.C b/src_rebuild/GAME/C/REPLAYS.C index ed00f04e..2ea28cc5 100644 --- a/src_rebuild/GAME/C/REPLAYS.C +++ b/src_rebuild/GAME/C/REPLAYS.C @@ -249,7 +249,47 @@ int SaveReplayToBuffer(char *buffer) header->HaveStoredData = 0x91827364; // -0x6e7d8c9c memcpy(pt, &MissionStartData, sizeof(MISSION_DATA)); } +#ifndef PSX + REPLAY_EXTRA_DATA extraData; + int extras = 0; + // set default values (-1 = disabled) + // if no overrides are set, the replay will contain junk data instead + memset(&extraData, -1, sizeof(REPLAY_EXTRA_DATA)); + + if (wantedTimeOfDay != -1) + { + extraData.wantedTimeOfDay = wantedTimeOfDay; + extras++; + } + + if (wantedWeather != -1) + { + extraData.wantedWeather = wantedWeather; + extras++; + } + + if (wantedStartPos != -1) + { + extraData.wantedStartPos = wantedStartPos; + extras++; + } + + // + // TODO: max civ cars, max cops? + // + + if (extras > 0) + { + // copy our overrides over + memcpy(&header->extraData, &extraData, sizeof(REPLAY_EXTRA_DATA)); + + // inform the use of one or more overrides + // once set, the game uses ALL known overrides! + header->HaveExtraData = 0xF12EB12D; + } + +#endif #ifdef PSX return 0x3644; // size? #else @@ -592,6 +632,16 @@ int LoadReplayFromBuffer(char *buffer) memcpy(&MissionStartData, pt, sizeof(MISSION_DATA)); gHaveStoredData = 1; } +#ifndef PSX + if (header->HaveExtraData == 0xF12EB12D) + { + wantedStartPos = header->extraData.wantedStartPos; + wantedTimeOfDay = header->extraData.wantedTimeOfDay; + wantedWeather = header->extraData.wantedWeather; + // + // TODO: max civ cars, max cops? + } +#endif return 1; } diff --git a/src_rebuild/GAME/DR2LIMITS.H b/src_rebuild/GAME/DR2LIMITS.H index b720ef8e..90a7fe9a 100644 --- a/src_rebuild/GAME/DR2LIMITS.H +++ b/src_rebuild/GAME/DR2LIMITS.H @@ -41,5 +41,12 @@ #define MAX_SIREN_NOISES 2 #define MAX_CAR_NOISES 4 +// misc. limits +#ifndef PSX +#define NUM_START_POINTS 4 +#else +// no additional spawn points +#define NUM_START_POINTS 0 +#endif #endif // DRLIMITS_H \ No newline at end of file diff --git a/src_rebuild/GAME/DR2TYPES.H b/src_rebuild/GAME/DR2TYPES.H index c5e6e5ca..f89a7809 100644 --- a/src_rebuild/GAME/DR2TYPES.H +++ b/src_rebuild/GAME/DR2TYPES.H @@ -964,6 +964,16 @@ struct REPLAY_PARAMETER_BLOCK unsigned char weather; }; +struct REPLAY_EXTRA_DATA +{ + char wantedTimeOfDay; + char wantedWeather; + char wantedStartPos; + char reserved1; + + int reserved2[4]; +}; + struct REPLAY_SAVE_HEADER { unsigned long magic; @@ -980,7 +990,14 @@ struct REPLAY_SAVE_HEADER int wantedCar[2]; int MissionNumber; int HaveStoredData; +#ifndef PSX + // only valid if HaveExtraData is correct; + // otherwise, this is all junk data + REPLAY_EXTRA_DATA extraData; + int HaveExtraData; +#else int reserved2[6]; +#endif }; struct REPLAY_STREAM_HEADER diff --git a/src_rebuild/GAME/FRONTEND/FEMAIN.C b/src_rebuild/GAME/FRONTEND/FEMAIN.C index 607084e0..cb520967 100644 --- a/src_rebuild/GAME/FRONTEND/FEMAIN.C +++ b/src_rebuild/GAME/FRONTEND/FEMAIN.C @@ -20,6 +20,7 @@ #include "C/FMVPLAY.H" #include "C/SCORES.H" #include "C/LOADSAVE.H" +#include "C/MAIN.H" #include "MEMCARD/MAIN.H" @@ -1159,7 +1160,33 @@ void DisplayOnScreenText(void) FEPrintStringSized(ScreenTitle, 40, 400, 0xc00, 1, 64, 64, 64); } +#ifndef PSX + else if (bDoingCarSelect) + { + if (NumPlayers == 2) + { + if (currPlayer != 1) + FEPrintStringSized("Player 2", 400, 260, 0xc00, 0, 128, 128, 128); + } + else + { + char startPos[32]; + char *posname = GetLevelStartName(GameLevel, wantedStartPos); + if (posname != NULL) + { + sprintf(startPos, "Location: %s", posname); + } + else + { + sprintf(startPos, "Location: %d", wantedStartPos + 1); + } + + FEPrintStringSized(startPos, 400, 260, 0xc00, 0, 128, 128, 128); + } + } + else +#endif if (bInCutSelect) { text = CutSceneNames[cutSelection + CutAmountsTotal[currCity]]; @@ -2551,9 +2578,10 @@ int CarSelectScreen(int bSetup) } if (currPlayer != 1) { +#ifdef PSX if (NumPlayers == 2) FEPrintStringSized("Player 2", 400, 260, 0xc00, 0, 128, 128, 128); - +#endif return 0; } @@ -2587,6 +2615,9 @@ int CarSelectScreen(int bSetup) feVariableSave[2] = -1; feVariableSave[3] = -1; +#ifndef PSX + wantedStartPos = -1; +#endif lastCutCity = -1; currSelIndex = 1; @@ -2617,6 +2648,8 @@ int CarSelectScreen(int bSetup) LoadImage(&rect, (u_long*)(_frontend_buffer + currCity * 0x8000)); DrawSync(0); } + + wantedStartPos = -1; #endif currPlayer = 1; bDoingCarSelect = 0; @@ -2690,7 +2723,24 @@ int CarSelectScreen(int bSetup) { currSelIndex = pCurrButton->d - 1; } - +#ifndef PSX +#define LAST_START_POINT NUM_START_POINTS-1 + else if (NumPlayers == 1) + { + if (fePad & 0x4) + { + FESound(2); + if (--wantedStartPos < -1) + wantedStartPos = LAST_START_POINT; + } + else if (fePad & 0x8) + { + FESound(2); + if (++wantedStartPos > LAST_START_POINT) + wantedStartPos = -1; + } + } +#endif return 0; }