From d64948a2737ee5766088ef2ff59fbbd33a4d2afc Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Mon, 16 May 2022 14:12:52 -0700 Subject: [PATCH 01/78] [Frontend] Add helper macros/defines for user functions --- src_rebuild/Game/Frontend/FEmain.c | 174 ++++++++++++++--------------- 1 file changed, 85 insertions(+), 89 deletions(-) diff --git a/src_rebuild/Game/Frontend/FEmain.c b/src_rebuild/Game/Frontend/FEmain.c index 724fd9939..ddfc00b6f 100644 --- a/src_rebuild/Game/Frontend/FEmain.c +++ b/src_rebuild/Game/Frontend/FEmain.c @@ -119,6 +119,8 @@ int UserReplaySelectScreen(int bSetup); int TimeOfDaySelectScreen(int bSetup); int DemoScreen(int bSetup); int MiniCarsOnOffScreen(int bSetup); +#define FN_OK 0 +#define FN_DONE 1 screenFunc fpUserFunctions[] = { CentreScreen, @@ -147,6 +149,12 @@ screenFunc fpUserFunctions[] = { MiniCarsOnOffScreen }; +#define FE_CALLBACK(userFunctionNum) (fpUserFunctions[userFunctionNum - 1]) + +#define FE_INIT_SCREEN(screen) FE_CALLBACK(screen->userFunctionNum)(1) +#define FE_STEP_SCREEN(screen) FE_CALLBACK(screen->userFunctionNum)(0) + + char* gfxNames[4] = { "DATA\\CARS\\CCARS.RAW", "DATA\\CARS\\HCARS.RAW", @@ -651,7 +659,7 @@ void SetupScreenSprts(PSXSCREEN *pScr) pNewScreen = NULL; pCurrScreen = pScr; - if (pScr->userFunctionNum == 0 || pScr->userFunctionNum == 128) + if (pScr->userFunctionNum == 0 || pScr->userFunctionNum == 128 || FE_INIT_SCREEN(pScr) == FN_OK) { if (pNewButton != NULL) { @@ -661,19 +669,6 @@ void SetupScreenSprts(PSXSCREEN *pScr) else pCurrButton = pScr->buttons; } - else - { - if ((fpUserFunctions[pScr->userFunctionNum - 1])(1) == 0) - { - if (pNewButton != NULL) - { - pCurrButton = pNewButton; - pNewButton = NULL; - } - else - pCurrButton = pCurrScreen->buttons; - } - } } DR_MOVE In; @@ -1288,7 +1283,7 @@ int HandleKeyPress(void) if (pCurrScreen->userFunctionNum != 0) { // notify the user function first - if ((fpUserFunctions[pCurrScreen->userFunctionNum - 1])(0) != 0) + if (FE_STEP_SCREEN(pCurrScreen) != FN_OK) { // user function handled the key press feNewPad = 0; @@ -1323,7 +1318,7 @@ int HandleKeyPress(void) case BTN_START_GAME: if (NumPlayers == 2 && iScreenSelect == SCREEN_CAR && (currPlayer == 2)) { - (fpUserFunctions[pCurrScreen->userFunctionNum - 1])(1); + FE_INIT_SCREEN(pCurrScreen); bRedrawFrontend = 1; } else @@ -1494,7 +1489,7 @@ void PadChecks(void) if (pCurrScreen->userFunctionNum != 0) { - (fpUserFunctions[pCurrScreen->userFunctionNum - 1])(0); + FE_STEP_SCREEN(pCurrScreen); } feNewPad = 0; @@ -1507,7 +1502,7 @@ void PadChecks(void) if (bRedrawFrontend == 0 && numPadsConnected != oldnum && (gInFrontend != 0 && (pCurrScreen != NULL && pCurrScreen->userFunctionNum != 0))) { - (fpUserFunctions[pCurrScreen->userFunctionNum - 1])(1); + FE_INIT_SCREEN(pCurrScreen); bRedrawFrontend = 1; } } @@ -1869,7 +1864,7 @@ int bScreenSetup = 0; int CentreScreen(int bSetup) { if (bSetup) - return 0; + return FN_OK; #if defined(DEBUG) && !defined(PSX) char text[32]; @@ -1938,13 +1933,13 @@ int CentreScreen(int bSetup) else { // unhandled button press - return 0; + return FN_OK; } FESound((done) ? 3 : 1); } - return 0; + return FN_OK; } @@ -1999,7 +1994,7 @@ int CarSelectScreen(int bSetup) #ifdef PSX if (currPlayer != 1) - return 0; + return FN_OK; #endif LoadBackgroundFile("DATA\\CARS\\CARBACK.RAW"); @@ -2037,7 +2032,7 @@ int CarSelectScreen(int bSetup) pCurrButton = &pCurrScreen->buttons[1]; - return 1; + return FN_DONE; } if (feNewPad & MPAD_TRIANGLE) @@ -2111,7 +2106,7 @@ int CarSelectScreen(int bSetup) if (NumPlayers == 2) currPlayer++; - return 0; + return FN_OK; } rect = extraRect; @@ -2136,7 +2131,7 @@ int CarSelectScreen(int bSetup) currSelIndex = pCurrButton->d - 1; } - return 0; + return FN_OK; } // [D] [T] @@ -2145,7 +2140,7 @@ int CopDiffLevelScreen(int bSetup) if (bSetup) { pCurrButton = &pCurrScreen->buttons[gCopDifficultyLevel]; - return 1; + return FN_DONE; } if (feNewPad & MPAD_CROSS) @@ -2161,7 +2156,7 @@ int CopDiffLevelScreen(int bSetup) currSelIndex = pCurrButton->d - 1; } - return 0; + return FN_OK; } // [D] [T] @@ -2171,7 +2166,7 @@ int VibroOnOffScreen(int bSetup) { currSelIndex = (gVibration ^ 1); pCurrButton = &pCurrScreen->buttons[currSelIndex]; - return 1; + return FN_DONE; } if (feNewPad & MPAD_CROSS) @@ -2187,7 +2182,7 @@ int VibroOnOffScreen(int bSetup) currSelIndex = pCurrButton->d - 1; } - return 0; + return FN_OK; } @@ -2364,7 +2359,7 @@ int MissionSelectScreen(int bSetup) missionSetup = 1; - return 1; + return FN_DONE; } if (feNewPad & MPAD_CROSS) @@ -2376,14 +2371,14 @@ int MissionSelectScreen(int bSetup) i -= 4; if (i < minmaxSelections[currCity][0]) - return 0; + return FN_OK; } else if (currSelIndex == 5) { i += 4; if (i > minmaxSelections[currCity][1] || i > gFurthestMission) - return 0; + return FN_OK; } else { @@ -2394,15 +2389,15 @@ int MissionSelectScreen(int bSetup) feVariableSave[2] = currCity; gCurrentMissionNumber = botch[currMission + (currSelIndex - 1)].missNum; - return 0; + return FN_OK; } currMission = i; FESound(3); - fpUserFunctions[pCurrScreen->userFunctionNum - 1](1); + FE_INIT_SCREEN(pCurrScreen); bRedrawFrontend = 1; - return 1; + return FN_DONE; } else if (feNewPad & MPAD_TRIANGLE) { @@ -2418,7 +2413,7 @@ int MissionSelectScreen(int bSetup) currSelIndex = pCurrButton->d - 1; } - return 0; + return FN_OK; } // [D] [T] @@ -2477,7 +2472,7 @@ int MissionCityScreen(int bSetup) bDrawExtra = 1; } - return 0; + return FN_OK; } if (feNewPad & MPAD_TRIANGLE) @@ -2503,7 +2498,7 @@ int MissionCityScreen(int bSetup) else { currCity = pCurrButton->u & 3; - return 0; + return FN_OK; } rect = extraRect; @@ -2520,7 +2515,7 @@ int MissionCityScreen(int bSetup) #endif } - return 0; + return FN_OK; } // [D] [T] @@ -2566,7 +2561,7 @@ int CutSceneSelectScreen(int bSetup) pCurrButton = pCurrScreen->buttons + 1; - return 1; + return FN_DONE; } if (feNewPad & MPAD_TRIANGLE) @@ -2604,7 +2599,7 @@ int CutSceneSelectScreen(int bSetup) ScreenNames[ScreenDepth] = pCurrButton->Name; SetState(STATE_FMVPLAY, (void*)(feVariableSave[0] + CutAmountsTotal[feVariableSave[1]] + 1)); - return 1; + return FN_DONE; } if (cutSelection == CutAmounts[currCity + 1] - 1 || cutUnlock[gFurthestMission] <= cutSelection + CutAmountsTotal[currCity] + 1) @@ -2631,7 +2626,7 @@ int CutSceneSelectScreen(int bSetup) EndFrame(); #endif - return 0; + return FN_OK; } else if (feNewPad & MPAD_D_UP) { @@ -2642,7 +2637,7 @@ int CutSceneSelectScreen(int bSetup) currSelIndex = pCurrButton->d - 1; } - return 0; + return FN_OK; } @@ -2734,7 +2729,7 @@ int CutSceneCitySelectScreen(int bSetup) DrawSync(0); } - return 0; + return FN_OK; } if (feNewPad & MPAD_CROSS) @@ -2754,14 +2749,14 @@ int CutSceneCitySelectScreen(int bSetup) feVariableSave[0] = currCity; SetState(STATE_FMVPLAY, (void*)96); - return 1; + return FN_DONE; } else { lastCity = -1; } - return 0; + return FN_OK; } else if (feNewPad & MPAD_TRIANGLE) { @@ -2771,7 +2766,7 @@ int CutSceneCitySelectScreen(int bSetup) iScreenSelect = SCREEN_NONE; bDrawExtra = 0; - return 0; + return FN_OK; } else if (feNewPad & MPAD_D_UP) { @@ -2802,7 +2797,7 @@ int CutSceneCitySelectScreen(int bSetup) EndFrame(); #endif - return 0; + return FN_OK; } @@ -2835,7 +2830,7 @@ int SetVolumeScreen(int bSetup) FEPrintString(text, 152, ypos[1], 2, 128, 128, 128); #endif - return 0; + return FN_OK; } #ifndef PSX @@ -2864,14 +2859,14 @@ int SetVolumeScreen(int bSetup) SetMasterVolume(gMasterVolume); SetXMVolume(gMusicVolume); - return 0; + return FN_OK; } else if (feNewPad & MPAD_CROSS) { if (currSelIndex == 2) LoadBackgroundFile("DATA\\GFX.RAW"); - return 0; + return FN_OK; } else { @@ -2972,11 +2967,11 @@ int SetVolumeScreen(int bSetup) EndFrame(); // [A] inlined #else // don't flush the screen - return 1; + return FN_DONE; #endif } - return 0; + return FN_OK; } int GameNum = 0; @@ -3068,7 +3063,7 @@ int ScoreScreen(int bSetup) iScreenSelect = SCREEN_SCORES; currSelIndex = 0; - return 0; + return FN_OK; } if (feNewPad & MPAD_CROSS) @@ -3122,7 +3117,7 @@ int ScoreScreen(int bSetup) else if (feNewPad & MPAD_TRIANGLE) { iScreenSelect = SCREEN_NONE; - return 0; + return FN_OK; } else if ((feNewPad & MPAD_D_UP) || (feNewPad & MPAD_D_DOWN)) { @@ -3133,7 +3128,7 @@ int ScoreScreen(int bSetup) DisplayScoreTable(); #endif - return 0; + return FN_OK; } // [D] [T] @@ -3150,9 +3145,9 @@ int SubtitlesOnOffScreen(int bSetup) pCurrButton = pCurrScreen->buttons; } - return 1; + return FN_DONE; } - return 0; + return FN_OK; } @@ -3188,7 +3183,7 @@ int CityCutOffScreen(int bSetup) DrawSync(0); } #endif - return 0; + return FN_OK; } #ifndef PSX @@ -3202,7 +3197,7 @@ int CityCutOffScreen(int bSetup) LoadBackgroundFile("DATA\\GFX.RAW"); loaded[0] = -1; - return 0; + return FN_OK; }*/ if (feNewPad & MPAD_TRIANGLE) @@ -3216,7 +3211,7 @@ int CityCutOffScreen(int bSetup) LoadBackgroundFile("DATA\\GFX.RAW"); loaded[0] = -1; - return 0; + return FN_OK; } else if (feNewPad & MPAD_D_UP) { @@ -3229,14 +3224,14 @@ int CityCutOffScreen(int bSetup) else { currCity = pCurrButton->u & 3; - return 0; + return FN_OK; } RECT16 rect = extraRect; LoadImage(&rect, (u_long *)(_frontend_buffer + currCity * 0x8000)); DrawSync(0); #endif - return 0; + return FN_OK; } @@ -3272,7 +3267,7 @@ int ControllerScreen(int bSetup) } } - return 0; + return FN_OK; } // [D] [T] @@ -3290,7 +3285,7 @@ int MainScreen(int bSetup) } } - return 0; + return FN_OK; } static char* cheatText[] = @@ -3333,7 +3328,7 @@ int CheatScreen(int bSetup) if (bSetup == 0) { - return 0; + return FN_OK; } if (gFurthestMission == 40) @@ -3352,7 +3347,7 @@ int CheatScreen(int bSetup) sprintf(pCurrScreen->buttons[0].Name, GET_GAME_TXT(cheatText[0])); - return 0; + return FN_OK; } pCurrScreen->numButtons = numOpen; @@ -3397,7 +3392,7 @@ int CheatScreen(int bSetup) currSelIndex = 0; - return 0; + return FN_OK; } if (numOpen == 1) @@ -3409,7 +3404,7 @@ int CheatScreen(int bSetup) currSelIndex = 0; - return 0; + return FN_OK; } if (numOpen == 3) @@ -3432,7 +3427,7 @@ int CheatScreen(int bSetup) pCurrScreen->buttons[2].u = 2; currSelIndex = 0; - return 0; + return FN_OK; } if (numOpen >= 4) @@ -3490,13 +3485,13 @@ int CheatScreen(int bSetup) } currSelIndex = 0; - return 0; + return FN_OK; } pCurrScreen->numButtons = 0; currSelIndex = 0; - return 0; + return FN_OK; } @@ -3509,10 +3504,10 @@ int ImmunityOnOffScreen(int bSetup) pCurrButton = pCurrScreen->buttons + 1; else pCurrButton = pCurrScreen->buttons; - return 1; + return FN_DONE; } - return 0; + return FN_OK; } // [D] [T] @@ -3525,9 +3520,9 @@ int InvincibleOnOffScreen(int bSetup) else pCurrButton = pCurrScreen->buttons; - return 1; + return FN_DONE; } - return 0; + return FN_OK; } int MiniCarsOnOffScreen(int bSetup) @@ -3539,9 +3534,9 @@ int MiniCarsOnOffScreen(int bSetup) else pCurrButton = pCurrScreen->buttons; - return 1; + return FN_DONE; } - return 0; + return FN_OK; } // [D] [T] @@ -3552,7 +3547,7 @@ int GamePlayScreen(int bSetup) pCurrScreen->buttons[2].action = (allowVibration == 0) ? FE_MAKEVAR(BTN_DISABLED, 0) : FE_MAKEVAR(BTN_NEXT_SCREEN, 17); } - return 0; + return FN_OK; } // [D] [T] @@ -3578,7 +3573,7 @@ int GameNameScreen(int bSetup) strcpy(pCurrScreen->buttons[1].Name, GAMEMODE_AREA_NAME(GameLevel, offset, 1)); } - return 0; + return FN_OK; } // [D] [T] int CheatNumlayerSelect(int bSetup) @@ -3593,9 +3588,9 @@ int CheatNumlayerSelect(int bSetup) { pCurrScreen->buttons[1].action = FE_MAKEVAR(BTN_DISABLED, 0); } - return 0; + return FN_OK; } - return 0; + return FN_OK; } int BuildButtonsVertical(int count, int xStart, int yStart) @@ -3712,7 +3707,7 @@ int UserReplaySelectScreen(int bSetup) strcpy(btn.Name, G_LTXT(GTXT_NoSavedData)); } - return 0; + return FN_OK; } if (gFEReplayCount) @@ -3738,7 +3733,7 @@ int UserReplaySelectScreen(int bSetup) } #endif - return 0; + return FN_OK; } char* TimeOfDayNames[] = { @@ -3796,7 +3791,7 @@ int TimeOfDaySelectScreen(int bSetup) pNewButton = &pCurrScreen->buttons[2]; iScreenSelect = SCREEN_TIMEOFDAY; - return 0; + return FN_OK; } FEPrintString(GET_GAME_TXT(TimeOfDayNames[wantedTimeOfDay]), 590, ypos[0], 4, 128, 128, 128); @@ -3845,13 +3840,13 @@ int TimeOfDaySelectScreen(int bSetup) dir = 0; } - return 0; + return FN_OK; } int DemoScreen(int bSetup) { if (bSetup) - return 0; + return FN_OK; if (feNewPad & MPAD_CROSS) { @@ -3867,7 +3862,7 @@ int DemoScreen(int bSetup) SetState(STATE_GAMESTART); - return 0; + return FN_OK; } if(mainScreenLoaded) @@ -3884,5 +3879,6 @@ int DemoScreen(int bSetup) LoadBackgroundFile("DATA\\GFX.RAW"); } - return 0; + return FN_OK; +} } \ No newline at end of file From 87c1acda6ae978499c7c59e24f06a31bef366a79 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Thu, 26 May 2022 15:11:27 -0700 Subject: [PATCH 02/78] Fixed incorrect debris color bug. --- src_rebuild/Game/C/debris.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src_rebuild/Game/C/debris.c b/src_rebuild/Game/C/debris.c index 60fe8e2f0..053b4cc85 100644 --- a/src_rebuild/Game/C/debris.c +++ b/src_rebuild/Game/C/debris.c @@ -2854,7 +2854,7 @@ void Setup_Sparks(VECTOR *ipos, VECTOR *ispeed, int num_sparks, char SparkType) // [D] [T] void DisplayDebris(DEBRIS *debris, char type) { - int uVar3; + u_int cbgr; TRI_POINT* tv; POLY_GT4 *poly1; POLY_FT3 *poly; @@ -2914,15 +2914,17 @@ void DisplayDebris(DEBRIS *debris, char type) gte_stsxy(&poly1->x3); + cbgr = (u_char)combointensity; + if (type == 2) - uVar3 = (debris->rgb.b + combointensity) * 0x10000 | (debris->rgb.g + combointensity) * 0x100 | 0x3c000000 | debris->rgb.r + combointensity; + cbgr = 0x3c000000 | (debris->rgb.b + cbgr) << 16 | (debris->rgb.g + cbgr) << 8 | (debris->rgb.r + cbgr); else - uVar3 = debris->rgb.b << 0x10 | debris->rgb.g << 8 | 0x3c000000 | debris->rgb.r; + cbgr = 0x3c000000 | debris->rgb.b << 16 | debris->rgb.g << 8 | debris->rgb.r; - *(u_int *)&poly1->r0 = uVar3; - *(u_int *)&poly1->r2 = uVar3; - *(u_int *)&poly1->r1 = uVar3 + 0x202020; - *(u_int *)&poly1->r3 = uVar3 + 0x303030; + *(u_int *)&poly1->r0 = cbgr; + *(u_int *)&poly1->r2 = cbgr; + *(u_int *)&poly1->r1 = cbgr + 0x202020; + *(u_int *)&poly1->r3 = cbgr + 0x303030; setPolyGT4(poly1); addPrim(current->ot + (z >> 3), poly1); From 045e429cbfcb54535078655cbe263210663572be Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 17 Jun 2022 14:06:18 -0700 Subject: [PATCH 03/78] Initial support for extra configuration data in profiles + replays/cutscenes. - Uses the padding reserved at the end of replay/profile data - Backwards compatible with older replays by using zero/empty values - Added parameter to RestoreGameVars - Added StoreGameVars + Load/SaveExtraData - Moved some code out of RestoreGameVars to where its intended usage is - Misc styling changes --- src_rebuild/Game/C/cutrecorder.c | 11 +++- src_rebuild/Game/C/cutscene.c | 6 ++ src_rebuild/Game/C/glaunch.c | 101 +++++++++++++++++++++++++++---- src_rebuild/Game/C/glaunch.h | 10 +++ src_rebuild/Game/C/loadsave.c | 6 +- src_rebuild/Game/C/replays.c | 10 ++- src_rebuild/Game/dr2types.h | 44 +++++++++++++- 7 files changed, 171 insertions(+), 17 deletions(-) diff --git a/src_rebuild/Game/C/cutrecorder.c b/src_rebuild/Game/C/cutrecorder.c index 44c1acc84..01f458d1c 100644 --- a/src_rebuild/Game/C/cutrecorder.c +++ b/src_rebuild/Game/C/cutrecorder.c @@ -545,6 +545,11 @@ int CutRec_LoadCutsceneAsReplayFromBuffer(char* buffer) NumPlayers = header->NumPlayers; gRandomChase = header->RandomChase; CutsceneEventTrigger = header->CutsceneEvent; + + StoreGameVars(1); + + LoadExtraData(&header->ExtraData, 0); + gCopDifficultyLevel = header->gCopDifficultyLevel; ActiveCheats = header->ActiveCheats; // TODO: restore old value @@ -640,7 +645,7 @@ int CutRec_LoadCutsceneAsReplayFromBuffer(char* buffer) replayptr = (char*)(PingBuffer + MAX_REPLAY_PINGS); - if (header->HaveStoredData == 0x91827364) // -0x6e7d8c9c + if (header->HaveStoredData == 0x91827364) { memcpy((u_char*)&MissionStartData, (u_char*)pt, sizeof(MISSION_DATA)); gHaveStoredData = 1; @@ -710,10 +715,12 @@ int CutRec_SaveReplayToBuffer(char* buffer) // [A] is that ever valid? if (gHaveStoredData) { - header->HaveStoredData = 0x91827364; // -0x6e7d8c9c + header->HaveStoredData = 0x91827364; memcpy((u_char*)pt, (u_char*)&MissionStartData, sizeof(MISSION_DATA)); } + SaveExtraData(&header->ExtraData, 0); + return pt - buffer; } diff --git a/src_rebuild/Game/C/cutscene.c b/src_rebuild/Game/C/cutscene.c index 4fd65411d..6f5c07c30 100644 --- a/src_rebuild/Game/C/cutscene.c +++ b/src_rebuild/Game/C/cutscene.c @@ -495,6 +495,8 @@ void ReleaseInGameCutscene(void) if (gInGameCutsceneActive != 0) { + RestoreGameVars(-1); + PingOutAllCivCarsAndCopCars(); InitCivCars(); @@ -905,6 +907,10 @@ int LoadCutsceneToReplayBuffer(int residentCutscene) return 0; } + StoreGameVars(-1); + + LoadExtraData(&rheader->ExtraData, 0); + CutsceneStreamIndex = NumReplayStreams; //rheader->NumReplayStreams; NumCutsceneStreams = rheader->NumReplayStreams; diff --git a/src_rebuild/Game/C/glaunch.c b/src_rebuild/Game/C/glaunch.c index f4dd417af..a3e3a65a1 100644 --- a/src_rebuild/Game/C/glaunch.c +++ b/src_rebuild/Game/C/glaunch.c @@ -118,6 +118,10 @@ int AttractMode = 0; int gLoadedReplay = 0; int gHaveStoredData = 0; +int gHaveExtraData = 0; + +EXTRA_CONFIG_DATA gExtraConfig = { 0 }; + int gLastChase = 0; int gChaseNumber = 0; int gRandomChase = 0; @@ -131,15 +135,88 @@ int gWantNight = 0; int gOldVibrationMode; int gSurvivalCopSettingsBackup; ACTIVE_CHEATS gCheatsBackup; +EXTRA_CONFIG_DATA gExtraConfigBackup; + +int vars_stored = 0; -void RestoreGameVars() +void RestoreGameVars(int replay) { - _CutRec_Reset(); - - gLoadedReplay = 0; - gVibration = gOldVibrationMode; - gCopDifficultyLevel = gSurvivalCopSettingsBackup; - ActiveCheats = gCheatsBackup; + if (vars_stored) + { + if (replay == 0) + { +#ifdef DEBUG + printInfo("**** Restoring game vars ****\n"); +#endif + gVibration = gOldVibrationMode; + gCopDifficultyLevel = gSurvivalCopSettingsBackup; + ActiveCheats = gCheatsBackup; + + vars_stored = 0; + } +#ifdef DEBUG + printInfo("**** Restoring extra data ****\n"); +#endif + gExtraConfig = gExtraConfigBackup; + gHaveExtraData = (gExtraConfig.magic == EXTRA_DATA_MAGIC); + } +} + +void StoreGameVars(int replay) +{ + if (!vars_stored) + { +#ifdef DEBUG + printInfo("**** Backing up game vars (replay=%d) ****\n", replay); +#endif + gOldVibrationMode = gVibration; + gSurvivalCopSettingsBackup = gCopDifficultyLevel; + gCheatsBackup = ActiveCheats; + gExtraConfigBackup = gExtraConfig; + + vars_stored = 1; + } + + if (replay != 0) + { + // clear all extra config data: + // - any zero value means 'do backwards compatiblity' + // - ensures older replays are fully backwards compatible + // - newer replays always have this data stored (even if empty) + memset(&gExtraConfig, 0, sizeof(EXTRA_CONFIG_DATA)); + gHaveExtraData = 0; + } +} + +void LoadExtraData(EXTRA_CONFIG_DATA *extraData, int profile) +{ + if (extraData->magic == EXTRA_DATA_MAGIC) + { + memcpy(&gExtraConfig, extraData, sizeof(EXTRA_CONFIG_DATA)); + gHaveExtraData = 1; + } + + if (profile) + { + // setup special flags to be saved into replays + gExtraConfig.Flags.NoWibblyWobblyCars = 1; + gExtraConfig.Flags.AllowParkedTurnedWheels = 1; + gExtraConfig.Flags.FixCivCarsOnStraights = 1; + } +} + +void SaveExtraData(EXTRA_CONFIG_DATA *extraData, int profile) +{ + // always save extra data, even if it's empty; + // this will make future backwards compat. efforts easier ;) + extraData->magic = EXTRA_DATA_MAGIC; + memcpy(extraData, &gExtraConfig, sizeof(EXTRA_CONFIG_DATA)); + + if (profile) + { + // don't save any special flags in profile data + memset(&extraData->Flags, 0, sizeof(ACTIVE_FLAGS)); + } } // [D] [T] @@ -162,9 +239,7 @@ void State_GameStart(void* param) AttractMode = 0; NewLevel = 1; - gOldVibrationMode = gVibration; - gSurvivalCopSettingsBackup = gCopDifficultyLevel; - gCheatsBackup = ActiveCheats; + StoreGameVars(0); switch (GameType) { @@ -664,7 +739,11 @@ void State_GameComplete(void* param) if(nextState == STATE_INITFRONTEND) { - RestoreGameVars(); + _CutRec_Reset(); + + gLoadedReplay = 0; + + RestoreGameVars(0); lead_car = 0; NoPlayerControl = 0; diff --git a/src_rebuild/Game/C/glaunch.h b/src_rebuild/Game/C/glaunch.h index f85cdefa3..3f5b7200b 100644 --- a/src_rebuild/Game/C/glaunch.h +++ b/src_rebuild/Game/C/glaunch.h @@ -12,6 +12,10 @@ extern int gSubGameNumber; extern int gLoadedReplay; extern int gHaveStoredData; +// [A] +extern int gHaveExtraData; +extern EXTRA_CONFIG_DATA gExtraConfig; + extern int gMissionLadderPos; extern int gFurthestMission; extern int gWantNight; @@ -45,6 +49,12 @@ extern void ReInitFrontend(int returnToMain); // 0x00052E98 extern void RunMissionLadder(int newgame); // 0x00052FE8 +extern void StoreGameVars(int replay); +extern void RestoreGameVars(int replay); + +extern void LoadExtraData(EXTRA_CONFIG_DATA *extraData, int profile); +extern void SaveExtraData(EXTRA_CONFIG_DATA *extraData, int profile); + extern void GetRandomChase(); // 0x000535D8 extern int FindPrevMissionFromLadderPos(int pos); // 0x000536D8 diff --git a/src_rebuild/Game/C/loadsave.c b/src_rebuild/Game/C/loadsave.c index d62f17e83..fc114acec 100644 --- a/src_rebuild/Game/C/loadsave.c +++ b/src_rebuild/Game/C/loadsave.c @@ -45,7 +45,7 @@ struct CONFIG_SAVE_HEADER int NTSCAdjustY; int gSubtitles; ACTIVE_CHEATS AvailableCheats; - int reserved[6]; + EXTRA_CONFIG_DATA ExtraData; // [A] use reserved space to store extra config data }; // [A] @@ -461,6 +461,8 @@ int SaveConfigData(char* buffer) header->ScoreTables = ScoreTables; + SaveExtraData(&header->ExtraData, 1); + return sizeof(CONFIG_SAVE_HEADER); } @@ -492,6 +494,8 @@ int LoadConfigData(char* buffer) ScoreTables = header->ScoreTables; + LoadExtraData(&header->ExtraData, 1); + return 1; } diff --git a/src_rebuild/Game/C/replays.c b/src_rebuild/Game/C/replays.c index a8482e7f1..7b8a5cc35 100644 --- a/src_rebuild/Game/C/replays.c +++ b/src_rebuild/Game/C/replays.c @@ -173,10 +173,11 @@ int SaveReplayToBuffer(char *buffer) // [A] is that ever valid? if (gHaveStoredData) { - header->HaveStoredData = 0x91827364; // -0x6e7d8c9c + header->HaveStoredData = 0x91827364; memcpy((u_char*)pt, (u_char*)&MissionStartData, sizeof(MISSION_DATA)); } + SaveExtraData(&header->ExtraData, 0); #ifdef PSX return 0x3644; // size? #else @@ -208,6 +209,11 @@ int LoadReplayFromBuffer(char *buffer) NumPlayers = header->NumPlayers; gRandomChase = header->RandomChase; CutsceneEventTrigger = header->CutsceneEvent; + + StoreGameVars(1); + + LoadExtraData(&header->ExtraData, 0); + gCopDifficultyLevel = header->gCopDifficultyLevel; ActiveCheats = header->ActiveCheats; // TODO: restore old value @@ -269,7 +275,7 @@ int LoadReplayFromBuffer(char *buffer) replayptr = (char*)(PingBuffer + MAX_REPLAY_PINGS); - if (header->HaveStoredData == 0x91827364) // -0x6e7d8c9c + if (header->HaveStoredData == 0x91827364) { memcpy((u_char*)&MissionStartData, (u_char*)pt, sizeof(MISSION_DATA)); gHaveStoredData = 1; diff --git a/src_rebuild/Game/dr2types.h b/src_rebuild/Game/dr2types.h index c716f3a7c..7b619f257 100644 --- a/src_rebuild/Game/dr2types.h +++ b/src_rebuild/Game/dr2types.h @@ -1035,6 +1035,48 @@ struct REPLAY_PARAMETER_BLOCK u_char weather; }; +#define EXTRA_DATA_MAGIC 0xF12EB12D + +struct ACTIVE_FLAGS +{ + // special flags for regression fixes, etc. + u_char NoWibblyWobblyCars : 1; + u_char AllowParkedTurnedWheels : 1; + u_char FixCivCarsOnStraights : 1; + u_char extraFlag4 : 1; + u_char extraFlag5 : 1; + u_char extraFlag6 : 1; + u_char extraFlag7 : 1; + u_char extraFlag8 : 1; + u_char extraFlag9 : 1; + u_char extraFlag10 : 1; + u_char extraFlag11 : 1; + u_char extraFlag12 : 1; + u_char extraFlag13 : 1; + u_char extraFlag14 : 1; + u_char extraFlag15 : 1; + u_char extraFlag16 : 1; + u_char reserved1; + u_char reserved2; +}; + +struct EXTRA_CONFIG_DATA +{ + u_int magic; + + // configuration options + u_char gTrafficDensity; + u_char gPedestrianDensity; + u_char pad1[2]; + + int reserved[3]; + + ACTIVE_FLAGS Flags; +}; + +// NB: necessary to fit at the end of certain fixed-size structs +assert_sizeof(EXTRA_CONFIG_DATA, 24); + struct REPLAY_SAVE_HEADER { u_int magic; @@ -1051,7 +1093,7 @@ struct REPLAY_SAVE_HEADER int wantedCar[2]; int MissionNumber; int HaveStoredData; - int reserved2[6]; + EXTRA_CONFIG_DATA ExtraData; // [A] use reserved space to store extra config data }; struct STREAM_SOURCE From 362a52f1b2010db0b1843d75ae52842436f9f2a2 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 17 Jun 2022 17:54:55 -0700 Subject: [PATCH 04/78] Add full support for more than 32 cars on non-PSX builds. - Use 8-bit char arrays in place of bitfields as needed - Slightly optimized car noise logic - Added several macros - Added collision debugging support for carsOnBoat --- src_rebuild/Game/C/bcollide.c | 19 +++ src_rebuild/Game/C/cars.c | 2 +- src_rebuild/Game/C/event.c | 70 ++++++++- src_rebuild/Game/C/event.h | 10 ++ src_rebuild/Game/C/gamesnd.c | 260 ++++++++++++++++++++-------------- src_rebuild/Game/C/gamesnd.h | 32 +++++ src_rebuild/Game/C/handling.c | 82 ++++++++++- src_rebuild/Game/C/mc_snd.c | 60 ++++---- src_rebuild/Game/C/mission.c | 34 ++++- src_rebuild/Game/dr2limits.h | 11 +- src_rebuild/Game/dr2types.h | 2 +- 11 files changed, 433 insertions(+), 149 deletions(-) diff --git a/src_rebuild/Game/C/bcollide.c b/src_rebuild/Game/C/bcollide.c index 78e67b2ea..58500a71e 100644 --- a/src_rebuild/Game/C/bcollide.c +++ b/src_rebuild/Game/C/bcollide.c @@ -14,6 +14,7 @@ #include "objanim.h" #include "system.h" #include "cutscene.h" +#include "event.h" extern int gCameraBoxOverlap; @@ -678,6 +679,7 @@ int CarBuildingCollision(CAR_DATA *cp, BUILDING_BOX *building, CELL_OBJECT *cop, #if defined(COLLISION_DEBUG) && !defined(PSX) extern int gShowCollisionDebug; + extern SVECTOR boatOffset; if (gShowCollisionDebug == 1) { extern void Debug_AddLine(VECTOR & pointA, VECTOR & pointB, CVECTOR & color); @@ -687,6 +689,8 @@ int CarBuildingCollision(CAR_DATA *cp, BUILDING_BOX *building, CELL_OBJECT *cop, CVECTOR rrcv = { 250, 0, 0 }; CVECTOR yycv = { 250, 250, 0 }; + VECTOR offset = { 0 }; + // show both box axes { VECTOR _zero = { 0 }; @@ -694,6 +698,21 @@ int CarBuildingCollision(CAR_DATA *cp, BUILDING_BOX *building, CELL_OBJECT *cop, VECTOR b2p = cd[1].x; b2p.vy = b1p.vy; + if (carsOnBoat.count != 0 && carsOnBoat.cars[cp->id]) + { + offset.vx = boatOffset.vx; + offset.vy = boatOffset.vy; + offset.vz = boatOffset.vz; + + b1p.vx -= offset.vx; + b1p.vy -= offset.vy; + b1p.vz -= offset.vz; + + b2p.vx -= offset.vx; + b2p.vy -= offset.vy; + b2p.vz -= offset.vz; + } + // show position to position //Debug_AddLine(b1p1, b2p1, yycv); diff --git a/src_rebuild/Game/C/cars.c b/src_rebuild/Game/C/cars.c index 7617c959c..f89541f0e 100644 --- a/src_rebuild/Game/C/cars.c +++ b/src_rebuild/Game/C/cars.c @@ -1573,7 +1573,7 @@ void DrawCar(CAR_DATA* cp, int view) if(CarHasSiren(cp->ap.model)) { if ((IS_ROADBLOCK_CAR(cp) || cp->controlType == CONTROL_TYPE_PURSUER_AI) || // any regular cop car including roadblock - gInGameCutsceneActive && cp->controlType == CONTROL_TYPE_CUTSCENE && force_siren[CAR_INDEX(cp)] != 0 || // any car with siren in cutscene + gInGameCutsceneActive && cp->controlType == CONTROL_TYPE_CUTSCENE && CARNOISE_HAS_FORCED_SIREN(CAR_INDEX(cp)) != 0 || // any car with siren in cutscene gCurrentMissionNumber == 26 && cp->controlType == CONTROL_TYPE_CUTSCENE && cp->ap.model == 4) // Vegas ambulance { if (cp->ai.p.dying < 75) diff --git a/src_rebuild/Game/C/event.c b/src_rebuild/Game/C/event.c index 33c36d415..4bf7058cd 100644 --- a/src_rebuild/Game/C/event.c +++ b/src_rebuild/Game/C/event.c @@ -542,9 +542,14 @@ static CameraDelay cameraDelay; static Detonator detonator; static int eventHaze = 0; static int doneFirstHavanaCameraHack = 0; -static SVECTOR boatOffset; +SVECTOR boatOffset; static FixedEvent* fixedEvent = NULL; + +#ifndef PSX +BOAT_CARS carsOnBoat; +#else int carsOnBoat = 0; +#endif MultiCar multiCar; @@ -892,7 +897,11 @@ void InitEvents(void) cameraDelay.delay = 0; eventHaze = 0; +#ifndef PSX + ClearMem((char*)&carsOnBoat, sizeof(BOAT_CARS)); // clear count + array +#else carsOnBoat = 0; +#endif doneFirstHavanaCameraHack = 0; boatOffset.vx = 0; @@ -1685,8 +1694,13 @@ void SetCamera(EVENT* ev) // [D] [T] void EventCollisions(CAR_DATA* cp, int type) { +#ifndef PSX + if (carsOnBoat.count == 0 || carsOnBoat.cars[CAR_INDEX(cp)] == 0) + return; +#else if (carsOnBoat >> CAR_INDEX(cp) == 0) return; +#endif if (type == 0) { @@ -2397,11 +2411,16 @@ void StepEvents(void) VECTOR* vel; CELL_OBJECT* cop; CAR_DATA* cp; +#ifndef PSX + static BOAT_CARS onBoatLastFrame; +#else int onBoatLastFrame; +#endif int dist; int thisCamera, otherCamera; onBoatLastFrame = carsOnBoat; + ev = firstEvent; if (detonator.timer) @@ -2418,22 +2437,43 @@ void StepEvents(void) i = 0; cp = car_data; +#ifndef PSX + ClearMem((char*)&carsOnBoat, sizeof(BOAT_CARS)); // clear count + array +#else carsOnBoat = 0; +#endif do { if (cp->controlType != CONTROL_TYPE_NONE && OnBoat((VECTOR*)cp->hd.where.t, ev, &dist)) { +#ifndef PSX + carsOnBoat.cars[i] = 1; + carsOnBoat.count++; +#else carsOnBoat |= 1 << i; +#endif } i++; cp++; +#ifndef PSX + } while (i < MAX_CARS); +#else } while (i < MAX_CARS && i < 32); +#endif // make Tanner on boat also if (player[0].playerType == 2 && OnBoat((VECTOR*)player[0].pos, ev, &dist)) + { +#ifndef PSX + carsOnBoat.cars[TANNER_COLLIDER_CARID] = 1; + carsOnBoat.cars[CAMERA_COLLIDER_CARID] = 1; + carsOnBoat.count += 2; +#else carsOnBoat |= (1 << TANNER_COLLIDER_CARID) | 0x200000;// 0x300000; +#endif + } BoatOffset(&boatOffset, ev); @@ -2467,18 +2507,27 @@ void StepEvents(void) } // move cars on boats +#ifndef PSX + if ((ev->flags & 0x40) && (carsOnBoat.count != 0 || onBoatLastFrame.count != 0)) + { +#else if ((ev->flags & 0x40) && (carsOnBoat != 0 || onBoatLastFrame != 0)) { int bit; +#endif speed.x = ev->position.vx - old.vx; speed.z = ev->position.vz - old.vz; // go thru cars +#ifndef PSX + for (i = 0; i < MAX_CARS + 1; i++) + { +#else for (i = 0; i < MAX_CARS + 1 && i < 32; i++) { bit = (1 << i); - +#endif if (i == TANNER_COLLIDER_CARID) { pos = (VECTOR*)player[0].pos; @@ -2491,7 +2540,11 @@ void StepEvents(void) } // update position and add velocity +#ifndef PSX + if (carsOnBoat.cars[i]) +#else if (carsOnBoat & bit) +#endif { pos->vx += speed.x; pos->vz += speed.z; @@ -2499,9 +2552,18 @@ void StepEvents(void) if (i == TANNER_COLLIDER_CARID) { SetTannerPosition(pos); +#ifndef PSX + carsOnBoat.cars[TANNER_COLLIDER_CARID] = 0; + carsOnBoat.count--; +#else carsOnBoat &= ~(1 << TANNER_COLLIDER_CARID); +#endif } +#ifndef PSX + else if (onBoatLastFrame.cars[i] == 0) +#else else if ((onBoatLastFrame & bit) == 0) +#endif { vel->vx -= speed.x * 4096; vel->vz -= speed.z * 4096; @@ -2511,7 +2573,11 @@ void StepEvents(void) // car_data[i].st.n.fposition[0] = pos->vx << 4; // car_data[i].st.n.fposition[2] = pos->vz << 4; } +#ifndef PSX + else if (vel && onBoatLastFrame.cars[i]) +#else else if (vel && (onBoatLastFrame & bit)) +#endif { vel->vx += speed.x * 4096; vel->vz += speed.z * 4096; diff --git a/src_rebuild/Game/C/event.h b/src_rebuild/Game/C/event.h index 69ffc48af..b10ff04b2 100644 --- a/src_rebuild/Game/C/event.h +++ b/src_rebuild/Game/C/event.h @@ -37,7 +37,17 @@ extern EventGlobal events; extern CELL_OBJECT *EventCop; extern int event_models_active; +#ifndef PSX +struct BOAT_CARS +{ + int count; + char cars[MAX_CARS+2]; +}; + +extern BOAT_CARS carsOnBoat; +#else extern int carsOnBoat; +#endif extern void InitEvents(); // 0x0004BBD4 extern void SetUpEvents(int full); // 0x00046258 diff --git a/src_rebuild/Game/C/gamesnd.c b/src_rebuild/Game/C/gamesnd.c index 5f6213e2f..1c8a7bdd2 100644 --- a/src_rebuild/Game/C/gamesnd.c +++ b/src_rebuild/Game/C/gamesnd.c @@ -952,8 +952,12 @@ void InitDopplerSFX(void) loudhail_time = 75; } +#ifndef PSX +char noisy_cars[MAX_CARS] = { 0 }; +#else char force_idle[8] = { 0 }; char force_siren[8] = { 0 }; +#endif // [D] [T] void DoDopplerSFX(void) @@ -962,7 +966,13 @@ void DoDopplerSFX(void) short* playerFelony; int i, j; int car; +#ifdef PSX u_int car_flags; + +#define CARNOISE_IS_ACTIVE(id) (car_flags & (1 << id)) +#define CARNOISE_ENABLE(id) (car_flags |= (1 << id)) +#define CARNOISE_DISABLE(id) (car_flags &= ~(1 << id)) +#endif int num_noisy_cars; int sirens; @@ -979,7 +989,10 @@ void DoDopplerSFX(void) for (i = 0; i < MAX_CARS; i++) { car_ptr = &car_data[i]; - +#ifndef PSX + // we don't use car_flags; reset it now since we're going through all cars + CARNOISE_DISABLE(i); +#endif dx = car_ptr->hd.where.t[0] - camera_position.vx; dz = car_ptr->hd.where.t[2] - camera_position.vz; @@ -1010,16 +1023,15 @@ void DoDopplerSFX(void) int tmpi; tmpi = indexlist[i]; - j = i - 1; - while (j >= 0 && car_dist[indexlist[j]] > car_dist[tmpi]) - { + for (j = i - 1; j >= 0 && car_dist[indexlist[j]] > car_dist[tmpi]; j--) indexlist[j + 1] = indexlist[j]; - j = j - 1; - } + indexlist[j + 1] = tmpi; } +#ifdef PSX car_flags = 0; +#endif sirens = 0; // collect cop cars for siren sound @@ -1047,7 +1059,7 @@ void DoDopplerSFX(void) } // any cutscene cop car or car with forced siren - if (gInGameCutsceneActive != 0 && car_ptr->controlType == CONTROL_TYPE_CUTSCENE && force_siren[indexlist[i]] != 0) + if (gInGameCutsceneActive != 0 && car_ptr->controlType == CONTROL_TYPE_CUTSCENE && CARNOISE_HAS_FORCED_SIREN(indexlist[i]) != 0) { siren = 1; } @@ -1062,72 +1074,85 @@ void DoDopplerSFX(void) siren = 1; } - if (!siren) - continue; - - car_flags |= 1 << indexlist[i]; + if (siren) + { + CARNOISE_ENABLE(indexlist[i]); - if (gInGameCutsceneActive == 0) - sirens++; + if (gInGameCutsceneActive == 0) + sirens++; + } } - // stop unused siren noises + int noises = 0; + + // update siren noise status for (i = 0; i < MAX_SIREN_NOISES; i++) { - int siren; - siren = (car_flags & 1 << siren_noise[i].car) != 0; - - siren_noise[i].in_use = siren; - car_flags &= ~(siren << siren_noise[i].car); + if (CARNOISE_IS_ACTIVE(siren_noise[i].car)) + { + // already in use, no need to start again + CARNOISE_DISABLE(siren_noise[i].car); - if (siren == 0 && siren_noise[i].stopped == 0) + siren_noise[i].in_use = 1; + noises++; + } + else { - StopChannel(siren_noise[i].chan); - UnlockChannel(siren_noise[i].chan); + // stop unused siren noises + if (siren_noise[i].stopped == 0) + { + StopChannel(siren_noise[i].chan); + UnlockChannel(siren_noise[i].chan); - siren_noise[i].chan = -1; - siren_noise[i].car = 20; - siren_noise[i].stopped = 1; + siren_noise[i].chan = -1; + siren_noise[i].car = MAX_CARS; + siren_noise[i].stopped = 1; + } + siren_noise[i].in_use = 0; } } - // start sirens - for (i = 0; i < num_noisy_cars; i++) + // start new sirens + // pick free car noise slot and play + // [A] stop if no more sounds are available + for (i = 0; i < num_noisy_cars && noises < MAX_SIREN_NOISES; i++) { - if (car_flags & 1 << indexlist[i]) - { - car = indexlist[i]; + car = indexlist[i]; - // dispatch siren sounds - for (j = 0; j < MAX_SIREN_NOISES; j++) - { - if (siren_noise[j].in_use != 0) - continue; + if (!CARNOISE_IS_ACTIVE(indexlist[i])) + continue; - siren_noise[j].in_use = 1; - siren_noise[j].stopped = 0; - siren_noise[j].car = car; + // dispatch siren sounds + for (j = 0; j < MAX_SIREN_NOISES; j++) + { + if (siren_noise[j].in_use != 0) + continue; - if (car_data[car].controlType != CONTROL_TYPE_CIV_AI) - { - int siren; - siren = CarHasSiren(car_data[car].ap.model); + siren_noise[j].in_use = 1; + siren_noise[j].stopped = 0; + siren_noise[j].car = car; - siren_noise[j].chan = Start3DTrackingSound(-1, (siren & 0xff00) >> 8, siren & 0xff, - (VECTOR*)car_data[car].hd.where.t, - (LONGVECTOR3*)car_data[car].st.n.linearVelocity); - } - else - { - // play music - siren_noise[j].chan = Start3DTrackingSound(-1, SOUND_BANK_ENVIRONMENT, 5, - (VECTOR*)car_data[car].hd.where.t, - (LONGVECTOR3*)car_data[car].st.n.linearVelocity); - } + if (car_data[car].controlType != CONTROL_TYPE_CIV_AI) + { + int siren; + siren = CarHasSiren(car_data[car].ap.model); - LockChannel(siren_noise[j].chan); - break; + siren_noise[j].chan = Start3DTrackingSound(-1, (siren & 0xff00) >> 8, siren & 0xff, + (VECTOR*)car_data[car].hd.where.t, + (LONGVECTOR3*)car_data[car].st.n.linearVelocity); } + else + { + // play music + siren_noise[j].chan = Start3DTrackingSound(-1, SOUND_BANK_ENVIRONMENT, 5, + (VECTOR*)car_data[car].hd.where.t, + (LONGVECTOR3*)car_data[car].st.n.linearVelocity); + } + + LockChannel(siren_noise[j].chan); + noises++; + + break; } } @@ -1153,88 +1178,105 @@ void DoDopplerSFX(void) // siren noises occupy car noise channels num_noisy_cars = MIN(num_noisy_cars, MAX_CAR_NOISES - sirens); +#ifndef PSX + // reset all cars' noisy status + for (i = 0; i < MAX_CARS; i++) + CARNOISE_DISABLE(i); +#else car_flags = 0; +#endif + // collect noisy cars for (j = 0; j < num_noisy_cars; j++) { car = indexlist[j]; if (car_data[car].controlType != CONTROL_TYPE_PURSUER_AI || car_data[car].ai.p.dying == 0) - car_flags |= 1 << car; + CARNOISE_ENABLE(car); } - for (j = 0; j < MAX_CAR_NOISES; j++) - { - int noise; - - noise = (car_flags & (1 << car_noise[j].car)) != 0; - car_noise[j].in_use = noise; - - car_flags &= ~(noise << car_noise[j].car); - } + noises = 0; + // update noisy cars' status for (j = 0; j < MAX_CAR_NOISES; j++) { - if (car_noise[j].in_use == 0 && car_noise[j].stopped == 0) + if (CARNOISE_IS_ACTIVE(car_noise[j].car)) { - StopChannel(car_noise[j].chan); - UnlockChannel(car_noise[j].chan); + // already in use, no need to start again + CARNOISE_DISABLE(car_noise[j].car); - car_noise[j].chan = -1; - car_noise[j].car = 20; - car_noise[j].stopped = 1; + car_noise[j].in_use = 1; + noises++; } + else + { + // stop unused car noises + if (car_noise[j].stopped == 0) + { + StopChannel(car_noise[j].chan); + UnlockChannel(car_noise[j].chan); + + car_noise[j].chan = -1; + car_noise[j].car = MAX_CARS; + car_noise[j].stopped = 1; + } + car_noise[j].in_use = 0; + } } // start new sounds // pick free car noise slot and play - for (i = 0; i < num_noisy_cars; i++) + // [A] stop if no more sounds are available + for (i = 0; i < num_noisy_cars && noises < MAX_CAR_NOISES; i++) { - if (car_flags & 1 << indexlist[i]) + car = indexlist[i]; + + if (!CARNOISE_IS_ACTIVE(car)) + continue; + + for (j = 0; j < MAX_CAR_NOISES; j++) { - car = indexlist[i]; - for (j = 0; j < MAX_CAR_NOISES; j++) - { - int bank, model; + int bank, model; - if (car_noise[j].in_use) - continue; + if (car_noise[j].in_use) + continue; - car_noise[j].in_use = 1; - car_noise[j].stopped = 0; - car_noise[j].car = car; + car_noise[j].in_use = 1; + car_noise[j].stopped = 0; + car_noise[j].car = car; - // determine which sound type it has to play - if (gInGameCutsceneActive != 0 && force_idle[car] > -1) - car_noise[j].idle = force_idle[car]; - else - car_noise[j].idle = (car_data[car].hd.speed < 17); + // determine which sound type it has to play + if (gInGameCutsceneActive != 0 && CARNOISE_HAS_FORCED_IDLE(car)) + car_noise[j].idle = 0; + else + car_noise[j].idle = (car_data[car].hd.speed < 17); - model = car_data[car].ap.model; + model = car_data[car].ap.model; - if (model == 3) - model = cop_model; + if (model == 3) + model = cop_model; - // get bank id - if (model == 4) - bank = ResidentModelsBodge(); - else if (model < 3) - bank = model; - else - bank = model - 1; + // get bank id + if (model == 4) + bank = ResidentModelsBodge(); + else if (model < 3) + bank = model; + else + bank = model - 1; - if (car_noise[j].idle) - sample = bank * 3 + 1; - else - sample = bank * 3; + if (car_noise[j].idle) + sample = bank * 3 + 1; + else + sample = bank * 3; - car_noise[j].chan = Start3DTrackingSound(-1, SOUND_BANK_CARS, sample, - (VECTOR*)car_data[car].hd.where.t, - (LONGVECTOR3*)car_data[car].st.n.linearVelocity); + car_noise[j].chan = Start3DTrackingSound(-1, SOUND_BANK_CARS, sample, + (VECTOR*)car_data[car].hd.where.t, + (LONGVECTOR3*)car_data[car].st.n.linearVelocity); - LockChannel(car_noise[j].chan); - break; - } + LockChannel(car_noise[j].chan); + noises++; + + break; } } @@ -1253,8 +1295,8 @@ void DoDopplerSFX(void) cp = &car_data[car]; // determine which sound type it has to play - if (gInGameCutsceneActive != 0 && force_idle[car] > -1) - car_noise[j].idle = force_idle[car]; + if (gInGameCutsceneActive != 0 && CARNOISE_HAS_FORCED_IDLE(car)) + car_noise[j].idle = 0; // [A] only one idle type anyways else car_noise[j].idle = (cp->hd.speed < 17); diff --git a/src_rebuild/Game/C/gamesnd.h b/src_rebuild/Game/C/gamesnd.h index 9c7915eac..51e0b2a17 100644 --- a/src_rebuild/Game/C/gamesnd.h +++ b/src_rebuild/Game/C/gamesnd.h @@ -74,9 +74,41 @@ extern int TimeSinceLastSpeech; extern char phrase_top; +#ifndef PSX +extern char noisy_cars[MAX_CARS]; + +#define CARNOISE_FLAG_NONE 0 +#define CARNOISE_FLAG_NOISY 1 +#define CARNOISE_FLAG_FORCE_IDLE 2 +#define CARNOISE_FLAG_FORCE_SIREN 4 + +#define CARNOISE_GET_FLAG(id,f) (noisy_cars[id] & f) +#define CARNOISE_SET_FLAG(id,f) (noisy_cars[id] |= f) +#define CARNOISE_CLEAR_FLAG(id,f) (noisy_cars[id] &= ~(f)) + +#define CARNOISE_IS_ACTIVE(id) CARNOISE_GET_FLAG(id,CARNOISE_FLAG_NOISY) +#define CARNOISE_ENABLE(id) CARNOISE_SET_FLAG(id,CARNOISE_FLAG_NOISY) +#define CARNOISE_DISABLE(id) CARNOISE_CLEAR_FLAG(id,CARNOISE_FLAG_NOISY) + +#define CARNOISE_HAS_FORCED_IDLE(id) CARNOISE_GET_FLAG(id,CARNOISE_FLAG_FORCE_IDLE) +#define CARNOISE_SET_FORCED_IDLE(id) CARNOISE_SET_FLAG(id,CARNOISE_FLAG_FORCE_IDLE) +#define CARNOISE_CLEAR_FORCED_IDLE(id) CARNOISE_CLEAR_FLAG(id,CARNOISE_FLAG_FORCE_IDLE) + +#define CARNOISE_HAS_FORCED_SIREN(id) CARNOISE_GET_FLAG(id,CARNOISE_FLAG_FORCE_SIREN) +#define CARNOISE_SET_FORCED_SIREN(id) CARNOISE_SET_FLAG(id,CARNOISE_FLAG_FORCE_SIREN) +#define CARNOISE_CLEAR_FORCED_SIREN(id) CARNOISE_CLEAR_FLAG(id,CARNOISE_FLAG_FORCE_SIREN) +#else extern char force_idle[8]; extern char force_siren[8]; +#define CARNOISE_HAS_FORCED_IDLE(id) (force_idle[id] > -1) +#define CARNOISE_SET_FORCED_IDLE(id) (force_idle[id] = 0) +#define CARNOISE_CLEAR_FORCED_IDLE(id) (force_idle[id] = -1) + +#define CARNOISE_HAS_FORCED_SIREN(id) (force_siren[id] != 0) +#define CARNOISE_SET_FORCED_SIREN(id) (force_siren[id] = 1) +#define CARNOISE_CLEAR_FORCED_SIREN(id) (force_siren[id] = 0) +#endif extern SPEECH_QUEUE gSpeechQueue; extern void LoadBankFromLump(int bank, int lump); // 0x00052460 diff --git a/src_rebuild/Game/C/handling.c b/src_rebuild/Game/C/handling.c index 84124ea83..f7423c990 100644 --- a/src_rebuild/Game/C/handling.c +++ b/src_rebuild/Game/C/handling.c @@ -267,6 +267,12 @@ int ghost_mode = 0; int playerghost = 0; int playerhitcopsanyway = 0; +#ifndef PSX +typedef char COLLISION_LIST[MAX_CARS]; + +COLLISION_LIST collided_cars[MAX_CARS]; +#endif + // [D] [T] void GlobalTimeStep(void) { @@ -274,7 +280,11 @@ void GlobalTimeStep(void) static RigidBodyState _d0[MAX_CARS]; // offset 0x410 static RigidBodyState _d1[MAX_CARS]; // offset 0x820 +#ifndef PSX + COLLISION_LIST *collisions; +#else int mayBeCollidingBits; +#endif int howHard; int tmp; RigidBodyState* thisState_i; @@ -413,11 +423,19 @@ void GlobalTimeStep(void) CheckScenaryCollisions(cp); } +#ifdef PSX mayBeCollidingBits = cp->hd.mayBeColliding; +#endif // if has any collision, process with double precision +#ifndef PSX + if (cp->hd.mayBeColliding) + { + collisions = &collided_cars[CAR_INDEX(cp)]; +#else if (mayBeCollidingBits) { +#endif if (RKstep == 0) { thisState_i = &cp->st; @@ -457,7 +475,13 @@ void GlobalTimeStep(void) // [A] optimized run to not use the box checking // as it has already composed bitfield / pairs - if((mayBeCollidingBits & (1 << CAR_INDEX(c1))) != 0 && (c1->hd.speed != 0 || cp->hd.speed != 0)) + if( +#ifndef PSX + collisions[CAR_INDEX(c1)] != 0 +#else + (mayBeCollidingBits & (1 << CAR_INDEX(c1))) != 0 +#endif + && (c1->hd.speed != 0 || cp->hd.speed != 0)) { if(CarCarCollision3(cp, c1, &depth, (VECTOR*)collisionpoint, (VECTOR*)normal)) { @@ -983,6 +1007,10 @@ void CheckCarToCarCollisions(void) cp = car_data; loop1 = 0; +#ifndef PSX + memset(collided_cars, 0, sizeof(collided_cars)); +#endif + // build boxes do { if (cp->controlType == CONTROL_TYPE_NONE || @@ -1030,10 +1058,15 @@ void CheckCarToCarCollisions(void) bb->y0 = (cp->hd.where.t[1] - colBox->vy * 2) / 16; bb->y1 = (cp->hd.where.t[1] + colBox->vy * 4) / 16; - // make player handled cars always processed with precision + // make player handled cars always processed with double precision if (cp->hndType == 0) { +#ifndef PSX + if (cp->controlType != CONTROL_TYPE_CIV_AI) + cp->hd.mayBeColliding = 2; +#else cp->hd.mayBeColliding = (1 << 31); +#endif } loop1++; @@ -1053,11 +1086,23 @@ void CheckCarToCarCollisions(void) while (loop2 < MAX_CARS) { if (bb1->y1 != INT_MAX && bb2->y1 != INT_MAX && - bb2->x0 < bb1->x1 && bb2->z0 < bb1->z1 && bb1->x0 < bb2->x1 && - bb1->z0 < bb2->z1 && bb2->y0 < bb1->y1 && bb1->y0 < bb2->y1) + bb2->x0 < bb1->x1 && + bb2->z0 < bb1->z1 && + bb1->x0 < bb2->x1 && + bb1->z0 < bb2->z1 && + bb2->y0 < bb1->y1 && + bb1->y0 < bb2->y1) { +#ifndef PSX + collided_cars[loop1][loop2] = 1; + collided_cars[loop2][loop1] = 1; + + car_data[loop1].hd.mayBeColliding |= 1; + car_data[loop2].hd.mayBeColliding |= 1; +#else car_data[loop1].hd.mayBeColliding |= (1 << loop2); car_data[loop2].hd.mayBeColliding |= (1 << loop1); +#endif } loop2++; @@ -1071,10 +1116,14 @@ void CheckCarToCarCollisions(void) extern void Debug_AddLine(VECTOR & pointA, VECTOR & pointB, CVECTOR & color); CVECTOR bbcv = { 0, 0, 250 }; + CVECTOR ggcv = { 0, 250, 0 }; + CVECTOR ppcv = { 250, 0, 250 }; CVECTOR rrcv = { 250, 0, 0 }; CVECTOR yycv = { 250, 250, 0 }; - CVECTOR bbcol = car_data[loop1].hd.mayBeColliding ? rrcv : yycv; + int mayBeColliding = car_data[loop1].hd.mayBeColliding; + + CVECTOR bbcol = (mayBeColliding == 1) ? rrcv : ((mayBeColliding == 2) ? ggcv : ((mayBeColliding == 3) ? ppcv : yycv)); VECTOR box_pointsy0[4] = { {bb1->x0 * 16, bb1->y0 * 16, bb1->z0 * 16, 0}, // front left @@ -1104,6 +1153,29 @@ void CheckCarToCarCollisions(void) Debug_AddLine(box_pointsy0[1], box_pointsy1[1], bbcol); Debug_AddLine(box_pointsy0[2], box_pointsy1[2], bbcol); Debug_AddLine(box_pointsy0[3], box_pointsy1[3], bbcol); + + if (car_data[loop1].hd.mayBeColliding) + { + for (loop2 = loop1 + 1; loop2 < MAX_CARS; loop2++) + { + if (!collided_cars[loop1][loop2]) + continue; + + bb2 = &bbox[loop2]; + + VECTOR box_pointsy3[4] = { + {bb1->x0 * 16, bb1->y0 * 16, bb1->z0 * 16, 0}, // front left + {bb2->x0 * 16, bb2->y0 * 16, bb2->z0 * 16, 0}, // front right + {bb1->x1 * 16, bb1->y0 * 16, bb1->z1 * 16, 0}, // back right + {bb2->x0 * 16, bb2->y0 * 16, bb2->z1 * 16, 0}, // back left + }; + + Debug_AddLine(box_pointsy3[0], box_pointsy3[1], bbcv); + Debug_AddLine(box_pointsy3[1], box_pointsy3[2], bbcv); + Debug_AddLine(box_pointsy3[2], box_pointsy3[3], bbcv); + Debug_AddLine(box_pointsy3[3], box_pointsy3[0], bbcv); + } + } } #endif diff --git a/src_rebuild/Game/C/mc_snd.c b/src_rebuild/Game/C/mc_snd.c index b70b14170..ae42be8a2 100644 --- a/src_rebuild/Game/C/mc_snd.c +++ b/src_rebuild/Game/C/mc_snd.c @@ -216,12 +216,18 @@ void InitializeCutsceneSound(int cutscene) int i; cutscene_timer = 0; - i = 0; - while (i < 8) +#ifndef PSX + for (i = 0; i < MAX_CARS; i++) { - force_idle[i] = -1; - force_siren[i++] = 0; + CARNOISE_CLEAR_FLAG(i, CARNOISE_FLAG_FORCE_IDLE|CARNOISE_FLAG_FORCE_SIREN); } +#else + for (i = 0; i < 8; i++) + { + CARNOISE_CLEAR_FORCED_IDLE(i); + CARNOISE_CLEAR_FORCED_SIREN(i); + } +#endif } @@ -240,9 +246,9 @@ void DoCutsceneSound(void) return; if (cutscene_timer > 74) - force_idle[1] = -1; + CARNOISE_CLEAR_FORCED_IDLE(1); else - force_idle[1] = 0; + CARNOISE_SET_FORCED_IDLE(1); break; case 5: if (gInGameCutsceneID != 0) @@ -250,18 +256,18 @@ void DoCutsceneSound(void) if (cutscene_timer > 150) { - force_siren[2] = 1; - force_siren[1] = 1; + CARNOISE_SET_FORCED_SIREN(2); + CARNOISE_SET_FORCED_SIREN(1); } else if (cutscene_timer > 140) { - force_siren[1] = 1; - force_siren[2] = 0; + CARNOISE_SET_FORCED_SIREN(1); + CARNOISE_CLEAR_FORCED_SIREN(2); } else { - force_siren[1] = 0; - force_siren[2] = 0; + CARNOISE_CLEAR_FORCED_SIREN(1); + CARNOISE_CLEAR_FORCED_SIREN(2); } break; @@ -269,14 +275,14 @@ void DoCutsceneSound(void) if (gInGameCutsceneID == 0) { if (cutscene_timer < 100) - force_idle[1] = 0; + CARNOISE_SET_FORCED_IDLE(1); else - force_idle[1] = -1; + CARNOISE_CLEAR_FORCED_IDLE(1); } if (gInGameCutsceneID != 1) return; - force_idle[1] = 0; + CARNOISE_SET_FORCED_IDLE(1); break; case 18: if (gInGameCutsceneID == 0) @@ -308,8 +314,8 @@ void DoCutsceneSound(void) if (gInGameCutsceneID != 0) return; - force_siren[2] = 1; - force_siren[1] = 1; + CARNOISE_SET_FORCED_SIREN(2); + CARNOISE_SET_FORCED_SIREN(1); break; case 27: if (gInGameCutsceneID != 0) @@ -318,12 +324,12 @@ void DoCutsceneSound(void) if (cutscene_timer == 460) { Start3DTrackingSound(-1, SOUND_BANK_MISSION, GetMissionSound(24), (VECTOR*)car_data[2].hd.where.t, NULL); - force_siren[7] = 1; - force_siren[6] = 1; - force_siren[5] = 1; - force_siren[4] = 1; - force_siren[3] = 1; - force_siren[2] = 1; + CARNOISE_SET_FORCED_SIREN(7); + CARNOISE_SET_FORCED_SIREN(6); + CARNOISE_SET_FORCED_SIREN(5); + CARNOISE_SET_FORCED_SIREN(4); + CARNOISE_SET_FORCED_SIREN(3); + CARNOISE_SET_FORCED_SIREN(2); } if (cutscene_timer == 510) @@ -332,7 +338,7 @@ void DoCutsceneSound(void) if (cutscene_timer < 51) return; - force_idle[1] = 0; + CARNOISE_SET_FORCED_IDLE(1); break; case 29: @@ -350,9 +356,9 @@ void DoCutsceneSound(void) } if (cutscene_timer < 641) - force_siren[3] = 0; + CARNOISE_CLEAR_FORCED_SIREN(3); else - force_siren[3] = 1; + CARNOISE_SET_FORCED_SIREN(3); } break; case 33: @@ -365,7 +371,7 @@ void DoCutsceneSound(void) if (cutscene_timer == 960) SetEnvSndVol(rio_alarm, 3000); - force_idle[1] = 0; + CARNOISE_SET_FORCED_IDLE(1); break; } diff --git a/src_rebuild/Game/C/mission.c b/src_rebuild/Game/C/mission.c index 5ef2bac36..4dcbb8393 100644 --- a/src_rebuild/Game/C/mission.c +++ b/src_rebuild/Game/C/mission.c @@ -1303,15 +1303,43 @@ int Swap2Cars(int curslot, int newslot) memcpy((u_char*)&car_data[curslot], (u_char*)&cd, sizeof(CAR_DATA)); // [A] event - swap cars on boat - tmp = carsOnBoat & (1 << newslot); - carsOnBoat &= ~(1 << newslot); +#ifndef PSX + tmp = carsOnBoat.cars[newslot]; + if (carsOnBoat.cars[curslot]) + { + if (!tmp) + { + carsOnBoat.cars[newslot] = 1; + carsOnBoat.count++; + } + } + else + { + if (tmp) + { + carsOnBoat.cars[newslot] = 0; + carsOnBoat.count--; + } + } + + if (tmp && carsOnBoat.cars[curslot] == 0) + { + carsOnBoat.cars[curslot] = 1; + carsOnBoat.count++; + } + +#else + tmp = carsOnBoat & (1 << newslot); + if (carsOnBoat & (1 << curslot)) carsOnBoat |= (1 << newslot); + else + carsOnBoat &= ~(1 << newslot); if(tmp) carsOnBoat |= (1 << curslot); - +#endif // swap ids car_data[newslot].id = newslot; car_data[curslot].id = curslot; diff --git a/src_rebuild/Game/dr2limits.h b/src_rebuild/Game/dr2limits.h index c0361c401..b59723dfb 100644 --- a/src_rebuild/Game/dr2limits.h +++ b/src_rebuild/Game/dr2limits.h @@ -17,12 +17,21 @@ #endif #define MAX_MODEL_SLOTS 1536 // DO NOT CHANGE. No effect in upping it - limited by cell types -#define MAX_CARS 20 #define MAX_CAR_MODELS 5 +#ifndef PSX +#define MAX_CARS 64 +#define MAX_PEDESTRIANS 64 +// NB: these are not used in this manner on PC +//#define MAX_SEATED_PEDS 20 +//#define MAX_PLACED_PEDS 15 +#else +#define MAX_CARS 20 // NB: Upper limit is 32 because we use bitfields for optimization! #define MAX_PEDESTRIANS 28 #define MAX_SEATED_PEDS 20 #define MAX_PLACED_PEDS 15 +#endif + #define MAX_EXPLOSION_OBJECTS 5 #define MAX_THROWN_BOMBS 5 #define MAX_MOTION_CAPTURE 24 diff --git a/src_rebuild/Game/dr2types.h b/src_rebuild/Game/dr2types.h index 7b619f257..ea0361a7a 100644 --- a/src_rebuild/Game/dr2types.h +++ b/src_rebuild/Game/dr2types.h @@ -351,7 +351,7 @@ typedef struct _HANDLING_DATA int direction; int front_vel; int rear_vel; - int mayBeColliding; // [A] now used as a bitfield to create collision pairs + int mayBeColliding; // [A][PSX] now used as a bitfield to create collision pairs short revs; char gear; char changingGear; From 55430ff2a1f95f7df5a20723443933296d2bb343 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 17 Jun 2022 18:00:47 -0700 Subject: [PATCH 05/78] Improve draw performance of many cars at once. - PRIMTAB_SIZE has also been increased due to this change --- src_rebuild/Game/C/cars.c | 20 ++++++++++++-------- src_rebuild/Game/C/cars.h | 6 ++++++ src_rebuild/Game/C/draw.c | 25 +++++++++++++++---------- src_rebuild/Game/C/system.h | 2 +- 4 files changed, 34 insertions(+), 19 deletions(-) diff --git a/src_rebuild/Game/C/cars.c b/src_rebuild/Game/C/cars.c index f89541f0e..39eb2c524 100644 --- a/src_rebuild/Game/C/cars.c +++ b/src_rebuild/Game/C/cars.c @@ -29,13 +29,6 @@ struct plotCarGlobals u_char* damageLevel; }; - -#ifndef PSX -#define CAR_LOD_SWITCH_DISTANCE switch_detail_distance -#else -#define CAR_LOD_SWITCH_DISTANCE 5500 -#endif - MATRIX light_matrix = { { @@ -1508,11 +1501,22 @@ void DrawCar(CAR_DATA* cp, int view) AddSmokingEngine(cp, doSmoke - 1, WheelSpeed); #if ENABLE_GAME_ENCHANCEMENTS - AddExhaustSmoke(cp, doSmoke > 1, WheelSpeed); + if (pos.vz < (CAR_LOD_SWITCH_DISTANCE / 2) + 750) + AddExhaustSmoke(cp, doSmoke > 1, WheelSpeed); #endif +#ifndef PSX + SetShadowPoints(cp, corners); + + // do simple shadows when further away + if (pos.vz >= CAR_LOD_SWITCH_DISTANCE / 4) + PlaceShadowForCar(corners, 0, 10, yVal < 0 ? 0 : 2); + else + PlaceShadowForCar(corners, 4, 10, yVal < 0 ? 0 : 2); +#else SetShadowPoints(cp, corners); PlaceShadowForCar(corners, 4, 10, yVal < 0 ? 0 : 2); +#endif ComputeCarLightingLevels(cp, 1); diff --git a/src_rebuild/Game/C/cars.h b/src_rebuild/Game/C/cars.h index 072790a04..56d65ba49 100644 --- a/src_rebuild/Game/C/cars.h +++ b/src_rebuild/Game/C/cars.h @@ -6,6 +6,12 @@ #define IS_ROADBLOCK_CAR(cp) (cp->controlType == CONTROL_TYPE_CIV_AI && (cp->controlFlags & CONTROL_FLAG_COP_SLEEPING)) +#ifndef PSX +#define CAR_LOD_SWITCH_DISTANCE (switch_detail_distance+500) +#else +#define CAR_LOD_SWITCH_DISTANCE 5500 +#endif + // PHYSICS extern CAR_DATA car_data[MAX_CARS + 2]; // all cars + Tanner cbox + Camera cbox diff --git a/src_rebuild/Game/C/draw.c b/src_rebuild/Game/C/draw.c index 9e4916fc1..c92518487 100644 --- a/src_rebuild/Game/C/draw.c +++ b/src_rebuild/Game/C/draw.c @@ -514,18 +514,14 @@ void DrawAllTheCars(int view) else dist = dx + dz / 2; -#ifdef PSX // do not account distance on PC if (dist < 16000) -#endif { car_distance[num_cars_to_draw] = dx + dz; cars_to_draw[num_cars_to_draw] = cp; num_cars_to_draw++; } } - - cp--; - } while (cp >= car_data); + } while (--cp >= car_data); if (num_cars_to_draw != 0) { @@ -554,19 +550,28 @@ void DrawAllTheCars(int view) for (i = 0; i < num_cars_to_draw; i++) { + int pofs = (int)(current->primtab - (current->primptr - PRIMTAB_SIZE)) - 3000; + // Don't exceed draw buffers - if ((int)(current->primtab + (-3000 - (int)(current->primptr - PRIMTAB_SIZE))) < 5800) - return; + if (pofs < 5800) + break; // make cars look uglier - if ((int)(current->primtab + (-3000 - (int)(current->primptr - PRIMTAB_SIZE)) - spacefree) < 5800) + if (pofs - spacefree < 5800) gForceLowDetailCars = 1; - +#ifndef PSX + // [A] make non-player far away cars look uglier + else if (cars_to_draw[i]->controlType != CONTROL_TYPE_PLAYER && car_distance[i] >= CAR_LOD_SWITCH_DISTANCE) + gForceLowDetailCars = 1; + else + gForceLowDetailCars = 0; +#else if (cars_to_draw[i]->controlType == CONTROL_TYPE_PLAYER) gForceLowDetailCars = 0; +#endif DrawCar(cars_to_draw[i], view); - + spacefree -= 2000; } } diff --git a/src_rebuild/Game/C/system.h b/src_rebuild/Game/C/system.h index 5ab055e34..890f71ed1 100644 --- a/src_rebuild/Game/C/system.h +++ b/src_rebuild/Game/C/system.h @@ -140,7 +140,7 @@ extern DRAW_MODE draw_mode_ntsc; #endif #ifdef USE_EXTENDED_PRIM_POINTERS -# define PRIMTAB_SIZE 0x50000 +# define PRIMTAB_SIZE 0xA0000 #else # define PRIMTAB_SIZE 0x1e000 #endif From 88fea59365eb469f917ad201ca5b6a8ab74b5aa1 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 17 Jun 2022 18:38:21 -0700 Subject: [PATCH 06/78] [Frontend] Refactor code + misc. improvements - Added enum for all screen types - PC version of button struct makes use of unused field - Setup some custom colors for PC version of buttons - Fixed flickering of 'Time of Day/Condition' text - Time of Day/Condition is now restored when returning from car select screen --- src_rebuild/Game/Frontend/FEmain.c | 441 +++++++++++++++++++++-------- 1 file changed, 326 insertions(+), 115 deletions(-) diff --git a/src_rebuild/Game/Frontend/FEmain.c b/src_rebuild/Game/Frontend/FEmain.c index ddfc00b6f..6b3286535 100644 --- a/src_rebuild/Game/Frontend/FEmain.c +++ b/src_rebuild/Game/Frontend/FEmain.c @@ -34,16 +34,83 @@ struct PSXBUTTON char Name[32]; }; -struct PSXSCREEN +#ifdef PSX +typedef struct PSXBUTTON FE_BUTTON; +#else +struct FE_BUTTON +{ + short x, y, w, h; + u_char l, r; // left, right next item id + u_char u, d; // up, down next item id + u_char cR, cG, cB, justify; + short s_x, s_y, s_w, s_h; + short action, var; + char Name[32]; +}; + +static_assert(sizeof(FE_BUTTON) == sizeof(PSXBUTTON), "SIZE INVALID"); +#endif + +typedef struct PSXSCREEN { u_char index; u_char numButtons; u_char userFunctionNum; - PSXBUTTON buttons[8]; -}; + FE_BUTTON buttons[8]; +} FE_SCREEN; // #define USE_EMBEDDED_FRONTEND_SCREENS +enum FEScreenType +{ + // Defaults - do not edit + Sc_Main = 0, + Sc_TakeARide = 1, + Sc_Undercover = 2, + Sc_TimeOfDay = 3, + Sc_Replays = 4, + Sc_DrivingGames = 5, + Sc_Multiplayer = 6, + Sc_SubGameType = 7, + Sc_SubGameTime = 8, + Sc_SubGameCity = 9, + Sc_NotAvailable = 10, // unused replay menu? + Sc_GameCity = 11, + Sc_CentreScreen = 12, + Sc_Options = 13, + Sc_CarSelect = 14, + Sc_GameplayOptions = 15, + Sc_CopDifficulty = 16, + Sc_VibrationOnOff = 17, + Sc_MPSubGameCity = 18, + Sc_MissionSelect = 19, + Sc_MissionCity = 20, + Sc_CutSceneCity = 21, + Sc_CutSceneSelect = 22, + Sc_SoundOptions = 23, + Sc_ScoreSelect = 24, + Sc_ScoreMode = 25, + Sc_HighScores = 26, + Sc_SubtitlesOnOff = 27, + Sc_Controller = 28, + Sc_Secrets = 29, + Sc_InvincibleOnOff = 30, + Sc_ImmunityOnOff = 31, + Sc_RaceSelect = 32, + Sc_RaceMode = 33, + Sc_MPCitySelect = 34, + Sc_MPChicagoMode = 35, + Sc_MPHavanaMode = 36, + Sc_MPVegasMode = 37, + Sc_MPRioMode = 38, + + // New entries + Sc_ReplayTheater, + Sc_MiniCarsOnOff, + + Sc_MAX_COUNT = 42, +}; + enum FEButtonAction { BTN_NEXT_SCREEN = 1, @@ -53,12 +120,36 @@ enum FEButtonAction BTN_HIDDEN = 5 }; +enum FEButtonVariable +{ + VAR_NONE = -1, + + // Defaults - do not edit + VAR_GAME_LEVEL = 1, + VAR_GAME_TYPE = 2, + VAR_MULTIPLAYER = 3, + VAR_TIMEOFDAY = 4, + VAR_MISSION_NUMBER = 5, + VAR_LOAD_GAME = 6, + VAR_SAVE_GAME = 7, + VAR_SUB_GAME = 8, + VAR_SUBTITLES = 9, + VAR_INVINCIBILITY = 10, + VAR_IMMUNITY = 11, + VAR_MINIGAME = 12, + VAR_DEMO_CHASE = 13, + + // New entries + VAR_BONUS_GALLERY, + VAR_MINI_CARS, +}; + #define FE_MAKEVAR(code, value) ((code & 0xffff) << 8 | (value & 0xff)) #ifdef USE_EMBEDDED_FRONTEND_SCREENS #include "FEscreens.inc" #else -PSXSCREEN PsxScreens[42]; +FE_SCREEN PsxScreens[Sc_MAX_COUNT]; #endif #define FE_OTSIZE 16 @@ -123,6 +214,8 @@ int MiniCarsOnOffScreen(int bSetup); #define FN_DONE 1 screenFunc fpUserFunctions[] = { + + // Defaults - do not edit CentreScreen, CarSelectScreen, CopDiffLevelScreen, @@ -143,10 +236,49 @@ screenFunc fpUserFunctions[] = { GamePlayScreen, GameNameScreen, CheatNumlayerSelect, + + // New entries UserReplaySelectScreen, TimeOfDaySelectScreen, DemoScreen, - MiniCarsOnOffScreen + MiniCarsOnOffScreen, + AdjustDensityScreen, +}; + +// NB: Any changes to 'fpUserFunctions' must be reflected here +enum FEUserFunction +{ + Fn_None = 0, + + // Defaults - do not edit + Fn_CentreScreen = 1, + Fn_CarSelectScreen = 2, + Fn_CopDiffLevelScreen = 3, + Fn_VibroOnOffScreen = 4, + Fn_MissionSelectScreen = 5, + Fn_MissionCityScreen = 6, + Fn_CutSceneCitySelectScreen = 7, + Fn_CutSceneSelectScreen = 8, + Fn_SetVolumeScreen = 9, + Fn_ScoreScreen = 10, + Fn_SubtitlesOnOffScreen = 11, + Fn_CityCutOffScreen = 12, + Fn_ControllerScreen = 13, + Fn_MainScreen = 14, + Fn_CheatScreen = 15, + Fn_ImmunityOnOffScreen = 16, + Fn_InvincibleOnOffScreen = 17, + Fn_GamePlayScreen = 18, + Fn_GameNameScreen = 19, + Fn_CheatNumlayerSelect = 20, + + // New entries + Fn_UserReplaySelectScreen, + Fn_TimeOfDaySelectScreen, + Fn_DemoScreen, + Fn_MiniCarsOnOffScreen, + + Fn_End = 128, }; #define FE_CALLBACK(userFunctionNum) (fpUserFunctions[userFunctionNum - 1]) @@ -441,14 +573,14 @@ char loaded[3] = { -1 // Cuts }; -PSXSCREEN* pCurrScreen = NULL; -PSXSCREEN* pNewScreen = NULL; +FE_SCREEN* pCurrScreen = NULL; +FE_SCREEN* pNewScreen = NULL; -PSXBUTTON* pNewButton = NULL; -PSXBUTTON* pCurrButton = NULL; +FE_BUTTON* pNewButton = NULL; +FE_BUTTON* pCurrButton = NULL; -PSXSCREEN* pScreenStack[10] = { 0 }; -PSXBUTTON* pButtonStack[10] = { 0 }; +FE_SCREEN* pScreenStack[10] = { 0 }; +FE_BUTTON* pButtonStack[10] = { 0 }; POLY_FT4 BackgroundPolys[6]; FE_FONT feFont; @@ -476,28 +608,28 @@ void SetVariable(int var) switch (code) { - case 1: + case VAR_GAME_LEVEL: GameLevel = value; break; - case 2: + case VAR_GAME_TYPE: GameType = (GAMETYPE)value; if (value != GAME_COPSANDROBBERS) gWantNight = 0; break; - case 3: + case VAR_MULTIPLAYER: NumPlayers = (value + 1); break; - case 4: + case VAR_TIMEOFDAY: gWantNight = value > 0; break; - case 5: + case VAR_MISSION_NUMBER: gCurrentMissionNumber = 1; GameType = GAME_MISSION; break; - case 6: + case VAR_LOAD_GAME: pScreenStack[ScreenDepth] = pCurrScreen; pButtonStack[ScreenDepth] = pCurrButton; @@ -530,7 +662,7 @@ void SetVariable(int var) } break; - case 7: + case VAR_SAVE_GAME: pScreenStack[ScreenDepth] = pCurrScreen; pButtonStack[ScreenDepth] = pCurrButton; @@ -552,35 +684,35 @@ void SetVariable(int var) #endif break; - case 8: + case VAR_SUB_GAME: gSubGameNumber = value; break; - case 9: + case VAR_SUBTITLES: gSubtitles = (value == 0) ? 0 : 1; break; - case 10: + case VAR_INVINCIBILITY: gInvincibleCar = value; ActiveCheats.cheat3 = value; break; - case 11: + case VAR_IMMUNITY: gPlayerImmune = value; ActiveCheats.cheat4 = value; break; - case 12: + case VAR_MINIGAME: GameLevel = 3; gSubGameNumber = (value == 0) ? 2 : 0; break; - case 13: + case VAR_DEMO_CHASE: GameType = GAME_IDLEDEMO; gCurrentMissionNumber = (value + 400); break; #if ENABLE_BONUS_CONTENT - case 14: // [A] + case VAR_BONUS_GALLERY: // [A] { ShowBonusGallery(); LoadFrontendScreens(0); } - case 15: // [A] mini cars cheat + case VAR_MINI_CARS: // [A] mini cars cheat { ActiveCheats.cheat13 = value; } @@ -659,7 +791,7 @@ void SetupScreenSprts(PSXSCREEN *pScr) pNewScreen = NULL; pCurrScreen = pScr; - if (pScr->userFunctionNum == 0 || pScr->userFunctionNum == 128 || FE_INIT_SCREEN(pScr) == FN_OK) + if (pScr->userFunctionNum == Fn_None || pScr->userFunctionNum == Fn_End || FE_INIT_SCREEN(pScr) == FN_OK) { if (pNewButton != NULL) { @@ -675,7 +807,18 @@ DR_MOVE In; DR_MOVE Out; RECT16 storeRect = { 768, 475, 255, 36 }; +char* TimeOfDayNames[] = { + G_LTXT_ID(GTXT_Dawn), + G_LTXT_ID(GTXT_Day), + G_LTXT_ID(GTXT_Dusk), + G_LTXT_ID(GTXT_Night) +}; +char* WeatherNames[] = { + G_LTXT_ID(GTXT_Clear), + G_LTXT_ID(GTXT_Rainy), + G_LTXT_ID(GTXT_Wet), +}; // [D] [T] void DisplayOnScreenText(void) @@ -721,10 +864,16 @@ void DisplayOnScreenText(void) FEPrintStringSized(text, 100, 226, 0xc00, 1, 64, 64, 64); } + + if (iScreenSelect == SCREEN_TIMEOFDAY) + { + FEPrintString(GET_GAME_TXT(TimeOfDayNames[wantedTimeOfDay]), 596, 208, 4, 128, 128, 128); + FEPrintString(GET_GAME_TXT(WeatherNames[wantedWeather]), 596, 246, 4, 128, 128, 128); + } } } -void DrawButton(PSXBUTTON* pBtn, int i) +void DrawButton(FE_BUTTON* pBtn, int i) { int status = pBtn->action >> 8; @@ -739,6 +888,10 @@ void DrawButton(PSXBUTTON* pBtn, int i) rect.x = pCurrButton->s_x; rect.y = pCurrButton->s_y; +#ifndef PSX + rect.w = pCurrButton->s_w; + rect.h = pCurrButton->s_h; +#endif hghltSprt = (SPRT*)current->primptr; current->primptr += sizeof(SPRT); @@ -749,6 +902,9 @@ void DrawButton(PSXBUTTON* pBtn, int i) *hghltDummy = HighlightDummy; setXY0(hghltSprt, rect.x, rect.y); +#ifndef PSX + setWH(hghltSprt, rect.w, rect.h); +#endif addPrim(current->ot + 6, hghltSprt); addPrim(current->ot + 6, hghltDummy); @@ -761,10 +917,17 @@ void DrawButton(PSXBUTTON* pBtn, int i) { if (status == BTN_DISABLED) { +#ifndef PSX + FEPrintString(pBtn->Name, pBtn->x * 2 + pBtn->w, pBtn->y, pBtn->justify, 32, 32, 32); +#else FEPrintString(pBtn->Name, pBtn->x * 2 + pBtn->w, pBtn->y, 4, 32, 32, 32); +#endif } else { +#ifndef PSX + FEPrintString(pBtn->Name, pBtn->x * 2 + pBtn->w, pBtn->y, pBtn->justify, pBtn->cR, pBtn->cG, pBtn->cB); +#else if (iScreenSelect == SCREEN_MISSION && (i == 0 || i == 5) || iScreenSelect == SCREEN_CAR && (i == 0 || i == 2) || iScreenSelect == SCREEN_CUTSCENE && (i == 0 || i == 2) || @@ -776,6 +939,7 @@ void DrawButton(PSXBUTTON* pBtn, int i) { FEPrintString(pBtn->Name, pBtn->x * 2 + pBtn->w, pBtn->y, 4, 128, 128, 128); } +#endif } } } @@ -1048,33 +1212,66 @@ void LoadFrontendScreens(int full) for (int j = 0; j < PsxScreens[i].numButtons; j++) { +#ifndef PSX + PSXBUTTON *pPSXBtn = (PSXBUTTON*)ptr; + FE_BUTTON *pBtn = &PsxScreens[i].buttons[j]; + + // copy everything into our struct + memcpy((u_char*)pBtn, (u_char*)ptr, sizeof(PSXBUTTON)); + ptr += sizeof(PSXBUTTON); + + // fixup our struct + pBtn->justify = 4; + + pBtn->s_w = 256; + pBtn->s_h = 36; + + pBtn->action = (short)pPSXBtn->action; + pBtn->var = (short)pPSXBtn->var; + + if (i == Sc_MissionSelect && (j == 0 || j == 5) || + i == Sc_CarSelect && (j == 0 || j == 2) || + i == Sc_CutSceneSelect && (j == 0 || j == 2)) + { + pBtn->cR = 124; + pBtn->cG = 108; + pBtn->cB = 40; + } + else + { + pBtn->cR = 128; + pBtn->cG = 128; + pBtn->cB = 128; + } +#else memcpy((u_char*)&PsxScreens[i].buttons[j], (u_char*)ptr, sizeof(PSXBUTTON)); ptr += sizeof(PSXBUTTON); +#endif } } // [A] SCREEN HACKS // Time of day extended screen - PsxScreens[3].userFunctionNum = 22; // TimeOfDaySelectScreen + PsxScreens[Sc_TimeOfDay].userFunctionNum = Fn_TimeOfDaySelectScreen; // for web demo content (or empty SCRS.BIN) - if (PsxScreens[0].userFunctionNum == 128) - PsxScreens[0].userFunctionNum = 23; // DemoScreen + if (PsxScreens[Sc_Main].userFunctionNum == Fn_End) + PsxScreens[Sc_Main].userFunctionNum = Fn_DemoScreen; #ifndef PSX // replay theater - PsxScreens[4].buttons[0].action = FE_MAKEVAR(BTN_NEXT_SCREEN, 39); - PsxScreens[4].buttons[0].var = -1; - PsxScreens[39].userFunctionNum = 21; // UserReplaySelectScreen + PsxScreens[Sc_Replays].buttons[0].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_ReplayTheater); + PsxScreens[Sc_Replays].buttons[0].var = VAR_NONE; + PsxScreens[Sc_ReplayTheater].userFunctionNum = Fn_UserReplaySelectScreen; #endif // PSX #if ENABLE_BONUS_CONTENT // make mini cars cheat screen - PsxScreens[40] = PsxScreens[31]; - PsxScreens[40].userFunctionNum = 24; // MiniCarsOnOffScreen - PsxScreens[40].buttons[0].var = FE_MAKEVAR(15, 1); - PsxScreens[40].buttons[1].var = FE_MAKEVAR(15, 0); + PsxScreens[Sc_MiniCarsOnOff] = PsxScreens[Sc_ImmunityOnOff]; + PsxScreens[Sc_MiniCarsOnOff].userFunctionNum = Fn_MiniCarsOnOffScreen; + PsxScreens[Sc_MiniCarsOnOff].buttons[0].var = FE_MAKEVAR(VAR_MINI_CARS, 1); + PsxScreens[Sc_MiniCarsOnOff].buttons[1].var = FE_MAKEVAR(VAR_MINI_CARS, 0); #endif } #endif @@ -1196,7 +1393,7 @@ void ReInitScreens(int returnToMain) // [A] state hack for demo if (pCurrScreen == NULL) - pCurrScreen = &PsxScreens[0]; + pCurrScreen = &PsxScreens[Sc_Main]; SetupScreenSprts(pCurrScreen); SetupBackgroundPolys(); @@ -1207,7 +1404,7 @@ void ReInitScreens(int returnToMain) // [D] [T] void NewSelection(short dir) { - PSXBUTTON *pNewB; + FE_BUTTON *pNewB; RECT16 rect; if (pCurrScreen->numButtons == 0) @@ -1280,7 +1477,7 @@ int HandleKeyPress(void) if (pCurrScreen == NULL || pCurrButton == NULL) return 0; - if (pCurrScreen->userFunctionNum != 0) + if (pCurrScreen->userFunctionNum != Fn_None) { // notify the user function first if (FE_STEP_SCREEN(pCurrScreen) != FN_OK) @@ -1298,7 +1495,7 @@ int HandleKeyPress(void) { FESound(2); - if (pCurrButton->var != -1) + if (pCurrButton->var != VAR_NONE) SetVariable(pCurrButton->var); switch (action) @@ -1458,7 +1655,7 @@ void PadChecks(void) { allowVibration = 0; - if (pCurrScreen->userFunctionNum == 18) + if (pCurrScreen->userFunctionNum == Fn_GamePlayScreen) { bRedrawFrontend = 1; GamePlayScreen(1); @@ -1471,7 +1668,7 @@ void PadChecks(void) { allowVibration = 1; - if (pCurrScreen->userFunctionNum == 18) + if (pCurrScreen->userFunctionNum == Fn_GamePlayScreen) { bRedrawFrontend = 1; GamePlayScreen(1); @@ -1487,7 +1684,7 @@ void PadChecks(void) bRedrawFrontend = 1; feNewPad = 0x10; - if (pCurrScreen->userFunctionNum != 0) + if (pCurrScreen->userFunctionNum != Fn_None) { FE_STEP_SCREEN(pCurrScreen); } @@ -1500,7 +1697,7 @@ void PadChecks(void) } } if (bRedrawFrontend == 0 && numPadsConnected != oldnum && - (gInFrontend != 0 && (pCurrScreen != NULL && pCurrScreen->userFunctionNum != 0))) + (gInFrontend != 0 && (pCurrScreen != NULL && pCurrScreen->userFunctionNum != Fn_None))) { FE_INIT_SCREEN(pCurrScreen); bRedrawFrontend = 1; @@ -1561,7 +1758,7 @@ void InitFrontend(void) LoadFrontendScreens(1); SetupBackgroundPolys(); - SetupScreenSprts(&PsxScreens[0]); + SetupScreenSprts(&PsxScreens[Sc_Main]); // load frontend bank LoadBankFromLump(SOUND_BANK_SFX, SBK_ID_MENU); @@ -1999,9 +2196,9 @@ int CarSelectScreen(int bSetup) LoadBackgroundFile("DATA\\CARS\\CARBACK.RAW"); - if (feVariableSave[0] != -1) + if (feVariableSave[2] != -1) { - carSelection = feVariableSave[0]; + carSelection = feVariableSave[2]; SetupExtraPoly(gfxNames[GameLevel], carSelection, 0); } else @@ -2022,10 +2219,10 @@ int CarSelectScreen(int bSetup) } } - feVariableSave[0] = -1; - feVariableSave[1] = -1; - feVariableSave[2] = -1; - feVariableSave[3] = -1; + //feVariableSave[0] = -1; + //feVariableSave[1] = -1; + //feVariableSave[2] = -1; + //feVariableSave[3] = -1; lastCutCity = -1; currSelIndex = 1; @@ -2059,6 +2256,8 @@ int CarSelectScreen(int bSetup) } #endif currPlayer = 1; + feVariableSave[2] = carSelection; + iScreenSelect = SCREEN_NONE; } @@ -2095,7 +2294,7 @@ int CarSelectScreen(int bSetup) // select the vehicle if (currPlayer == 1) { - feVariableSave[0] = carSelection; + feVariableSave[2] = carSelection; wantedCar[0] = carNumLookup[GameLevel][carSelection]; } else { @@ -2434,31 +2633,31 @@ int MissionCityScreen(int bSetup) } else if (gFurthestMission < 10) { - pCurrScreen->buttons[0].action = FE_MAKEVAR(BTN_NEXT_SCREEN, 19); + pCurrScreen->buttons[0].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_MissionSelect); pCurrScreen->buttons[1].action = FE_MAKEVAR(BTN_DISABLED, 0); pCurrScreen->buttons[2].action = FE_MAKEVAR(BTN_DISABLED, 0); pCurrScreen->buttons[3].action = FE_MAKEVAR(BTN_DISABLED, 0); } else if (gFurthestMission < 21) { - pCurrScreen->buttons[0].action = FE_MAKEVAR(BTN_NEXT_SCREEN, 19); - pCurrScreen->buttons[1].action = FE_MAKEVAR(BTN_NEXT_SCREEN, 19); + pCurrScreen->buttons[0].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_MissionSelect); + pCurrScreen->buttons[1].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_MissionSelect); pCurrScreen->buttons[2].action = FE_MAKEVAR(BTN_DISABLED, 0); pCurrScreen->buttons[3].action = FE_MAKEVAR(BTN_DISABLED, 0); } else if (gFurthestMission < 31) { - pCurrScreen->buttons[0].action = FE_MAKEVAR(BTN_NEXT_SCREEN, 19); - pCurrScreen->buttons[1].action = FE_MAKEVAR(BTN_NEXT_SCREEN, 19); - pCurrScreen->buttons[2].action = FE_MAKEVAR(BTN_NEXT_SCREEN, 19); + pCurrScreen->buttons[0].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_MissionSelect); + pCurrScreen->buttons[1].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_MissionSelect); + pCurrScreen->buttons[2].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_MissionSelect); pCurrScreen->buttons[3].action = FE_MAKEVAR(BTN_DISABLED, 0); } else { - pCurrScreen->buttons[0].action = FE_MAKEVAR(BTN_NEXT_SCREEN, 19); - pCurrScreen->buttons[1].action = FE_MAKEVAR(BTN_NEXT_SCREEN, 19); - pCurrScreen->buttons[2].action = FE_MAKEVAR(BTN_NEXT_SCREEN, 19); - pCurrScreen->buttons[3].action = FE_MAKEVAR(BTN_NEXT_SCREEN, 19); + pCurrScreen->buttons[0].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_MissionSelect); + pCurrScreen->buttons[1].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_MissionSelect); + pCurrScreen->buttons[2].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_MissionSelect); + pCurrScreen->buttons[3].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_MissionSelect); } LoadBackgroundFile("DATA\\CITYBACK.RAW"); @@ -2680,31 +2879,31 @@ int CutSceneCitySelectScreen(int bSetup) } else if (gFurthestMission < 10) { - pCurrScreen->buttons[0].action = FE_MAKEVAR(BTN_NEXT_SCREEN, 22); + pCurrScreen->buttons[0].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_CutSceneSelect); pCurrScreen->buttons[1].action = FE_MAKEVAR(BTN_DISABLED, 0); pCurrScreen->buttons[2].action = FE_MAKEVAR(BTN_DISABLED, 0); pCurrScreen->buttons[3].action = FE_MAKEVAR(BTN_DISABLED, 0); } else if (gFurthestMission < 21) { - pCurrScreen->buttons[0].action = FE_MAKEVAR(BTN_NEXT_SCREEN, 22); - pCurrScreen->buttons[1].action = FE_MAKEVAR(BTN_NEXT_SCREEN, 22); + pCurrScreen->buttons[0].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_CutSceneSelect); + pCurrScreen->buttons[1].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_CutSceneSelect); pCurrScreen->buttons[2].action = FE_MAKEVAR(BTN_DISABLED, 0); pCurrScreen->buttons[3].action = FE_MAKEVAR(BTN_DISABLED, 0); } else if (gFurthestMission < 31) { - pCurrScreen->buttons[0].action = FE_MAKEVAR(BTN_NEXT_SCREEN, 22); - pCurrScreen->buttons[1].action = FE_MAKEVAR(BTN_NEXT_SCREEN, 22); - pCurrScreen->buttons[2].action = FE_MAKEVAR(BTN_NEXT_SCREEN, 22); + pCurrScreen->buttons[0].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_CutSceneSelect); + pCurrScreen->buttons[1].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_CutSceneSelect); + pCurrScreen->buttons[2].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_CutSceneSelect); pCurrScreen->buttons[3].action = FE_MAKEVAR(BTN_DISABLED, 0); } else { - pCurrScreen->buttons[0].action = FE_MAKEVAR(BTN_NEXT_SCREEN, 22); - pCurrScreen->buttons[1].action = FE_MAKEVAR(BTN_NEXT_SCREEN, 22); - pCurrScreen->buttons[2].action = FE_MAKEVAR(BTN_NEXT_SCREEN, 22); - pCurrScreen->buttons[3].action = FE_MAKEVAR(BTN_NEXT_SCREEN, 22); + pCurrScreen->buttons[0].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_CutSceneSelect); + pCurrScreen->buttons[1].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_CutSceneSelect); + pCurrScreen->buttons[2].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_CutSceneSelect); + pCurrScreen->buttons[3].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_CutSceneSelect); if (gFurthestMission == 40) { @@ -3277,7 +3476,7 @@ int MainScreen(int bSetup) { if (numPadsConnected == 2) { - pCurrScreen->buttons[3].action = FE_MAKEVAR(BTN_NEXT_SCREEN, 6); + pCurrScreen->buttons[3].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_Multiplayer); } else { @@ -3309,21 +3508,21 @@ int CheatScreen(int bSetup) int evilRuss[6]; int hackLookup1[6] = { - FE_MAKEVAR(BTN_NEXT_SCREEN, 33), - FE_MAKEVAR(BTN_NEXT_SCREEN, 33), - FE_MAKEVAR(BTN_NEXT_SCREEN, 30), - FE_MAKEVAR(BTN_NEXT_SCREEN, 31), - FE_MAKEVAR(BTN_NEXT_SCREEN, 40), + FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_RaceMode), + FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_RaceMode), + FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_InvincibleOnOff), + FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_ImmunityOnOff), + FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_MiniCarsOnOff), 0, }; int hackLookup2[6] = { - FE_MAKEVAR(12, 1), - FE_MAKEVAR(12, 0), + FE_MAKEVAR(VAR_MINIGAME, 1), + FE_MAKEVAR(VAR_MINIGAME, 0), -1, -1, -1, - FE_MAKEVAR(14, 0), + FE_MAKEVAR(VAR_BONUS_GALLERY, 0), }; if (bSetup == 0) @@ -3544,7 +3743,7 @@ int GamePlayScreen(int bSetup) { if (bSetup) { - pCurrScreen->buttons[2].action = (allowVibration == 0) ? FE_MAKEVAR(BTN_DISABLED, 0) : FE_MAKEVAR(BTN_NEXT_SCREEN, 17); + pCurrScreen->buttons[2].action = (allowVibration == 0) ? FE_MAKEVAR(BTN_DISABLED, 0) : FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_VibrationOnOff); } return FN_OK; @@ -3582,7 +3781,7 @@ int CheatNumlayerSelect(int bSetup) { if (numPadsConnected == 2) { - pCurrScreen->buttons[1].action = FE_MAKEVAR(BTN_NEXT_SCREEN, 32); + pCurrScreen->buttons[1].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_RaceSelect); } else { @@ -3611,10 +3810,10 @@ int BuildButtonsVertical(int count, int xStart, int yStart) if (nextButton >= numButtons) nextButton -= numButtons; - PSXBUTTON& btn = pCurrScreen->buttons[i]; + FE_BUTTON& btn = pCurrScreen->buttons[i]; // copy button 0 - btn = PsxScreens[4].buttons[0]; + btn = PsxScreens[Sc_Replays].buttons[0]; btn.u = prevButton + 1; btn.d = nextButton + 1; @@ -3687,7 +3886,7 @@ int UserReplaySelectScreen(int bSetup) for (int i = 0; i < numButtons; i++) { - PSXBUTTON& btn = pCurrScreen->buttons[i]; + FE_BUTTON& btn = pCurrScreen->buttons[i]; strncpy(btn.Name, gFEReplayList[i], sizeof(btn.Name)); tmp = strchr(btn.Name, '.'); @@ -3702,7 +3901,7 @@ int UserReplaySelectScreen(int bSetup) { BuildButtonsVertical(1, 160, 208); - PSXBUTTON& btn = pCurrScreen->buttons[0]; + FE_BUTTON& btn = pCurrScreen->buttons[0]; btn.action = FE_MAKEVAR(BTN_PREVIOUS_SCREEN, 0); strcpy(btn.Name, G_LTXT(GTXT_NoSavedData)); } @@ -3736,19 +3935,6 @@ int UserReplaySelectScreen(int bSetup) return FN_OK; } -char* TimeOfDayNames[] = { - G_LTXT_ID(GTXT_Dawn), - G_LTXT_ID(GTXT_Day), - G_LTXT_ID(GTXT_Dusk), - G_LTXT_ID(GTXT_Night) -}; - -char* WeatherNames[] = { - G_LTXT_ID(GTXT_Clear), - G_LTXT_ID(GTXT_Rainy), - G_LTXT_ID(GTXT_Wet), -}; - char* TimeOfDayItems[] = { G_LTXT_ID(GTXT_TimeOfDay), G_LTXT_ID(GTXT_Condition), @@ -3765,45 +3951,70 @@ int TimeOfDaySelectScreen(int bSetup) if (bSetup) { // setup time we want to reset it - wantedWeather = 0; - wantedTimeOfDay = TIME_DAY; + if (feVariableSave[0] == -1) + { + wantedTimeOfDay = TIME_DAY; + wantedWeather = 0; + } + else + { + wantedTimeOfDay = feVariableSave[0]; + wantedWeather = feVariableSave[1]; + } numButtons = BuildButtonsVertical(3, 168, 208); for (i = 0; i < numButtons; i++) { - PSXBUTTON& btn = pCurrScreen->buttons[i]; + FE_BUTTON& btn = pCurrScreen->buttons[i]; sprintf(btn.Name, "%s%c", GET_GAME_TXT(TimeOfDayItems[i]), i == 2 ? 0 : ':'); if (i == 2) { btn.y += 32; btn.s_y += 32; - btn.action = FE_MAKEVAR(BTN_NEXT_SCREEN, 14); + btn.action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_CarSelect); +#ifndef PSX + btn.cR = 124; + btn.cG = 108; + btn.cB = 40; +#endif } else { - btn.x -= 80; + btn.x -= 50; btn.l = btn.r = i + 1; +#ifndef PSX + btn.cR = 124; + btn.cG = 76; + btn.cB = 20; +#endif } } - pNewButton = &pCurrScreen->buttons[2]; + pCurrButton = &pCurrScreen->buttons[2]; iScreenSelect = SCREEN_TIMEOFDAY; - return FN_OK; + return FN_DONE; } - FEPrintString(GET_GAME_TXT(TimeOfDayNames[wantedTimeOfDay]), 590, ypos[0], 4, 128, 128, 128); - FEPrintString(GET_GAME_TXT(WeatherNames[wantedWeather]), 590, ypos[1], 4, 128, 128, 128); + //FEPrintString(GET_GAME_TXT(TimeOfDayNames[wantedTimeOfDay]), 590, ypos[0], 4, 128, 128, 128); + //FEPrintString(GET_GAME_TXT(WeatherNames[wantedWeather]), 590, ypos[1], 4, 128, 128, 128); if (feNewPad & MPAD_TRIANGLE) { // reset back - wantedWeather = -1; wantedTimeOfDay = -1; + wantedWeather = -1; + + feVariableSave[3] = -1; + feVariableSave[2] = -1; + feVariableSave[1] = -1; + feVariableSave[0] = -1; iScreenSelect = SCREEN_NONE; + + return FN_OK; } dir = 0; @@ -3812,7 +4023,7 @@ int TimeOfDaySelectScreen(int bSetup) { dir = -1; } - else if (feNewPad & MPAD_D_RIGHT) + else if (feNewPad & (MPAD_D_RIGHT | MPAD_CROSS)) { dir = 1; } @@ -3825,6 +4036,7 @@ int TimeOfDaySelectScreen(int bSetup) { wantedTimeOfDay += dir; wantedTimeOfDay &= 3; + feVariableSave[0] = wantedTimeOfDay; gWantNight = wantedTimeOfDay == TIME_DUSK || wantedTimeOfDay == TIME_NIGHT; } @@ -3835,9 +4047,8 @@ int TimeOfDaySelectScreen(int bSetup) wantedWeather += 3; else if (wantedWeather >= 3) wantedWeather -= 3; + feVariableSave[1] = wantedWeather; } - else - dir = 0; } return FN_OK; From ec43cc620c891915ebbac48c2e384f074ad8f240 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 17 Jun 2022 18:40:11 -0700 Subject: [PATCH 07/78] [Frontend] Add Traffic/Pedestrian Density screens. - TODO: Localization entries --- src_rebuild/Game/Frontend/FEmain.c | 126 +++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/src_rebuild/Game/Frontend/FEmain.c b/src_rebuild/Game/Frontend/FEmain.c index 6b3286535..d4c4a2c17 100644 --- a/src_rebuild/Game/Frontend/FEmain.c +++ b/src_rebuild/Game/Frontend/FEmain.c @@ -107,6 +107,7 @@ enum FEScreenType // New entries Sc_ReplayTheater, Sc_MiniCarsOnOff, + Sc_ChangeDensity, Sc_MAX_COUNT = 42, }; @@ -142,6 +143,7 @@ enum FEButtonVariable // New entries VAR_BONUS_GALLERY, VAR_MINI_CARS, + VAR_DENSITY_TYPE, }; #define FE_MAKEVAR(code, value) ((code & 0xffff) << 8 | (value & 0xff)) @@ -210,6 +212,8 @@ int UserReplaySelectScreen(int bSetup); int TimeOfDaySelectScreen(int bSetup); int DemoScreen(int bSetup); int MiniCarsOnOffScreen(int bSetup); +int AdjustDensityScreen(int bSetup); + #define FN_OK 0 #define FN_DONE 1 @@ -277,6 +281,7 @@ enum FEUserFunction Fn_TimeOfDaySelectScreen, Fn_DemoScreen, Fn_MiniCarsOnOffScreen, + Fn_AdjustDensityScreen, Fn_End = 128, }; @@ -565,6 +570,9 @@ int lastCity = -1; int currMission = -1; int missionSetup = 0; +int density_type; +u_char *density_value; + char* ScreenNames[12] = { 0 }; char loaded[3] = { @@ -717,6 +725,23 @@ void SetVariable(int var) ActiveCheats.cheat13 = value; } #endif + case VAR_DENSITY_TYPE: // [A] density type + { + density_type = value; + switch (value) + { + case 0: + density_value = &gExtraConfig.gTrafficDensity; + break; + case 1: + density_value = &gExtraConfig.gPedestrianDensity; + break; + default: + density_value = NULL; + density_type = -1; + break; + } + } } } @@ -1264,6 +1289,58 @@ void LoadFrontendScreens(int full) PsxScreens[Sc_Replays].buttons[0].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_ReplayTheater); PsxScreens[Sc_Replays].buttons[0].var = VAR_NONE; PsxScreens[Sc_ReplayTheater].userFunctionNum = Fn_UserReplaySelectScreen; + + // traffic/pedestrian density menu, copy the Cop Difficulty screen + PsxScreens[Sc_ChangeDensity] = PsxScreens[Sc_CopDifficulty]; + PsxScreens[Sc_ChangeDensity].userFunctionNum = Fn_AdjustDensityScreen; + { + // + // add to end of Gameplay menu + // + + FE_SCREEN *gameplaySc = &PsxScreens[Sc_GameplayOptions]; + FE_BUTTON *btn = &gameplaySc->buttons[gameplaySc->numButtons - 1]; + + int lastButton = gameplaySc->numButtons; + + static char *density_names[] = { + "Traffic Density", + "Peds Density", + }; + + for (int i = 0; i < 2; i++) + { + if (i == 0) + btn->d = lastButton + 1; + else + btn[i].d = lastButton + 1; + + // copy the button + btn[i + 1] = *btn; + + btn[i + 1].u = lastButton; + btn[i + 1].d = 1; + + btn[i + 1].l = 0; + btn[i + 1].r = 0; + + btn[i + 1].s_x = btn->s_x; + btn[i + 1].s_y = btn->s_y + (i + 1) * 38; + + btn[i + 1].x = btn->x; + btn[i + 1].y = btn->y + (i + 1) * 38; + + btn[i + 1].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_ChangeDensity); + btn[i + 1].var = FE_MAKEVAR(VAR_DENSITY_TYPE, i); + + strcpy(btn[i + 1].Name, density_names[i]); + + lastButton = ++gameplaySc->numButtons; + } + + gameplaySc->buttons[0].u = lastButton; + gameplaySc->buttons[lastButton - 1].d = 1; + } #endif // PSX #if ENABLE_BONUS_CONTENT @@ -4092,4 +4169,53 @@ int DemoScreen(int bSetup) return FN_OK; } + +char* DensityItems[] = { + "Low", + "Medium", + "High", + "Ultra", +}; + +int AdjustDensityScreen(int bSetup) +{ + if (bSetup) + { + int numButtons = BuildButtonsVertical(4, 168, 208); + int what = -1; + + if (density_value) + what = *density_value; + + for (int i = 0; i < numButtons; i++) + { + FE_BUTTON& btn = pCurrScreen->buttons[i]; + strcpy(btn.Name, DensityItems[i]); + + btn.action = FE_MAKEVAR(BTN_PREVIOUS_SCREEN, 0); + } + + if (what != -1) + pCurrButton = &pCurrScreen->buttons[what]; + else + pCurrButton = pCurrScreen->buttons; + + return FN_DONE; + } + + if (feNewPad & MPAD_CROSS) + { + if (density_value) + *density_value = (currSelIndex & 3) + 1; + } + else if (feNewPad & MPAD_D_UP) + { + currSelIndex = pCurrButton->u - 1; + } + else if (feNewPad & MPAD_D_DOWN) + { + currSelIndex = pCurrButton->d - 1; + } + + return FN_OK; } \ No newline at end of file From 7a99d9e477891a24f11a15814d390c46c9b618f6 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 17 Jun 2022 18:46:14 -0700 Subject: [PATCH 08/78] Add support for custom traffic/pedestrian densities. --- src_rebuild/Game/C/civ_ai.c | 41 +++++++++++++++++- src_rebuild/Game/C/civ_ai.h | 2 +- src_rebuild/Game/C/cutscene.c | 4 +- src_rebuild/Game/C/main.c | 2 +- src_rebuild/Game/C/mission.c | 11 ++++- src_rebuild/Game/C/pedest.c | 78 +++++++++++++++++++++++++++++++++-- src_rebuild/Game/C/pedest.h | 3 ++ src_rebuild/Game/C/replays.c | 1 + 8 files changed, 131 insertions(+), 11 deletions(-) diff --git a/src_rebuild/Game/C/civ_ai.c b/src_rebuild/Game/C/civ_ai.c index aa1f7d920..93eb47623 100644 --- a/src_rebuild/Game/C/civ_ai.c +++ b/src_rebuild/Game/C/civ_ai.c @@ -25,6 +25,7 @@ #include "overlay.h" #include "cutrecorder.h" #include "draw.h" +#include "glaunch.h" const u_char speedLimits[3] = { 56, 97, 138 }; @@ -1741,8 +1742,30 @@ int TrafficLightCycle(int exit) return 2; } +struct TRAFFIC_DENSITY_DATA +{ + int maxCivCars; + int maxParkedCars; +}; + +TRAFFIC_DENSITY_DATA trafficDensityMap[2][4] = { + { + { 14, 7 }, + { 25, 11 }, + { 40, 24 }, + { 64, 32 }, + }, + { + // recording-specific densities + { 14, 7 }, + { 25, 11 }, + { 32, 24 }, // <-- recordings have fixed limits above Medium + { 32, 24 }, + }, +}; + // [D] [T] -void InitCivCars(void) +void InitCivCars(/*[A]*/int recording) { PingBufferPos = 0; cookieCount = 0; @@ -1763,6 +1786,22 @@ void InitCivCars(void) testNumPingedOut = 0; currentAngle = 0; closeEncounter = 3; + +#ifndef PSX + if (gExtraConfig.gTrafficDensity != 0) + { + TRAFFIC_DENSITY_DATA *trafficDensity = &trafficDensityMap[recording & 1][(gExtraConfig.gTrafficDensity - 1) & 3]; + + maxCivCars = trafficDensity->maxCivCars; + maxParkedCars = trafficDensity->maxParkedCars; + } + else + { + // make sure we always have the bare minimum amount available + maxCivCars = 14; + maxParkedCars = 7; + } +#endif } const int EVENT_CAR_SPEED = 71; diff --git a/src_rebuild/Game/C/civ_ai.h b/src_rebuild/Game/C/civ_ai.h index 069ebf00f..2e74e75a6 100644 --- a/src_rebuild/Game/C/civ_ai.h +++ b/src_rebuild/Game/C/civ_ai.h @@ -23,7 +23,7 @@ extern char makeLimoPullOver; extern char junctionLightsPhase[2]; -extern void InitCivCars(); // 0x0002CDA4 +extern void InitCivCars(int recording); // 0x0002CDA4 extern int InitCar(CAR_DATA *cp, int direction, LONGVECTOR4* startPos, unsigned char control, int model, int palette, char *extraData); // 0x00023DE8 extern int InitCivState(CAR_DATA* cp, EXTRA_CIV_DATA* extraData); // 0x000280D8 diff --git a/src_rebuild/Game/C/cutscene.c b/src_rebuild/Game/C/cutscene.c index 6f5c07c30..9e14a5a4d 100644 --- a/src_rebuild/Game/C/cutscene.c +++ b/src_rebuild/Game/C/cutscene.c @@ -498,7 +498,7 @@ void ReleaseInGameCutscene(void) RestoreGameVars(-1); PingOutAllCivCarsAndCopCars(); - InitCivCars(); + InitCivCars(0); for (i = CutsceneStreamIndex; i < NumReplayStreams; i++) { @@ -672,7 +672,7 @@ int TriggerInGameCutsceneSystem(int cutscene) if (gHaveInGameCutscene != 0) { PingOutAllCivCarsAndCopCars(); - InitCivCars(); + InitCivCars(1); DestroyCivPedestrians(); if (CutsceneStreamIndex <= player[0].playerCarId) diff --git a/src_rebuild/Game/C/main.c b/src_rebuild/Game/C/main.c index c1cc89be9..4fb680927 100644 --- a/src_rebuild/Game/C/main.c +++ b/src_rebuild/Game/C/main.c @@ -2477,7 +2477,7 @@ void InitGameVariables(void) } } - InitCivCars(); + InitCivCars(0); } // [D] [T] diff --git a/src_rebuild/Game/C/mission.c b/src_rebuild/Game/C/mission.c index 4dcbb8393..9a9ee8b4a 100644 --- a/src_rebuild/Game/C/mission.c +++ b/src_rebuild/Game/C/mission.c @@ -238,8 +238,15 @@ void InitialiseMissionDefaults(void) tannerDeathTimer = 0; maxPlayerCars = 1; - maxCivCars = 14; - maxParkedCars = 7; +#ifndef PSX + // make sure we always have the bare minimum amount available + // (just in case InitCivCars didn't go first) + if (gExtraConfig.gTrafficDensity == 0) +#endif + { + maxCivCars = 14; + maxParkedCars = 7; + } maxCopCars = 4; gPlayerDamageFactor = 4096; diff --git a/src_rebuild/Game/C/pedest.c b/src_rebuild/Game/C/pedest.c index 574f64d6c..07dc78fdc 100644 --- a/src_rebuild/Game/C/pedest.c +++ b/src_rebuild/Game/C/pedest.c @@ -100,9 +100,18 @@ LPPEDESTRIAN pUsedPeds = NULL; // linked list of pedestrians LPPEDESTRIAN pFreePeds = NULL; LPPEDESTRIAN pHold = NULL; -int max_pedestrians; +int max_pedestrians = 28; int num_pedestrians; +int max_sitter_peds,max_placed_peds; + +#ifndef PSX +#define MAX_TANNER_PEDS 8 +#define NO_MORE_PEDS() (num_pedestrians >= max_placed_peds) +#else +#define NO_MORE_PEDS() (num_pedestrians >= MAX_PLACED_PEDS) +#endif + char ping_in_pedestrians = 0; int bKilled = 0; @@ -182,6 +191,14 @@ void SetTannerPosition(VECTOR* pVec) } } +#ifndef PSX +static int PED_PING_RADIUS = (250000 << 6); + +int pedestrianDensityMap[] = { 28, 38, 48, 64 }; +#else +const int PED_PING_RADIUS = (250000 << 6); +#endif + // [D] [T] void InitPedestrians(void) { @@ -191,6 +208,13 @@ void InitPedestrians(void) memset((u_char*)pedestrians, 0, sizeof(pedestrians)); DestroyPedestrians(); + max_pedestrians = 28; + +#ifndef PSX + if (gExtraConfig.gPedestrianDensity != 0) + max_pedestrians = pedestrianDensityMap[gExtraConfig.gPedestrianDensity - 1]; +#endif + LPPEDESTRIAN lastPed = &pedestrians[0]; lastPed->pPrev = NULL; @@ -203,6 +227,17 @@ void InitPedestrians(void) currPed->pPrev = lastPed++; } +#ifndef PSX + // terminate linked-list earlier if needed + if (max_pedestrians < MAX_PEDESTRIANS) + { + lastPed = &pedestrians[max_pedestrians - 1]; + + // break the chain + lastPed->pNext->pPrev = NULL; + } +#endif + lastPed->pNext = NULL; pUsedPeds = NULL; @@ -228,6 +263,23 @@ void InitPedestrians(void) seated_count = 0; ping_in_pedestrians = 1; numCopPeds = 0; + +#ifndef PSX + int peds_available = (max_pedestrians-MAX_TANNER_PEDS); + + if (peds_available > 20) + { + // smoothly ramp up clustering factor when not using defaults + PED_PING_RADIUS = ((250000 >> (peds_available / 20)) << 6); + } + else + { + PED_PING_RADIUS = (250000 << 6); + } + + max_sitter_peds = peds_available / 4; + max_placed_peds = peds_available - max_sitter_peds; +#endif } // [D] [T] @@ -422,7 +474,7 @@ int CreatePedAtLocation(LONGVECTOR4* pPos, int pedType) { LPPEDESTRIAN pPed; - if (num_pedestrians >= MAX_PLACED_PEDS) + if ( NO_MORE_PEDS() ) return 0; pPed = CreatePedestrian(); @@ -1426,7 +1478,7 @@ void PingInPedestrians(void) VECTOR randomLoc; VECTOR baseLoc; - if (num_pedestrians >= MAX_PLACED_PEDS || pFreePeds == NULL || pFreePeds->pNext == NULL) + if (NO_MORE_PEDS() || pFreePeds == NULL || pFreePeds->pNext == NULL) return; baseLoc.vx = player[0].pos[0]; @@ -1461,7 +1513,7 @@ void PingInPedestrians(void) bFound = 0; - while (dx * dx + dz * dz > 15999999) + while (dx * dx + dz * dz >= PED_PING_RADIUS) { pPed = pPed->pNext; @@ -2258,13 +2310,31 @@ SEATEDPTR FindTannerASeat(LPPEDESTRIAN pPed) return NULL; } +#ifndef PSX +int PedsAvailable() +{ + int peds_available = max_pedestrians - num_pedestrians; + + if (peds_available <= MAX_TANNER_PEDS) + return 0; + + peds_available -= MAX_TANNER_PEDS; + + return peds_available; +} +#endif + // [D] [T] void add_seated(SEATEDPTR seatedptr, int seat_index) { LPPEDESTRIAN pedptr; int rnd; +#ifndef PSX + if (PedsAvailable() > 0) +#else if (num_pedestrians < MAX_SEATED_PEDS) +#endif { pedptr = CreatePedestrian(); diff --git a/src_rebuild/Game/C/pedest.h b/src_rebuild/Game/C/pedest.h index b0d3af7e9..f1b92c36a 100644 --- a/src_rebuild/Game/C/pedest.h +++ b/src_rebuild/Game/C/pedest.h @@ -16,6 +16,9 @@ extern int bReverseYRotation; extern LPPEDESTRIAN pUsedPeds; +// [A] for PC version adjustable density +extern int max_pedestrians; + extern void ProcessChairLump(char *lump_file, int lump_size); // 0x00073328 extern void InitTanner(); // 0x0006E408 diff --git a/src_rebuild/Game/C/replays.c b/src_rebuild/Game/C/replays.c index 7b8a5cc35..962e4775f 100644 --- a/src_rebuild/Game/C/replays.c +++ b/src_rebuild/Game/C/replays.c @@ -11,6 +11,7 @@ #include "camera.h" #include "civ_ai.h" #include "cutrecorder.h" +#include "pedest.h" char AnalogueUnpack[16] = { 0, -51, -63, -75, -87, -99, -111, -123, From 081510670ef0ba11023d9eefca54b24eb7722448 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 17 Jun 2022 18:54:25 -0700 Subject: [PATCH 09/78] Add support for fixing regressions w/ backwards compatibility. --- src_rebuild/Game/C/civ_ai.c | 70 +++++++++++++++++++++++++++++------ src_rebuild/Game/C/handling.c | 8 +++- src_rebuild/Game/C/players.c | 3 +- 3 files changed, 66 insertions(+), 15 deletions(-) diff --git a/src_rebuild/Game/C/civ_ai.c b/src_rebuild/Game/C/civ_ai.c index 93eb47623..957a8e274 100644 --- a/src_rebuild/Game/C/civ_ai.c +++ b/src_rebuild/Game/C/civ_ai.c @@ -2343,21 +2343,40 @@ int PingInCivCar(int minPingInDist) { int theta; int minDistAlong; - int scDist; - if (requestCopCar == 0) + // don't spawn outside straight + if (!gExtraConfig.Flags.FixCivCarsOnStraights) { - scDist = lbody * 2; - minDistAlong = lbody * 3; + int scDist; + + if (requestCopCar == 0) + { + scDist = lbody * 2; + minDistAlong = lbody * 3; + } + else + { + scDist = lbody / 2; // *** BUGGERED *** + minDistAlong = 0; + } + + if (roadInfo.straight->length <= (scDist + lbody) * 2) + return 0; } else { - scDist = lbody / 2; - minDistAlong = 0; - } + if (requestCopCar == 0) + { + minDistAlong = lbody * 3; + } + else + { + minDistAlong = 0; + } - if (roadInfo.straight->length <= (scDist + lbody) * 2) // don't spawn outside straight - return 0; + if (roadInfo.straight->length <= lbody * 6) + return 0; + } dx = randomLoc.vx - roadInfo.straight->Midx; dz = randomLoc.vz - roadInfo.straight->Midz; @@ -2509,6 +2528,19 @@ int PingInCivCar(int minPingInDist) { numParkedCars++; + if (gExtraConfig.Flags.AllowParkedTurnedWheels) + { + int tmp = ((Random2(0) & 0xff) + 1536) & 0x1ff; + + if (FrameCnt % 16) + { + if (tmp & 8) + tmp = -tmp; + + newCar->wheel_angle = tmp; + } + } + // parked car is going to unpark if (newCar->ai.c.thrustState == 3) newCar->controlFlags |= CONTROL_FLAG_WAS_PARKED; @@ -3686,10 +3718,24 @@ int CivControl(CAR_DATA* cp) if (cp->ai.c.thrustState != 3) steer = CivSteerAngle(cp); - thrust = CivAccel(cp) - MAX(ABS(steer), 4) * 3; // [A] reduce acceleration when steering is applied + thrust = CivAccel(cp); + + // [A] reduce acceleration when steering is applied + if (gExtraConfig.Flags.NoWibblyWobblyCars) + { + if (thrust != 0) + thrust -= MAX(ABS(steer), 4) * 3; + + if (thrust < 0 && cp->hd.wheel_speed < 100) + thrust = 0; + } + else + { + thrust = thrust - MAX(ABS(steer), 4) * 3; - if (thrust < 0 && cp->hd.wheel_speed < 5) - thrust = 0; + if (thrust < 0 && cp->hd.wheel_speed < 5) + thrust = 0; + } cp->wheel_angle = steer; cp->thrust = thrust; diff --git a/src_rebuild/Game/C/handling.c b/src_rebuild/Game/C/handling.c index f7423c990..7b1f9b7e4 100644 --- a/src_rebuild/Game/C/handling.c +++ b/src_rebuild/Game/C/handling.c @@ -1191,8 +1191,10 @@ void ProcessCarPad(CAR_DATA* cp, u_int pad, char PadSteer, char use_analogue) int player_id; int int_steer; int analog_angle; + int leaving_car; PED_MODEL_TYPES whoExit; + leaving_car = 0; whoExit = TANNER_MODEL; int_steer = PadSteer; @@ -1212,6 +1214,7 @@ void ProcessCarPad(CAR_DATA* cp, u_int pad, char PadSteer, char use_analogue) whoExit = OTHER_MODEL; ActivatePlayerPedestrian(cp, NULL, 0, NULL, whoExit); + leaving_car = gExtraConfig.Flags.NoWibblyWobblyCars; } } else if (lockAllTheDoors != 0) @@ -1311,8 +1314,8 @@ void ProcessCarPad(CAR_DATA* cp, u_int pad, char PadSteer, char use_analogue) } } - if (pad & (CAR_PAD_LEFT | CAR_PAD_RIGHT)) - cp->hd.autoBrake++; + if (pad & (CAR_PAD_LEFT | CAR_PAD_RIGHT) && !leaving_car) // [A] bugfix: wibbly wobbly cars + cp->hd.autoBrake++; else cp->hd.autoBrake = 0; } @@ -1353,6 +1356,7 @@ void ProcessCarPad(CAR_DATA* cp, u_int pad, char PadSteer, char use_analogue) cp->thrust = 0; //if (gTimeInWater != 0) + if (!leaving_car) // [A] bugfix: wibbly wobbly cars { if (pad & CAR_PAD_BRAKE) { diff --git a/src_rebuild/Game/C/players.c b/src_rebuild/Game/C/players.c index 1ef118c0f..892384e43 100644 --- a/src_rebuild/Game/C/players.c +++ b/src_rebuild/Game/C/players.c @@ -123,7 +123,8 @@ void ChangeCarPlayerToPed(int playerID) } lcp->controlType = CONTROL_TYPE_CIV_AI; - lcp->wheel_angle = 0; + if (!gExtraConfig.Flags.AllowParkedTurnedWheels) + lcp->wheel_angle = 0; lcp->ai.c.thrustState = 3; lcp->ai.c.ctrlState = 7; From 4ef7f9823212bbb357b19de8657adddf5984b328 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 17 Jun 2022 18:56:23 -0700 Subject: [PATCH 10/78] Add pedestrian density to debug information. --- src_rebuild/DebugOverlay.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src_rebuild/DebugOverlay.cpp b/src_rebuild/DebugOverlay.cpp index bd4a63777..ba3d99890 100644 --- a/src_rebuild/DebugOverlay.cpp +++ b/src_rebuild/DebugOverlay.cpp @@ -95,6 +95,8 @@ void DrawDebugOverlays() extern int numParkedCars; extern int maxCopCars; extern int maxCivCars; + extern int num_pedestrians; + extern int max_pedestrians; extern int current_region; extern int LoadedArea; @@ -103,7 +105,7 @@ void DrawDebugOverlays() sprintf(tempBuf, "Spooling: %d spec: %d, active: %d, Reg: %d, Ar: %d, Cn: %d %d", doSpooling, allowSpecSpooling, spoolactive, current_region, LoadedArea, spoolptr->connected_areas[0] & 0x3f, spoolptr->connected_areas[1] & 0x3f); PrintString(tempBuf, 10, 30); - sprintf(tempBuf, "Civs: %d - %d parked - max %d", numCivCars, numParkedCars, maxCivCars); + sprintf(tempBuf, "Civs: %d - %d parked - max %d, Peds: %d - max %d", numCivCars, numParkedCars, maxCivCars, num_pedestrians, max_pedestrians); PrintString(tempBuf, 10, 40); sprintf(tempBuf, "Cops: %d - %d active - max %d - seen: %d", numCopCars, numActiveCops, maxCopCars, CopsCanSeePlayer); From 48c60d7350f3ec9b8bb22c23ad7232f52cd17ce0 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 17 Jun 2022 19:31:45 -0700 Subject: [PATCH 11/78] [Frontend] Fix incorrect density screen button selections. --- src_rebuild/Game/Frontend/FEmain.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src_rebuild/Game/Frontend/FEmain.c b/src_rebuild/Game/Frontend/FEmain.c index d4c4a2c17..87c46e9e6 100644 --- a/src_rebuild/Game/Frontend/FEmain.c +++ b/src_rebuild/Game/Frontend/FEmain.c @@ -4185,7 +4185,7 @@ int AdjustDensityScreen(int bSetup) int what = -1; if (density_value) - what = *density_value; + what = *density_value - 1; for (int i = 0; i < numButtons; i++) { @@ -4196,7 +4196,7 @@ int AdjustDensityScreen(int bSetup) } if (what != -1) - pCurrButton = &pCurrScreen->buttons[what]; + pCurrButton = &pCurrScreen->buttons[what & 3]; else pCurrButton = pCurrScreen->buttons; From 8453251307473a4d367388e2811f3a624fc8aab5 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 17 Jun 2022 22:07:41 -0700 Subject: [PATCH 12/78] Add regression fix for Tanner phasing through cars on foot. - Small code optimization as well --- src_rebuild/Game/C/glaunch.c | 1 + src_rebuild/Game/C/pedest.c | 19 +++++++++++++++---- src_rebuild/Game/dr2types.h | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src_rebuild/Game/C/glaunch.c b/src_rebuild/Game/C/glaunch.c index a3e3a65a1..2eb57a40e 100644 --- a/src_rebuild/Game/C/glaunch.c +++ b/src_rebuild/Game/C/glaunch.c @@ -202,6 +202,7 @@ void LoadExtraData(EXTRA_CONFIG_DATA *extraData, int profile) gExtraConfig.Flags.NoWibblyWobblyCars = 1; gExtraConfig.Flags.AllowParkedTurnedWheels = 1; gExtraConfig.Flags.FixCivCarsOnStraights = 1; + gExtraConfig.Flags.FixTannerPhasingThruCars = 1; } } diff --git a/src_rebuild/Game/C/pedest.c b/src_rebuild/Game/C/pedest.c index 07dc78fdc..65d6cdf00 100644 --- a/src_rebuild/Game/C/pedest.c +++ b/src_rebuild/Game/C/pedest.c @@ -1731,6 +1731,13 @@ int TannerCarCollisionCheck(VECTOR* pPos, int dir, int bQuick) cp1 = &car_data[MAX_CARS - 1]; do { + // [A] skip sooner + if (cp1->controlType == CONTROL_TYPE_NONE) + { + cp1--; + continue; + } + car_cos = &car_cosmetics[cp1->ap.model]; cd[1].length[0] = car_cos->colBox.vz; @@ -1751,15 +1758,19 @@ int TannerCarCollisionCheck(VECTOR* pPos, int dir, int bQuick) gte_stlvnl(&cd[1].x); - if (cp1->controlType != CONTROL_TYPE_NONE && - ABS(cp1->hd.where.t[1] + pPos->vy) < 500 && - bcollided2d(cd)) + int dist = ABS(cp1->hd.where.t[1] + pPos->vy); + + if (dist < 500 && bcollided2d(cd)) { if (bQuick != 0) return 1; if (FIXEDH(cp1->hd.wheel_speed) > 50) - return 1; + { + // [A] testing revealed the dist was usually 99 or 100 here + if (!gExtraConfig.Flags.FixTannerPhasingThruCars || dist > 100) + return 1; + } bFindCollisionPoint(cd, &collisionResult); diff --git a/src_rebuild/Game/dr2types.h b/src_rebuild/Game/dr2types.h index ea0361a7a..0f86098e4 100644 --- a/src_rebuild/Game/dr2types.h +++ b/src_rebuild/Game/dr2types.h @@ -1043,7 +1043,7 @@ struct ACTIVE_FLAGS u_char NoWibblyWobblyCars : 1; u_char AllowParkedTurnedWheels : 1; u_char FixCivCarsOnStraights : 1; - u_char extraFlag4 : 1; + u_char FixTannerPhasingThruCars : 1; u_char extraFlag5 : 1; u_char extraFlag6 : 1; u_char extraFlag7 : 1; From 4fb244521afc98884f7e31817fb616779745ee0a Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Sat, 18 Jun 2022 03:54:26 -0700 Subject: [PATCH 13/78] Tried getting clippedPolygon working... at least it doesn't crash! xD Draw code doesn't seem to do anything. There goes 4 hours of my life I'll never get back. --- src_rebuild/Game/C/debris.c | 11 +- src_rebuild/Game/C/debris.h | 3 + src_rebuild/Game/C/shadow.c | 396 ++++++++++++++++++------------------ src_rebuild/Game/C/shadow.h | 4 +- 4 files changed, 207 insertions(+), 207 deletions(-) diff --git a/src_rebuild/Game/C/debris.c b/src_rebuild/Game/C/debris.c index 053b4cc85..b78ec5465 100644 --- a/src_rebuild/Game/C/debris.c +++ b/src_rebuild/Game/C/debris.c @@ -348,6 +348,7 @@ char PoolPrimData[16] = { 0xA, 0x5, 0xB, 0x7 }; +short light_col = 0; int LightSortCorrect = 0; TEXTURE_DETAILS smoke_texture; @@ -607,6 +608,8 @@ void PlacePoolForCar(CAR_DATA *cp, CVECTOR *col, int front, int in_car) for(i = 0; i < 4; i++) { char* VertIdx; + + spolys = (POLY_F3*)current->primptr; VertIdx = PoolPrimData + i * 4; @@ -620,7 +623,7 @@ void PlacePoolForCar(CAR_DATA *cp, CVECTOR *col, int front, int in_car) if (brightness) { - int test = col->r * brightness; + light_col = brightness * 16; color.r = MIN(255, col->r * brightness >> 4); color.g = MIN(255, col->g * brightness >> 4); @@ -631,15 +634,17 @@ void PlacePoolForCar(CAR_DATA *cp, CVECTOR *col, int front, int in_car) sQuad(sout + VertIdx[0], sout + VertIdx[2], sout + VertIdx[3], - sout + VertIdx[1], &color, LightSortCorrect); + sout + VertIdx[1], &color); } else { sQuad(sout + VertIdx[1], sout + VertIdx[3], sout + VertIdx[2], - sout + VertIdx[0], &color, LightSortCorrect); + sout + VertIdx[0], &color); } + + current->primptr = (char*)spolys; } } } diff --git a/src_rebuild/Game/C/debris.h b/src_rebuild/Game/C/debris.h index 6a19fd43f..67d2e38f1 100644 --- a/src_rebuild/Game/C/debris.h +++ b/src_rebuild/Game/C/debris.h @@ -17,6 +17,9 @@ struct SMASHABLE_OBJECT #define OBJECT_SMASHED_MARK 0xFD46FEC0 +extern short light_col; +extern int LightSortCorrect; + extern TEXTURE_DETAILS smoke_texture; extern TEXTURE_DETAILS debris_texture; extern TEXTURE_DETAILS litter_texture; diff --git a/src_rebuild/Game/C/shadow.c b/src_rebuild/Game/C/shadow.c index 4b50779ca..ee5e89ea1 100644 --- a/src_rebuild/Game/C/shadow.c +++ b/src_rebuild/Game/C/shadow.c @@ -10,6 +10,7 @@ #include "debris.h" #include "handling.h" #include "convert.h" +#include "debris.h" #include "mission.h" #include "tile.h" @@ -26,6 +27,8 @@ struct TYRE_TRACK SVECTOR_NOPAD p4; }; +POLY_F3 *spolys; + int gShadowTexturePage; int gShadowTextureNum; @@ -518,88 +521,70 @@ static int numcv; static int lastcv; static SVECTOR cv[12]; -// [D] - refactored - NOT TESTED YET +// [D] [T] int clipAgainstZ(void) + { - SVECTOR *curr; - SVECTOR *prev; - int _tmp; - int temp; - int d; - SVECTOR *dst; - int flags; int srccount; int dstcount; + SVECTOR *current; + SVECTOR *previous; + SVECTOR *dst; + int flags; + int q; dstcount = 0; - - curr = cv + lastcv; - dst = cv + lastcv + 2; - srccount = numcv-1; - - flags = ((curr + numcv * 0x1fffffff)[1].vz > 0) << 1; - prev = curr + numcv * 0x1fffffff + 1; - - do { - - if (srccount < 0) - { - numcv = dstcount; - lastcv = lastcv + 2; - return 0; - } - + current = cv + lastcv; + dst = current + 2; + srccount = numcv - 1; + previous = current + (1 - numcv); + flags = (0 < previous->vz) << 1; + + while(srccount > 0) { flags >>= 1; - if (curr->vz > 0) + if (current->vz > 0) flags |= 2; - if (flags == 1) + if (flags == 1) { - d = prev->vz - curr->vz; + q = previous->vz - current->vz; - dst->vx = (curr->vx * prev->vz - prev->vx * curr->vz) / d; - dst->vy = (curr->vy * prev->vz - prev->vy * curr->vz) / d; - dst->pad = (curr->pad * prev->vz - prev->pad * curr->vz) / d; + dst->vx = (short)((current->vx * previous->vz - previous->vx * current->vz) / q); + dst->vy = (short)((current->vy * previous->vz - previous->vy * current->vz) / q); + dst->pad = (short)((current->pad * previous->vz - previous->pad * current->vz) / q); dst->vz = 0; - LAB_00076ca4: + dst--; dstcount++; } - else if (flags < 2) - { - if (flags != 0) - { - LAB_00076c84: - temp = curr->vz; - dst->vx = prev->vx; - dst->vz = temp; - goto LAB_00076ca4; - } - } - else + else if (flags == 2) { - if (flags != 2) - { - goto LAB_00076c84; - } - - d = prev->vz - curr->vz; - - dst->vx = (curr->vx * prev->vz - prev->vx * curr->vz) / d; - dst->vy = (curr->vy * prev->vz - prev->vy * curr->vz) / d; - dst->pad = (curr->pad * prev->vz - prev->pad * curr->vz) / d; + q = previous->vz - current->vz; + + dst->vx = (short)((current->vx * previous->vz - previous->vx * current->vz) / q); + dst->vy = (short)((current->vy * previous->vz - previous->vy * current->vz) / q); + dst->pad = (short)((current->pad * previous->vz - previous->pad * current->vz) / q); dst->vz = 0; - _tmp = curr->vz; - dst[-1].vx = prev->vx; - dst[-1].vz = _tmp; + + dst[-1] = *current; dst -= 2; - dstcount += 2; + dstcount += 2; + } + else + { + *dst-- = *current; + dstcount++; } srccount--; - prev = curr--; - } while (true); + previous = current--; + }; + + numcv = dstcount; + lastcv += 2; + + return 0; } @@ -642,157 +627,160 @@ int clipAgainstZ(void) /* WARNING: Unknown calling convention yet parameter storage is locked */ + +// [D] - refactored - nothing is showing up... wtf?? void clippedPoly(void) { - UNIMPLEMENTED(); - /* - undefined4 uVar1; - int track; - int iVar3; - POLY_F3 *pPVar4; - DB *pDVar5; - undefined4 in_zero; - undefined4 in_at; - int iVar6; - SVECTOR *pSVar7; - short *psVar8; - ulong *in_a1; - short *psVar9; - int iVar10; - int iVar11; - u_int *puVar12; - - pPVar4 = spolys; - iVar11 = numcv + -1; - if (iVar11 != -1) { - in_a1 = (ulong *)0xffffffff; - psVar8 = &(&cv)[lastcv].vz; - do { - iVar11 = iVar11 + -1; - *psVar8 = *psVar8 * 2 - psVar8[-2]; - psVar8 = psVar8 + -4; - } while (iVar11 != -1); + int iVar2; + DB *pDVar3; + short *psVar4; + int z1; + SVECTOR *psVar8; + SVECTOR *pSVar5; + SVECTOR *psVar5; + SVECTOR *psVar9; + SVECTOR *in_a1; + short *psVar6; + int iVar7; + POLY_G3 *pPVar8; + int z[3]; + POLY_G3 *pg3; + + pg3 = (POLY_G3*)spolys; + { + iVar2 = lastcv; + for (iVar7 = numcv - 1; iVar7 >= 0; iVar7--) + { + // FIXME: bad math?? + cv[iVar2].vz *= 2 - cv[iVar2].vx; + iVar2--; + } } + clipAgainstZ(); - if (2 < numcv) { - iVar11 = numcv + -1; - if (numcv != 0) { - in_a1 = (ulong *)0xffffffff; - pSVar7 = &cv + lastcv; - do { - iVar11 = iVar11 + -1; - pSVar7->vz = pSVar7->vz + pSVar7->vx * 2; - pSVar7 = pSVar7 + -1; - } while (iVar11 != -1); + + if (numcv < 3) + return; + + { + iVar2 = lastcv; + for (iVar7 = numcv - 1; iVar7 > 0; iVar7--) + { + // FIXME: bad math?? + cv[iVar2].vz += cv[iVar2].vx * 2; + iVar2--; } - clipAgainstZ(); - if (2 < numcv) { - iVar11 = numcv + -1; - if (numcv != 0) { - in_a1 = (ulong *)&(&cv)[lastcv].vy; - do { - iVar11 = iVar11 + -1; - *(short *)((int)in_a1 + 2) = - *(short *)((int)in_a1 + 2) - (*(short *)((int)in_a1 + -2) + *(short *)in_a1 * 2); - in_a1 = in_a1 + -2; - } while (iVar11 != -1); - } - clipAgainstZ(); - if (2 < numcv) { - iVar11 = numcv + -1; - if (numcv != 0) { - in_a1 = (ulong *)0xffffffff; - psVar8 = &(&cv)[lastcv].vy; - do { - iVar11 = iVar11 + -1; - psVar8[1] = psVar8[1] + *psVar8 * 4; - psVar8 = psVar8 + -4; - } while (iVar11 != -1); - } - clipAgainstZ(); - if (2 < numcv) { - iVar11 = numcv + -1; - if (numcv != 0) { - in_a1 = (ulong *)0xffffffff; - psVar8 = &(&cv)[lastcv].vy; - do { - iVar11 = iVar11 + -1; - psVar8[1] = (short)((int)(((u_int)(ushort)psVar8[1] + (int)*psVar8 * -2) * 0x10000) >> - 0x11); - psVar8 = psVar8 + -4; - } while (iVar11 != -1); - } - iVar11 = numcv + -3; - iVar3 = lastcv; - spolys = pPVar4; - while (-1 < iVar11) { - iVar6 = iVar3 * 8; - setCopReg(2, in_zero, *(undefined4 *)(&cv + lastcv)); - setCopReg(2, in_at, *(undefined4 *)&(&cv)[lastcv].vz); - setCopReg(2, &DAT_000da928 + iVar6, *(undefined4 *)(&DAT_000da928 + iVar6)); - setCopReg(2, &Cont_12 + iVar6, *(undefined4 *)(&DAT_000da92c + iVar6)); - setCopReg(2, &cv + lastcv, *(undefined4 *)(&Cont_12 + iVar6)); - setCopReg(2, in_a1, *(undefined4 *)(&DAT_000da924 + iVar6)); - copFunction(2, 0x280030); - *(undefined *)((int)&spolys->tag + 3) = 6; - spolys->code = '2'; - spolys->r0 = *(uchar *)&(&cv)[lastcv].pad; - spolys->g0 = *(uchar *)&(&cv)[lastcv].pad; - psVar9 = &(&cv)[iVar3 + -1].pad; - spolys->b0 = *(uchar *)&(&cv)[lastcv].pad; - *(undefined *)&spolys->x1 = *(undefined *)psVar9; - *(undefined *)((int)&spolys->x1 + 1) = *(undefined *)psVar9; - psVar8 = &(&cv)[iVar3 + -2].pad; - *(undefined *)&spolys->y1 = *(undefined *)psVar9; - *(undefined *)&spolys[1].tag = *(undefined *)psVar8; - *(undefined *)((int)&spolys[1].tag + 1) = *(undefined *)psVar8; - *(undefined *)((int)&spolys[1].tag + 2) = *(undefined *)psVar8; - uVar1 = getCopReg(2, 0xc); - *(undefined4 *)&spolys->x0 = uVar1; - uVar1 = getCopReg(2, 0xd); - *(undefined4 *)&spolys->x2 = uVar1; - uVar1 = getCopReg(2, 0xe); - *(undefined4 *)&spolys[1].r0 = uVar1; - pDVar5 = current; - iVar6 = getCopReg(2, 0x11); - iVar10 = getCopReg(2, 0x12); - track = getCopReg(2, 0x13); - iVar6 = (iVar6 + iVar10 + track) / 3 + LightSortCorrect; - iVar10 = iVar6 >> 3; - if (iVar6 < 0x40) { - iVar10 = 8; - } - spolys->tag = spolys->tag & 0xff000000 | current->ot[iVar10] & 0xffffff; - puVar12 = (u_int *)&spolys[1].x0; - pDVar5->ot[iVar10] = pDVar5->ot[iVar10] & 0xff000000 | (u_int)spolys & 0xffffff; - *(undefined *)((int)&spolys[1].y0 + 1) = 7; - *(undefined *)((int)&spolys[1].y1 + 1) = 0x24; - pDVar5 = current; - spolys[1].x2 = -1; - spolys[1].y2 = -1; - *(undefined2 *)&spolys[2].r0 = 0xffff; - *(undefined2 *)&spolys[2].b0 = 0xffff; - spolys[2].x1 = -1; - spolys[2].y1 = -1; - spolys[2].y0 = 0x20; - *puVar12 = *puVar12 & 0xff000000 | pDVar5->ot[iVar10] & 0xffffff; - iVar11 = iVar11 + -1; - in_a1 = pDVar5->ot + iVar10; - *in_a1 = *in_a1 & 0xff000000 | (u_int)puVar12 & 0xffffff; - spolys = (POLY_F3 *)&spolys[2].x2; - pDVar5->primptr = pDVar5->primptr + 0x20; - iVar3 = iVar3 + -1; - } - } - } + } + + clipAgainstZ(); + + if (numcv < 3) + return; + + { + iVar2 = lastcv; + for (iVar7 = numcv - 1; iVar7 > 0; iVar7--) + { + // FIXME: bad math?? + cv[iVar2].vz -= (cv[iVar2].vx + cv[iVar2].vy * 2); + iVar2--; } } - return;*/ + + clipAgainstZ(); + + if (numcv < 3) + return; + + { + iVar2 = lastcv; + for (iVar7 = numcv - 1; iVar7 > 0; iVar7--) + { + // FIXME: bad math?? + cv[iVar2].vz += cv[iVar2].vy * 4; + iVar2--; + } + } + + clipAgainstZ(); + + if (numcv < 3) + return; + + { + iVar2 = lastcv; + for (iVar7 = numcv - 1; iVar7 > 0; iVar7--) + { + // FIXME: bad math?? + cv[iVar2].vz = (short)(cv[iVar2].vz + cv[iVar2].vy * -2) >> 1; + iVar2--; + } + } + + iVar2 = lastcv; + for (iVar7 = numcv - 3; iVar7 >= 0; iVar7--) { + // + // FIXME: NOTHING GETS DRAWN?! + // + + gte_ldv3(&cv[lastcv], &cv[iVar2 - 2], &cv[iVar2 - 1]); + + gte_rtpt(); + + setPolyG3(pg3); + setSemiTrans(pg3, 1); + + pg3->r0 = cv[lastcv].pad; + pg3->g0 = cv[lastcv].pad; + pg3->b0 = cv[lastcv].pad; + + pg3->r1 = cv[iVar2 - 1].pad; + pg3->g1 = cv[iVar2 - 1].pad; + pg3->b1 = cv[iVar2 - 1].pad; + + pg3->r2 = cv[iVar2 - 2].pad; + pg3->g2 = cv[iVar2 - 2].pad; + pg3->b2 = cv[iVar2 - 2].pad; + + gte_stsxy3(&pg3->x0, &pg3->x1, &pg3->x2); + + gte_stsz3(&z[0], &z[1], &z[2]); + + z1 = (z[0] + z[1] + z[2]) / 3 + LightSortCorrect; + + if (z1 < 64) + z1 = 64; + + z1 >>= 3; + + addPrim(current->ot + z1, pg3); + current->primptr += sizeof(POLY_G3); + + POLY_FT3* null = (POLY_FT3*)current->primptr; + + setPolyFT3(null); + null->x0 = -1; + null->y0 = -1; + null->x1 = -1; + null->y1 = -1; + null->x2 = -1; + null->y2 = -1; + null->tpage = 0x20; + + addPrim(current->ot + z1, null); + current->primptr += sizeof(POLY_FT3); + + spolys = (POLY_F3*)current->primptr; + + iVar2--; + } } + + // [D] [T] -void sQuad(SVECTOR *v0, SVECTOR *v1, SVECTOR *v2, SVECTOR *v3, CVECTOR* light_col, int LightSortCorrect) +void sQuad(SVECTOR *v0, SVECTOR *v1, SVECTOR *v2, SVECTOR *v3, CVECTOR* color) { int z1; int z[4]; @@ -837,9 +825,9 @@ void sQuad(SVECTOR *v0, SVECTOR *v1, SVECTOR *v2, SVECTOR *v3, CVECTOR* light_co setPolyG4(poly); setSemiTrans(poly, 1); - poly->r1 = light_col->r; - poly->g1 = light_col->g; - poly->b1 = light_col->b; + poly->r1 = color->r; + poly->g1 = color->g; + poly->b1 = color->b; poly->r0 = 0; poly->g0 = 0; @@ -888,6 +876,8 @@ void sQuad(SVECTOR *v0, SVECTOR *v1, SVECTOR *v2, SVECTOR *v3, CVECTOR* light_co addPrim(current->ot + z1, null); current->primptr += sizeof(POLY_FT3); + + spolys = (POLY_F3*)current->primptr; } } diff --git a/src_rebuild/Game/C/shadow.h b/src_rebuild/Game/C/shadow.h index 629a6338e..d74eb7cd5 100644 --- a/src_rebuild/Game/C/shadow.h +++ b/src_rebuild/Game/C/shadow.h @@ -5,6 +5,8 @@ extern int gShadowTexturePage; extern int gShadowTextureNum; extern UV shadowuv; +extern POLY_F3 *spolys; + extern void InitTyreTracks(); // 0x00077524 extern void InitShadow(); // 0x00075F34 @@ -19,7 +21,7 @@ extern void DrawTyreTracks(); // 0x000759E0 extern void SubdivShadow(long z0, long z1, long z2, long z3, POLY_FT4 *sps); // 0x00076108 extern void PlaceShadowForCar(VECTOR *shadowPoints, int subdiv, int zOfs, int flag); // 0x000766CC -extern void sQuad(SVECTOR *v0, SVECTOR *v1, SVECTOR *v2, SVECTOR *v3, CVECTOR* light_col, int LightSortCorrect); // 0x00077138 +extern void sQuad(SVECTOR *v0, SVECTOR *v1, SVECTOR *v2, SVECTOR *v3, CVECTOR* color); // 0x00077138 #endif From 5ae9b7b7935d579b2b06614a777cfec0fb8ea277 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Sat, 18 Jun 2022 04:10:02 -0700 Subject: [PATCH 14/78] Remove all bug regression checks per Soapy's request. --- src_rebuild/Game/C/civ_ai.c | 33 ++++++--------------------------- src_rebuild/Game/C/glaunch.c | 3 --- src_rebuild/Game/C/handling.c | 2 +- src_rebuild/Game/C/pedest.c | 3 +-- src_rebuild/Game/dr2types.h | 8 ++++---- 5 files changed, 12 insertions(+), 37 deletions(-) diff --git a/src_rebuild/Game/C/civ_ai.c b/src_rebuild/Game/C/civ_ai.c index 957a8e274..e09bcdfb9 100644 --- a/src_rebuild/Game/C/civ_ai.c +++ b/src_rebuild/Game/C/civ_ai.c @@ -2345,39 +2345,18 @@ int PingInCivCar(int minPingInDist) int minDistAlong; // don't spawn outside straight - if (!gExtraConfig.Flags.FixCivCarsOnStraights) + if (requestCopCar == 0) { - int scDist; - - if (requestCopCar == 0) - { - scDist = lbody * 2; - minDistAlong = lbody * 3; - } - else - { - scDist = lbody / 2; // *** BUGGERED *** - minDistAlong = 0; - } - - if (roadInfo.straight->length <= (scDist + lbody) * 2) - return 0; + minDistAlong = lbody * 3; } else { - if (requestCopCar == 0) - { - minDistAlong = lbody * 3; - } - else - { - minDistAlong = 0; - } - - if (roadInfo.straight->length <= lbody * 6) - return 0; + minDistAlong = 0; } + if (roadInfo.straight->length <= lbody * 6) + return 0; + dx = randomLoc.vx - roadInfo.straight->Midx; dz = randomLoc.vz - roadInfo.straight->Midz; diff --git a/src_rebuild/Game/C/glaunch.c b/src_rebuild/Game/C/glaunch.c index 2eb57a40e..7713b1a52 100644 --- a/src_rebuild/Game/C/glaunch.c +++ b/src_rebuild/Game/C/glaunch.c @@ -199,10 +199,7 @@ void LoadExtraData(EXTRA_CONFIG_DATA *extraData, int profile) if (profile) { // setup special flags to be saved into replays - gExtraConfig.Flags.NoWibblyWobblyCars = 1; gExtraConfig.Flags.AllowParkedTurnedWheels = 1; - gExtraConfig.Flags.FixCivCarsOnStraights = 1; - gExtraConfig.Flags.FixTannerPhasingThruCars = 1; } } diff --git a/src_rebuild/Game/C/handling.c b/src_rebuild/Game/C/handling.c index 7b1f9b7e4..a5cd6c0f0 100644 --- a/src_rebuild/Game/C/handling.c +++ b/src_rebuild/Game/C/handling.c @@ -1214,7 +1214,7 @@ void ProcessCarPad(CAR_DATA* cp, u_int pad, char PadSteer, char use_analogue) whoExit = OTHER_MODEL; ActivatePlayerPedestrian(cp, NULL, 0, NULL, whoExit); - leaving_car = gExtraConfig.Flags.NoWibblyWobblyCars; + leaving_car = 1; } } else if (lockAllTheDoors != 0) diff --git a/src_rebuild/Game/C/pedest.c b/src_rebuild/Game/C/pedest.c index 65d6cdf00..78b123cb6 100644 --- a/src_rebuild/Game/C/pedest.c +++ b/src_rebuild/Game/C/pedest.c @@ -1767,8 +1767,7 @@ int TannerCarCollisionCheck(VECTOR* pPos, int dir, int bQuick) if (FIXEDH(cp1->hd.wheel_speed) > 50) { - // [A] testing revealed the dist was usually 99 or 100 here - if (!gExtraConfig.Flags.FixTannerPhasingThruCars || dist > 100) + if (dist > 100) // [A] add dist check; testing usually showed 99 or 100 here return 1; } diff --git a/src_rebuild/Game/dr2types.h b/src_rebuild/Game/dr2types.h index 0f86098e4..3d05264ad 100644 --- a/src_rebuild/Game/dr2types.h +++ b/src_rebuild/Game/dr2types.h @@ -1039,11 +1039,11 @@ struct REPLAY_PARAMETER_BLOCK struct ACTIVE_FLAGS { - // special flags for regression fixes, etc. - u_char NoWibblyWobblyCars : 1; + // special feature flags u_char AllowParkedTurnedWheels : 1; - u_char FixCivCarsOnStraights : 1; - u_char FixTannerPhasingThruCars : 1; + u_char extraFlags2 : 1; + u_char extraFlags3 : 1; + u_char extraFlags4 : 1; u_char extraFlag5 : 1; u_char extraFlag6 : 1; u_char extraFlag7 : 1; From fb9443c9ef3ab906b9458b4be35a48e3366faa30 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Sat, 18 Jun 2022 04:11:40 -0700 Subject: [PATCH 15/78] Such minor grammar mistake --- src_rebuild/Game/dr2types.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src_rebuild/Game/dr2types.h b/src_rebuild/Game/dr2types.h index 3d05264ad..370a83e45 100644 --- a/src_rebuild/Game/dr2types.h +++ b/src_rebuild/Game/dr2types.h @@ -1041,9 +1041,9 @@ struct ACTIVE_FLAGS { // special feature flags u_char AllowParkedTurnedWheels : 1; - u_char extraFlags2 : 1; - u_char extraFlags3 : 1; - u_char extraFlags4 : 1; + u_char extraFlag2 : 1; + u_char extraFlag3 : 1; + u_char extraFlag4 : 1; u_char extraFlag5 : 1; u_char extraFlag6 : 1; u_char extraFlag7 : 1; From 353072c1cb05030948cabc29e9c2498896d594c2 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Sat, 18 Jun 2022 04:14:58 -0700 Subject: [PATCH 16/78] Replaced some inline code with equivalent function/macro. --- src_rebuild/Game/C/convert.c | 28 ++++------------------------ src_rebuild/Game/C/event.c | 12 ++---------- src_rebuild/Game/C/sound.c | 6 ++---- src_rebuild/Game/C/system.c | 3 +-- 4 files changed, 9 insertions(+), 40 deletions(-) diff --git a/src_rebuild/Game/C/convert.c b/src_rebuild/Game/C/convert.c index 2d8e1ca6f..25d3f27b0 100644 --- a/src_rebuild/Game/C/convert.c +++ b/src_rebuild/Game/C/convert.c @@ -68,18 +68,8 @@ void BuildWorldMatrix(void) { MATRIX newmatrix; - newmatrix.m[0][0] = ONE; - newmatrix.m[1][0] = 0; - newmatrix.m[2][0] = 0; - - newmatrix.m[0][1] = 0; - newmatrix.m[1][1] = ONE; - newmatrix.m[2][1] = 0; - - newmatrix.m[0][2] = 0; - newmatrix.m[1][2] = 0; - newmatrix.m[2][2] = ONE; - + InitMatrix(newmatrix); + _RotMatrixY(&newmatrix, camera_angle.vy); _RotMatrixZ(&newmatrix, camera_angle.vz); _RotMatrixX(&newmatrix, camera_angle.vx); @@ -115,18 +105,8 @@ void ScaleCamera(void) RotMatrixYXZ(&tempang, &temp); InvertMatrix(&temp, &temp2); - scale.m[0][0] = ONE; - scale.m[0][1] = 0; - scale.m[0][2] = 0; - - scale.m[1][0] = 0; - scale.m[1][1] = ONE; - scale.m[1][2] = 0; - - scale.m[2][0] = 0; - scale.m[2][1] = 0; - scale.m[2][2] = ONE; - + InitMatrix(scale); + MulMatrix0(&scale, &inv_camera_matrix, &scaledcammat); TransMatrix(&scaledcammat, &pos); SetRotMatrix(&scaledcammat); diff --git a/src_rebuild/Game/C/event.c b/src_rebuild/Game/C/event.c index 4bf7058cd..81485e28d 100644 --- a/src_rebuild/Game/C/event.c +++ b/src_rebuild/Game/C/event.c @@ -3026,16 +3026,8 @@ void DrawEvents(int camera) pos.vy = ev->position.vy - camera_position.vy; pos.vz = ev->position.vz - camera_position.vz; - matrix.m[0][0] = ONE; - matrix.m[1][0] = 0; - matrix.m[2][0] = 0; - matrix.m[0][1] = 0; - matrix.m[1][1] = ONE; - matrix.m[2][1] = 0; - matrix.m[0][2] = 0; - matrix.m[1][2] = 0; - matrix.m[2][2] = ONE; - + InitMatrix(matrix); + reflection = 0; if ((ev->flags & 2U) == 0) diff --git a/src_rebuild/Game/C/sound.c b/src_rebuild/Game/C/sound.c index de7faa64a..e2af2c0de 100644 --- a/src_rebuild/Game/C/sound.c +++ b/src_rebuild/Game/C/sound.c @@ -312,10 +312,8 @@ int CalculateVolume(int channel) ofse.vy = srcPos->vy + plPos->vy; ofse.vz = srcPos->vz - plPos->vz; - gte_ldlvl(&ofse); - gte_sqr0(); - gte_stlvnl(&ofse); - + gte_Square0(&ofse, &ofse); + distance = SquareRoot0(ofse.vx + ofse.vy + ofse.vz); if (distance < 1024) diff --git a/src_rebuild/Game/C/system.c b/src_rebuild/Game/C/system.c index ac185f3d6..2067311f6 100644 --- a/src_rebuild/Game/C/system.c +++ b/src_rebuild/Game/C/system.c @@ -697,8 +697,7 @@ void SwapDrawBuffers2(int player) current = MPcurrent[1 - player]; last = MPlast[1 - player]; - ClearOTagR((u_long*)current->ot, OTSIZE); - current->primptr = current->primtab; + ClearCurrentDrawBuffers(); } short paddp; From 5f64034b38871a6d70ba9faeb1c526fbe323c924 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Sat, 18 Jun 2022 04:15:40 -0700 Subject: [PATCH 17/78] Added missing changes to remove bug regression stuff. --- src_rebuild/Game/C/civ_ai.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src_rebuild/Game/C/civ_ai.c b/src_rebuild/Game/C/civ_ai.c index e09bcdfb9..e0d3f559a 100644 --- a/src_rebuild/Game/C/civ_ai.c +++ b/src_rebuild/Game/C/civ_ai.c @@ -3700,21 +3700,12 @@ int CivControl(CAR_DATA* cp) thrust = CivAccel(cp); // [A] reduce acceleration when steering is applied - if (gExtraConfig.Flags.NoWibblyWobblyCars) - { - if (thrust != 0) - thrust -= MAX(ABS(steer), 4) * 3; - - if (thrust < 0 && cp->hd.wheel_speed < 100) - thrust = 0; - } - else - { - thrust = thrust - MAX(ABS(steer), 4) * 3; + if (thrust != 0) + thrust -= MAX(ABS(steer), 4) * 3; - if (thrust < 0 && cp->hd.wheel_speed < 5) - thrust = 0; - } + // [A] fix backwards crawl + if (thrust < 0 && cp->hd.wheel_speed < 100) + thrust = 0; cp->wheel_angle = steer; cp->thrust = thrust; From fa19818ec597a5e449209a420b24504883e3e0e1 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Sat, 18 Jun 2022 22:05:01 -0700 Subject: [PATCH 18/78] Refactor extra data structure and add some more features. - Time of Day and Weather now properly stored in extra data - Added support for custom spawn point data - Added future support for extra profile data - Moved ACTIVE_FLAGS structure into anonymous union - TODO: Ability to select a spawn point in Take a Ride --- src_rebuild/Game/C/glaunch.c | 182 ++++++++++++++++++++++++++++++++++- src_rebuild/Game/C/glaunch.h | 7 ++ src_rebuild/Game/C/main.c | 43 +++++++-- src_rebuild/Game/C/mission.c | 74 ++++++++++---- src_rebuild/Game/C/mission.h | 1 + src_rebuild/Game/C/pause.c | 30 +++++- src_rebuild/Game/C/players.c | 2 +- src_rebuild/Game/dr2types.h | 96 +++++++++++++----- 8 files changed, 377 insertions(+), 58 deletions(-) diff --git a/src_rebuild/Game/C/glaunch.c b/src_rebuild/Game/C/glaunch.c index 7713b1a52..81d9cf611 100644 --- a/src_rebuild/Game/C/glaunch.c +++ b/src_rebuild/Game/C/glaunch.c @@ -121,6 +121,7 @@ int gHaveStoredData = 0; int gHaveExtraData = 0; EXTRA_CONFIG_DATA gExtraConfig = { 0 }; +SAVED_CAR_POS gSavedCars[2] = { 0 }; int gLastChase = 0; int gChaseNumber = 0; @@ -185,6 +186,9 @@ void StoreGameVars(int replay) // - newer replays always have this data stored (even if empty) memset(&gExtraConfig, 0, sizeof(EXTRA_CONFIG_DATA)); gHaveExtraData = 0; + + // clear saved cars + memset(&gSavedCars, 0, sizeof(gSavedCars)); } } @@ -198,8 +202,43 @@ void LoadExtraData(EXTRA_CONFIG_DATA *extraData, int profile) if (profile) { - // setup special flags to be saved into replays - gExtraConfig.Flags.AllowParkedTurnedWheels = 1; + if (gExtraConfig.sdType == 1) + { + // TODO: load profile overrides + } + + // clear the data since we're done with it + memset(&gExtraConfig.data, 0, sizeof(gExtraConfig.data)); + + // initialize extra data for missions + gExtraConfig.sdType = 2; + gExtraConfig.m.AllowParkedTurnedWheels = 1; + } + else if (gExtraConfig.sdType == 2) + { + // load mission overrides + REPLAY_SAVE_HEADER *header = (REPLAY_SAVE_HEADER*)((char*)&extraData[1] - sizeof(REPLAY_SAVE_HEADER)); + + // resolve saved position slots + for (int i = 0; i < 2; i++) + { + if (extraData->m.SavedSlot[i] != -1) + { + gSavedCars[i] = header->SavedData.CarPos[extraData->m.SavedSlot[i]]; + + gExtraConfig.m.SavedPos[i] = &gSavedCars[i]; + } + else + { + gExtraConfig.m.SavedPos[i] = NULL; + } + } + } + else if (gExtraConfig.sdType != 0) + { + // clear out invalid data + gExtraConfig.cookie = 0; + memset(&gExtraConfig.data, 0, sizeof(extraData->data)); } } @@ -210,11 +249,146 @@ void SaveExtraData(EXTRA_CONFIG_DATA *extraData, int profile) extraData->magic = EXTRA_DATA_MAGIC; memcpy(extraData, &gExtraConfig, sizeof(EXTRA_CONFIG_DATA)); + int invalid = 0; + if (profile) { - // don't save any special flags in profile data - memset(&extraData->Flags, 0, sizeof(ACTIVE_FLAGS)); + if (extraData->sdType != 1) + { + // don't save non-profile data + invalid = 1; + } + } + else if (extraData->sdType == 2) + { + REPLAY_SAVE_HEADER *header = (REPLAY_SAVE_HEADER*)((char*)&extraData[1] - sizeof(REPLAY_SAVE_HEADER)); + + if (extraData->mfStartPos) + { + int slot = 0; + + if (header->HaveStoredData != 0) + { + do + { + // find first free slot + if (!header->SavedData.CarPos[slot].active) + break; + } while (++slot < 6); + } + + // fixup pointers; store info in first free saved car slot + // if no free slots are available, well.. sorry! + for (int i = 0; i < 2; i++) + { + if (extraData->m.SavedPos[i] == NULL) + { + extraData->m.SavedSlot[i] = -1; + continue; + } + + if (slot >= 6) + { + printWarning("Couldn't save player %d start position - no more slots available!\n", i + 1); + continue; + } + + header->SavedData.CarPos[slot] = *extraData->m.SavedPos[i]; + extraData->m.SavedSlot[i] = slot++; + } + } + } + else + { + // don't save non-mission data + invalid = 1; + } + + if (invalid) + { + // clear out invalid data + extraData->cookie = 0; + memset(&extraData->data, 0, sizeof(extraData->data)); + } +} + +int GetSavedCar(STREAM_SOURCE *player, int slot) +{ + if (slot > 1 || !gExtraConfig.mfStartPos) + return -1; + + if (gExtraConfig.m.SavedPos[slot] == NULL) + return 0; + + player->model = gExtraConfig.m.SavedPos[slot]->model; + player->palette = gExtraConfig.m.SavedPos[slot]->palette; + player->rotation = gExtraConfig.m.SavedPos[slot]->direction & 0xfff; + player->position.vx = gExtraConfig.m.SavedPos[slot]->vx; + player->position.vz = gExtraConfig.m.SavedPos[slot]->vz; + + return 1; +} + +int SetSavedCar(int slot, STREAM_SOURCE *player) +{ + if (slot > 1) + return -1; + + if (gExtraConfig.m.SavedPos[slot] == NULL) + { + gExtraConfig.mfStartPos = 1; + gExtraConfig.m.SavedPos[slot] = &gSavedCars[slot]; } + + gExtraConfig.m.SavedPos[slot]->model = player->model; + gExtraConfig.m.SavedPos[slot]->palette = player->palette; + gExtraConfig.m.SavedPos[slot]->direction = player->rotation & 0xfff; + gExtraConfig.m.SavedPos[slot]->vx = player->position.vx; + gExtraConfig.m.SavedPos[slot]->vz = player->position.vz; + + return 1; +} + +int SavePlayerCarSpawn(int slot) +{ + if (slot > 1) + return -1; + + if (gExtraConfig.m.SavedPos[slot] == NULL) + { + gExtraConfig.mfStartPos = 1; + gExtraConfig.m.SavedPos[slot] = &gSavedCars[slot]; + } + + extern PLAYER player[]; + extern CAR_DATA car_data[]; + + PLAYER *plr = &player[slot]; + + if (plr->cameraCarId == -1) + return 0; + + CAR_DATA *lcp = &car_data[plr->cameraCarId]; + + gExtraConfig.m.SavedPos[slot]->direction = lcp->hd.direction & 0xfff; + gExtraConfig.m.SavedPos[slot]->vx = lcp->hd.where.t[0]; + gExtraConfig.m.SavedPos[slot]->vz = lcp->hd.where.t[2]; + + return 1; +} + +extern int ResetPlayerCarSpawn(int slot) +{ + if (slot > 1) + return -1; + + if (gExtraConfig.m.SavedPos[slot] != NULL) + { + gExtraConfig.m.SavedPos[slot] = NULL; + gExtraConfig.mfStartPos = gExtraConfig.m.SavedPos[slot ^ 1] != NULL; + } + + return 1; } // [D] [T] diff --git a/src_rebuild/Game/C/glaunch.h b/src_rebuild/Game/C/glaunch.h index 3f5b7200b..903a63452 100644 --- a/src_rebuild/Game/C/glaunch.h +++ b/src_rebuild/Game/C/glaunch.h @@ -15,6 +15,7 @@ extern int gHaveStoredData; // [A] extern int gHaveExtraData; extern EXTRA_CONFIG_DATA gExtraConfig; +extern SAVED_CAR_POS gSavedCars[2]; extern int gMissionLadderPos; extern int gFurthestMission; @@ -55,6 +56,12 @@ extern void RestoreGameVars(int replay); extern void LoadExtraData(EXTRA_CONFIG_DATA *extraData, int profile); extern void SaveExtraData(EXTRA_CONFIG_DATA *extraData, int profile); +extern int GetSavedCar(STREAM_SOURCE *player, int slot); +extern int SetSavedCar(int slot, STREAM_SOURCE *player); + +extern int SavePlayerCarSpawn(int slot); +extern int ResetPlayerCarSpawn(int slot); + extern void GetRandomChase(); // 0x000535D8 extern int FindPrevMissionFromLadderPos(int pos); // 0x000536D8 diff --git a/src_rebuild/Game/C/main.c b/src_rebuild/Game/C/main.c index 4fb680927..c4645b020 100644 --- a/src_rebuild/Game/C/main.c +++ b/src_rebuild/Game/C/main.c @@ -2352,7 +2352,7 @@ void RenderGame2(int view) } // Steven Adams and Andreas Tawn of Havana team - notInDreaAndStevesEvilLair = Havana3DOcclusion(DrawMapPSX, (int*)&ObjectDrawnValue); + notInDreaAndStevesEvilLair = Havana3DOcclusion(DrawMapPSX, &ObjectDrawnValue); if (notInDreaAndStevesEvilLair) { @@ -2448,11 +2448,24 @@ void InitGameVariables(void) PlayerStartInfo[0]->controlType = CONTROL_TYPE_PLAYER; PlayerStartInfo[0]->flags = 0; - PlayerStartInfo[0]->rotation = levelstartpos[GameLevel + (gWantNight * 4)][1]; - PlayerStartInfo[0]->position.vy = 0; - PlayerStartInfo[0]->position.vx = levelstartpos[GameLevel + (gWantNight * 4)][0]; - PlayerStartInfo[0]->position.vz = levelstartpos[GameLevel + (gWantNight * 4)][2]; + +#if 0 // !!! NOT IMPLEMENTED YET !!! + if (wantedStartPos != -1) + { + // select player 1 custom spawn point and save the car position + // ... + // ... + + SetSavedCar(PlayerStartInfo[0], 0); + } + else +#endif + { + PlayerStartInfo[0]->rotation = levelstartpos[GameLevel + (gWantNight * 4)][1]; + PlayerStartInfo[0]->position.vx = levelstartpos[GameLevel + (gWantNight * 4)][0]; + PlayerStartInfo[0]->position.vz = levelstartpos[GameLevel + (gWantNight * 4)][2]; + } numPlayersToCreate = 1; @@ -2467,11 +2480,25 @@ void InitGameVariables(void) PlayerStartInfo[1]->controlType = CONTROL_TYPE_PLAYER; PlayerStartInfo[1]->flags = 0; - PlayerStartInfo[1]->rotation = levelstartpos[GameLevel][1]; PlayerStartInfo[1]->position.vy = 0; - PlayerStartInfo[1]->position.vx = levelstartpos[GameLevel][0] + 600; - PlayerStartInfo[1]->position.vz = levelstartpos[GameLevel][2]; + +#if 0 // !!! NOT IMPLEMENTED YET !!! + if (wantedStartPos != -1) + { + // select player 2 custom spawn point and save the car position + // ... + // ... + + SetSavedCar(PlayerStartInfo[1], 1); + } + else +#endif + { + PlayerStartInfo[1]->rotation = levelstartpos[GameLevel][1]; + PlayerStartInfo[1]->position.vx = levelstartpos[GameLevel][0] + 600; + PlayerStartInfo[1]->position.vz = levelstartpos[GameLevel][2]; + } numPlayersToCreate = NumPlayers; } diff --git a/src_rebuild/Game/C/mission.c b/src_rebuild/Game/C/mission.c index 9a9ee8b4a..4979b1b27 100644 --- a/src_rebuild/Game/C/mission.c +++ b/src_rebuild/Game/C/mission.c @@ -162,6 +162,7 @@ int wantedCar[2] = { -1, -1 }; // [A] int wantedTimeOfDay = -1; int wantedWeather = -1; +int wantedStartPos = -1; MS_TARGET* MissionTargets; u_int* MissionScript; @@ -489,7 +490,10 @@ void LoadMission(int missionnum) PlayerStartInfo[0]->rotation = MissionHeader->playerStartRotation; PlayerStartInfo[0]->position.vx = MissionHeader->playerStartPosition.x; PlayerStartInfo[0]->position.vz = MissionHeader->playerStartPosition.y; - + + PlayerStartInfo[0]->model = MissionHeader->playerCarModel; + PlayerStartInfo[0]->palette = MissionHeader->playerCarColour; + #ifdef DEBUG_OPTIONS if(gStartPos.x != 0 && gStartPos.z != 0) { @@ -498,9 +502,16 @@ void LoadMission(int missionnum) PlayerStartInfo[0]->position.vz = gStartPos.z; } #endif - - PlayerStartInfo[0]->model = MissionHeader->playerCarModel; - PlayerStartInfo[0]->palette = MissionHeader->playerCarColour; + + // [A] override start position if available, otherwise store it for the replay + if (gExtraConfig.mfStartPos) + { + GetSavedCar(PlayerStartInfo[0], 0); + } + else + { + SetSavedCar(0, PlayerStartInfo[0]); + } } if (MissionHeader->maxDamage != 0) @@ -509,17 +520,32 @@ void LoadMission(int missionnum) MaxPlayerDamage[0] = MissionHeader->maxDamage; } - // setup weather and time of day + // setup weather and time of day using mission defaults gTimeOfDay = MissionHeader->time; gWeather = MissionHeader->weather; - // [A] custom time of day - if(wantedTimeOfDay > -1) + // [A] use overrides if available + if (gExtraConfig.m.TimeOfDay != 0) + { + gTimeOfDay = gExtraConfig.m.TimeOfDay - 1; + } + else if (wantedTimeOfDay > -1) + { + // [A] use custom time of day and store in replay gTimeOfDay = wantedTimeOfDay; + gExtraConfig.m.TimeOfDay = gTimeOfDay + 1; + } - // [A] custom weather - if (wantedWeather > -1) + if (gExtraConfig.m.Weather != 0) + { + gWeather = gExtraConfig.m.Weather - 1; + } + else if (wantedWeather > -1) + { + // [A] use custom weather and store in replay gWeather = wantedWeather; + gExtraConfig.m.Weather = gWeather + 1; + } if (gTimeOfDay >= TIME_NIGHT) gNight = 1; @@ -2771,15 +2797,27 @@ void PreProcessTargets(void) { PlayerStartInfo[1] = &ReplayStreams[1].SourceType; - ReplayStreams[1].SourceType.type = 1; - ReplayStreams[1].SourceType.position.vx = target->s.car.posX; - ReplayStreams[1].SourceType.position.vy = 0; - ReplayStreams[1].SourceType.position.vz = target->s.car.posZ; - ReplayStreams[1].SourceType.rotation = target->s.car.rotation; - ReplayStreams[1].SourceType.model = target->s.car.model; - ReplayStreams[1].SourceType.palette = target->s.car.palette; - ReplayStreams[1].SourceType.controlType = CONTROL_TYPE_PLAYER; - ReplayStreams[1].SourceType.flags = 0; + PlayerStartInfo[1]->type = 1; + + PlayerStartInfo[1]->position.vx = target->s.car.posX; + PlayerStartInfo[1]->position.vy = 0; + PlayerStartInfo[1]->position.vz = target->s.car.posZ; + PlayerStartInfo[1]->rotation = target->s.car.rotation; + PlayerStartInfo[1]->model = target->s.car.model; + PlayerStartInfo[1]->palette = target->s.car.palette; + + // [A] override start position if available, otherwise store it for the replay + if (gExtraConfig.mfStartPos) + { + GetSavedCar(PlayerStartInfo[1], 1); + } + else + { + SetSavedCar(1, PlayerStartInfo[1]); + } + + PlayerStartInfo[1]->controlType = CONTROL_TYPE_PLAYER; + PlayerStartInfo[1]->flags = 0; if (target->s.car.type & 0x3) target->s.car.cutscene = -1; diff --git a/src_rebuild/Game/C/mission.h b/src_rebuild/Game/C/mission.h index 6a9d9df74..419ed3348 100644 --- a/src_rebuild/Game/C/mission.h +++ b/src_rebuild/Game/C/mission.h @@ -62,6 +62,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/pause.c b/src_rebuild/Game/C/pause.c index e271b77ba..582d976a0 100644 --- a/src_rebuild/Game/C/pause.c +++ b/src_rebuild/Game/C/pause.c @@ -121,6 +121,20 @@ void SetDisplayPosition(int direction) gDisplayPosition ^= 1; } +void SetSpawnPosition(int direction) +{ + extern int SavePlayerCarSpawn(int slot); + + SavePlayerCarSpawn(0); +} + +void ResetSpawnPosition(int direction) +{ + extern int ResetPlayerCarSpawn(int slot); + + ResetPlayerCarSpawn(0); +} + void ToggleInvincibility(int direction) { extern int gInvincibleCar; @@ -222,7 +236,10 @@ void DebugTimeOfDayRain(int direction) { //extern int weather; //weather ^= weather; - gWeather ^= 1; + + if (gWeather++ == WEATHER_WET) + gWeather = WEATHER_NONE; + wantedWeather = gWeather; if (gWeather == WEATHER_RAIN) @@ -256,8 +273,19 @@ MENU_ITEM DebugJustForFunItems[] = MENU_HEADER DebugJustForFunHeader = { "Just for fun", { 0, 0, 0, 0 }, 0u, DebugJustForFunItems }; +MENU_ITEM DebugSpawnPositionItems[] = +{ + { "Set To Player Car", PAUSE_TYPE_FUNC,2, SetSpawnPosition, MENU_QUIT_RESTART, NULL}, + { "Set To Default", PAUSE_TYPE_FUNC,2, ResetSpawnPosition, MENU_QUIT_RESTART, NULL}, + { NULL, PAUSE_TYPE_ENDITEMS, 0u, NULL, MENU_QUIT_NONE, NULL } +}; + +MENU_HEADER DebugSpawnPositionHeader = +{ "Spawn Position", { 0, 0, 0, 0}, 0, DebugSpawnPositionItems }; + MENU_ITEM DebugOptionsItems[] = { + { "Spawn position", PAUSE_TYPE_SUBMENU, 2, NULL, MENU_QUIT_NONE, &DebugSpawnPositionHeader }, #ifdef CUTSCENE_RECORDER //{ gCutsceneRecorderPauseText, 5u, 2u, (pauseFunc)&NextCutsceneRecorderPlayer, MENU_QUIT_NONE, NULL }, { gCurrentChasePauseText, 5u, 2u, (pauseFunc)&CutRec_NextChase, MENU_QUIT_NONE, NULL }, diff --git a/src_rebuild/Game/C/players.c b/src_rebuild/Game/C/players.c index 892384e43..31b68e3e2 100644 --- a/src_rebuild/Game/C/players.c +++ b/src_rebuild/Game/C/players.c @@ -123,7 +123,7 @@ void ChangeCarPlayerToPed(int playerID) } lcp->controlType = CONTROL_TYPE_CIV_AI; - if (!gExtraConfig.Flags.AllowParkedTurnedWheels) + if (!gExtraConfig.m.AllowParkedTurnedWheels) lcp->wheel_angle = 0; lcp->ai.c.thrustState = 3; lcp->ai.c.ctrlState = 7; diff --git a/src_rebuild/Game/dr2types.h b/src_rebuild/Game/dr2types.h index 370a83e45..33d8f16da 100644 --- a/src_rebuild/Game/dr2types.h +++ b/src_rebuild/Game/dr2types.h @@ -1037,29 +1037,6 @@ struct REPLAY_PARAMETER_BLOCK #define EXTRA_DATA_MAGIC 0xF12EB12D -struct ACTIVE_FLAGS -{ - // special feature flags - u_char AllowParkedTurnedWheels : 1; - u_char extraFlag2 : 1; - u_char extraFlag3 : 1; - u_char extraFlag4 : 1; - u_char extraFlag5 : 1; - u_char extraFlag6 : 1; - u_char extraFlag7 : 1; - u_char extraFlag8 : 1; - u_char extraFlag9 : 1; - u_char extraFlag10 : 1; - u_char extraFlag11 : 1; - u_char extraFlag12 : 1; - u_char extraFlag13 : 1; - u_char extraFlag14 : 1; - u_char extraFlag15 : 1; - u_char extraFlag16 : 1; - u_char reserved1; - u_char reserved2; -}; - struct EXTRA_CONFIG_DATA { u_int magic; @@ -1067,11 +1044,78 @@ struct EXTRA_CONFIG_DATA // configuration options u_char gTrafficDensity; u_char gPedestrianDensity; - u_char pad1[2]; + u_char pad1; - int reserved[3]; + // flags to determine what data we hold + union + { + struct + { + u_char sdType : 2; // the type of data we have + u_char sdFlags : 6; // reserved + }; + struct /* type 1 - PROFILE */ + { + u_char : 2; // reserved for type + u_char pfReserved : 6; + }; + struct /* type 2 - MISSION */ + { + u_char : 2; // reserved for type + u_char : 5; + u_char mfStartPos : 1; + }; + u_char cookie; + }; + + union + { + struct MISSION_OVERRIDES + { + u_char TimeOfDay; + u_char Weather; + u_char pad1[2]; + + union + { + SAVED_CAR_POS *SavedPos[2]; + int SavedSlot[2]; + }; // valid if mfStartPos = 1 + + struct + { + // special feature flags + u_char AllowParkedTurnedWheels : 1; + u_char extraFlag2 : 1; + u_char extraFlag3 : 1; + u_char extraFlag4 : 1; + u_char extraFlag5 : 1; + u_char extraFlag6 : 1; + u_char extraFlag7 : 1; + u_char extraFlag8 : 1; + u_char extraFlag9 : 1; + u_char extraFlag10 : 1; + u_char extraFlag11 : 1; + u_char extraFlag12 : 1; + u_char extraFlag13 : 1; + u_char extraFlag14 : 1; + u_char extraFlag15 : 1; + u_char extraFlag16 : 1; + }; - ACTIVE_FLAGS Flags; + u_char pad2[2]; + } m; // type 2 + + struct PROFILE_OVERRIDES + { + int reserved[3]; + } p; // type 1 + + struct + { + int zeropad[4]; + } data; // type 0 + }; }; // NB: necessary to fit at the end of certain fixed-size structs From 04ef491b082fa57d02eb7c7c8d7b7db7686ef6c1 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Sat, 18 Jun 2022 22:13:38 -0700 Subject: [PATCH 19/78] Fix a bug where the extra data magic gets overwritten. --- src_rebuild/Game/C/glaunch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src_rebuild/Game/C/glaunch.c b/src_rebuild/Game/C/glaunch.c index 81d9cf611..7c04e8a43 100644 --- a/src_rebuild/Game/C/glaunch.c +++ b/src_rebuild/Game/C/glaunch.c @@ -246,8 +246,8 @@ void SaveExtraData(EXTRA_CONFIG_DATA *extraData, int profile) { // always save extra data, even if it's empty; // this will make future backwards compat. efforts easier ;) - extraData->magic = EXTRA_DATA_MAGIC; memcpy(extraData, &gExtraConfig, sizeof(EXTRA_CONFIG_DATA)); + extraData->magic = EXTRA_DATA_MAGIC; int invalid = 0; From f1e2dfd19833e51b8e2ded655beff2232436f9fd Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Sat, 18 Jun 2022 22:21:12 -0700 Subject: [PATCH 20/78] Only load extra data if the header has correct magic. --- src_rebuild/Game/C/glaunch.c | 54 ++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/src_rebuild/Game/C/glaunch.c b/src_rebuild/Game/C/glaunch.c index 7c04e8a43..c2d94dbba 100644 --- a/src_rebuild/Game/C/glaunch.c +++ b/src_rebuild/Game/C/glaunch.c @@ -202,43 +202,49 @@ void LoadExtraData(EXTRA_CONFIG_DATA *extraData, int profile) if (profile) { - if (gExtraConfig.sdType == 1) + if (gHaveExtraData) { - // TODO: load profile overrides - } + if (gExtraConfig.sdType == 1) + { + // TODO: load profile overrides + } - // clear the data since we're done with it - memset(&gExtraConfig.data, 0, sizeof(gExtraConfig.data)); + // clear the data since we're done with it + memset(&gExtraConfig.data, 0, sizeof(gExtraConfig.data)); + } // initialize extra data for missions gExtraConfig.sdType = 2; gExtraConfig.m.AllowParkedTurnedWheels = 1; } - else if (gExtraConfig.sdType == 2) + else if (gHaveExtraData) { - // load mission overrides - REPLAY_SAVE_HEADER *header = (REPLAY_SAVE_HEADER*)((char*)&extraData[1] - sizeof(REPLAY_SAVE_HEADER)); - - // resolve saved position slots - for (int i = 0; i < 2; i++) + if (gExtraConfig.sdType == 2) { - if (extraData->m.SavedSlot[i] != -1) - { - gSavedCars[i] = header->SavedData.CarPos[extraData->m.SavedSlot[i]]; + // load mission overrides + REPLAY_SAVE_HEADER *header = (REPLAY_SAVE_HEADER*)((char*)&extraData[1] - sizeof(REPLAY_SAVE_HEADER)); - gExtraConfig.m.SavedPos[i] = &gSavedCars[i]; - } - else + // resolve saved position slots + for (int i = 0; i < 2; i++) { - gExtraConfig.m.SavedPos[i] = NULL; + if (gExtraConfig.m.SavedSlot[i] != -1) + { + gSavedCars[i] = header->SavedData.CarPos[gExtraConfig.m.SavedSlot[i]]; + + gExtraConfig.m.SavedPos[i] = &gSavedCars[i]; + } + else + { + gExtraConfig.m.SavedPos[i] = NULL; + } } } - } - else if (gExtraConfig.sdType != 0) - { - // clear out invalid data - gExtraConfig.cookie = 0; - memset(&gExtraConfig.data, 0, sizeof(extraData->data)); + else if (gExtraConfig.sdType != 0) + { + // clear out invalid data + gExtraConfig.cookie = 0; + memset(&gExtraConfig.data, 0, sizeof(gExtraConfig.data)); + } } } From d51d5bbf33d5c59b0f3da2c793e30cdcaee43255 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Sat, 18 Jun 2022 23:40:32 -0700 Subject: [PATCH 21/78] Haha oops --- src_rebuild/Game/C/civ_ai.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src_rebuild/Game/C/civ_ai.c b/src_rebuild/Game/C/civ_ai.c index d752adf21..8eda0794f 100644 --- a/src_rebuild/Game/C/civ_ai.c +++ b/src_rebuild/Game/C/civ_ai.c @@ -2507,7 +2507,7 @@ int PingInCivCar(int minPingInDist) { numParkedCars++; - if (gExtraConfig.Flags.AllowParkedTurnedWheels) + if (gExtraConfig.m.AllowParkedTurnedWheels) { int tmp = ((Random2(0) & 0xff) + 1536) & 0x1ff; From 066f9c6a054579e1e8079252f4ddc169d05e7ed6 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Sat, 18 Jun 2022 23:47:20 -0700 Subject: [PATCH 22/78] Flag cars with an ugly low LOD, increase some distances on PC. --- src_rebuild/Game/C/camera.c | 8 ++++---- src_rebuild/Game/C/civ_ai.c | 19 +++++++++++++++++++ src_rebuild/Game/C/draw.c | 2 +- src_rebuild/Game/C/draw.h | 8 ++++++-- src_rebuild/Game/dr2types.h | 1 + 5 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src_rebuild/Game/C/camera.c b/src_rebuild/Game/C/camera.c index 26012cebf..c37e023b6 100644 --- a/src_rebuild/Game/C/camera.c +++ b/src_rebuild/Game/C/camera.c @@ -415,7 +415,7 @@ short gCameraDefaultScrZ = 256; CAR_DATA *jcam = NULL; -int switch_detail_distance = 10000; +int switch_detail_distance = SWITCH_LOD_DIST; // [D] [T] void PlaceCameraFollowCar(PLAYER *lp) @@ -545,7 +545,7 @@ void PlaceCameraFollowCar(PLAYER *lp) camera_angle.vz = 0; SetGeomScreen(scr_z = gCameraDefaultScrZ); - switch_detail_distance = 10000; + switch_detail_distance = SWITCH_LOD_DIST; BuildWorldMatrix(); } @@ -651,7 +651,7 @@ void PlaceCameraInCar(PLAYER *lp, int BumperCam) SetGeomScreen(scr_z = gCameraDefaultScrZ); - switch_detail_distance = 10000; + switch_detail_distance = SWITCH_LOD_DIST; } // [D] [T] @@ -727,6 +727,6 @@ void PlaceCameraAtLocation(PLAYER* lp, int zoom) scr_z = gCameraDefaultScrZ; SetGeomScreen(scr_z); - switch_detail_distance = 10000 + (d >> 1); + switch_detail_distance = SWITCH_LOD_DIST + (d >> 1); BuildWorldMatrix(); } \ No newline at end of file diff --git a/src_rebuild/Game/C/civ_ai.c b/src_rebuild/Game/C/civ_ai.c index 8eda0794f..022de0eb6 100644 --- a/src_rebuild/Game/C/civ_ai.c +++ b/src_rebuild/Game/C/civ_ai.c @@ -86,6 +86,15 @@ int test555 = 0; cp->ai.c.thrustState = 3; cp->ai.c.ctrlState = 7; #endif +#ifndef PSX +char UglyLowCarLODs[4][10] = { + { 0,0,0,0,0, 1,0,0,0, 0 }, + { 0,0,0,0,0, 0,0,0,0, 0 }, + { 0,0,0,0,0, 0,0,1,1, 0 }, + { 1,0,0,0,0, 1,1,1,0, 0 }, +}; +#endif + // [D] [T] int InitCar(CAR_DATA* cp, int direction, LONGVECTOR4* startPos, unsigned char control, int model, int palette, char* extraData) { @@ -160,6 +169,16 @@ int InitCar(CAR_DATA* cp, int direction, LONGVECTOR4* startPos, unsigned char co break; } +#ifndef PSX + int rm = MissionHeader->residentModels[cp->ap.model]; + + if (rm >= 8) + rm -= 3; + + if (UglyLowCarLODs[GameLevel][rm]) + cp->controlFlags |= CONTROL_FLAG_DONT_USE_LOW_LOD; +#endif + CreateDentableCar(cp); DentCar(cp); diff --git a/src_rebuild/Game/C/draw.c b/src_rebuild/Game/C/draw.c index 6520e2ecc..e746b064d 100644 --- a/src_rebuild/Game/C/draw.c +++ b/src_rebuild/Game/C/draw.c @@ -568,7 +568,7 @@ void DrawAllTheCars(int view) #ifndef PSX // [A] make non-player far away cars look uglier else if (cars_to_draw[i]->controlType != CONTROL_TYPE_PLAYER && car_distance[i] >= CAR_LOD_SWITCH_DISTANCE) - gForceLowDetailCars = 1; + gForceLowDetailCars = 1 ^ ((cars_to_draw[i]->controlFlags & CONTROL_FLAG_DONT_USE_LOW_LOD) != 0); else gForceLowDetailCars = 0; #else diff --git a/src_rebuild/Game/C/draw.h b/src_rebuild/Game/C/draw.h index 862974f69..50443433a 100644 --- a/src_rebuild/Game/C/draw.h +++ b/src_rebuild/Game/C/draw.h @@ -60,6 +60,8 @@ extern MATRIX2 CompoundMatrix[64]; #define DRAW_LOD_DIST_HIGH 4000 #define DRAW_LOD_DIST_LOW 7000 +#define SWITCH_LOD_DIST 10000 + #define plotContext (*(_pct*)((u_char*)getScratchAddr(0) + 1024 - sizeof(_pct))) #else @@ -69,8 +71,10 @@ extern MATRIX2 CompoundMatrix[64]; #define MAX_DRAWN_ANIMATING 48 #define MAX_DRAWN_SPRITES 128 -#define DRAW_LOD_DIST_HIGH 7000 -#define DRAW_LOD_DIST_LOW 10000 +#define DRAW_LOD_DIST_HIGH 8000 +#define DRAW_LOD_DIST_LOW 16000 + +#define SWITCH_LOD_DIST DRAW_LOD_DIST_LOW extern _pct& plotContext; diff --git a/src_rebuild/Game/dr2types.h b/src_rebuild/Game/dr2types.h index 33d8f16da..8ee83d79f 100644 --- a/src_rebuild/Game/dr2types.h +++ b/src_rebuild/Game/dr2types.h @@ -494,6 +494,7 @@ enum ECarControlFlags CONTROL_FLAG_COP_SLEEPING = (1 << 1), // passive cop flag (roadblocks). Hitting car with that flag results it's activation CONTROL_FLAG_WAS_PARKED = (1 << 2), // car pinged in as parked. Really nothing to do with it CONTROL_FLAG_PLAYER_START_CAR = (1 << 3), // car owned by player + CONTROL_FLAG_DONT_USE_LOW_LOD = (1 << 4), // [A] car is too ugly for its own good }; typedef struct _CAR_DATA From d48420c5c60adcb7170b42a6bc0b8db3edde7ac7 Mon Sep 17 00:00:00 2001 From: Ilya Shurumov Date: Tue, 12 Jul 2022 22:11:43 +0600 Subject: [PATCH 23/78] - fix PSX compile errors --- src_rebuild/Game/C/glaunch.c | 14 +++--- src_rebuild/Game/dr2types.h | 82 +++++++++++++++++++----------------- 2 files changed, 50 insertions(+), 46 deletions(-) diff --git a/src_rebuild/Game/C/glaunch.c b/src_rebuild/Game/C/glaunch.c index c2d94dbba..b4aca7193 100644 --- a/src_rebuild/Game/C/glaunch.c +++ b/src_rebuild/Game/C/glaunch.c @@ -184,11 +184,11 @@ void StoreGameVars(int replay) // - any zero value means 'do backwards compatiblity' // - ensures older replays are fully backwards compatible // - newer replays always have this data stored (even if empty) - memset(&gExtraConfig, 0, sizeof(EXTRA_CONFIG_DATA)); + memset((u_char*)&gExtraConfig, 0, sizeof(EXTRA_CONFIG_DATA)); gHaveExtraData = 0; // clear saved cars - memset(&gSavedCars, 0, sizeof(gSavedCars)); + memset((u_char*)&gSavedCars, 0, sizeof(gSavedCars)); } } @@ -196,7 +196,7 @@ void LoadExtraData(EXTRA_CONFIG_DATA *extraData, int profile) { if (extraData->magic == EXTRA_DATA_MAGIC) { - memcpy(&gExtraConfig, extraData, sizeof(EXTRA_CONFIG_DATA)); + memcpy((u_char*)&gExtraConfig, (u_char*)extraData, sizeof(EXTRA_CONFIG_DATA)); gHaveExtraData = 1; } @@ -210,7 +210,7 @@ void LoadExtraData(EXTRA_CONFIG_DATA *extraData, int profile) } // clear the data since we're done with it - memset(&gExtraConfig.data, 0, sizeof(gExtraConfig.data)); + memset((u_char*)&gExtraConfig.data, 0, sizeof(gExtraConfig.data)); } // initialize extra data for missions @@ -243,7 +243,7 @@ void LoadExtraData(EXTRA_CONFIG_DATA *extraData, int profile) { // clear out invalid data gExtraConfig.cookie = 0; - memset(&gExtraConfig.data, 0, sizeof(gExtraConfig.data)); + memset((u_char*)&gExtraConfig.data, 0, sizeof(gExtraConfig.data)); } } } @@ -252,7 +252,7 @@ void SaveExtraData(EXTRA_CONFIG_DATA *extraData, int profile) { // always save extra data, even if it's empty; // this will make future backwards compat. efforts easier ;) - memcpy(extraData, &gExtraConfig, sizeof(EXTRA_CONFIG_DATA)); + memcpy((u_char*)extraData, (u_char*)&gExtraConfig, sizeof(EXTRA_CONFIG_DATA)); extraData->magic = EXTRA_DATA_MAGIC; int invalid = 0; @@ -314,7 +314,7 @@ void SaveExtraData(EXTRA_CONFIG_DATA *extraData, int profile) { // clear out invalid data extraData->cookie = 0; - memset(&extraData->data, 0, sizeof(extraData->data)); + memset((u_char*)&extraData->data, 0, sizeof(extraData->data)); } } diff --git a/src_rebuild/Game/dr2types.h b/src_rebuild/Game/dr2types.h index 8ee83d79f..ec04dfc6a 100644 --- a/src_rebuild/Game/dr2types.h +++ b/src_rebuild/Game/dr2types.h @@ -1038,6 +1038,47 @@ struct REPLAY_PARAMETER_BLOCK #define EXTRA_DATA_MAGIC 0xF12EB12D +struct MISSION_OVERRIDES +{ + u_char TimeOfDay; + u_char Weather; + u_char pad1[2]; + + union + { + SAVED_CAR_POS* SavedPos[2]; + int SavedSlot[2]; + }; // valid if mfStartPos = 1 + + struct + { + // special feature flags + u_char AllowParkedTurnedWheels : 1; + u_char extraFlag2 : 1; + u_char extraFlag3 : 1; + u_char extraFlag4 : 1; + u_char extraFlag5 : 1; + u_char extraFlag6 : 1; + u_char extraFlag7 : 1; + u_char extraFlag8 : 1; + u_char extraFlag9 : 1; + u_char extraFlag10 : 1; + u_char extraFlag11 : 1; + u_char extraFlag12 : 1; + u_char extraFlag13 : 1; + u_char extraFlag14 : 1; + u_char extraFlag15 : 1; + u_char extraFlag16 : 1; + }; + + u_char pad2[2]; +}; + +struct PROFILE_OVERRIDES +{ + int reserved[3]; +}; + struct EXTRA_CONFIG_DATA { u_int magic; @@ -1071,46 +1112,9 @@ struct EXTRA_CONFIG_DATA union { - struct MISSION_OVERRIDES - { - u_char TimeOfDay; - u_char Weather; - u_char pad1[2]; - - union - { - SAVED_CAR_POS *SavedPos[2]; - int SavedSlot[2]; - }; // valid if mfStartPos = 1 + MISSION_OVERRIDES m; // type 2 - struct - { - // special feature flags - u_char AllowParkedTurnedWheels : 1; - u_char extraFlag2 : 1; - u_char extraFlag3 : 1; - u_char extraFlag4 : 1; - u_char extraFlag5 : 1; - u_char extraFlag6 : 1; - u_char extraFlag7 : 1; - u_char extraFlag8 : 1; - u_char extraFlag9 : 1; - u_char extraFlag10 : 1; - u_char extraFlag11 : 1; - u_char extraFlag12 : 1; - u_char extraFlag13 : 1; - u_char extraFlag14 : 1; - u_char extraFlag15 : 1; - u_char extraFlag16 : 1; - }; - - u_char pad2[2]; - } m; // type 2 - - struct PROFILE_OVERRIDES - { - int reserved[3]; - } p; // type 1 + PROFILE_OVERRIDES p; // type 1 struct { From c8ded05cff2be5cd4f2992feb8a325e9b35002d7 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Sun, 24 Jul 2022 17:17:13 -0700 Subject: [PATCH 24/78] Fixed bugs + cleaned up code related to noisy car sounds. --- src_rebuild/Game/C/cars.c | 2 +- src_rebuild/Game/C/gamesnd.c | 36 +++++++++++++++++++++++++----------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src_rebuild/Game/C/cars.c b/src_rebuild/Game/C/cars.c index 39eb2c524..28d60e129 100644 --- a/src_rebuild/Game/C/cars.c +++ b/src_rebuild/Game/C/cars.c @@ -1577,7 +1577,7 @@ void DrawCar(CAR_DATA* cp, int view) if(CarHasSiren(cp->ap.model)) { if ((IS_ROADBLOCK_CAR(cp) || cp->controlType == CONTROL_TYPE_PURSUER_AI) || // any regular cop car including roadblock - gInGameCutsceneActive && cp->controlType == CONTROL_TYPE_CUTSCENE && CARNOISE_HAS_FORCED_SIREN(CAR_INDEX(cp)) != 0 || // any car with siren in cutscene + gInGameCutsceneActive && cp->controlType == CONTROL_TYPE_CUTSCENE && CARNOISE_HAS_FORCED_SIREN(CAR_INDEX(cp)) || // any car with siren in cutscene gCurrentMissionNumber == 26 && cp->controlType == CONTROL_TYPE_CUTSCENE && cp->ap.model == 4) // Vegas ambulance { if (cp->ai.p.dying < 75) diff --git a/src_rebuild/Game/C/gamesnd.c b/src_rebuild/Game/C/gamesnd.c index 1c8a7bdd2..f12e928a1 100644 --- a/src_rebuild/Game/C/gamesnd.c +++ b/src_rebuild/Game/C/gamesnd.c @@ -934,16 +934,17 @@ void InitDopplerSFX(void) for (i = 0; i < MAX_SIREN_NOISES; i++) { siren_noise[i].chan = -1; - siren_noise[i].car = 20; + siren_noise[i].car = MAX_CARS; siren_noise[i].in_use = 0; + siren_noise[i].stopped = 1; // [A] initially stopped } for (i = 0; i < MAX_CAR_NOISES; i++) { car_noise[i].chan = -1; - car_noise[i].chan = -1; - car_noise[i].car = 20; + car_noise[i].car = MAX_CARS; car_noise[i].in_use = 0; + car_noise[i].stopped = 1; // [A] initially stopped } if (GameType == GAME_GETAWAY) @@ -1011,9 +1012,8 @@ void DoDopplerSFX(void) else continue; - indexlist[num_noisy_cars] = i; car_dist[i] = dist; - num_noisy_cars++; + indexlist[num_noisy_cars++] = i; } } @@ -1059,7 +1059,7 @@ void DoDopplerSFX(void) } // any cutscene cop car or car with forced siren - if (gInGameCutsceneActive != 0 && car_ptr->controlType == CONTROL_TYPE_CUTSCENE && CARNOISE_HAS_FORCED_SIREN(indexlist[i]) != 0) + if (gInGameCutsceneActive != 0 && car_ptr->controlType == CONTROL_TYPE_CUTSCENE && CARNOISE_HAS_FORCED_SIREN(indexlist[i])) { siren = 1; } @@ -1088,10 +1088,17 @@ void DoDopplerSFX(void) // update siren noise status for (i = 0; i < MAX_SIREN_NOISES; i++) { - if (CARNOISE_IS_ACTIVE(siren_noise[i].car)) + car = siren_noise[i].car; + +#ifndef PSX + // [A] fix memory overflow reads + if (car < MAX_CARS && CARNOISE_IS_ACTIVE(car)) +#else + if (CARNOISE_IS_ACTIVE(car)) +#endif { // already in use, no need to start again - CARNOISE_DISABLE(siren_noise[i].car); + CARNOISE_DISABLE(car); siren_noise[i].in_use = 1; noises++; @@ -1119,7 +1126,7 @@ void DoDopplerSFX(void) { car = indexlist[i]; - if (!CARNOISE_IS_ACTIVE(indexlist[i])) + if (!CARNOISE_IS_ACTIVE(car)) continue; // dispatch siren sounds @@ -1200,10 +1207,17 @@ void DoDopplerSFX(void) // update noisy cars' status for (j = 0; j < MAX_CAR_NOISES; j++) { - if (CARNOISE_IS_ACTIVE(car_noise[j].car)) + car = car_noise[j].car; + +#ifndef PSX + // [A] fix memory overflow reads + if (car < MAX_CARS && CARNOISE_IS_ACTIVE(car)) +#else + if (CARNOISE_IS_ACTIVE(car)) +#endif { // already in use, no need to start again - CARNOISE_DISABLE(car_noise[j].car); + CARNOISE_DISABLE(car); car_noise[j].in_use = 1; noises++; From c5a67d46810cc6472e2eb3b3180fa6a0e0cbacf3 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Tue, 26 Jul 2022 01:25:08 -0700 Subject: [PATCH 25/78] Cleanup ResidentModelsBodge, MapCarIndexToBank --- src_rebuild/Game/C/gamesnd.c | 154 +++++++++++++++-------------------- 1 file changed, 66 insertions(+), 88 deletions(-) diff --git a/src_rebuild/Game/C/gamesnd.c b/src_rebuild/Game/C/gamesnd.c index f12e928a1..ec93b00a6 100644 --- a/src_rebuild/Game/C/gamesnd.c +++ b/src_rebuild/Game/C/gamesnd.c @@ -203,53 +203,52 @@ int SpecialVehicleKludge(char vehicle2) // [D] [T] int ResidentModelsBodge(void) { - int i; - int j; - - j = MissionHeader->residentModels[4]; - - if (gCurrentMissionNumber == 24 || gCurrentMissionNumber == 27 || - gCurrentMissionNumber == 29 || - (gCurrentMissionNumber == 30 || gCurrentMissionNumber == 35)) - { - return 3; - } + int i, j; - if (gCurrentMissionNumber - 50U < 16 && j == 12) + i = MissionHeader->residentModels[4]; + j = 3; + + // mission-specific bodges + switch (gCurrentMissionNumber) { - return 5; + case 24: + case 27: + case 29: + case 30: + case 35: + return 3; + default: + if (gCurrentMissionNumber >= 50 && gCurrentMissionNumber <= 65) + { + if (i == 12) + return 5; + } + break; } + // level-specific bodges if (GameLevel == 0) { - i = 11; - - if (j != 9) - return 3; + if (i == 9 || i == 11) + j = 4; } - else if (GameLevel == 1) + else if (GameLevel == 1) { - if (j - 8U > 1) - return 3; + if (i == 8 || i == 9) + j = 4; } else if (GameLevel == 2) { - i = 8; - - if (j != i) - return 3; + if (i == 8) + j = 4; } else if (GameLevel == 3) { - i = 11; - - if (j != i) - return 3; + if (i == 11) + j = 4; } - else - return 3; - return 4; + return j; } // [D] [T] @@ -270,25 +269,29 @@ int MapCarIndexToBank(int index) RM = MissionHeader->residentModels; model = RM[index]; + ret = 1; - if (gCurrentMissionNumber - 39U < 2 && RM[index] == 13) + if (model != 0) { - model = 10 - (RM[0] + RM[1] + RM[2]); + if (gCurrentMissionNumber == 39 || gCurrentMissionNumber == 40) + { + if (model == 13) + { + model = 10 - (RM[0] + RM[1] + RM[2]); - if (model < 1) - model = 1; + if (model < 1) + model = 1; - if (model > 4) - model = 4; - } - - ret = model - 1; + if (model > 4) + model = 4; + } + } - if (model == 0) - ret = 1; + ret = model - 1; - if (ret > 6) - ret -= 3; + if (ret > 6) + ret -= 3; + } return car_banks[GameLevel][ret]; } @@ -613,7 +616,6 @@ void StartGameSounds(void) ushort GetEngineRevs(CAR_DATA* cp) { int acc; - GEAR_DESC* gd; int gear; int lastgear; int ws, lws; @@ -631,49 +633,33 @@ ushort GetEngineRevs(CAR_DATA* cp) if (gear > 3) gear = 3; - gd = &geard[type][gear]; - do { + lastgear = gear; + if (acc < 1) - lws = gd->lowidl_ws; + lws = geard[type][gear].lowidl_ws; else - lws = gd->low_ws; - - lastgear = gear; + lws = geard[type][gear].low_ws; if (ws < lws) - { - gd--; - lastgear = gear - 1; - } - - if (gd->hi_ws < ws) - { - gd++; - lastgear++; - } + gear--; - if (gear == lastgear) - break; - - gear = lastgear; - - } while (true); - - cp->hd.gear = lastgear; + if (ws > geard[type][gear].hi_ws) + gear++; + } while (gear != lastgear); } else { ws = -ws / 2048; - lastgear = 0; - - cp->hd.gear = 0; + gear = 0; } + cp->hd.gear = gear; + if (acc != 0) - return ws * geard[type][lastgear].ratio_ac; + return ws * geard[type][gear].ratio_ac; - return ws * geard[type][lastgear].ratio_id; + return ws * geard[type][gear].ratio_id; } const int maxrevdrop = 1440; @@ -794,14 +780,10 @@ char PlaySpeech(SPEECH_QUEUE* pSpeechQueue, int sound) if (pSpeechQueue->count >= 7) return 0; - i = pSpeechQueue->count - 1; - - while (i >= 0) - { - pSpeechQueue->slot[i + 1] = pSpeechQueue->slot[i]; - i--; - } - + // move speech queue back + for (i = pSpeechQueue->count; i != 0; i--) + pSpeechQueue->slot[i] = pSpeechQueue->slot[i - 1]; + pSpeechQueue->slot[0] = sound; pSpeechQueue->count++; @@ -857,16 +839,12 @@ void ControlSpeech(SPEECH_QUEUE* pSpeechQueue) channels[pSpeechQueue->chan].time = 0; - pSpeechQueue->count--; - - DoSpeech(pSpeechQueue->chan, pSpeechQueue->slot[pSpeechQueue->count]); + DoSpeech(pSpeechQueue->chan, pSpeechQueue->slot[--pSpeechQueue->count]); TimeSinceLastSpeech = 0; } else if (SpuGetKeyStatus(SPU_VOICECH(pSpeechQueue->chan)) == 0) { - pSpeechQueue->count--; - - DoSpeech(pSpeechQueue->chan, pSpeechQueue->slot[pSpeechQueue->count]); + DoSpeech(pSpeechQueue->chan, pSpeechQueue->slot[--pSpeechQueue->count]); TimeSinceLastSpeech = 0; } } From 1733c23c1f68a1d7d8c00eff0d75fc8d3cfebcbc Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Thu, 4 Aug 2022 01:50:29 -0700 Subject: [PATCH 26/78] Fix up some conditional operators for readability sake. --- src_rebuild/Game/C/bcollide.c | 14 +++-- src_rebuild/Game/C/debris.c | 2 +- src_rebuild/Game/C/event.c | 9 +-- src_rebuild/Game/C/gamesnd.c | 18 +++--- src_rebuild/Game/C/handling.c | 4 +- src_rebuild/Game/C/main.c | 8 +-- src_rebuild/Game/C/sky.c | 101 +++++++++++++++++----------------- src_rebuild/Game/C/tile.c | 2 +- 8 files changed, 83 insertions(+), 75 deletions(-) diff --git a/src_rebuild/Game/C/bcollide.c b/src_rebuild/Game/C/bcollide.c index 58500a71e..82ed4b01f 100644 --- a/src_rebuild/Game/C/bcollide.c +++ b/src_rebuild/Game/C/bcollide.c @@ -467,14 +467,16 @@ int DamageCar3D(CAR_DATA *cp, LONGVECTOR4* delta, int strikeVel, CAR_DATA *pOthe if (player_id < 0) player_id = GetPlayerId(pOtherCar); - kludge = GetPlayerId(cp); - - if (kludge != 0 || (kludge = 2, pOtherCar->controlType != CONTROL_TYPE_CIV_AI)) + if (GetPlayerId(cp) == 0 && pOtherCar->controlType == CONTROL_TYPE_CIV_AI || + GetPlayerId(pOtherCar) == 0 && cp->controlType == CONTROL_TYPE_CIV_AI) { + // tanner collided with a civilian - his passenger may react to this + kludge = 2; + } + else + { + // normal collision between two cars kludge = 1; - - if (GetPlayerId(pOtherCar) == 0 && cp->controlType == CONTROL_TYPE_CIV_AI) - kludge = 2; } CollisionSound(player_id, cp, strikeVel / 128, kludge); diff --git a/src_rebuild/Game/C/debris.c b/src_rebuild/Game/C/debris.c index b78ec5465..224df2d72 100644 --- a/src_rebuild/Game/C/debris.c +++ b/src_rebuild/Game/C/debris.c @@ -1097,7 +1097,7 @@ void DrawSmashable_sprites(void) { UNIMPLEMENTED(); - if (gWeather - 1U < 2 || gTimeOfDay == TIME_NIGHT) + if (gWeather == WEATHER_RAIN || gWeather == WEATHER_WET || gTimeOfDay == TIME_NIGHT) { plotContext.colour = NightAmbient << 0x10 | NightAmbient << 8 | NightAmbient | 0x2c000000; } diff --git a/src_rebuild/Game/C/event.c b/src_rebuild/Game/C/event.c index effa5933f..b64bca01f 100644 --- a/src_rebuild/Game/C/event.c +++ b/src_rebuild/Game/C/event.c @@ -3460,7 +3460,8 @@ VECTOR* TriggerEvent(int i) return NULL; } - if (GameLevel >= 2 && i > 0 && i < 4) // Vegas and Rio detonators + if ((GameLevel == 2 || GameLevel == 3) && + (i >= 1 && i <= 3)) // Vegas and Rio detonators { if (stage[i] == 0) { @@ -3900,11 +3901,11 @@ int DetonatorTimer(void) if (gCurrentMissionNumber == 23) { - if (detonator.timer - 3U < 17) + if (detonator.timer > 2 && detonator.timer < 18) { ScreenShake(detonator.timer - 2, &rememberCameraAngle); } - else if (detonator.timer - 31U > 8) + else if (detonator.timer <= 30 || detonator.timer >= 40) { if (detonator.timer == 21) { @@ -3961,7 +3962,7 @@ int DetonatorTimer(void) } else { - if (detonator.timer - 141U < 19) + if (detonator.timer > 140 && detonator.timer < 160) { ScreenShake(detonator.timer - 140, &rememberCameraAngle); Setup_Smoke(&firstMissionEvent[0].position, 100, 500, SMOKE_BLACK, 0, &dummy, 0); diff --git a/src_rebuild/Game/C/gamesnd.c b/src_rebuild/Game/C/gamesnd.c index ec93b00a6..6714c3960 100644 --- a/src_rebuild/Game/C/gamesnd.c +++ b/src_rebuild/Game/C/gamesnd.c @@ -331,7 +331,8 @@ void LoadLevelSFX(int missionNum) LoadBankFromLump(SOUND_BANK_VOICES, SBK_COP_SIREN_START + (GameLevel & 3)); // Load cop voices except those missions - if (missionNum - 1U > 3 && missionNum != 6 && missionNum != 7 && + if (missionNum != 1 && missionNum != 2 && missionNum != 3 && + missionNum != 4 && missionNum != 6 && missionNum != 7 && missionNum != 9 && missionNum != 10 && missionNum != 11 && missionNum != 13 && missionNum != 14 && missionNum != 18 && missionNum != 19 && missionNum != 20 && missionNum != 22 && @@ -371,12 +372,13 @@ void LoadLevelSFX(int missionNum) // total phrases phrase_top = 0; - if (missionNum - 2U < 3 || missionNum == 9 || missionNum == 10 || missionNum == 27) + if (missionNum == 2 || missionNum == 3 || missionNum == 4 || + missionNum == 9 || missionNum == 10 || missionNum == 27) { LoadBankFromLump(SOUND_BANK_MISSION, SBK_ID_JONES); phrase_top = 7; } - else if (missionNum - 20U < 2 || missionNum == 25 || missionNum == 39) + else if (missionNum == 20 || missionNum == 21 || missionNum == 25 || missionNum == 39) { LoadBankFromLump(SOUND_BANK_MISSION, SBK_ID_JERICHO); phrase_top = 3; @@ -476,7 +478,7 @@ void LoadLevelSFX(int missionNum) LoadSoundBankDynamic(NULL, 3, SOUND_BANK_CARS); // special vehicle 1 bank - if (missionNum - 39U < 2 || missionNum >= 400 && missionNum <= 404) + if (missionNum == 39 || missionNum == 40 || (missionNum >= 400 && missionNum <= 404)) LoadBankFromLump(SOUND_BANK_CARS, MapCarIndexToBank(4)); else LoadBankFromLump(SOUND_BANK_CARS, SpecialVehicleKludge(0)); @@ -490,7 +492,7 @@ void LoadLevelSFX(int missionNum) } // secret car sound bank - if (missionNum - 50U < 16 || missionNum >= 400) + if ((missionNum >= 50 && missionNum <= 65) || missionNum >= 400) { LoadBankFromLump(SOUND_BANK_CARS, SpecialVehicleKludge(2)); } @@ -702,7 +704,7 @@ void ControlCarRevs(CAR_DATA* cp) newRevs = desiredRevs; desiredRevs = (oldRevs - newRevs); - if (maxrevdrop < desiredRevs) + if (desiredRevs > maxrevdrop) { acc = 0; cp->hd.changingGear = 1; @@ -711,13 +713,13 @@ void ControlCarRevs(CAR_DATA* cp) desiredRevs = newRevs - oldRevs; - if (maxrevrise < desiredRevs) + if (desiredRevs > maxrevrise) newRevs = oldRevs + maxrevrise; cp->hd.revs = newRevs; if (player_id != -1) { - if (acc == 0 && newRevs < 7001) + if (acc == 0 && newRevs <= 7000) { acc = player[player_id].revsvol; diff --git a/src_rebuild/Game/C/handling.c b/src_rebuild/Game/C/handling.c index a5cd6c0f0..cf063e435 100644 --- a/src_rebuild/Game/C/handling.c +++ b/src_rebuild/Game/C/handling.c @@ -1617,7 +1617,7 @@ void CheckCarEffects(CAR_DATA* cp, int player_id) // should be on asphalt if (skidsound != 0 && ((cp->hd.wheel[1].surface & 0x80) == 0 || (cp->hd.wheel[3].surface & 0x80) == 0)) { - if (gWeather - 1U < 2) + if (gWeather == WEATHER_RAIN || gWeather == WEATHER_WET) desired_skid = -1; else desired_skid = 7; @@ -1672,7 +1672,7 @@ void CheckCarEffects(CAR_DATA* cp, int player_id) if (wheel2 > wnse) wnse = wheel2; - if (gWeather - 1U > 1) + if (gWeather == WEATHER_RAIN || gWeather == WEATHER_WET) { if (wnse != 0) desired_wheel = wnse + 8; diff --git a/src_rebuild/Game/C/main.c b/src_rebuild/Game/C/main.c index c4645b020..2094d4198 100644 --- a/src_rebuild/Game/C/main.c +++ b/src_rebuild/Game/C/main.c @@ -1327,10 +1327,10 @@ void StepGame(void) { gLightsOn = 0; - if (gWeather - 1U > 1) - NightAmbient = 128; - else + if (gWeather == WEATHER_RAIN || gWeather == WEATHER_WET) NightAmbient = 78; + else + NightAmbient = 128; } else if (gTimeOfDay == TIME_DUSK) { @@ -1349,7 +1349,7 @@ void StepGame(void) } } - if (gWeather - 1U < 2) + if (gWeather == WEATHER_RAIN || gWeather == WEATHER_WET) NightAmbient = 78 - (DawnCount >> 7); else NightAmbient = 96 - (DawnCount >> 5); diff --git a/src_rebuild/Game/C/sky.c b/src_rebuild/Game/C/sky.c index e6e1be227..4c5df161f 100644 --- a/src_rebuild/Game/C/sky.c +++ b/src_rebuild/Game/C/sky.c @@ -255,7 +255,7 @@ void LoadSky(void) else skyNum = 0; - if (gWeather - 1U < 2) + if (gWeather == WEATHER_RAIN || gWeather == WEATHER_WET) { if (gTimeOfDay == TIME_NIGHT) offset = 0x10000; @@ -503,46 +503,51 @@ void DrawLensFlare(void) source = sun_source; - if (gWeather - 1U <= 1 || (M_BIT(gTimeOfDay) & (M_BIT(TIME_DAWN) | M_BIT(TIME_DUSK)))) + if (gWeather == WEATHER_RAIN || gWeather == WEATHER_WET) return; - - if (gTimeOfDay == TIME_NIGHT) - col.r = 128; - else - col.r = 254; - flare_col = 0; + if (gTimeOfDay == TIME_DAWN || gTimeOfDay == TIME_DUSK) + return; - col.g = col.r; - col.b = col.r; + flare_col = 0; - // get the sun brightness from framebuffer copy - if (gTimeOfDay != TIME_NIGHT && last_attempt_failed == 0) + if (gTimeOfDay == TIME_NIGHT) + { + col.r = 128; + } + else { - pwBuffer = buffer; - StoreImage(&source, (u_long*)buffer); + col.r = 254; - bufferY = 0; - do + // get the sun brightness from framebuffer copy + if (!last_attempt_failed) { - bufferY++; - bufferX = 0; + pwBuffer = buffer; + StoreImage(&source, (u_long*)buffer); + bufferY = 0; do { - if (*pwBuffer == 0xFFFF || *pwBuffer == 0x7fff) - flare_col++; + bufferY++; + bufferX = 0; - bufferX++; - pwBuffer++; - } - while (bufferX < 12); + do + { + if (*pwBuffer == 0xFFFF || *pwBuffer == 0x7fff) + flare_col++; + + bufferX++; + pwBuffer++; + } while (bufferX < 12); - pwBuffer += 4; + pwBuffer += 4; + } while (bufferY < 10); } - while (bufferY < 10); } + col.g = col.r; + col.b = col.r; + gte_SetRotMatrix(&inv_camera_matrix); gte_SetTransVector(&dummy); @@ -695,21 +700,18 @@ void TunnelSkyFade(void) int tun; int px, pz; - if (GameLevel != 3 && gTunnelNum < 3) - tun = gTunnelNum; - else + if (GameLevel == 3 && gTunnelNum > 2) tun = 2; - + else + tun = gTunnelNum; + v1 = NULL; v2 = NULL; - // HMM? - // DIFF_ANGLES(camera_angle.vy, tunnelDir[tun][0]) + 1247 < 2495; - - if (DIFF_ANGLES(camera_angle.vy, tunnelDir[tun][0]) + 1247 < 2495) // (((tunnelDir[tun][0] - camera_angle.vy) + 2048 & 4095) - 801 < 2495) + if (DIFF_ANGLES(camera_angle.vy, tunnelDir[tun][0]) + 1248 <= 2496) // (((tunnelDir[tun][0] - camera_angle.vy) + 2048 & 4095) - 801 < 2495) v1 = &tunnelPos[tun][0]; - if (DIFF_ANGLES(camera_angle.vy, tunnelDir[tun][1]) + 1247 < 2495) // (((tunnelDir[tun][1] - camera_angle.vy) + 2048 & 4095) - 801 < 2495) + if (DIFF_ANGLES(camera_angle.vy, tunnelDir[tun][1]) + 1248 <= 2496) // (((tunnelDir[tun][1] - camera_angle.vy) + 2048 & 4095) - 801 < 2495) v2 = &tunnelPos[tun][1]; px = player[0].pos[0]; @@ -796,23 +798,24 @@ void calc_sky_brightness(RGB16* skycolor) skycolor->r = 128; } - if (gTunnelNum == -1 || - GameLevel == 0 || - GameLevel == 1 && gTunnelNum == 2 || - GameLevel == 2 || - GameLevel == 3 && gTunnelNum != 1) - return; - - TunnelSkyFade(); + if (gTunnelNum != -1) + { + // conditionally draw Havana and Rio tunnels + if (GameLevel == 1 && gTunnelNum != 2 || + GameLevel == 3 && gTunnelNum == 1) + { + TunnelSkyFade(); - if (skycolor->r > skyFade) - skycolor->r = skyFade; + if (skycolor->r > skyFade) + skycolor->r = skyFade; - if (skycolor->g > skyFade) - skycolor->g = skyFade; + if (skycolor->g > skyFade) + skycolor->g = skyFade; - if (skycolor->b > skyFade) - skycolor->b = skyFade; + if (skycolor->b > skyFade) + skycolor->b = skyFade; + } + } } #ifdef USE_PGXP diff --git a/src_rebuild/Game/C/tile.c b/src_rebuild/Game/C/tile.c index 45551b816..6f370923e 100644 --- a/src_rebuild/Game/C/tile.c +++ b/src_rebuild/Game/C/tile.c @@ -244,7 +244,7 @@ void DrawTILES(PACKED_CELL_OBJECT** tiles, int tile_amount) previous_matrix = -1; - if (gWeather - 1U < 2) + if (gWeather == WEATHER_RAIN || gWeather == WEATHER_WET) { u_int col; col = plotContext.colour >> 2 & 63; From 283da52b65499fad9a566c01f102ef6823360cce Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Thu, 4 Aug 2022 16:22:40 -0700 Subject: [PATCH 27/78] [Game:civ_ai] Minor code cleanup --- src_rebuild/Game/C/civ_ai.c | 54 +++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/src_rebuild/Game/C/civ_ai.c b/src_rebuild/Game/C/civ_ai.c index 022de0eb6..29e73f9e4 100644 --- a/src_rebuild/Game/C/civ_ai.c +++ b/src_rebuild/Game/C/civ_ai.c @@ -45,7 +45,13 @@ struct } civPingTest; #endif // DEBUG -char modelRandomList[] = { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 0, 1, 0, 4 }; +char modelRandomList[] = { + 0, 0, 0, 0, + 1, 1, 1, 1, + 2, 2, 2, 2, + 0, 1, 0, 4 +}; + u_char reservedSlots[MAX_CARS] = { 0 }; int distFurthestCivCarSq = 0; @@ -2028,7 +2034,7 @@ int PingInCivCar(int minPingInDist) u_int retDistSq; unsigned char* slot; - civDat.distAlongSegment = -5; + int distAlongSegment = -5; lane = -1; dir = 0xffffff; @@ -2328,15 +2334,16 @@ int PingInCivCar(int minPingInDist) model = 3; civDat.controlFlags = CONTROL_FLAG_COP; } + else if (minPingInDist == 666) + { + // force spawn limo nearby in Caine's Cash + model = 4; + } else { model = modelRandomList[Random2(0) & 0xf]; } - // force spawn limo nearby in Caine's Cash - if (minPingInDist == 666) - model = 4; - // select car color palette if (MissionHeader->residentModels[model] == 0 || MissionHeader->residentModels[model] > 4) { @@ -2381,15 +2388,15 @@ int PingInCivCar(int minPingInDist) theta = roadInfo.straight->angle - ratan2(dx, dz); - civDat.distAlongSegment = (roadInfo.straight->length / 2) + FIXEDH(RCOS(theta) * SquareRoot0(dx * dx + dz * dz)); + distAlongSegment = (roadInfo.straight->length / 2) + FIXEDH(RCOS(theta) * SquareRoot0(dx * dx + dz * dz)); if (requestCopCar == 0) { - if (civDat.distAlongSegment < minDistAlong) - civDat.distAlongSegment = minDistAlong; + if (distAlongSegment < minDistAlong) + distAlongSegment = minDistAlong; - if (roadInfo.straight->length - civDat.distAlongSegment < minDistAlong) - civDat.distAlongSegment = roadInfo.straight->length - minDistAlong; + if (roadInfo.straight->length - distAlongSegment < minDistAlong) + distAlongSegment = roadInfo.straight->length - minDistAlong; } if (ROAD_LANE_DIR(roadInfo.straight, lane) == 0) @@ -2416,24 +2423,25 @@ int PingInCivCar(int minPingInDist) } segmentLen = (roadInfo.curve->end - roadInfo.curve->start) - minDistAlong & 0xfff; + distAlongSegment = (currentAngle & 0xfffU) - roadInfo.curve->start; if (roadInfo.curve->inside < 10) - civDat.distAlongSegment = (currentAngle & 0xfffU) - roadInfo.curve->start & 0xf80; + distAlongSegment &= 0xf80; else if (roadInfo.curve->inside < 20) - civDat.distAlongSegment = (currentAngle & 0xfffU) - roadInfo.curve->start & 0xfc0; + distAlongSegment &= 0xfc0; else - civDat.distAlongSegment = (currentAngle & 0xfffU) - roadInfo.curve->start & 0xfe0; + distAlongSegment &= 0xfe0; - if (civDat.distAlongSegment <= minDistAlong) - civDat.distAlongSegment = minDistAlong; + if (distAlongSegment <= minDistAlong) + distAlongSegment = minDistAlong; - if (civDat.distAlongSegment >= segmentLen) - civDat.distAlongSegment = segmentLen; + if (distAlongSegment >= segmentLen) + distAlongSegment = segmentLen; if (ROAD_LANE_DIR(roadInfo.curve, lane) == 0) - dir = civDat.distAlongSegment + roadInfo.curve->start + 1024; + dir = distAlongSegment + roadInfo.curve->start + 1024; else - dir = civDat.distAlongSegment + roadInfo.curve->start - 1024; + dir = distAlongSegment + roadInfo.curve->start - 1024; curveLength = ((roadInfo.curve->end - roadInfo.curve->start & 0xfffU) * roadInfo.curve->inside * 11) / 7; @@ -2447,13 +2455,13 @@ int PingInCivCar(int minPingInDist) return 0; } - if (dir == 0xffffff || lane < 0 || civDat.distAlongSegment < 0) + if (dir == 0xffffff || lane < 0 || distAlongSegment < 0) { //CIV_STATE_SET_CONFUSED(newCar); return 0; } - GetNodePos(roadInfo.straight, NULL, roadInfo.curve, civDat.distAlongSegment, newCar, &newCar->ai.c.targetRoute[0].x, &newCar->ai.c.targetRoute[0].z, lane); + GetNodePos(roadInfo.straight, NULL, roadInfo.curve, distAlongSegment, newCar, &newCar->ai.c.targetRoute[0].x, &newCar->ai.c.targetRoute[0].z, lane); retDistSq = INT_MAX; pos[0] = newCar->ai.c.targetRoute[0].x; @@ -2512,7 +2520,7 @@ int PingInCivCar(int minPingInDist) return 0; } - + civDat.distAlongSegment = distAlongSegment; civDat.angle = dir; InitCar(newCar, dir, &pos, 2, model, 0, (char*)&civDat); From b3efd1ef37d2a155596f82953dd9a4f7577a8d68 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Thu, 4 Aug 2022 16:25:44 -0700 Subject: [PATCH 28/78] [Game:gamesnd] Some code cleanup and refactoring --- src_rebuild/Game/C/gamesnd.c | 288 +++++++++++++++++++++-------------- 1 file changed, 173 insertions(+), 115 deletions(-) diff --git a/src_rebuild/Game/C/gamesnd.c b/src_rebuild/Game/C/gamesnd.c index 6714c3960..da90fa36a 100644 --- a/src_rebuild/Game/C/gamesnd.c +++ b/src_rebuild/Game/C/gamesnd.c @@ -326,32 +326,53 @@ void LoadLevelSFX(int missionNum) LoadBankFromLump(SOUND_BANK_TANNER, SBK_ID_TANNER ); if (GameLevel & 2) - LoadBankFromLump(SOUND_BANK_VOICES, SBK_COP_SIREN_START + (GameLevel & 1) * 2); + LoadBankFromLump(SOUND_BANK_VOICES, SBK_COP_SIREN_START + (GameLevel & 1) * 2); // Vegas, Rio else - LoadBankFromLump(SOUND_BANK_VOICES, SBK_COP_SIREN_START + (GameLevel & 3)); - - // Load cop voices except those missions - if (missionNum != 1 && missionNum != 2 && missionNum != 3 && - missionNum != 4 && missionNum != 6 && missionNum != 7 && - missionNum != 9 && missionNum != 10 && missionNum != 11 && - missionNum != 13 && missionNum != 14 && missionNum != 18 && - missionNum != 19 && missionNum != 20 && missionNum != 22 && - missionNum != 26 && missionNum != 28 && missionNum != 31 && - missionNum != 33 && missionNum != 34 && missionNum != 38 && - missionNum != 40) - { - // first bank - directions - // second bank - - if (GameLevel & 2) - { - LoadBankFromLump(SOUND_BANK_VOICES, SBK_COP_PHRASES_START + (GameLevel & 1) * 8 + (GameLevel & 1) * 2); - LoadBankFromLump(SOUND_BANK_VOICES, SBK_COP_PHRASES_START + (GameLevel & 1) * 10 + cop_bank); - } - else - { - LoadBankFromLump(SOUND_BANK_VOICES, SBK_COP_PHRASES_START + (GameLevel & 3) * 4 + (GameLevel & 3)); - LoadBankFromLump(SOUND_BANK_VOICES, SBK_COP_PHRASES_START + (GameLevel & 3) * 5 + cop_bank); - } + LoadBankFromLump(SOUND_BANK_VOICES, SBK_COP_SIREN_START + (GameLevel & 3)); // Chicago, Havana + + // Load cop voices except for certain missions + switch (missionNum) + { + case 1: + case 2: + case 3: + case 4: + case 6: + case 7: + case 9: + case 10: + case 11: + case 13: + case 14: + case 18: + case 19: + case 20: + case 22: + case 26: + case 28: + case 31: + case 33: + case 34: + case 38: + case 40: + // don't load + break; + default: + // first bank - directions + // second bank - + if (GameLevel & 2) + { + // Vegas, Rio + LoadBankFromLump(SOUND_BANK_VOICES, SBK_COP_PHRASES_START + (GameLevel & 1) * 8 + (GameLevel & 1) * 2); + LoadBankFromLump(SOUND_BANK_VOICES, SBK_COP_PHRASES_START + (GameLevel & 1) * 10 + cop_bank); + } + else + { + // Chicago, Havana + LoadBankFromLump(SOUND_BANK_VOICES, SBK_COP_PHRASES_START + (GameLevel & 3) * 4 + (GameLevel & 3)); + LoadBankFromLump(SOUND_BANK_VOICES, SBK_COP_PHRASES_START + (GameLevel & 3) * 5 + cop_bank); + } + break; } ShowLoading(); @@ -359,29 +380,34 @@ void LoadLevelSFX(int missionNum) // load ambient effects if (NumPlayers < 2 || NoPlayerControl != 0) { - if (GameLevel == 0) - LoadBankFromLump(SOUND_BANK_ENVIRONMENT, SBK_CITY_EFFECTS_START + city_night_fx); - else if (GameLevel == 1) - LoadBankFromLump(SOUND_BANK_ENVIRONMENT, SBK_CITY_EFFECTS_START + city_night_fx + 2); - else if (GameLevel == 2) - LoadBankFromLump(SOUND_BANK_ENVIRONMENT, SBK_CITY_EFFECTS_START + city_night_fx + 4); - else if (GameLevel == 3) - LoadBankFromLump(SOUND_BANK_ENVIRONMENT, SBK_CITY_EFFECTS_START + city_night_fx + 6); + // NB: 2 ambient effects per city + LoadBankFromLump(SOUND_BANK_ENVIRONMENT, SBK_CITY_EFFECTS_START + city_night_fx + (GameLevel * 2)); } // total phrases phrase_top = 0; - if (missionNum == 2 || missionNum == 3 || missionNum == 4 || - missionNum == 9 || missionNum == 10 || missionNum == 27) - { - LoadBankFromLump(SOUND_BANK_MISSION, SBK_ID_JONES); - phrase_top = 7; - } - else if (missionNum == 20 || missionNum == 21 || missionNum == 25 || missionNum == 39) + // in-car voices + switch (missionNum) { - LoadBankFromLump(SOUND_BANK_MISSION, SBK_ID_JERICHO); - phrase_top = 3; + case 2: + case 3: + case 4: + case 9: + case 10: + case 27: + // jones in the car + LoadBankFromLump(SOUND_BANK_MISSION, SBK_ID_JONES); + phrase_top = 7; + break; + case 20: + case 21: + case 25: + case 39: + // jericho in the car + LoadBankFromLump(SOUND_BANK_MISSION, SBK_ID_JERICHO); + phrase_top = 3; + break; } switch (missionNum) @@ -468,53 +494,84 @@ void LoadLevelSFX(int missionNum) LoadBankFromLump(SOUND_BANK_MISSION, index); // special siren bank - if (GameLevel == 0 || GameLevel == 3) - LoadBankFromLump(SOUND_BANK_SFX, SBK_ID_SPECIAL_SIREN1); - else if (GameLevel == 2) - LoadBankFromLump(SOUND_BANK_SFX, SBK_ID_SPECIAL_SIREN2); - + switch (GameLevel) + { + case 0: + case 3: + LoadBankFromLump(SOUND_BANK_SFX, SBK_ID_SPECIAL_SIREN1); + break; + case 2: + LoadBankFromLump(SOUND_BANK_SFX, SBK_ID_SPECIAL_SIREN2); + break; + } + // [A] padding? LoadSoundBankDynamic(NULL, 1, SOUND_BANK_DUMMY); LoadSoundBankDynamic(NULL, 3, SOUND_BANK_CARS); // special vehicle 1 bank - if (missionNum == 39 || missionNum == 40 || (missionNum >= 400 && missionNum <= 404)) - LoadBankFromLump(SOUND_BANK_CARS, MapCarIndexToBank(4)); - else - LoadBankFromLump(SOUND_BANK_CARS, SpecialVehicleKludge(0)); + switch (missionNum) + { + case 39: + case 40: + // [A] + case 400: + case 401: + case 402: + case 403: + case 404: + LoadBankFromLump(SOUND_BANK_CARS, MapCarIndexToBank(4)); + break; + default: + LoadBankFromLump(SOUND_BANK_CARS, SpecialVehicleKludge(0)); + break; + } // special vehicle 2 bank - if (missionNum != 24 && missionNum != 27 && - missionNum != 29 && missionNum != 30 && - missionNum != 35) + switch (missionNum) { - LoadBankFromLump(SOUND_BANK_CARS, SpecialVehicleKludge(1)); + case 24: + case 27: + case 29: + case 30: + case 35: + // don't load + break; + default: + LoadBankFromLump(SOUND_BANK_CARS, SpecialVehicleKludge(1)); + break; } // secret car sound bank - if ((missionNum >= 50 && missionNum <= 65) || missionNum >= 400) + if ((missionNum >= 50 && missionNum <= 65) || + missionNum >= 400 /*[A]*/) { LoadBankFromLump(SOUND_BANK_CARS, SpecialVehicleKludge(2)); } // disable cop speech on specific missions (gangs) // and set cop model (car sound bank) - if (missionNum == 7 || missionNum == 9 || - missionNum == 11 || missionNum == 20 || - missionNum == 26 || missionNum == 31 || - missionNum == 33 || missionNum == 40) + switch (missionNum) { - gDoCopSpeech = 0; + case 7: + case 9: + case 11: + case 20: + case 26: + case 31: + case 33: + case 40: + gDoCopSpeech = 0; - for (i = 0; i < 3; i++) - { - if (MissionHeader->residentModels[i] == MissionHeader->residentModels[3]) - cop_model = i; - } - } - else - { - gDoCopSpeech = 1; + for (i = 0; i < 3; i++) + { + if (MissionHeader->residentModels[i] == MissionHeader->residentModels[3]) + cop_model = i; + } + break; + default: + gDoCopSpeech = 1; + break; } } @@ -717,14 +774,13 @@ void ControlCarRevs(CAR_DATA* cp) newRevs = oldRevs + maxrevrise; cp->hd.revs = newRevs; + if (player_id != -1) { if (acc == 0 && newRevs <= 7000) { - acc = player[player_id].revsvol; - player[player_id].idlevol += 200; - player[player_id].revsvol = acc - 200; + player[player_id].revsvol -= 200; if (player[player_id].idlevol > -6000) player[player_id].idlevol = -6000; @@ -748,15 +804,15 @@ void ControlCarRevs(CAR_DATA* cp) player[player_id].idlevol += acc; + if (player[player_id].idlevol < -10000) + player[player_id].idlevol = -10000; + if (spin == 0) acc = 175; else acc = 700; - player[player_id].revsvol = player[player_id].revsvol + acc; - - if (player[player_id].idlevol < -10000) - player[player_id].idlevol = -10000; + player[player_id].revsvol += acc; if (player[player_id].revsvol > revsmax) player[player_id].revsvol = revsmax; @@ -1330,7 +1386,7 @@ void DoDopplerSFX(void) else volume = -6250; - pitch = (car_data[car].hd.revs << 0x10) >> 0x12; + pitch = car_data[car].hd.revs / 4; if (car_noise[j].idle != 0) pitch += 4096; @@ -1485,43 +1541,45 @@ void CollisionSound(char player_id, CAR_DATA* cp, int impact, int car_car) player[playerid].crash_timer = 2; - if ((impact & 5) && - GetPlayerId(cp) == 0 && - (gCurrentMissionNumber - 2 <= 2 || gCurrentMissionNumber == 9 || gCurrentMissionNumber == 10 || gCurrentMissionNumber == 27)) + if ((impact & 5) && GetPlayerId(cp) == 0) { - rnd = Random2(1); - - if (rnd == (rnd / 3) * 3) - { - phrase |= 4; - } - else + switch (gCurrentMissionNumber) { - if (car_car != 2) - { - if (phrase != 0) + case 2: + case 3: + case 4: + case 9: + case 10: + case 27: + rnd = Random2(1); + + if (rnd == (rnd / 3) * 3) { - if ((Random2(1) & 1) == 0) - sample = 3; - else - sample = 0; - - BodSay(sample); + phrase |= 4; } + else if (car_car != 2) + { + if (phrase != 0) + { + if ((rnd & 1) != 0) + sample = 0; + else + sample = 3; - return; - } - - if (phrase == 0) - return; + BodSay(sample); + } + } + else if (phrase != 0) + { + if ((rnd & 1) != 0) + phrase = 1; + else + phrase = 2; - if ((Random2(1) & 1) != 0) - phrase = 1; - else - phrase = 2; + BodSay(phrase); + } + break; } - - BodSay(phrase); } } @@ -1608,20 +1666,20 @@ void JerichoSpeak(void) // [D] [T] void FunkUpDaBGMTunez(int funk) { - if (funk == 0) + if (funk) { - if (copmusic != 0) + if (copmusic == 0) { - copmusic = 0; - Song_SetPos = 0; + copmusic = 1; + Song_SetPos = xm_coptrackpos[current_music_id]; } } else { - if (copmusic == 0) + if (copmusic != 0) { - copmusic = 1; - Song_SetPos = xm_coptrackpos[current_music_id]; + copmusic = 0; + Song_SetPos = 0; } } } From 959ab5241b9749348efba80e2902d10ee4ae7163 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Thu, 4 Aug 2022 16:26:26 -0700 Subject: [PATCH 29/78] [Game:glaunch] Minor code cleanup --- src_rebuild/Game/C/glaunch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src_rebuild/Game/C/glaunch.c b/src_rebuild/Game/C/glaunch.c index b4aca7193..419e3a78b 100644 --- a/src_rebuild/Game/C/glaunch.c +++ b/src_rebuild/Game/C/glaunch.c @@ -591,8 +591,8 @@ void ReInitFrontend(int returnToMain) SpuSetReverbVoice(0, SPU_ALLCH); UnPauseSound(); - LoadSoundBankDynamic((char*)0x0, 0, 0); - LoadBankFromLump(1, 0); + LoadSoundBankDynamic(NULL, 0, 0); + LoadBankFromLump(SOUND_BANK_SFX, 0); // load frontend LOAD_OVERLAY("FRONTEND.BIN", _overlay_buffer); From 0ae9be237cdd518a52bdb7aeef97064d63bab0ca Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Thu, 4 Aug 2022 16:29:26 -0700 Subject: [PATCH 30/78] [Game:handling] Some code cleanup and refactoring --- src_rebuild/Game/C/handling.c | 44 ++++++++++++++--------------------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/src_rebuild/Game/C/handling.c b/src_rebuild/Game/C/handling.c index cf063e435..496e953ad 100644 --- a/src_rebuild/Game/C/handling.c +++ b/src_rebuild/Game/C/handling.c @@ -1045,14 +1045,14 @@ void CheckCarToCarCollisions(void) bb->z1 = (cp->hd.where.t[2] + zz) / 16; if (cp->st.n.linearVelocity[0] < 0) - bb->x0 = (cp->hd.where.t[0] - xx) / 16 + FIXEDH(cp->st.n.linearVelocity[0]) / 8; + bb->x0 += FIXEDH(cp->st.n.linearVelocity[0]) / 8; else - bb->x1 = (cp->hd.where.t[0] + xx) / 16 + FIXEDH(cp->st.n.linearVelocity[0]) / 8; + bb->x1 += FIXEDH(cp->st.n.linearVelocity[0]) / 8; if (cp->st.n.linearVelocity[2] < 0) - bb->z0 = bb->z0 + (FIXEDH(cp->st.n.linearVelocity[2]) / 8); + bb->z0 += FIXEDH(cp->st.n.linearVelocity[2]) / 8; else - bb->z1 = bb->z1 + (FIXEDH(cp->st.n.linearVelocity[2]) / 8); + bb->z1 += FIXEDH(cp->st.n.linearVelocity[2]) / 8; // [A] 2400 for box size - bye bye collision check performance under bridges bb->y0 = (cp->hd.where.t[1] - colBox->vy * 2) / 16; @@ -1501,23 +1501,14 @@ void nose_down(CAR_DATA* cp) // [D] [T] void jump_debris(CAR_DATA* cp) { - WHEEL* wheel; - int count; - VECTOR position; - VECTOR velocity; - - wheel = cp->hd.wheel; - - for(count = 0; count < 4; count++) + for(int count = 0; count < 4; count++) { - if (wheel->susCompression != 0) + if (cp->hd.wheel[count].susCompression != 0) { DebrisTimer = 0; cp->wasOnGround = 1; return; } - - wheel++; } if (cp->wasOnGround == 1) @@ -1530,17 +1521,15 @@ void jump_debris(CAR_DATA* cp) if (DebrisTimer != 0 && --DebrisTimer < 75) { + VECTOR position, velocity; + memset((u_char*)&velocity, 0, sizeof(velocity)); velocity.vx = cp->hd.where.t[0] + ((rand() & 0x1ff) - 256); velocity.vy = 200 - cp->hd.where.t[1]; + velocity.vz = cp->hd.where.t[2] + ((rand() & 0x1ff) - 256); - position.vz = cp->hd.where.t[2] + ((rand() & 0x1ff) - 256); - position.vx = velocity.vx; - position.vy = velocity.vy; - position.pad = velocity.pad; - - velocity.vz = position.vz; + position = velocity; memset((u_char*)&velocity, 0, sizeof(velocity)); Setup_Debris(&position, &velocity, 5, 0xb); @@ -1674,13 +1663,16 @@ void CheckCarEffects(CAR_DATA* cp, int player_id) if (gWeather == WEATHER_RAIN || gWeather == WEATHER_WET) { - if (wnse != 0) - desired_wheel = wnse + 8; - else - desired_wheel = -1; + desired_wheel = 13 - 4; + } + else if (wnse != 0) + { + desired_wheel = wnse + 8; } else - desired_wheel = 13 - 4; + { + desired_wheel = -1; + } } // play noise sound From bcf089de700e18285842952c39dfa646a85ee593 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Thu, 4 Aug 2022 16:30:28 -0700 Subject: [PATCH 31/78] [Game:job_fx] Cleaned up DrawExplosion, added reusable DrawGlobe function. --- src_rebuild/Game/C/job_fx.c | 184 +++++++++++++++--------------------- 1 file changed, 74 insertions(+), 110 deletions(-) diff --git a/src_rebuild/Game/C/job_fx.c b/src_rebuild/Game/C/job_fx.c index f8919b30c..04902cb0b 100644 --- a/src_rebuild/Game/C/job_fx.c +++ b/src_rebuild/Game/C/job_fx.c @@ -208,136 +208,57 @@ void initExplosion(void) } } - -// [D] [T] -void DrawExplosion(int time, VECTOR position, int hscale, int rscale) +void DrawGlobe(int time, + int step, + int hscale, + int rscale, + int smoke, + int polyCount, + u_int u0, + u_int u1, + u_int u2, + u_int u3) { int j; POLY_FT4 *poly; SVECTOR *src; - + int rgb, transparency; int red, green, blue; - int sf, sf1, sf2; - - u_int u0, u1,u2,u3; + int sf, st; + int i; - VECTOR v; MATRIX workmatrix; int z; - u0 = *(ushort*)&smoke_texture.coords.u0 + 0x200 | *(ushort*)&smoke_texture.clutid << 0x10; - u1 = *(ushort*)&smoke_texture.coords.u1 + 0x200 | (*(ushort*)&smoke_texture.tpageid | 0x20) << 0x10; - u2 = *(ushort*)&smoke_texture.coords.u2 - 0x800; - u3 = *(ushort*)&smoke_texture.coords.u3 - 0x800; - - v.vx = position.vx - camera_position.vx; - v.vy = position.vy - camera_position.vy; - v.vz = position.vz - camera_position.vz; - transparency = 255 - (time >> 4); - rgb = (transparency * transparency >> 10 << 8 | - (255 - transparency) * (transparency >> 2) + transparency * (transparency >> 1) >> 8) << 8 | - transparency | - 0x2e000000; - - Apply_Inv_CameraMatrix(&v); - gte_SetTransVector(&v); - - // [A] modify scale factor to make explosions prettier - sf1 = FIXEDH(time * (5000 - time) * 4) + 12; - sf2 = FIXEDH(time * (10000 - time) * 2) + 12; - for (i = 0; i < 2; i++) + if (step > 0) { - sf = CameraCnt * (64 - i * 90); - - SS.m[1][1] = FIXED(sf1 * hscale); - SS.m[0][0] = FIXEDH(FIXED(sf1 * rscale) * RCOS(sf)); - SS.m[2][0] = FIXEDH(FIXED(sf1 * rscale) * RSIN(sf)); - SS.m[0][2] = -SS.m[2][0]; - SS.m[2][2] = SS.m[0][0]; - - MulMatrix0(&inv_camera_matrix, &SS, &workmatrix); - - gte_SetRotMatrix(&workmatrix); - - src = globemesh; - - for (j = 0; j < 12; j++) - { - poly = (POLY_FT4*)current->primptr; - - gte_ldv3(&src[0], &src[1], &src[2]); - gte_rtpt(); - - *(u_int*)&poly[0].r0 = rgb; - *(u_int*)&poly[1].r0 = rgb; - - setPolyFT4(&poly[0]); - setSemiTrans(&poly[0], 1); - - setPolyFT4(&poly[1]); - setSemiTrans(&poly[1], 1); - - gte_stsxy3(&poly[0].x0, &poly[0].x1, &poly[0].x2); - - gte_stsxy2(&poly[1].x0); - - gte_stsz(&z); - - if (z > 32) - { - gte_ldv3(&src[3], &src[4], &src[5]); - gte_rtpt(); - - *(u_int*)&poly[0].u0 = u0; - *(u_int*)&poly[0].u1 = u1; - *(u_int*)&poly[0].u2 = u2; - *(u_int*)&poly[0].u3 = u3; - - *(u_int*)&poly[1].u0 = u0; - *(u_int*)&poly[1].u1 = u1; - *(u_int*)&poly[1].u2 = u2; - *(u_int*)&poly[1].u3 = u3; - - setPolyFT4(poly); - setSemiTrans(poly, 1); - - setPolyFT4(&poly[1]); - setSemiTrans(&poly[1], 1); - - gte_stsxy3(&poly[1].x1, &poly[1].x2, &poly[1].x3); - - gte_stsxy0(&poly[0].x3); - - addPrim(current->ot + (z >> 3), &poly[0]); - addPrim(current->ot + (z >> 3), &poly[1]); + rgb = transparency >> step; - current->primptr += sizeof(POLY_FT4) * 2; - } - - if ((j & 3) == 3) - src += 6; - else - src += 4; - } + red = rgb + (transparency * transparency >> 10) >> step; + green = rgb + ((255 - transparency) * (transparency >> 2) + transparency * rgb >> 8) >> step; + blue = rgb; + } + else + { + red = transparency * transparency >> 10; + green = (255 - transparency) * (transparency >> 2) + transparency * (transparency >> 1) >> 8; + blue = transparency; } - transparency = 255 - (time >> 4); + rgb = (red << 8 | green) << 8 | blue | 0x2e000000; - rgb = transparency >> 1; - rgb = (rgb + (transparency * transparency >> 10) >> 1 << 8 | - rgb + ((255 - transparency) * (transparency >> 2) + transparency * rgb >> 8) >> 1) << 8 | - rgb | 0x2e000000; + st = FIXEDH(time * ((5000 << step) - time) * (4 >> step)) + 12; for (i = 0; i < 2; i++) { sf = CameraCnt * (i * -90 + 64); - - SS.m[1][1] = FIXED(sf2 * hscale); - SS.m[0][0] = FIXEDH(FIXED(sf2 * rscale) * RCOS(sf)); - SS.m[2][0] = FIXEDH(FIXED(sf2 * rscale) * RSIN(sf)); + + SS.m[1][1] = FIXED(st * hscale); + SS.m[0][0] = FIXEDH(FIXED(st * rscale) * RCOS(sf)); + SS.m[2][0] = FIXEDH(FIXED(st * rscale) * RSIN(sf)); SS.m[0][2] = -SS.m[2][0]; SS.m[2][2] = SS.m[0][0]; @@ -346,7 +267,7 @@ void DrawExplosion(int time, VECTOR position, int hscale, int rscale) src = globemesh; - for (j = 0; j < 8; j++) + for (j = 0; j < polyCount; j++) { poly = (POLY_FT4 *)current->primptr; @@ -357,6 +278,15 @@ void DrawExplosion(int time, VECTOR position, int hscale, int rscale) *(u_int *)&poly[1].r0 = rgb; *(u_int *)&poly[0].r0 = rgb; + if (smoke) + { + setPolyFT4(&poly[0]); + setSemiTrans(&poly[0], 1); + + setPolyFT4(&poly[1]); + setSemiTrans(&poly[1], 1); + } + gte_stsxy3(&poly[0].x0, &poly[0].x1, &poly[0].x2); gte_stsxy2(&poly[1].x0); @@ -402,6 +332,40 @@ void DrawExplosion(int time, VECTOR position, int hscale, int rscale) } +// [D] [T] +void DrawExplosion(int time, VECTOR position, int hscale, int rscale) +{ + int j; + POLY_FT4 *poly; + SVECTOR *src; + + int rgb, transparency; + int red, green, blue; + int sf, sf1, sf2; + + u_int u0, u1,u2,u3; + int i; + VECTOR v; + MATRIX workmatrix; + int z; + + u0 = *(ushort*)&smoke_texture.coords.u0 + 0x200 | *(ushort*)&smoke_texture.clutid << 0x10; + u1 = *(ushort*)&smoke_texture.coords.u1 + 0x200 | (*(ushort*)&smoke_texture.tpageid | 0x20) << 0x10; + u2 = *(ushort*)&smoke_texture.coords.u2 - 0x800; + u3 = *(ushort*)&smoke_texture.coords.u3 - 0x800; + + v.vx = position.vx - camera_position.vx; + v.vy = position.vy - camera_position.vy; + v.vz = position.vz - camera_position.vz; + + Apply_Inv_CameraMatrix(&v); + gte_SetTransVector(&v); + + DrawGlobe(time, 0, hscale, rscale, 0, 12, u0, u1, u2, u3); + DrawGlobe(time, 1, hscale, rscale, 1, 8, u0, u1, u2, u3); +} + + // [D] [T] void DrawAllExplosions(void) { From 43007955ceecbf0850f4fceec42cd959765ef78a Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Thu, 4 Aug 2022 16:32:31 -0700 Subject: [PATCH 32/78] [Game:leadai] Corrected DIFF_ANGLES macro usage --- src_rebuild/Game/C/leadai.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src_rebuild/Game/C/leadai.c b/src_rebuild/Game/C/leadai.c index 2d3b55ea5..f122b69b7 100644 --- a/src_rebuild/Game/C/leadai.c +++ b/src_rebuild/Game/C/leadai.c @@ -1216,8 +1216,8 @@ void BlockToMap(MAP_DATA* data) dx = corners[left][1] - corners[right][1]; dy = corners[left][0] - corners[right][0]; - theta = (ratan2(dy, dx) + 3072 & 0xfff) - 2048; // there should be DIFF_ANGLES but idk - + theta = DIFF_ANGLES(0, ratan2(dy, dx) + 1024); + vx = RSIN(theta) * corners[left][0]; vz = RCOS(theta) * corners[left][1]; From b8f6b19b99dd9494506c4d2f052de80a8f38fecd Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Thu, 4 Aug 2022 16:33:44 -0700 Subject: [PATCH 33/78] [Game:main] Minor code cleanup and refactoring --- src_rebuild/Game/C/main.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src_rebuild/Game/C/main.c b/src_rebuild/Game/C/main.c index 2094d4198..831937e08 100644 --- a/src_rebuild/Game/C/main.c +++ b/src_rebuild/Game/C/main.c @@ -910,13 +910,16 @@ void StepSim(void) for (i = 0; i < 10; i++) PingInCivCar(15900); } - else if (numCivCars < maxCivCars && (NumPlayers == 1 || (NumPlayers == 2 && GameType == GAME_COPSANDROBBERS))) + else { - // make 5 tries - for (i = 0; i < 5; i++) + if (numCivCars < maxCivCars && (NumPlayers == 1 || (NumPlayers == 2 && GameType == GAME_COPSANDROBBERS))) { - if (PingInCivCar(15900)) - break; + // make 5 tries + for (i = 0; i < 5; i++) + { + if (PingInCivCar(15900)) + break; + } } } @@ -2207,11 +2210,17 @@ void UpdatePlayerInformation(void) } // die with fade on mountain race track - if ((gCurrentMissionNumber > 479 && gCurrentMissionNumber < 482 || - gCurrentMissionNumber > 483 && gCurrentMissionNumber < 486) && - cp->hd.where.t[1] < -750 && gDieWithFade == 0) - { - gDieWithFade = 1; + switch (gCurrentMissionNumber) + { + case 480: + case 481: + case 484: + case 485: + case 486: + case 487: + if (cp->hd.where.t[1] < -750 && !gDieWithFade) + gDieWithFade = 1; + break; } } } @@ -2754,9 +2763,6 @@ int Havana3DOcclusion(occlFunc func, int* param) events.camera = 0; return outside; } - - (*func)(param); - return 1; } (*func)(param); From a44a186704d4c6968c78473e3dba7a461e879ae4 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Thu, 4 Aug 2022 16:34:37 -0700 Subject: [PATCH 34/78] [Game:main] Add missing reset value for Havana3DLevelMode --- src_rebuild/Game/C/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src_rebuild/Game/C/main.c b/src_rebuild/Game/C/main.c index 831937e08..ade9b4124 100644 --- a/src_rebuild/Game/C/main.c +++ b/src_rebuild/Game/C/main.c @@ -2437,6 +2437,7 @@ void InitGameVariables(void) CopsCanSeePlayer = 0; Havana3DLevelDraw = -1; + Havana3DLevelMode = -1; srand(0x1234); RandomInit(0xd431, 0x350b1); From 09dd49dd33a3925da3240745b9d016af7011522f Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Thu, 4 Aug 2022 16:37:59 -0700 Subject: [PATCH 35/78] [Game:mc_snd] Code cleanup and refactoring - Fixed GetMissionSound needing to use u_char instead of char type - Cleaned up missionstarts and id_map data structs --- src_rebuild/Game/C/gamesnd.c | 4 +- src_rebuild/Game/C/mc_snd.c | 156 ++++++++++++++--------------------- 2 files changed, 65 insertions(+), 95 deletions(-) diff --git a/src_rebuild/Game/C/gamesnd.c b/src_rebuild/Game/C/gamesnd.c index da90fa36a..cb70ce827 100644 --- a/src_rebuild/Game/C/gamesnd.c +++ b/src_rebuild/Game/C/gamesnd.c @@ -1592,7 +1592,7 @@ void ExplosionSound(VECTOR* pos, int type) int bang; VECTOR P; - bang = 255; + bang = -1; rnd = Random2(4); if (gCurrentMissionNumber == 13 || gCurrentMissionNumber == 23) @@ -1604,7 +1604,7 @@ void ExplosionSound(VECTOR* pos, int type) bang = GetMissionSound(29); } - if (bang == 255) + if (bang == -1) return; if (type == BIG_BANG) diff --git a/src_rebuild/Game/C/mc_snd.c b/src_rebuild/Game/C/mc_snd.c index ae42be8a2..47ebfdbeb 100644 --- a/src_rebuild/Game/C/mc_snd.c +++ b/src_rebuild/Game/C/mc_snd.c @@ -26,70 +26,41 @@ typedef struct __xa_request } xa_request; char missionstarts[42] = { - 0xFF, 0xFF, 0, 2, 4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 6, 8, 0xFF, 9, 0xFF, 12, 13, 0xFF, 14, 0xFF, 19, - 20, 0xFF, 21, 24, 26, 0xFF, 28, 0xFF, 30, - 33, 0xFF, 37, 39, 0xFF, 41, 0xFF, 0xFF, 0xFF, - 46, 48, 49 + -1, + -1, 0, 2, 4, -1, -1, -1, -1, -1, + 6, 8, -1, 9, -1, 12, 13, -1, 14, -1, 19, + 20, -1, 21, 24, 26, -1, 28, -1, 30, 33, + -1, 37, 39, -1, 41, -1, -1, -1, 46, 48, + 49, }; io id_map[49] = { - {0, 0},{0, 1}, - - {2, 0}, - {3, 1}, - {4, 0}, - {5, 1}, - {4, 0}, - {5, 1}, - {11, 0}, - - {12, 0},{12, 1}, - - {11, 2}, - - {14, 0},{14, 0}, - - {15, 0}, - - {16, 1},{16, 2}, - - {18, 3},{18, 4}, - - {11, 0},{11, 0}, - - {20, 0}, - - {12, 1}, - - {13, 2}, - - {21, 0}, - {31, 1},{31, 0}, - {11, 1}, - {23, 0}, - {24, 1}, - {26, 0}, - {27, 1}, - {28, 2}, - {34, 0}, - - {29, 1}, {29, 2}, - - {20, 3}, - {31, 0}, - {11, 1}, - {31, 0}, - {33, 1}, - {34, 0}, - {36, 1}, - {29, 2}, - {29, 3}, - {20, 4}, - {37, 0}, - {38, 1}, - {39, 0}, + /*00*/{0, 0},{0, 1}, + /*02*/{2, 0},{3, 1}, + /*04*/{4, 0},{5, 1}, + /*06*/{4, 0},{5, 1}, + + /*08*/{11, 0}, + /*09*/{12, 0},{12, 1},{11, 2}, + /*12*/{14, 0}, + /*13*/{14, 0}, + /*14*/{15, 0},{16, 1},{16, 2},{18, 3},{18, 4}, + /*19*/{11, 0}, + + /*20*/{11, 0}, + /*21*/{20, 0},{12, 1},{13, 2}, + /*24*/{21, 0},{31, 1}, + /*26*/{31, 0},{11, 1}, + /*28*/{23, 0},{24, 1}, + /*30*/{26, 0},{27, 1},{28, 2}, + /*33*/{34, 0},{29, 1}, {29, 2},{20, 3}, + + /*37*/{31, 0},{11, 1}, + /*39*/{31, 0},{33, 1}, + /*41*/{34, 0},{36, 1},{29, 2},{29, 3},{20, 4}, + /*46*/{37, 0},{38, 1}, + /*48*/{39, 0}, }; xa_request xa_data[26] = { @@ -119,7 +90,7 @@ xa_request xa_data[26] = { {16, 2, 7, 39, 0}, {750, 3, 0, 33, 1}, - {0, 0, 0, 0xFF, 0}, + {0, 0, 0, -1, 0}, }; int cutscene_timer = 0; @@ -129,41 +100,40 @@ static intptr_t bodgevar = 0; // [D] [T] char GetMissionSound(char id) { - u_char end; - u_char rnd; - u_char c; - u_char start; + char c; + char start; + char end; + char rnd; - start = missionstarts[gCurrentMissionNumber]; - rnd = Random2(5); + // [A] + if (gCurrentMissionNumber > 40) + return -1; - if (start != 0xff) + c = 0; + + start = missionstarts[gCurrentMissionNumber]; + rnd = Random2(5) % 2; + + if (start != -1) { - c = 1; - do { - end = missionstarts[gCurrentMissionNumber + c]; + do + { c++; - } while (end == 0xff); + end = missionstarts[gCurrentMissionNumber + c]; + } while (end == -1); - while (start < end) + for (c = start; c < end; c++) { - c = start + 1; - - if (id_map[start].in == id) + if (id_map[c].in == id) { - if (c == end) - return id_map[start].out + phrase_top; - - if(id_map[c].in == id) - return id_map[start + (rnd % 2 & 0xffU)].out + phrase_top; - - return id_map[start].out + phrase_top; + if (c + 1 != end && id_map[c + 1].in == id) + return id_map[c + rnd].out + phrase_top; + return id_map[c].out + phrase_top; } - - start = c; } } + return -1; } @@ -396,7 +366,7 @@ void InitializeMissionSound(void) } else if (GameLevel == 1) { - if (gCurrentMissionNumber - 15U < 2) + if (gCurrentMissionNumber == 15 || gCurrentMissionNumber == 16) { es_mobile[0] = AddEnvSnd(3, 0x20, SOUND_BANK_MISSION, GetMissionSound(14), 0, -10000, 0, 0, 0); } @@ -456,7 +426,7 @@ void DoMissionSound(void) { channel = GetFreeChannel(); - Start3DSoundVolPitch(channel, SOUND_BANK_MISSION, GetMissionSound(11), pos[0], pos[1], pos[2], -1000, 0x1000); + Start3DSoundVolPitch(channel, SOUND_BANK_MISSION, GetMissionSound(11), pos[0], pos[1], pos[2], -1000, 4096); bodgevar = 2; } else if (bodgevar == 3) @@ -486,7 +456,7 @@ void DoMissionSound(void) case 23: if (holdall == -1) { - for (i = 0; i < 16; i++) + for (i = 0; i < MAX_MISSION_TARGETS; i++) { if (MissionTargets[i].type == Target_Car) { @@ -522,7 +492,7 @@ void DoMissionSound(void) { channel = GetFreeChannel(); - Start3DSoundVolPitch(channel, SOUND_BANK_MISSION, GetMissionSound(11), pos[0], pos[1], pos[2], -1000, 0x1000); + Start3DSoundVolPitch(channel, SOUND_BANK_MISSION, GetMissionSound(11), pos[0], pos[1], pos[2], -1000, 4096); holdall++; bodgevar = 2; } @@ -546,7 +516,7 @@ void DoMissionSound(void) { P = &Q[bodgevar - 1]; - Start3DSoundVolPitch(-1, SOUND_BANK_MISSION, GetMissionSound(34), P->vx, P->vy, P->vz, -1000, 0x1000); + Start3DSoundVolPitch(-1, SOUND_BANK_MISSION, GetMissionSound(34), P->vx, P->vy, P->vz, -1000, 4096); bodgevar += 4; } @@ -578,7 +548,7 @@ void DoMissionSound(void) if (bodgevar == 1) { channel = GetFreeChannel(); - Start3DSoundVolPitch(channel, SOUND_BANK_MISSION, GetMissionSound(11), pos[0], pos[1], pos[2], -1000, 0x1000); + Start3DSoundVolPitch(channel, SOUND_BANK_MISSION, GetMissionSound(11), pos[0], pos[1], pos[2], -1000, 4096); bodgevar = 2; } else if (bodgevar == 3) @@ -596,7 +566,7 @@ void DoMissionSound(void) case 33: if (holdall == -1) { - StartSound(2, SOUND_BANK_VOICES, 0, -10000, 0x81); + StartSound(2, SOUND_BANK_VOICES, 0, -10000, 129); holdall = 0; } break; @@ -638,7 +608,7 @@ void DoMissionSound(void) case 39: if (holdall == -1) { - for (i = 0; i < 16; i++) + for (i = 0; i < MAX_MISSION_TARGETS; i++) { if (MissionTargets[i].type == Target_Car) { From bd785cb30d64de6e6cdfe63d00b7a612aaec4115 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Thu, 4 Aug 2022 16:38:43 -0700 Subject: [PATCH 36/78] [Game:mdraw] Minor code cleanup and refactoring --- src_rebuild/Game/C/mdraw.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src_rebuild/Game/C/mdraw.c b/src_rebuild/Game/C/mdraw.c index a234ca381..088709fa2 100644 --- a/src_rebuild/Game/C/mdraw.c +++ b/src_rebuild/Game/C/mdraw.c @@ -53,6 +53,8 @@ void DisplayPlayerPosition(void) char string[40]; sprintf(string, "X: %d, Y: %d, Z: %d", player[0].pos[0], player[0].pos[1], player[0].pos[2]); + + SetTextColour(128, 128, 64); PrintString(string, 20, 210); } @@ -323,9 +325,6 @@ void DrawWorldTarget(MS_TARGET *target) // [D] [T] void DrawMultiplayerTarget(MS_TARGET *target) { - u_char b; - u_char g; - u_char r; VECTOR tv; int activeTargets; @@ -338,9 +337,9 @@ void DrawMultiplayerTarget(MS_TARGET *target) if (activeTargets == 0) return; - r = 64; - g = 64; - b = 64; + u_char r = 64; + u_char g = 64; + u_char b = 64; if(activeTargets == 1) { @@ -431,12 +430,10 @@ void DrawMultiplayerTarget(MS_TARGET *target) // [D] [T] void DrawWorldTargets(void) { - int i; - if (!Mission.active) return; - for (i = 0; i < MAX_MISSION_TARGETS; i++) + for (int i = 0; i < MAX_MISSION_TARGETS; i++) DrawWorldTarget(&MissionTargets[i]); } @@ -444,12 +441,10 @@ void DrawWorldTargets(void) // [D] [T] void DrawOverheadTargets(void) { - int i; - if (!Mission.active) return; - for (i = 0; i < MAX_MISSION_TARGETS; i++) + for (int i = 0; i < MAX_MISSION_TARGETS; i++) DrawOverheadTarget(&MissionTargets[i]); } From 3a93223282c73384fb3f72cc640119ba21247ae6 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Thu, 4 Aug 2022 17:04:48 -0700 Subject: [PATCH 37/78] [Game:motion_c] Fixed sprite shadow drawing bugs, cleaned up code - [PC] Added extra parameter to DoCivHead so there's not a floating head in the corner of the screen - [PC] Some improvements for non-Tanner model drawing --- src_rebuild/Game/C/motion_c.c | 50 +++++++++++++++++++++++++++++++++-- src_rebuild/Game/C/motion_c.h | 6 ++++- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src_rebuild/Game/C/motion_c.c b/src_rebuild/Game/C/motion_c.c index 7f7da3cc0..a93aaba13 100644 --- a/src_rebuild/Game/C/motion_c.c +++ b/src_rebuild/Game/C/motion_c.c @@ -563,6 +563,10 @@ void DrawBodySprite(LPPEDESTRIAN pDrawingPed, int boneId, VERTTYPE v1[2], VERTTY { width -= 5; } +#ifndef PSX + else if (bDoingShadow && (bone == HEAD) && pDrawingPed->pedType == OTHER_SPRITE) + width += 7; +#endif x = v1[0] - v2[0]; y = v1[1] - v2[1]; @@ -1065,6 +1069,10 @@ void newShowTanner(LPPEDESTRIAN pDrawingPed) playerPos->vy = pDrawingPed->position.vy - 15; // [A] elevate Tanner model a little bit so his legs are not in the ground (when Z-buffer enabled) playerPos->vz = pDrawingPed->position.vz; + // [A] lift sprites feet out of the ground + if (pDrawingPed->pedType == OTHER_SPRITE) + playerPos->vy -= 80; + cameraPos->vx = camera_position.vx; cameraPos->vy = camera_position.vy; cameraPos->vz = camera_position.vz; @@ -1107,7 +1115,7 @@ void newShowTanner(LPPEDESTRIAN pDrawingPed) vJPos[pBone->id].vy = vJPos[lval].vy + pBone->vCurrPos.vy; vJPos[pBone->id].vz = vJPos[lval].vz + pBone->vCurrPos.vz; - if (pDrawingPed->pedType == TANNER_MODEL && pBone->id == HEAD) + if (pDrawingPed->pedType != CIVILIAN && pBone->id == HEAD) pDrawingPed->head_pos = vJPos[lval].vy; if (pBone->pModel != NULL @@ -1247,7 +1255,11 @@ void newShowTanner(LPPEDESTRIAN pDrawingPed) v2.vz = vJPos[pBone->pParent->id & 127].vz; bAllreadyRotated = 1; +#ifndef PSX + DoCivHead(pDrawingPed, &v2, &v1, vJPos); +#else DoCivHead(pDrawingPed, &v2, &v1); +#endif bAllreadyRotated = 0; } } @@ -1551,7 +1563,11 @@ void DrawCiv(LPPEDESTRIAN pPed) if (bHeadModel) { bAllreadyRotated = 0; +#ifndef PSX + DoCivHead(pPed, &srLerpData[5], &srLerpData[4], srLerpData); +#else DoCivHead(pPed, &srLerpData[5], &srLerpData[4]); +#endif ppos.vx = 0; ppos.vy = 0; @@ -1691,7 +1707,13 @@ int DrawCharacter(LPPEDESTRIAN pPed) iCurrBone = 0; newShowTanner(pPed); +#ifdef PSX + // only draw a shadow for tanner (who must be the last ped) if (pUsedPeds->pNext == NULL && pPed->pedType == TANNER_MODEL) +#else + // draw a nice shadow for non-civilian peds :) + if (pPed->pedType != CIVILIAN) +#endif { v.vx = (pPed->position.vx - camera_position.vx) + Skel[ROOT].pvOrigPos->vx; v.vz = (pPed->position.vz - camera_position.vz) + Skel[ROOT].pvOrigPos->vz; @@ -1712,7 +1734,11 @@ int DrawCharacter(LPPEDESTRIAN pPed) bDoingShadow = 0; } - else if (pPed->pedType == CIVILIAN) + else +#ifdef PSX + // draw a round shadow for civilians + if (pPed->pedType == CIVILIAN) +#endif { pos.vx = pPed->position.vx; pos.vy = pPed->position.vy; @@ -1962,7 +1988,11 @@ void TannerShadow(LPPEDESTRIAN pDrawingPed, VECTOR* pPedPos, SVECTOR* pLightPos, } // [A] - totally custom function but it works pretty much same as original +#ifndef PSX +void DoCivHead(LPPEDESTRIAN pPed, SVECTOR* vert1, SVECTOR* vert2, SVECTOR* vJPos) +#else void DoCivHead(LPPEDESTRIAN pPed, SVECTOR* vert1, SVECTOR* vert2) +#endif { SVECTOR spos; VECTOR pos; @@ -1995,6 +2025,11 @@ void DoCivHead(LPPEDESTRIAN pPed, SVECTOR* vert1, SVECTOR* vert2) spos.vy = headpos.vy + pPed->position.vy - camera_position.vy; spos.vz = headpos.vz + pPed->position.vz - camera_position.vz; +#ifndef PSX + if (bDoingShadow && pPed->pedType == OTHER_SPRITE) + spos.vy -= 20; +#endif + gte_SetRotMatrix(&inv_camera_matrix); gte_ldv0(&spos); gte_rtv0(); @@ -2016,7 +2051,18 @@ void DoCivHead(LPPEDESTRIAN pPed, SVECTOR* vert1, SVECTOR* vert2) if (gNight) combointensity = 0x404040; +#ifndef PSX + if (bDoingShadow) + { + DrawSprite(pPed, &Skel[HEAD], vJPos); + } + else + { + RenderModel(gPed1HeadModelPtr, pHeadRot, &pos, 1, flags, 0, 0); + } +#else RenderModel(gPed1HeadModelPtr, pHeadRot, &pos, 1, flags, 0, 0); +#endif combointensity = oldcombointensity; } diff --git a/src_rebuild/Game/C/motion_c.h b/src_rebuild/Game/C/motion_c.h index 9dbf6ee72..50fd1269e 100644 --- a/src_rebuild/Game/C/motion_c.h +++ b/src_rebuild/Game/C/motion_c.h @@ -30,7 +30,11 @@ extern int DrawCharacter(LPPEDESTRIAN pPed); // 0x00067D44 extern void InitTannerShadow(); // 0x000681EC extern void TannerShadow(LPPEDESTRIAN pDrawingPed, VECTOR *pPedPos, SVECTOR *pLightPos, CVECTOR *col, short angle); // 0x00068358 +#ifndef PSX +// [A] extra parameter for proper sprite shadow support +extern void DoCivHead(LPPEDESTRIAN pPed, SVECTOR *vert1, SVECTOR *vert2, SVECTOR *vJPos); // 0x00068B2C +#else extern void DoCivHead(LPPEDESTRIAN pPed, SVECTOR *vert1, SVECTOR *vert2); // 0x00068B2C - +#endif #endif From 26e947f8cd5455e7d1cde1ee285f293dc9fe3f98 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Thu, 4 Aug 2022 17:05:52 -0700 Subject: [PATCH 38/78] [Game:objanim] Fixed incorrect coordinates check for Vegas street lights --- src_rebuild/Game/C/objanim.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src_rebuild/Game/C/objanim.c b/src_rebuild/Game/C/objanim.c index 039363c44..3eec20383 100644 --- a/src_rebuild/Game/C/objanim.c +++ b/src_rebuild/Game/C/objanim.c @@ -628,10 +628,12 @@ void animate_object(CELL_OBJECT* cop, int type) if (gLightsOn == 0) break; - // spooled? - if (cop->pos.vx - 137190U < 50687 && cop->pos.vz > 713372 && cop->pos.vz < 719516) + // fremont lights by the parking garage + // coordinates were incorrect before + if (cop->pos.vx >= 147190 && cop->pos.vx <= 197878) { - AddSmallStreetLight(cop, -620, -101, 0, 0); + if (cop->pos.vz > 701372 && cop->pos.vz < 709516) + AddSmallStreetLight(cop, -620, -1618, 0, 0); break; } From fa65031708a782fc994a9a94f4aae0a3bd8e4822 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Thu, 4 Aug 2022 17:36:11 -0700 Subject: [PATCH 39/78] [Game:pedest] Some code cleanup and refactoring - Make sure PEDESTRIAN.padId is never a negative number for players - Optimized some conditional checks for a player pedestrian using PEDESTRIAN.padId - Civilians now have PEDESTRIAN.padId set to -1 --- src_rebuild/Game/C/motion_c.c | 13 ++++-- src_rebuild/Game/C/pedest.c | 78 ++++++++++++++++++----------------- 2 files changed, 50 insertions(+), 41 deletions(-) diff --git a/src_rebuild/Game/C/motion_c.c b/src_rebuild/Game/C/motion_c.c index a93aaba13..7d04e64a2 100644 --- a/src_rebuild/Game/C/motion_c.c +++ b/src_rebuild/Game/C/motion_c.c @@ -1088,9 +1088,16 @@ void newShowTanner(LPPEDESTRIAN pDrawingPed) // do not draw the root Skel[ROOT].id = (LIMBS)(Skel[ROOT].id | 0x80); - draw = (pDrawingPed->padId > -1 && pDrawingPed->padId == CurrentPlayerView) - ? player[pDrawingPed->padId].cameraView != 2 - : 1; + // draw the main body? + draw = 1; + + if (pDrawingPed->pedType != CIVILIAN) + { + char padId = pDrawingPed->padId; + + if (padId == CurrentPlayerView && player[padId].cameraView == 2) + draw = 0; + } for (i = 0; i < 5; i++) { diff --git a/src_rebuild/Game/C/pedest.c b/src_rebuild/Game/C/pedest.c index 08b900f2b..47b5e89d9 100644 --- a/src_rebuild/Game/C/pedest.c +++ b/src_rebuild/Game/C/pedest.c @@ -177,7 +177,7 @@ void SetTannerPosition(VECTOR* pVec) pPed = pUsedPeds; while (pPed) { - if (pPed->pedType == TANNER_MODEL || ActiveCheats.cheat12 && pPed->pedType == OTHER_MODEL) + if (pPed->padId == 0) { pPed->position.vx = pVec->vx; pPed->position.vy = -pVec->vy; @@ -186,6 +186,8 @@ void SetTannerPosition(VECTOR* pVec) player[0].pos[0] = pVec->vx; player[0].pos[1] = pVec->vy; player[0].pos[2] = pVec->vz; + + break; } pPed = pPed->pNext; @@ -288,7 +290,7 @@ void DestroyPedestrians(void) { while (pUsedPeds) { - if (pUsedPeds->pedType == TANNER_MODEL || ActiveCheats.cheat12 && pUsedPeds->pedType == OTHER_MODEL) + if (pUsedPeds->pedType != CIVILIAN) numTannerPeds--; DestroyPedestrian(pUsedPeds); @@ -487,6 +489,7 @@ int CreatePedAtLocation(LONGVECTOR4* pPos, int pedType) pPed->position.vy = (*pPos)[1]; pPed->position.vz = (*pPos)[2]; + pPed->padId = -1; pPed->pedType = CIVILIAN; pPed->dir.vz = 0; @@ -501,6 +504,9 @@ int CreatePedAtLocation(LONGVECTOR4* pPos, int pedType) { pPed->flags = 0; pPed->fpRestState = fpPedPersonalityFunctions[7]; + // [A] fix cops coming out of vehicles after roadblocks + if (pPed->pallet == 85) + pPed->pallet = (Random2(0) % 5) + (Random2(0) % 5) * 16; } else if (pedType >= 8 && pedType <= 13) { @@ -717,7 +723,7 @@ void AnimatePed(LPPEDESTRIAN pPed) pPed->frame1 = 0; } - if ((pPed->pedType == TANNER_MODEL || (ActiveCheats.cheat12 && pPed->pedType == OTHER_MODEL)) && pPed->type < PED_ACTION_BACK) + if (pPed->pedType != CIVILIAN && pPed->padId != -1 && pPed->type < PED_ACTION_BACK) { int surfId; surfId = PedSurfaceType(&vec); @@ -729,17 +735,16 @@ void AnimatePed(LPPEDESTRIAN pPed) surfId != SURF_DEEPWATER) { if (pPed->frame1 == 3) - Start3DSoundVolPitch(-1, SOUND_BANK_TANNER, 0, pPed->position.vx, -pPed->position.vy, pPed->position.vz, -5000, 0x1000); + Start3DSoundVolPitch(-1, SOUND_BANK_TANNER, 0, pPed->position.vx, -pPed->position.vy, pPed->position.vz, -5000, 4096); if (pPed->frame1 == 11) - Start3DSoundVolPitch(-1, SOUND_BANK_TANNER, 1, pPed->position.vx, -pPed->position.vy, pPed->position.vz, -5000, 0x1000); + Start3DSoundVolPitch(-1, SOUND_BANK_TANNER, 1, pPed->position.vx, -pPed->position.vy, pPed->position.vz, -5000, 4096); } } if (pPed->pedType != CIVILIAN) { - int padId; - padId = ABS(pPed->padId); + int padId = pPed->padId; player[padId].pos[0] = pPed->position.vx; player[padId].pos[1] = -pPed->position.vy; @@ -1258,7 +1263,7 @@ void SetupGetInCar(LPPEDESTRIAN pPed) // HEY! CreatePedAtLocation(&pos, 8); - Start3DSoundVolPitch(-1, SOUND_BANK_TANNER, 5, pos[0], pos[1], pos[2], 0, 0x1000); + Start3DSoundVolPitch(-1, SOUND_BANK_TANNER, sample, pos[0], pos[1], pos[2], 0, 4096); carToGetIn->controlFlags |= CONTROL_FLAG_WAS_PARKED; } @@ -1268,8 +1273,6 @@ void SetupGetInCar(LPPEDESTRIAN pPed) // [D] [T] void PedGetInCar(LPPEDESTRIAN pPed) { - int playerID; - pPed->speed = 0; if (pPed->frame1 < 0xf) @@ -1278,14 +1281,12 @@ void PedGetInCar(LPPEDESTRIAN pPed) } else { - playerID = ABS(pPed->padId); - pPed->speed = 0; pPed->fpAgitatedState = NULL; pPed->flags &= ~0x10; - ChangePedPlayerToCar(playerID, carToGetIn); + ChangePedPlayerToCar(pPed->padId, carToGetIn); DestroyPedestrian(pPed); numTannerPeds--; @@ -2383,8 +2384,8 @@ void add_seated(SEATEDPTR seatedptr, int seat_index) } } -CAR_COLLISION_BOX collision_box[8]; -CAR_DATA* collision_car_ptr[8]; +CAR_COLLISION_BOX collision_box[MAX_PED_COLLISIONS]; +CAR_DATA* collision_car_ptr[MAX_PED_COLLISIONS]; // [D] [T] void set_coll_box(int index, CAR_DATA* cp, int offset) @@ -2394,7 +2395,7 @@ void set_coll_box(int index, CAR_DATA* cp, int offset) VECTOR BoxCentre; - if (index >= 8) + if (index >= MAX_PED_COLLISIONS) return; boxSize = 400; @@ -2423,7 +2424,7 @@ void set_coll_box(int index, CAR_DATA* cp, int offset) collision_box[index].max_z = BoxCentre.vz + boxSize; } -CAR_COLLISION_BOX extra_collision_boxes[5]; +CAR_COLLISION_BOX extra_collision_boxes[MAX_EXPLOSION_OBJECTS]; CAR_COLLISION_BOX tanner_collision_box; int num_extra_boxes_set; int collision_boxes_set; @@ -2436,21 +2437,28 @@ void BuildCarCollisionBox(void) int vx, vz; int index; EXOBJECT* expl; - CAR_DATA* cp; + CAR_DATA* cp, *lcp; if (player[0].playerCarId != -1) // [A] ASan bug fix { - set_coll_box(0, &car_data[player[0].playerCarId], 8); - set_coll_box(1, &car_data[player[0].playerCarId], 9); + lcp = &car_data[player[0].playerCarId]; + + set_coll_box(0, lcp, 8); + set_coll_box(1, lcp, 9); + + collision_boxes_set = 2; + } + else + { + lcp = NULL; + collision_boxes_set = 0; } cp = &car_data[(CameraCnt & 3)]; - collision_boxes_set = 2; - while (cp < &car_data[MAX_CARS]) { - if (cp != &car_data[player[0].playerCarId] && cp->controlType != CONTROL_TYPE_NONE) + if (cp != lcp && cp->controlType != CONTROL_TYPE_NONE) { set_coll_box(collision_boxes_set, cp, 8); collision_boxes_set++; @@ -2475,7 +2483,7 @@ void BuildCarCollisionBox(void) num_extra_boxes_set = 0; expl = explosion; - index = 4; + index = MAX_EXPLOSION_OBJECTS-1; do { if (expl->time >= 2048) @@ -2559,6 +2567,7 @@ void CalculatePedestrianInterest(LPPEDESTRIAN pPed) if (carId == -1) // [A] ASan bug fix { + pPed->interest = 0; pPed->head_rot = 0; return; } @@ -2676,12 +2685,9 @@ void ProcessTannerPad(LPPEDESTRIAN pPed, u_int pad, char PadSteer, char use_anal sdPlane* plane; PLAYER* lcp; - int padId; - - padId = ABS(pPed->padId); plane = NULL; - lcp = &player[padId]; + lcp = &player[pPed->padId]; // don't move dead Tanner if (lcp->dying != 0) @@ -2873,7 +2879,6 @@ int ActivatePlayerPedestrian(CAR_DATA* pCar, char* padId, int direction, LONGVEC if (padId == NULL) { playerId = GetPlayerId(pCar); - lp = &player[playerId]; } else { @@ -2883,7 +2888,7 @@ int ActivatePlayerPedestrian(CAR_DATA* pCar, char* padId, int direction, LONGVEC while (pedptr != NULL) { - if (ABS(pedptr->padId) == playerId) + if (pedptr->padId == playerId) { player[playerId].pPed = pedptr; return 0; @@ -2891,10 +2896,10 @@ int ActivatePlayerPedestrian(CAR_DATA* pCar, char* padId, int direction, LONGVEC pedptr = pedptr->pNext; } - - lp = &player[playerId]; } + lp = &player[playerId]; + if (pCar == NULL) { x = (*position)[0]; @@ -2952,10 +2957,7 @@ int ActivatePlayerPedestrian(CAR_DATA* pCar, char* padId, int direction, LONGVEC pedptr->interest = 0; // idle timer pedptr->flags &= ~4; // reverse animation - if (padId == NULL) - pedptr->padId = playerId; - else - pedptr->padId = *padId; + pedptr->padId = playerId; if (pedptr) pos = (VECTOR*)&pedptr->position; @@ -3031,7 +3033,7 @@ int ActivatePlayerPedestrian(CAR_DATA* pCar, char* padId, int direction, LONGVEC else { MakeTheCarShutUp(playerId); - Start3DSoundVolPitch(-1, SOUND_BANK_TANNER, 2, lp->pos[0], lp->pos[1], lp->pos[2], 0, 0x1000); + Start3DSoundVolPitch(-1, SOUND_BANK_TANNER, 2, lp->pos[0], lp->pos[1], lp->pos[2], 0, 4096); SetupGetOutCar(pedptr, pCar, side); //pedptr->padId = 0; @@ -3089,7 +3091,7 @@ void DeActivatePlayerPedestrian(LPPEDESTRIAN pPed) pPed->type = PED_ACTION_GETINCAR; pPed->fpAgitatedState = PedGetInCar; - Start3DSoundVolPitch(-1, SOUND_BANK_TANNER, 2, player[0].pos[0], player[0].pos[1], player[0].pos[2], 0, 0x1000); + Start3DSoundVolPitch(-1, SOUND_BANK_TANNER, 2, player[0].pos[0], player[0].pos[1], player[0].pos[2], 0, 4096); SetupPedestrian(pPed); SetupGetInCar(pPed); } From 320c0e54ed1412dfb14e51ead0e9263127cc9897 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Thu, 4 Aug 2022 17:36:44 -0700 Subject: [PATCH 40/78] [Game:players] Minor code cleanup --- src_rebuild/Game/C/players.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src_rebuild/Game/C/players.c b/src_rebuild/Game/C/players.c index 31b68e3e2..05b050bbd 100644 --- a/src_rebuild/Game/C/players.c +++ b/src_rebuild/Game/C/players.c @@ -247,7 +247,7 @@ void ChangePedPlayerToCar(int playerID, CAR_DATA *newCar) } // play door close sound - Start3DSoundVolPitch(-1, SOUND_BANK_TANNER, 3, newCar->hd.where.t[0], newCar->hd.where.t[1], newCar->hd.where.t[2], 0, 0x1000); + Start3DSoundVolPitch(-1, SOUND_BANK_TANNER, 3, newCar->hd.where.t[0], newCar->hd.where.t[1], newCar->hd.where.t[2], 0, 4096); } // [D] [T] From f878b961df7c39ebf41263037499944ffd031e3d Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Thu, 4 Aug 2022 17:38:16 -0700 Subject: [PATCH 41/78] [Game:tile] Draw models unlit if no dynamic lights are available --- src_rebuild/Game/C/tile.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src_rebuild/Game/C/tile.c b/src_rebuild/Game/C/tile.c index 6f370923e..afab27c84 100644 --- a/src_rebuild/Game/C/tile.c +++ b/src_rebuild/Game/C/tile.c @@ -15,6 +15,12 @@ #ifdef DYNAMIC_LIGHTING void Tile1x1Lit(MODEL* model) { + if (gNumDlights == 0) + { + Tile1x1(model); + return; + } + int opz, Z; int ofse; PL_POLYFT4* polys; @@ -492,6 +498,12 @@ void drawMesh(MVERTEX(*VSP)[5][5], int m, int n, _pct *pc) #ifdef DYNAMIC_LIGHTING void drawMeshLit(MVERTEX(*VSP)[5][5], int m, int n, _pct* pc) { + if (gNumDlights == 0) + { + drawMesh(VSP, m, n, pc); + return; + } + POLY_GT4* prim; int z, opz; From 399cdba77f10d6e23b4618b9217f51746a1cae5e Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Thu, 4 Aug 2022 17:39:07 -0700 Subject: [PATCH 42/78] [Game:wheelforces] Minor code cleanup and refactoring --- src_rebuild/Game/C/wheelforces.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src_rebuild/Game/C/wheelforces.c b/src_rebuild/Game/C/wheelforces.c index f6abdb75e..337f3053f 100644 --- a/src_rebuild/Game/C/wheelforces.c +++ b/src_rebuild/Game/C/wheelforces.c @@ -412,7 +412,7 @@ void AddWheelForcesDriver1(CAR_DATA* cp, CAR_LOCALS* cl) if (slidevel < -12500) slidevel = -12500; } - + if ((i & 1U) != 0) { // rear wheels @@ -437,12 +437,12 @@ void AddWheelForcesDriver1(CAR_DATA* cp, CAR_LOCALS* cl) else { // front wheels - sidevel = frontFS * slidevel + 2048 >> 12; + sidevel = FIXEDH(frontFS * slidevel); if (wheel->locked) { - sidevel = (frontFS * slidevel + 2048 >> 13) + sidevel >> 1; - + sidevel = (sidevel >> 1) + sidevel >> 1; + forcefac = FixHalfRound(FIXEDH(-sidevel * lfx) * sdz - FIXEDH(-sidevel * lfz) * sdx, 11); force.vx = forcefac * sdz; @@ -462,8 +462,8 @@ void AddWheelForcesDriver1(CAR_DATA* cp, CAR_LOCALS* cl) } - force.vx += (susForce * surfaceNormal[0] - sidevel * lfx) - cl->vel[0] * 12; - force.vz += (susForce * surfaceNormal[2] - sidevel * lfz) - cl->vel[2] * 12; + force.vx += (susForce * surfaceNormal[0] - sidevel * lfx) + cl->vel[0] * -12; + force.vz += (susForce * surfaceNormal[2] - sidevel * lfz) + cl->vel[2] * -12; // apply speed reduction by water if ((wheel->surface & 7) == 1) @@ -489,7 +489,7 @@ void AddWheelForcesDriver1(CAR_DATA* cp, CAR_LOCALS* cl) if (surfaceNormal[1] < 3276) friction_coef = friction_coef * surfaceNormal[1] * 5 >> 0xe; - force.vy = FIXEDH(susForce * surfaceNormal[1] - cl->vel[1] * 12); + force.vy = FIXEDH(susForce * surfaceNormal[1] + cl->vel[1] * -12); force.vx = FIXEDH(force.vx) * friction_coef >> 0xc; force.vz = FIXEDH(force.vz) * friction_coef >> 0xc; @@ -519,9 +519,9 @@ void AddWheelForcesDriver1(CAR_DATA* cp, CAR_LOCALS* cl) if (cp->hd.wheel[1].susCompression == 0 && cp->hd.wheel[3].susCompression == 0) { if (cp->thrust >= 1) - cp->hd.wheel_speed = 1703936 + 0x4000; + cp->hd.wheel_speed = 0x1A0000 + 0x4000; else if (cp->thrust <= -1) - cp->hd.wheel_speed = -1245184 + 0x4000; + cp->hd.wheel_speed = -0x130000 + 0x4000; else cp->hd.wheel_speed = 0; } From 4a058c94bb8a9cb1d53257d983824932ac6f1e8b Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Thu, 4 Aug 2022 17:40:51 -0700 Subject: [PATCH 43/78] [redriver2_psxpc] Fixed a bug where FreeRoamer debug test cars may have invalid palettes --- src_rebuild/redriver2_psxpc.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src_rebuild/redriver2_psxpc.cpp b/src_rebuild/redriver2_psxpc.cpp index 45ffc7743..ac8b64703 100644 --- a/src_rebuild/redriver2_psxpc.cpp +++ b/src_rebuild/redriver2_psxpc.cpp @@ -207,7 +207,7 @@ void GameDebugKeys(int nKey, char down) static bool already = false; static bool leadReady = false; - static int lastmodel = 1; + static int lastmodel = 4; /* ---- LEAD VALUES ---- @@ -269,18 +269,19 @@ void GameDebugKeys(int nKey, char down) // rare chance of spawning special car model = MissionHeader->residentModels[4]; palette = 0; - lastmodel = model; - break; } else if (tmp & 3) { model = newmodel; palette = CameraCnt % 6; - lastmodel = model; - break; - } + } } } + + if (model > 4) + palette = 0; + + lastmodel = model; } // add a little more room From 0538d277f15101f3872be24f34fe096c984229f8 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Thu, 4 Aug 2022 17:41:36 -0700 Subject: [PATCH 44/78] Add missing MAX_PED_COLLISIONS define --- src_rebuild/Game/dr2limits.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src_rebuild/Game/dr2limits.h b/src_rebuild/Game/dr2limits.h index b59723dfb..caf632a46 100644 --- a/src_rebuild/Game/dr2limits.h +++ b/src_rebuild/Game/dr2limits.h @@ -32,6 +32,7 @@ #define MAX_PLACED_PEDS 15 #endif +#define MAX_PED_COLLISIONS 8 #define MAX_EXPLOSION_OBJECTS 5 #define MAX_THROWN_BOMBS 5 #define MAX_MOTION_CAPTURE 24 From 04cdce56f10d74f5ab262ac8d0eb54e6bbbddf11 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Thu, 4 Aug 2022 17:43:33 -0700 Subject: [PATCH 45/78] [Game:cars] Draw cars unlit if no dynamic lights are available --- src_rebuild/Game/C/cars.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src_rebuild/Game/C/cars.c b/src_rebuild/Game/C/cars.c index 28d60e129..7b9870a68 100644 --- a/src_rebuild/Game/C/cars.c +++ b/src_rebuild/Game/C/cars.c @@ -276,6 +276,12 @@ void plotCarPolyGT3(int numTris, CAR_POLY *src, SVECTOR *vlist, SVECTOR *nlist, #ifdef DYNAMIC_LIGHTING void plotCarPolyGT3Lit(int numTris, CAR_POLY* src, SVECTOR* vlist, SVECTOR* nlist, plotCarGlobals* pg, int palette) { + if (gNumDlights == 0) + { + plotCarPolyGT3(numTris, src, vlist, nlist, pg, palette); + return; + } + int Z; int otz; SVECTOR* v2; From 80439d45e3e6881eb39b8a3663d82e7ceee64084 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Thu, 4 Aug 2022 17:45:17 -0700 Subject: [PATCH 46/78] [Game:cars] Make use of gte_NormalColorCol macro --- src_rebuild/Game/C/cars.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src_rebuild/Game/C/cars.c b/src_rebuild/Game/C/cars.c index 7b9870a68..13c000f76 100644 --- a/src_rebuild/Game/C/cars.c +++ b/src_rebuild/Game/C/cars.c @@ -898,10 +898,7 @@ void plotNewCarModel(CAR_MODEL* car, int palette) setupLightingMatrices(); - gte_ldv0(&v); - gte_ldrgb(&lightlevel); - - gte_nccs(); + gte_NormalColorCol(&v, &lightlevel, &underIntensity); _pg.primptr = (u_char*)current->primptr; _pg.intensity = 0; @@ -910,8 +907,6 @@ void plotNewCarModel(CAR_MODEL* car, int palette) _pg.ot = (OTTYPE*)(current->ot + 28); - gte_strgb(&underIntensity); - // draw wheel arcs plotCarPolyB3(car->numB3, car->pB3, car->vlist, &_pg); _pg.intensity = underIntensity & 0xffffff; From ddf78dde23c3e773119fd08c00365721af5cbe51 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 5 Aug 2022 05:23:13 -0700 Subject: [PATCH 47/78] Added support for more profile/mission data overrides. - Added SYSTEM_CONFIG struct that is initialized upon startup - Refactored FEMain since it was getting quite big - Moved some types out of FEMain and into their own file - Added support for custom player car colors in Take a Ride using L1/R1 buttons - Added initial support for profile override data (TODO: Language, FullScreen) - Added Details menu to Options screen - Moved density adjustment options to Details menu - Fixed bugs related to initializing extra data parameters - MISSION_OVERRIDES.AllowParkedTurnedWheels now lets wheels be turned on fully damaged cars - Some other various code cleanup and refactoring --- src_rebuild/Game/C/draw.c | 80 ++- src_rebuild/Game/C/draw.h | 2 + src_rebuild/Game/C/glaunch.c | 68 +- src_rebuild/Game/C/handling.c | 17 +- src_rebuild/Game/C/main.c | 4 +- src_rebuild/Game/C/mission.c | 31 +- src_rebuild/Game/C/mission.h | 1 + src_rebuild/Game/C/pedest.c | 5 +- src_rebuild/Game/C/system.c | 3 + src_rebuild/Game/C/system.h | 35 + src_rebuild/Game/Frontend/FEmain.c | 995 ++++++++++++++++++++-------- src_rebuild/Game/Frontend/FEtypes.h | 65 ++ src_rebuild/Game/dr2types.h | 17 +- src_rebuild/redriver2_psxpc.cpp | 50 +- 14 files changed, 1046 insertions(+), 327 deletions(-) create mode 100644 src_rebuild/Game/Frontend/FEtypes.h diff --git a/src_rebuild/Game/C/draw.c b/src_rebuild/Game/C/draw.c index e746b064d..3e2530eb0 100644 --- a/src_rebuild/Game/C/draw.c +++ b/src_rebuild/Game/C/draw.c @@ -327,25 +327,34 @@ void SetupPlaneColours(u_int ambient) { u_int r, g, b; - if (gWeather == 0 && (M_BIT(gTimeOfDay) & (M_BIT(TIME_DAWN) | M_BIT(TIME_DUSK))) == 0) + if (gWeather != WEATHER_NONE || (M_BIT(gTimeOfDay) & (M_BIT(TIME_DAWN) | M_BIT(TIME_DUSK))) != 0) + { + plotContext.planeColours[0] = ambient; + plotContext.planeColours[1] = ambient + 0x10101; + plotContext.planeColours[2] = ambient + 0x30303; + plotContext.planeColours[3] = ambient + 0x80808; + plotContext.planeColours[4] = ambient + 0xa0a0a; + plotContext.planeColours[5] = ambient + 0x80808; + plotContext.planeColours[6] = ambient + 0x30303; + plotContext.planeColours[7] = ambient + 0x10101; + } + else if (gTimeOfDay == TIME_DAY) + { + b = ambient & 255; + g = ambient >> 8 & 255; + r = ambient >> 16 & 255; + + plotContext.planeColours[0] = M_INT_RGB(r, g, b); + plotContext.planeColours[1] = M_INT_RGB(r * 120 >> 7, g * 120 >> 7, b * 120 >> 7); + plotContext.planeColours[2] = M_INT_RGB(r * 103 >> 7, g * 103 >> 7, b * 103 >> 7); + plotContext.planeColours[3] = M_INT_RGB(r * 13 >> 5, g * 13 >> 5, b * 13 >> 5); + plotContext.planeColours[4] = M_INT_RGB(r * 3 >> 3, g * 3 >> 3, b * 3 >> 3); + plotContext.planeColours[5] = plotContext.planeColours[3]; + plotContext.planeColours[6] = plotContext.planeColours[2]; + plotContext.planeColours[7] = plotContext.planeColours[1]; + } + else { - if (gTimeOfDay == TIME_DAY) - { - b = ambient & 255; - g = ambient >> 8 & 255; - r = ambient >> 16 & 255; - - plotContext.planeColours[1] = (r * 120 >> 7) << 16 | (g * 120 >> 7) << 8 | b * 120 >> 7; - plotContext.planeColours[2] = (r * 103 >> 7) << 16 | (g * 103 >> 7) << 8 | b * 103 >> 7; - plotContext.planeColours[3] = (r * 13 >> 5) << 16 | (g * 13 >> 5) << 8 | b * 13 >> 5; - plotContext.planeColours[0] = r << 16 | g << 8 | b; - plotContext.planeColours[4] = (r * 3 >> 3) << 16 | (g * 3 >> 3) << 8 | b * 3 >> 3; - plotContext.planeColours[5] = plotContext.planeColours[3]; - plotContext.planeColours[6] = plotContext.planeColours[2]; - plotContext.planeColours[7] = plotContext.planeColours[1]; - return; - } - plotContext.planeColours[0] = ambient; plotContext.planeColours[1] = ambient; plotContext.planeColours[2] = ambient; @@ -354,17 +363,34 @@ void SetupPlaneColours(u_int ambient) plotContext.planeColours[5] = ambient; plotContext.planeColours[6] = ambient; plotContext.planeColours[7] = ambient; - return; } +} - plotContext.planeColours[0] = ambient; - plotContext.planeColours[1] = ambient + 0x10101; - plotContext.planeColours[2] = ambient + 0x30303; - plotContext.planeColours[3] = ambient + 0x80808; - plotContext.planeColours[4] = ambient + 0xa0a0a; - plotContext.planeColours[5] = ambient + 0x80808; - plotContext.planeColours[6] = ambient + 0x30303; - plotContext.planeColours[7] = ambient + 0x10101; +void SetDrawDistance(int level) +{ + switch (level) + { + case 1: + gDrawDistance = 441; + syscfg.gDrawDistanceLevel = 0; + break; + case 2: + gDrawDistance = 600; + syscfg.gDrawDistanceLevel = 1; + break; + case 3: + gDrawDistance = 1200; + syscfg.gDrawDistanceLevel = 2; + break; + case 4: + gDrawDistance = 1800; + syscfg.gDrawDistanceLevel = 3; + break; + case 5: + gDrawDistance = syscfg.gDrawDistance; + syscfg.gDrawDistanceLevel = 4; + break; + } } diff --git a/src_rebuild/Game/C/draw.h b/src_rebuild/Game/C/draw.h index 50443433a..c129d3e44 100644 --- a/src_rebuild/Game/C/draw.h +++ b/src_rebuild/Game/C/draw.h @@ -95,6 +95,8 @@ extern int combointensity; extern int gForceLowDetailCars; extern int num_cars_drawn; +extern void SetDrawDistance(int level); + extern int PositionVisible(VECTOR* pos); // 0x0005D560 extern void DrawMapPSX(int *comp_val); // 0x0003F6B0 diff --git a/src_rebuild/Game/C/glaunch.c b/src_rebuild/Game/C/glaunch.c index 419e3a78b..c6fad9469 100644 --- a/src_rebuild/Game/C/glaunch.c +++ b/src_rebuild/Game/C/glaunch.c @@ -192,6 +192,14 @@ void StoreGameVars(int replay) } } +int GetOptionOrDefault(int option_value, int default_value) +{ + if (option_value < 1) + return default_value; + + return option_value - 1; +} + void LoadExtraData(EXTRA_CONFIG_DATA *extraData, int profile) { if (extraData->magic == EXTRA_DATA_MAGIC) @@ -206,16 +214,44 @@ void LoadExtraData(EXTRA_CONFIG_DATA *extraData, int profile) { if (gExtraConfig.sdType == 1) { - // TODO: load profile overrides - } + extern void SetDrawDistance(int level); + extern int gEnableDlights; + extern int gUserLanguage; - // clear the data since we're done with it - memset((u_char*)&gExtraConfig.data, 0, sizeof(gExtraConfig.data)); - } + gUserLanguage = GetOptionOrDefault(gExtraConfig.p.Language, syscfg.gUserLanguage); + + // NB: not implemented yet + int fullScreen = GetOptionOrDefault(gExtraConfig.p.FullScreen, syscfg.fullScreen); + + int pgxpMode = GetOptionOrDefault(gExtraConfig.p.PGXPMode, syscfg.psyx_cfg_pgxpMode); + + g_cfg_pgxpZBuffer = (pgxpMode & 2); + g_cfg_pgxpTextureCorrection = (pgxpMode & 1); + g_cfg_swapInterval = GetOptionOrDefault(gExtraConfig.p.VSync, syscfg.vsync); + g_cfg_bilinearFiltering = GetOptionOrDefault(gExtraConfig.p.Bilinear, syscfg.psyx_cfg_bilinearFiltering); + + int drawDistance = GetOptionOrDefault(gExtraConfig.p.DrawDistance, syscfg.gDrawDistanceLevelBackup); - // initialize extra data for missions - gExtraConfig.sdType = 2; - gExtraConfig.m.AllowParkedTurnedWheels = 1; + SetDrawDistance(drawDistance); + + gEnableDlights = GetOptionOrDefault(gExtraConfig.p.DynamicLights, syscfg.gEnableDlights); + } + else + { + // init profile configuration + gExtraConfig.sdType = 1; + gExtraConfig.gTrafficDensity = syscfg.gTrafficDensity + 1; + gExtraConfig.gPedestrianDensity = syscfg.gPedestrianDensity + 1; + + gExtraConfig.p.Language = syscfg.gUserLanguage + 1; + gExtraConfig.p.FullScreen = syscfg.fullScreen + 1; + gExtraConfig.p.VSync = syscfg.vsync + 1; + gExtraConfig.p.Bilinear = syscfg.psyx_cfg_bilinearFiltering + 1; + gExtraConfig.p.PGXPMode = syscfg.psyx_cfg_pgxpMode + 1; + gExtraConfig.p.DrawDistance = syscfg.gDrawDistanceLevel + 1; + gExtraConfig.p.DynamicLights = syscfg.gEnableDlights + 1; + } + } } else if (gHaveExtraData) { @@ -231,6 +267,9 @@ void LoadExtraData(EXTRA_CONFIG_DATA *extraData, int profile) { gSavedCars[i] = header->SavedData.CarPos[gExtraConfig.m.SavedSlot[i]]; + header->wantedCar[i] = gSavedCars[i].model; + wantedColour[i] = gSavedCars[i].palette; + gExtraConfig.m.SavedPos[i] = &gSavedCars[i]; } else @@ -332,6 +371,9 @@ int GetSavedCar(STREAM_SOURCE *player, int slot) player->position.vx = gExtraConfig.m.SavedPos[slot]->vx; player->position.vz = gExtraConfig.m.SavedPos[slot]->vz; + wantedCar[slot] = player->model; + wantedColour[slot] = player->palette; + return 1; } @@ -419,6 +461,13 @@ void State_GameStart(void* param) StoreGameVars(0); + // clear the data since we're done with it + memset((u_char*)&gExtraConfig.data, 0, sizeof(gExtraConfig.data)); + + // initialize extra data for missions + gExtraConfig.sdType = 2; + gExtraConfig.m.AllowParkedTurnedWheels = 1; + switch (GameType) { case GAME_MISSION: @@ -572,6 +621,9 @@ void ReInitFrontend(int returnToMain) wantedCar[1] = -1; wantedCar[0] = -1; + wantedColour[1] = -1; + wantedColour[0] = -1; + wantedWeather = -1; wantedTimeOfDay = -1; diff --git a/src_rebuild/Game/C/handling.c b/src_rebuild/Game/C/handling.c index 496e953ad..019589ae9 100644 --- a/src_rebuild/Game/C/handling.c +++ b/src_rebuild/Game/C/handling.c @@ -1224,17 +1224,28 @@ void ProcessCarPad(CAR_DATA* cp, u_int pad, char PadSteer, char use_analogue) } } + int noPlayerInput = gStopPadReads != 0 || gCantDrive != 0; + // Lock car if it has mission lock or fully damaged - if (gStopPadReads != 0 || MaxPlayerDamage[*cp->ai.padid] <= cp->totalDamage || gCantDrive != 0) + if (noPlayerInput || cp->totalDamage >= MaxPlayerDamage[*cp->ai.padid]) { + u_int oldpad = pad; + pad = CAR_PAD_HANDBRAKE; // apply brakes if (cp->hd.wheel_speed > 36864) pad = CAR_PAD_BRAKE; - int_steer = 0; - use_analogue = 1; + if (noPlayerInput) + { + int_steer = 0; + use_analogue = 1; + } + else if (gExtraConfig.m.AllowParkedTurnedWheels) + { + pad |= (oldpad & (CAR_PAD_LEFT | CAR_PAD_RIGHT | CAR_PAD_FASTSTEER)); + } } // turn of horning diff --git a/src_rebuild/Game/C/main.c b/src_rebuild/Game/C/main.c index ade9b4124..0a576b575 100644 --- a/src_rebuild/Game/C/main.c +++ b/src_rebuild/Game/C/main.c @@ -2467,7 +2467,7 @@ void InitGameVariables(void) // ... // ... - SetSavedCar(PlayerStartInfo[0], 0); + SetSavedCar(0, PlayerStartInfo[0]); } else #endif @@ -2500,7 +2500,7 @@ void InitGameVariables(void) // ... // ... - SetSavedCar(PlayerStartInfo[1], 1); + SetSavedCar(1, PlayerStartInfo[1]); } else #endif diff --git a/src_rebuild/Game/C/mission.c b/src_rebuild/Game/C/mission.c index 4979b1b27..9d302f7fc 100644 --- a/src_rebuild/Game/C/mission.c +++ b/src_rebuild/Game/C/mission.c @@ -38,7 +38,7 @@ char* MissionName[37] = { - // Chicago + // Chicago (0 - 7) M_LTXT_ID(MTXT_Surveillancetipoff), M_LTXT_ID(MTXT_Chasethewitness), M_LTXT_ID(MTXT_Trainpursuit), @@ -48,7 +48,7 @@ char* MissionName[37] = M_LTXT_ID(MTXT_Cainescompound), M_LTXT_ID(MTXT_LeavingChicago), - // Havana + // Havana (8 - 17) M_LTXT_ID(MTXT_Followupthelead), M_LTXT_ID(MTXT_Hijackthetruck), M_LTXT_ID(MTXT_Stopthetruck), @@ -60,7 +60,7 @@ char* MissionName[37] = M_LTXT_ID(MTXT_PursueJericho), M_LTXT_ID(MTXT_EscapetheBrazilians), - // Vegas + // Vegas (18 - 27) M_LTXT_ID(MTXT_Casinogetaway), M_LTXT_ID(MTXT_Beatthetrain), M_LTXT_ID(MTXT_Carbomb), @@ -72,7 +72,7 @@ char* MissionName[37] = M_LTXT_ID(MTXT_C4deal), M_LTXT_ID(MTXT_Destroytheyard), - // Rio + // Rio (28 - 36) M_LTXT_ID(MTXT_Buscrash), M_LTXT_ID(MTXT_Stealthecopcar), M_LTXT_ID(MTXT_Cainescash), @@ -158,6 +158,7 @@ int gDontPingInCops = 0; int gBatterPlayer = 1; int wantedCar[2] = { -1, -1 }; +int wantedColour[2] = { -1, -1 }; // [A] int wantedTimeOfDay = -1; @@ -382,6 +383,12 @@ void SetupResidentModels() // force palette if (singlePal) PlayerStartInfo[i]->palette = 0; + else + PlayerStartInfo[i]->palette = wantedColour[i]; + + // store for replay if necessary + if (gExtraConfig.m.SavedPos[i] == NULL) + SetSavedCar(i, PlayerStartInfo[i]); } } } @@ -505,13 +512,7 @@ void LoadMission(int missionnum) // [A] override start position if available, otherwise store it for the replay if (gExtraConfig.mfStartPos) - { GetSavedCar(PlayerStartInfo[0], 0); - } - else - { - SetSavedCar(0, PlayerStartInfo[0]); - } } if (MissionHeader->maxDamage != 0) @@ -2806,16 +2807,10 @@ void PreProcessTargets(void) PlayerStartInfo[1]->model = target->s.car.model; PlayerStartInfo[1]->palette = target->s.car.palette; - // [A] override start position if available, otherwise store it for the replay + // [A] override start position if available if (gExtraConfig.mfStartPos) - { GetSavedCar(PlayerStartInfo[1], 1); - } - else - { - SetSavedCar(1, PlayerStartInfo[1]); - } - + PlayerStartInfo[1]->controlType = CONTROL_TYPE_PLAYER; PlayerStartInfo[1]->flags = 0; diff --git a/src_rebuild/Game/C/mission.h b/src_rebuild/Game/C/mission.h index 419ed3348..4df5e7ab7 100644 --- a/src_rebuild/Game/C/mission.h +++ b/src_rebuild/Game/C/mission.h @@ -60,6 +60,7 @@ extern STOPCOPS gStopCops; extern MR_MISSION Mission; extern int wantedCar[2]; +extern int wantedColour[2]; extern int wantedTimeOfDay; extern int wantedWeather; extern int wantedStartPos; diff --git a/src_rebuild/Game/C/pedest.c b/src_rebuild/Game/C/pedest.c index 47b5e89d9..6e45cde3a 100644 --- a/src_rebuild/Game/C/pedest.c +++ b/src_rebuild/Game/C/pedest.c @@ -723,7 +723,7 @@ void AnimatePed(LPPEDESTRIAN pPed) pPed->frame1 = 0; } - if (pPed->pedType != CIVILIAN && pPed->padId != -1 && pPed->type < PED_ACTION_BACK) + if (pPed->pedType != CIVILIAN && pPed->type < PED_ACTION_BACK) { int surfId; surfId = PedSurfaceType(&vec); @@ -3072,9 +3072,6 @@ void DeActivatePlayerPedestrian(LPPEDESTRIAN pPed) getIn = 0; playerId = pPed->padId; - if (playerId < 0) - playerId = -playerId; - cp = FindClosestCar(player[playerId].pos[0], player[playerId].pos[1], player[playerId].pos[2], &distToCarSq); if (!cp) diff --git a/src_rebuild/Game/C/system.c b/src_rebuild/Game/C/system.c index 2067311f6..3fb23ae4a 100644 --- a/src_rebuild/Game/C/system.c +++ b/src_rebuild/Game/C/system.c @@ -40,6 +40,9 @@ _repl_org | 0x1FABBC | 0x3444 | probably inside mallocTab #else +// initialized elsewhere +SYSTEM_CONFIG syscfg; + // Initialized in redriver2_main volatile char* _frontend_buffer = NULL; // 0xFB400 volatile char* _other_buffer = NULL; // 0xF3000 diff --git a/src_rebuild/Game/C/system.h b/src_rebuild/Game/C/system.h index 890f71ed1..43df125c7 100644 --- a/src_rebuild/Game/C/system.h +++ b/src_rebuild/Game/C/system.h @@ -1,6 +1,41 @@ #ifndef SYSTEM_H #define SYSTEM_H +#ifndef PSX +struct SYSTEM_CONFIG +{ + int windowWidth; + int windowHeight; + int screenWidth; + int screenHeight; + int fullScreen; + int vsync; + + int psyx_cfg_pad1device; + int psyx_cfg_pad2device; + int psyx_cfg_swapInterval; + int psyx_cfg_pgxpMode; + int psyx_cfg_bilinearFiltering; + + int gUserLanguage; + int gDrawDistance; + int gDrawDistanceLevel; + int gDrawDistanceLevelBackup; + int gEnableDlights; + int gDisableChicagoBridges; + int gCameraDefaultScrZ; + int gDriver1Music; + int gWidescreenOverlayAlign; + int gFastLoadingScreens; + int gContentOverride; + + int gTrafficDensity; + int gPedestrianDensity; +}; + +extern SYSTEM_CONFIG syscfg; +#endif + struct DRAW_MODE { short x1, y1; diff --git a/src_rebuild/Game/Frontend/FEmain.c b/src_rebuild/Game/Frontend/FEmain.c index 87c46e9e6..526418d37 100644 --- a/src_rebuild/Game/Frontend/FEmain.c +++ b/src_rebuild/Game/Frontend/FEmain.c @@ -22,44 +22,9 @@ #include "C/spool.h" #include "C/state.h" +#include "FEtypes.h" -struct PSXBUTTON -{ - short x, y, w, h; - u_char l, r; // left, right next item id - u_char u, d; // up, down next item id - int userDrawFunctionNum; - short s_x, s_y; - int action, var; - char Name[32]; -}; - -#ifdef PSX -typedef struct PSXBUTTON FE_BUTTON; -#else -struct FE_BUTTON -{ - short x, y, w, h; - u_char l, r; // left, right next item id - u_char u, d; // up, down next item id - u_char cR, cG, cB, justify; - short s_x, s_y, s_w, s_h; - short action, var; - char Name[32]; -}; - -static_assert(sizeof(FE_BUTTON) == sizeof(PSXBUTTON), "SIZE INVALID"); -#endif - -typedef struct PSXSCREEN -{ - u_char index; - u_char numButtons; - u_char userFunctionNum; - FE_BUTTON buttons[8]; -} FE_SCREEN; - -// #define USE_EMBEDDED_FRONTEND_SCREENS +#define FE_OTSIZE 16 enum FEScreenType { @@ -104,72 +69,39 @@ enum FEScreenType Sc_MPVegasMode = 37, Sc_MPRioMode = 38, + _Sc_DefaultsLast = Sc_MPRioMode, + // New entries Sc_ReplayTheater, Sc_MiniCarsOnOff, - Sc_ChangeDensity, - - Sc_MAX_COUNT = 42, -}; - -enum FEButtonAction -{ - BTN_NEXT_SCREEN = 1, - BTN_START_GAME = 2, - BTN_DISABLED = 3, - BTN_PREVIOUS_SCREEN = 4, - BTN_HIDDEN = 5 -}; + Sc_AdjustDensity, -enum FEButtonVariable -{ - VAR_NONE = -1, +#ifndef PSX + Sc_DetailOptions, + Sc_FullScreenOnOff, // NB: implement if/when Psy-X can reload the renderer + Sc_VSyncOnOff, + Sc_BilinearOnOff, + Sc_PGXPSettings, + Sc_DrawDistance, + Sc_DynamicLightsOnOff, +#endif - // Defaults - do not edit - VAR_GAME_LEVEL = 1, - VAR_GAME_TYPE = 2, - VAR_MULTIPLAYER = 3, - VAR_TIMEOFDAY = 4, - VAR_MISSION_NUMBER = 5, - VAR_LOAD_GAME = 6, - VAR_SAVE_GAME = 7, - VAR_SUB_GAME = 8, - VAR_SUBTITLES = 9, - VAR_INVINCIBILITY = 10, - VAR_IMMUNITY = 11, - VAR_MINIGAME = 12, - VAR_DEMO_CHASE = 13, + // Total number of screens + _Sc_NumScreens, // default = 42 - // New entries - VAR_BONUS_GALLERY, - VAR_MINI_CARS, - VAR_DENSITY_TYPE, + // Helpers + _Sc_NumDefaultScreens = _Sc_DefaultsLast + 1, + _Sc_NumCustomScreens = _Sc_NumScreens - _Sc_NumDefaultScreens, }; -#define FE_MAKEVAR(code, value) ((code & 0xffff) << 8 | (value & 0xff)) +// #define USE_EMBEDDED_FRONTEND_SCREENS #ifdef USE_EMBEDDED_FRONTEND_SCREENS #include "FEscreens.inc" #else -FE_SCREEN PsxScreens[Sc_MAX_COUNT]; +FE_SCREEN PsxScreens[_Sc_NumScreens]; #endif -#define FE_OTSIZE 16 - -struct FE_CHARDATA -{ - u_char u; - u_char v; - u_char w; - u_char h; -}; - -struct FE_FONT -{ - int NumFonts; - FE_CHARDATA CharInfo[256]; -}; - struct SCREEN_LIMITS { short minx, miny, maxx, maxy; @@ -183,8 +115,6 @@ struct BOTCH char* NullStr = "\0"; -typedef int(*screenFunc)(int bSetup); - extern ACTIVE_CHEATS AvailableCheats; extern ACTIVE_CHEATS ActiveCheats; @@ -212,10 +142,10 @@ int UserReplaySelectScreen(int bSetup); int TimeOfDaySelectScreen(int bSetup); int DemoScreen(int bSetup); int MiniCarsOnOffScreen(int bSetup); -int AdjustDensityScreen(int bSetup); +#ifndef PSX +int ChooseOptionScreen(int bSetup); -#define FN_OK 0 -#define FN_DONE 1 +#endif screenFunc fpUserFunctions[] = { @@ -246,9 +176,14 @@ screenFunc fpUserFunctions[] = { TimeOfDaySelectScreen, DemoScreen, MiniCarsOnOffScreen, - AdjustDensityScreen, + ChooseOptionScreen, }; +#define FE_CALLBACK(userFunctionNum) (fpUserFunctions[userFunctionNum - 1]) + +#define FE_INIT_SCREEN(screen) FE_CALLBACK(screen->userFunctionNum)(1) +#define FE_STEP_SCREEN(screen) FE_CALLBACK(screen->userFunctionNum)(0) + // NB: Any changes to 'fpUserFunctions' must be reflected here enum FEUserFunction { @@ -281,16 +216,45 @@ enum FEUserFunction Fn_TimeOfDaySelectScreen, Fn_DemoScreen, Fn_MiniCarsOnOffScreen, - Fn_AdjustDensityScreen, + Fn_ChooseOptionScreen, Fn_End = 128, }; -#define FE_CALLBACK(userFunctionNum) (fpUserFunctions[userFunctionNum - 1]) +enum FEButtonAction +{ + BTN_NEXT_SCREEN = 1, + BTN_START_GAME = 2, + BTN_DISABLED = 3, + BTN_PREVIOUS_SCREEN = 4, + BTN_HIDDEN = 5 +}; -#define FE_INIT_SCREEN(screen) FE_CALLBACK(screen->userFunctionNum)(1) -#define FE_STEP_SCREEN(screen) FE_CALLBACK(screen->userFunctionNum)(0) +enum FEButtonVariable +{ + VAR_NONE = FE_NULLVAR, + // Defaults - do not edit + VAR_GAME_LEVEL = 1, + VAR_GAME_TYPE = 2, + VAR_MULTIPLAYER = 3, + VAR_TIMEOFDAY = 4, + VAR_MISSION_NUMBER = 5, + VAR_LOAD_GAME = 6, + VAR_SAVE_GAME = 7, + VAR_SUB_GAME = 8, + VAR_SUBTITLES = 9, + VAR_INVINCIBILITY = 10, + VAR_IMMUNITY = 11, + VAR_MINIGAME = 12, + VAR_DEMO_CHASE = 13, + + // New entries + VAR_BONUS_GALLERY, + VAR_MINI_CARS, + VAR_CHOOSE_TYPE, + VAR_CHOOSE_VALUE, +}; char* gfxNames[4] = { "DATA\\CARS\\CCARS.RAW", @@ -482,6 +446,7 @@ int minmaxSelections[4][2] = { }; BOTCH botch[38] = { + // Chicago { 1, &MissionName[0]}, { 2, &MissionName[1]}, { 3, &MissionName[2]}, @@ -490,6 +455,7 @@ BOTCH botch[38] = { { 6, &MissionName[5]}, { 7, &MissionName[6]}, { 9, &MissionName[7]}, + // Havana { 10, &MissionName[8]}, { 11, &MissionName[9]}, { 13, &MissionName[10]}, @@ -500,6 +466,7 @@ BOTCH botch[38] = { { 18, &MissionName[15]}, { 19, &MissionName[16]}, { 20, &MissionName[17]}, + // Vegas { 21, &MissionName[18]}, { 22, &MissionName[19]}, { 23, &MissionName[20]}, @@ -510,6 +477,7 @@ BOTCH botch[38] = { { 28, &MissionName[25]}, { 29, &MissionName[26]}, { 30, &MissionName[27]}, + // Rio { 31, &MissionName[28]}, { 32, &MissionName[29]}, { 33, &MissionName[30]}, @@ -564,14 +532,26 @@ int bQuitToSystem = 0; int bQuitToSystemSel = 0; int carSelection = 0; +int carColour = 0; int currSelIndex = 0; int lastCutCity = -1; int lastCity = -1; int currMission = -1; int missionSetup = 0; -int density_type; -u_char *density_value; +#ifndef PSX +#define S_INT(v) (( +#define S_INT_U8(v) ((((v) << 24) >> 24) & 0xff) + +int choose_type; +int choose_mode; +int choose_count; +int choose_error; +int *choose_custom; +int *choose_default; +char **choose_items; +u_char *choose_value; +#endif char* ScreenNames[12] = { 0 }; @@ -598,7 +578,8 @@ RECT16 extraRect = { 896, 256, 64, 219 }; SPRT extraSprt; POLY_FT3 extraDummy; -int BuildButtonsVertical(int count, int xStart, int yStart); +int BuildButtonsVertical(FE_SCREEN *screen, int count, int xStart, int yStart); +void InitChooserScreen(FE_SCREEN *screen); int FEStringWidth(char* string); int FEPrintStringSized(char* string, int x, int y, int scale, int transparent, int r, int g, int b); @@ -609,7 +590,7 @@ void NewSelection(short dir); void EndFrame(void); // [D] [T] -void SetVariable(int var) +void SetVariable(int var, int &action) { int code = (var >> 8); int value = (var & 0xff); @@ -716,32 +697,190 @@ void SetVariable(int var) break; #if ENABLE_BONUS_CONTENT case VAR_BONUS_GALLERY: // [A] - { ShowBonusGallery(); LoadFrontendScreens(0); - } + break; case VAR_MINI_CARS: // [A] mini cars cheat - { ActiveCheats.cheat13 = value; - } + break; #endif - case VAR_DENSITY_TYPE: // [A] density type - { - density_type = value; +#ifndef PSX + case VAR_CHOOSE_TYPE: // [A] chooser type + { + static char* ChooseQualityItems[] = { + "Low", + "Medium", + "High", + "Ultra", + NULL, + }; + + static char* ChoosePGXPItems[] = { + "Disabled", + "Textures only", + "ZBuffer only", + "Enabled", + NULL, + }; + + choose_type = value; + choose_default = NULL; + choose_custom = NULL; + choose_items = NULL; + choose_value = NULL; + choose_mode = -1; + choose_error = 0; + switch (value) { case 0: - density_value = &gExtraConfig.gTrafficDensity; + choose_default = &syscfg.gTrafficDensity; + choose_value = &gExtraConfig.gTrafficDensity; + choose_items = ChooseQualityItems; + choose_mode = 1; break; case 1: - density_value = &gExtraConfig.gPedestrianDensity; + choose_default = &syscfg.gPedestrianDensity; + choose_value = &gExtraConfig.gPedestrianDensity; + choose_items = ChooseQualityItems; + choose_mode = 1; + break; + case 2: + choose_custom = &syscfg.gDrawDistance; + choose_default = &syscfg.gDrawDistanceLevelBackup; + choose_value = &gExtraConfig.p.DrawDistance; + choose_items = ChooseQualityItems; + choose_mode = 1; + break; + case 3: + choose_default = &syscfg.psyx_cfg_pgxpMode; + choose_value = &gExtraConfig.p.PGXPMode; + choose_items = ChoosePGXPItems; + choose_mode = 1; + break; + case 4: + // TODO + choose_default = &syscfg.fullScreen; + choose_value = &gExtraConfig.p.FullScreen; + choose_mode = 0; + break; + case 5: + choose_default = &syscfg.vsync; + choose_value = &gExtraConfig.p.VSync; + choose_mode = 0; + break; + case 6: + choose_default = &syscfg.psyx_cfg_bilinearFiltering; + choose_value = &gExtraConfig.p.Bilinear; + choose_mode = 0; + break; + case 7: + choose_default = &syscfg.gEnableDlights; + choose_value = &gExtraConfig.p.DynamicLights; + choose_mode = 0; break; default: - density_value = NULL; - density_type = -1; + choose_type = -1; break; } + + choose_count = 0; + + if (choose_mode == 1) + { + while (choose_items[choose_count] != 0) + choose_count++; + } + + break; } + case VAR_CHOOSE_VALUE: + if (choose_value) + { + if (value > choose_count) + { + value = -1; + + if (choose_mode == 0) + { + if (choose_default == NULL) + { + printError("HEY!\n"); + return; + } + + value = *choose_default; + } + else if (choose_custom == NULL) + { + if (choose_default != NULL) + value = *choose_default; + } + + if (value == -1) + { + int var = pCurrScreen->buttons[choose_count - 1].var; + + int code = (var >> 8); + + value = (var & 0xff); + + if (code != VAR_CHOOSE_VALUE) + { + action = 0; + + FESound(1); + choose_error = 1; + } + } + + choose_error = 0; + } + + if (choose_error) + return; + + *choose_value = value + 1; + + switch (choose_type) + { + case 2: + extern void SetDrawDistance(int level); + + value = *choose_value; + + SetDrawDistance(value); + break; + case 3: + extern int g_cfg_pgxpTextureCorrection; + extern int g_cfg_pgxpZBuffer; + + // Disabled/None (0), TextureCorrection (1), ZBuffer (2), Enabled/Both (3) + g_cfg_pgxpTextureCorrection = (value & 1); + g_cfg_pgxpZBuffer = (value & 2); + + break; + case 4: + // TODO: Psy-X reinitialize in fullscreen! + break; + case 5: + extern int g_cfg_swapInterval; + g_cfg_swapInterval = value; + break; + case 6: + extern int g_cfg_bilinearFiltering; + g_cfg_bilinearFiltering = value; + break; + case 7: + extern int gEnableDlights; + gEnableDlights = value; + break; + } + } + + choose_error = 0; + break; +#endif } } @@ -895,6 +1034,43 @@ void DisplayOnScreenText(void) FEPrintString(GET_GAME_TXT(TimeOfDayNames[wantedTimeOfDay]), 596, 208, 4, 128, 128, 128); FEPrintString(GET_GAME_TXT(WeatherNames[wantedWeather]), 596, 246, 4, 128, 128, 128); } + + if (iScreenSelect == SCREEN_CAR) + { + FE_BUTTON *btn = &PsxScreens[Sc_CarSelect].buttons[3]; + + extern CVECTOR debris_colour[4][31]; + + int car_model = carNumLookup[GameLevel][carSelection]; + int car_colour = 0; + + if (car_model == 0) + car_colour = 1; + else if(car_model < 8) + car_colour = (car_model-1) * 6 + carColour + 7; + else + car_colour = car_model - 6; + + CVECTOR *col = &debris_colour[GameLevel][car_colour]; + + FEPrintString("Color", btn->x + 190, btn->y + 270, 4, 128, 128, 128); + + POLY_F4 *f4 = (POLY_F4*)current->primptr; + current->primptr += sizeof(POLY_F4); + + setPolyF4(f4); + setXYWH(f4, btn->x + 200, btn->y + 277, 24, 24); + setRGB0(f4, col->r, col->g, col->b); + + addPrim(current->ot + 1, f4); + } + +#ifndef PSX + if (choose_error) + { + FEPrintStringSized("Invalid selection - please select a new option", 140, 200, 0xc00, 0, 128, 0, 0); + } +#endif } } @@ -1211,6 +1387,245 @@ void LoadBackgroundFile(char* name) bRedrawFrontend = 1; } +FE_BUTTON * InsertButtonVertical(FE_SCREEN *screen, int index, char *text) +{ + if (index < 0 || index >= 8) + return NULL; + + int numButtons = screen->numButtons; + int lastButton = numButtons - 1; + int height = 0; + + if (numButtons + 1 > 8) + return NULL; + + if (index < numButtons) + { + height = screen->buttons[index].y - screen->buttons[index - 1].y; + + for (int i = lastButton; i >= index; i--) + { + FE_BUTTON& oldBtn = screen->buttons[i]; + FE_BUTTON& newBtn = screen->buttons[i + 1]; + + newBtn = oldBtn; + + if (newBtn.u != 0) + { + newBtn.u++; + } + + if (newBtn.d != 0) + { + if (newBtn.d > 1) + newBtn.d++; + } + + newBtn.y += height; + newBtn.s_y += height; + } + } + else + { + if (numButtons > 1) + { + height = screen->buttons[lastButton].y - screen->buttons[lastButton - 1].y; + } + else + { + height = screen->buttons[lastButton].y + 38; + } + + height *= 1 + (index - numButtons); + + FE_BUTTON& oldBtn = screen->buttons[lastButton]; + FE_BUTTON& newBtn = screen->buttons[index]; + + newBtn = oldBtn; + + oldBtn.d = index + 1; + newBtn.u = index; + + newBtn.y += height; + newBtn.s_y += height; + + newBtn.action = 0; + newBtn.var = VAR_NONE; + } + + if (text != NULL) + strcpy(screen->buttons[index].Name, text); + else + screen->buttons[index].Name[0] = '\0'; + + screen->buttons[screen->numButtons++].d = 1; + screen->buttons[0].u = screen->numButtons; + + return &screen->buttons[index]; +} + +void InitChooserScreen(FE_SCREEN *screen) +{ + *screen = PsxScreens[Sc_SubtitlesOnOff]; + screen->userFunctionNum = Fn_ChooseOptionScreen; + + // NB: assumes 'On' / 'Off' buttons in that order! + for (int i = 0; i < screen->numButtons; i++) + { + FE_BUTTON& btn = screen->buttons[i]; + + btn.action = FE_MAKEVAR(BTN_PREVIOUS_SCREEN, 0); + btn.var = FE_MAKEVAR(VAR_CHOOSE_VALUE, i ^ 1); + } +} + +void InitDetailsScreen(FE_SCREEN *screen) +{ + static int ButtonScreenMap[] = { + Sc_FullScreenOnOff, + Sc_VSyncOnOff, + Sc_PGXPSettings, + Sc_BilinearOnOff, + Sc_DrawDistance, + Sc_DynamicLightsOnOff, + Sc_AdjustDensity, + Sc_AdjustDensity, + }; + + static char ButtonTypeMap[] = { + -4, 5, 3, 6, 2, 7, 0, 1 + }; + + static char *ButtonNames[] = { + "FullScreen", + "VSync", + "PGXP", + "Texture Filter", + "Draw Distance", + "Dynamic Lights", + "Traffic Density", + "Peds Density", + }; + + int numButtons = BuildButtonsVertical(screen, 8, 156, 190); + + for (int i = 0; i < numButtons; i++) + { + FE_BUTTON& btn = screen->buttons[i]; + + int type = ButtonTypeMap[i]; + char *name = ButtonNames[i]; + + int index = ButtonScreenMap[i]; + + strcpy(btn.Name, name); + + if (type < 0) + { + type = -type; + btn.action = FE_MAKEVAR(BTN_DISABLED, 0); + } + else + { + btn.action = FE_MAKEVAR(BTN_NEXT_SCREEN, index); + } + + btn.var = FE_MAKEVAR(VAR_CHOOSE_TYPE, type); + } +} + +void InitCustomScreens() +{ + // Time of day extended screen + PsxScreens[Sc_TimeOfDay].userFunctionNum = Fn_TimeOfDaySelectScreen; + + // for web demo content (or empty SCRS.BIN) + if (PsxScreens[Sc_Main].userFunctionNum == Fn_End) + PsxScreens[Sc_Main].userFunctionNum = Fn_DemoScreen; + +#ifndef PSX + // replay theater + PsxScreens[Sc_Replays].buttons[0].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_ReplayTheater); + PsxScreens[Sc_Replays].buttons[0].var = VAR_NONE; + PsxScreens[Sc_ReplayTheater].userFunctionNum = Fn_UserReplaySelectScreen; + + InitChooserScreen(&PsxScreens[Sc_FullScreenOnOff]); + InitChooserScreen(&PsxScreens[Sc_VSyncOnOff]); + InitChooserScreen(&PsxScreens[Sc_BilinearOnOff]); + InitChooserScreen(&PsxScreens[Sc_PGXPSettings]); + InitChooserScreen(&PsxScreens[Sc_DrawDistance]); + InitChooserScreen(&PsxScreens[Sc_DynamicLightsOnOff]); + InitChooserScreen(&PsxScreens[Sc_AdjustDensity]); + + InitDetailsScreen(&PsxScreens[Sc_DetailOptions]); + + // insert link in Options + InsertButtonVertical(&PsxScreens[Sc_Options], 2, "Details"); + + FE_BUTTON &btn = PsxScreens[Sc_Options].buttons[2]; + + btn.action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_DetailOptions); + btn.var = VAR_NONE; + + //{ + // // + // // add to end of Gameplay menu + // // + // + // FE_SCREEN *gameplaySc = &PsxScreens[Sc_GameplayOptions]; + // FE_BUTTON *btn = &gameplaySc->buttons[gameplaySc->numButtons - 1]; + // + // int lastButton = gameplaySc->numButtons; + // + // static char *density_names[] = { + // "Traffic Density", + // "Peds Density", + // }; + // + // for (int i = 0; i < 2; i++) + // { + // if (i == 0) + // btn->d = lastButton + 1; + // else + // btn[i].d = lastButton + 1; + // + // // copy the button + // btn[i + 1] = *btn; + // + // btn[i + 1].u = lastButton; + // btn[i + 1].d = 1; + // + // btn[i + 1].l = 0; + // btn[i + 1].r = 0; + // + // btn[i + 1].s_x = btn->s_x; + // btn[i + 1].s_y = btn->s_y + (i + 1) * 38; + // + // btn[i + 1].x = btn->x; + // btn[i + 1].y = btn->y + (i + 1) * 38; + // + // btn[i + 1].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_AdjustDensity); + // btn[i + 1].var = FE_MAKEVAR(VAR_CHOOSE_TYPE, i); + // + // strcpy(btn[i + 1].Name, density_names[i]); + // + // lastButton = ++gameplaySc->numButtons; + // } + // + // gameplaySc->buttons[0].u = lastButton; + // gameplaySc->buttons[lastButton - 1].d = 1; + //} +#endif // PSX + +#if ENABLE_BONUS_CONTENT + // make mini cars cheat screen + PsxScreens[Sc_MiniCarsOnOff] = PsxScreens[Sc_ImmunityOnOff]; + PsxScreens[Sc_MiniCarsOnOff].userFunctionNum = Fn_MiniCarsOnOffScreen; + PsxScreens[Sc_MiniCarsOnOff].buttons[0].var = FE_MAKEVAR(VAR_MINI_CARS, 1); + PsxScreens[Sc_MiniCarsOnOff].buttons[1].var = FE_MAKEVAR(VAR_MINI_CARS, 0); +#endif +} + // [D] [T] void LoadFrontendScreens(int full) { @@ -1274,84 +1689,11 @@ void LoadFrontendScreens(int full) #endif } } - - // [A] SCREEN HACKS - - // Time of day extended screen - PsxScreens[Sc_TimeOfDay].userFunctionNum = Fn_TimeOfDaySelectScreen; - - // for web demo content (or empty SCRS.BIN) - if (PsxScreens[Sc_Main].userFunctionNum == Fn_End) - PsxScreens[Sc_Main].userFunctionNum = Fn_DemoScreen; - -#ifndef PSX - // replay theater - PsxScreens[Sc_Replays].buttons[0].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_ReplayTheater); - PsxScreens[Sc_Replays].buttons[0].var = VAR_NONE; - PsxScreens[Sc_ReplayTheater].userFunctionNum = Fn_UserReplaySelectScreen; - - // traffic/pedestrian density menu, copy the Cop Difficulty screen - PsxScreens[Sc_ChangeDensity] = PsxScreens[Sc_CopDifficulty]; - PsxScreens[Sc_ChangeDensity].userFunctionNum = Fn_AdjustDensityScreen; - { - // - // add to end of Gameplay menu - // - - FE_SCREEN *gameplaySc = &PsxScreens[Sc_GameplayOptions]; - FE_BUTTON *btn = &gameplaySc->buttons[gameplaySc->numButtons - 1]; - - int lastButton = gameplaySc->numButtons; - - static char *density_names[] = { - "Traffic Density", - "Peds Density", - }; - - for (int i = 0; i < 2; i++) - { - if (i == 0) - btn->d = lastButton + 1; - else - btn[i].d = lastButton + 1; - - // copy the button - btn[i + 1] = *btn; - - btn[i + 1].u = lastButton; - btn[i + 1].d = 1; - - btn[i + 1].l = 0; - btn[i + 1].r = 0; - - btn[i + 1].s_x = btn->s_x; - btn[i + 1].s_y = btn->s_y + (i + 1) * 38; - - btn[i + 1].x = btn->x; - btn[i + 1].y = btn->y + (i + 1) * 38; - - btn[i + 1].action = FE_MAKEVAR(BTN_NEXT_SCREEN, Sc_ChangeDensity); - btn[i + 1].var = FE_MAKEVAR(VAR_DENSITY_TYPE, i); - - strcpy(btn[i + 1].Name, density_names[i]); - - lastButton = ++gameplaySc->numButtons; - } - - gameplaySc->buttons[0].u = lastButton; - gameplaySc->buttons[lastButton - 1].d = 1; - } -#endif // PSX - -#if ENABLE_BONUS_CONTENT - // make mini cars cheat screen - PsxScreens[Sc_MiniCarsOnOff] = PsxScreens[Sc_ImmunityOnOff]; - PsxScreens[Sc_MiniCarsOnOff].userFunctionNum = Fn_MiniCarsOnOffScreen; - PsxScreens[Sc_MiniCarsOnOff].buttons[0].var = FE_MAKEVAR(VAR_MINI_CARS, 1); - PsxScreens[Sc_MiniCarsOnOff].buttons[1].var = FE_MAKEVAR(VAR_MINI_CARS, 0); -#endif } -#endif +#endif // !USE_EMBEDDED_FRONTEND_SCREENS + + // [A] SCREEN HACKS + InitCustomScreens(); rect.w = 64; rect.h = 256; @@ -1573,7 +1915,7 @@ int HandleKeyPress(void) FESound(2); if (pCurrButton->var != VAR_NONE) - SetVariable(pCurrButton->var); + SetVariable(pCurrButton->var, action); switch (action) { @@ -1585,6 +1927,11 @@ int HandleKeyPress(void) pNewScreen = &PsxScreens[pCurrButton->action & 0xFF]; +#ifndef PSX + if (pNewScreen->userFunctionNum == Fn_ChooseOptionScreen) + InitChooserScreen(pNewScreen); +#endif + if (ScreenDepth < 10) ScreenDepth++; @@ -2216,6 +2563,7 @@ int CentreScreen(int bSetup) return FN_OK; } +u_char defaultCarColours[] = { 5, 0, 0, 1 }; // [D] [T] int CarSelectScreen(int bSetup) @@ -2296,6 +2644,8 @@ int CarSelectScreen(int bSetup) } } + carColour = defaultCarColours[GameLevel]; // special player color + //feVariableSave[0] = -1; //feVariableSave[1] = -1; //feVariableSave[2] = -1; @@ -2340,42 +2690,18 @@ int CarSelectScreen(int bSetup) else if (feNewPad & MPAD_CROSS) { - if (currSelIndex == 0) - { - // find best-fit for previous vehicle - do - { - newSel--; - if (newSel < 0) - newSel = 9; - - } while (CarAvailability[GameLevel][newSel] == 0); - - carSelection = newSel; - } - else if (currSelIndex == 2) - { - // find best-fit for next vehicle - do - { - newSel++; - if (newSel > 9) - newSel = 0; - - } while (CarAvailability[GameLevel][newSel] == 0); - - carSelection = newSel; - } - else + if (currSelIndex == 1) { // select the vehicle if (currPlayer == 1) { feVariableSave[2] = carSelection; wantedCar[0] = carNumLookup[GameLevel][carSelection]; + wantedColour[0] = carColour; } else { wantedCar[1] = carNumLookup[GameLevel][carSelection]; + wantedColour[1] = carColour; } // time for player 2 to select their vehicle? @@ -2384,6 +2710,39 @@ int CarSelectScreen(int bSetup) return FN_OK; } + else + { + if (currSelIndex == 0) + { + // find best-fit for previous vehicle + do + { + if (--newSel < 0) + newSel = 9; + + } while (CarAvailability[GameLevel][newSel] == 0); + } + else if (currSelIndex == 2) + { + // find best-fit for next vehicle + do + { + if (++newSel > 9) + newSel = 0; + + } while (CarAvailability[GameLevel][newSel] == 0); + } + + if (newSel != carSelection) + { + carSelection = newSel; + + if (carSelection < 4) + carColour = 0; // cop cars / specials don't have multiple colors + else + carColour = defaultCarColours[GameLevel]; + } + } rect = extraRect; LoadImage(&rect, (u_long *)(_frontend_buffer + carSelection * 0x8000)); @@ -2406,6 +2765,29 @@ int CarSelectScreen(int bSetup) { currSelIndex = pCurrButton->d - 1; } + else if (carSelection < 4) + { + if (feNewPad & MPAD_L1) + { + if (--carColour < 0) + carColour = 5; + FESound(3); + } + else if (feNewPad & MPAD_R1) + { + if (++carColour > 5) + carColour = 0; + FESound(3); + } + } + else + { + if (feNewPad & (MPAD_L1 | MPAD_R1)) + { + // can't change colors + FESound(1); + } + } return FN_OK; } @@ -3869,7 +4251,7 @@ int CheatNumlayerSelect(int bSetup) return FN_OK; } -int BuildButtonsVertical(int count, int xStart, int yStart) +int BuildButtonsVertical(FE_SCREEN *screen, int count, int xStart, int yStart) { int numButtons = count; @@ -3887,7 +4269,7 @@ int BuildButtonsVertical(int count, int xStart, int yStart) if (nextButton >= numButtons) nextButton -= numButtons; - FE_BUTTON& btn = pCurrScreen->buttons[i]; + FE_BUTTON& btn = screen->buttons[i]; // copy button 0 btn = PsxScreens[Sc_Replays].buttons[0]; @@ -3911,7 +4293,7 @@ int BuildButtonsVertical(int count, int xStart, int yStart) sprintf(btn.Name, "Button %d", i + 1); } - pCurrScreen->numButtons = numButtons; + screen->numButtons = numButtons; return numButtons; } @@ -3959,7 +4341,7 @@ int UserReplaySelectScreen(int bSetup) if (gFEReplayCount < 6) yOfs = 208; - int numButtons = BuildButtonsVertical(gFEReplayCount, 160, yOfs); + int numButtons = BuildButtonsVertical(pCurrScreen, gFEReplayCount, 160, yOfs); for (int i = 0; i < numButtons; i++) { @@ -3976,7 +4358,7 @@ int UserReplaySelectScreen(int bSetup) } else { - BuildButtonsVertical(1, 160, 208); + BuildButtonsVertical(pCurrScreen, 1, 160, 208); FE_BUTTON& btn = pCurrScreen->buttons[0]; btn.action = FE_MAKEVAR(BTN_PREVIOUS_SCREEN, 0); @@ -4039,7 +4421,7 @@ int TimeOfDaySelectScreen(int bSetup) wantedWeather = feVariableSave[1]; } - numButtons = BuildButtonsVertical(3, 168, 208); + numButtons = BuildButtonsVertical(pCurrScreen, 3, 168, 208); for (i = 0; i < numButtons; i++) { @@ -4170,52 +4552,149 @@ int DemoScreen(int bSetup) return FN_OK; } -char* DensityItems[] = { - "Low", - "Medium", - "High", - "Ultra", -}; - -int AdjustDensityScreen(int bSetup) +#ifndef PSX +int ChooseOptionScreen(int bSetup) { if (bSetup) { - int numButtons = BuildButtonsVertical(4, 168, 208); + int numButtons = pCurrScreen->numButtons; + int defaultValue = -1; int what = -1; - if (density_value) - what = *density_value - 1; + FE_BUTTON *extraBtn = NULL; + FE_BUTTON *resetBtn = NULL; + + // create buttons + if (choose_mode == 1) + { + // build buttons + numButtons = BuildButtonsVertical(pCurrScreen, choose_count, 161, 245); + + for (int i = 0; i < numButtons; i++) + { + FE_BUTTON& btn = pCurrScreen->buttons[i]; + strcpy(btn.Name, choose_items[i]); + + btn.action = FE_MAKEVAR(BTN_PREVIOUS_SCREEN, 0); + btn.var = FE_MAKEVAR(VAR_CHOOSE_VALUE, i); + + btn.y += (i * 8); + btn.s_y += (i * 8); + } + + if (choose_custom) + { + int value = *choose_custom; + + if (value >= 0) + { + extraBtn = InsertButtonVertical(pCurrScreen, numButtons, "Custom"); + + if (extraBtn != NULL) + { + what = numButtons++; + extraBtn->action = FE_MAKEVAR(BTN_PREVIOUS_SCREEN, 0); + extraBtn->var = FE_MAKEVAR(VAR_CHOOSE_VALUE, what); + choose_count++; + } + } + } + } + else if (choose_mode == 0) + { + choose_count = numButtons; + } + + if (choose_default) + { + defaultValue = *choose_default; + + if (defaultValue >= 0) + { + resetBtn = InsertButtonVertical(pCurrScreen, numButtons, "Reset to Default"); + + if (resetBtn != NULL) + { + resetBtn->cR = 124; + resetBtn->cG = 108; + resetBtn->cB = 40; + + resetBtn->action = FE_MAKEVAR(BTN_PREVIOUS_SCREEN, 0); + resetBtn->var = FE_MAKEVAR(VAR_CHOOSE_VALUE, 255); + + resetBtn->y += 16; + resetBtn->s_y += 16; + numButtons++; + } + } + } + + if (numButtons > 5) + { + for (int i = 0; i < numButtons; i++) + { + FE_BUTTON& btn = pCurrScreen->buttons[i]; + + btn.y -= 32; + btn.s_y -= 32; + } + } + + if (choose_value) + { + int value = *choose_value; + + if (value != 0) + { + what = value - 1; + + if (defaultValue >= 0 && what == defaultValue) + { + if (resetBtn) + resetBtn->action = FE_MAKEVAR(BTN_DISABLED, 0); + } + } + } + + if (choose_mode == 0) + { + if (what > choose_count) + { + // does not exist! + what = choose_count - 1; + choose_error = 1; + } + } + else if (what == -1) + { + if (defaultValue >= 0) + what = defaultValue; + } + + if (what == -1) + what = choose_count - 1; + for (int i = 0; i < numButtons; i++) { - FE_BUTTON& btn = pCurrScreen->buttons[i]; - strcpy(btn.Name, DensityItems[i]); + FE_BUTTON &btn = pCurrScreen->buttons[i]; - btn.action = FE_MAKEVAR(BTN_PREVIOUS_SCREEN, 0); + int code = (btn.var >> 8); + int value = (btn.var & 0xff); + + if (code == VAR_CHOOSE_VALUE && value == what) + { + pCurrButton = &pCurrScreen->buttons[i]; + return FN_DONE; + } } - if (what != -1) - pCurrButton = &pCurrScreen->buttons[what & 3]; - else - pCurrButton = pCurrScreen->buttons; + pCurrButton = &pCurrScreen->buttons[0]; + choose_error = 1; return FN_DONE; } - if (feNewPad & MPAD_CROSS) - { - if (density_value) - *density_value = (currSelIndex & 3) + 1; - } - else if (feNewPad & MPAD_D_UP) - { - currSelIndex = pCurrButton->u - 1; - } - else if (feNewPad & MPAD_D_DOWN) - { - currSelIndex = pCurrButton->d - 1; - } - return FN_OK; -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/src_rebuild/Game/Frontend/FEtypes.h b/src_rebuild/Game/Frontend/FEtypes.h new file mode 100644 index 000000000..9381ad836 --- /dev/null +++ b/src_rebuild/Game/Frontend/FEtypes.h @@ -0,0 +1,65 @@ +#ifndef FETYPES_H +#define FETYPES_H + +// Platform types +#include + +struct FE_CHARDATA +{ + u_char u; + u_char v; + u_char w; + u_char h; +}; + +struct FE_FONT +{ + int NumFonts; + FE_CHARDATA CharInfo[256]; +}; + +struct PSXBUTTON +{ + short x, y, w, h; + u_char l, r; // left, right next item id + u_char u, d; // up, down next item id + int userDrawFunctionNum; + short s_x, s_y; + int action, var; + char Name[32]; +}; + +#ifdef PSX +typedef struct PSXBUTTON FE_BUTTON; +#else +struct FE_BUTTON +{ + short x, y, w, h; + u_char l, r; // left, right next item id + u_char u, d; // up, down next item id + u_char cR, cG, cB, justify; + short s_x, s_y, s_w, s_h; + short action, var; + char Name[32]; +}; + +static_assert(sizeof(FE_BUTTON) == sizeof(PSXBUTTON), "SIZE INVALID"); +#endif + +typedef struct PSXSCREEN +{ + u_char index; + u_char numButtons; + u_char userFunctionNum; + FE_BUTTON buttons[8]; +} FE_SCREEN; + +typedef int(*screenFunc)(int bSetup); + +#define FN_OK 0 +#define FN_DONE 1 + +#define FE_NULLVAR -1 +#define FE_MAKEVAR(code, value) ((code & 0xffff) << 8 | (value & 0xff)) + +#endif \ No newline at end of file diff --git a/src_rebuild/Game/dr2types.h b/src_rebuild/Game/dr2types.h index ec04dfc6a..672e2c830 100644 --- a/src_rebuild/Game/dr2types.h +++ b/src_rebuild/Game/dr2types.h @@ -1076,7 +1076,22 @@ struct MISSION_OVERRIDES struct PROFILE_OVERRIDES { - int reserved[3]; + // NB: not implemented yet + u_char Language; + u_char FullScreen; + //------------------------ + + u_char VSync; + u_char Bilinear; + u_char PGXPMode; + u_char DrawDistance; + u_char DynamicLights; + u_char pad1; + + // NB: not implemented yet + u_short DisplayWidth; + u_short DisplayHeight; + //------------------------ }; struct EXTRA_CONFIG_DATA diff --git a/src_rebuild/redriver2_psxpc.cpp b/src_rebuild/redriver2_psxpc.cpp index ac8b64703..9ec003afa 100644 --- a/src_rebuild/redriver2_psxpc.cpp +++ b/src_rebuild/redriver2_psxpc.cpp @@ -543,9 +543,6 @@ int main(int argc, char** argv) config = ini_load(configFilename); - // best distance - gDrawDistance = 600; - int windowWidth = 800; int windowHeight = 600; int screenWidth = 800; @@ -553,13 +550,14 @@ int main(int argc, char** argv) int fullScreen = 0; int vsync = 0; int enableFreecamera = 0; + int drawDistance = -1; extern int gUserLanguage; + extern int gDisableChicagoBridges; + extern int gContentOverride; if (config) { - extern int gDisableChicagoBridges; - extern int gContentOverride; int newScrZ = gCameraDefaultScrZ; const char* dataFolderStr = ini_get(config, "fs", "dataFolder"); const char* userReplaysStr = ini_get(config, "game", "userChases"); @@ -585,7 +583,7 @@ int main(int argc, char** argv) ini_sget(config, "render", "bilinearFiltering", "%d", &g_cfg_bilinearFiltering); // configure host game - ini_sget(config, "game", "drawDistance", "%d", &gDrawDistance); + ini_sget(config, "game", "drawDistance", "%d", &drawDistance); ini_sget(config, "game", "dynamicLights", "%d", &gEnableDlights); ini_sget(config, "game", "disableChicagoBridges", "%d", &gDisableChicagoBridges); ini_sget(config, "game", "fieldOfView", "%d", &newScrZ); @@ -643,6 +641,46 @@ int main(int argc, char** argv) #endif + syscfg.windowWidth = windowWidth; + syscfg.windowHeight = windowHeight; + syscfg.screenWidth = screenWidth; + syscfg.screenHeight = screenHeight; + syscfg.fullScreen = fullScreen; + syscfg.vsync = g_cfg_swapInterval; + + syscfg.gUserLanguage = gUserLanguage; + syscfg.gEnableDlights = gEnableDlights; + syscfg.gDisableChicagoBridges = gDisableChicagoBridges; + syscfg.gCameraDefaultScrZ = gCameraDefaultScrZ; + syscfg.gDriver1Music = gDriver1Music; + syscfg.gWidescreenOverlayAlign = gWidescreenOverlayAlign; + syscfg.gFastLoadingScreens = gFastLoadingScreens; + syscfg.gContentOverride = gContentOverride; + + if (drawDistance != -1) + { + syscfg.gDrawDistance = drawDistance; + SetDrawDistance(5); + } + else + { + syscfg.gDrawDistance = -1; + + // best distance + SetDrawDistance(2); + } + + syscfg.gDrawDistanceLevelBackup = syscfg.gDrawDistanceLevel; + + syscfg.gTrafficDensity = 1; + syscfg.gPedestrianDensity = 1; + + syscfg.psyx_cfg_pad1device = g_cfg_controllerToSlotMapping[0]; + syscfg.psyx_cfg_pad2device = g_cfg_controllerToSlotMapping[1]; + syscfg.psyx_cfg_swapInterval = g_cfg_swapInterval; + syscfg.psyx_cfg_pgxpMode = ((g_cfg_pgxpZBuffer != 0) << 1) | (g_cfg_pgxpTextureCorrection != 0); + syscfg.psyx_cfg_bilinearFiltering = g_cfg_bilinearFiltering; + PsyX_Initialise("REDRIVER2", fullScreen ? screenWidth : windowWidth, fullScreen ? screenHeight : windowHeight, fullScreen); char version_info[32]; From d60f16971c72409598925fed1be156628c9d7dba Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 5 Aug 2022 05:26:36 -0700 Subject: [PATCH 48/78] Added GetPlayerFelonyData and UpdatePlayerFelonyData functions. --- src_rebuild/Game/C/felony.c | 32 ++++++++++++++++++++++++-------- src_rebuild/Game/C/felony.h | 3 +++ src_rebuild/Game/C/gamesnd.c | 16 ++-------------- src_rebuild/Game/C/handling.c | 8 +------- src_rebuild/Game/C/main.c | 18 ++---------------- src_rebuild/Game/C/overlay.c | 9 +-------- src_rebuild/Game/C/overmap.c | 15 ++------------- 7 files changed, 35 insertions(+), 66 deletions(-) diff --git a/src_rebuild/Game/C/felony.c b/src_rebuild/Game/C/felony.c index 13c388408..30020e75a 100644 --- a/src_rebuild/Game/C/felony.c +++ b/src_rebuild/Game/C/felony.c @@ -68,6 +68,28 @@ void InitFelonyData(FELONY_DATA *pFelonyData) memcpy((u_char*)&pFelonyData->value, (u_char*)&initialFelonyValue, sizeof(initialFelonyValue)); } +// [A] +short * GetPlayerFelonyData() +{ + short *playerFelony; + + if (player[0].playerCarId < 0) + return &pedestrianFelony; + else + return &car_data[player[0].playerCarId].felonyRating; +} + +// [A] +void UpdatePlayerFelonyData() +{ + short *playerFelony = GetPlayerFelonyData(); + + if (gPlayerImmune != 0) + *playerFelony = 0; + + FelonyBar.position = *playerFelony; +} + // [D] [T] int GetCarHeading(int direction) { @@ -97,10 +119,7 @@ void NoteFelony(FELONY_DATA *pFelonyData, char type, short scale) int phrase; int additionalFelonyPoints; - if (player[0].playerCarId < 0) - felony = &pedestrianFelony; - else - felony = &car_data[player[0].playerCarId].felonyRating; + felony = GetPlayerFelonyData(); felonyTooLowForRoadblocks = *felony; @@ -233,10 +252,7 @@ void AdjustFelony(FELONY_DATA *pFelonyData) FELONY_DELAY *pFelonyDelay; short *felony; - if (player[0].playerCarId < 0) - felony = &pedestrianFelony; - else - felony = &car_data[player[0].playerCarId].felonyRating; + felony = GetPlayerFelonyData(); if (*felony != 0 && *felony <= FELONY_PURSUIT_MIN_VALUE) { diff --git a/src_rebuild/Game/C/felony.h b/src_rebuild/Game/C/felony.h index 5dd1c5d86..eff384112 100644 --- a/src_rebuild/Game/C/felony.h +++ b/src_rebuild/Game/C/felony.h @@ -14,6 +14,9 @@ extern FELONY_DATA felonyData; extern void InitFelonySystem(); // 0x0004D280 extern void CheckPlayerMiscFelonies(); // 0x0004CC28 +extern short * GetPlayerFelonyData(); +extern void UpdatePlayerFelonyData(); + extern int GetCarHeading(int direction); // 0x0004D420 extern char GetCarDirectionOfTravel(CAR_DATA *cp); // 0x0004D430 diff --git a/src_rebuild/Game/C/gamesnd.c b/src_rebuild/Game/C/gamesnd.c index cb70ce827..9e13db94a 100644 --- a/src_rebuild/Game/C/gamesnd.c +++ b/src_rebuild/Game/C/gamesnd.c @@ -1000,7 +1000,6 @@ char force_siren[8] = { 0 }; void DoDopplerSFX(void) { int pitch, volume, sample; - short* playerFelony; int i, j; int car; #ifdef PSX @@ -1401,12 +1400,7 @@ void DoDopplerSFX(void) // bark on player if (CopsCanSeePlayer) { - if (player[0].playerCarId < 0) - playerFelony = &pedestrianFelony; - else - playerFelony = &car_data[player[0].playerCarId].felonyRating; - - if (*playerFelony > FELONY_PURSUIT_MIN_VALUE) + if (*GetPlayerFelonyData() > FELONY_PURSUIT_MIN_VALUE) DoPoliceLoudhailer(num_noisy_cars, indexlist, car_dist); } @@ -1639,19 +1633,13 @@ void JerichoSpeak(void) { static u_int j_said = 0; int rnd; - short* playerFelony; rnd = Random2(3); if (CopsCanSeePlayer == 0) return; - if (player[0].playerCarId < 0) - playerFelony = &pedestrianFelony; - else - playerFelony = &car_data[player[0].playerCarId].felonyRating; - - if (*playerFelony > FELONY_PURSUIT_MIN_VALUE && rnd == rnd / 5 * 5) + if (*GetPlayerFelonyData() > FELONY_PURSUIT_MIN_VALUE && rnd == rnd / 5 * 5) { if (j_said > 60) { diff --git a/src_rebuild/Game/C/handling.c b/src_rebuild/Game/C/handling.c index 019589ae9..4c9cc27a8 100644 --- a/src_rebuild/Game/C/handling.c +++ b/src_rebuild/Game/C/handling.c @@ -317,12 +317,6 @@ void GlobalTimeStep(void) int m2; int strength; int carsDentedThisFrame; - short *felony; - - if (player[0].playerCarId < 0) - felony = &pedestrianFelony; - else - felony = &car_data[player[0].playerCarId].felonyRating; StepCars(); CheckCarToCarCollisions(); @@ -543,7 +537,7 @@ void GlobalTimeStep(void) // wake up cops if they've ben touched // [A] check player felony. // If player touch them without felony player will be charged with felony (hit cop car) - if (numCopCars < 4 && numActiveCops < maxCopCars && GameType != GAME_GETAWAY && *felony >= FELONY_PURSUIT_MIN_VALUE) + if (numCopCars < 4 && numActiveCops < maxCopCars && GameType != GAME_GETAWAY && *GetPlayerFelonyData() >= FELONY_PURSUIT_MIN_VALUE) { if (cp->controlType == CONTROL_TYPE_PLAYER && IS_ROADBLOCK_CAR(c1)) { diff --git a/src_rebuild/Game/C/main.c b/src_rebuild/Game/C/main.c index 0a576b575..4778f517e 100644 --- a/src_rebuild/Game/C/main.c +++ b/src_rebuild/Game/C/main.c @@ -840,7 +840,6 @@ void StepSim(void) static char t2; // offset 0x5 char padAcc; - short* playerFelony; int stream; CAR_DATA* cp; PLAYER* pl; @@ -871,13 +870,8 @@ void StepSim(void) lead_pad = (u_int)controller_bits; - if (player[0].playerCarId < 0) - playerFelony = &pedestrianFelony; - else - playerFelony = &car_data[player[0].playerCarId].felonyRating; - // control cop roadblocks - if (*playerFelony <= FELONY_ROADBLOCK_MIN_VALUE || numRoadblockCars != 0) + if (*GetPlayerFelonyData() <= FELONY_ROADBLOCK_MIN_VALUE || numRoadblockCars != 0) { if (roadblockCount != 0) { @@ -2133,15 +2127,7 @@ void UpdatePlayerInformation(void) PlayerDamageBar.max = MaxPlayerDamage[0]; Player2DamageBar.max = MaxPlayerDamage[1]; - if (player[0].playerCarId < 0) - playerFelony = &pedestrianFelony; - else - playerFelony = &car_data[player[0].playerCarId].felonyRating; - - if (gPlayerImmune != 0) - *playerFelony = 0; - - FelonyBar.position = *playerFelony; + UpdatePlayerFelonyData(); for (i = 0; i < NumPlayers; i++) { diff --git a/src_rebuild/Game/C/overlay.c b/src_rebuild/Game/C/overlay.c index ea17f0439..9fca84959 100644 --- a/src_rebuild/Game/C/overlay.c +++ b/src_rebuild/Game/C/overlay.c @@ -673,8 +673,6 @@ void DrawDrivingGameOverlays(void) // [D] [T] void DisplayOverlays(void) { - short* felony; - #ifndef PSX if (gWidescreenOverlayAlign) { @@ -734,12 +732,7 @@ void DisplayOverlays(void) if (CopsCanSeePlayer) { - if (player[0].playerCarId < 0) - felony = &pedestrianFelony; - else - felony = &car_data[player[0].playerCarId].felonyRating; - - if (*felony > FELONY_PURSUIT_MIN_VALUE) + if (*GetPlayerFelonyData() > FELONY_PURSUIT_MIN_VALUE) DrawCopIndicators(); } } diff --git a/src_rebuild/Game/C/overmap.c b/src_rebuild/Game/C/overmap.c index b05d0199b..b406f23ed 100644 --- a/src_rebuild/Game/C/overmap.c +++ b/src_rebuild/Game/C/overmap.c @@ -1074,7 +1074,6 @@ void DrawMultiplayerMap(void) void DrawOverheadMap(void) { u_char tmp; - short *playerFelony; TILE_1 *tile1; POLY_F4 *sptb; POLY_FT4 *spt; @@ -1139,12 +1138,7 @@ void DrawOverheadMap(void) // flash the overhead map if (player_position_known > 0) { - if (player[0].playerCarId < 0) - playerFelony = &pedestrianFelony; - else - playerFelony = &car_data[player[0].playerCarId].felonyRating; - - if (*playerFelony > FELONY_PURSUIT_MIN_VALUE) + if (*GetPlayerFelonyData() > FELONY_PURSUIT_MIN_VALUE) FlashOverheadMap(ptab[CameraCnt & 0xf], 0, ptab[CameraCnt + 8U & 0xf]); } else @@ -1153,12 +1147,7 @@ void DrawOverheadMap(void) { if (flashtimer == 0) { - if (player[0].playerCarId < 0) - playerFelony = &pedestrianFelony; - else - playerFelony = &car_data[player[0].playerCarId].felonyRating; - - if (*playerFelony > FELONY_PURSUIT_MIN_VALUE) + if (*GetPlayerFelonyData() > FELONY_PURSUIT_MIN_VALUE) flashtimer = 48; } } From f83cd213526e0e8b3cea84d603d17b4db2f25397 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 5 Aug 2022 05:27:27 -0700 Subject: [PATCH 49/78] [Game:felony] Minor code cleanup and refactoring --- src_rebuild/Game/C/felony.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src_rebuild/Game/C/felony.c b/src_rebuild/Game/C/felony.c index 30020e75a..d8e4b4018 100644 --- a/src_rebuild/Game/C/felony.c +++ b/src_rebuild/Game/C/felony.c @@ -202,20 +202,17 @@ void NoteFelony(FELONY_DATA *pFelonyData, char type, short scale) case 11: break; case 3: - if ((rnd & 3) != 0) - break; + if ((rnd & 3) == 0) + CopSay(5, 0); - CopSay(5, 0); break; case 4: - if ((rnd % 3) & 0xff != 0) - break; - - CopSay((rnd & 1) + 7, 0); + if ((rnd % 3) == 0) + CopSay((rnd & 1) + 7, 0); break; default: - if ((rnd % 17) & 0xFF == 0) + if ((rnd % 17) == 0) { if (MaxPlayerDamage[0] * 3 / 4 < car_data[player[0].playerCarId].totalDamage) phrase = rnd % 4; @@ -278,7 +275,7 @@ void AdjustFelony(FELONY_DATA *pFelonyData) pFelonyDelay = pFelonyData->reoccurrenceDelay; - while (pFelonyDelay <= &pFelonyData->reoccurrenceDelay[11]) + while (pFelonyDelay < &pFelonyData->reoccurrenceDelay[12]) { if (pFelonyDelay->current != 0) pFelonyDelay->current--; @@ -422,7 +419,7 @@ void CheckPlayerMiscFelonies(void) NoteFelony(&felonyData, 10, 4096); // check the speed limit - if (speedLimits[2] == maxSpeed) + if (maxSpeed == speedLimits[2]) limit = (maxSpeed * 19) >> 4; else limit = (maxSpeed * 3) >> 1; From fb7d70e7e8d7de65c83dd7a13054f3cbc46b8245 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 5 Aug 2022 05:29:28 -0700 Subject: [PATCH 50/78] [Game:draw] Minor code cleanup and refactoring --- src_rebuild/Game/C/draw.c | 89 +++++++++++++-------------------------- 1 file changed, 30 insertions(+), 59 deletions(-) diff --git a/src_rebuild/Game/C/draw.c b/src_rebuild/Game/C/draw.c index 3e2530eb0..58f20f130 100644 --- a/src_rebuild/Game/C/draw.c +++ b/src_rebuild/Game/C/draw.c @@ -159,8 +159,8 @@ void addSubdivSpriteShadow(POLYFT4* src, SVECTOR* verts, int z) copyVector(&subdiVerts.verts[0][3], &verts[src->v2]); subdiVerts.verts[0][3].uv.val = *(ushort*)&src->uv2; - makeMesh((MVERTEX(*)[5][5])subdiVerts.verts, m, m); - drawMesh((MVERTEX(*)[5][5])subdiVerts.verts, m, m, &plotContext); + makeMesh(&subdiVerts.verts, m, m); + drawMesh(&subdiVerts.verts, m, m, &plotContext); plotContext.ot -= 28; } @@ -216,8 +216,8 @@ void DrawSprites(PACKED_CELL_OBJECT** sprites, int numFound) } plotContext.primptr = current->primptr; - plotContext.ptexture_pages = (ushort(*)[128])texture_pages; - plotContext.ptexture_cluts = (ushort(*)[128][32])texture_cluts; + plotContext.ptexture_pages = &texture_pages; + plotContext.ptexture_cluts = &texture_cluts; plotContext.polySizes = PolySizes; plotContext.ot = current->ot; plotContext.colour = spriteColour; @@ -279,8 +279,8 @@ void DrawSprites(PACKED_CELL_OBJECT** sprites, int numFound) copyVector(&subdiVerts.verts[0][3], &verts[src->v2]); subdiVerts.verts[0][3].uv.val = *(ushort*)&src->uv2; - makeMesh((MVERTEX(*)[5][5])subdiVerts.verts, 4, 4); - drawMesh((MVERTEX(*)[5][5])subdiVerts.verts, 4, 4, &plotContext); + makeMesh(&subdiVerts.verts, 4, 4); + drawMesh(&subdiVerts.verts, 4, 4, &plotContext); src++; } @@ -747,8 +747,7 @@ void PlotBuildingModel(MODEL* model, int rot, _pct* pc) r = (rot >> 3) * 4; - i = model->num_polys; - while (i-- > 0) + for (i = model->num_polys; i > 0; i--) { ptype = polys->id & 31; @@ -842,8 +841,7 @@ void PlotBuildingModelSubdivNxN(MODEL* model, int rot, _pct* pc, int n) r = (rot >> 3) * 4; - i = model->num_polys; - while (i-- > 0) + for (i = model->num_polys; i > 0; i--) { // iterate through polygons // with skipping @@ -879,20 +877,10 @@ void PlotBuildingModelSubdivNxN(MODEL* model, int rot, _pct* pc, int n) pc->tpage = (*pc->ptexture_pages)[polys->texture_set]; pc->clut = (*pc->ptexture_cluts)[polys->texture_set][polys->texture_id]; - minZ = pc->scribble[2]; - if (pc->scribble[1] < minZ) - minZ = pc->scribble[1]; - - if (pc->scribble[0] < minZ) - minZ = pc->scribble[0]; - - maxZ = pc->scribble[2]; - if (maxZ < pc->scribble[1]) - maxZ = pc->scribble[1]; - + minZ = MIN(pc->scribble[0], MIN(pc->scribble[1], pc->scribble[2])); + maxZ = MAX(pc->scribble[0], MAX(pc->scribble[1], pc->scribble[2])); + diff = maxZ - minZ; - if (maxZ < pc->scribble[0]) - diff = pc->scribble[0] - minZ; ushort uv0, uv1, uv2, uv3; @@ -913,7 +901,7 @@ void PlotBuildingModelSubdivNxN(MODEL* model, int rot, _pct* pc, int n) uv3 = *(ushort*)&polys->uv3; } - if (n == 0 || diff << 2 <= minZ - 350) + if (n == 0 || minZ - 350 >= (diff << 2)) { prims = (POLY_FT4*)pc->primptr; @@ -1081,8 +1069,7 @@ void PlotModelSubdivNxN(MODEL* model, int rot, _pct* pc, int n) if (pc->flags & PLOT_TRANSPARENT) combo |= 0x2000000; - i = model->num_polys; - while (i > 0) + for (i = model->num_polys; i > 0; i--) { // iterate through polygons // with skipping @@ -1091,7 +1078,6 @@ void PlotModelSubdivNxN(MODEL* model, int rot, _pct* pc, int n) if (ptype != 11 && ptype != 21 && ptype != 23) { polys = (PL_POLYFT4*)((char*)polys + pc->polySizes[ptype]); - i--; continue; } @@ -1134,20 +1120,10 @@ void PlotModelSubdivNxN(MODEL* model, int rot, _pct* pc, int n) if ((pc->flags & PLOT_CUSTOM_PALETTE) == 0) // [A] custom palette flag - for pedestrian heads pc->clut = (*pc->ptexture_cluts)[polys->texture_set][polys->texture_id]; - minZ = pc->scribble[2]; - if (pc->scribble[1] < minZ) - minZ = pc->scribble[1]; - - if (pc->scribble[0] < minZ) - minZ = pc->scribble[0]; - - maxZ = pc->scribble[2]; - if (maxZ < pc->scribble[1]) - maxZ = pc->scribble[1]; + minZ = MIN(pc->scribble[0], MIN(pc->scribble[1], pc->scribble[2])); + maxZ = MAX(pc->scribble[0], MAX(pc->scribble[1], pc->scribble[2])); diff = maxZ - minZ; - if (maxZ < pc->scribble[0]) - diff = pc->scribble[0] - minZ; ushort uv0, uv1, uv2, uv3; @@ -1168,7 +1144,7 @@ void PlotModelSubdivNxN(MODEL* model, int rot, _pct* pc, int n) uv3 = *(ushort*)&polys->uv3; } - if (n == 0 || diff << 2 <= minZ - 350) + if (n == 0 || minZ - 350 >= (diff << 2)) { prims = (POLY_FT4*)pc->primptr; @@ -1201,13 +1177,14 @@ void PlotModelSubdivNxN(MODEL* model, int rot, _pct* pc, int n) } else { - r = n; + int sub; + sub = n; if (n == 1) { if (minZ - 150 < (diff << 1)) - r = 4; + sub = 4; else - r = 2; + sub = 2; } copyVector(&subdiVerts.verts[0][0], &srcVerts[polys->v0]); @@ -1222,13 +1199,12 @@ void PlotModelSubdivNxN(MODEL* model, int rot, _pct* pc, int n) copyVector(&subdiVerts.verts[0][3], &srcVerts[polys->v2]); subdiVerts.verts[0][3].uv.val = uv2; - makeMesh((MVERTEX(*)[5][5])subdiVerts.verts, r, r); - drawMesh((MVERTEX(*)[5][5])subdiVerts.verts, r, r, pc); + makeMesh((MVERTEX(*)[5][5])subdiVerts.verts, sub, sub); + drawMesh((MVERTEX(*)[5][5])subdiVerts.verts, sub, sub, pc); } } polys = (PL_POLYFT4*)((char*)polys + pc->polySizes[ptype]); - i--; } } @@ -1440,15 +1416,11 @@ void DrawMapPSX(int* comp_val) { QuickUnpackCellObject(ppco, &ci.nearCell, &ground_debris[groundDebrisIndex]); - if (groundDebrisIndex < MAX_GROUND_DEBRIS - 1) - groundDebrisIndex++; - else + if (++groundDebrisIndex > MAX_GROUND_DEBRIS - 1) groundDebrisIndex = 0; } - if (treecount < 15) - treecount++; - else + if (++treecount > 15) treecount = 0; } } @@ -1474,15 +1446,11 @@ void DrawMapPSX(int* comp_val) { if (model->flags2 & MODEL_FLAG_ALLEY) { - alleycount++; - - if (alleycount == 13) + if (++alleycount == 13) { QuickUnpackCellObject(ppco, &ci.nearCell, &ground_debris[groundDebrisIndex]); - if (groundDebrisIndex < MAX_GROUND_DEBRIS - 1) - groundDebrisIndex++; - else + if (++groundDebrisIndex > MAX_GROUND_DEBRIS - 1) groundDebrisIndex = 0; alleycount = 0; @@ -1594,7 +1562,7 @@ void AddDlight(VECTOR* position, CVECTOR* color, int radius) { DLIGHT* pLight; VECTOR lightPos; - if (gNumDlights + 1 >= MAX_DLIGHTS) + if (!gEnableDlights || gNumDlights + 1 >= MAX_DLIGHTS) { return; } @@ -1614,6 +1582,9 @@ void GetDLightLevel(SVECTOR* position, u_int* inOutColor) int dx, dy, dz, dist, light; u_int lightR, lightG, lightB; + if (!gEnableDlights || gNumDlights == 0) + return; + lightR = (*inOutColor & 255); lightG = (*inOutColor >> 8 & 255); lightB = (*inOutColor >> 16 & 255); From 850ba2c5fd6c03c150cbdee5c514b4438eac8358 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 5 Aug 2022 05:32:18 -0700 Subject: [PATCH 51/78] [Game:mission] Cleanup and refactor code; improved mission script dumps --- src_rebuild/Game/C/mission.c | 315 ++++++++++++++++++++++++----------- 1 file changed, 216 insertions(+), 99 deletions(-) diff --git a/src_rebuild/Game/C/mission.c b/src_rebuild/Game/C/mission.c index 9d302f7fc..7728edb13 100644 --- a/src_rebuild/Game/C/mission.c +++ b/src_rebuild/Game/C/mission.c @@ -182,7 +182,7 @@ static char NewLeadDelay = 0; MR_MISSION Mission; u_int MissionStack[MAX_MISSION_THREADS][16]; -MR_THREAD MissionThreads[MAX_MISSION_TARGETS]; +MR_THREAD MissionThreads[MAX_MISSION_THREADS]; unsigned char playercollected[2] = { 0, 0 }; @@ -748,9 +748,125 @@ void LoadMission(int missionnum) #if 0 { // MISSION SCRIPT DUMP - u_int* script = MissionScript; + printInfo("== MISSION %d - SCRIPT DUMP ==\n\n", missionnum); + + for (int i = 0; i < MAX_MISSION_TARGETS; i++) + { + MS_TARGET *target = &MissionTargets[i]; + + printInfo("Target %d = ", i); + + switch (target->type) + { + case Target_Point: + printInfo("Point\n"); + break; + case Target_Car: + printInfo("Car\n"); + break; + case Target_Event: + printInfo("Event\n"); + break; + case Target_Player2Start: + printInfo("Player2Start\n"); + break; + case Target_MultiCar: + printInfo("MultiCar\n"); + break; + default: + printInfo("NULL\n"); + continue; + } + + printWarning(" Flags %x\n", target->s.target_flags); + printWarning(" DisplayFlags %x\n", target->s.display_flags); + + switch (target->type) + { + case Target_Point: + printWarning(" Position %d, %d\n", target->s.point.posX, target->s.point.posZ); + printWarning(" Radius %d\n", target->s.point.radius); + printWarning(" YPos %d\n", target->s.point.posY); + printWarning(" Height %d\n", target->s.point.height); + if (target->s.point.loseTailMessage != -1) + printWarning(" LoseTailMessage \"%s\"\n", MissionStrings + target->s.point.loseTailMessage); + printWarning(" ActionFlag %X\n", target->s.point.actionFlag); + if (target->s.target_flags & TARGET_FLAG_POINT_ON_BOAT) + printWarning(" BoatOffset %d, %d\n", target->s.point.boatOffsetX, target->s.point.boatOffsetZ); + break; + case Target_Car: + case Target_Player2Start: + printWarning(" Position %d, %d\n", target->s.car.posX, target->s.car.posZ); + printWarning(" Rotation %d\n", target->s.car.rotation); + printWarning(" Slot %d\n", target->s.car.slot); + printWarning(" Model %d\n", target->s.car.model); + printWarning(" Palette %d\n", target->s.car.palette); + printWarning(" Type %d\n", target->s.car.type); + printWarning(" Flags %d\n", target->s.car.flags); + printWarning(" Cutscene %d\n", target->s.car.cutscene); + printWarning(" MaxDistance %d\n", target->s.car.maxDistance); + switch (target->s.target_flags & 0xf0) + { + case 0: + printWarning(" MaxDamage %d\n", target->s.car.chasing.maxDamage); + printWarning(" TooFarMessage \"%s\"\n", MissionStrings + target->s.car.chasing.tooFarMessage); + printWarning(" GettingFarMessage %d\n", target->s.car.chasing.gettingFarMessage); + break; + case CATTARGET_FLAG_PROXIMITY_TARGET: + printWarning(" CloseMessages %d\n", target->s.car.tail.closeMessages); + printWarning(" FarMessages %d\n", target->s.car.tail.closeMessages); + break; + case CARTARGET_FLAG_STEAL_TARGET: + case CARTARGET_FLAG_ESCAPE_TARGET: + break; + case CARTARGET_FLAG_CnR_TARGET: + printWarning(" MaxDamage %d\n", target->s.car.chasing.maxDamage); + printWarning(" TooFarMessage \"%s\"\n", MissionStrings + target->s.car.chasing.tooFarMessage); + break; + } + break; + case Target_Event: + printWarning(" Id %d\n", target->s.event.eventId); + if (target->s.event.loseMessage != -1) + printWarning(" LoseMessage \"%s\"\n", MissionStrings + target->s.event.loseMessage); + break; + case Target_MultiCar: + for (int j = 0; j < 5; j++) + { + MULTICAR_DATA *mcd = &target->multiCar[j]; + + if (mcd->x == 0x80000000) + break; + + printInfo(" Car %d\n", j); + + printWarning(" Position %d, %d\n", mcd->x, mcd->z); + printWarning(" Rotation %d\n", mcd->rot); + printWarning(" Model %d\n", mcd->model); + printWarning(" Palette %d\n", mcd->palette); + + printInfo(" End\n"); + } + break; + } + + switch (target->type) + { + case Target_Point: + case Target_Car: + case Target_Event: + case Target_Player2Start: + case Target_MultiCar: + for (int j = 0; j < 15; j++) + printInfo(" Field %d = %08X\n", j, target->data[j]); + printInfo("End\n"); + break; + } + } - while (true) + u_int* script = MissionScript; + + while (script < (u_int*)MissionStrings) { u_int* value = script; @@ -777,13 +893,13 @@ void LoadMission(int missionnum) { val1 = *--value; - printWarning("MR command: PlayCutscene(%d)\n", val1); + printWarning("PlayCutscene %d\n", val1); break; } case 0x1000021: // CompleteAllActiveTargets { - printWarning("MR command: CompleteAllActiveTargets\n"); + printWarning("CompleteAllActiveTargets\n"); break; } @@ -795,19 +911,19 @@ void LoadMission(int missionnum) switch (val1) { case 0x2000008: - printWarning("MR command: SetVariable(Timer, %d)\n", val2); + printWarning("SET Timer %d\n", val2); break; case 0x2000100: - printWarning("MR command: SetVariable(gCopDesiredSpeedScale, %d)\n", val2); + printWarning("SET Cops_SpeedScale %d\n", val2); break; case 0x2000101: - printWarning("MR command: SetVariable(gCopMaxPowerScale, %d)\n", val2); + printWarning("SET Cops_PowerScale %d\n", val2); break; case 0x2000102: - printWarning("MR command: SetVariable(gMinimumCops, %d)\n", val2); + printWarning("SET Min_Cops %d\n", val2); break; case 0x2000103: - printWarning("MR command: SetVariable(maxCopCars, %d)\n", val2); + printWarning("SET Max_Cops %d\n", val2); break; } @@ -817,7 +933,7 @@ void LoadMission(int missionnum) { val1 = *--value; - printWarning("MR command: Jump(%d)\n", val1); + printWarning("Jump %d\n", val1); break; } @@ -826,7 +942,7 @@ void LoadMission(int missionnum) val1 = *--value; val2 = *--value; - printWarning("MR command: BranchIf result != 0 TO %d\n", val1, val2); + printWarning("WaitForObjectiveComplete(%d)\n", (script - MissionScript) + val1 + 1); break; } @@ -834,7 +950,7 @@ void LoadMission(int missionnum) { val1 = *--value; - printWarning("MR command: MultiCarEvent(%d)\n", val1); + printWarning("MultiCarEvent %d\n", val1); break; } @@ -842,7 +958,7 @@ void LoadMission(int missionnum) { val1 = *--value; - printWarning("MR command: SetPlayerFelony(%d)\n", val1); + printWarning("ForceFelonyRating %d\n", val1); break; } @@ -851,7 +967,7 @@ void LoadMission(int missionnum) val1 = *--value; val2 = *--value; - printWarning("MR command: ShowPlayerMessage(%d, %d)\n", val1, val2); + printWarning("InformPlayer \"%s\", %d\n", MissionStrings + val1, val2); break; } @@ -859,7 +975,7 @@ void LoadMission(int missionnum) { val1 = *--value; - printWarning("MR command: TriggerEvent(%d)\n", val1); + printWarning("TriggerEvent %d\n", val1); break; } @@ -867,7 +983,7 @@ void LoadMission(int missionnum) { val1 = *--value; - printWarning("MR command: SetDoorsLocked(%d)\n", val1); + printWarning("SetDoorsLocked %d\n", val1); break; } @@ -875,19 +991,19 @@ void LoadMission(int missionnum) { val1 = *--value; - printWarning("MR command: SetStealMessage(%d)\n", val1); + printWarning("SetStealMessage \"%s\"\n", MissionStrings + val1); break; } case 0x1000055: // ShowOutOfTimeMessage { - printWarning("MR command: ShowOutOfTimeMessage\n"); + printWarning("ShowOutOfTimeMessage\n"); break; } case 0x1001000: // StopThread { - printWarning("MR command: StopThread\n"); + printWarning("Return\n"); break; } @@ -895,7 +1011,7 @@ void LoadMission(int missionnum) { val1 = *--value; - printWarning("MR command: StartThreadForPlayer(%d)\n", (value - MissionScript) + val1 + 1); + printWarning("StartThreadForPlayer(%d)\n", (script - MissionScript) + val1 + 1); break; } @@ -903,25 +1019,25 @@ void LoadMission(int missionnum) { val1 = *--value; - printWarning("MR command: StartThread2(%d)\n", (value - MissionScript) + val1 + 1); + printWarning("StartThread2(%d)\n", (script - MissionScript) + val1 + 1); break; } case 0x1000100: // SetCameraEvent { - printWarning("MR command: SetCameraEvent\n"); + printWarning("SetCameraEvent\n"); break; } case 0x1000071: // AwardPlayerCheat { val1 = *--value; - printWarning("MR command: AwardPlayerCheat %d\n", val1); + printWarning("AwardPlayerCheat %d\n", val1); break; } case 0x1000090: // SetRaining { - printWarning("MR command: SetRaining\n"); + printWarning("Raining\n"); break; } case 0x1000040: @@ -941,7 +1057,7 @@ void LoadMission(int missionnum) } case 0x1001001: { - printWarning("MR command: SetMissionComplete\n"); + printWarning("MissionEnd\n"); break; } } @@ -954,6 +1070,8 @@ void LoadMission(int missionnum) char opValue1[32] = { 0 }; char opValue2[32] = { 0 }; + int vars = 0; + val1 = *--value; // MRGetParam @@ -974,18 +1092,20 @@ void LoadMission(int missionnum) sprintf(opValue1, "Timer"); break; case 0x2000100: - sprintf(opValue1, "gCopDesiredSpeedScale"); + sprintf(opValue1, "Cops_SpeedScale"); break; case 0x2000101: - sprintf(opValue1, "gCopMaxPowerScale"); + sprintf(opValue1, "Cops_PowerScale"); break; case 0x2000102: - sprintf(opValue1, "gMinimumCops"); + sprintf(opValue1, "Min_Cops"); break; case 0x2000103: - sprintf(opValue1, "maxCopCars"); + sprintf(opValue1, "Max_Cops"); break; } + + vars++; } default: sprintf(opValue1, "result"); @@ -1011,47 +1131,54 @@ void LoadMission(int missionnum) sprintf(opValue2, "Timer"); break; case 0x2000100: - sprintf(opValue2, "gCopDesiredSpeedScale"); + sprintf(opValue2, "Cops_SpeedScale"); break; case 0x2000101: - sprintf(opValue2, "gCopMaxPowerScale"); + sprintf(opValue2, "Cops_PowerScale"); break; case 0x2000102: - sprintf(opValue2, "gMinimumCops"); + sprintf(opValue2, "Min_Cops"); break; case 0x2000103: - sprintf(opValue2, "maxCopCars"); + sprintf(opValue2, "Max_Cops"); break; } + + vars++; } default: sprintf(opValue2, "result"); } + char opText[64] = { 0 }; + + if (vars != 0) + sprintf(opText, " %s, %s", opValue1, opValue2); + value += 2; switch (*value) { case 0x3000003: // AND - printWarning("MR: operator %s && %s\n", opValue1, opValue2); + printWarning("AndIf%s\n", opText); break; case 0x3000004: // OR - printWarning("MR: operator %s || %s\n", opValue1, opValue2); + printWarning("OrIf%s\n", opText); break; case 0x3000005: // NEQ - printWarning("MR: operator %s != %s\n", opValue1, opValue2); + printWarning("IfNotEqual%s\n", opText); break; case 0x3000006: // EQ - printWarning("MR: operator %s == %s\n", opValue1, opValue2); + printWarning("IfEqual%s\n", opText); break; case 0x3000007: // GT - printWarning("MR: operator %s > %s\n", opValue1, opValue2); + printWarning("IfGreaterThan%s\n", opText); break; case 0x3000008: // LT - printWarning("MR: operator %s < %s\n", opValue1, opValue2); + printWarning("IfLessThan%s\n", opText); break; case 0x3000009: // ADD - printWarning("MR: operator %s + %s\n", opValue1, opValue2); + printWarning("Add%s\n", opText); break; default: printWarning("MR: operator INVALID\n"); @@ -1066,7 +1193,7 @@ void LoadMission(int missionnum) if (*value == 0x4000020) { val1 = *--value; - printWarning("MR: function MRProcessTarget %d\n", val1); + printWarning("ProcessTarget %d\n", val1); } @@ -1110,7 +1237,7 @@ void HandleTimer(MR_TIMER *timer) MissionHeader->timerFlags &= ~MISSIONTIMER_FLAG_BOMB_TIMER; timer->count = 9000; - timer->flags |= 0x28; + timer->flags |= (TIMER_FLAG_BOMB_TRIGGERED | TIMER_FLAG_COMPLETE_ON_OUT); } else { @@ -1153,71 +1280,67 @@ void HandleTimer(MR_TIMER *timer) // [D] [T] void RegisterChaseHit(int car1, int car2) { + if (!Mission.ChaseTarget || Mission.ChaseHitDelay == 0) + return; + int player_id; - if (Mission.ChaseTarget && Mission.ChaseHitDelay == 0) + if (gPlayerWithTheFlag == -1) { - if (gPlayerWithTheFlag == -1) + if (Mission.ChaseTarget->s.car.slot == car1 || Mission.ChaseTarget->s.car.slot == car2) { - if (car1 == Mission.ChaseTarget->s.car.slot || car2 == Mission.ChaseTarget->s.car.slot) - { - Mission.ChaseTarget->s.car.chasing.maxDamage--; - Mission.ChaseHitDelay = 20; - DamageBar.position++; - } - } - else - { - player_id = 1 - gPlayerWithTheFlag; - gPlayerWithTheFlag = player_id; - - player[player_id].targetCarId = -1; + Mission.ChaseTarget->s.car.chasing.maxDamage--; Mission.ChaseHitDelay = 20; - player[1 - player_id].targetCarId = gPlayerWithTheFlag; - - SetPlayerMessage(player_id, G_LTXT(GTXT_YouGotTheFlag),2,1); + DamageBar.position++; } } + else + { + // swap flag between the 2 players + player[gPlayerWithTheFlag].targetCarId = (gPlayerWithTheFlag ^= 1); + player[gPlayerWithTheFlag].targetCarId = -1; + Mission.ChaseHitDelay = 20; + + SetPlayerMessage(gPlayerWithTheFlag, G_LTXT(GTXT_YouGotTheFlag), 2, 1); + } } // [D] [T] void PauseMissionTimer(int pause) { - if (pause == 0) + if (pause != 0) { - Mission.timer[0].flags &= ~TIMER_FLAG_PAUSED; - Mission.timer[1].flags &= ~TIMER_FLAG_PAUSED; + Mission.timer[0].flags |= TIMER_FLAG_PAUSED; + Mission.timer[1].flags |= TIMER_FLAG_PAUSED; } else { - Mission.timer[0].flags |= TIMER_FLAG_PAUSED; - Mission.timer[1].flags |= TIMER_FLAG_PAUSED; + Mission.timer[0].flags &= ~TIMER_FLAG_PAUSED; + Mission.timer[1].flags &= ~TIMER_FLAG_PAUSED; } } // [D] [T] void SetMissionMessage(char *message, int priority, int seconds) { - int i; - if (message == MissionStrings - 1 || message == NULL || NumPlayers == 0) return; - for (i = 0; i < NumPlayers; i++) + for (int i = 0; i < NumPlayers; i++) { if (Mission.message_timer[i] == 0 || Mission.message_priority[i] <= priority) { Mission.message_string[i] = message; Mission.message_priority[i] = priority; - if (seconds == 0) + if (seconds != 0) { - Mission.message_timer[i] = 5; + Mission.message_timer[i] = seconds * 30; } else { - Mission.message_timer[i] = seconds * 30; + Mission.message_timer[i] = 5; } } } @@ -3138,48 +3261,34 @@ void SetMissionOver(PAUSEMODE mode) // [D] [T] void ActivateNextFlag(void) { - int j; - MS_TARGET *target; - int i; - if (last_flag == -1) last_flag = 0; else MissionTargets[last_flag].s.target_flags |= TARGET_FLAG_COMPLETED_ALLP; - j = last_flag; - - for (i = 0; i < MAX_MISSION_TARGETS; i++) + for (int i = 0, j = last_flag + 1; i < MAX_MISSION_TARGETS; i++, j++) { - j++; + j %= MAX_MISSION_TARGETS; - j = j % MAX_MISSION_TARGETS; - - target = &MissionTargets[j]; + MS_TARGET *target = &MissionTargets[j]; if (target->type == Target_Point && (target->s.target_flags & TARGET_FLAG_POINT_CTF_FLAG) == TARGET_FLAG_POINT_CTF_FLAG) + { + target->s.target_flags &= ~TARGET_FLAG_COMPLETED_ALLP; + last_flag = j; break; + } } - - target->s.target_flags &= ~TARGET_FLAG_COMPLETED_ALLP; - last_flag = j; } // [D] [T] int CalcLapTime(int player, int time, int lap) { - int i; - int ptime; - - ptime = 0; + int ptime = 0; - i = 0; - while (i < lap) - { + for (int i = 0; i < lap; i++) ptime += gLapTimes[player][i]; - i++; - } - + return time - ptime; } @@ -3236,15 +3345,23 @@ void HandleMission(void) switch (MissionHeader->type & 0x30) { - case 0x20: - FelonyBar.flags |= 0x2; case 0: - FelonyBar.active = 0x1; + // normal felony bar + FelonyBar.active = 1; break; case 0x10: + // no felony bar FelonyBar.active = 0; + break; + case 0x20: + // felony bar with hidden felony + FelonyBar.active = 1; + FelonyBar.flags |= 0x2; + break; default: + // invalid felony bar type FelonyBar.active = 0; + break; } } From 1a6f6a492dfa76653ca78036270cf2171ba9b59c Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 5 Aug 2022 05:33:44 -0700 Subject: [PATCH 52/78] [Game:pedest] Use PED_ACTION_TIME as the idle animation for a nicer look and feel --- src_rebuild/Game/C/pedest.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src_rebuild/Game/C/pedest.c b/src_rebuild/Game/C/pedest.c index 6e45cde3a..93cc00085 100644 --- a/src_rebuild/Game/C/pedest.c +++ b/src_rebuild/Game/C/pedest.c @@ -758,7 +758,7 @@ void SetupDoNowt(LPPEDESTRIAN pPed) { pPed->speed = 0; pPed->dir.vz = 0; - pPed->type = PED_ACTION_BACK; + pPed->type = PED_ACTION_TIME; SetupPedMotionData(pPed); @@ -946,6 +946,19 @@ void PedDoNothing(LPPEDESTRIAN pPed) if (iAllowWatch != 0) iAllowWatch--; } + else if (pPed->speed == 0) + { + if (pPed->doing_turn != 0) + { + pPed->type = PED_ACTION_BACK; + SetupPedMotionData(pPed); + } + else if (pPed->interest != 0 && pPed->type != PED_ACTION_TIME) + { + pPed->type = PED_ACTION_TIME; + SetupPedMotionData(pPed); + } + } } // [D] [T] @@ -1314,7 +1327,7 @@ void PedPressButton(LPPEDESTRIAN pPed) } else { - pPed->type = PED_ACTION_BACK; + pPed->type = PED_ACTION_TIME; pPed->fpAgitatedState = NULL; pPed->frame1 = 0; @@ -2966,7 +2979,7 @@ int ActivatePlayerPedestrian(CAR_DATA* pCar, char* padId, int direction, LONGVEC if (pCar == NULL) { - pedptr->type = PED_ACTION_BACK; + pedptr->type = PED_ACTION_TIME; pedptr->fpAgitatedState = NULL; pedptr->fpRestState = fpPedPersonalityFunctions[0]; } From 71d27aec7069c24d42a030712fe280d4d7090bdb Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 5 Aug 2022 05:34:54 -0700 Subject: [PATCH 53/78] [Game:pres] Added support for custom text scaling values --- src_rebuild/Game/C/pres.c | 65 ++++++++++++++++++++++++++++++--------- src_rebuild/Game/C/pres.h | 4 +++ 2 files changed, 54 insertions(+), 15 deletions(-) diff --git a/src_rebuild/Game/C/pres.c b/src_rebuild/Game/C/pres.c index d6ce86654..634c88fa6 100644 --- a/src_rebuild/Game/C/pres.c +++ b/src_rebuild/Game/C/pres.c @@ -21,6 +21,9 @@ TextureID gHiresDigitsTexture = 0; stbtt_packedchar gSTBCharData[224]; // ASCII 32..126 is 95 glyphs +int gFontScale = 4096; +int gLastFontScale = 4096; + void InitHiresFonts() { char namebuffer[64]; @@ -137,7 +140,9 @@ void GetHiresBakedQuad(int char_index, float* xpos, float* ypos, stbtt_aligned_q float iph = 1.0f / (float)HIRES_FONT_SIZE_H; const stbtt_packedchar* b = gSTBCharData + char_index; - float scale = 0.45f; + float scaling = gFontScale / 4096.f; + + float scale = 0.45f * scaling; float s_x = b->x1 - b->x0; float s_y = b->y1 - b->y0; @@ -152,7 +157,7 @@ void GetHiresBakedQuad(int char_index, float* xpos, float* ypos, stbtt_aligned_q q->s1 = s_x * 255.0f * ipw; q->t1 = s_y * 255.0f * iph; - q->y0 += 14.0f; + q->y0 += (14.0f * scaling); *xpos += b->xadvance * scale; } @@ -163,11 +168,13 @@ int StrighWidthHires(char* string) float width; width = 0; + int spacing = (24 * gFontScale) / 4096; + while ((chr = *string++) != 0) { if (chr >= 128 && chr <= 138) { - width += 24; + width += spacing; continue; } @@ -199,6 +206,8 @@ int PrintStringHires(char* string, int x, int y) SetHiresFontTexture(showMap); + int spacing = (24 * gFontScale) / 4096; + while ((chr = *string++) != 0) { if (chr >= 128 && chr <= 138) @@ -211,8 +220,8 @@ int PrintStringHires(char* string, int x, int y) if (showMap) SetHiresFontTexture(1); - width += 24; - x += 24; + width += spacing; + x += spacing; continue; } @@ -286,6 +295,8 @@ void PrintStringBoxedHires(char* string, int ix, int iy) x = ix; y = iy; + int spacing = (14 * gFontScale) / 4096; + while (*string) { string = GetNextWord(string, word); @@ -293,7 +304,7 @@ void PrintStringBoxedHires(char* string, int ix, int iy) if (x + StringWidth(word) > 308 && (wordcount != 1 || *string != 0)) { x = ix; - y += 14; + y += spacing; } x = PrintStringHires(word, x, y); @@ -351,6 +362,19 @@ short fontclutid = 0; char AsciiTable[256] = { 0 }; OUT_FONTINFO fontinfo[128]; +void SetTextScale(int scale, int saveLastScale) +{ + if (saveLastScale) + gLastFontScale = gFontScale; + + gFontScale = scale; +} + +void ResetTextScale() +{ + gFontScale = gLastFontScale; +} + // [D] [T] void SetTextColour(u_char Red, u_char Green, u_char Blue) { @@ -373,6 +397,9 @@ int StringWidth(char *pString) int w; w = 0; + + int spacing = (24 * gFontScale) / 4096; + int whitespace = (gFontScale / 1024); while (true) { @@ -381,9 +408,9 @@ int StringWidth(char *pString) break; if (let == 32) - w += 4; + w += whitespace; else if ((let + 128 & 0xff) < 11) - w += 24; + w += spacing; else if (AsciiTable[let] != -1) w += fontinfo[AsciiTable[let]].width; } @@ -560,7 +587,7 @@ int PrintString(char *string, int x, int y) while ((chr = *string++) != 0) { - if (chr == 32) + if (chr == ' ') { width += 4; continue; @@ -645,20 +672,22 @@ short PrintDigit(int x, int y, char *string) while ((chr = *string++) != 0) { - if (chr == 58) + if (chr == ':') index = 11; - else if (chr == 47) + else if (chr == '/') index = 10; else - index = chr - 48 & 0xff; + index = chr - '0' & 0xff; pDigit = &fontDigit[index]; - if (chr == 58) + if (chr == ':') fixedWidth = 8; else fixedWidth = 16; + fixedWidth = (fixedWidth * gFontScale) / 4096; + if (index < 6) { vOff = 0; @@ -670,6 +699,8 @@ short PrintDigit(int x, int y, char *string) h = 31; } + h = (h * gFontScale) / 4096; + setSprt(font); setSemiTrans(font, 1); @@ -768,7 +799,7 @@ void PrintStringBoxed(char *string, int ix, int iy) if (x + StringWidth(word) > 308 && (wordcount != 1 || *string != 0)) { x = ix; - y += 14; + y += ((14 * gFontScale) / 4096); } wpt = word; @@ -779,7 +810,7 @@ void PrintStringBoxed(char *string, int ix, int iy) { if (c == ' ') { - x += 4; + x += (gFontScale / 1024); continue; } @@ -892,9 +923,13 @@ int PrintScaledString(int y, char *string, int scale) height = 31; } + y1 = (height / 2 * scale) / 16; width = (pDigit->width * scale) / 16; + width = (width * gFontScale) / 4096; + height = (height * gFontScale) / 4096; + y0 = y - y1; y1 = y + y1; x1 = x + width; diff --git a/src_rebuild/Game/C/pres.h b/src_rebuild/Game/C/pres.h index 821814c09..81489a7d5 100644 --- a/src_rebuild/Game/C/pres.h +++ b/src_rebuild/Game/C/pres.h @@ -18,6 +18,10 @@ extern void InitButtonTextures(); // 0x00074E54 extern void LoadFont(char *buffer); // 0x00073CC8 +// [A] +extern void SetTextScale(int scale, int saveLastScale); +extern void ResetTextScale(); + extern void SetTextColour(u_char Red, u_char Green, u_char Blue); // 0x00074A10 extern int StringWidth(char *pString); // 0x00074A24 From 87978582c4e161709d3b98c89f31a20ddc634a81 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 5 Aug 2022 05:36:28 -0700 Subject: [PATCH 54/78] Add missing data for new mission script dump code. --- src_rebuild/Game/dr2types.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src_rebuild/Game/dr2types.h b/src_rebuild/Game/dr2types.h index 672e2c830..a54bb735e 100644 --- a/src_rebuild/Game/dr2types.h +++ b/src_rebuild/Game/dr2types.h @@ -770,6 +770,8 @@ typedef struct _TARGET } event; }; } s; + + int data[15]; }; } MS_TARGET; From d19a88b4e015d80d79e1da872d5c23fb54b048dd Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 5 Aug 2022 05:41:29 -0700 Subject: [PATCH 55/78] Added support for custom user mission threads/handlers. --- src_rebuild/Game/C/event.c | 259 +++++++++++++++++++++++++++++++++++ src_rebuild/Game/C/event.h | 2 + src_rebuild/Game/C/mission.c | 101 +++++++++++--- src_rebuild/Game/dr2types.h | 25 +++- 4 files changed, 362 insertions(+), 25 deletions(-) diff --git a/src_rebuild/Game/C/event.c b/src_rebuild/Game/C/event.c index b64bca01f..2fe144167 100644 --- a/src_rebuild/Game/C/event.c +++ b/src_rebuild/Game/C/event.c @@ -22,6 +22,8 @@ #include "dr2roads.h" #include "ASM/rndrasm.h" #include "cutrecorder.h" +#include "overmap.h" +#include "mission.h" struct FixedEvent // same as EVENT but different fields { @@ -4097,4 +4099,261 @@ void MultiCarEvent(MS_TARGET* target) //firstEvent->next = first; // [A] bug fix multiCar.event[multiCar.count - 1].next = first; +} + +extern int MRProcessTarget(MR_THREAD * thread, MS_TARGET * target); + +int user_events_allowed = 0; + +int FindFreeTargets(MS_TARGET **targets, int count, int index) +{ + if (targets == NULL || count == 0 || index >= MAX_MISSION_TARGETS) + return -1; + + int found = 0; + + for (int i = index; i < MAX_MISSION_TARGETS && found < count; i++) + { + MS_TARGET *target = &MissionTargets[i]; + + if (target->type == 0) + targets[found++] = target; + } + + return found; +} + +int EmptyMissionEvents(MR_THREAD *thread, int init) +{ + return 0; +} + +int ChicagoTAREvents(MR_THREAD *thread, int init) +{ + if (init) + { + printInfo("**** CHICAGO TAR EVENT SETUP\n"); + + if (gCurrentMissionNumber == 50 || gCurrentMissionNumber == 51) + return 1; + } + + return 0; +} + +int HavanaTAREvents(MR_THREAD *thread, int init) +{ + static MS_TARGET *safehouse_targets[4]; + static int targets; + static int cars_to_spawn; + static int door_state; + + if (init) + { + printInfo("**** HAVANA TAR EVENT SETUP\n"); + + safehouse_targets[0] = NULL; + safehouse_targets[1] = NULL; + targets = 0; + cars_to_spawn = 0; + door_state = 0; + + if (gCurrentMissionNumber == 52 || gCurrentMissionNumber == 53) + { + targets = FindFreeTargets(safehouse_targets, 4, 0); + + // need at least 2 free targets + if (targets < 2) + return 0; + + MS_TARGET *target = safehouse_targets[0]; + + // outside switch + target->type = Target_Point; + target->s.target_flags = 0x400000; + target->s.display_flags = 0; + target->s.point.posX = -182450; + target->s.point.posZ = -41235; + target->s.point.radius = 150; + target->s.point.actionFlag = 0x310003; + + // inside switch + target++; + target->type = Target_Point; + target->s.target_flags = 0x400000; + target->s.display_flags = 0; + target->s.point.posX = -182705; + target->s.point.posZ = -41723; + target->s.point.radius = 150; + target->s.point.actionFlag = 0x310003; + + printInfo("**** Doors are ready!\n"); + + if (targets == 4) + { + // random car 1 + target++; + target->type = Target_Car; + target->s.target_flags = 0; + target->s.display_flags = 0; + target->s.car.posX = -184200; + target->s.car.posZ = -43680; + target->s.car.rotation = 0; + target->s.car.slot = -1; + target->s.car.type = 1; + target->s.car.flags = 32; + + // random car 2 + target++; + target->type = Target_Car; + target->s.target_flags = 0; + target->s.display_flags = 0; + target->s.car.posX = -181920; + target->s.car.posZ = -43400; + target->s.car.rotation = -1536; + target->s.car.slot = -1; + target->s.car.type = 1; + target->s.car.flags = 32; + + cars_to_spawn = 2; + + printInfo("**** Cars are ready!\n"); + } + + return 1; + } + + // setup failed! + return 0; + } + + // doors + for (int i = 0; i < 2; i++) + { + if (MRProcessTarget(thread, safehouse_targets[i])) + { + TriggerEvent(2); + + if (i == 0) + door_state = (door_state == 0) ? 1 : 0; + else if (i == 1) + door_state = (door_state == 1) ? 0 : 1; + + printWarning("**** DOOR IS NOW %s\n", (door_state == 1) ? "OPEN" : "CLOSED"); + } + } + + if (door_state == 1 && cars_to_spawn > 0) + { + VECTOR tv; + + for (int j = 0; j < cars_to_spawn; j++) + { + MS_TARGET *target = safehouse_targets[j + 2]; + + if (!(target->s.target_flags & TARGET_FLAG_CAR_PINGED_IN)) + { + printWarning("**** REQUESTING RANDOM SPAWN OF CAR %d\n", j); + + int model = 0; + int pal = Random2(0) % 6; + int rm = Random2(0) % 3; + + // only request available civ cars (no cops or specials) + if (rm > 2) + rm = 2; + + model = MissionHeader->residentModels[rm]; + + target->s.car.model = model; + target->s.car.palette = pal; + + MRProcessTarget(thread, target); + return 0; + } + } + + // door is opened and all cars are spawned + cars_to_spawn = -cars_to_spawn; + } + else if (door_state == 0 && cars_to_spawn < 0) + { + // door is closed - check if all cars are spawned next time it opens + cars_to_spawn = -cars_to_spawn; + } + + return 0; +} + +int VegasTAREvents(MR_THREAD *thread, int init) +{ + if (init) + { + printInfo("**** VEGAS TAR EVENT SETUP\n"); + + if (gCurrentMissionNumber == 54 || gCurrentMissionNumber == 55) + return 1; + } + + return 0; +} + +int RioTAREvents(MR_THREAD *thread, int init) +{ + if (init) + { + printInfo("**** RIO TAR EVENT SETUP\n"); + + if (gCurrentMissionNumber == 56 || gCurrentMissionNumber == 57) + return 1; + } + + return 0; +} + +typedef int userEventFunc(MR_THREAD *thread, int init); +typedef userEventFunc * (userEventFuncList)[4]; + +userEventFuncList fnTAREventHandlers[] = { + ChicagoTAREvents, + HavanaTAREvents, + VegasTAREvents, + RioTAREvents, +}; + +userEventFuncList fnNullMissionEventHandlers[] = { + EmptyMissionEvents, + EmptyMissionEvents, + EmptyMissionEvents, + EmptyMissionEvents, +}; + +userEventFuncList * fnMissionEventHandlers; + +int StopUserMissionEvents(MR_THREAD *thread) +{ + return 1; +} + +int RunUserMissionEvents(MR_THREAD *thread) +{ + if (gCurrentMissionNumber >= 50 && gCurrentMissionNumber <= 65) + maxCopCars = 32; + + return (*fnMissionEventHandlers)[GameLevel](thread, 0); +} + +int InitUserMissionEvents(MR_THREAD *thread) +{ + thread->stepFunc = RunUserMissionEvents; + thread->stopFunc = StopUserMissionEvents; + + if (gCurrentMissionNumber >= 50 && gCurrentMissionNumber <= 57) + fnMissionEventHandlers = fnTAREventHandlers; + else + fnMissionEventHandlers = fnNullMissionEventHandlers; + + user_events_allowed = (*fnMissionEventHandlers)[GameLevel](thread, 1); + + return 1; } \ No newline at end of file diff --git a/src_rebuild/Game/C/event.h b/src_rebuild/Game/C/event.h index b10ff04b2..d91549edf 100644 --- a/src_rebuild/Game/C/event.h +++ b/src_rebuild/Game/C/event.h @@ -71,5 +71,7 @@ extern int DetonatorTimer(); // 0x0004B5FC extern void MultiCarEvent(MS_TARGET *target); // 0x0004BAB0 +extern int InitUserMissionEvents(MR_THREAD *thread); + #endif diff --git a/src_rebuild/Game/C/mission.c b/src_rebuild/Game/C/mission.c index 7728edb13..60ded8833 100644 --- a/src_rebuild/Game/C/mission.c +++ b/src_rebuild/Game/C/mission.c @@ -1627,28 +1627,36 @@ void HandleMissionThreads(void) while (running && (Mission.gameover_delay == -1) && (!gInGameCutsceneActive && gInGameCutsceneDelay == 0)) { - value = *thread->pc++; - - switch (value & 0xff000000) + if (thread->type == 2) { - case 0x0: - case 0x2000000: - case 0xff000000: - MR_DebugPrint("MR: push %d\n", value); - MRPush(thread, value); - break; - case 0x1000000: - MR_DebugPrint("MR: command %x\n", value); - running = MRCommand(thread, value); - break; - case 0x3000000: - MR_DebugPrint("MR: operator %x\n", value); - running = MROperator(thread, value); - break; - case 0x4000000: - MR_DebugPrint("MR: function %x\n", value); - running = MRFunction(thread, value); - break; + if (thread->stepFunc != NULL) + running = thread->stepFunc(thread); + } + else + { + value = *thread->pc++; + + switch (value & 0xff000000) + { + case 0x0: + case 0x2000000: + case 0xff000000: + MR_DebugPrint("MR: push %d\n", value); + MRPush(thread, value); + break; + case 0x1000000: + MR_DebugPrint("MR: command %x\n", value); + running = MRCommand(thread, value); + break; + case 0x3000000: + MR_DebugPrint("MR: operator %x\n", value); + running = MROperator(thread, value); + break; + case 0x4000000: + MR_DebugPrint("MR: function %x\n", value); + running = MRFunction(thread, value); + break; + } } } @@ -1957,11 +1965,38 @@ int MRFunction(MR_THREAD *thread, u_int fnc) void MRInitialiseThread(MR_THREAD *thread, u_int *pc, u_char player) { thread->active = 1; + thread->type = 1; + thread->flags = 0; thread->pc = pc; thread->player = player; thread->sp = thread->initial_sp; } +void MRInitialiseUserThread(MR_THREAD *thread, MR_THREAD *callingthread, threadFunc *initFunc, u_char player) +{ + thread->active = 1; + thread->type = 2; + thread->flags = 0; + thread->player = player; + + thread->owner = callingthread; + thread->stepFunc = NULL; + thread->stopFunc = NULL; + + int handled = 0; + + if (initFunc) + handled = initFunc(thread); + + if (!handled) + { + if (thread->stepFunc == NULL || thread->stopFunc == NULL) + { + thread->active = 0; + thread->flags = -666; + } + } +} // [D] [T] void MRStartThread(MR_THREAD *callingthread, u_int addr, unsigned char player) @@ -1969,7 +2004,7 @@ void MRStartThread(MR_THREAD *callingthread, u_int addr, unsigned char player) int i; for (i = 0; i < MAX_MISSION_THREADS; i++) { - if (!MissionThreads[i].active) + if (!MissionThreads[i].active && MissionThreads[i].type != 2) { MRInitialiseThread(&MissionThreads[i], callingthread->pc + addr, player); break; @@ -1977,10 +2012,30 @@ void MRStartThread(MR_THREAD *callingthread, u_int addr, unsigned char player) } } +void MRStartUserThread(MR_THREAD *callingthread, threadFunc *initFunc, u_char player) +{ + // NB: make user threads run at the end + for (int i = 12; i < MAX_MISSION_THREADS; i++) + { + if (!MissionThreads[i].active && MissionThreads[i].type != 1) + { + MRInitialiseUserThread(&MissionThreads[i], callingthread, initFunc, player); + break; + } + } +} + // [D] [T] int MRStopThread(MR_THREAD *thread) { thread->active = 0; + + if (thread->type == 2) + { + if (thread->stopFunc != NULL) + return thread->stopFunc(thread); + } + return 0; } @@ -3363,6 +3418,8 @@ void HandleMission(void) FelonyBar.active = 0; break; } + + MRStartUserThread(&MissionThreads[0], InitUserMissionEvents, 0); } if (bMissionTitleFade) diff --git a/src_rebuild/Game/dr2types.h b/src_rebuild/Game/dr2types.h index a54bb735e..30805b46d 100644 --- a/src_rebuild/Game/dr2types.h +++ b/src_rebuild/Game/dr2types.h @@ -839,15 +839,34 @@ struct MR_MISSION char* StealMessage; }; +typedef int threadFunc(struct MR_THREAD *thread); + struct MR_THREAD { u_char active; u_char player; - u_int* initial_sp; - u_int* pc; - u_int* sp; + u_char type; + u_char flags; + union + { + struct + { + u_int* initial_sp; + u_int* pc; + u_int* sp; + }; + + struct + { + MR_THREAD *owner; + threadFunc *stepFunc; + threadFunc *stopFunc; + }; + }; }; +assert_sizeof(MR_THREAD, 16); + //--------------------------------------------------------------------------------------- // TODO: SCORES.H From b6ed4d8d2ef34cc4ebdbfd1e444883f810ba385b Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 5 Aug 2022 05:42:35 -0700 Subject: [PATCH 56/78] [Game:cop_ai] Minor code cleanup and refactoring --- src_rebuild/Game/C/cop_ai.c | 51 +++++++++---------------------------- 1 file changed, 12 insertions(+), 39 deletions(-) diff --git a/src_rebuild/Game/C/cop_ai.c b/src_rebuild/Game/C/cop_ai.c index 5607550a6..ac6482ff6 100644 --- a/src_rebuild/Game/C/cop_ai.c +++ b/src_rebuild/Game/C/cop_ai.c @@ -217,24 +217,18 @@ void WibbleDownTheRoad(VECTOR *from, int distance, VECTOR *to) // [D] [T] void UpdateCopSightData(void) { - short* playerFelony; - - if (player[0].playerCarId < 0) - playerFelony = &pedestrianFelony; - else - playerFelony = &car_data[player[0].playerCarId].felonyRating; - - if (*playerFelony > FELONY_PURSUIT_MIN_VALUE) + if (*GetPlayerFelonyData() > FELONY_PURSUIT_MIN_VALUE) { copSightData.surroundViewDistance = 5440; copSightData.frontViewDistance = 16320; copSightData.frontViewAngle = 1024; - return; } - - copSightData.surroundViewDistance = 2720; - copSightData.frontViewDistance = 7820; - copSightData.frontViewAngle = 512; + else + { + copSightData.surroundViewDistance = 2720; + copSightData.frontViewDistance = 7820; + copSightData.frontViewAngle = 512; + } } // [D] [T] @@ -351,10 +345,7 @@ void CopControl1(CAR_DATA *cp) iVectNT path[2]; AIZone targetZone; - if (player[0].playerCarId < 0) - playerFelony = &pedestrianFelony; - else - playerFelony = &car_data[player[0].playerCarId].felonyRating; + playerFelony = GetPlayerFelonyData(); desiredSteerAngle = 0; @@ -715,11 +706,6 @@ void CopControl1(CAR_DATA *cp) if (pathStraight != 0) maxPower += (gCopDifficultyLevel + 4) * 1024; - if (player[0].playerCarId < 0) - playerFelony = &pedestrianFelony; - else - playerFelony = &car_data[player[0].playerCarId].felonyRating; - maxPower = FIXEDH(maxPower * (gCopMaxPowerScale + FIXEDH(*playerFelony * gCopData.autoMaxPowerScaleLimit))); if (currentSpeed < -50) @@ -972,14 +958,7 @@ void ControlCopDetection(void) // [D] [T] void PassiveCopTasks(CAR_DATA *cp) { - short *playerFelony; - - if (player[0].playerCarId < 0) - playerFelony = &pedestrianFelony; - else - playerFelony = &car_data[player[0].playerCarId].felonyRating; - - if (*playerFelony <= FELONY_PURSUIT_MIN_VALUE) + if (*GetPlayerFelonyData() <= FELONY_PURSUIT_MIN_VALUE) return; // [A] make an ambush on player in Destroy the yard @@ -1010,13 +989,10 @@ void ControlNumberOfCops(void) pTrigger = gCopData.trigger; numWantedCops = 0; + playerFelony = GetPlayerFelonyData(); + while( true ) { - if (player[0].playerCarId < 0) - playerFelony = &pedestrianFelony; - else - playerFelony = &car_data[player[0].playerCarId].felonyRating; - if (*playerFelony < *pTrigger) break; @@ -1115,10 +1091,7 @@ void ControlCops(void) } #endif - if (player[0].playerCarId < 0) - playerFelony = &pedestrianFelony; - else - playerFelony = &car_data[player[0].playerCarId].felonyRating; + playerFelony = GetPlayerFelonyData(); gCopData.autoBatterPlayerTrigger = 2048; From c1c5b52f576cd2c2f03ef52cacc9f6b4ff48edd5 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 5 Aug 2022 05:43:52 -0700 Subject: [PATCH 57/78] [Game:debris] Fixed some incorrect debris color entries --- src_rebuild/Game/C/debris.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src_rebuild/Game/C/debris.c b/src_rebuild/Game/C/debris.c index 224df2d72..08eb5d898 100644 --- a/src_rebuild/Game/C/debris.c +++ b/src_rebuild/Game/C/debris.c @@ -165,7 +165,7 @@ CVECTOR debris_colour[4][31] = { 150, 164, 184, 0 }, { 102, 102, 102, 0 }, { 140, 114, 99, 0 }, - { 75, 63, 134, 0 }, + { 160, 200, 140, 0 }, }, { { 100, 100, 100, 0 }, { 83, 82, 97, 0 }, @@ -224,7 +224,7 @@ CVECTOR debris_colour[4][31] = { 183, 183, 183, 0 }, { 126, 98, 84, 0 }, { 126, 125, 156, 0 }, - { 36, 74, 203, 0 }, + { 251, 241, 175, 0 }, { 105, 105, 105, 0 }, { 162, 179, 183, 0 }, { 102, 130, 162, 0 }, From 809a8fb201cbd00e2d2bf9aff90640865c0bebd1 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 5 Aug 2022 05:45:34 -0700 Subject: [PATCH 58/78] [Game:overlay] [PC] Added custom speedometer code --- src_rebuild/Game/C/overlay.c | 49 ++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src_rebuild/Game/C/overlay.c b/src_rebuild/Game/C/overlay.c index 9fca84959..8898f90a0 100644 --- a/src_rebuild/Game/C/overlay.c +++ b/src_rebuild/Game/C/overlay.c @@ -669,6 +669,51 @@ void DrawDrivingGameOverlays(void) } } +#ifndef PSX +void DrawSpeedometer() +{ + extern u_char speedLimits[4]; + + char buffer[32]; + + if (NumPlayers > 1) + return; + + int playerCarId = player[0].playerCarId; + + if (playerCarId == -1) + return; + + CAR_DATA *cp = &car_data[playerCarId]; + + float KPH_FACTOR = 1.8875f; + float MPH_FACTOR = 1.6f; + + int limitKmh = (int)(speedLimits[3] / KPH_FACTOR); + int limitMph = (int)(limitKmh / MPH_FACTOR); + + int speedKmh = (int)(cp->hd.speed / KPH_FACTOR); + int speedMph = (int)(speedKmh / MPH_FACTOR); + + sprintf(buffer, "%dmph", speedMph); + + char col = 255; + + if (FelonyBar.active && FIXEDH(cp->hd.wheel_speed) > speedLimits[3]) + col = ((CameraCnt + 1) % 16) * 16; + + // setup scaling and color + SetTextScale(0xc00, 1); + SetTextColour(255, col, col); + + // display the speedometer + PrintStringRightAligned(buffer, gMapXOffset + MAP_SIZE_W, gMapYOffset + MAP_SIZE_H - 2); + + // restore scaling + ResetTextScale(); +} +#endif + // [D] [T] void DisplayOverlays(void) @@ -735,6 +780,10 @@ void DisplayOverlays(void) if (*GetPlayerFelonyData() > FELONY_PURSUIT_MIN_VALUE) DrawCopIndicators(); } + +#ifndef PSX + DrawSpeedometer(); +#endif } else { From 718cc185bae8084953bc6ed1391c559a38d30811 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 5 Aug 2022 05:47:02 -0700 Subject: [PATCH 59/78] Attempt to hackily fix yet another wibbly-wobbly car bug... --- src_rebuild/Game/C/handling.c | 6 ++++++ src_rebuild/Game/C/wheelforces.c | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src_rebuild/Game/C/handling.c b/src_rebuild/Game/C/handling.c index 4c9cc27a8..a73685fd7 100644 --- a/src_rebuild/Game/C/handling.c +++ b/src_rebuild/Game/C/handling.c @@ -261,6 +261,12 @@ void FixCarCos(CAR_COSMETICS* carCos, int externalModelNumber) { car_cosmetics[2].mass *= 3; } + + // [A] vegas box truck + if (GameLevel == 2 && externalModelNumber == 10) + { + carCos->extraInfo |= 4; // wibbly wobbly fuckery hack... + } } int ghost_mode = 0; diff --git a/src_rebuild/Game/C/wheelforces.c b/src_rebuild/Game/C/wheelforces.c index 337f3053f..84f5d4fb5 100644 --- a/src_rebuild/Game/C/wheelforces.c +++ b/src_rebuild/Game/C/wheelforces.c @@ -528,6 +528,32 @@ void AddWheelForcesDriver1(CAR_DATA* cp, CAR_LOCALS* cl) else { cp->hd.wheel_speed = cdz / 64 * (cl->vel[2] / 64) + cdx / 64 * (cl->vel[0] / 64); + + // [A] wibbly wobbly fuckery hack... + if (car_cos->extraInfo & 4) + { + if (cp->thrust == 0 && cp->handbrake && (cp->hd.speed > 0 && cp->hd.speed < 4)) + { + cp->hd.speed--; + cp->hd.wheel_speed >>= 1; + + cp->hd.acc[0] >>= 1; + cp->hd.acc[1] >>= 1; + cp->hd.acc[2] >>= 1; + + cp->hd.aacc[0] >>= 2; + cp->hd.aacc[1] >>= 2; + cp->hd.aacc[2] >>= 2; + + //cp->st.n.linearVelocity[0] >>= 1; + //cp->st.n.linearVelocity[1] >>= 1; + //cp->st.n.linearVelocity[2] >>= 1; + + cp->st.n.angularVelocity[0] >>= 2; + cp->st.n.angularVelocity[1] >>= 2; + cp->st.n.angularVelocity[2] >>= 2; + } + } } } From b227ae88426d694e119dc63f9d6ced32a748a8b6 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 5 Aug 2022 05:48:24 -0700 Subject: [PATCH 60/78] Add MORE missing code because I've gotten really good at this :D --- src_rebuild/Game/C/civ_ai.c | 4 +++- src_rebuild/Game/C/civ_ai.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src_rebuild/Game/C/civ_ai.c b/src_rebuild/Game/C/civ_ai.c index 29e73f9e4..f78acb306 100644 --- a/src_rebuild/Game/C/civ_ai.c +++ b/src_rebuild/Game/C/civ_ai.c @@ -26,8 +26,10 @@ #include "cutrecorder.h" #include "draw.h" #include "glaunch.h" +#include "pad.h" -const u_char speedLimits[3] = { 56, 97, 138 }; +// [A] keep track of player's speed limit using last one +u_char speedLimits[4] = { 56, 97, 138 }; #ifdef DEBUG struct diff --git a/src_rebuild/Game/C/civ_ai.h b/src_rebuild/Game/C/civ_ai.h index 2e74e75a6..5afb24f5b 100644 --- a/src_rebuild/Game/C/civ_ai.h +++ b/src_rebuild/Game/C/civ_ai.h @@ -12,7 +12,7 @@ typedef struct _EXTRA_CIV_DATA u_char controlFlags; } EXTRA_CIV_DATA; -extern const u_char speedLimits[3]; +extern u_char speedLimits[4]; extern unsigned char reservedSlots[MAX_CARS]; extern int frameStart; From d53a1723daf89e6fe35b04ebe13dad0f926b4e71 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 5 Aug 2022 05:51:48 -0700 Subject: [PATCH 61/78] Added much-improved headlight drawing code. --- src_rebuild/Game/C/debris.c | 120 +++++++++++++++++++------------- src_rebuild/redriver2_psxpc.cpp | 5 ++ 2 files changed, 76 insertions(+), 49 deletions(-) diff --git a/src_rebuild/Game/C/debris.c b/src_rebuild/Game/C/debris.c index 08eb5d898..5bad604f6 100644 --- a/src_rebuild/Game/C/debris.c +++ b/src_rebuild/Game/C/debris.c @@ -21,6 +21,7 @@ #include "cosmetic.h" #include "denting.h" #include "gamesnd.h" +#include "glaunch.h" #include "ASM/rndrasm.h" @@ -402,6 +403,8 @@ DAMAGED_LAMP damaged_lamp[MAX_DAMAGED_LAMPS]; MATRIX debris_mat; MATRIX leaf_mat; +int gNewHeadlights = 1; + // [D] [T] void PlacePoolForCar(CAR_DATA *cp, CVECTOR *col, int front, int in_car) { @@ -428,77 +431,93 @@ void PlacePoolForCar(CAR_DATA *cp, CVECTOR *col, int front, int in_car) if (front) { - s1[3].vz = -(car_cos->colBox.vz + 50); - s1[8].vz = s1[3].vz - 1160; - s1[6].vz = s1[3].vz; - s1[7].vz = s1[3].vz; - - if (in_car) + // make headlight polys + if (gNewHeadlights) { - // slightly shifted vertices to make it look more beautiful - s1[1].vz = s1[8].vz + 600; + s1[3].vz = car_cos->cPoints[4].vz - 20; + s1[3].vz -= (ActiveCheats.cheat13) ? 25 : 50; + s1[0].vx = car_cos->colBox.vx; + s1[1].vx = MAX(car_cos->headLight.vz, -380); + s1[6].vx = car_cos->headLight.vx + 60; + s1[7].vx = 21; + s1[10].vx = car_cos->colBox.vx; + s1[11].vx = car_cos->headLight.vx; + } + else + { + s1[3].vz = -(car_cos->colBox.vz + 50); s1[0].vx = 136; s1[1].vx = -344; - s1[2].vx = -21; - s1[3].vx = -143; - s1[4].vx = 344; - s1[5].vx = -136; s1[6].vx = 143; s1[7].vx = 21; - s1[8].vz = s1[8].vz - 400; - s1[9].vz = s1[3].vz + 10; - s1[8].vx = -82; s1[10].vx = 82; - s1[9].vx = -82; s1[11].vx = 82; - s1[4].vz = s1[1].vz; - s1[5].vz = s1[1].vz; - s1[10].vz = s1[8].vz; - s1[11].vz = s1[9].vz; + } + + s1[6].vz = s1[3].vz; + s1[7].vz = s1[3].vz; + s1[8].vz = s1[3].vz - 1160; + s1[9].vz = s1[3].vz; + + // mirror onto other side + s1[5].vx = -s1[0].vx; + s1[4].vx = -s1[1].vx; + s1[3].vx = -s1[6].vx; + s1[2].vx = -s1[7].vx; + s1[8].vx = -s1[10].vx; + s1[9].vx = -s1[11].vx; + + if (in_car) + { + // slightly shifted vertices to make it look more beautiful + s1[1].vz = s1[8].vz + 600; + s1[8].vz -= 400; + s1[9].vz += 10; + + if (in_car == 2) + LightSortCorrect = -500; + else + LightSortCorrect = -800; - LightSortCorrect = -800; - sub_level = 3; } else { s1[1].vz = s1[8].vz + 100; - s1[0].vx = 136; - s1[1].vx = -344; - s1[2].vx = -21; - s1[3].vx = -143; - s1[4].vx = 344; - s1[5].vx = -136; - s1[6].vx = 143; - s1[7].vx = 21; - s1[10].vx = 82; - s1[11].vx = 82; - s1[8].vx = -82; - s1[9].vx = -82; - s1[4].vz = s1[1].vz; - s1[5].vz = s1[1].vz; - s1[9].vz = s1[3].vz; - s1[10].vz = s1[8].vz; - s1[11].vz = s1[3].vz; - - sub_level = 3; if (player[CurrentPlayerView].cameraView == 2 && cp == &car_data[player[CurrentPlayerView].playerCarId]) LightSortCorrect = -320; else LightSortCorrect = -200; + + sub_level = 3; } + + // merge cross polys together + s1[4].vz = s1[1].vz; + s1[5].vz = s1[4].vz; + s1[10].vz = s1[8].vz; + s1[11].vz = s1[9].vz; } else { // back light - - s1[0].vx = -204; - s1[1].vx = 204; - s1[2].vx = -204; - s1[3].vx = 204; - s1[3].vz = (car_cos->colBox.vz - 10); - s1[1].vz = s1[3].vz + 204; + + if (gNewHeadlights) + s1[0].vx = car_cos->cPoints[4].vx - 80; + else + s1[0].vx = -204; + + s1[1].vx = -s1[0].vx; + s1[2].vx = s1[0].vx; + s1[3].vx = s1[1].vx; + + if (gNewHeadlights) + s1[3].vz = -(car_cos->cPoints[4].vz + 25); + else + s1[3].vz = car_cos->colBox.vz - 10; + + s1[1].vz = s1[3].vz + s1[1].vx; sub_level = 0; } @@ -510,7 +529,10 @@ void PlacePoolForCar(CAR_DATA *cp, CVECTOR *col, int front, int in_car) mid_position.vx = 0; mid_position.vy = 0; - mid_position.vz = -500; + if (gNewHeadlights) + mid_position.vz = -(car_cos->cPoints[4].vz + car_cos->cPoints[8].vz / 2); + else + mid_position.vz = -500; _MatrixRotate(&mid_position); diff --git a/src_rebuild/redriver2_psxpc.cpp b/src_rebuild/redriver2_psxpc.cpp index 9ec003afa..e5d3efd0d 100644 --- a/src_rebuild/redriver2_psxpc.cpp +++ b/src_rebuild/redriver2_psxpc.cpp @@ -201,6 +201,11 @@ void GameDebugKeys(int nKey, char down) extern void CreateRoadblock(); CreateRoadblock(); } + else if (nKey == SDL_SCANCODE_KP_5) + { + extern int gNewHeadlights; + gNewHeadlights ^= 1; + } else if (nKey == SDL_SCANCODE_KP_PLUS) { extern LEAD_PARAMETERS LeadValues; From 31caa2b6aff37260bde6f367ff491b250f0745f4 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 5 Aug 2022 05:57:20 -0700 Subject: [PATCH 62/78] [Game:event] Minor code cleanup and refactoring pass --- src_rebuild/Game/C/event.c | 158 ++++++++++++++++--------------------- 1 file changed, 70 insertions(+), 88 deletions(-) diff --git a/src_rebuild/Game/C/event.c b/src_rebuild/Game/C/event.c index 2fe144167..7fca0e10b 100644 --- a/src_rebuild/Game/C/event.c +++ b/src_rebuild/Game/C/event.c @@ -265,10 +265,10 @@ FixedEvent chicagoDoor[3] = { -207616, 0, 659706, 0 }, 0, 0, - 800u, - 0u, - 25u, - 50u, + 800, + 0, + 25, + 50, 80, 0, 0, @@ -279,10 +279,10 @@ FixedEvent chicagoDoor[3] = { -209152, -512, 668928, 0 }, 0, 0, - 2496u, - 4096u, - 25u, - 50u, + 2496, + 4096, + 25, + 50, 64, 0, 0, @@ -293,10 +293,10 @@ FixedEvent chicagoDoor[3] = { 195264, -3728, 74752, 0 }, 0, 0, - 0u, - 0u, - 0u, - 0u, + 0, + 0, + 0, + 0, 1088, 0, 0, @@ -325,10 +325,10 @@ FixedEvent havanaFixed[3] = { -455168, 1529, -125440, 0 }, 0, 0, - 0u, - 0u, - 0u, - 0u, + 0, + 0, + 0, + 0, 1536, 0, 0, @@ -339,10 +339,10 @@ FixedEvent havanaFixed[3] = { -487936, 0, -136689, 0 }, 0, 0, - 1152u, - 0u, - 10u, - 20u, + 1152, + 0, + 10, + 20, 80, 0, 0, @@ -432,10 +432,10 @@ FixedEvent rioDoor[6] = { -123328, -177, -254720, 0 }, 0, 0, - 3200u, - 4096u, - 25u, - 50u, + 3200, + 4096, + 25, + 50, 96, 0, 0, @@ -446,10 +446,10 @@ FixedEvent rioDoor[6] = { -125248, -17, -256208, 0 }, 0, 0, - 1600u, - 0u, - 25u, - 50u, + 1600, + 0, + 25, + 50, 80, 0, 0, @@ -460,10 +460,10 @@ FixedEvent rioDoor[6] = { -274000, -17, -321408, 0 }, 0, 0, - 1748u, - 3072u, - 25u, - 50u, + 1748, + 3072, + 25, + 50, 80, 0, 0, @@ -474,10 +474,10 @@ FixedEvent rioDoor[6] = { -274000, -17, -322432, 0 }, 0, 0, - 2348u, - 1024u, - 25u, - 50u, + 2348, + 1024, + 25, + 50, 80, 0, 0, @@ -488,10 +488,10 @@ FixedEvent rioDoor[6] = { -40432, -17, 383328, 0 }, 0, 0, - 700u, - 2048u, - 25u, - 50u, + 700, + 2048, + 25, + 50, 80, 0, 0, @@ -502,10 +502,10 @@ FixedEvent rioDoor[6] = { -39424, -17, 383328, 0 }, 0, 0, - 900u, - 0u, - 25u, - 50u, + 900, + 0, + 25, + 50, 80, 0, 0, @@ -517,17 +517,6 @@ FixedEvent rioDoor[6] = Helicopter HelicopterData = { 400, - 0, - 0, - 0, - 0, - 0, - 0, - { { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, 0u, 0u, 0, 0 }, - 0, - 0, - 0, - 0 }; static Foam foam; @@ -673,10 +662,9 @@ void VisibilityLists(VisType type, int i) if (type == VIS_SORT) { num = 0; - do { - j = 0; - - while (j < count) + do + { + for (j = 0; j < count; j++) { vis = GetVisValue(list[num][j], num); @@ -689,6 +677,7 @@ void VisibilityLists(VisType type, int i) tempList = list[num][j]; k = j - 1; + do { n = k; @@ -704,14 +693,10 @@ void VisibilityLists(VisType type, int i) table[n] = vis; list[num][n] = tempList; } - - j++; } - num++; - } while (num < 2); + } while (++num < 2); - num = 0; - while (num < NumPlayers) + for (num = 0; num < NumPlayers; num++) { if (num != 0) camera = 0x4000; @@ -726,8 +711,6 @@ void VisibilityLists(VisType type, int i) do { } while ((*(firstZ[num]++) & camera) == 0); - - num++; } } else if (type == VIS_INIT) @@ -749,12 +732,10 @@ void VisibilityLists(VisType type, int i) count = 4; } - num = 0; - while (num < NumPlayers) + for (num = 0; num < NumPlayers; num++) { firstX[num] = xList; firstZ[num] = zList; - num++; } } else if (type == VIS_ADD) @@ -1014,8 +995,7 @@ void SetUpEvents(int full) p = &LiftingBridges[1]; // make lifting bridges - n = 0; - while (n < cBridges) + for (n = 0; n < cBridges; n++) { int timeOffset; cameraEventsActive = 1; @@ -1055,17 +1035,18 @@ void SetUpEvents(int full) timeOffset = (Random2(0) >> (n & 31) & 255) * 32; evt = &event[cEvents]; + for (i = 0; i < 2; i++) { if (direction) { evt[i].flags = 0x1; - evt[i].position.vx = *p; + evt[i].position.vx = p[0]; } else { evt[i].flags = 0x21; - evt[i].position.vz = *p; + evt[i].position.vz = p[0]; } evt[i].node = p; @@ -1089,30 +1070,28 @@ void SetUpEvents(int full) cEvents += 2; e = &evt->next->next; - n++; } if (full) ElTrackModel = FindModelIdxWithName("ELTRAIN"); - count = ElTrainData[0]; p = ElTrainData; + + count = p[0]; - n = 0; missionTrain[0].engine = &event[cEvents]; missionTrain[1].engine = missionTrain[0].engine; // add trains - while (n < count-1) + for (n = 0; n < count - 1; n++) { // randomize carriage count if (n != 0) - i = (Random2(0) >> (n & 0x1f) & 3U) + 2; + i = (Random2(0) >> (n & 0x1f) & 3) + 2; else i = 5; direction = 1; - n++; p++; while (--i >= 0) @@ -1141,11 +1120,9 @@ void SetUpEvents(int full) cEvents++; } - //i = *p; - - do - { - } while (*++p + PATH_NODE_WRAP > 1); + // skip PATH_NODE_STATION, PATH_NODE_REVERSE + while (p[1] + PATH_NODE_WRAP > 1) + p++; } fixedEvent = chicagoDoor; @@ -1239,9 +1216,9 @@ void SetUpEvents(int full) e = &(*e)->next; cEvents = 2; - if (full != 0) + if (full) { - event->model = FindModelIdxWithName("FERRY"); + event[0].model = FindModelIdxWithName("FERRY"); event[1].model = FindModelIdxWithName("LIFT"); havanaFixed[1].model = FindModelIdxWithName(havanaFixed[1].modelName); @@ -3200,7 +3177,12 @@ void DrawEvents(int camera) if (gTimeOfDay != TIME_DAY) SetupPlaneColours(0x00282828); - RenderModel(foam.model, &matrix, &pos, 200, (foam.rotate & 0x8000) ? 0x3 : 0x1, 1, 0); + int flags = PLOT_TRANSPARENT; + + if (foam.rotate & 0x8000) + flags |= PLOT_INV_CULL; + + RenderModel(foam.model, &matrix, &pos, 200, flags, 1, 0); SetupPlaneColours(combointensity); } } From b150b132a7b5503b37a43571672ec8eb5e73df2c Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 5 Aug 2022 06:01:11 -0700 Subject: [PATCH 63/78] Created 'AddEvent' and 'NewEvent' functions for easier linked list operations. --- src_rebuild/Game/C/event.c | 79 ++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 37 deletions(-) diff --git a/src_rebuild/Game/C/event.c b/src_rebuild/Game/C/event.c index 7fca0e10b..b67105c29 100644 --- a/src_rebuild/Game/C/event.c +++ b/src_rebuild/Game/C/event.c @@ -854,6 +854,22 @@ void InitTrain(EVENT* ev, int count, int type) } } +// [A] +void AddEvent(EVENT *ev, EVENT*** e) +{ + **e = ev; + *e = &ev->next; +} + +// [A] +void NewEvent(EVENT *ev, EVENT*** e) +{ + **e = ev; + ev->next = &ev[1]; + + *e = &(ev->next)->next; +} + // [D] [T] void InitDoor(FixedEvent* ev, EVENT*** e, int* cEvents) { @@ -861,8 +877,7 @@ void InitDoor(FixedEvent* ev, EVENT*** e, int* cEvents) ev->rotation = ev->finalRotation; ev->flags |= 0x200; - *(FixedEvent**)*e = ev; // [A] is that gonna work? - *e = &(**e)->next; + AddEvent((EVENT*)ev, e); VisibilityLists(VIS_ADD, (ev - fixedEvent) | 0x80); } @@ -1062,14 +1077,9 @@ void SetUpEvents(int full) p++; } - *e = &event[cEvents]; - - evt = *e; - evt->next = &event[cEvents + 1]; - + NewEvent(evt, &e); + cEvents += 2; - - e = &evt->next->next; } if (full) @@ -1112,9 +1122,8 @@ void SetUpEvents(int full) if (full) evt->model = ElTrackModel; - *e = evt; - e = &(*e)->next; - + AddEvent(evt, &e); + VisibilityLists(VIS_ADD, cEvents); cEvents++; @@ -1130,9 +1139,8 @@ void SetUpEvents(int full) InitDoor(&chicagoDoor[0], &e, &cEvents); InitDoor(&chicagoDoor[1], &e, &cEvents); - *e = (EVENT*)&chicagoDoor[2]; - e = &(*e)->next; - + AddEvent((EVENT*)&chicagoDoor[2], &e); + VisibilityLists(VIS_ADD, 130); if (full) @@ -1187,18 +1195,17 @@ void SetUpEvents(int full) evt->data[2] = RCOS(CameraCnt * 16) + 4096 >> 7; VisibilityLists(VIS_ADD, 0); - MakeEventTrackable(evt); - - *e = evt; - fixedEvent = havanaFixed; - e = &(*e)->next; + MakeEventTrackable(event); - InitDoor(havanaFixed, &e, &cEvents); - InitDoor(havanaFixed + 2, &e, &cEvents); + AddEvent(event, &e); - *e = (EVENT*)(&havanaFixed[1]); - e = &(*e)->next; + fixedEvent = havanaFixed; + + InitDoor(&havanaFixed[0], &e, &cEvents); + InitDoor(&havanaFixed[2], &e, &cEvents); + AddEvent((EVENT*)&havanaFixed[1], &e); + VisibilityLists(VIS_ADD, 129); evt[1].flags = 0x4212; @@ -1212,8 +1219,9 @@ void SetUpEvents(int full) evt[1].data = HavanaMiniData; VisibilityLists(VIS_ADD, 1); - *e = event + 1; - e = &(*e)->next; + + AddEvent(&event[1], &e); + cEvents = 2; if (full) @@ -1263,8 +1271,7 @@ void SetUpEvents(int full) if (full) evt[i].model = trainModel; - *e = &evt[i]; - e = &(*e)->next; + AddEvent(&evt[i], &e); } // zero first and last train links @@ -1305,8 +1312,7 @@ void SetUpEvents(int full) if (full) evt[i].model = trainModel; - *e = &evt[i]; - e = &(*e)->next; + AddEvent(&evt[i], &e); } evt->flags |= 0x500; @@ -1380,11 +1386,11 @@ void SetUpEvents(int full) VisibilityLists(VIS_ADD, 0); MakeEventTrackable(event); - *e = event; + + AddEvent(event, &e); cEvents = 1; fixedEvent = rioDoor; - e = &(*e)->next; for (i = 0; i < 6; i++) { @@ -1486,9 +1492,7 @@ void SetUpEvents(int full) VisibilityLists(VIS_ADD, cEvents); MakeEventTrackable(event + cEvents); - *e = &evt[cEvents++]; - - e = &(*e)->next; + AddEvent(&event[cEvents++], &e); } } @@ -3396,11 +3400,12 @@ void MakeEventTrackable(EVENT* ev) EVENT** p; p = trackingEvent; + while (*p) p++; - *p = ev; - p[1] = NULL; // WTF? + *p++ = ev; + *p = NULL; // mark next free trackable event } // [D] [T] From 45f879271c03fa54c735933e5d06fc6329bec0be Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 5 Aug 2022 06:04:00 -0700 Subject: [PATCH 64/78] [Game:event] Major code cleanup and refactoring - Added HARDCODED_CAMERA_EVENT macro for special camera sets --- src_rebuild/Game/C/event.c | 549 +++++++++++++++++------------------ src_rebuild/Game/C/event.h | 2 + src_rebuild/Game/C/mission.c | 2 +- 3 files changed, 277 insertions(+), 276 deletions(-) diff --git a/src_rebuild/Game/C/event.c b/src_rebuild/Game/C/event.c index b67105c29..3a88875f8 100644 --- a/src_rebuild/Game/C/event.c +++ b/src_rebuild/Game/C/event.c @@ -176,7 +176,7 @@ int VegasMonorailData[] = { -70500, -67510, -111000, PATH_NODE_REVERSE, -70500, PATH_NODE_WRAP, }; -int HavanaFerryData[12] = { +int HavanaFerryData[] = { 40, 0, 64, 425555, -452, 20000, // Ferry 1 25, 0, 64, 315750, 130740, 135960 // Ferry 2 }; @@ -978,6 +978,7 @@ void SetUpEvents(int full) int carModel; firstEvent = NULL; + e = &firstEvent; // Multiplayer level loaded? @@ -1090,7 +1091,7 @@ void SetUpEvents(int full) count = p[0]; missionTrain[0].engine = &event[cEvents]; - missionTrain[1].engine = missionTrain[0].engine; + missionTrain[1].engine = &event[cEvents]; // add trains for (n = 0; n < count - 1; n++) @@ -1176,23 +1177,21 @@ void SetUpEvents(int full) } else if (GameLevel == 1) { - evt = event; - cameraEventsActive = 1; - evt->radius = 0; - evt->position.vy = 111; - evt->position.vx = HavanaFerryData[3]; - evt->position.vz = HavanaFerryData[4];; - evt->rotation = 3072; - evt->flags = -0x77ad; - evt->timer = -1; - evt->node = HavanaFerryData + 4; - evt->data = HavanaFerryData; + event[0].radius = 0; + event[0].position.vy = 111; + event[0].position.vx = HavanaFerryData[3]; + event[0].position.vz = HavanaFerryData[4]; + event[0].rotation = 3072; + event[0].flags = -0x77ad; + event[0].timer = -1; + event[0].node = HavanaFerryData + 4; + event[0].data = HavanaFerryData; // [A] reset Ferry angles - evt->data[1] = RSIN(CameraCnt * 32) >> 9; - evt->data[2] = RCOS(CameraCnt * 16) + 4096 >> 7; + event[0].data[1] = RSIN(CameraCnt * 32) >> 9; + event[0].data[2] = RCOS(CameraCnt * 16) + 4096 >> 7; VisibilityLists(VIS_ADD, 0); MakeEventTrackable(event); @@ -1208,15 +1207,15 @@ void SetUpEvents(int full) VisibilityLists(VIS_ADD, 129); - evt[1].flags = 0x4212; - evt[1].node = HavanaMiniData + 1; - evt[1].position.vy = 3995; - evt[1].position.vx = -455167; - evt[1].position.vz = -125439; - evt[1].rotation = 0; - evt[1].timer = -1; - evt[1].radius = 0; - evt[1].data = HavanaMiniData; + event[1].flags = 0x4212; + event[1].node = HavanaMiniData + 1; + event[1].position.vy = 3995; + event[1].position.vx = -455167; + event[1].position.vz = -125439; + event[1].rotation = 0; + event[1].timer = -1; + event[1].radius = 0; + event[1].data = HavanaMiniData; VisibilityLists(VIS_ADD, 1); @@ -3465,240 +3464,247 @@ VECTOR* TriggerEvent(int i) detonator.count++; } } - else + else if (GameLevel == 0) // Chicago events { - if (GameLevel == 0) + switch (i) { - switch (i) - { - case 0: - case 1: - if (stage[i] == 0) - { - int offset, nodePos; - - ev = missionTrain[i].engine; - - MakeEventTrackable(ev); - ev->flags |= 0x180; - - if (*missionTrain[i].node - missionTrain[i].start > -1) - offset = 1600; + case 0: + case 1: + if (stage[i] == 0) + { + int offset, nodePos; + + ev = missionTrain[i].engine; + + MakeEventTrackable(ev); + ev->flags |= 0x180; + + if (missionTrain[i].node[0] - missionTrain[i].start > -1) + offset = 1600; + else + offset = -1600; + + loop = 0; + + do { + if (missionTrain[i].node[0] == PATH_NODE_STATION) + nodePos = missionTrain[i].node[-1]; else - offset = -1600; + nodePos = missionTrain[i].node[1]; - loop = 0; + if (missionTrain[i].startDir == 0x8000) + { + ev->flags |= 0x8000; + ev->position.vx = nodePos; + ev->position.vz = missionTrain[i].start + loop * offset; + } + else + { + ev->flags &= ~0x8000; + ev->position.vz = nodePos; + ev->position.vx = missionTrain[i].start + loop * offset; + } - do { - if (missionTrain[i].node[0] == PATH_NODE_STATION) - nodePos = missionTrain[i].node[-1]; - else - nodePos = missionTrain[i].node[1]; + ev->node = missionTrain[i].node; + ev->data = &missionTrain[i].cornerSpeed; + ev->timer = 0; - if (missionTrain[i].startDir == 0x8000) - { - ev->flags |= 0x8000; - ev->position.vx = nodePos; - ev->position.vz = missionTrain[i].start + loop * offset; - } - else - { - ev->flags &= ~0x8000; - ev->position.vz = nodePos; - ev->position.vx = missionTrain[i].start + loop * offset; - } + ev->flags &= ~0x7000; + ev->flags |= 0x3000; - ev->node = missionTrain[i].node; - ev->data = &missionTrain[i].cornerSpeed; - ev->timer = 0; - - ev->flags &= ~0x7000; - ev->flags |= 0x3000; + SetElTrainRotation(ev); - SetElTrainRotation(ev); + loop++; + ev = ev->next; + } while (ev && (ev->flags & 0x400U) == 0); + } + else + { + ev = missionTrain[i].engine; - loop++; - ev = ev->next; - } while (ev && (ev->flags & 0x400U) == 0); - } - else - { - ev = missionTrain[i].engine; - - pos = &ev->position; - - if (ev->timer != 0) - ev->timer = 1; + pos = &ev->position; - } - break; - case 2: - case 3: - case 4: - if (stage[i] == 0) + if (ev->timer != 0) + ev->timer = 1; + + } + break; + case 2: + case 3: + case 4: + if (stage[i] == 0) + { + // start bridges raised + ev = firstMissionEvent; + for (loop = 0; loop < 10; loop++) { - // start bridges raised - ev = firstMissionEvent; - for (loop = 0; loop < 10; loop++) - { - ev->flags |= 0x100; + ev->flags |= 0x100; - if (i == 4) - ev->timer = 2600; - else - ev->timer = 1000; - - ev++; - } + if (i == 4) + ev->timer = 2600; + else + ev->timer = 1000; - if (i == 2) - { - firstMissionEvent[9].timer = 2600; - firstMissionEvent[8].timer = 2600; - } + ev++; } - else + + if (i == 2) { - // raise bridges - firstMissionEvent[8].timer = 0; - firstMissionEvent[9].timer = 0; + firstMissionEvent[9].timer = 2600; + firstMissionEvent[8].timer = 2600; } - break; - case 5: - PrepareSecretCar(); - events.cameraEvent = (EVENT*)&chicagoDoor[0]; - case 6: - TriggerDoor(&chicagoDoor[i - 5], &stage[i], 1); - } + } + else + { + // raise bridges + firstMissionEvent[8].timer = 0; + firstMissionEvent[9].timer = 0; + } + break; + case 5: + PrepareSecretCar(); + events.cameraEvent = (EVENT*)&chicagoDoor[0]; + TriggerDoor(&chicagoDoor[0], &stage[i], 1); + break; + case 6: + TriggerDoor(&chicagoDoor[1], &stage[i], 1); + break; } - else if (GameLevel == 1) + } + else if (GameLevel == 1) // Havana events + { + switch (i) { - switch (i) - { - case 0: - event->timer = 1; - break; - case 1: - event->position.vx = HavanaFerryData[9]; - event->position.vz = HavanaFerryData[10]; - - event->timer = 1; - - event->node = &HavanaFerryData[10]; - event->data = &HavanaFerryData[6]; - - // [A] reset Ferry angles - event->data[1] = RSIN(CameraCnt * 32) >> 9; - event->data[2] = RCOS(CameraCnt * 16) + 4096 >> 7; - - break; - case 2: - TriggerDoor(&havanaFixed[0], &stage[i], 1); - break; - case 3: - PrepareSecretCar(); - events.cameraEvent = (EVENT*)&havanaFixed[2]; - TriggerDoor(&havanaFixed[2], &stage[i], 0); - break; - case 4: - if (stage[i] != 0) - { - SetSpecialCamera(SPECIAL_CAMERA_WAIT, 0); - event[1].node++; - } + case 0: + event->timer = 1; + break; + case 1: + event->position.vx = HavanaFerryData[9]; + event->position.vz = HavanaFerryData[10]; + + event->timer = 1; + + event->node = &HavanaFerryData[10]; + event->data = &HavanaFerryData[6]; + + // [A] reset Ferry angles + event->data[1] = RSIN(CameraCnt * 32) >> 9; + event->data[2] = RCOS(CameraCnt * 16) + 4096 >> 7; + + break; + case 2: + TriggerDoor(&havanaFixed[0], &stage[i], 1); + break; + case 3: + PrepareSecretCar(); + events.cameraEvent = (EVENT*)&havanaFixed[2]; + TriggerDoor(&havanaFixed[2], &stage[i], 0); + break; + case 4: + if (stage[i] != 0) + { + SetSpecialCamera(SPECIAL_CAMERA_WAIT, 0); + event[1].node++; + } - SetMSoundVar(1, &event[1].position); + SetMSoundVar(1, &event[1].position); - event[1].timer = 0; - events.cameraEvent = &event[1]; - } + event[1].timer = 0; + events.cameraEvent = &event[1]; + break; } - else if (GameLevel == 2) + } + else if (GameLevel == 2) // Vegas events + { + switch (i) { - switch (i) - { - case 0: - loop = 0; - - // start train - do { - ev = &event[loop]; - - ev->data = VegasTrainData; - - InitTrain(ev, loop, 1); - - ev->flags |= 0x200; + case 0: + // start train + for (loop = 0; loop < 9; loop++) + { + ev = &event[loop]; - if (loop > 1) - VisibilityLists(VIS_ADD, loop); + ev->data = VegasTrainData; - loop++; - } while (loop < 9); + InitTrain(ev, loop, 1); - event->flags |= 0x500; + ev->flags |= 0x200; - MakeEventTrackable(ev); + if (loop > 1) + VisibilityLists(VIS_ADD, loop); + } - event[1].next = &event[2]; - break; - case 4: - TriggerDoor(&vegasDoor[i - 4], &stage[i], 0); - break; - case 8: - events.cameraEvent = (EVENT*)&vegasDoor[4]; - PrepareSecretCar(); - case 5: - case 6: - case 7: - TriggerDoor(&vegasDoor[i - 4], &stage[i], 1); - break; - case 9: - SetMSoundVar(5, NULL); - } + event->flags |= 0x500; + + MakeEventTrackable(ev); + + event[1].next = &event[2]; + break; + case 4: + TriggerDoor(&vegasDoor[0], &stage[i], 0); + break; + case 5: + case 6: + case 7: + // trigger doors 1-3 + TriggerDoor(&vegasDoor[i - 4], &stage[i], 1); + break; + case 8: + events.cameraEvent = (EVENT*)&vegasDoor[4]; + PrepareSecretCar(); + TriggerDoor(&vegasDoor[4], &stage[i], 1); + break; + case 9: + SetMSoundVar(5, NULL); + break; } - else if (GameLevel == 3) + } + else if (GameLevel == 3) // Rio events + { + switch (i) { - switch (i) - { - case 0: - event->timer = 1; - break; - case 4: - // open race track gates - TriggerDoor(&rioDoor[2], &stage[i], 0); - TriggerDoor(&rioDoor[3], &stage[i], 0); - - events.cameraEvent = (EVENT*)&rioDoor[2]; - break; - case 5: - case 6: - TriggerDoor(&rioDoor[i - 5], &stage[i], (i == 5)); - break; - case 7: - if (stage[i] == 0) - { - pos = &event[1].position; - } - else - { - event[1].position.vy = -17; - event[1].position.vx = -241619; - event[1].position.vz = -212638; - event[1].timer = -2; - event[1].model = HelicopterData.deadModel; - } + case 0: + event->timer = 1; + break; + case 4: + // open race track gates + TriggerDoor(&rioDoor[2], &stage[i], 0); + TriggerDoor(&rioDoor[3], &stage[i], 0); + + events.cameraEvent = (EVENT*)&rioDoor[2]; + break; + case 5: + // police station garage + TriggerDoor(&rioDoor[0], &stage[i], 1); + break; + case 6: + // police station door + TriggerDoor(&rioDoor[1], &stage[i], 0); + break; + case 7: + if (stage[i] == 0) + { + pos = &event[1].position; + } + else + { + event[1].position.vy = -17; + event[1].position.vx = -241619; + event[1].position.vz = -212638; + event[1].timer = -2; + event[1].model = HelicopterData.deadModel; + } - break; - case 8: - // open gate to secret car - PingOutAllSpecialCivCars(); - - TriggerDoor(&rioDoor[4], &stage[i], 0); - TriggerDoor(&rioDoor[5], &stage[i], 0); - - events.cameraEvent = (EVENT*)&rioDoor[4]; - } + break; + case 8: + // open gate to secret car + PingOutAllSpecialCivCars(); + + TriggerDoor(&rioDoor[4], &stage[i], 0); + TriggerDoor(&rioDoor[5], &stage[i], 0); + + events.cameraEvent = (EVENT*)&rioDoor[4]; + break; } } @@ -3773,7 +3779,7 @@ void SetSpecialCamera(SpecialCamera type, int change) if (gCurrentMissionNumber == 15) { boat = boatCamera; - events.cameraEvent = (EVENT*)0x1; + events.cameraEvent = HARDCODED_CAMERA_EVENT; } else { @@ -3802,7 +3808,7 @@ void SetSpecialCamera(SpecialCamera type, int change) if (type != SPECIAL_CAMERA_SET2) { hackCamera = &VegasCameraHack[6]; - events.cameraEvent = (EVENT*)0x1; + events.cameraEvent = HARDCODED_CAMERA_EVENT; } else { @@ -3813,7 +3819,7 @@ void SetSpecialCamera(SpecialCamera type, int change) { hackCamera = &VegasCameraHack[13]; - events.cameraEvent = (EVENT*)0x1; + events.cameraEvent = HARDCODED_CAMERA_EVENT; camera_position.vy = -1800; } else if (gCurrentMissionNumber == 30) @@ -3884,7 +3890,6 @@ int DetonatorTimer(void) static SVECTOR rememberCameraAngle; // offset 0x30 static int count = 0; // offset 0x38 - int cnt; EVENT* ev; VECTOR pos; @@ -3896,7 +3901,12 @@ int DetonatorTimer(void) } else if (detonator.timer <= 30 || detonator.timer >= 40) { - if (detonator.timer == 21) + if (detonator.timer == 0) + { + SetSpecialCamera(SPECIAL_CAMERA_SET, 0); + detonator.timer = 70; + } + else if (detonator.timer == 21) { count++; @@ -3923,16 +3933,11 @@ int DetonatorTimer(void) } else { - detonator.timer = detonator.timer + 1; + detonator.timer++; } player[0].cameraPos.vz = camera_position.vz; } - else if (detonator.timer == 0) - { - SetSpecialCamera(SPECIAL_CAMERA_SET, 0); - detonator.timer = 70; - } else if (detonator.timer == 22) { SetSpecialCamera(SPECIAL_CAMERA_SET2, 0); @@ -3963,55 +3968,49 @@ int DetonatorTimer(void) ev = &firstMissionEvent[1]; ev++; } - else + else if (detonator.timer < 168) { - if (detonator.timer < 168) + if (detonator.timer == 0) { - if (detonator.timer == 0) - { - cnt = detonator.count - 1; - ev = &firstMissionEvent[0]; + ev = &firstMissionEvent[0]; - if (detonator.count < 3) + if (detonator.count < 3) + { + while (--detonator.count != -1) { - while (detonator.count = cnt, detonator.count != -1) - { - AddExplosion(ev->position, BIG_BANG); - cnt = detonator.count - 1; - ev++; - } - - return 0; + AddExplosion(ev->position, BIG_BANG); + ev++; } - detonator.timer = 200; - SetSpecialCamera(SPECIAL_CAMERA_SET, 0); - events.cameraEvent = (EVENT*)0x1; - - rememberCameraAngle = camera_angle; + return 0; } - else if (detonator.timer == 160) - { - if (GameLevel == 3) - { - event->flags &= ~0x1; - event->flags |= 0x20; - - AddExplosion(event[0].position, HEY_MOMMA); - } - else - { - AddExplosion(firstMissionEvent[1].position, HEY_MOMMA); - } + detonator.timer = 200; + SetSpecialCamera(SPECIAL_CAMERA_SET, 0); + events.cameraEvent = HARDCODED_CAMERA_EVENT; + rememberCameraAngle = camera_angle; + } + else if (detonator.timer == 160) + { + if (GameLevel == 3) + { + event->flags &= ~0x1; + event->flags |= 0x20; + AddExplosion(event[0].position, HEY_MOMMA); + } + else + { + AddExplosion(firstMissionEvent[1].position, HEY_MOMMA); } - - detonator.timer--; - return 1; } + detonator.timer--; + return 1; + } + else + { ev = &firstMissionEvent[0]; if (detonator.timer == 180) diff --git a/src_rebuild/Game/C/event.h b/src_rebuild/Game/C/event.h index d91549edf..401f87561 100644 --- a/src_rebuild/Game/C/event.h +++ b/src_rebuild/Game/C/event.h @@ -32,6 +32,8 @@ struct EventGlobal EVENT* cameraEvent; }; +#define HARDCODED_CAMERA_EVENT (EVENT*)0x1 + extern EventGlobal events; extern CELL_OBJECT *EventCop; diff --git a/src_rebuild/Game/C/mission.c b/src_rebuild/Game/C/mission.c index 60ded8833..1af1908c5 100644 --- a/src_rebuild/Game/C/mission.c +++ b/src_rebuild/Game/C/mission.c @@ -1260,7 +1260,7 @@ void HandleTimer(MR_TIMER *timer) if (timer->flags & TIMER_FLAG_BOMB_COUNTDOWN) { - events.cameraEvent = (EVENT*)0x1; + events.cameraEvent = HARDCODED_CAMERA_EVENT; BombThePlayerToHellAndBack(gCarWithABerm); } From 4724a56023d5f007d75b72c2702438db1907d22e Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 5 Aug 2022 06:04:50 -0700 Subject: [PATCH 65/78] Yet ANOTHER missing piece of code for my speedometer..sheesh! --- src_rebuild/Game/C/felony.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src_rebuild/Game/C/felony.c b/src_rebuild/Game/C/felony.c index d8e4b4018..165eb22dd 100644 --- a/src_rebuild/Game/C/felony.c +++ b/src_rebuild/Game/C/felony.c @@ -424,6 +424,8 @@ void CheckPlayerMiscFelonies(void) else limit = (maxSpeed * 3) >> 1; + speedLimits[3] = limit; + if (FIXEDH(cp->hd.wheel_speed) > limit) NoteFelony(&felonyData, 2, 4096); } From e127c58460a4dda40dd69e19c855d80e9525ba27 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 5 Aug 2022 06:08:49 -0700 Subject: [PATCH 66/78] Make the pedestrians be more lively once in awhile! --- src_rebuild/Game/C/gamesnd.c | 3 +++ src_rebuild/Game/C/pedest.c | 47 ++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/src_rebuild/Game/C/gamesnd.c b/src_rebuild/Game/C/gamesnd.c index 9e13db94a..545e9af8c 100644 --- a/src_rebuild/Game/C/gamesnd.c +++ b/src_rebuild/Game/C/gamesnd.c @@ -409,6 +409,9 @@ void LoadLevelSFX(int missionNum) phrase_top = 3; break; } + + // [A] pedestrian sounds + LoadBankFromLump(SOUND_BANK_TANNER, SBK_ID_JONES); switch (missionNum) { diff --git a/src_rebuild/Game/C/pedest.c b/src_rebuild/Game/C/pedest.c index 93cc00085..a6475beda 100644 --- a/src_rebuild/Game/C/pedest.c +++ b/src_rebuild/Game/C/pedest.c @@ -106,6 +106,9 @@ int num_pedestrians; int max_sitter_peds,max_placed_peds; +int ped_speech_timer = 0; +int ped_speech_last = -1; + #ifndef PSX #define MAX_TANNER_PEDS 8 #define NO_MORE_PEDS() (num_pedestrians >= max_placed_peds) @@ -211,6 +214,9 @@ void InitPedestrians(void) memset((u_char*)pedestrians, 0, sizeof(pedestrians)); DestroyPedestrians(); + ped_speech_timer = 0; + ped_speech_last = -1; + max_pedestrians = 28; #ifndef PSX @@ -1948,6 +1954,47 @@ void CivPedJump(LPPEDESTRIAN pPed) pPed->speed *= 2; else if (pPed->frame1 == 14) pPed->speed /= 2; + else if (pPed->frame1 == 1 && pPed->interest != 0) + { + ped_speech_timer -= pPed->interest / 10; + + if (ped_speech_timer < 200) + { + int pitch = 0x1000; + + if (((CameraCnt - frameStart) % 16) == 0) + { + int rand = Random2(0) & 0x3f; + if (rand % 32) + rand = (-rand + (rand & 0x7f)); + pitch -= rand; + } + + int sample = Random2(0) % 5; + + if (sample == 0) + sample = 5; // HEY! + else if ((CameraCnt % sample) == 0) + sample = 6; // DAMN! + else + sample += 7; // WOAH! / WHAT THE!? + + if (sample != ped_speech_last) + { + pitch += ((sample >> 3) * 48); + + Start3DSoundVolPitch(-1, SOUND_BANK_TANNER, sample, pPed->position.vx, pPed->position.vy, pPed->position.vz, -4500, pitch); + + ped_speech_timer = pPed->interest; + ped_speech_last = sample; + } + else + { + // give the next ped a chance to say something + ped_speech_timer = 0; + } + } + } AnimatePed(pPed); From f2e1a9608e64844f064f1b3aba97ed9b371ae6f8 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 5 Aug 2022 06:21:05 -0700 Subject: [PATCH 67/78] [Game:debris] Minor code cleanup and refactoring --- src_rebuild/Game/C/debris.c | 61 ++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 34 deletions(-) diff --git a/src_rebuild/Game/C/debris.c b/src_rebuild/Game/C/debris.c index 5bad604f6..e18e64e89 100644 --- a/src_rebuild/Game/C/debris.c +++ b/src_rebuild/Game/C/debris.c @@ -600,9 +600,7 @@ void PlacePoolForCar(CAR_DATA *cp, CVECTOR *col, int front, int in_car) *(ushort*)&poly->u2 = *(ushort*)&light_pool_texture.coords.u2; *(ushort*)&poly->u3 = *(ushort*)&light_pool_texture.coords.u3; - poly->r0 = col->r / 2; - poly->g0 = col->g / 2; - poly->b0 = col->b / 2; + setRGB0(poly, col->r / 2, col->g / 2, col->b / 2); gte_stsxy3(&poly->x0, &poly->x1, &poly->x2); @@ -1251,10 +1249,8 @@ void DisplayLightReflections(VECTOR* v1, CVECTOR* col, short size, TEXTURE_DETAI poly->tpage = texture->tpageid | 0x20; poly->clut = texture->clutid; - poly->r0 = thiscol.r; - poly->g0 = thiscol.g; - poly->b0 = thiscol.b; - + setRGB0(poly, thiscol.r, thiscol.g, thiscol.b); + addPrim(current->ot + (z >> 4), poly); current->primptr += sizeof(POLY_FT4); } @@ -1319,8 +1315,7 @@ void AddSmallStreetLight(CELL_OBJECT *cop, int x, int y, int z, int type) size = 300; } - count = 0; - for(count = 0; count < 4; count++) + for(count = 0; count < MAX_DAMAGED_LAMPS; count++) { if (dam->index == cop->pos.vx + cop->pos.vz) { @@ -1705,10 +1700,8 @@ void ShowFlare(VECTOR* v1, CVECTOR* col, short size, int rotation) setPolyFT4(poly); setSemiTrans(poly, 1); - poly->r0 = col->r >> 1; - poly->g0 = col->g >> 1; - poly->b0 = col->b >> 1; - + setRGB0(poly, col->r >> 1, col->g >> 1, col->b >> 1); + gte_stsz(&z); if (z >> 3 > 39) @@ -1739,12 +1732,16 @@ void AddTrafficLight(CELL_OBJECT *cop, int x, int y, int z, int flag, int yang) int tempfade; int lDiffAnglesX, lDiffAnglesY; int AbsX, AbsY; + int cy, sy; CVECTOR a, c; VECTOR v1, v2; + cy = RCOS(yang); + sy = RSIN(yang); + v1.vy = (cop->pos.vy - camera_position.vy) + y; - v1.vx = (cop->pos.vx - camera_position.vx) + FIXEDH(RCOS(yang) * x + RSIN(yang) * z); - v1.vz = (cop->pos.vz - camera_position.vz) + FIXEDH(RCOS(yang) * z - RSIN(yang) * x); + v1.vx = (cop->pos.vx - camera_position.vx) + FIXEDH(cy * x + sy * z); + v1.vz = (cop->pos.vz - camera_position.vz) + FIXEDH(cy * z - sy * x); a.cd = 0; @@ -1949,10 +1946,8 @@ void ShowLight1(VECTOR *v1, CVECTOR *col, short size, TEXTURE_DETAILS *texture) setPolyFT4(poly); SetSemiTrans(poly, 1); - poly->r0 = col->r; - poly->g0 = col->g; - poly->b0 = col->b; - + setRGB0(poly, col->r, col->g, col->b); + gte_stsxy3(&poly->x0, &poly->x1, &poly->x2); gte_stsz(&z); @@ -2039,9 +2034,7 @@ void ShowLight(VECTOR *v1, CVECTOR *col, short size, TEXTURE_DETAILS *texture) poly->u3 = texture->coords.u3; poly->v3 = texture->coords.v3; - poly->r0 = col->r; - poly->g0 = col->g; - poly->b0 = col->b; + setRGB0(poly, col->r, col->g, col->b); gte_stsxy3(&poly->x0, &poly->x1, &poly->x2); @@ -2284,10 +2277,8 @@ void ShowGroundLight(VECTOR *v1, CVECTOR *col, short size) poly->tpage = light_texture.tpageid | 0x20; poly->clut = light_texture.clutid;; - poly->r0 = col->r; - poly->g0 = col->g; - poly->b0 = col->b; - + setRGB0(poly, col->r, col->g, col->b); + gte_stsxy3(&poly->x0, &poly->x1, &poly->x2); gte_ldv0(&vert[3]); @@ -2352,10 +2343,8 @@ void RoundShadow(VECTOR *v1, CVECTOR *col, short size) setPolyFT4(poly); setSemiTrans(poly, 1); - poly->r0 = col->r; - poly->g0 = col->g; - poly->b0 = col->b; - + setRGB0(poly, col->r, col->g, col->b); + gte_stsz(&z); if (z - 150 < 9851) @@ -2511,13 +2500,15 @@ void DisplaySpark(SMOKE *spark) { poly->r0 = 0; poly->g0 = (spark->transparency >> 3); - poly->r1 = 0; poly->b0 = (spark->transparency >> 4); + + poly->r1 = 0; poly->g1 = (spark->transparency >> 3); + poly->b1 = (spark->transparency >> 4); + poly->r2 = 12; poly->g2 = 4; poly->b2 = 4; - poly->b1 = (spark->transparency >> 4); } } else @@ -2525,9 +2516,11 @@ void DisplaySpark(SMOKE *spark) poly->r0 = spark->transparency; poly->g0 = spark->transparency; poly->b0 = spark->transparency / 2; + poly->r1 = spark->transparency; poly->g1 = spark->transparency; poly->b1 = spark->transparency / 2; + poly->r2 = spark->transparency; poly->g2 = 0; poly->b2 = 0; @@ -2794,7 +2787,7 @@ void Setup_Smoke(VECTOR *ipos, int start_w, int end_w, int SmokeType, int WheelS mysmoke->drift.vy = 0; mysmoke->drift.vz = 0; - if (mysmoke->life < 40 || SmokeType == 4) + if (mysmoke->life < 40 || SmokeType == SMOKE_FIRE) { mysmoke->drift_change.vx = 0; mysmoke->drift_change.vy = 1; @@ -3063,7 +3056,7 @@ void DisplaySmoke(SMOKE* smoke) } else if (smoke->flags & 0x1000) { - if ((smoke->transparency >> 3) + 50 & 0xff < 60) + if (((smoke->transparency >> 3) + 50 & 0xff) < 60) poly->g0 = (smoke->transparency >> 3); else poly->g0 = smoke->transparency >> 2; From e77f9ba906ae7d3f6ba7614472c619b36120df98 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Fri, 5 Aug 2022 06:23:13 -0700 Subject: [PATCH 68/78] [Game:cars] Just a little code cleanup --- src_rebuild/Game/C/cars.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src_rebuild/Game/C/cars.c b/src_rebuild/Game/C/cars.c index 13c000f76..acb0257f6 100644 --- a/src_rebuild/Game/C/cars.c +++ b/src_rebuild/Game/C/cars.c @@ -96,7 +96,7 @@ void plotCarPolyB3(int numTris, CAR_POLY *src, SVECTOR *vlist, plotCarGlobals *p { int Z; int indices; - u_int FT3rgb; + u_int F3rgb; SVECTOR *v2; SVECTOR *v1; SVECTOR *v0; @@ -104,7 +104,7 @@ void plotCarPolyB3(int numTris, CAR_POLY *src, SVECTOR *vlist, plotCarGlobals *p OTTYPE *ot; prim = (POLY_F3 *)pg->primptr; - FT3rgb = pg->intensity; + F3rgb = pg->intensity | 0x20000000; ot = pg->ot; while (numTris > 0) @@ -124,7 +124,7 @@ void plotCarPolyB3(int numTris, CAR_POLY *src, SVECTOR *vlist, plotCarGlobals *p if (Z > -1) { - *(u_int*)&prim->r0 = FT3rgb | 0x20000000; + *(u_int*)&prim->r0 = F3rgb; gte_stsxy3(&prim->x0, &prim->x1, &prim->x2); From d2f6dcbe1d446e7bcb19e95706d51e6a84906dd4 Mon Sep 17 00:00:00 2001 From: Ilya Shurumov Date: Thu, 1 Sep 2022 00:06:44 +0600 Subject: [PATCH 69/78] - fix rain drops - added RAND macro --- src_rebuild/Game/C/convert.c | 2 +- src_rebuild/Game/C/debris.c | 61 +++++++++++++++++++----------------- src_rebuild/Game/dr2math.h | 2 ++ 3 files changed, 36 insertions(+), 29 deletions(-) diff --git a/src_rebuild/Game/C/convert.c b/src_rebuild/Game/C/convert.c index 25d3f27b0..7545ff56b 100644 --- a/src_rebuild/Game/C/convert.c +++ b/src_rebuild/Game/C/convert.c @@ -163,5 +163,5 @@ extern int frameStart; // [D] [T] int Random2(int step) { - return (CameraCnt - frameStart) * (CameraCnt - frameStart) * 0x19660d + 0x3c6ef35fU >> 8 & 0xffff; + return RAND((CameraCnt - frameStart) * (CameraCnt - frameStart)) >> 8 & 65535; } diff --git a/src_rebuild/Game/C/debris.c b/src_rebuild/Game/C/debris.c index d4e1f93c0..b60cffc12 100644 --- a/src_rebuild/Game/C/debris.c +++ b/src_rebuild/Game/C/debris.c @@ -1778,6 +1778,7 @@ void AddTrafficLight(CELL_OBJECT *cop, int x, int y, int z, int flag, int yang) v2.vx = v1.vx; v2.vz = v1.vz; + v2.vy = v1.vy; v2.vy = -camera_position.vy - MapHeight((VECTOR*)&cop->pos); if (gNight) @@ -3500,43 +3501,49 @@ void DisplaySplashes(void) if (pauseflag != 0) return; - if (gRainCount >> 2 > 30) + SplashNo = gRainCount >> 1; + + if (SplashNo > 30) SplashNo = 30; - else - SplashNo = (gRainCount >> 2); SplashFrac = FIXEDH(SplashNo * FrAng * 3); gte_SetRotMatrix(&identity); // [A] norot CamGnd.vx = camera_position.vx; + CamGnd.vy = camera_position.vy; CamGnd.vz = camera_position.vz; + CamGnd.vy = -camera_position.vy - MapHeight(&CamGnd); ang = FrAng - camera_angle.vy; + + Gnd1.vx = (RSIN(ang) >> 1) + camera_position.vx; + Gnd1.vy = CamGnd.vy; + Gnd1.vz = (RCOS(ang) >> 1) + camera_position.vz; - Gnd1.vx = RSIN(ang) + camera_position.vx; - Gnd1.vz = RCOS(ang) + camera_position.vz; - - Gnd1.vx = Gnd1.vx - CamGnd.vx; - Gnd1.vy = -camera_position.vy - MapHeight(&Gnd1) - CamGnd.vy; - Gnd1.vz = Gnd1.vz - CamGnd.vz; + Gnd1.vy = -camera_position.vy - MapHeight(&Gnd1); + Gnd1.vx -= CamGnd.vx; + Gnd1.vy -= CamGnd.vy; + Gnd1.vz -= CamGnd.vz; ang = -FrAng - camera_angle.vy; - Gnd2.vx = RSIN(ang) + camera_position.vx; - Gnd2.vz = RCOS(ang) + camera_position.vz; + Gnd2.vx = (RSIN(ang) >> 1) + camera_position.vx; + Gnd2.vy = CamGnd.vy; + Gnd2.vz = (RCOS(ang) >> 1) + camera_position.vz; - Gnd2.vx = Gnd2.vx - CamGnd.vx; - Gnd2.vy = (-camera_position.vy - MapHeight(&Gnd2)) - CamGnd.vy; - Gnd2.vz = Gnd2.vz - CamGnd.vz; + Gnd2.vy = -camera_position.vy - MapHeight(&Gnd2); + Gnd2.vx -= CamGnd.vx; + Gnd2.vy -= CamGnd.vy; + Gnd2.vz -= CamGnd.vz; while (--SplashFrac >= 0) { - d2 = rand * 0x19660d + 0x3c6ef35f; - d1 = d2 >> 4 & 0xfff; - rand = d2 * 0x19660d + 0x3c6ef35f; - d2 = rand >> 0xe & 0xfff; + d2 = RAND(rand); + d1 = d2 >> 4 & 4095; + rand = RAND(d2); + d2 = rand >> 14 & 4095; Position.vx = FIXEDH(Gnd1.vx * d1 + Gnd2.vx * d2); Position.vy = FIXEDH(Gnd1.vy * d1 + Gnd2.vy * d2) + CamGnd.vy; @@ -3610,7 +3617,6 @@ void DrawRainDrops(void) RainPtr->position.vy += RAIN_DROP_SPEED; RainPtr->position.vx -= drift.vx * 2; RainPtr->position.vz -= drift.vz * 2; - *(u_int *)&poly->x0 = *(u_int *)&RainPtr->oldposition; } @@ -3653,10 +3659,9 @@ void DrawRainDrops(void) else *(u_int *)&RainPtr->oldposition = *(u_int *)&poly->x2; } - else + else if (pauseflag == 0) { - if(pauseflag == 0) - ReleaseRainDrop(RainPtr->oldposition.pad); + ReleaseRainDrop(RainPtr->oldposition.pad); } RainPtr++; @@ -3705,14 +3710,14 @@ void AddRainDrops(void) if (RainIndex < 0) return; - tmp = rand * 0x19660d + 0x3c6ef35f; - v.vz = (tmp >> 0x14 & 0x1ffU) + 400; + tmp = RAND(rand); + v.vz = (tmp >> 20 & 511) + 400; - tmp = tmp * 0x19660d + 0x3c6ef35f; - v.vy = -((tmp >> 0x14) & 0x1ff); + tmp = RAND(tmp); + v.vy = -((tmp >> 20) & 511); - rand = tmp * 0x19660d + 0x3c6ef35f; - v.vx = ((rand >> 0x14) & 0x1ff) - 256; + rand = RAND(tmp); + v.vx = ((rand >> 20) & 511) - 256; if (v.vz > 512) { diff --git a/src_rebuild/Game/dr2math.h b/src_rebuild/Game/dr2math.h index 6e005886c..eb1567dec 100644 --- a/src_rebuild/Game/dr2math.h +++ b/src_rebuild/Game/dr2math.h @@ -39,6 +39,8 @@ extern short rcossin_tbl[8192]; #define isin(a) (rcossin_tbl[( ( a ) & 4095) * 2]) #define icos(a) (rcossin_tbl[((( a )+1024) & 4095) * 2]) +#define RAND(seed) ((seed) * 0x19660D + 0x3C6EF35F) + #define DIFF_ANGLES_R( A, B, RANGE ) \ (((((B) - (A)) + (RANGE>>1)) & RANGE-1) - (RANGE>>1)) From 06e669baec171de57c316eb85e9117c474e32033 Mon Sep 17 00:00:00 2001 From: Ilya Shurumov Date: Tue, 13 Sep 2022 20:48:25 +0600 Subject: [PATCH 70/78] - SetUpCivCollFlags regression fix causing height check to skip --- src_rebuild/Game/C/civ_ai.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src_rebuild/Game/C/civ_ai.c b/src_rebuild/Game/C/civ_ai.c index f78acb306..cddddb8bb 100644 --- a/src_rebuild/Game/C/civ_ai.c +++ b/src_rebuild/Game/C/civ_ai.c @@ -2943,7 +2943,7 @@ void SetUpCivCollFlags(void) if (ABS(cd[0].x.vx - cd[1].x.vx) >= dist || ABS(cd[0].x.vz - cd[1].x.vz) >= dist || - isTanner && ABS(cd[0].x.vy - cd[1].x.vy) >= 500) + ABS(cd[0].x.vy - cd[1].x.vy) >= 500) { continue; } From 49c37ee4d39f920607dc15e98538cf318a727488 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Tue, 13 Sep 2022 03:08:52 -0700 Subject: [PATCH 71/78] Fixed some compiler errors :P --- src_rebuild/Game/C/pedest.c | 2 +- src_rebuild/Game/reversing.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src_rebuild/Game/C/pedest.c b/src_rebuild/Game/C/pedest.c index a6475beda..12c1d891c 100644 --- a/src_rebuild/Game/C/pedest.c +++ b/src_rebuild/Game/C/pedest.c @@ -1282,7 +1282,7 @@ void SetupGetInCar(LPPEDESTRIAN pPed) // HEY! CreatePedAtLocation(&pos, 8); - Start3DSoundVolPitch(-1, SOUND_BANK_TANNER, sample, pos[0], pos[1], pos[2], 0, 4096); + Start3DSoundVolPitch(-1, SOUND_BANK_TANNER, 5, pos[0], pos[1], pos[2], 0, 4096); carToGetIn->controlFlags |= CONTROL_FLAG_WAS_PARKED; } diff --git a/src_rebuild/Game/reversing.h b/src_rebuild/Game/reversing.h index 09ed9489a..c6a3fa824 100644 --- a/src_rebuild/Game/reversing.h +++ b/src_rebuild/Game/reversing.h @@ -16,6 +16,9 @@ #define M_BIT(x) (1 << (x)) +// makes RGB int out of three bytes +#define M_INT_RGB(r,g,b) (((r) << 16) | ((g) << 8) | (b)) + //--------------------------------------- #if !defined( __TYPEINFOGEN__ ) && !defined( _lint ) && defined(_WIN32) // pcLint has problems with assert_offsetof() From f62a2b6db4c4304f60de37033d8e08dc16b27488 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Sat, 10 Sep 2022 14:22:53 -0700 Subject: [PATCH 72/78] [Game:mission] Fixed a code refactoring bug where chase hits were never registered. --- src_rebuild/Game/C/mission.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src_rebuild/Game/C/mission.c b/src_rebuild/Game/C/mission.c index 1af1908c5..19a6ac0e6 100644 --- a/src_rebuild/Game/C/mission.c +++ b/src_rebuild/Game/C/mission.c @@ -1280,7 +1280,7 @@ void HandleTimer(MR_TIMER *timer) // [D] [T] void RegisterChaseHit(int car1, int car2) { - if (!Mission.ChaseTarget || Mission.ChaseHitDelay == 0) + if (!Mission.ChaseTarget || Mission.ChaseHitDelay != 0) return; int player_id; From 6de91adce7889ac68169a7f74700dcf823c22dac Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Tue, 13 Sep 2022 03:12:17 -0700 Subject: [PATCH 73/78] [Game:mission] Fixed a bug where palettes get overridden by mistake. --- src_rebuild/Game/C/mission.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src_rebuild/Game/C/mission.c b/src_rebuild/Game/C/mission.c index 19a6ac0e6..a58f3c3b9 100644 --- a/src_rebuild/Game/C/mission.c +++ b/src_rebuild/Game/C/mission.c @@ -383,7 +383,7 @@ void SetupResidentModels() // force palette if (singlePal) PlayerStartInfo[i]->palette = 0; - else + else if (wantedColour[i] != -1) PlayerStartInfo[i]->palette = wantedColour[i]; // store for replay if necessary From d790f3df4a7d3759ae3d741431c78468c5208695 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Tue, 13 Sep 2022 03:13:05 -0700 Subject: [PATCH 74/78] [Game:overmap] Fix speedometer overlap in minigames. --- src_rebuild/Game/C/overmap.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src_rebuild/Game/C/overmap.c b/src_rebuild/Game/C/overmap.c index b406f23ed..729e60311 100644 --- a/src_rebuild/Game/C/overmap.c +++ b/src_rebuild/Game/C/overmap.c @@ -1001,7 +1001,12 @@ void DrawMultiplayerMap(void) map_z_offset = 0; xPos = gMapXOffset; +#ifndef PSX + // [A] add room for speedometer + yPos = gMapYOffset - 4; +#else yPos = gMapYOffset; +#endif DrawMultiplayerTargets(); From 4abcb60dfddbde81df7bc09516215381b6066388 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Tue, 13 Sep 2022 03:15:20 -0700 Subject: [PATCH 75/78] [Game:motion_c] Fixed OTHER_SPRITE's using TannerShadow by mistake. --- src_rebuild/Game/C/motion_c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src_rebuild/Game/C/motion_c.c b/src_rebuild/Game/C/motion_c.c index 7d04e64a2..0d201470f 100644 --- a/src_rebuild/Game/C/motion_c.c +++ b/src_rebuild/Game/C/motion_c.c @@ -1719,7 +1719,7 @@ int DrawCharacter(LPPEDESTRIAN pPed) if (pUsedPeds->pNext == NULL && pPed->pedType == TANNER_MODEL) #else // draw a nice shadow for non-civilian peds :) - if (pPed->pedType != CIVILIAN) + if (pPed->pedType == TANNER_MODEL || pPed->pedType == OTHER_MODEL) #endif { v.vx = (pPed->position.vx - camera_position.vx) + Skel[ROOT].pvOrigPos->vx; From 27a099952b510144477cf72f3b0e00b205720e1e Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Tue, 13 Sep 2022 03:30:49 -0700 Subject: [PATCH 76/78] [Game:event] Disabled testing stuff for user event threads. --- src_rebuild/Game/C/event.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src_rebuild/Game/C/event.c b/src_rebuild/Game/C/event.c index c8ad7ea2e..efbcdb3df 100644 --- a/src_rebuild/Game/C/event.c +++ b/src_rebuild/Game/C/event.c @@ -4324,8 +4324,8 @@ int StopUserMissionEvents(MR_THREAD *thread) int RunUserMissionEvents(MR_THREAD *thread) { - if (gCurrentMissionNumber >= 50 && gCurrentMissionNumber <= 65) - maxCopCars = 32; + //if (gCurrentMissionNumber >= 50 && gCurrentMissionNumber <= 65) + // maxCopCars = 32; return (*fnMissionEventHandlers)[GameLevel](thread, 0); } From 761e6bf27c536f4063be7b70f479c1ab5f86f816 Mon Sep 17 00:00:00 2001 From: Fireboyd78 Date: Tue, 13 Sep 2022 03:29:06 -0700 Subject: [PATCH 77/78] Improved fixes for wibbly wobbly cars. --- src_rebuild/Game/C/handling.c | 23 +++++++++++++++++--- src_rebuild/Game/C/wheelforces.c | 37 ++++++-------------------------- 2 files changed, 27 insertions(+), 33 deletions(-) diff --git a/src_rebuild/Game/C/handling.c b/src_rebuild/Game/C/handling.c index 19db7207c..18701451c 100644 --- a/src_rebuild/Game/C/handling.c +++ b/src_rebuild/Game/C/handling.c @@ -262,10 +262,11 @@ void FixCarCos(CAR_COSMETICS* carCos, int externalModelNumber) car_cosmetics[2].mass *= 3; } - // [A] vegas box truck - if (GameLevel == 2 && externalModelNumber == 10) + // [A] wibbly wobbly fuckery hacks... + // flag certain cars that have a tendency to go CRAZY at a stand-still + if (GameLevel == 2 && externalModelNumber == 10) // vegas box truck { - carCos->extraInfo |= 4; // wibbly wobbly fuckery hack... + carCos->extraInfo |= 4; } } @@ -334,6 +335,22 @@ void GlobalTimeStep(void) st = &cp->st; + // [A] bugfix: wibbly wobbly cars + // (see end of FixCarCos for cars that have this flag) + if (car_cosmetics[cp->ap.model].extraInfo & 4) + { + if (cp->handbrake && cp->wasOnGround && cp->hd.speed < 3) + { + cp->hd.aacc[0] >>= 1; + cp->hd.aacc[1] >>= 1; + cp->hd.aacc[2] >>= 1; + + cp->hd.acc[0] >>= 1; + cp->hd.acc[1] >>= 1; + cp->hd.acc[2] >>= 1; + } + } + st->n.linearVelocity[0] += cp->hd.acc[0]; st->n.linearVelocity[1] += cp->hd.acc[1]; st->n.linearVelocity[2] += cp->hd.acc[2]; diff --git a/src_rebuild/Game/C/wheelforces.c b/src_rebuild/Game/C/wheelforces.c index 84f5d4fb5..a87e7d907 100644 --- a/src_rebuild/Game/C/wheelforces.c +++ b/src_rebuild/Game/C/wheelforces.c @@ -213,12 +213,15 @@ void AddWheelForcesDriver1(CAR_DATA* cp, CAR_LOCALS* cl) int player_id; int oldCutRoughness; - oldSpeed = cp->hd.speed * 3 >> 1; + // NB: skips precision every 3rd increment or so + int speed = cp->hd.speed * 3 >> 1; - if (oldSpeed < 32) - oldSpeed = oldSpeed * -72 + 3696; + if (speed < 32) + oldSpeed = 4096 - (72 * speed); else - oldSpeed = 1424 - oldSpeed; + oldSpeed = 1824 - speed; + + oldSpeed -= 400; dir = cp->hd.direction; cdx = RSIN(dir); @@ -528,32 +531,6 @@ void AddWheelForcesDriver1(CAR_DATA* cp, CAR_LOCALS* cl) else { cp->hd.wheel_speed = cdz / 64 * (cl->vel[2] / 64) + cdx / 64 * (cl->vel[0] / 64); - - // [A] wibbly wobbly fuckery hack... - if (car_cos->extraInfo & 4) - { - if (cp->thrust == 0 && cp->handbrake && (cp->hd.speed > 0 && cp->hd.speed < 4)) - { - cp->hd.speed--; - cp->hd.wheel_speed >>= 1; - - cp->hd.acc[0] >>= 1; - cp->hd.acc[1] >>= 1; - cp->hd.acc[2] >>= 1; - - cp->hd.aacc[0] >>= 2; - cp->hd.aacc[1] >>= 2; - cp->hd.aacc[2] >>= 2; - - //cp->st.n.linearVelocity[0] >>= 1; - //cp->st.n.linearVelocity[1] >>= 1; - //cp->st.n.linearVelocity[2] >>= 1; - - cp->st.n.angularVelocity[0] >>= 2; - cp->st.n.angularVelocity[1] >>= 2; - cp->st.n.angularVelocity[2] >>= 2; - } - } } } From 475e610e7ee6ea41054109ee1f59709a80f38597 Mon Sep 17 00:00:00 2001 From: SoapyMan Date: Fri, 21 Apr 2023 22:40:57 +0600 Subject: [PATCH 78/78] - support locale for Game graphics options menu --- data/DRIVER2/LANG/EN_GAME.LTXT | 21 ++++++++++++ data/DRIVER2/LANG/FR_GAME.LTXT | 21 ++++++++++++ data/DRIVER2/LANG/GE_GAME.LTXT | 22 ++++++++++++- data/DRIVER2/LANG/IT_GAME.LTXT | 21 ++++++++++++ data/DRIVER2/LANG/SP_GAME.LTXT | 21 ++++++++++++ src_rebuild/Game/Frontend/FEmain.c | 51 ++++++++++++++---------------- src_rebuild/Game/dr2locale.h | 26 ++++++++++++++- 7 files changed, 154 insertions(+), 29 deletions(-) diff --git a/data/DRIVER2/LANG/EN_GAME.LTXT b/data/DRIVER2/LANG/EN_GAME.LTXT index 3cef42942..ae391917b 100644 --- a/data/DRIVER2/LANG/EN_GAME.LTXT +++ b/data/DRIVER2/LANG/EN_GAME.LTXT @@ -104,3 +104,24 @@ Night Clear Rainy Wet +Color +Details +FullScreen +VSync +PGXP +Texture Filter +Draw Distance +Dynamic Lights +Traffic Density +Peds Density +Low +Medium +High +Ultra +Off +On +Textures Only +ZBuffer Only +All +Reset to Default +Custom \ No newline at end of file diff --git a/data/DRIVER2/LANG/FR_GAME.LTXT b/data/DRIVER2/LANG/FR_GAME.LTXT index 7c705b489..60c77ef55 100644 --- a/data/DRIVER2/LANG/FR_GAME.LTXT +++ b/data/DRIVER2/LANG/FR_GAME.LTXT @@ -104,3 +104,24 @@ Nuit Dégager Pluvieux Mouiller +Color +Details +FullScreen +VSync +PGXP +TextureFilter +DrawDistance +DynamicLights +TrafficDensity +PedsDensity +Low +Medium +High +Ultra +Off +On +TexturesOnly +ZBufferOnly +All +ResetToDefault +Custom \ No newline at end of file diff --git a/data/DRIVER2/LANG/GE_GAME.LTXT b/data/DRIVER2/LANG/GE_GAME.LTXT index a4b654774..95777452b 100644 --- a/data/DRIVER2/LANG/GE_GAME.LTXT +++ b/data/DRIVER2/LANG/GE_GAME.LTXT @@ -104,4 +104,24 @@ Nacht klar Regnerisch Nass - +Color +Details +FullScreen +VSync +PGXP +TextureFilter +DrawDistance +DynamicLights +TrafficDensity +PedsDensity +Low +Medium +High +Ultra +Off +On +TexturesOnly +ZBufferOnly +All +ResetToDefault +Custom \ No newline at end of file diff --git a/data/DRIVER2/LANG/IT_GAME.LTXT b/data/DRIVER2/LANG/IT_GAME.LTXT index 743ffa01c..659ce6990 100644 --- a/data/DRIVER2/LANG/IT_GAME.LTXT +++ b/data/DRIVER2/LANG/IT_GAME.LTXT @@ -104,3 +104,24 @@ Notte Sereno Piovoso Bagnato +Color +Details +FullScreen +VSync +PGXP +TextureFilter +DrawDistance +DynamicLights +TrafficDensity +PedsDensity +Low +Medium +High +Ultra +Off +On +TexturesOnly +ZBufferOnly +All +ResetToDefault +Custom \ No newline at end of file diff --git a/data/DRIVER2/LANG/SP_GAME.LTXT b/data/DRIVER2/LANG/SP_GAME.LTXT index 15512eb13..ed0c387d2 100644 --- a/data/DRIVER2/LANG/SP_GAME.LTXT +++ b/data/DRIVER2/LANG/SP_GAME.LTXT @@ -104,3 +104,24 @@ Noche Claro Lluvioso Mojado +Color +Details +FullScreen +VSync +PGXP +TextureFilter +DrawDistance +DynamicLights +TrafficDensity +PedsDensity +Low +Medium +High +Ultra +Off +On +TexturesOnly +ZBufferOnly +All +ResetToDefault +Custom \ No newline at end of file diff --git a/src_rebuild/Game/Frontend/FEmain.c b/src_rebuild/Game/Frontend/FEmain.c index 472e24aad..83287df4e 100644 --- a/src_rebuild/Game/Frontend/FEmain.c +++ b/src_rebuild/Game/Frontend/FEmain.c @@ -961,18 +961,18 @@ void SetVariable(int var, int &action) case VAR_CHOOSE_TYPE: // [A] chooser type { static char* ChooseQualityItems[] = { - "Low", - "Medium", - "High", - "Ultra", + G_LTXT(GTXT_Low), + G_LTXT(GTXT_Medium), + G_LTXT(GTXT_High), + G_LTXT(GTXT_Ultra), NULL, }; static char* ChoosePGXPItems[] = { - "Disabled", - "Textures only", - "ZBuffer only", - "Enabled", + G_LTXT(GTXT_Off), + G_LTXT(GTXT_TexturesOnly), + G_LTXT(GTXT_ZBufferOnly), + G_LTXT(GTXT_All), NULL, }; @@ -1251,7 +1251,8 @@ void DisplayOnScreenText(void) text = "Please insert controller into Port 1"; transparent = 1; } - else { + else + { if (Pads[0].type != 1) return; @@ -1306,7 +1307,7 @@ void DisplayOnScreenText(void) CVECTOR *col = &debris_colour[GameLevel][car_colour]; - FEPrintString("Color", btn->x + 190, btn->y + 270, 4, 128, 128, 128); + FEPrintString(G_LTXT(GTXT_Color), btn->x + 190, btn->y + 270, 4, 128, 128, 128); POLY_F4 *f4 = (POLY_F4*)current->primptr; current->primptr += sizeof(POLY_F4); @@ -1750,14 +1751,14 @@ void InitDetailsScreen(FE_SCREEN *screen) }; static char *ButtonNames[] = { - "FullScreen", - "VSync", - "PGXP", - "Texture Filter", - "Draw Distance", - "Dynamic Lights", - "Traffic Density", - "Peds Density", + G_LTXT(GTXT_FullScreen), + G_LTXT(GTXT_VSync), + G_LTXT(GTXT_PGXP), + G_LTXT(GTXT_TextureFilter), + G_LTXT(GTXT_DrawDistance), + G_LTXT(GTXT_DynamicLights), + G_LTXT(GTXT_TrafficDensity), + G_LTXT(GTXT_PedsDensity), }; int numButtons = BuildButtonsVertical(screen, 8, 156, 190); @@ -1765,13 +1766,9 @@ void InitDetailsScreen(FE_SCREEN *screen) for (int i = 0; i < numButtons; i++) { FE_BUTTON& btn = screen->buttons[i]; - int type = ButtonTypeMap[i]; - char *name = ButtonNames[i]; - - int index = ButtonScreenMap[i]; - strcpy(btn.Name, name); + strcpy(btn.Name, ButtonNames[i]); if (type < 0) { @@ -1780,7 +1777,7 @@ void InitDetailsScreen(FE_SCREEN *screen) } else { - btn.action = FE_MAKEVAR(BTN_NEXT_SCREEN, index); + btn.action = FE_MAKEVAR(BTN_NEXT_SCREEN, ButtonScreenMap[i]); } btn.var = FE_MAKEVAR(VAR_CHOOSE_TYPE, type); @@ -1813,7 +1810,7 @@ void InitCustomScreens() InitDetailsScreen(&PsxScreens[Sc_DetailOptions]); // insert link in Options - InsertButtonVertical(&PsxScreens[Sc_Options], 2, "Details"); + InsertButtonVertical(&PsxScreens[Sc_Options], 2, G_LTXT(GTXT_Details)); FE_BUTTON &btn = PsxScreens[Sc_Options].buttons[2]; @@ -4851,7 +4848,7 @@ int ChooseOptionScreen(int bSetup) if (value >= 0) { - extraBtn = InsertButtonVertical(pCurrScreen, numButtons, "Custom"); + extraBtn = InsertButtonVertical(pCurrScreen, numButtons, G_LTXT(GTXT_Custom)); if (extraBtn != NULL) { @@ -4874,7 +4871,7 @@ int ChooseOptionScreen(int bSetup) if (defaultValue >= 0) { - resetBtn = InsertButtonVertical(pCurrScreen, numButtons, "Reset to Default"); + resetBtn = InsertButtonVertical(pCurrScreen, numButtons, G_LTXT(GTXT_ResetToDefault)); if (resetBtn != NULL) { diff --git a/src_rebuild/Game/dr2locale.h b/src_rebuild/Game/dr2locale.h index 6653f7d43..f3691dc62 100644 --- a/src_rebuild/Game/dr2locale.h +++ b/src_rebuild/Game/dr2locale.h @@ -126,7 +126,31 @@ enum GameStrId GTXT_Clear, GTXT_Rainy, - GTXT_Wet + GTXT_Wet, + + GTXT_Color, + + GTXT_Details, + GTXT_FullScreen, + GTXT_VSync, + GTXT_PGXP, + GTXT_TextureFilter, + GTXT_DrawDistance, + GTXT_DynamicLights, + GTXT_TrafficDensity, + GTXT_PedsDensity, + + GTXT_Low, + GTXT_Medium, + GTXT_High, + GTXT_Ultra, + GTXT_Off, + GTXT_On, + GTXT_TexturesOnly, + GTXT_ZBufferOnly, + GTXT_All, + GTXT_ResetToDefault, + GTXT_Custom }; enum MissionStrId