From ec1d14971c9bb1d751c0256093483d621dd719b8 Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Wed, 27 May 2020 00:25:12 +0300 Subject: [PATCH 01/26] mission replay --- src/control/GameLogic.cpp | 26 +++++- src/control/Script.cpp | 147 ++++++++++++++++++++++++++++++++ src/control/Script.h | 19 +++++ src/core/Frontend.cpp | 19 +++++ src/core/Frontend.h | 6 +- src/core/MenuScreens.h | 10 ++- src/core/Pools.cpp | 43 ++++++++++ src/core/config.h | 2 + src/save/GenericGameStorage.cpp | 45 ++++++++++ src/save/GenericGameStorage.h | 8 +- src/save/PCSave.cpp | 5 +- 11 files changed, 325 insertions(+), 5 deletions(-) diff --git a/src/control/GameLogic.cpp b/src/control/GameLogic.cpp index abb5c5f3..ae26dd05 100644 --- a/src/control/GameLogic.cpp +++ b/src/control/GameLogic.cpp @@ -83,12 +83,20 @@ CGameLogic::Update() } break; case WBSTATE_WASTED: +#ifdef MISSION_REPLAY + if ((CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > AddExtraDeathDelay() + 0x800) && (CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= AddExtraDeathDelay() + 0x800)) { +#else if ((CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800) && (CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800)) { +#endif TheCamera.SetFadeColour(200, 200, 200); TheCamera.Fade(2.0f, FADE_OUT); } +#ifdef MISSION_REPLAY + if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= AddExtraDeathDelay() + 0x1000) { +#else if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) { +#endif pPlayerInfo.m_WBState = WBSTATE_PLAYING; if (pPlayerInfo.m_bGetOutOfHospitalFree) { pPlayerInfo.m_bGetOutOfHospitalFree = false; @@ -131,11 +139,19 @@ CGameLogic::Update() } break; case WBSTATE_BUSTED: +#ifdef MISSION_REPLAY + if ((CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > AddExtraDeathDelay() + 0x800) && (CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= AddExtraDeathDelay() + 0x800)) { +#else if ((CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800) && (CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800)) { +#endif TheCamera.SetFadeColour(0, 0, 0); TheCamera.Fade(2.0f, FADE_OUT); } +#ifdef MISSION_REPLAY + if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= AddExtraDeathDelay() + 0x1000) { +#else if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) { +#endif pPlayerInfo.m_WBState = WBSTATE_PLAYING; int takeMoney; @@ -203,11 +219,19 @@ CGameLogic::Update() } break; case WBSTATE_FAILED_CRITICAL_MISSION: - if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800 && CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800) { +#ifdef MISSION_REPLAY + if ((CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > AddExtraDeathDelay() + 0x800) && (CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= AddExtraDeathDelay() + 0x800)) { +#else + if ((CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800) && (CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800)) { +#endif TheCamera.SetFadeColour(0, 0, 0); TheCamera.Fade(2.0f, FADE_OUT); } +#ifdef MISSION_REPLAY + if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= AddExtraDeathDelay() + 0x1000) { +#else if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) { +#endif pPlayerInfo.m_WBState = WBSTATE_PLAYING; if (pPlayerInfo.m_pPed->bInVehicle) { CVehicle *pVehicle = pPlayerInfo.m_pPed->m_pMyVehicle; diff --git a/src/control/Script.cpp b/src/control/Script.cpp index 406b11b7..549f53ad 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -28,6 +28,9 @@ #include "Gangs.h" #include "Garages.h" #include "General.h" +#ifdef MISSION_REPLAY +#include "GenericGameStorage.h" +#endif #include "HandlingMgr.h" #include "Heli.h" #include "Hud.h" @@ -128,6 +131,38 @@ uint16 CTheScripts::CommandsExecuted; uint16 CTheScripts::ScriptsUpdated; int32 ScriptParams[32]; +#ifdef MISSION_REPLAY + +static const char* nonMissionScripts[] = { + "copcar", + "ambulan", + "taxi", + "firetru", + "rampage", + "t4x4_1", + "t4x4_2", + "t4x4_3", + "rc1", + "rc2", + "rc3", + "rc4", + "hj", + "usj", + "mayhem" +}; + +int AllowMissionReplay; +uint32 NextMissionDelay; +uint32 MissionStartTime; +uint32 WaitForMissionActivate; +uint32 WaitForSave; +float oldTargetX; +float oldTargetY; +int missionRetryScriptIndex; +bool doingMissionRetry; + +#endif + const uint32 CRunningScript::nSaveStructSize = #ifdef COMPATIBLE_SAVES @@ -666,6 +701,41 @@ void CTheScripts::Process() if (UseTextCommands == 1) UseTextCommands = 0; } + +#ifdef MISSION_REPLAY + static uint32 TimeToWaitTill; + switch (AllowMissionReplay) { + case 2: + AllowMissionReplay = 3; + TimeToWaitTill = CTimer::GetTimeInMilliseconds() + (AddExtraDeathDelay() > 1000 ? 4000 : 2500); + break; + case 3: + if (TimeToWaitTill < CTimer::GetTimeInMilliseconds()) + AllowMissionReplay = 4; + break; + case 4: + AllowMissionReplay = 5; + RetryMission(0, 0); + case 6: + AllowMissionReplay = 7; + TimeToWaitTill = CTimer::GetTimeInMilliseconds() + 500; + case 7: + if (TimeToWaitTill < CTimer::GetTimeInMilliseconds()) { + AllowMissionReplay = 0; + return; + } + break; + } + if (WaitForMissionActivate) { + if (WaitForMissionActivate > CTimer::GetTimeInMilliseconds()) + return; + WaitForMissionActivate = 0; + WaitForSave = CTimer::GetTimeInMilliseconds() + 3000; + } + if (WaitForSave && WaitForSave > CTimer::GetTimeInMilliseconds()) + WaitForSave = 0; +#endif + CRunningScript* script = pActiveScripts; while (script != nil){ CRunningScript* next = script->GetNext(); @@ -1239,6 +1309,17 @@ int8 CRunningScript::ProcessCommands0To99(int32 command) CTheScripts::bAlreadyRunningAMissionScript = false; RemoveScriptFromList(&CTheScripts::pActiveScripts); AddScriptToList(&CTheScripts::pIdleScripts); +#ifdef MISSION_REPLAY + if (m_bMissionFlag) { + CPlayerInfo* pPlayerInfo = &CWorld::Players[CWorld::PlayerInFocus]; + if (pPlayerInfo->m_pPed->GetPedState() != PED_DEAD && pPlayerInfo->m_WBState == WBSTATE_PLAYING && !m_bDeatharrestExecuted) + SaveGameForPause(1); + oldTargetX = oldTargetY = 0.0f; + if (AllowMissionReplay == 1) + AllowMissionReplay = 2; + // I am fairly sure they forgot to set return value here + } +#endif return 1; case COMMAND_START_NEW_SCRIPT: { @@ -2149,7 +2230,14 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) CollectParameters(&m_nIp, 2); CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); assert(car); +#if defined MISSION_REPLAY && defined SIMPLIER_MISSIONS + car->AutoPilot.m_nCruiseSpeed = *(float*)&ScriptParams[1]; + if (missionRetryScriptIndex == 40 && car->GetModelIndex() == MI_CHEETAH) // Turismo + car->AutoPilot.m_nCruiseSpeed = 8 * car->AutoPilot.m_nCruiseSpeed / 10; + car->AutoPilot.m_nCruiseSpeed = Min(car->AutoPilot.m_nCruiseSpeed, 60.0f * car->pHandling->Transmission.fUnkMaxVelocity); +#else car->AutoPilot.m_nCruiseSpeed = Min(*(float*)&ScriptParams[1], 60.0f * car->pHandling->Transmission.fUnkMaxVelocity); +#endif return 0; } case COMMAND_SET_CAR_DRIVING_STYLE: @@ -2219,6 +2307,10 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) case COMMAND_PRINT_BIG: { wchar* key = TheText.Get((char*)&CTheScripts::ScriptSpace[m_nIp]); +#ifdef MISSION_REPLAY + if (strcmp((char*)&CTheScripts::ScriptSpace[m_nIp], "M_FAIL") == 0 && CanAllowMissionReplay()) + AllowMissionReplay = 1; +#endif m_nIp += KEY_LENGTH_IN_SCRIPT; CollectParameters(&m_nIp, 2); CMessages::AddBigMessage(key, ScriptParams[0], ScriptParams[1] - 1); @@ -8479,6 +8571,10 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) case COMMAND_MAKE_PLAYER_SAFE_FOR_CUTSCENE: { CollectParameters(&m_nIp, 1); +#ifdef MISSION_REPLAY + AllowMissionReplay = 0; + SaveGameForPause(3); +#endif CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]]; CPad::GetPad(ScriptParams[0])->DisablePlayerControls |= PLAYERCONTROL_DISABLED_80; pPlayerInfo->MakePlayerSafe(true); @@ -8685,6 +8781,11 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) case COMMAND_LOAD_AND_LAUNCH_MISSION_INTERNAL: { CollectParameters(&m_nIp, 1); +#ifdef MISSION_REPLAY + missionRetryScriptIndex = ScriptParams[0]; + if (missionRetryScriptIndex == 19) + CStats::LastMissionPassedName[0] = '\0'; +#endif CTimer::Suspend(); int offset = CTheScripts::MultiScriptArray[ScriptParams[0]]; CFileMgr::ChangeDir("\\"); @@ -11074,6 +11175,12 @@ void CRunningScript::DoDeatharrestCheck() CPlayerInfo* pPlayer = &CWorld::Players[CWorld::PlayerInFocus]; if (!pPlayer->IsRestartingAfterDeath() && !pPlayer->IsRestartingAfterArrest() && !CTheScripts::UpsideDownCars.AreAnyCarsUpsideDown()) return; +#ifdef MISSION_REPLAY + if (AllowMissionReplay != 0) + return; + if (CanAllowMissionReplay()) + AllowMissionReplay = 1; +#endif assert(m_nStackPointer > 0); while (m_nStackPointer > 1) --m_nStackPointer; @@ -11755,3 +11862,43 @@ void CRunningScript::Load(uint8*& buf) prev = p; #endif } + +#ifdef MISSION_REPLAY + +bool CRunningScript::CanAllowMissionReplay() +{ + if (AllowMissionReplay) + return false; + if (CStats::LastMissionPassedName[0] == '\0') + return false; + for (int i = 0; i < ARRAY_SIZE(nonMissionScripts); i++) { + if (strcmp(m_abScriptName, nonMissionScripts[i]) == 0) + return false; + } + return true; +} + +uint32 AddExtraDeathDelay() +{ + if (missionRetryScriptIndex == 63) + return 7000; + if (missionRetryScriptIndex == 64) + return 4000; + return 1000; +} + +void RetryMission(int type, int unk) +{ + if (type == 0) { + doingMissionRetry = true; + FrontEndMenuManager.m_nCurrScreen = MENUPAGE_MISSION_RETRY; + FrontEndMenuManager.RequestFrontEndStartUp(); + } + else if (type == 2) { + doingMissionRetry = false; + AllowMissionReplay = 6; + CTheScripts::MissionCleanup.Process(); + } +} + +#endif diff --git a/src/control/Script.h b/src/control/Script.h index acab66cc..743fad99 100644 --- a/src/control/Script.h +++ b/src/control/Script.h @@ -372,6 +372,9 @@ private: friend class CRunningScript; friend class CHud; friend void CMissionCleanup::Process(); +#ifdef FIX_BUGS + friend void RetryMission(int, int); +#endif }; @@ -479,6 +482,10 @@ private: void CharInAreaCheckCommand(int32, uint32*); void CarInAreaCheckCommand(int32, uint32*); +#ifdef MISSION_REPLAY + bool CanAllowMissionReplay(); +#endif + float LimitAngleOnCircle(float angle) { return angle < 0.0f ? angle + 360.0f : angle; } bool ThisIsAValidRandomPed(uint32 pedtype) { @@ -502,3 +509,15 @@ private: } } }; + +#ifdef MISSION_REPLAY +extern int AllowMissionReplay; +extern uint32 WaitForMissionActivate; +extern uint32 WaitForSave; +extern uint32 MissionStartTime; +extern int missionRetryScriptIndex; +extern bool doingMissionRetry; + +uint32 AddExtraDeathDelay(); +void RetryMission(int, int); +#endif diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index d58d0576..b291886f 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -3497,6 +3497,13 @@ CMenuManager::Process(void) SaveLoadFileError_SetUpErrorScreen(); } if (m_nCurrScreen == MENUPAGE_LOADING_IN_PROGRESS) { +#ifdef MISSION_REPLAY + if (doingMissionRetry) { + RetryMission(2, 0); + m_nCurrSaveSlot = SLOT_COUNT; + doingMissionRetry = false; + } +#endif if (CheckSlotDataValid(m_nCurrSaveSlot)) { TheCamera.m_bUseMouse3rdPerson = m_ControlMethod == CONTROL_STANDARD; if (m_PrefsVsyncDisp != m_PrefsVsync) @@ -4661,6 +4668,18 @@ CMenuManager::ProcessButtonPresses(void) DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1); OutputDebugString("STARTED PLAYING FRONTEND AUDIO TRACK"); break; +#ifdef MISSION_REPLAY + case MENUACTION_REJECT_RETRY: + doingMissionRetry = false; + AllowMissionReplay = 0; + RequestFrontEndShutDown(); + break; + case MENUACTION_UNK114: + doingMissionRetry = false; + RequestFrontEndShutDown(); + RetryMission(2, 0); + return; +#endif } } ProcessOnOffMenuOptions(); diff --git a/src/core/Frontend.h b/src/core/Frontend.h index 89517528..b65a60f1 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -245,7 +245,7 @@ enum eMenuScreen MENUPAGE_SKIN_SELECT = 54, MENUPAGE_KEYBOARD_CONTROLS = 55, MENUPAGE_MOUSE_CONTROLS = 56, - MENUPAGE_57 = 57, // mission failed, wanna restart page in mobile + MENUPAGE_MISSION_RETRY = 57, MENUPAGE_58 = 58, #ifdef MENU_MAP MENUPAGE_MAP = 59, @@ -366,6 +366,10 @@ enum eMenuAction MENUACTION_UNK108, MENUACTION_UNK109, MENUACTION_UNK110, + MENUACTION_UNK111, + MENUACTION_UNK112, + MENUACTION_REJECT_RETRY, + MENUACTION_UNK114, #ifdef MORE_LANGUAGES MENUACTION_LANG_PL, MENUACTION_LANG_RUS, diff --git a/src/core/MenuScreens.h b/src/core/MenuScreens.h index 6c2ebdb8..339ae2ce 100644 --- a/src/core/MenuScreens.h +++ b/src/core/MenuScreens.h @@ -445,11 +445,19 @@ const CMenuScreen aScreens[] = { MENUACTION_MOUSESTEER, "FET_MST", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS, MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, }, + // MENUPAGE_MISSION_RETRY = 57 +#ifdef MISSION_REPLAY - // MENUPAGE_57 = 57 + { "M_FAIL", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, + MENUACTION_LABEL, "FESZ_RM", SAVESLOT_NONE, MENUPAGE_NONE, + MENUACTION_CHANGEMENU, "FEM_YES", SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS, + MENUACTION_REJECT_RETRY, "FEM_NO", SAVESLOT_NONE, MENUPAGE_NONE + }, +#else { "", 0, MENUPAGE_NONE, MENUPAGE_NONE, 0, 0, // mission failed, wanna restart page in mobile }, +#endif // MENUPAGE_58 = 58 { "", 0, MENUPAGE_NONE, MENUPAGE_NONE, 0, 0, diff --git a/src/core/Pools.cpp b/src/core/Pools.cpp index 17b9e08d..bd0814d0 100644 --- a/src/core/Pools.cpp +++ b/src/core/Pools.cpp @@ -4,6 +4,9 @@ #include "Boat.h" #include "CarCtrl.h" +#ifdef MISSION_REPLAY +#include "GenericGameStorage.h" +#endif #include "Population.h" #include "ProjectileInfo.h" #include "Streaming.h" @@ -206,11 +209,24 @@ INITSAVEBUF if (pVehicle->pPassengers[j]) bHasPassenger = true; } +#ifdef MISSION_REPLAY + bool bForceSaving = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pMyVehicle == pVehicle && IsQuickSave; +#ifdef FIX_BUGS + if ((!pVehicle->pDriver && !bHasPassenger) || bForceSaving) { +#else + if (!pVehicle->pDriver && !bHasPassenger) { +#endif + if (pVehicle->IsCar() && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving)) + ++nNumCars; + if (pVehicle->IsBoat() && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving)) + ++nNumBoats; +#else if (!pVehicle->pDriver && !bHasPassenger) { if (pVehicle->IsCar() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) ++nNumCars; if (pVehicle->IsBoat() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) ++nNumBoats; +#endif } } *size = nNumCars * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + CAutomobile::nSaveStructSize) + sizeof(int) + @@ -226,23 +242,42 @@ INITSAVEBUF if (pVehicle->pPassengers[j]) bHasPassenger = true; } +#ifdef MISSION_REPLAY + bool bForceSaving = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pMyVehicle == pVehicle && IsQuickSave; +#endif +#if defined FIX_BUGS && defined MISSION_REPLAY + if ((!pVehicle->pDriver && !bHasPassenger) || bForceSaving) { +#else if (!pVehicle->pDriver && !bHasPassenger) { +#endif #ifdef COMPATIBLE_SAVES +#ifdef MISSION_REPLAY + if ((pVehicle->IsCar() || pVehicle->IsBoat()) && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving)) { +#else if ((pVehicle->IsCar() || pVehicle->IsBoat()) && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) { +#endif WriteSaveBuf(buf, pVehicle->m_vehType); WriteSaveBuf(buf, pVehicle->GetModelIndex()); WriteSaveBuf(buf, GetVehicleRef(pVehicle)); pVehicle->Save(buf); } +#else +#ifdef MISSION_REPLAY + if (pVehicle->IsCar() && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving)) { #else if (pVehicle->IsCar() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) { +#endif WriteSaveBuf(buf, (uint32)pVehicle->m_vehType); WriteSaveBuf(buf, pVehicle->GetModelIndex()); WriteSaveBuf(buf, GetVehicleRef(pVehicle)); memcpy(buf, pVehicle, sizeof(CAutomobile)); SkipSaveBuf(buf, sizeof(CAutomobile)); } +#ifdef MISSION_REPLAY + if (pVehicle->IsBoat() && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving)) { +#else if (pVehicle->IsBoat() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) { +#endif WriteSaveBuf(buf, (uint32)pVehicle->m_vehType); WriteSaveBuf(buf, pVehicle->GetModelIndex()); WriteSaveBuf(buf, GetVehicleRef(pVehicle)); @@ -400,7 +435,11 @@ INITSAVEBUF CPed* pPed = GetPedPool()->GetSlot(i); if (!pPed) continue; +#ifdef MISSION_REPLAY + if ((!pPed->bInVehicle || (pPed == CWorld::Players[CWorld::PlayerInFocus].m_pPed && IsQuickSave)) && pPed->m_nPedType == PEDTYPE_PLAYER1) +#else if (!pPed->bInVehicle && pPed->m_nPedType == PEDTYPE_PLAYER1) +#endif nNumPeds++; } *size = sizeof(int) + nNumPeds * (sizeof(uint32) + sizeof(int16) + sizeof(int) + CPlayerPed::nSaveStructSize + @@ -410,7 +449,11 @@ INITSAVEBUF CPed* pPed = GetPedPool()->GetSlot(i); if (!pPed) continue; +#ifdef MISSION_REPLAY + if ((!pPed->bInVehicle || (pPed == CWorld::Players[CWorld::PlayerInFocus].m_pPed && IsQuickSave)) && pPed->m_nPedType == PEDTYPE_PLAYER1) { +#else if (!pPed->bInVehicle && pPed->m_nPedType == PEDTYPE_PLAYER1) { +#endif CopyToBuf(buf, pPed->m_nPedType); CopyToBuf(buf, pPed->m_modelIndex); int32 ref = GetPedRef(pPed); diff --git a/src/core/config.h b/src/core/config.h index f43067d7..5ad12fba 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -227,6 +227,8 @@ enum Config { #define USE_DEBUG_SCRIPT_LOADER // makes game load main_freeroam.scm by default #define USE_MEASUREMENTS_IN_METERS // makes game use meters instead of feet in script #define USE_PRECISE_MEASUREMENT_CONVERTION // makes game convert feet to meeters more precisely +#define MISSION_REPLAY // mobile feature +//#define SIMPLIER_MISSIONS // apply simplifications from mobile #define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible diff --git a/src/save/GenericGameStorage.cpp b/src/save/GenericGameStorage.cpp index 8aae4011..eff0f2ff 100644 --- a/src/save/GenericGameStorage.cpp +++ b/src/save/GenericGameStorage.cpp @@ -42,6 +42,11 @@ const uint32 SIZE_OF_ONE_GAME_IN_BYTES = 201729; +#ifdef MISSION_REPLAY +int8 IsQuickSave; +const int PAUSE_SAVE_SLOT = SLOT_COUNT; +#endif + char DefaultPCSaveFileName[260]; char ValidSaveName[260]; char LoadFileName[256]; @@ -134,7 +139,12 @@ GenericSave(int file) WriteDataToBufferPointer(buf, saveName); GetLocalTime(&saveTime); WriteDataToBufferPointer(buf, saveTime); +#ifdef MISSION_REPLAY + int32 data = IsQuickSave << 24 | SIZE_OF_ONE_GAME_IN_BYTES; + WriteDataToBufferPointer(buf, data); +#else WriteDataToBufferPointer(buf, SIZE_OF_ONE_GAME_IN_BYTES); +#endif WriteDataToBufferPointer(buf, CGame::currLevel); WriteDataToBufferPointer(buf, TheCamera.GetPosition().x); WriteDataToBufferPointer(buf, TheCamera.GetPosition().y); @@ -240,6 +250,9 @@ GenericLoad() uint8 *buf; int32 file; uint32 size; +#ifdef MISSION_REPLAY + int8 qs; +#endif int32 saveSize; CPad *currPad; @@ -254,6 +267,9 @@ GenericLoad() ReadDataFromFile(file, work_buff, size); buf = (work_buff + 0x40); ReadDataFromBufferPointer(buf, saveSize); +#ifdef MISSION_REPLAY // a hack to keep compatibility but get new data from save + qs = saveSize >> 24; +#endif ReadDataFromBufferPointer(buf, CGame::currLevel); ReadDataFromBufferPointer(buf, TheCamera.GetMatrix().GetPosition().x); ReadDataFromBufferPointer(buf, TheCamera.GetMatrix().GetPosition().y); @@ -296,6 +312,11 @@ GenericLoad() ReadDataFromBufferPointer(buf, TheCamera.PedZoomIndicator); #endif assert(buf - work_buff == SIZE_OF_SIMPLEVARS); +#ifdef MISSION_REPLAY + WaitForSave = 0; + if (FrontEndMenuManager.m_nCurrSaveSlot == PAUSE_SAVE_SLOT && qs == 3) + WaitForMissionActivate = CTimer::GetTimeInMilliseconds() + 2000; +#endif ReadDataFromBlock("Loading Scripts \n", CTheScripts::LoadAllScripts); // Load the rest @@ -563,3 +584,27 @@ align4bytes(int32 size) { return (size + 3) & 0xFFFFFFFC; } + +#ifdef MISSION_REPLAY + +void DisplaySaveResult(int unk, char* name) +{} + +bool SaveGameForPause(int type) +{ + if (AllowMissionReplay != 0 || type != 3 && WaitForSave > CTimer::GetTimeInMilliseconds()) + return false; + WaitForSave = 0; + if (gGameState != GS_PLAYING_GAME || CTheScripts::IsPlayerOnAMission() || CStats::LastMissionPassedName[0] == '\0') { + DisplaySaveResult(3, CStats::LastMissionPassedName); + return false; + } + IsQuickSave = type; + MissionStartTime = 0; + int res = PcSaveHelper.SaveSlot(PAUSE_SAVE_SLOT); + PcSaveHelper.PopulateSlotInfo(); + IsQuickSave = 0; + DisplaySaveResult(res, CStats::LastMissionPassedName); + return true; +} +#endif diff --git a/src/save/GenericGameStorage.h b/src/save/GenericGameStorage.h index b913c305..ee8a52a1 100644 --- a/src/save/GenericGameStorage.h +++ b/src/save/GenericGameStorage.h @@ -40,4 +40,10 @@ extern uint32 TimeToStayFadedBeforeFadeOut; extern char SaveFileNameJustSaved[260]; // 8F2570 -const char TopLineEmptyFile[] = "THIS FILE IS NOT VALID YET"; \ No newline at end of file +const char TopLineEmptyFile[] = "THIS FILE IS NOT VALID YET"; + +#ifdef MISSION_REPLAY +extern int8 IsQuickSave; // originally int + +bool SaveGameForPause(int); +#endif diff --git a/src/save/PCSave.cpp b/src/save/PCSave.cpp index 3dc80f73..3103c7ab 100644 --- a/src/save/PCSave.cpp +++ b/src/save/PCSave.cpp @@ -41,7 +41,10 @@ C_PcSave::SaveSlot(int32 slot) _psGetUserFilesFolder(); int file = CFileMgr::OpenFile(ValidSaveName, "wb"); if (file != 0) { - DoGameSpecificStuffBeforeSave(); +#ifdef MISSION_REPLAY + if (!IsQuickSave) +#endif + DoGameSpecificStuffBeforeSave(); if (GenericSave(file)) { if (!!CFileMgr::CloseFile(file)) nErrorCode = SAVESTATUS_ERR_SAVE_CLOSE; From d8749c2305408b65d298f5e2e302dd5e9d68d249 Mon Sep 17 00:00:00 2001 From: aap Date: Wed, 27 May 2020 20:41:13 +0200 Subject: [PATCH 02/26] librw update --- librw | 2 +- src/fakerw/fake.cpp | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/librw b/librw index 84c582c1..6ff378bb 160000 --- a/librw +++ b/librw @@ -1 +1 @@ -Subproject commit 84c582c1d7a64a213523b8e4c8211f8b7a4fdcd1 +Subproject commit 6ff378bb16007ad003b1a71996944a20f2e76556 diff --git a/src/fakerw/fake.cpp b/src/fakerw/fake.cpp index 08d106f4..f95845a8 100644 --- a/src/fakerw/fake.cpp +++ b/src/fakerw/fake.cpp @@ -790,6 +790,12 @@ RpMaterial *RpMatFXMaterialSetEnvMapFrame( RpMaterial *material, RwFrame *frame mfx->setEnvFrame(frame); return material; } +RpMaterial *RpMatFXMaterialSetEnvMapFrameBufferAlpha( RpMaterial *material, RwBool useFrameBufferAlpha ) +{ + MatFX *mfx = MatFX::get(material); + mfx->setEnvFBAlpha(useFrameBufferAlpha); + return material; +} RpMaterial *RpMatFXMaterialSetEnvMapCoefficient( RpMaterial *material, RwReal coef ) { MatFX *mfx = MatFX::get(material); From 2a1b9281e49685b6d5d3cf0770cfa0c3e15d1e94 Mon Sep 17 00:00:00 2001 From: aap Date: Wed, 27 May 2020 22:32:57 +0200 Subject: [PATCH 03/26] automobile fixes --- src/vehicles/Automobile.cpp | 32 ++++++++++++++++++++------------ src/vehicles/DamageManager.cpp | 10 +++------- src/vehicles/DamageManager.h | 2 +- src/vehicles/Vehicle.cpp | 8 ++++---- 4 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index e572c123..5d39b525 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -3232,7 +3232,7 @@ CAutomobile::VehicleDamage(float impulse, uint16 damagedPiece) if(impulse > 25.0f && GetStatus() != STATUS_WRECKED){ if(bIsLawEnforcer && FindPlayerVehicle() && FindPlayerVehicle() == m_pDamageEntity && - GetStatus() != STATUS_ABANDONED && + GetStatus() != STATUS_ABANDONED && FindPlayerVehicle()->m_vecMoveSpeed.Magnitude() >= m_vecMoveSpeed.Magnitude() && FindPlayerVehicle()->m_vecMoveSpeed.Magnitude() > 0.1f) FindPlayerPed()->SetWantedLevelNoDrop(1); @@ -3276,6 +3276,7 @@ CAutomobile::VehicleDamage(float impulse, uint16 damagedPiece) case CAR_PIECE_BONNET: GetComponentWorldPosition(CAR_BONNET, pos); dmgDrawCarCollidingParticles(pos, impulse); + if(GetModelIndex() != MI_DODO) if(Damage.ApplyDamage(COMPONENT_DOOR_BONNET, impulse*impulseMult, pHandling->fCollisionDamageMultiplier)){ SetDoorDamage(CAR_BONNET, DOOR_BONNET); doubleMoney = true; @@ -3286,7 +3287,7 @@ CAutomobile::VehicleDamage(float impulse, uint16 damagedPiece) case CAR_PIECE_BUMP_REAR: GetComponentWorldPosition(CAR_BUMP_REAR, pos); dmgDrawCarCollidingParticles(pos, impulse); - if(Damage.ApplyDamage(COMPONENT_BUMPER_FRONT, impulse*impulseMult, pHandling->fCollisionDamageMultiplier)){ + if(Damage.ApplyDamage(COMPONENT_BUMPER_REAR, impulse*impulseMult, pHandling->fCollisionDamageMultiplier)){ SetBumperDamage(CAR_BUMP_REAR, VEHBUMPER_REAR); doubleMoney = true; } @@ -3542,8 +3543,8 @@ CAutomobile::AddWheelDirtAndWater(CColPoint *colpoint, uint32 belowEffectSpeed) int i; CVector dir; static RwRGBA grassCol = { 8, 24, 8, 255 }; - static RwRGBA dirtCol = { 64, 64, 64, 255 }; - static RwRGBA dirttrackCol = { 64, 32, 16, 255 }; + static RwRGBA gravelCol = { 64, 64, 64, 255 }; + static RwRGBA mudCol = { 64, 32, 16, 255 }; static RwRGBA waterCol = { 48, 48, 64, 0 }; if(!belowEffectSpeed) @@ -3565,7 +3566,7 @@ CAutomobile::AddWheelDirtAndWater(CColPoint *colpoint, uint32 belowEffectSpeed) for(i = 0; i < 4; i++){ dir.z = CGeneral::GetRandomNumberInRange(0.03f, 0.06f); CParticle::AddParticle(PARTICLE_WHEEL_DIRT, colpoint->point, dir, nil, - CGeneral::GetRandomNumberInRange(0.02f, 0.06f), dirtCol); + CGeneral::GetRandomNumberInRange(0.02f, 0.06f), gravelCol); } return 1; case SURFACE_MUD_DRY: @@ -3574,7 +3575,7 @@ CAutomobile::AddWheelDirtAndWater(CColPoint *colpoint, uint32 belowEffectSpeed) for(i = 0; i < 4; i++){ dir.z = CGeneral::GetRandomNumberInRange(0.03f, 0.06f); CParticle::AddParticle(PARTICLE_WHEEL_DIRT, colpoint->point, dir, nil, - CGeneral::GetRandomNumberInRange(0.02f, 0.06f), dirttrackCol); + CGeneral::GetRandomNumberInRange(0.02f, 0.06f), mudCol); } return 0; default: @@ -4404,7 +4405,7 @@ CAutomobile::SpawnFlyingComponent(int32 component, uint32 type) (component == COMPGROUP_BONNET || component == COMPGROUP_BOOT || component == CAR_WINDSCREEN)){ obj->m_vecMoveSpeed.z *= -1.5f; obj->m_vecMoveSpeed.z += 0.04f; - }else{ + }else{p obj->m_vecMoveSpeed.z *= 0.25f; } obj->m_vecMoveSpeed.x *= 0.75f; @@ -4420,7 +4421,7 @@ CAutomobile::SpawnFlyingComponent(int32 component, uint32 type) dist += GetUp(); if(GetUp().z > 0.0f){ // simulate fast upward movement if going fast - float speed = CVector2D(m_vecMoveSpeed).MagnitudeSqr(); + float speed = CVector2D(m_vecMoveSpeed).Magnitude(); obj->GetMatrix().Translate(GetUp()*speed); } } @@ -4452,8 +4453,11 @@ CAutomobile::RemoveBonnetInPedCollision(void) if(Damage.GetDoorStatus(DOOR_BONNET) == DOOR_STATUS_SWINGING && Doors[DOOR_BONNET].RetAngleWhenOpen()*0.4f < Doors[DOOR_BONNET].m_fAngle){ - // BUG? why not COMPGROUP_BONNET? +#ifdef FIX_BUGS + obj = SpawnFlyingComponent(CAR_BONNET, COMPGROUP_BONNET); +#else obj = SpawnFlyingComponent(CAR_BONNET, COMPGROUP_DOOR); +#endif // make both doors invisible on car SetComponentVisibility(m_aCarNodes[CAR_BONNET], ATOMIC_FLAG_NONE); Damage.SetDoorStatus(DOOR_BONNET, DOOR_STATUS_MISSING); @@ -4514,13 +4518,16 @@ CAutomobile::SetDoorDamage(int32 component, eDoors door, bool noFlyingComponents status = DOOR_STATUS_MISSING; } - if(status == DOOR_STATUS_SMASHED){ + switch(status){ + case DOOR_STATUS_SMASHED: // show damaged part SetComponentVisibility(m_aCarNodes[component], ATOMIC_FLAG_DAM); - }else if(status == DOOR_STATUS_SWINGING){ + break; + case DOOR_STATUS_SWINGING: // turn off angle cull for swinging doors RwFrameForAllObjects(m_aCarNodes[component], CVehicleModelInfo::SetAtomicFlagCB, (void*)ATOMIC_FLAG_NOCULL); - }else if(status == DOOR_STATUS_MISSING){ + break; + case DOOR_STATUS_MISSING: if(!noFlyingComponents){ if(door == DOOR_BONNET) SpawnFlyingComponent(component, COMPGROUP_BONNET); @@ -4531,6 +4538,7 @@ CAutomobile::SetDoorDamage(int32 component, eDoors door, bool noFlyingComponents } // hide both SetComponentVisibility(m_aCarNodes[component], ATOMIC_FLAG_NONE); + break; } } diff --git a/src/vehicles/DamageManager.cpp b/src/vehicles/DamageManager.cpp index 6b59ccda..c625a4e7 100644 --- a/src/vehicles/DamageManager.cpp +++ b/src/vehicles/DamageManager.cpp @@ -11,7 +11,7 @@ CDamageManager::CDamageManager(void) { ResetDamageStatus(); m_fWheelDamageEffect = 0.75f; - field_24 = 1; + field_18 = 1; } void @@ -28,12 +28,8 @@ CDamageManager::FuckCarCompletely(void) m_wheelStatus[0] = WHEEL_STATUS_MISSING; // wheels 1-3 not reset? - m_doorStatus[0] = DOOR_STATUS_MISSING; - m_doorStatus[1] = DOOR_STATUS_MISSING; - m_doorStatus[2] = DOOR_STATUS_MISSING; - m_doorStatus[3] = DOOR_STATUS_MISSING; - m_doorStatus[4] = DOOR_STATUS_MISSING; - m_doorStatus[5] = DOOR_STATUS_MISSING; + for(i = 0; i < ARRAY_SIZE(m_doorStatus); i++) + m_doorStatus[i] = DOOR_STATUS_MISSING; for(i = 0; i < 3; i++){ #ifdef FIX_BUGS diff --git a/src/vehicles/DamageManager.h b/src/vehicles/DamageManager.h index bf0c59a1..312006e3 100644 --- a/src/vehicles/DamageManager.h +++ b/src/vehicles/DamageManager.h @@ -86,7 +86,7 @@ public: uint8 m_doorStatus[6]; uint32 m_lightStatus; uint32 m_panelStatus; - uint32 field_24; + uint8 field_18; CDamageManager(void); diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp index e264d7ed..77c549f9 100644 --- a/src/vehicles/Vehicle.cpp +++ b/src/vehicles/Vehicle.cpp @@ -780,7 +780,7 @@ CVehicle::ShufflePassengersToMakeSpace(void) return false; if (pPassengers[1] && !(m_nGettingInFlags & CAR_DOOR_FLAG_LR) && - IsRoomForPedToLeaveCar(COMPONENT_DOOR_REAR_LEFT, nil)) { + IsRoomForPedToLeaveCar(CAR_DOOR_LR, nil)) { if (!pPassengers[2] && !(m_nGettingInFlags & CAR_DOOR_FLAG_RR)) { pPassengers[2] = pPassengers[1]; pPassengers[1] = nil; @@ -797,7 +797,7 @@ CVehicle::ShufflePassengersToMakeSpace(void) } if (pPassengers[2] && !(m_nGettingInFlags & CAR_DOOR_FLAG_RR) && - IsRoomForPedToLeaveCar(COMPONENT_DOOR_REAR_RIGHT, nil)) { + IsRoomForPedToLeaveCar(CAR_DOOR_RR, nil)) { if (!pPassengers[1] && !(m_nGettingInFlags & CAR_DOOR_FLAG_LR)) { pPassengers[1] = pPassengers[2]; pPassengers[2] = nil; @@ -814,7 +814,7 @@ CVehicle::ShufflePassengersToMakeSpace(void) } if (pPassengers[0] && !(m_nGettingInFlags & CAR_DOOR_FLAG_RF) && - IsRoomForPedToLeaveCar(COMPONENT_DOOR_FRONT_RIGHT, nil)) { + IsRoomForPedToLeaveCar(CAR_DOOR_RF, nil)) { if (!pPassengers[1] && !(m_nGettingInFlags & CAR_DOOR_FLAG_LR)) { pPassengers[1] = pPassengers[0]; pPassengers[0] = nil; @@ -1192,7 +1192,7 @@ CVehicle::ProcessCarAlarm(void) { uint32 step; - if(m_nAlarmState == 0 || m_nAlarmState == -1) + if(!IsAlarmOn()) return; step = CTimer::GetTimeStepInMilliseconds(); From 0bc6eef55d560a0d17c58792668d01cfeaf4bf66 Mon Sep 17 00:00:00 2001 From: aap Date: Wed, 27 May 2020 22:34:10 +0200 Subject: [PATCH 04/26] bla --- src/vehicles/Automobile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 5d39b525..654713b1 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -4405,7 +4405,7 @@ CAutomobile::SpawnFlyingComponent(int32 component, uint32 type) (component == COMPGROUP_BONNET || component == COMPGROUP_BOOT || component == CAR_WINDSCREEN)){ obj->m_vecMoveSpeed.z *= -1.5f; obj->m_vecMoveSpeed.z += 0.04f; - }else{p + }else{ obj->m_vecMoveSpeed.z *= 0.25f; } obj->m_vecMoveSpeed.x *= 0.75f; From d9d57f12fc28c4d93a3534bd3c96be2158e213b9 Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Thu, 28 May 2020 01:00:49 +0300 Subject: [PATCH 05/26] crash fix --- src/control/Script.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/control/Script.cpp b/src/control/Script.cpp index 406b11b7..1ea970c4 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -10398,8 +10398,8 @@ void CRunningScript::LocateCharCarCommand(int32 command, uint32* pIp) case COMMAND_LOCATE_CHAR_ON_FOOT_CAR_3D: result = !pPed->bInVehicle; break; - case COMMAND_LOCATE_CHAR_IN_CAR_CHAR_2D: - case COMMAND_LOCATE_CHAR_IN_CAR_CHAR_3D: + case COMMAND_LOCATE_CHAR_IN_CAR_CAR_2D: + case COMMAND_LOCATE_CHAR_IN_CAR_CAR_3D: result = pPed->bInVehicle; break; default: From 329a387fdfab403bfd8fadef025510ee1081e38f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Thu, 28 May 2020 03:07:26 +0300 Subject: [PATCH 06/26] Frontend customization functions, freecam toggle, minor things --- src/control/Script.cpp | 13 +- src/core/Cam.cpp | 2 +- src/core/Frontend.cpp | 227 +++++++++++++------- src/core/Frontend.h | 17 +- src/core/Game.cpp | 6 +- src/core/{MenuScreens.h => MenuScreens.cpp} | 36 +--- src/core/config.h | 1 + src/core/main.cpp | 1 - src/core/re3.cpp | 98 +++++++++ src/extras/frontendoption.cpp | 163 ++++++++++++++ src/extras/frontendoption.h | 86 ++++++++ src/skel/glfw/glfw.cpp | 2 +- 12 files changed, 531 insertions(+), 121 deletions(-) rename src/core/{MenuScreens.h => MenuScreens.cpp} (95%) create mode 100644 src/extras/frontendoption.cpp create mode 100644 src/extras/frontendoption.h diff --git a/src/control/Script.cpp b/src/control/Script.cpp index 1ea970c4..c52b28c6 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -1,4 +1,3 @@ -#define WITHWINDOWS // for our script loading hack #include "common.h" #include "Script.h" @@ -504,10 +503,22 @@ void CRunningScript::Init() } #ifdef USE_DEBUG_SCRIPT_LOADER +#ifdef _WIN32 +#include +#endif int open_script() { static int scriptToLoad = 0; + // Doesn't work because of CGame::Initialise is blocking + /* + if (glfwGetKey(PSGLOBAL(window), GLFW_KEY_G) == GLFW_PRESS) + scriptToLoad = 0; + if (glfwGetKey(PSGLOBAL(window), GLFW_KEY_R) == GLFW_PRESS) + scriptToLoad = 1; + if (glfwGetKey(PSGLOBAL(window), GLFW_KEY_D) == GLFW_PRESS) + scriptToLoad = 2; + */ #ifdef _WIN32 if (GetAsyncKeyState('G') & 0x8000) scriptToLoad = 0; diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index 247e77ce..6347e111 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -29,7 +29,7 @@ bool PrintDebugCode = false; int16 DebugCamMode; #ifdef FREE_CAM -bool CCamera::bFreeCam = true; +bool CCamera::bFreeCam; int nPreviousMode = -1; #endif diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index d58d0576..710fc692 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -23,7 +23,6 @@ #include "GenericGameStorage.h" #include "Script.h" #include "Camera.h" -#include "MenuScreens.h" #include "ControllerConfig.h" #include "Vehicle.h" #include "MBlur.h" @@ -36,6 +35,7 @@ #include "Stats.h" #include "Messages.h" #include "FileLoader.h" +#include "frontendoption.h" #define TIDY_UP_PBP // ProcessButtonPresses #define MAX_VISIBLE_LIST_ROW 30 @@ -382,7 +382,7 @@ CMenuManager::PageDownList(bool playSoundOnSuccess) } inline void -CMenuManager::ThingsToDoBeforeLeavingPage() +CMenuManager::ThingsToDoBeforeGoingBack() { if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) && strcmp(m_aSkinName, m_PrefsSkinFile) != 0) { CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile); @@ -395,9 +395,6 @@ CMenuManager::ThingsToDoBeforeLeavingPage() #endif } else if (m_nCurrScreen == MENUPAGE_GRAPHICS_SETTINGS) { m_nDisplayVideoMode = m_nPrefsVideoMode; -#ifdef IMPROVED_VIDEOMODE - m_nSelectedScreenMode = m_nPrefsWindowed; -#endif } if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) { @@ -407,6 +404,43 @@ CMenuManager::ThingsToDoBeforeLeavingPage() if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) || (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS)) { m_nTotalListRow = 0; } + +#ifdef CUSTOM_FRONTEND_OPTIONS + for (int i = 0; i < numCustomFrontendOptions; i++) { + FrontendOption &option = customFrontendOptions[i]; + if (option.type != FEOPTION_REDIRECT && option.type != FEOPTION_GOBACK && m_nCurrScreen == option.screen) { + if (option.returnPrevPageFunc) + option.returnPrevPageFunc(); + + if (option.onlyApplyOnEnter) + option.displayedValue = *option.value; + } + } +#endif +} + +inline int8 +CMenuManager::GetPreviousPageOption() +{ +#ifndef CUSTOM_FRONTEND_OPTIONS + return !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_ParentEntry[1] : aScreens[m_nCurrScreen].m_ParentEntry[0]; +#else + int8 prevPage = !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage[1] : aScreens[m_nCurrScreen].m_PreviousPage[0]; + + if (prevPage == -1) // Game also does same + return 0; + + prevPage = prevPage == MENUPAGE_NONE ? (!m_bGameNotLoaded ? MENUPAGE_PAUSE_MENU : MENUPAGE_START_MENU) : prevPage; + + for (int i = 0; i < NUM_MENUROWS; i++) { + if (aScreens[prevPage].m_aEntries[i].m_TargetMenu == m_nCurrScreen) { + return i; + } + } + + // Couldn't find current screen option on previous page, use default behaviour (maybe save-related screen?) + return !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_ParentEntry[1] : aScreens[m_nCurrScreen].m_ParentEntry[0]; +#endif } // ------ Functions not in the game/inlined ends @@ -923,6 +957,9 @@ CMenuManager::Draw() #endif for (int i = 0; i < NUM_MENUROWS; ++i) { +#ifdef CUSTOM_FRONTEND_OPTIONS + bool isOptionDisabled = false; +#endif if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action != MENUACTION_LABEL && aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName[0] != '\0') { wchar *rightText = nil; wchar *leftText; @@ -1105,17 +1142,6 @@ CMenuManager::Draw() AsciiToUnicode(_psGetVideoModeList()[m_nDisplayVideoMode], unicodeTemp); rightText = unicodeTemp; break; -#ifdef IMPROVED_VIDEOMODE - case MENUACTION_SCREENMODE: - if (m_nSelectedScreenMode == 0) - sprintf(asciiTemp, "FULLSCREEN"); - else - sprintf(asciiTemp, "WINDOWED"); - - AsciiToUnicode(asciiTemp, unicodeTemp); - rightText = unicodeTemp; - break; -#endif case MENUACTION_AUDIOHW: if (m_nPrefsAudio3DProviderIndex == -1) rightText = TheText.Get("FEA_NAH"); @@ -1166,6 +1192,28 @@ CMenuManager::Draw() case MENUACTION_MOUSESTEER: rightText = TheText.Get(CVehicle::m_bDisableMouseSteering ? "FEM_OFF" : "FEM_ON"); break; +#ifdef CUSTOM_FRONTEND_OPTIONS + case MENUACTION_TRIGGERFUNC: + FrontendOption& option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[i].m_TargetMenu]; + if (m_nCurrScreen == option.screen && i == option.screenOptionOrder) { + leftText = (wchar*)option.leftText; + if (option.type == FEOPTION_SELECT) { + if (option.displayedValue >= option.numRightTexts || option.displayedValue < 0) + option.displayedValue = 0; + + rightText = (wchar*)option.rightTexts[option.displayedValue]; + + } else if (option.type == FEOPTION_DYNAMIC) { + if (option.drawFunc) { + option.drawFunc(unicodeTemp, &isOptionDisabled); + rightText = unicodeTemp; + } + } + } else + assert(0 && "Custom frontend options is borked"); + + break; +#endif } float nextItemY = headerHeight + nextYToUse; @@ -1244,7 +1292,11 @@ CMenuManager::Draw() CFont::SetRightJustifyOn(); if(!strcmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FED_RES") - && !m_bGameNotLoaded && textLayer == 1) { + && !m_bGameNotLoaded && textLayer == 1 +#ifdef CUSTOM_FRONTEND_OPTIONS + || isOptionDisabled +#endif + ) { CFont::SetColor(CRGBA(155, 117, 6, FadeIn(255))); } CFont::PrintString(MENU_X_RIGHT_ALIGNED(columnWidth - textLayer), itemY, rightText); @@ -1287,12 +1339,12 @@ CMenuManager::Draw() SetHelperText(3); } } -#ifdef IMPROVED_VIDEOMODE - if (m_nSelectedScreenMode != m_nPrefsWindowed) { - if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "SCRFOR") != 0 - && m_nCurrScreen == MENUPAGE_GRAPHICS_SETTINGS) { - m_nSelectedScreenMode = m_nPrefsWindowed; - } + +#ifdef CUSTOM_FRONTEND_OPTIONS + if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action == MENUACTION_TRIGGERFUNC) { + FrontendOption &option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[i].m_TargetMenu]; + if (option.onlyApplyOnEnter && m_nCurrOption != i) + option.displayedValue = *option.value; } #endif @@ -2993,6 +3045,11 @@ CMenuManager::InitialiseChangedLanguageSettings() default: break; } + +#ifdef CUSTOM_FRONTEND_OPTIONS + RemoveCustomFrontendOptions(); + CustomFrontendOptionsPopulate(); +#endif } } @@ -3138,6 +3195,9 @@ CMenuManager::LoadSettings() CFileMgr::Read(fileHandle, m_PrefsSkinFile, 256); CFileMgr::Read(fileHandle, (char*)&m_ControlMethod, 1); CFileMgr::Read(fileHandle, (char*)&m_PrefsLanguage, 1); +#ifdef FREE_CAM + CFileMgr::Read(fileHandle, (char*)&TheCamera.bFreeCam, 1); +#endif } } @@ -3228,6 +3288,9 @@ CMenuManager::SaveSettings() CFileMgr::Write(fileHandle, m_PrefsSkinFile, 256); CFileMgr::Write(fileHandle, (char*)&m_ControlMethod, 1); CFileMgr::Write(fileHandle, (char*)&m_PrefsLanguage, 1); +#ifdef FREE_CAM + CFileMgr::Write(fileHandle, (char*)&TheCamera.bFreeCam, 1); +#endif } CFileMgr::CloseFile(fileHandle); @@ -4322,10 +4385,12 @@ CMenuManager::ProcessButtonPresses(void) CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile); SaveSettings(); } else { - if (!m_bGameNotLoaded) - ChangeScreen(aScreens[m_nCurrScreen].m_PreviousPage[1], aScreens[m_nCurrScreen].m_ParentEntry[1], true, true); - else - ChangeScreen(aScreens[m_nCurrScreen].m_PreviousPage[0], aScreens[m_nCurrScreen].m_ParentEntry[0], true, true); +#ifndef TIDY_UP_PBP + ChangeScreen(!m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage[1] : aScreens[m_nCurrScreen].m_PreviousPage[0], + GetPreviousPageOption(), true, true); +#else + goBack = true; +#endif } } else if (m_nCurrScreen != MENUPAGE_MULTIPLAYER_FIND_GAME) { option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action; @@ -4377,26 +4442,6 @@ CMenuManager::ProcessButtonPresses(void) InitialiseChangedLanguageSettings(); SaveSettings(); break; -#ifdef MORE_LANGUAGES - case MENUACTION_LANG_PL: - m_PrefsLanguage = LANGUAGE_POLISH; - m_bFrontEnd_ReloadObrTxtGxt = true; - InitialiseChangedLanguageSettings(); - SaveSettings(); - break; - case MENUACTION_LANG_RUS: - m_PrefsLanguage = LANGUAGE_RUSSIAN; - m_bFrontEnd_ReloadObrTxtGxt = true; - CMenuManager::InitialiseChangedLanguageSettings(); - SaveSettings(); - break; - case MENUACTION_LANG_JAP: - m_PrefsLanguage = LANGUAGE_JAPANESE; - m_bFrontEnd_ReloadObrTxtGxt = true; - InitialiseChangedLanguageSettings(); - SaveSettings(); - break; -#endif case MENUACTION_POPULATESLOTS_CHANGEMENU: PcSaveHelper.PopulateSlotInfo(); @@ -4426,10 +4471,8 @@ CMenuManager::ProcessButtonPresses(void) if (strncmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEDS_TB", 8) == 0) { #ifndef TIDY_UP_PBP ResetHelperText(); - if (!m_bGameNotLoaded) - ChangeScreen(aScreens[m_nCurrScreen].m_PreviousPage[1], aScreens[m_nCurrScreen].m_ParentEntry[1], true, true); - else - ChangeScreen(aScreens[m_nCurrScreen].m_PreviousPage[0], aScreens[m_nCurrScreen].m_ParentEntry[0], true, true); + ChangeScreen(!m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage[1] : aScreens[m_nCurrScreen].m_PreviousPage[0], + GetPreviousPageOption(), true, true); #else goBack = true; break; @@ -4536,16 +4579,6 @@ CMenuManager::ProcessButtonPresses(void) SaveSettings(); } break; -#ifdef IMPROVED_VIDEOMODE - case MENUACTION_SCREENMODE: - if (m_nSelectedScreenMode != m_nPrefsWindowed) { - m_nPrefsWindowed = m_nSelectedScreenMode; - _psSelectScreenVM(m_nPrefsVideoMode); // apply same resolution - SetHelperText(0); - SaveSettings(); - } - break; -#endif case MENUACTION_AUDIOHW: { int selectedProvider = m_nPrefsAudio3DProviderIndex; @@ -4661,6 +4694,31 @@ CMenuManager::ProcessButtonPresses(void) DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1); OutputDebugString("STARTED PLAYING FRONTEND AUDIO TRACK"); break; +#ifdef CUSTOM_FRONTEND_OPTIONS + case MENUACTION_TRIGGERFUNC: + FrontendOption& option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu]; + if (m_nCurrScreen == option.screen && m_nCurrOption == option.screenOptionOrder) { + if (option.type == FEOPTION_SELECT) { + if (!option.onlyApplyOnEnter) { + option.displayedValue++; + if (option.displayedValue >= option.numRightTexts || option.displayedValue < 0) + option.displayedValue = 0; + } + option.changeFunc(option.displayedValue); + *option.value = option.displayedValue; + + } else if (option.type == FEOPTION_DYNAMIC) { + option.buttonPressFunc(FEOPTION_ACTION_SELECT); + } else if (option.type == FEOPTION_REDIRECT) { + ChangeScreen(option.to, option.option, true, option.fadeIn); + } else if (option.type == FEOPTION_GOBACK) { + goBack = true; + } + } else + assert(0 && "Custom frontend options are borked"); + + break; +#endif } } ProcessOnOffMenuOptions(); @@ -4693,7 +4751,7 @@ CMenuManager::ProcessButtonPresses(void) #endif RequestFrontEndShutDown(); } - // It's now in ThingsToDoBeforeLeavingPage() + // It's now in ThingsToDoBeforeGoingBack() #ifndef TIDY_UP_PBP else if (m_nCurrScreen == MENUPAGE_SOUND_SETTINGS) { DMAudio.StopFrontEndTrack(); @@ -4702,10 +4760,10 @@ CMenuManager::ProcessButtonPresses(void) #endif int oldScreen = !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage[1] : aScreens[m_nCurrScreen].m_PreviousPage[0]; - int oldOption = !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_ParentEntry[1] : aScreens[m_nCurrScreen].m_ParentEntry[0]; + int oldOption = GetPreviousPageOption(); if (oldScreen != -1) { - ThingsToDoBeforeLeavingPage(); + ThingsToDoBeforeGoingBack(); #ifdef PS2_LIKE_MENU if (!bottomBarActive && @@ -4803,11 +4861,11 @@ CMenuManager::ProcessButtonPresses(void) if (changeValueBy > 0) { m_PrefsUseWideScreen++; if (m_PrefsUseWideScreen > 2) - m_PrefsUseWideScreen = 2; + m_PrefsUseWideScreen = 0; } else { m_PrefsUseWideScreen--; if (m_PrefsUseWideScreen < 0) - m_PrefsUseWideScreen = 0; + m_PrefsUseWideScreen = 2; } DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0); SaveSettings(); @@ -4834,12 +4892,6 @@ CMenuManager::ProcessButtonPresses(void) } } break; -#ifdef IMPROVED_VIDEOMODE - case MENUACTION_SCREENMODE: - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0); - m_nSelectedScreenMode = !m_nSelectedScreenMode; - break; -#endif case MENUACTION_AUDIOHW: if (m_nPrefsAudio3DProviderIndex != -1) { m_nPrefsAudio3DProviderIndex += changeValueBy; @@ -4862,6 +4914,34 @@ CMenuManager::ProcessButtonPresses(void) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0); SaveSettings(); break; +#ifdef CUSTOM_FRONTEND_OPTIONS + case MENUACTION_TRIGGERFUNC: + FrontendOption& option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu]; + if (m_nCurrScreen == option.screen && m_nCurrOption == option.screenOptionOrder) { + if (option.type == FEOPTION_SELECT) { + if (changeValueBy > 0) { + option.displayedValue++; + if (option.displayedValue >= option.numRightTexts) + option.displayedValue = 0; + } else { + option.displayedValue--; + if (option.displayedValue < 0) + option.displayedValue = option.numRightTexts - 1; + } + if (!option.onlyApplyOnEnter) { + option.changeFunc(option.displayedValue); + *option.value = option.displayedValue; + } + } else if (option.type == FEOPTION_DYNAMIC) { + option.buttonPressFunc(changeValueBy > 0 ? FEOPTION_ACTION_RIGHT : FEOPTION_ACTION_LEFT); + } + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0); + } + else + assert(0 && "Custom frontend options are borked"); + + break; +#endif } ProcessOnOffMenuOptions(); if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) { @@ -5083,7 +5163,7 @@ CMenuManager::SwitchMenuOnAndOff() bottomBarActive = false; #endif #ifdef FIX_BUGS - ThingsToDoBeforeLeavingPage(); + ThingsToDoBeforeGoingBack(); #endif ShutdownJustMenu(); SaveSettings(); @@ -5830,3 +5910,4 @@ uint8 CMenuManager::GetNumberOfMenuOptions() #undef GetBackJustUp #undef GetBackJustDown +#undef ChangeScreen diff --git a/src/core/Frontend.h b/src/core/Frontend.h index 89517528..6f68de33 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -366,13 +366,8 @@ enum eMenuAction MENUACTION_UNK108, MENUACTION_UNK109, MENUACTION_UNK110, -#ifdef MORE_LANGUAGES - MENUACTION_LANG_PL, - MENUACTION_LANG_RUS, - MENUACTION_LANG_JAP, -#endif -#ifdef IMPROVED_VIDEOMODE - MENUACTION_SCREENMODE +#ifdef CUSTOM_FRONTEND_OPTIONS + MENUACTION_TRIGGERFUNC #endif }; @@ -468,7 +463,7 @@ struct CMenuScreen int32 m_Action; // eMenuAction char m_EntryName[8]; int32 m_SaveSlot; // eSaveSlot - int32 m_TargetMenu; // eMenuScreen + int32 m_TargetMenu; // eMenuScreen // FrontendOption ID if it's a custom option } m_aEntries[NUM_MENUROWS]; }; @@ -647,12 +642,13 @@ public: int GetNumOptionsCntrlConfigScreens(); int ConstructStatLine(int); - // New (not in function or inlined in the game) - void ThingsToDoBeforeLeavingPage(); + // New (inlined ones and the ones we can't believe it's not inlined) + void ThingsToDoBeforeGoingBack(); void ScrollUpListByOne(); void ScrollDownListByOne(); void PageUpList(bool); void PageDownList(bool); + int8 GetPreviousPageOption(); // uint8 GetNumberOfMenuOptions(); }; @@ -662,3 +658,4 @@ VALIDATE_SIZE(CMenuManager, 0x564); #endif extern CMenuManager FrontEndMenuManager; +extern CMenuScreen aScreens[]; \ No newline at end of file diff --git a/src/core/Game.cpp b/src/core/Game.cpp index 33afc956..7983a7c3 100644 --- a/src/core/Game.cpp +++ b/src/core/Game.cpp @@ -85,8 +85,7 @@ #include "ZoneCull.h" #include "Zones.h" #include "debugmenu.h" - - +#include "frontendoption.h" eLevelName CGame::currLevel; bool CGame::bDemoMode = true; @@ -234,6 +233,9 @@ bool CGame::InitialiseOnceAfterRW(void) DMAudio.SetMusicFadeVol(127); CWorld::Players[0].SetPlayerSkin(CMenuManager::m_PrefsSkinFile); +#ifdef CUSTOM_FRONTEND_OPTIONS + CustomFrontendOptionsPopulate(); +#endif return true; } diff --git a/src/core/MenuScreens.h b/src/core/MenuScreens.cpp similarity index 95% rename from src/core/MenuScreens.h rename to src/core/MenuScreens.cpp index 6c2ebdb8..ca561af8 100644 --- a/src/core/MenuScreens.h +++ b/src/core/MenuScreens.cpp @@ -1,17 +1,12 @@ -#pragma once +#include "common.h" +#include "Frontend.h" -// TODO: There are some missing/wrong entries in here. - -const CMenuScreen aScreens[] = { +CMenuScreen aScreens[] = { // MENUPAGE_NONE = 0 { "", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, }, // MENUPAGE_STATS = 1 -#ifdef MENU_MAP - { "FET_STA", 1, MENUPAGE_NONE, MENUPAGE_NONE, 5, 3, -#else { "FET_STA", 1, MENUPAGE_NONE, MENUPAGE_NONE, 5, 2, -#endif MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, }, @@ -24,11 +19,7 @@ const CMenuScreen aScreens[] = { }, // MENUPAGE_BRIEFS = 3 -#ifdef MENU_MAP - { "FET_BRE", 1, MENUPAGE_NONE, MENUPAGE_NONE, 6, 4, -#else { "FET_BRE", 1, MENUPAGE_NONE, MENUPAGE_NONE, 6, 3, -#endif MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, }, @@ -62,9 +53,6 @@ const CMenuScreen aScreens[] = { MENUACTION_SUBTITLES, "FED_SUB", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, MENUACTION_WIDESCREEN, "FED_WIS", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, MENUACTION_SCREENRES, "FED_RES", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, -#ifdef IMPROVED_VIDEOMODE - MENUACTION_SCREENMODE, "SCRFOR", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, -#endif MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, }, @@ -76,11 +64,6 @@ const CMenuScreen aScreens[] = { MENUACTION_LANG_GER, "FEL_GER", SAVESLOT_NONE, MENUPAGE_NONE, MENUACTION_LANG_ITA, "FEL_ITA", SAVESLOT_NONE, MENUPAGE_NONE, MENUACTION_LANG_SPA, "FEL_SPA", SAVESLOT_NONE, MENUPAGE_NONE, -#ifdef MORE_LANGUAGES - MENUACTION_LANG_PL, "FEL_POL", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_LANG_RUS, "FEL_RUS", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_LANG_JAP, "FEL_JAP", SAVESLOT_NONE, MENUPAGE_NONE, -#endif MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, }, @@ -333,11 +316,7 @@ const CMenuScreen aScreens[] = { }, // MENUPAGE_OPTIONS = 41 -#ifdef MENU_MAP - { "FET_OPT", 1, MENUPAGE_NONE, MENUPAGE_NONE, 1, 5, -#else { "FET_OPT", 1, MENUPAGE_NONE, MENUPAGE_NONE, 1, 4, -#endif MENUACTION_CHANGEMENU, "FET_CTL", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, MENUACTION_LOADRADIO, "FET_AUD", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, MENUACTION_CHANGEMENU, "FET_DIS", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, @@ -347,11 +326,7 @@ const CMenuScreen aScreens[] = { }, // MENUPAGE_EXIT = 42 -#ifdef MENU_MAP - { "FET_QG", 1, MENUPAGE_NONE, MENUPAGE_NONE, 2, 6, -#else { "FET_QG", 1, MENUPAGE_NONE, MENUPAGE_NONE, 2, 5, -#endif MENUACTION_LABEL, "FEQ_SRE", SAVESLOT_NONE, MENUPAGE_NONE, MENUACTION_CHANGEMENU, "FEM_NO", SAVESLOT_NONE, MENUPAGE_NONE, MENUACTION_CANCELGAME, "FEM_YES", SAVESLOT_NONE, MENUPAGE_NONE, @@ -412,9 +387,6 @@ const CMenuScreen aScreens[] = { { "FET_PAU", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, MENUACTION_RESUME, "FEM_RES", SAVESLOT_NONE, MENUPAGE_NONE, MENUACTION_CHANGEMENU, "FEN_STA", SAVESLOT_NONE, MENUPAGE_NEW_GAME, -#ifdef MENU_MAP - MENUACTION_CHANGEMENU, "FEG_MAP", SAVESLOT_NONE, MENUPAGE_MAP, -#endif MENUACTION_CHANGEMENU, "FEP_STA", SAVESLOT_NONE, MENUPAGE_STATS, MENUACTION_CHANGEMENU, "FEP_BRI", SAVESLOT_NONE, MENUPAGE_BRIEFS, MENUACTION_CHANGEMENU, "FET_OPT", SAVESLOT_NONE, MENUPAGE_OPTIONS, @@ -463,4 +435,4 @@ const CMenuScreen aScreens[] = { MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, }, #endif -}; +}; \ No newline at end of file diff --git a/src/core/config.h b/src/core/config.h index f43067d7..b7a811a0 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -196,6 +196,7 @@ enum Config { #define USE_TXD_CDIMAGE // generate and load textures from txd.img #define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number //#define USE_TEXTURE_POOL +#define CUSTOM_FRONTEND_OPTIONS // Particle //#define PC_PARTICLE diff --git a/src/core/main.cpp b/src/core/main.cpp index 666758c8..b5e222be 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -95,7 +95,6 @@ void TheGame(void); void DebugMenuPopulate(void); #endif - void ValidateVersion() { diff --git a/src/core/re3.cpp b/src/core/re3.cpp index 883caec5..df394056 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -27,6 +27,7 @@ #include "Radar.h" #include "debugmenu.h" #include "Frontend.h" +#include "Text.h" #ifndef _WIN32 #include "assert.h" @@ -66,6 +67,100 @@ mysrand(unsigned int seed) myrand_seed = seed; } +#ifdef CUSTOM_FRONTEND_OPTIONS +#include "frontendoption.h" +#include "platform.h" + +void ReloadFrontendOptions(void) +{ + RemoveCustomFrontendOptions(); + CustomFrontendOptionsPopulate(); +} + +#ifdef MORE_LANGUAGES +void LangPolSelect(int8 action) +{ + if (action == FEOPTION_ACTION_SELECT) { + FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_POLISH; + FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true; + FrontEndMenuManager.InitialiseChangedLanguageSettings(); + FrontEndMenuManager.SaveSettings(); + } +} + +void LangRusSelect(int8 action) +{ + if (action == FEOPTION_ACTION_SELECT) { + FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_RUSSIAN; + FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true; + FrontEndMenuManager.InitialiseChangedLanguageSettings(); + FrontEndMenuManager.SaveSettings(); + } +} + +void LangJapSelect(int8 action) +{ + if (action == FEOPTION_ACTION_SELECT) { + FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_JAPANESE; + FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true; + FrontEndMenuManager.InitialiseChangedLanguageSettings(); + FrontEndMenuManager.SaveSettings(); + } +} +#endif + +#ifdef IMPROVED_VIDEOMODE +void ScreenModeChange(int8 displayedValue) +{ + if (displayedValue != FrontEndMenuManager.m_nPrefsWindowed) { + FrontEndMenuManager.m_nPrefsWindowed = displayedValue; + _psSelectScreenVM(FrontEndMenuManager.m_nPrefsVideoMode); // apply same resolution + FrontEndMenuManager.SetHelperText(0); + FrontEndMenuManager.SaveSettings(); + } +} +#endif + +#ifdef FREE_CAM +void ToggleFreeCam(int8 action) +{ + if (action == FEOPTION_ACTION_SELECT) { + TheCamera.bFreeCam = !TheCamera.bFreeCam; + FrontEndMenuManager.SaveSettings(); + } +} +#endif + +// Reloaded on language change, so you can use hardcoded wchar* and TheText.Get with peace of mind +void +CustomFrontendOptionsPopulate(void) +{ +#ifdef MORE_LANGUAGES + FrontendOptionSetPosition(MENUPAGE_LANGUAGE_SETTINGS); + FrontendOptionAddDynamic(TheText.Get("FEL_POL"), nil, LangPolSelect, nil); + FrontendOptionAddDynamic(TheText.Get("FEL_RUS"), nil, LangRusSelect, nil); + FrontendOptionAddDynamic(TheText.Get("FEL_JAP"), nil, LangJapSelect, nil); +#endif + +#ifdef IMPROVED_VIDEOMODE + static const wchar *screenModes[] = { (wchar*)L"FULLSCREEN", (wchar*)L"WINDOWED" }; + FrontendOptionSetPosition(MENUPAGE_GRAPHICS_SETTINGS, 8); + FrontendOptionAddSelect(TheText.Get("SCRFOR"), screenModes, 2, (int8*)&FrontEndMenuManager.m_nPrefsWindowed, true, ScreenModeChange, nil); +#endif + +#ifdef MENU_MAP + FrontendOptionSetPosition(MENUPAGE_PAUSE_MENU, 2); + FrontendOptionAddRedirect(TheText.Get("FEG_MAP"), MENUPAGE_MAP); +#endif + +#ifdef FREE_CAM + static const wchar *text = (wchar*)L"TOGGLE FREE CAM"; + FrontendOptionSetPosition(MENUPAGE_CONTROLLER_PC, 1); + FrontendOptionAddDynamic(text, nil, ToggleFreeCam, nil); +#endif +} +#endif + #ifdef DEBUGMENU void WeaponCheat(); void HealthCheat(); @@ -382,6 +477,9 @@ DebugMenuPopulate(void) DebugMenuAddCmd("Debug", "Catalina Fly Away", CHeli::MakeCatalinaHeliFlyAway); DebugMenuAddVarBool8("Debug", "Script Heli On", &CHeli::ScriptHeliOn, nil); +#ifdef CUSTOM_FRONTEND_OPTIONS + DebugMenuAddCmd("Debug", "Reload custom frontend options", ReloadFrontendOptions); +#endif #ifdef TOGGLEABLE_BETA_FEATURES DebugMenuAddVarBool8("Debug", "Toggle popping heads on headshot", &CPed::bPopHeadsOnHeadshot, nil); DebugMenuAddVarBool8("Debug", "Toggle peds running to phones to report crimes", &CPed::bMakePedsRunToPhonesToReportCrimes, nil); diff --git a/src/extras/frontendoption.cpp b/src/extras/frontendoption.cpp new file mode 100644 index 00000000..7b7ad229 --- /dev/null +++ b/src/extras/frontendoption.cpp @@ -0,0 +1,163 @@ +#include "common.h" + +#ifdef CUSTOM_FRONTEND_OPTIONS +#include "frontendoption.h" + +int numCustomFrontendOptions = 0; +FrontendOption *customFrontendOptions; + +int optionCursor = -1; +eMenuScreen currentMenu; + +void ChangeScreen(eMenuScreen screen, int option, bool fadeIn) +{ + FrontEndMenuManager.m_nPrevScreen = FrontEndMenuManager.m_nCurrScreen; + FrontEndMenuManager.m_nCurrScreen = screen; + FrontEndMenuManager.m_nCurrOption = option; + if (fadeIn) + FrontEndMenuManager.m_nMenuFadeAlpha = 0; +} + +void GoBack(bool fadeIn) +{ + int screen = !FrontEndMenuManager.m_bGameNotLoaded ? + aScreens[FrontEndMenuManager.m_nCurrScreen].m_PreviousPage[1] : aScreens[FrontEndMenuManager.m_nCurrScreen].m_PreviousPage[0]; + int option = !FrontEndMenuManager.m_bGameNotLoaded ? + aScreens[FrontEndMenuManager.m_nCurrScreen].m_ParentEntry[1] : aScreens[FrontEndMenuManager.m_nCurrScreen].m_ParentEntry[0]; + + FrontEndMenuManager.ThingsToDoBeforeGoingBack(); + + ChangeScreen((eMenuScreen)screen, option, fadeIn); +} + +uint8 +GetNumberOfMenuOptions(int screen) +{ + uint8 Rows = 0; + for (int i = 0; i < NUM_MENUROWS; i++) { + if (aScreens[screen].m_aEntries[i].m_Action == MENUACTION_NOTHING) + break; + + ++Rows; + } + return Rows; +} + +// Used before reloading in InitialiseChangedLanguageSettings and debugmenu +void +RemoveCustomFrontendOptions() +{ + for (int i = 0; i < MENUPAGES; i++) { + for (int j = 0; j < NUM_MENUROWS; j++) { + if (aScreens[i].m_aEntries[j].m_Action == MENUACTION_TRIGGERFUNC) { + aScreens[i].m_aEntries[j].m_Action = MENUACTION_NOTHING; + aScreens[i].m_aEntries[j].m_EntryName[0] = '\0'; + } + } + } + free(customFrontendOptions); + numCustomFrontendOptions = 0; +} + +int8 RegisterNewOption(int screen) +{ + numCustomFrontendOptions++; + if (numCustomFrontendOptions == 1) + customFrontendOptions = (FrontendOption*)malloc(numCustomFrontendOptions * sizeof(FrontendOption)); + else + customFrontendOptions = (FrontendOption*)realloc(customFrontendOptions, numCustomFrontendOptions * sizeof(FrontendOption)); + + uint8 nth = GetNumberOfMenuOptions(screen); + if (optionCursor < 0) { + if (optionCursor == -1) { + if (!strcmp(aScreens[screen].m_aEntries[nth - 1].m_EntryName, "FEDS_TB") || !strcmp(aScreens[screen].m_aEntries[nth - 1].m_EntryName, "FESZ_CA")) { + // Move back button one below + memcpy(&aScreens[screen].m_aEntries[nth], &aScreens[screen].m_aEntries[nth - 1], sizeof(CMenuScreen::CMenuEntry)); + nth--; + } + } + } else { + if (aScreens[screen].m_aEntries[optionCursor].m_Action != MENUACTION_NOTHING) { + for (int i = nth - 1; i >= optionCursor; i--) { + memcpy(&aScreens[screen].m_aEntries[i + 1], &aScreens[screen].m_aEntries[i], sizeof(CMenuScreen::CMenuEntry)); + } + } + nth = optionCursor; + optionCursor++; + } + + aScreens[screen].m_aEntries[nth].m_Action = MENUACTION_TRIGGERFUNC; + aScreens[screen].m_aEntries[nth].m_TargetMenu = numCustomFrontendOptions - 1; + aScreens[screen].m_aEntries[nth].m_EntryName[0] = 1; // just something to fool it + return nth; +} + +void FrontendOptionSetPosition(eMenuScreen screen, int8 option) +{ + currentMenu = screen; + optionCursor = option; +} + +void FrontendOptionAddSelect(const wchar* leftText, const wchar** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, ReturnPrevPageFunc returnPrevPageFunc) +{ + int8 screenOptionOrder = RegisterNewOption(currentMenu); + + FrontendOption& option = customFrontendOptions[numCustomFrontendOptions - 1]; + option.screen = currentMenu; + option.type = FEOPTION_SELECT; + option.leftText = leftText; + option.rightTexts = rightTexts; + option.numRightTexts = numRightTexts; + option.value = var; + option.displayedValue = *var; + option.onlyApplyOnEnter = onlyApplyOnEnter; + option.changeFunc = changeFunc; + option.screenOptionOrder = screenOptionOrder; + option.returnPrevPageFunc = returnPrevPageFunc; +} + +void FrontendOptionAddDynamic(const wchar* leftText, DrawFunc drawFunc, ButtonPressFunc buttonPressFunc, ReturnPrevPageFunc returnPrevPageFunc) +{ + int8 screenOptionOrder = RegisterNewOption(currentMenu); + + FrontendOption& option = customFrontendOptions[numCustomFrontendOptions - 1]; + option.screen = currentMenu; + option.type = FEOPTION_DYNAMIC; + option.drawFunc = drawFunc; + option.buttonPressFunc = buttonPressFunc; + option.leftText = leftText; + option.onlyApplyOnEnter = false; + option.screenOptionOrder = screenOptionOrder; + option.returnPrevPageFunc = returnPrevPageFunc; +} + +void FrontendOptionAddRedirect(const wchar* text, eMenuScreen to, int8 selectedOption, bool fadeIn) +{ + int8 screenOptionOrder = RegisterNewOption(currentMenu); + + FrontendOption &option = customFrontendOptions[numCustomFrontendOptions - 1]; + option.screen = currentMenu; + option.type = FEOPTION_REDIRECT; + option.to = to; + option.option = selectedOption; + option.fadeIn = fadeIn; + option.leftText = text; + option.onlyApplyOnEnter = false; + option.screenOptionOrder = screenOptionOrder; + option.returnPrevPageFunc = nil; +} + +void FrontendOptionAddBackButton(const wchar* text, bool fadeIn) +{ + int8 screenOptionOrder = RegisterNewOption(currentMenu); + + FrontendOption& option = customFrontendOptions[numCustomFrontendOptions - 1]; + option.screen = currentMenu; + option.type = FEOPTION_GOBACK; + option.fadeIn = fadeIn; + option.leftText = text; + option.onlyApplyOnEnter = false; + option.screenOptionOrder = screenOptionOrder; + option.returnPrevPageFunc = nil; +} +#endif \ No newline at end of file diff --git a/src/extras/frontendoption.h b/src/extras/frontendoption.h new file mode 100644 index 00000000..6c6ac20c --- /dev/null +++ b/src/extras/frontendoption.h @@ -0,0 +1,86 @@ +#pragma once +#include "common.h" + +#ifdef CUSTOM_FRONTEND_OPTIONS +#include "Frontend.h" + +// Warning: All of the code relies on that you won't use more then NUM_MENUROWS(18) options on one page. Also congrats if you can make 18 options visible at once. + + +// Static/select: User allocates variable, passes it to function and it's set automatically from input among the strings given to function, +// then you can handle ChangeFunc and ReturnPrevPageFunc if needed. +// +// Dynamic: Function doesn't accept value pointer, user should do operations with handling ButtonPressFunc. +// Right-side text can be set via DrawFunc, which is called on every draw. ReturnPrevPageFunc is also here if needed. + +#define FEOPTION_SELECT 0 +#define FEOPTION_DYNAMIC 1 +#define FEOPTION_REDIRECT 2 +#define FEOPTION_GOBACK 3 + +#define FEOPTION_ACTION_LEFT 0 +#define FEOPTION_ACTION_RIGHT 1 +#define FEOPTION_ACTION_SELECT 2 + +void RemoveCustomFrontendOptions(); +void CustomFrontendOptionsPopulate(); + +// for static and dynamic options +typedef void (*ReturnPrevPageFunc)(); + +// for static options +typedef void (*ChangeFunc)(int8 displayedValue); // called before updating the value + +// for dynamic options +typedef void (*DrawFunc)(wchar* out, bool* disabled); // parameters should be set by user, both is allocated. disabled option will be dark yellow +typedef void (*ButtonPressFunc)(int8 action); // see FEOPTION_ACTIONs above + +struct FrontendOption +{ + int8 type; + int8 screenOptionOrder; + eMenuScreen screen; + const wchar* leftText; + ReturnPrevPageFunc returnPrevPageFunc; + + union { + // Only for dynamic + struct { + DrawFunc drawFunc; + ButtonPressFunc buttonPressFunc; + }; + + // Only for static/select + struct { + const wchar** rightTexts; + int8 numRightTexts; + int8 *value; + int8 displayedValue; // if onlyApplyOnEnter enabled + bool onlyApplyOnEnter; + ChangeFunc changeFunc; + }; + + // Only for redirect + struct { + eMenuScreen to; + int8 option; + bool fadeIn; + }; + }; +}; + +extern int numCustomFrontendOptions; +extern FrontendOption* customFrontendOptions; + +// To be used in ButtonPressFunc / ChangeFunc(but that would be weird): +void ChangeScreen(eMenuScreen screen, int option = 0, bool fadeIn = true); +void GoBack(bool fadeIn = true); + +// If option is positive number, all calls will increase it before using it (you can think it as cursor). -1 means before the back button, -2 is end of page +void FrontendOptionSetPosition(eMenuScreen screen, int8 option = -1); + +void FrontendOptionAddSelect(const wchar* leftText, const wchar** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, ReturnPrevPageFunc returnPrevPageFunc); +void FrontendOptionAddDynamic(const wchar* leftText, DrawFunc rightTextDrawFunc, ButtonPressFunc buttonPressFunc, ReturnPrevPageFunc returnPrevPageFunc); +void FrontendOptionAddRedirect(const wchar* text, eMenuScreen to, int8 selectedOption = 0, bool fadeIn = true); +void FrontendOptionAddBackButton(const wchar* text, bool fadeIn = true); +#endif \ No newline at end of file diff --git a/src/skel/glfw/glfw.cpp b/src/skel/glfw/glfw.cpp index 21115585..3ef0ab63 100644 --- a/src/skel/glfw/glfw.cpp +++ b/src/skel/glfw/glfw.cpp @@ -1747,7 +1747,7 @@ void CapturePad(RwInt32 padID) void joysChangeCB(int jid, int event) { - if (event == GLFW_CONNECTED) + if (event == GLFW_CONNECTED && !IsThisJoystickBlacklisted(jid)) { if (PSGLOBAL(joy1id) == -1) PSGLOBAL(joy1id) = jid; From 98a97a32fac0e97bd9810128d97c418ead52330e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Thu, 28 May 2020 11:49:58 +0300 Subject: [PATCH 07/26] config reorganization --- src/core/config.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/core/config.h b/src/core/config.h index a652c9fe..9b620cef 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -192,11 +192,14 @@ enum Config { #define FIX_BUGS // fixes bugs that we've came across during reversing, TODO: use this more #define TOGGLEABLE_BETA_FEATURES // toggleable from debug menu. not too many things #define MORE_LANGUAGES // Add more translations to the game +#define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible + +// Rendering/display +#define ASPECT_RATIO_SCALE // Not just makes everything scale with aspect ratio, also adds support for all aspect ratios #define DEFAULT_NATIVE_RESOLUTION // Set default video mode to your native resolution (fixes Windows 10 launch) #define USE_TXD_CDIMAGE // generate and load textures from txd.img #define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number //#define USE_TEXTURE_POOL -#define CUSTOM_FRONTEND_OPTIONS // Particle //#define PC_PARTICLE @@ -213,7 +216,6 @@ enum Config { #define REGISTER_START_BUTTON // Hud, frontend and radar -#define ASPECT_RATIO_SCALE // Not just makes everything scale with aspect ratio, also adds support for all aspect ratios #define TRIANGULAR_BLIPS // height indicating triangular radar blips, as in VC #define PS2_SAVE_DIALOG // PS2 style save dialog with transparent black box // #define PS2_LIKE_MENU // An effort to recreate PS2 menu, cycling through tabs, different bg etc. @@ -223,6 +225,7 @@ enum Config { // #define CIRCLE_BACK_BUTTON #define HUD_ENHANCEMENTS // Adjusts some aspects to make the HUD look/behave a little bit better. #define BETA_SLIDING_TEXT +#define CUSTOM_FRONTEND_OPTIONS // Script #define USE_DEBUG_SCRIPT_LOADER // makes game load main_freeroam.scm by default @@ -231,8 +234,6 @@ enum Config { #define MISSION_REPLAY // mobile feature //#define SIMPLIER_MISSIONS // apply simplifications from mobile -#define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible - // Replay //#define DONT_FIX_REPLAY_BUGS // keeps various bugs in CReplay, some of which are fairly cool! //#define USE_BETA_REPLAY_MODE // adds another replay mode, a few seconds slomo (caution: buggy!) From e6401bce181b2a9eb1ba31db0945e79277207a23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Thu, 28 May 2020 12:46:51 +0300 Subject: [PATCH 08/26] Detect R and start game on menu --- src/control/Script.cpp | 14 +++----------- src/control/Script.h | 4 ++++ src/core/Frontend.cpp | 21 +++++++++++++++++++++ 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/control/Script.cpp b/src/control/Script.cpp index 0b0341b4..bc15a695 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -538,22 +538,14 @@ void CRunningScript::Init() } #ifdef USE_DEBUG_SCRIPT_LOADER +int scriptToLoad = 0; + #ifdef _WIN32 #include #endif int open_script() { - static int scriptToLoad = 0; - - // Doesn't work because of CGame::Initialise is blocking - /* - if (glfwGetKey(PSGLOBAL(window), GLFW_KEY_G) == GLFW_PRESS) - scriptToLoad = 0; - if (glfwGetKey(PSGLOBAL(window), GLFW_KEY_R) == GLFW_PRESS) - scriptToLoad = 1; - if (glfwGetKey(PSGLOBAL(window), GLFW_KEY_D) == GLFW_PRESS) - scriptToLoad = 2; - */ + // glfwGetKey doesn't work because of CGame::Initialise is blocking #ifdef _WIN32 if (GetAsyncKeyState('G') & 0x8000) scriptToLoad = 0; diff --git a/src/control/Script.h b/src/control/Script.h index 743fad99..7964ec6c 100644 --- a/src/control/Script.h +++ b/src/control/Script.h @@ -521,3 +521,7 @@ extern bool doingMissionRetry; uint32 AddExtraDeathDelay(); void RetryMission(int, int); #endif + +#ifdef USE_DEBUG_SCRIPT_LOADER +extern int scriptToLoad; +#endif \ No newline at end of file diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index 53a95ae6..cdacc0a4 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -3568,6 +3568,9 @@ CMenuManager::Process(void) } #endif if (CheckSlotDataValid(m_nCurrSaveSlot)) { +#ifdef USE_DEBUG_SCRIPT_LOADER + scriptToLoad = 0; +#endif TheCamera.m_bUseMouse3rdPerson = m_ControlMethod == CONTROL_STANDARD; if (m_PrefsVsyncDisp != m_PrefsVsync) m_PrefsVsync = m_PrefsVsyncDisp; @@ -3688,6 +3691,24 @@ CMenuManager::ProcessButtonPresses(void) bool assumeIncrease = false; #endif +#ifdef USE_DEBUG_SCRIPT_LOADER + if (m_nCurrScreen == MENUPAGE_START_MENU || m_nCurrScreen == MENUPAGE_NEW_GAME || m_nCurrScreen == MENUPAGE_NEW_GAME_RELOAD) { +#ifdef RW_GL3 + if (glfwGetKey(PSGLOBAL(window), GLFW_KEY_R) == GLFW_PRESS) { + scriptToLoad = 1; + DoSettingsBeforeStartingAGame(); + return; + } +#elif defined _WIN32 + if (GetAsyncKeyState('R') & 0x8000) { + scriptToLoad = 1; + DoSettingsBeforeStartingAGame(); + return; + } +#endif + } +#endif + if (!m_bShowMouse && (m_nMouseOldPosX != m_nMousePosX || m_nMouseOldPosY != m_nMousePosY)) { m_bShowMouse = true; } From a61736c51b3712d78cdf76afe466eb48b2be5227 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Thu, 28 May 2020 13:08:21 +0300 Subject: [PATCH 09/26] theoretically fix linux build --- src/core/Frontend.cpp | 12 ++++++------ src/core/Frontend.h | 12 ++++++------ src/core/MenuScreens.cpp | 2 ++ 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index cdacc0a4..fc3a05d9 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -315,7 +315,7 @@ ScaleAndCenterX(float x) // --- Functions not in the game/inlined starts -inline void +void CMenuManager::ScrollUpListByOne() { if (m_nSelectedListRow == m_nFirstVisibleRowOnList) { @@ -329,7 +329,7 @@ CMenuManager::ScrollUpListByOne() } } -inline void +void CMenuManager::ScrollDownListByOne() { if (m_nSelectedListRow == m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1) { @@ -345,7 +345,7 @@ CMenuManager::ScrollDownListByOne() } } -inline void +void CMenuManager::PageUpList(bool playSoundOnSuccess) { if (m_nTotalListRow > MAX_VISIBLE_LIST_ROW) { @@ -363,7 +363,7 @@ CMenuManager::PageUpList(bool playSoundOnSuccess) } } -inline void +void CMenuManager::PageDownList(bool playSoundOnSuccess) { if (m_nTotalListRow > MAX_VISIBLE_LIST_ROW) { @@ -381,7 +381,7 @@ CMenuManager::PageDownList(bool playSoundOnSuccess) } } -inline void +void CMenuManager::ThingsToDoBeforeGoingBack() { if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) && strcmp(m_aSkinName, m_PrefsSkinFile) != 0) { @@ -419,7 +419,7 @@ CMenuManager::ThingsToDoBeforeGoingBack() #endif } -inline int8 +int8 CMenuManager::GetPreviousPageOption() { #ifndef CUSTOM_FRONTEND_OPTIONS diff --git a/src/core/Frontend.h b/src/core/Frontend.h index aa2b92f5..9a364b71 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -647,12 +647,12 @@ public: int ConstructStatLine(int); // New (inlined ones and the ones we can't believe it's not inlined) - void ThingsToDoBeforeGoingBack(); - void ScrollUpListByOne(); - void ScrollDownListByOne(); - void PageUpList(bool); - void PageDownList(bool); - int8 GetPreviousPageOption(); + inline void ThingsToDoBeforeGoingBack(); + inline void ScrollUpListByOne(); + inline void ScrollDownListByOne(); + inline void PageUpList(bool); + inline void PageDownList(bool); + inline int8 GetPreviousPageOption(); // uint8 GetNumberOfMenuOptions(); }; diff --git a/src/core/MenuScreens.cpp b/src/core/MenuScreens.cpp index be914c09..4ced8c0b 100644 --- a/src/core/MenuScreens.cpp +++ b/src/core/MenuScreens.cpp @@ -1,6 +1,8 @@ #include "common.h" #include "Frontend.h" +// If you want to add new options, please don't do that here and see CustomFrontendOptionsPopulate in re3.cpp. + CMenuScreen aScreens[] = { // MENUPAGE_NONE = 0 { "", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, }, From 111d23beabbc580d2f1befec11b2fd114f297d5f Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Thu, 28 May 2020 17:21:00 +0300 Subject: [PATCH 10/26] fix --- src/core/World.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/World.cpp b/src/core/World.cpp index 39681428..c3633d77 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -120,14 +120,14 @@ CWorld::ClearExcitingStuffFromArea(const CVector &pos, float radius, bool bRemov for(int32 i = 0; i < pedPool->GetSize(); i++) { CPed *pPed = pedPool->GetSlot(i); if(pPed && !pPed->IsPlayer() && pPed->CanBeDeleted() && - CVector2D(pPed->GetPosition() - pos).MagnitudeSqr() < radius) { + CVector2D(pPed->GetPosition() - pos).MagnitudeSqr() < SQR(radius)) { CPopulation::RemovePed(pPed); } } CVehiclePool *VehiclePool = CPools::GetVehiclePool(); for(int32 i = 0; i < VehiclePool->GetSize(); i++) { CVehicle *pVehicle = VehiclePool->GetSlot(i); - if(pVehicle && CVector2D(pVehicle->GetPosition() - pos).MagnitudeSqr() < radius && + if(pVehicle && CVector2D(pVehicle->GetPosition() - pos).MagnitudeSqr() < SQR(radius) && !pVehicle->bIsLocked && pVehicle->CanBeDeleted()) { if(pVehicle->pDriver) { CPopulation::RemovePed(pVehicle->pDriver); From 9acf27fc5359ec8a4e047a35384ca28270145db8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Thu, 28 May 2020 13:39:08 +0300 Subject: [PATCH 11/26] remove inlining attempts + reload frontend options for real --- src/core/Frontend.h | 15 ++++++++------- src/extras/frontendoption.cpp | 9 +++++++-- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/core/Frontend.h b/src/core/Frontend.h index 9a364b71..7d4cdacc 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -646,13 +646,14 @@ public: int GetNumOptionsCntrlConfigScreens(); int ConstructStatLine(int); - // New (inlined ones and the ones we can't believe it's not inlined) - inline void ThingsToDoBeforeGoingBack(); - inline void ScrollUpListByOne(); - inline void ScrollDownListByOne(); - inline void PageUpList(bool); - inline void PageDownList(bool); - inline int8 GetPreviousPageOption(); + // Those are either inlined in game, not in function yet, or I can't believe that they're not inlined. + // Names were made up by me. + void ThingsToDoBeforeGoingBack(); + void ScrollUpListByOne(); + void ScrollDownListByOne(); + void PageUpList(bool); + void PageDownList(bool); + int8 GetPreviousPageOption(); // uint8 GetNumberOfMenuOptions(); }; diff --git a/src/extras/frontendoption.cpp b/src/extras/frontendoption.cpp index 7b7ad229..6ab2801c 100644 --- a/src/extras/frontendoption.cpp +++ b/src/extras/frontendoption.cpp @@ -50,8 +50,13 @@ RemoveCustomFrontendOptions() for (int i = 0; i < MENUPAGES; i++) { for (int j = 0; j < NUM_MENUROWS; j++) { if (aScreens[i].m_aEntries[j].m_Action == MENUACTION_TRIGGERFUNC) { - aScreens[i].m_aEntries[j].m_Action = MENUACTION_NOTHING; - aScreens[i].m_aEntries[j].m_EntryName[0] = '\0'; + int k; + for (k = j; k < NUM_MENUROWS-1; k++) { + memcpy(&aScreens[i].m_aEntries[k], &aScreens[i].m_aEntries[k+1], sizeof(CMenuScreen::CMenuEntry)); + } + aScreens[i].m_aEntries[k].m_Action = MENUACTION_NOTHING; + aScreens[i].m_aEntries[k].m_EntryName[0] = '\0'; + j--; } } } From 20cacb18f0ed75d51766d0006d9181613842e95c Mon Sep 17 00:00:00 2001 From: rollschuh2282 <53496587+rollschuh2282@users.noreply.github.com> Date: Fri, 29 May 2020 12:03:32 +0200 Subject: [PATCH 12/26] Add files via upload --- src/core/config.h | 4 ++-- src/core/main.cpp | 8 ++++++++ src/core/main.h | 4 ++++ src/core/re3.cpp | 6 ++++++ 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/core/config.h b/src/core/config.h index 9b620cef..837d8165 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -186,7 +186,7 @@ enum Config { # define NO_CDCHECK # define CHATTYSPLASH // print what the game is loading # define DEBUGMENU -//# define TIMEBARS // print debug timers +# define TIMEBARS // print debug timers #endif #define FIX_BUGS // fixes bugs that we've came across during reversing, TODO: use this more @@ -228,7 +228,7 @@ enum Config { #define CUSTOM_FRONTEND_OPTIONS // Script -#define USE_DEBUG_SCRIPT_LOADER // makes game load main_freeroam.scm by default +#define USE_DEBUG_SCRIPT_LOADER // Loads main.scm by default. Hold R for main_freeroam.scm and D for main_d.scm #define USE_MEASUREMENTS_IN_METERS // makes game use meters instead of feet in script #define USE_PRECISE_MEASUREMENT_CONVERTION // makes game convert feet to meeters more precisely #define MISSION_REPLAY // mobile feature diff --git a/src/core/main.cpp b/src/core/main.cpp index b5e222be..a69890b0 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -73,6 +73,10 @@ float FramesPerSecond = 30.0f; bool gbPrintShite = false; bool gbModelViewer; +//Custom Timebars Toggle +#ifdef TIMEBARS +bool gbShowTimebars; +#endif int32 frameCount; @@ -1096,8 +1100,12 @@ Idle(void *arg) #endif CCredits::Render(); + #ifdef TIMEBARS +//Custom Timebars toggle + if (gbShowTimebars) tbDisplay(); + #endif DoRWStuffEndOfFrame(); diff --git a/src/core/main.h b/src/core/main.h index 32a880d6..5c514bbb 100644 --- a/src/core/main.h +++ b/src/core/main.h @@ -14,6 +14,10 @@ extern wchar gUString[256]; extern wchar gUString2[256]; extern bool gbPrintShite; extern bool gbModelViewer; +//Custom Timebars Toggle +#ifdef TIMEBARS +extern bool gbShowTimebars; +#endif class CSprite2d; diff --git a/src/core/re3.cpp b/src/core/re3.cpp index df394056..c77cf6d9 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -28,6 +28,8 @@ #include "debugmenu.h" #include "Frontend.h" #include "Text.h" +#include "WaterLevel.h" +#include "main.h" #ifndef _WIN32 #include "assert.h" @@ -459,6 +461,7 @@ DebugMenuPopulate(void) DebugMenuAddVarBool8("Render", "Don't render Peds", &gbDontRenderPeds, nil); DebugMenuAddVarBool8("Render", "Don't render Vehicles", &gbDontRenderVehicles, nil); DebugMenuAddVarBool8("Render", "Don't render Objects", &gbDontRenderObjects, nil); + DebugMenuAddVarBool8("Render", "Donīt Render Water", &gbDontRenderWater, nil); DebugMenuAddVarBool8("Debug", "Edit on", &CSceneEdit::m_bEditOn, nil); #ifdef MENU_MAP @@ -488,6 +491,9 @@ DebugMenuPopulate(void) DebugMenuAddCmd("Debug", "Start Credits", CCredits::Start); DebugMenuAddCmd("Debug", "Stop Credits", CCredits::Stop); + DebugMenuAddVarBool8("Debug", "Show DebugStuffInRelease", &gbDebugStuffInRelease, nil); + DebugMenuAddVarBool8("Debug", "Show Timebars", &gbShowTimebars, nil); + extern bool PrintDebugCode; extern int16 DebugCamMode; DebugMenuAddVarBool8("Cam", "Use mouse Cam", &CCamera::m_bUseMouse3rdPerson, nil); From 2d5f7d92e5ced42e787caabcaa6c5b535c4cdfd1 Mon Sep 17 00:00:00 2001 From: rollschuh2282 <53496587+rollschuh2282@users.noreply.github.com> Date: Fri, 29 May 2020 12:04:20 +0200 Subject: [PATCH 13/26] Add files via upload --- src/render/WaterLevel.cpp | 7 +++++++ src/render/WaterLevel.h | 2 ++ 2 files changed, 9 insertions(+) diff --git a/src/render/WaterLevel.cpp b/src/render/WaterLevel.cpp index 1a28ce83..6133b1d7 100644 --- a/src/render/WaterLevel.cpp +++ b/src/render/WaterLevel.cpp @@ -35,6 +35,8 @@ bool CWaterLevel::WavesCalculatedThisFrame; RpAtomic *CWaterLevel::ms_pWavyAtomic; RpGeometry *CWaterLevel::apGeomArray[8]; int16 CWaterLevel::nGeomUsed; +//"Custom" Donīt Render Water Toggle +bool gbDontRenderWater; //RwTexture *gpWaterTex; //RwRaster *gpWaterRaster; @@ -332,6 +334,11 @@ SectorRadius(float fSize) void CWaterLevel::RenderWater() { +//"Custom" Donīt Render Water Toggle +#ifndef MASTER + if (gbDontRenderWater) + return; +#endif bool bUseCamEndX = false; bool bUseCamStartY = false; diff --git a/src/render/WaterLevel.h b/src/render/WaterLevel.h index 985c9744..325be0a5 100644 --- a/src/render/WaterLevel.h +++ b/src/render/WaterLevel.h @@ -65,6 +65,8 @@ #define MAX_BOAT_WAKES 8 extern RwRaster* gpWaterRaster; +//"Custom" Donīt Render Water Toggle +extern bool gbDontRenderWater; class CWaterLevel { From 9adde91b3a22d15d5e83f94cc9f0b5a9aa4b6b2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Fri, 29 May 2020 20:29:18 +0300 Subject: [PATCH 14/26] frontend options fix --- src/core/Frontend.cpp | 28 ++++++++++++++++++++-------- src/extras/frontendoption.h | 3 ++- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index fc3a05d9..5350cb02 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -412,6 +412,9 @@ CMenuManager::ThingsToDoBeforeGoingBack() if (option.returnPrevPageFunc) option.returnPrevPageFunc(); + if (option.type == FEOPTION_DYNAMIC) + option.buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS); + if (option.onlyApplyOnEnter) option.displayedValue = *option.value; } @@ -1205,8 +1208,7 @@ CMenuManager::Draw() } else if (option.type == FEOPTION_DYNAMIC) { if (option.drawFunc) { - option.drawFunc(unicodeTemp, &isOptionDisabled); - rightText = unicodeTemp; + rightText = option.drawFunc(&isOptionDisabled); } } } else @@ -1291,14 +1293,15 @@ CMenuManager::Draw() if (!CFont::Details.centre) CFont::SetRightJustifyOn(); - if(!strcmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FED_RES") - && !m_bGameNotLoaded && textLayer == 1 + if(textLayer == 1) + if(!strcmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FED_RES") + && !m_bGameNotLoaded #ifdef CUSTOM_FRONTEND_OPTIONS - || isOptionDisabled + || isOptionDisabled #endif - ) { - CFont::SetColor(CRGBA(155, 117, 6, FadeIn(255))); - } + ) + CFont::SetColor(CRGBA(155, 117, 6, FadeIn(255))); + CFont::PrintString(MENU_X_RIGHT_ALIGNED(columnWidth - textLayer), itemY, rightText); } if (i == m_nCurrOption && itemsAreSelectable){ @@ -1345,6 +1348,7 @@ CMenuManager::Draw() FrontendOption &option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[i].m_TargetMenu]; if (option.onlyApplyOnEnter && m_nCurrOption != i) option.displayedValue = *option.value; + } #endif @@ -4318,6 +4322,7 @@ CMenuManager::ProcessButtonPresses(void) } #endif + int prevOption = m_nCurrOption; if (goDown && (m_nCurrScreen != MENUPAGE_MULTIPLAYER_FIND_GAME)) { m_nCurrOption++; if (m_nCurrOption == NUM_MENUROWS || (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_NOTHING)) { @@ -4334,6 +4339,13 @@ CMenuManager::ProcessButtonPresses(void) m_nCurrOption--; } } +#ifdef CUSTOM_FRONTEND_OPTIONS + if (m_nCurrOption != prevOption && aScreens[m_nCurrScreen].m_aEntries[prevOption].m_Action == MENUACTION_TRIGGERFUNC) { + FrontendOption &option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[prevOption].m_TargetMenu]; + if (option.type == FEOPTION_DYNAMIC) + option.buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS); + } +#endif if (optionSelected) { int option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action; diff --git a/src/extras/frontendoption.h b/src/extras/frontendoption.h index 6c6ac20c..7cfc09a7 100644 --- a/src/extras/frontendoption.h +++ b/src/extras/frontendoption.h @@ -21,6 +21,7 @@ #define FEOPTION_ACTION_LEFT 0 #define FEOPTION_ACTION_RIGHT 1 #define FEOPTION_ACTION_SELECT 2 +#define FEOPTION_ACTION_FOCUSLOSS 3 void RemoveCustomFrontendOptions(); void CustomFrontendOptionsPopulate(); @@ -32,7 +33,7 @@ typedef void (*ReturnPrevPageFunc)(); typedef void (*ChangeFunc)(int8 displayedValue); // called before updating the value // for dynamic options -typedef void (*DrawFunc)(wchar* out, bool* disabled); // parameters should be set by user, both is allocated. disabled option will be dark yellow +typedef wchar* (*DrawFunc)(bool* disabled); // should return pointer to right text. *disabled = true will make it dark yellow typedef void (*ButtonPressFunc)(int8 action); // see FEOPTION_ACTIONs above struct FrontendOption From e38f2a7fb238787aec527f648fc5ce2bce2296c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Fri, 29 May 2020 21:06:08 +0300 Subject: [PATCH 15/26] fix fix --- src/core/Frontend.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index 5350cb02..a38df5e0 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -412,7 +412,7 @@ CMenuManager::ThingsToDoBeforeGoingBack() if (option.returnPrevPageFunc) option.returnPrevPageFunc(); - if (option.type == FEOPTION_DYNAMIC) + if (m_nCurrOption == option.screenOptionOrder && option.type == FEOPTION_DYNAMIC) option.buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS); if (option.onlyApplyOnEnter) @@ -1344,11 +1344,18 @@ CMenuManager::Draw() } #ifdef CUSTOM_FRONTEND_OPTIONS + static int lastOption = m_nCurrOption; if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action == MENUACTION_TRIGGERFUNC) { FrontendOption &option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[i].m_TargetMenu]; if (option.onlyApplyOnEnter && m_nCurrOption != i) option.displayedValue = *option.value; + if (m_nCurrOption != lastOption && lastOption == i) { + FrontendOption &oldOption = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[lastOption].m_TargetMenu]; + if (oldOption.type == FEOPTION_DYNAMIC) + oldOption.buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS); + } + lastOption = m_nCurrOption; } #endif @@ -4339,13 +4346,6 @@ CMenuManager::ProcessButtonPresses(void) m_nCurrOption--; } } -#ifdef CUSTOM_FRONTEND_OPTIONS - if (m_nCurrOption != prevOption && aScreens[m_nCurrScreen].m_aEntries[prevOption].m_Action == MENUACTION_TRIGGERFUNC) { - FrontendOption &option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[prevOption].m_TargetMenu]; - if (option.type == FEOPTION_DYNAMIC) - option.buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS); - } -#endif if (optionSelected) { int option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action; From 517f0b9189bed37c06110f8cb6bc2ab7763ce8f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Fri, 29 May 2020 21:31:06 +0300 Subject: [PATCH 16/26] fix fix fix --- src/core/Frontend.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index a38df5e0..b95deee3 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -959,6 +959,10 @@ CMenuManager::Draw() } #endif +#ifdef CUSTOM_FRONTEND_OPTIONS + static int lastOption = m_nCurrOption; +#endif + for (int i = 0; i < NUM_MENUROWS; ++i) { #ifdef CUSTOM_FRONTEND_OPTIONS bool isOptionDisabled = false; @@ -1344,7 +1348,6 @@ CMenuManager::Draw() } #ifdef CUSTOM_FRONTEND_OPTIONS - static int lastOption = m_nCurrOption; if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action == MENUACTION_TRIGGERFUNC) { FrontendOption &option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[i].m_TargetMenu]; if (option.onlyApplyOnEnter && m_nCurrOption != i) @@ -1355,7 +1358,6 @@ CMenuManager::Draw() if (oldOption.type == FEOPTION_DYNAMIC) oldOption.buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS); } - lastOption = m_nCurrOption; } #endif @@ -1402,6 +1404,10 @@ CMenuManager::Draw() } } +#ifdef CUSTOM_FRONTEND_OPTIONS + lastOption = m_nCurrOption; +#endif + switch (m_nCurrScreen) { case MENUPAGE_CONTROLLER_SETTINGS: case MENUPAGE_SOUND_SETTINGS: From e6b9c2013146af9271398d899caa346a0c5f04ff Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Sat, 30 May 2020 18:07:01 +0300 Subject: [PATCH 17/26] fix --- src/control/RoadBlocks.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/control/RoadBlocks.cpp b/src/control/RoadBlocks.cpp index 572f8134..caf9ed34 100644 --- a/src/control/RoadBlocks.cpp +++ b/src/control/RoadBlocks.cpp @@ -174,7 +174,7 @@ CRoadBlocks::GenerateRoadBlocks(void) pVehicle->bExtendedRange = true; if (pVehicle->UsesSiren(pVehicle->GetModelIndex()) && CGeneral::GetRandomNumber() & 1) pVehicle->m_bSirenOrAlarm = true; - if (pVehicle->GetForward().z > 0.94f) { + if (pVehicle->GetUp().z > 0.94f) { CVisibilityPlugins::SetClumpAlpha(pVehicle->GetClump(), 0); CWorld::Add(pVehicle); pVehicle->bCreateRoadBlockPeds = true; From bae3a3e72f6b22b72155d377d38725cdbdff688c Mon Sep 17 00:00:00 2001 From: aap Date: Sun, 31 May 2020 17:45:26 +0200 Subject: [PATCH 18/26] fixed to CAutomobile and friends --- src/core/Cam.cpp | 5 +- src/math/Matrix.h | 1 + src/math/math.cpp | 6 ++ src/modelinfo/SimpleModelInfo.cpp | 7 +++ src/render/Skidmarks.h | 2 +- src/vehicles/Automobile.cpp | 91 ++++++++++++++----------------- src/vehicles/Automobile.h | 6 +- src/vehicles/Vehicle.cpp | 10 ++-- 8 files changed, 65 insertions(+), 63 deletions(-) diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index 6347e111..60145cd0 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -3792,7 +3792,7 @@ CCam::Process_Debug(const CVector&, float, float, float) if(FindPlayerVehicle()) FindPlayerVehicle()->Teleport(Source); else - CWorld::Players[CWorld::PlayerInFocus].m_pPed->SetPosition(Source); + CWorld::Players[CWorld::PlayerInFocus].m_pPed->SetPosition(Source); } // stay inside sectors @@ -3859,8 +3859,7 @@ CCam::Process_Debug(const CVector&, float, float, float) if(FindPlayerVehicle()) FindPlayerVehicle()->Teleport(Source); else - CWorld::Players[CWorld::PlayerInFocus].m_pPed->GetPosition() = Source; - + CWorld::Players[CWorld::PlayerInFocus].m_pPed->SetPosition(Source); } // stay inside sectors diff --git a/src/math/Matrix.h b/src/math/Matrix.h index b7e055c5..5ec79aba 100644 --- a/src/math/Matrix.h +++ b/src/math/Matrix.h @@ -223,6 +223,7 @@ public: void SetRotate(float xAngle, float yAngle, float zAngle); void Rotate(float x, float y, float z); void RotateX(float x); + void RotateY(float y); void RotateZ(float z); void Reorthogonalise(void); diff --git a/src/math/math.cpp b/src/math/math.cpp index eeb9d3fa..29f18d03 100644 --- a/src/math/math.cpp +++ b/src/math/math.cpp @@ -59,6 +59,12 @@ CMatrix::RotateX(float x) Rotate(x, 0.0f, 0.0f); } +void +CMatrix::RotateY(float y) +{ + Rotate(0.0f, y, 0.0f); +} + void CMatrix::RotateZ(float z) { diff --git a/src/modelinfo/SimpleModelInfo.cpp b/src/modelinfo/SimpleModelInfo.cpp index a781cf58..091d4dff 100644 --- a/src/modelinfo/SimpleModelInfo.cpp +++ b/src/modelinfo/SimpleModelInfo.cpp @@ -157,6 +157,13 @@ CSimpleModelInfo::SetupBigBuilding(void) if(related) m_lodDistances[2] = related->GetLargestLodDistance()/TheCamera.LODDistMultiplier; else +#ifdef FIX_BUGS + if(strnicmp(GetName(), "lod", 3) == 0) m_lodDistances[2] = 100.0f; + else + m_lodDistances[2] = 0.0f; +#else + m_lodDistances[2] = 100.0f; +#endif } } diff --git a/src/render/Skidmarks.h b/src/render/Skidmarks.h index 085b4c6d..c061782d 100644 --- a/src/render/Skidmarks.h +++ b/src/render/Skidmarks.h @@ -11,7 +11,7 @@ public: bool m_isMuddy; uintptr m_id; int16 m_last; - uint32 m_lastUpdate;; + uint32 m_lastUpdate; uint32 m_fadeStart; uint32 m_fadeEnd; CVector m_pos[SKIDMARK_LENGTH]; diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 654713b1..37b224d1 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -67,7 +67,7 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy) CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(id); m_fFireBlowUpTimer = 0.0f; - field_4E0 = 0; + m_auto_unk1 = 0; bTaxiLight = m_sAllTaxiLights; bFixedColour = false; bBigWheels = false; @@ -77,8 +77,8 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy) pHandling = mod_HandlingManager.GetHandlingData((eHandlingId)mi->m_handlingId); - field_49C = 20.0f; - field_4D8 = 0; + m_auto_unused1 = 20.0f; + m_auto_unused2 = 0; mi->ChooseVehicleColour(m_currentColour1, m_currentColour2); @@ -236,23 +236,16 @@ CAutomobile::ProcessControl(void) // Improve grip of vehicles in certain cases bool strongGrip1 = false; bool strongGrip2 = false; - if(FindPlayerVehicle() && this != FindPlayerVehicle()){ - switch(AutoPilot.m_nCarMission){ - case MISSION_RAMPLAYER_FARAWAY: - case MISSION_RAMPLAYER_CLOSE: - case MISSION_BLOCKPLAYER_FARAWAY: - case MISSION_BLOCKPLAYER_CLOSE: - if(FindPlayerSpeed().Magnitude() > 0.3f){ - strongGrip1 = true; - if(FindPlayerSpeed().Magnitude() > 0.4f){ - if(m_vecMoveSpeed.Magnitude() < 0.3f) - strongGrip2 = true; - }else{ - if((GetPosition() - FindPlayerCoors()).Magnitude() > 50.0f) - strongGrip2 = true; - } - } - default: break; + if(FindPlayerVehicle() && this != FindPlayerVehicle() && + (AutoPilot.m_nCarMission == MISSION_RAMPLAYER_FARAWAY || AutoPilot.m_nCarMission == MISSION_RAMPLAYER_CLOSE || + AutoPilot.m_nCarMission == MISSION_BLOCKPLAYER_FARAWAY || AutoPilot.m_nCarMission == MISSION_BLOCKPLAYER_CLOSE)){ + if(FindPlayerSpeed().Magnitude() > 0.3f){ + strongGrip1 = true; + if(FindPlayerSpeed().Magnitude() > 0.4f && + m_vecMoveSpeed.Magnitude() < 0.3f) + strongGrip2 = true; + else if((GetPosition() - FindPlayerCoors()).Magnitude() > 50.0f) + strongGrip2 = true; } } @@ -263,7 +256,7 @@ CAutomobile::ProcessControl(void) // Scan if this car sees the player committing any crimes if(GetStatus() != STATUS_ABANDONED && GetStatus() != STATUS_WRECKED && - GetStatus() != STATUS_PLAYER && GetStatus() != STATUS_PLAYER_REMOTE && GetStatus() != STATUS_PLAYER_DISABLED){ + GetStatus() != STATUS_PLAYER && GetStatus() != STATUS_PLAYER_REMOTE && GetStatus() != STATUS_PLAYER_DISABLED){ switch(GetModelIndex()) case MI_FBICAR: case MI_POLICE: @@ -596,7 +589,7 @@ CAutomobile::ProcessControl(void) m_aSuspensionSpringRatio[i] = (m_aSuspensionSpringRatio[i]-wheelRadius)/(1.0f-wheelRadius); } - float fwdSpeed = DotProduct(m_vecMoveSpeed, GetForward()); + float fwdSpeed = Abs(DotProduct(m_vecMoveSpeed, GetForward())); CVector contactPoints[4]; // relative to model CVector contactSpeeds[4]; // speed at contact points CVector springDirections[4]; // normalized, in model space @@ -689,7 +682,7 @@ CAutomobile::ProcessControl(void) float brakeBiasFront = neutralHandling ? 1.0f : 2.0f*pHandling->fBrakeBias; float brakeBiasRear = neutralHandling ? 1.0f : 2.0f*(1.0f-pHandling->fBrakeBias); float tractionBiasFront = neutralHandling ? 1.0f : 2.0f*pHandling->fTractionBias; - float tractionBiasRear = neutralHandling ? 1.0f : 2.0f*(1.0f-pHandling->fTractionBias); + float tractionBiasRear = neutralHandling ? 1.0f : 2.0f-tractionBiasFront; // Count how many wheels are touching the ground @@ -1160,7 +1153,7 @@ CAutomobile::ProcessControl(void) uint8 freq = Min(200.0f*suspShake*speed*2000.0f/m_fMass + 100.0f, 250.0f); CPad::GetPad(0)->StartShake(20000.0f*CTimer::GetTimeStep()/freq, freq); }else{ - uint8 freq = Min(200.0f*surfShake*speed*2000.0f/m_fMass + 40.0f, 145.0f); + uint8 freq = Min(200.0f*surfShake*speed*2000.0f/m_fMass + 40.0f, 150.0f); CPad::GetPad(0)->StartShake(5000.0f*CTimer::GetTimeStep()/freq, freq); } } @@ -1302,7 +1295,7 @@ CAutomobile::PreRender(void) int drawParticles = Abs(fwdSpeed) < 90.0f; if(GetStatus() == STATUS_SIMPLE || GetStatus() == STATUS_PHYSICS || - GetStatus() == STATUS_PLAYER || GetStatus() == STATUS_PLAYER_PLAYBACKFROMBUFFER){ + GetStatus() == STATUS_PLAYER || GetStatus() == STATUS_PLAYER_PLAYBACKFROMBUFFER){ bool rearSkidding = false; if(m_aWheelState[CARWHEEL_REAR_LEFT] == WHEEL_STATE_SKIDDING || m_aWheelState[CARWHEEL_REAR_RIGHT] == WHEEL_STATE_SKIDDING) @@ -1434,7 +1427,7 @@ CAutomobile::PreRender(void) n = 6.0f*CWeather::Rain; for(j = 0; j <= n; j++) CParticle::AddParticle(PARTICLE_RAIN_SPLASHUP, - c + CVector(CGeneral::GetRandomNumberInRange(-.04f, 0.4f), CGeneral::GetRandomNumberInRange(-.04f, 0.4f), 0.0f), + c + CVector(CGeneral::GetRandomNumberInRange(-0.4f, 0.4f), CGeneral::GetRandomNumberInRange(-0.4f, 0.4f), 0.0f), CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, 0, 0, CGeneral::GetRandomNumber() & 1); } @@ -1622,11 +1615,9 @@ CAutomobile::PreRender(void) break; } - if(GetModelIndex() == MI_RCBANDIT || GetModelIndex() == MI_DODO || - GetModelIndex() == MI_RHINO) { - CShadows::StoreShadowForCar(this); - return; - } + if(GetModelIndex() != MI_RCBANDIT && GetModelIndex() != MI_DODO && + GetModelIndex() != MI_RHINO) { + // Process lights // Turn lights on/off bool shouldLightsBeOn = @@ -1873,14 +1864,9 @@ CAutomobile::PreRender(void) CPointLights::FOG_NONE, false); } } - }else{ + }else if(GetStatus() != STATUS_ABANDONED && GetStatus() != STATUS_WRECKED){ // Lights off - if(GetStatus() == STATUS_ABANDONED || GetStatus() == STATUS_WRECKED) { - CShadows::StoreShadowForCar(this); - return; - } - CVector lightPos = mi->m_positions[CAR_POS_TAILLIGHTS]; CVector lightR = GetMatrix() * lightPos; CVector lightL = lightR; @@ -1937,6 +1923,8 @@ CAutomobile::PreRender(void) CCoronas::UpdateCoronaCoors((uintptr)this + 3, lightR, 50.0f*TheCamera.LODDistMultiplier, 0.0f); } } + // end of lights + } CShadows::StoreShadowForCar(this); } @@ -2507,7 +2495,7 @@ CAutomobile::TankControl(void) float f = i/15.0f; CParticle::AddParticle(PARTICLE_GUNSMOKE2, point1, shotDir*CGeneral::GetRandomNumberInRange(0.3f, 1.0f)*f, - nil, CGeneral::GetRandomNumberInRange(0.5f, 1.0f)*f, black); + nil, CGeneral::GetRandomNumberInRange(0.5f, 1.5f)*f, black); } // And some gun flashes near the gun @@ -2539,6 +2527,9 @@ CAutomobile::TankControl(void) } } +#define HYDRAULIC_UPPER_EXT (-0.12f) +#define HYDRAULIC_LOWER_EXT (0.14f) + void CAutomobile::HydraulicControl(void) { @@ -2601,8 +2592,8 @@ CAutomobile::HydraulicControl(void) m_hydraulicState = 20; else{ m_hydraulicState = 0; - normalUpperLimit += -0.12f; - normalSpringLength = normalUpperLimit - (normalLowerLimit+0.14f); + normalUpperLimit += HYDRAULIC_UPPER_EXT; + normalSpringLength = normalUpperLimit - (normalLowerLimit+HYDRAULIC_LOWER_EXT); DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_HYDRAULIC_2, 0.0f); } @@ -2635,7 +2626,7 @@ CAutomobile::HydraulicControl(void) float radius = Max(specialColModel->boundingBox.min.Magnitude(), specialColModel->boundingBox.max.Magnitude()); if(specialColModel->boundingSphere.radius < radius) specialColModel->boundingSphere.radius = radius; - + return; } if(playerInfo->m_WBState != WBSTATE_PLAYING) @@ -2645,8 +2636,6 @@ CAutomobile::HydraulicControl(void) if(m_hydraulicState < 20 && m_fVelocityChangeForAudio > 0.2f){ if(m_hydraulicState == 0){ m_hydraulicState = 20; - for(i = 0; i < 4; i++) - m_aWheelPosition[i] -= 0.06f; DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_HYDRAULIC_1, 0.0f); setPrevRatio = true; }else{ @@ -2674,8 +2663,8 @@ CAutomobile::HydraulicControl(void) if(m_hydraulicState < 100){ if(m_hydraulicState == 0){ - normalUpperLimit += -0.12f; - normalLowerLimit += 0.14f; + normalUpperLimit += HYDRAULIC_UPPER_EXT; + normalLowerLimit += HYDRAULIC_LOWER_EXT; normalSpringLength = normalUpperLimit - normalLowerLimit; } @@ -2740,8 +2729,8 @@ CAutomobile::HydraulicControl(void) // Lowered, move wheels up if(m_hydraulicState == 0){ - normalUpperLimit += -0.12f; - normalLowerLimit += 0.14f; + normalUpperLimit += HYDRAULIC_UPPER_EXT; + normalLowerLimit += HYDRAULIC_LOWER_EXT; normalSpringLength = normalUpperLimit - normalLowerLimit; } @@ -2782,8 +2771,8 @@ CAutomobile::HydraulicControl(void) } if(m_fVelocityChangeForAudio < 0.1f){ - normalUpperLimit += -0.12f; - normalLowerLimit += 0.14f; + normalUpperLimit += HYDRAULIC_UPPER_EXT; + normalLowerLimit += HYDRAULIC_LOWER_EXT; normalSpringLength = normalUpperLimit - normalLowerLimit; } @@ -2920,7 +2909,7 @@ CAutomobile::ProcessBuoyancy(void) DMAudio.PlayOneShot(m_audioEntityId, SOUND_WATER_FALL, 0.0f); } - if(nGenerateWaterCircles > 0 && nGenerateWaterCircles < CTimer::GetTimeInMilliseconds()){ + if(nGenerateWaterCircles > 0 && nGenerateWaterCircles <= CTimer::GetTimeInMilliseconds()){ CVector pos = GetPosition(); float waterLevel = 0.0f; if(CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &waterLevel, false)) @@ -2940,7 +2929,7 @@ CAutomobile::ProcessBuoyancy(void) } } - if(nGenerateRaindrops > 0 && nGenerateRaindrops < CTimer::GetTimeInMilliseconds()){ + if(nGenerateRaindrops > 0 && nGenerateRaindrops <= CTimer::GetTimeInMilliseconds()){ CVector pos = GetPosition(); float waterLevel = 0.0f; if(CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &waterLevel, false)) diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h index 0c02379f..8fa7ed67 100644 --- a/src/vehicles/Automobile.h +++ b/src/vehicles/Automobile.h @@ -84,13 +84,13 @@ public: float m_aSuspensionSpringRatio[4]; float m_aSuspensionSpringRatioPrev[4]; float m_aWheelTimer[4]; // set to 4.0 when wheel is touching ground, then decremented - float field_49C; + float m_auto_unused1; bool m_aWheelSkidmarkMuddy[4]; bool m_aWheelSkidmarkBloody[4]; float m_aWheelRotation[4]; float m_aWheelPosition[4]; float m_aWheelSpeed[4]; - uint8 field_4D8; + uint8 m_auto_unused2; uint8 m_bombType : 3; uint8 bTaxiLight : 1; uint8 bDriverLastFrame : 1; // for bombs @@ -100,7 +100,7 @@ public: uint8 bNotDamagedUpsideDown : 1; uint8 bMoreResistantToDamage : 1; CEntity *m_pBombRigger; - int16 field_4E0; + int16 m_auto_unk1; uint16 m_hydraulicState; uint32 m_nBusDoorTimerEnd; uint32 m_nBusDoorTimerStart; diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp index 77c549f9..1132f79f 100644 --- a/src/vehicles/Vehicle.cpp +++ b/src/vehicles/Vehicle.cpp @@ -288,7 +288,7 @@ CVehicle::FlyingControl(eFlightModel flightModel) { // thrust float fForwSpeed = DotProduct(GetMoveSpeed(), GetForward()); - CVector vecWidthForward = GetColModel()->boundingBox.min.y * GetForward(); + CVector vecTail = GetColModel()->boundingBox.min.y * GetForward(); float fThrust = (CPad::GetPad(0)->GetAccelerate() - CPad::GetPad(0)->GetBrake()) / 255.0f; if (fForwSpeed > 0.1f || (flightModel == FLIGHT_MODEL_RCPLANE && fForwSpeed > 0.02f)) fThrust += 1.0f; @@ -311,13 +311,13 @@ CVehicle::FlyingControl(eFlightModel flightModel) fSideSlipAccel = Abs(fSideSpeed) * fSideSpeed * fSeaSideSlipMult; ApplyMoveForce(m_fMass * GetRight() * fSideSlipAccel * CTimer::GetTimeStep()); - float fYaw = -DotProduct(GetSpeed(vecWidthForward), GetRight()); + float fYaw = -DotProduct(GetSpeed(vecTail), GetRight()); float fYawAccel; if (flightModel == FLIGHT_MODEL_RCPLANE) fYawAccel = fRCRudderMult * fYaw * Abs(fYaw) + fRCYawMult * fSteerLR * fForwSpeed; else fYawAccel = fSeaRudderMult * fYaw * Abs(fYaw) + fSeaYawMult * fSteerLR * fForwSpeed; - ApplyTurnForce(fYawAccel * GetRight() * m_fTurnMass * CTimer::GetTimeStep(), vecWidthForward); + ApplyTurnForce(fYawAccel * GetRight() * m_fTurnMass * CTimer::GetTimeStep(), vecTail); float fRollAccel; if (flightModel == FLIGHT_MODEL_RCPLANE) { @@ -341,14 +341,14 @@ CVehicle::FlyingControl(eFlightModel flightModel) ApplyTurnForce(fStabiliseSpeed * m_fTurnMass * GetRight(), GetUp()); // no CTimer::GetTimeStep(), is it right? VC doesn't have it too // up/down - float fTail = -DotProduct(GetSpeed(vecWidthForward), GetUp()); + float fTail = -DotProduct(GetSpeed(vecTail), GetUp()); float fSteerUD = -CPad::GetPad(0)->GetSteeringUpDown() / 128.0f; float fPitchAccel; if (flightModel == FLIGHT_MODEL_RCPLANE) fPitchAccel = fRCTailMult * fTail * Abs(fTail) + fRCPitchMult * fSteerUD * fForwSpeed; else fPitchAccel = fSeaTailMult * fTail * Abs(fTail) + fSeaPitchMult * fSteerUD * fForwSpeed; - ApplyTurnForce(fPitchAccel * m_fTurnMass * GetUp() * CTimer::GetTimeStep(), vecWidthForward); + ApplyTurnForce(fPitchAccel * m_fTurnMass * GetUp() * CTimer::GetTimeStep(), vecTail); float fLift = -DotProduct(GetMoveSpeed(), GetUp()) / Max(0.01f, GetMoveSpeed().Magnitude()); float fLiftAccel; From 12cc0e4132f9bdb0440a4e9223618ef3e2c00240 Mon Sep 17 00:00:00 2001 From: aap Date: Sun, 31 May 2020 22:35:29 +0200 Subject: [PATCH 19/26] getting rid of strnicmp --- src/modelinfo/SimpleModelInfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modelinfo/SimpleModelInfo.cpp b/src/modelinfo/SimpleModelInfo.cpp index 091d4dff..32204500 100644 --- a/src/modelinfo/SimpleModelInfo.cpp +++ b/src/modelinfo/SimpleModelInfo.cpp @@ -158,7 +158,7 @@ CSimpleModelInfo::SetupBigBuilding(void) m_lodDistances[2] = related->GetLargestLodDistance()/TheCamera.LODDistMultiplier; else #ifdef FIX_BUGS - if(strnicmp(GetName(), "lod", 3) == 0) + if(toupper(m_name[0]) == 'L' && toupper(m_name[1]) == 'O' && toupper(m_name[2]) == 'D') m_lodDistances[2] = 100.0f; else m_lodDistances[2] = 0.0f; From c8b93d057552c271e5b200555084a4ee338f2c0b Mon Sep 17 00:00:00 2001 From: aap Date: Mon, 1 Jun 2020 10:30:01 +0200 Subject: [PATCH 20/26] fixed bumper colmodel --- src/core/TempColModels.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/TempColModels.cpp b/src/core/TempColModels.cpp index b4d994ec..1252e2c7 100644 --- a/src/core/TempColModels.cpp +++ b/src/core/TempColModels.cpp @@ -155,7 +155,7 @@ CTempColModels::Initialise(void) } ms_colModelBumper1.boundingSphere.Set(2.2f, CVector(0.0f, -0.6f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelBumper1.boundingBox.Set(CVector(-1.2f, -0.3f, -0.2f), CVector(1.2f, 0.3f, -0.2f), SURFACE_DEFAULT, 0); + ms_colModelBumper1.boundingBox.Set(CVector(-1.2f, -0.3f, -0.2f), CVector(1.2f, 0.3f, 0.2f), SURFACE_DEFAULT, 0); SET_COLMODEL_SPHERES(ms_colModelBumper1, s_aBumperSpheres); From 0803c821ae4d78f827f593cb6030988e8f91aa27 Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Mon, 1 Jun 2020 12:45:03 +0300 Subject: [PATCH 21/26] fixed roadblocks --- src/control/PathFind.cpp | 7 ++- src/control/RoadBlocks.cpp | 100 ++++++++++++++++++------------------- 2 files changed, 53 insertions(+), 54 deletions(-) diff --git a/src/control/PathFind.cpp b/src/control/PathFind.cpp index ee15b82f..46895678 100644 --- a/src/control/PathFind.cpp +++ b/src/control/PathFind.cpp @@ -404,11 +404,10 @@ CPathFind::PreparePathData(void) maxX = 0.0f; maxY = 0.0f; for(j = 0; j < 12; j++){ - k = i*12 + j; + k = m_mapObjects[i]->GetModelIndex()*12 + j; if(InfoForTileCars[k].type == NodeTypeExtern){ numExtern++; - if(InfoForTileCars[k].numLeftLanes + InfoForTileCars[k].numRightLanes > numLanes) - numLanes = InfoForTileCars[k].numLeftLanes + InfoForTileCars[k].numRightLanes; + numLanes = Max(numLanes, InfoForTileCars[k].numLeftLanes + InfoForTileCars[k].numRightLanes); maxX = Max(maxX, Abs(InfoForTileCars[k].x)); maxY = Max(maxY, Abs(InfoForTileCars[k].y)); }else if(InfoForTileCars[k].type == NodeTypeIntern) @@ -417,7 +416,7 @@ CPathFind::PreparePathData(void) if(numIntern == 1 && numExtern == 2){ if(numLanes < 4){ - if((i & 7) == 4){ // WHAT? + if((i & 7) == 4){ // 1/8 probability m_objectFlags[i] |= UseInRoadBlock; if(maxX > maxY) m_objectFlags[i] |= ObjectEastWest; diff --git a/src/control/RoadBlocks.cpp b/src/control/RoadBlocks.cpp index caf9ed34..ee9ec17e 100644 --- a/src/control/RoadBlocks.cpp +++ b/src/control/RoadBlocks.cpp @@ -132,58 +132,58 @@ CRoadBlocks::GenerateRoadBlocks(void) CColModel *pVehicleColModel = CModelInfo::GetModelInfo(vehicleId)->GetColModel(); float fModelRadius = 2.0f * pVehicleColModel->boundingSphere.radius + 0.25f; int16 radius = (int16)(fMapObjectRadius / fModelRadius); - if (radius > 0 && radius < 6) { - CVector2D vecDistanceToCamera = TheCamera.GetPosition() - mapObject->GetPosition(); - float fDotProduct = DotProduct2D(vecDistanceToCamera, mapObject->GetForward()); - float fOffset = 0.5f * fModelRadius * (float)(radius - 1); - for (int16 i = 0; i < radius; i++) { - uint8 nRoadblockType = fDotProduct < 0.0f; - if (CGeneral::GetRandomNumber() & 1) { - offsetMatrix.SetRotateZ(((CGeneral::GetRandomNumber() & 0xFF) - 128.0f) * 0.003f + HALFPI); + if (radius >= 6) + continue; + CVector2D vecDistanceToCamera = TheCamera.GetPosition() - mapObject->GetPosition(); + float fDotProduct = DotProduct2D(vecDistanceToCamera, mapObject->GetForward()); + float fOffset = 0.5f * fModelRadius * (float)(radius - 1); + for (int16 i = 0; i < radius; i++) { + uint8 nRoadblockType = fDotProduct < 0.0f; + if (CGeneral::GetRandomNumber() & 1) { + offsetMatrix.SetRotateZ(((CGeneral::GetRandomNumber() & 0xFF) - 128.0f) * 0.003f + HALFPI); + } + else { + nRoadblockType = !nRoadblockType; + offsetMatrix.SetRotateZ(((CGeneral::GetRandomNumber() & 0xFF) - 128.0f) * 0.003f - HALFPI); + } + if (ThePaths.m_objectFlags[RoadBlockObjects[nRoadblockNode]] & ObjectEastWest) + offsetMatrix.GetPosition() = CVector(0.0f, i * fModelRadius - fOffset, 0.6f); + else + offsetMatrix.GetPosition() = CVector(i * fModelRadius - fOffset, 0.0f, 0.6f); + CMatrix vehicleMatrix = mapObject->m_matrix * offsetMatrix; + float fModelRadius = CModelInfo::GetModelInfo(vehicleId)->GetColModel()->boundingSphere.radius - 0.25f; + int16 colliding = 0; + CWorld::FindObjectsKindaColliding(vehicleMatrix.GetPosition(), fModelRadius, 0, &colliding, 2, nil, false, true, true, false, false); + if (!colliding) { + CAutomobile *pVehicle = new CAutomobile(vehicleId, RANDOM_VEHICLE); + pVehicle->SetStatus(STATUS_ABANDONED); + // pVehicle->GetHeightAboveRoad(); // called but return value is ignored? + vehicleMatrix.GetPosition().z += fModelRadius - 0.6f; + pVehicle->m_matrix = vehicleMatrix; + pVehicle->PlaceOnRoadProperly(); + pVehicle->bIsStatic = false; + pVehicle->m_matrix.UpdateRW(); + pVehicle->m_nDoorLock = CARLOCK_UNLOCKED; + CCarCtrl::JoinCarWithRoadSystem(pVehicle); + pVehicle->bIsLocked = false; + pVehicle->AutoPilot.m_nCarMission = MISSION_NONE; + pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE; + pVehicle->AutoPilot.m_nCurrentLane = 0; + pVehicle->AutoPilot.m_nNextLane = 0; + pVehicle->AutoPilot.m_fMaxTrafficSpeed = 0.0f; + pVehicle->AutoPilot.m_nCruiseSpeed = 0.0f; + pVehicle->bExtendedRange = true; + if (pVehicle->UsesSiren(pVehicle->GetModelIndex()) && CGeneral::GetRandomNumber() & 1) + pVehicle->m_bSirenOrAlarm = true; + if (pVehicle->GetUp().z > 0.94f) { + CVisibilityPlugins::SetClumpAlpha(pVehicle->GetClump(), 0); + CWorld::Add(pVehicle); + pVehicle->bCreateRoadBlockPeds = true; + pVehicle->m_nRoadblockType = nRoadblockType; + pVehicle->m_nRoadblockNode = nRoadblockNode; } else { - nRoadblockType = !nRoadblockType; - offsetMatrix.SetRotateZ(((CGeneral::GetRandomNumber() & 0xFF) - 128.0f) * 0.003f - HALFPI); - } - if (ThePaths.m_objectFlags[RoadBlockObjects[nRoadblockNode]] & ObjectEastWest) - offsetMatrix.GetPosition() = CVector(0.0f, -fOffset, 0.6f); - else - offsetMatrix.GetPosition() = CVector(-fOffset, 0.0f, 0.6f); - CMatrix vehicleMatrix = mapObject->m_matrix * offsetMatrix; - float fModelRadius = CModelInfo::GetModelInfo(vehicleId)->GetColModel()->boundingSphere.radius - 0.25f; - int16 colliding = 0; - CWorld::FindObjectsKindaColliding(vehicleMatrix.GetPosition(), fModelRadius, 0, &colliding, 2, nil, false, true, true, false, false); - if (!colliding) { - CAutomobile *pVehicle = new CAutomobile(vehicleId, RANDOM_VEHICLE); - pVehicle->SetStatus(STATUS_ABANDONED); - // pVehicle->GetHeightAboveRoad(); // called but return value is ignored? - vehicleMatrix.GetPosition().z += fModelRadius - 0.6f; - pVehicle->m_matrix = vehicleMatrix; - pVehicle->PlaceOnRoadProperly(); - pVehicle->bIsStatic = false; - pVehicle->m_matrix.UpdateRW(); - pVehicle->m_nDoorLock = CARLOCK_UNLOCKED; - CCarCtrl::JoinCarWithRoadSystem(pVehicle); - pVehicle->bIsLocked = false; - pVehicle->AutoPilot.m_nCarMission = MISSION_NONE; - pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE; - pVehicle->AutoPilot.m_nCurrentLane = 0; - pVehicle->AutoPilot.m_nNextLane = 0; - pVehicle->AutoPilot.m_fMaxTrafficSpeed = 0.0f; - pVehicle->AutoPilot.m_nCruiseSpeed = 0.0f; - pVehicle->bExtendedRange = true; - if (pVehicle->UsesSiren(pVehicle->GetModelIndex()) && CGeneral::GetRandomNumber() & 1) - pVehicle->m_bSirenOrAlarm = true; - if (pVehicle->GetUp().z > 0.94f) { - CVisibilityPlugins::SetClumpAlpha(pVehicle->GetClump(), 0); - CWorld::Add(pVehicle); - pVehicle->bCreateRoadBlockPeds = true; - pVehicle->m_nRoadblockType = nRoadblockType; - pVehicle->m_nRoadblockNode = nRoadblockNode; - } - else { - delete pVehicle; - } + delete pVehicle; } } } From 7c7727e7dab52483d9dbcf0002d95a8bf10e7b41 Mon Sep 17 00:00:00 2001 From: aap Date: Mon, 1 Jun 2020 13:21:19 +0200 Subject: [PATCH 22/26] fixed timebar toggle --- src/core/main.cpp | 5 +---- src/core/main.h | 1 - src/core/re3.cpp | 4 +++- src/render/WaterLevel.h | 1 - 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/core/main.cpp b/src/core/main.cpp index a69890b0..eb39b287 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -73,7 +73,6 @@ float FramesPerSecond = 30.0f; bool gbPrintShite = false; bool gbModelViewer; -//Custom Timebars Toggle #ifdef TIMEBARS bool gbShowTimebars; #endif @@ -1102,10 +1101,8 @@ Idle(void *arg) #ifdef TIMEBARS -//Custom Timebars toggle if (gbShowTimebars) - tbDisplay(); - + tbDisplay(); #endif DoRWStuffEndOfFrame(); diff --git a/src/core/main.h b/src/core/main.h index 5c514bbb..9ad4ed1c 100644 --- a/src/core/main.h +++ b/src/core/main.h @@ -14,7 +14,6 @@ extern wchar gUString[256]; extern wchar gUString2[256]; extern bool gbPrintShite; extern bool gbModelViewer; -//Custom Timebars Toggle #ifdef TIMEBARS extern bool gbShowTimebars; #endif diff --git a/src/core/re3.cpp b/src/core/re3.cpp index c77cf6d9..38854f25 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -461,7 +461,7 @@ DebugMenuPopulate(void) DebugMenuAddVarBool8("Render", "Don't render Peds", &gbDontRenderPeds, nil); DebugMenuAddVarBool8("Render", "Don't render Vehicles", &gbDontRenderVehicles, nil); DebugMenuAddVarBool8("Render", "Don't render Objects", &gbDontRenderObjects, nil); - DebugMenuAddVarBool8("Render", "Donīt Render Water", &gbDontRenderWater, nil); + DebugMenuAddVarBool8("Render", "Don't Render Water", &gbDontRenderWater, nil); DebugMenuAddVarBool8("Debug", "Edit on", &CSceneEdit::m_bEditOn, nil); #ifdef MENU_MAP @@ -492,7 +492,9 @@ DebugMenuPopulate(void) DebugMenuAddCmd("Debug", "Stop Credits", CCredits::Stop); DebugMenuAddVarBool8("Debug", "Show DebugStuffInRelease", &gbDebugStuffInRelease, nil); +#ifdef TIMEBARS DebugMenuAddVarBool8("Debug", "Show Timebars", &gbShowTimebars, nil); +#endif extern bool PrintDebugCode; extern int16 DebugCamMode; diff --git a/src/render/WaterLevel.h b/src/render/WaterLevel.h index 325be0a5..269d6091 100644 --- a/src/render/WaterLevel.h +++ b/src/render/WaterLevel.h @@ -65,7 +65,6 @@ #define MAX_BOAT_WAKES 8 extern RwRaster* gpWaterRaster; -//"Custom" Donīt Render Water Toggle extern bool gbDontRenderWater; class CWaterLevel From 8bbb6a2a4a104469f1c3a285f68088445332d671 Mon Sep 17 00:00:00 2001 From: aap Date: Mon, 1 Jun 2020 20:28:04 +0200 Subject: [PATCH 23/26] hanim fix --- src/core/common.h | 4 ++-- src/rw/RwHelper.cpp | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/core/common.h b/src/core/common.h index f79b199b..7d339660 100644 --- a/src/core/common.h +++ b/src/core/common.h @@ -29,14 +29,14 @@ #define STREAMFILE(str) (((rw::StreamFile*)(str))->file) #define HIERNODEINFO(hier) ((hier)->nodeInfo) #define HIERNODEID(hier, i) ((hier)->nodeInfo[i].id) -#define HANIMFRAMES(anim) ((anim)->keyframes) +#define HANIMFRAME(anim, i) ((RwUInt8*)(anim)->keyframes + (i)*(anim)->interpInfo->animKeyFrameSize) #else #define RWHALFPIXEL // always d3d #define STREAMPOS(str) ((str)->Type.memory.position) #define STREAMFILE(str) ((str)->Type.file.fpFile) #define HIERNODEINFO(hier) ((hier)->pNodeInfo) #define HIERNODEID(hier, i) ((hier)->pNodeInfo[i].nodeID) -#define HANIMFRAMES(anim) ((anim)->pFrames) +#define HANIMFRAME(anim, i) ((RwUInt8*)(anim)->pFrames + (i)*(anim)->interpInfo->keyFrameSize) #endif #ifdef RWHALFPIXEL diff --git a/src/rw/RwHelper.cpp b/src/rw/RwHelper.cpp index 191fc7ab..cd2a1bf6 100644 --- a/src/rw/RwHelper.cpp +++ b/src/rw/RwHelper.cpp @@ -319,14 +319,20 @@ HAnimAnimationCreateForHierarchy(RpHAnimHierarchy *hier) RpHAnimAnimation *anim = RpHAnimAnimationCreate(rpHANIMSTDKEYFRAMETYPEID, numNodes, 0, 0.0f); if(anim == nil) return nil; - RpHAnimStdKeyFrame *frame = (RpHAnimStdKeyFrame*)HANIMFRAMES(anim); + RpHAnimStdKeyFrame *frame; for(i = 0; i < numNodes; i++){ + frame = (RpHAnimStdKeyFrame*)HANIMFRAME(anim, i); // games uses struct size here, not safe frame->q.real = 1.0f; frame->q.imag.x = frame->q.imag.y = frame->q.imag.z = 0.0f; frame->t.x = frame->t.y = frame->t.z = 0.0f; +#ifdef FIX_BUGS + // times are subtracted and divided giving NaNs + // so they can't both be 0 + frame->time = i/hier->numNodes; +#else frame->time = 0.0f; +#endif frame->prevFrame = nil; - frame++; } return anim; } From c00f7a8d222dae3f9a3989fefdd875ca2ef19c04 Mon Sep 17 00:00:00 2001 From: aap Date: Mon, 1 Jun 2020 20:50:26 +0200 Subject: [PATCH 24/26] CTimer fix --- src/core/Timer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/Timer.h b/src/core/Timer.h index e7b6fec8..4e8b8805 100644 --- a/src/core/Timer.h +++ b/src/core/Timer.h @@ -18,10 +18,10 @@ public: static const float &GetTimeStep(void) { return ms_fTimeStep; } static void SetTimeStep(float ts) { ms_fTimeStep = ts; } static float GetTimeStepInSeconds() { return ms_fTimeStep / 50.0f; } - static float GetTimeStepInMilliseconds() { return ms_fTimeStep / 50.0f * 1000.0f; } + static uint32 GetTimeStepInMilliseconds() { return ms_fTimeStep / 50.0f * 1000.0f; } static const float &GetTimeStepNonClipped(void) { return ms_fTimeStepNonClipped; } static float GetTimeStepNonClippedInSeconds(void) { return ms_fTimeStepNonClipped / 50.0f; } - static float GetTimeStepNonClippedInMilliseconds(void) { return ms_fTimeStepNonClipped / 50.0f * 1000.0f; } + static uint32 GetTimeStepNonClippedInMilliseconds(void) { return ms_fTimeStepNonClipped / 50.0f * 1000.0f; } static void SetTimeStepNonClipped(float ts) { ms_fTimeStepNonClipped = ts; } static const uint32 &GetFrameCounter(void) { return m_FrameCounter; } static void SetFrameCounter(uint32 fc) { m_FrameCounter = fc; } From 575c5466dfb3d0d0cdaa47a03b601e4f23f6af94 Mon Sep 17 00:00:00 2001 From: aap Date: Tue, 2 Jun 2020 14:38:57 +0200 Subject: [PATCH 25/26] renamed a vehicle thing --- src/vehicles/Automobile.cpp | 18 +++++++++--------- src/vehicles/Vehicle.cpp | 2 +- src/vehicles/Vehicle.h | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 37b224d1..f35dd9e3 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -2241,22 +2241,22 @@ CAutomobile::ProcessControlInputs(uint8 pad) // Steer left/right if(CCamera::m_bUseMouse3rdPerson && !CVehicle::m_bDisableMouseSteering){ if(CPad::GetPad(pad)->GetMouseX() != 0.0f){ - m_fSteerRatio += fMouseSteerSens*CPad::GetPad(pad)->GetMouseX(); + m_fSteerInput += fMouseSteerSens*CPad::GetPad(pad)->GetMouseX(); nLastControlInput = 2; - if(Abs(m_fSteerRatio) < fMouseCentreRange) - m_fSteerRatio *= Pow(fMouseCentreMult, CTimer::GetTimeStep()); + if(Abs(m_fSteerInput) < fMouseCentreRange) + m_fSteerInput *= Pow(fMouseCentreMult, CTimer::GetTimeStep()); }else if(CPad::GetPad(pad)->GetSteeringLeftRight() || nLastControlInput != 2){ // mouse hasn't move, steer with pad like below - m_fSteerRatio += (-CPad::GetPad(pad)->GetSteeringLeftRight()/128.0f - m_fSteerRatio)* + m_fSteerInput += (-CPad::GetPad(pad)->GetSteeringLeftRight()/128.0f - m_fSteerInput)* 0.2f*CTimer::GetTimeStep(); nLastControlInput = 0; } }else{ - m_fSteerRatio += (-CPad::GetPad(pad)->GetSteeringLeftRight()/128.0f - m_fSteerRatio)* + m_fSteerInput += (-CPad::GetPad(pad)->GetSteeringLeftRight()/128.0f - m_fSteerInput)* 0.2f*CTimer::GetTimeStep(); nLastControlInput = 0; } - m_fSteerRatio = clamp(m_fSteerRatio, -1.0f, 1.0f); + m_fSteerInput = clamp(m_fSteerInput, -1.0f, 1.0f); // Accelerate/Brake float acceleration = (CPad::GetPad(pad)->GetAccelerate() - CPad::GetPad(pad)->GetBrake())/255.0f; @@ -2307,10 +2307,10 @@ CAutomobile::ProcessControlInputs(uint8 pad) // Actually turn wheels static float fValue; // why static? - if(m_fSteerRatio < 0.0f) - fValue = -sq(m_fSteerRatio); + if(m_fSteerInput < 0.0f) + fValue = -sq(m_fSteerInput); else - fValue = sq(m_fSteerRatio); + fValue = sq(m_fSteerInput); m_fSteerAngle = DEGTORAD(pHandling->fSteeringLock) * fValue; if(bComedyControls){ diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp index 1132f79f..dbb15b5d 100644 --- a/src/vehicles/Vehicle.cpp +++ b/src/vehicles/Vehicle.cpp @@ -52,7 +52,7 @@ CVehicle::CVehicle(uint8 CreatedBy) m_nCurrentGear = 1; m_fChangeGearTime = 0.0f; - m_fSteerRatio = 0.0f; + m_fSteerInput = 0.0f; m_type = ENTITY_TYPE_VEHICLE; VehicleCreatedBy = CreatedBy; bIsLocked = false; diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h index de4d3f88..89117d40 100644 --- a/src/vehicles/Vehicle.h +++ b/src/vehicles/Vehicle.h @@ -194,7 +194,7 @@ public: bool m_bSirenOrAlarm; int8 m_comedyControlState; CStoredCollPoly m_aCollPolys[2]; // poly which is under front/rear part of car - float m_fSteerRatio; + float m_fSteerInput; eVehicleType m_vehType; static void *operator new(size_t); From 04a91761df7c90ed16b37407d65d8674033efd3f Mon Sep 17 00:00:00 2001 From: aap Date: Tue, 2 Jun 2020 23:34:53 +0200 Subject: [PATCH 26/26] some vehicle cleanup --- src/core/Cam.cpp | 3 ++- src/modelinfo/VehicleModelInfo.cpp | 21 ++++++++-------- src/modelinfo/VehicleModelInfo.h | 38 +++++++++++++++++++++++++++++ src/peds/Ped.cpp | 39 ++++++------------------------ src/vehicles/Automobile.cpp | 28 +++++++++++++++------ src/vehicles/Automobile.h | 16 ------------ src/vehicles/Plane.h | 7 ------ src/vehicles/Train.h | 9 ------- src/vehicles/Vehicle.h | 6 ----- src/weapons/Weapon.cpp | 21 ++++++++-------- 10 files changed, 88 insertions(+), 100 deletions(-) diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index 60145cd0..53c49634 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -5,6 +5,7 @@ #include "World.h" #include "Vehicle.h" #include "Automobile.h" +#include "Boat.h" #include "Ped.h" #include "PlayerPed.h" #include "CopPed.h" @@ -2732,7 +2733,7 @@ CCam::Process_1stPerson(const CVector &CameraTarget, float TargetOrientation, fl }else{ assert(CamTargetEntity->IsVehicle()); CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(CamTargetEntity->GetModelIndex()); - CVector CamPos = mi->m_vehicleType == VEHICLE_TYPE_BOAT ? mi->m_positions[BOAT_POS_FRONTSEAT] : mi->m_positions[CAR_POS_FRONTSEAT]; + CVector CamPos = mi->GetFrontSeatPosn(); CamPos.x = 0.0f; CamPos.y += -0.08f; CamPos.z += 0.62f; diff --git a/src/modelinfo/VehicleModelInfo.cpp b/src/modelinfo/VehicleModelInfo.cpp index 74285c19..d8b388d5 100644 --- a/src/modelinfo/VehicleModelInfo.cpp +++ b/src/modelinfo/VehicleModelInfo.cpp @@ -16,6 +16,7 @@ #include "Train.h" #include "Plane.h" #include "Heli.h" +#include "Bike.h" #include "ModelIndices.h" #include "ModelInfo.h" @@ -120,16 +121,16 @@ RwObjectNameIdAssocation planeIds[] = { }; RwObjectNameIdAssocation bikeIds[] = { - { "chassis_dummy", 1, 0 }, - { "forks_front", 2, 0 }, - { "forks_rear", 3, 0 }, - { "wheel_front", 4, 0 }, - { "wheel_rear", 5, 0 }, - { "mudguard", 6, 0 }, - { "ped_frontseat", 2, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID }, - { "headlights", 0, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID }, - { "taillights", 1, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID }, - { "exhaust", 9, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID }, + { "chassis_dummy", BIKE_CHASSIS, 0 }, + { "forks_front", BIKE_FORKS_FRONT, 0 }, + { "forks_rear", BIKE_FORKS_REAR, 0 }, + { "wheel_front", BIKE_WHEEL_FRONT, 0 }, + { "wheel_rear", BIKE_WHEEL_REAR, 0 }, + { "mudguard", BIKE_MUDGUARD, 0 }, + { "ped_frontseat", CAR_POS_FRONTSEAT, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID }, + { "headlights", CAR_POS_HEADLIGHTS, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID }, + { "taillights", CAR_POS_TAILLIGHTS, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID }, + { "exhaust", CAR_POS_EXHAUST, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID }, { "extra1", 0, VEHICLE_FLAG_DRAWLAST | VEHICLE_FLAG_COMP | CLUMP_FLAG_NO_HIERID }, { "extra2", 0, VEHICLE_FLAG_DRAWLAST | VEHICLE_FLAG_COMP | CLUMP_FLAG_NO_HIERID }, { "extra3", 0, VEHICLE_FLAG_DRAWLAST | VEHICLE_FLAG_COMP | CLUMP_FLAG_NO_HIERID }, diff --git a/src/modelinfo/VehicleModelInfo.h b/src/modelinfo/VehicleModelInfo.h index ba25d3cd..468ce96d 100644 --- a/src/modelinfo/VehicleModelInfo.h +++ b/src/modelinfo/VehicleModelInfo.h @@ -35,6 +35,43 @@ enum eVehicleType { NUM_VEHICLE_TYPES }; +enum eCarPositions +{ + CAR_POS_HEADLIGHTS, + CAR_POS_TAILLIGHTS, + CAR_POS_FRONTSEAT, + CAR_POS_BACKSEAT, + // these are unused so we don't know the actual values + CAR_POS_REVERSELIGHTS, + CAR_POS_BRAKELIGHTS, + CAR_POS_INDICATORS_FRONT, + CAR_POS_INDICATORS_BACK, + CAR_POS_STEERWHEEL, + // + CAR_POS_EXHAUST +}; + +enum eBoatPositions +{ + BOAT_POS_FRONTSEAT +}; + +enum eTrainPositions +{ + TRAIN_POS_LIGHT_FRONT, + TRAIN_POS_LIGHT_REAR, + TRAIN_POS_LEFT_ENTRY, + TRAIN_POS_MID_ENTRY, + TRAIN_POS_RIGHT_ENTRY +}; + +enum ePlanePositions +{ + PLANE_POS_LIGHT_LEFT, + PLANE_POS_LIGHT_RIGHT, + PLANE_POS_LIGHT_TAIL, +}; + enum { NUM_VEHICLE_POSITIONS = 10 }; @@ -100,6 +137,7 @@ public: void SetVehicleComponentFlags(RwFrame *frame, uint32 flags); void PreprocessHierarchy(void); void GetWheelPosn(int32 n, CVector &pos); + CVector &GetFrontSeatPosn(void) { return m_positions[m_vehicleType == VEHICLE_TYPE_BOAT ? BOAT_POS_FRONTSEAT : CAR_POS_FRONTSEAT]; }; int32 ChooseComponent(void); int32 ChooseSecondComponent(void); diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index 6b3b8686..055581ad 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -1682,11 +1682,7 @@ CPed::GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float seatP switch (component) { case CAR_DOOR_RF: - if (vehModel->m_vehicleType == VEHICLE_TYPE_BOAT) - vehDoorPos = vehModel->m_positions[BOAT_POS_FRONTSEAT]; - else - vehDoorPos = vehModel->m_positions[CAR_POS_FRONTSEAT]; - + vehDoorPos = vehModel->GetFrontSeatPosn(); vehDoorPos.x += seatOffset; vehDoorOffset.x = -vehDoorOffset.x; break; @@ -1698,11 +1694,7 @@ CPed::GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float seatP break; case CAR_DOOR_LF: - if (vehModel->m_vehicleType == VEHICLE_TYPE_BOAT) - vehDoorPos = vehModel->m_positions[BOAT_POS_FRONTSEAT]; - else - vehDoorPos = vehModel->m_positions[CAR_POS_FRONTSEAT]; - + vehDoorPos = vehModel->GetFrontSeatPosn(); vehDoorPos.x = -(vehDoorPos.x + seatOffset); break; @@ -1712,11 +1704,7 @@ CPed::GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float seatP break; default: - if (vehModel->m_vehicleType == VEHICLE_TYPE_BOAT) - vehDoorPos = vehModel->m_positions[BOAT_POS_FRONTSEAT]; - else - vehDoorPos = vehModel->m_positions[CAR_POS_FRONTSEAT]; - + vehDoorPos = vehModel->GetFrontSeatPosn(); vehDoorOffset = CVector(0.0f, 0.0f, 0.0f); } return vehDoorPos - vehDoorOffset; @@ -15031,11 +15019,7 @@ CPed::SeekBoatPosition(void) CVehicleModelInfo *boatModel = m_carInObjective->GetModelInfo(); CVector enterOffset; - if (boatModel->m_vehicleType == VEHICLE_TYPE_BOAT) - enterOffset = boatModel->m_positions[BOAT_POS_FRONTSEAT]; - else - enterOffset = boatModel->m_positions[CAR_POS_FRONTSEAT]; - + enterOffset = boatModel->GetFrontSeatPosn(); enterOffset.x = 0.0f; CMatrix boatMat(m_carInObjective->GetMatrix()); SetMoveState(PEDMOVE_WALK); @@ -16817,29 +16801,20 @@ CPed::SetPedPositionInCar(void) CMatrix newMat(m_pMyVehicle->GetMatrix()); CVector seatPos; if (m_pMyVehicle->pDriver == this) { - if (vehModel->m_vehicleType == VEHICLE_TYPE_BOAT) - seatPos = vehModel->m_positions[BOAT_POS_FRONTSEAT]; - else - seatPos = vehModel->m_positions[CAR_POS_FRONTSEAT]; - + seatPos = vehModel->GetFrontSeatPosn(); if (!m_pMyVehicle->IsBoat() && m_pMyVehicle->m_vehType != VEHICLE_TYPE_BIKE) seatPos.x = -seatPos.x; } else if (m_pMyVehicle->pPassengers[0] == this) { - if (vehModel->m_vehicleType == VEHICLE_TYPE_BOAT) - seatPos = vehModel->m_positions[BOAT_POS_FRONTSEAT]; - else - seatPos = vehModel->m_positions[CAR_POS_FRONTSEAT]; + seatPos = vehModel->GetFrontSeatPosn(); } else if (m_pMyVehicle->pPassengers[1] == this) { seatPos = vehModel->m_positions[CAR_POS_BACKSEAT]; seatPos.x = -seatPos.x; } else { if (m_pMyVehicle->pPassengers[2] == this) { seatPos = vehModel->m_positions[CAR_POS_BACKSEAT]; - } else if (vehModel->m_vehicleType == VEHICLE_TYPE_BOAT) { - seatPos = vehModel->m_positions[BOAT_POS_FRONTSEAT]; } else { - seatPos = vehModel->m_positions[CAR_POS_FRONTSEAT]; + seatPos = vehModel->GetFrontSeatPosn(); } } newMat.GetPosition() += Multiply3x3(newMat, seatPos); diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index f35dd9e3..9aa5ae7c 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -145,8 +145,7 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy) for(i = 0; i < 4; i++){ m_aGroundPhysical[i] = nil; m_aGroundOffset[i] = CVector(0.0f, 0.0f, 0.0f); - m_aSuspensionSpringRatio[i] = 1.0f; - m_aSuspensionSpringRatioPrev[i] = m_aSuspensionSpringRatio[i]; + m_aSuspensionSpringRatioPrev[i] = m_aSuspensionSpringRatio[i] = 1.0f; m_aWheelTimer[i] = 0.0f; m_aWheelRotation[i] = 0.0f; m_aWheelSpeed[i] = 0.0f; @@ -2314,6 +2313,17 @@ CAutomobile::ProcessControlInputs(uint8 pad) m_fSteerAngle = DEGTORAD(pHandling->fSteeringLock) * fValue; if(bComedyControls){ +#if 0 // old comedy controls from PS2 - same as bike's + if(((CTimer::GetTimeInMilliseconds() >> 10) & 0xF) < 12) + m_fGasPedal = 1.0f; + if((((CTimer::GetTimeInMilliseconds() >> 10)+6) & 0xF) < 12) + m_fBrakePedal = 0.0f; + bIsHandbrakeOn = false; + if(CTimer::GetTimeInMilliseconds() & 0x800) + m_fSteerAngle += 0.08f; + else + m_fSteerAngle -= 0.03f; +#else int rnd = CGeneral::GetRandomNumber() % 10; switch(m_comedyControlState){ case 0: @@ -2333,8 +2343,10 @@ CAutomobile::ProcessControlInputs(uint8 pad) m_comedyControlState = 0; break; } - }else + }else{ m_comedyControlState = 0; +#endif + } // Brake if player isn't in control // BUG: game always uses pad 0 here @@ -3948,8 +3960,8 @@ CAutomobile::BurstTyre(uint8 wheel) CCarCtrl::SwitchVehicleToRealPhysics(this); } - ApplyMoveForce(GetRight() * CGeneral::GetRandomNumberInRange(-0.3f, 0.3f)); - ApplyTurnForce(GetRight() * CGeneral::GetRandomNumberInRange(-0.3f, 0.3f), GetForward()); + ApplyMoveForce(GetRight() * m_fMass * CGeneral::GetRandomNumberInRange(-0.03f, 0.03f)); + ApplyTurnForce(GetRight() * m_fTurnMass * CGeneral::GetRandomNumberInRange(-0.03f, 0.03f), GetForward()); } } @@ -3964,10 +3976,10 @@ CAutomobile::IsRoomForPedToLeaveCar(uint32 component, CVector *doorOffset) CVector seatPos; switch(component){ case CAR_DOOR_RF: - seatPos = mi->m_positions[mi->m_vehicleType == VEHICLE_TYPE_BOAT ? BOAT_POS_FRONTSEAT : CAR_POS_FRONTSEAT]; + seatPos = mi->GetFrontSeatPosn(); break; case CAR_DOOR_LF: - seatPos = mi->m_positions[mi->m_vehicleType == VEHICLE_TYPE_BOAT ? BOAT_POS_FRONTSEAT : CAR_POS_FRONTSEAT]; + seatPos = mi->GetFrontSeatPosn(); seatPos.x = -seatPos.x; break; case CAR_DOOR_RR: @@ -4558,7 +4570,7 @@ CAutomobile::SetupModelNodes(void) int i; for(i = 0; i < NUM_CAR_NODES; i++) m_aCarNodes[i] = nil; - CClumpModelInfo::FillFrameArray((RpClump*)m_rwObject, m_aCarNodes); + CClumpModelInfo::FillFrameArray(GetClump(), m_aCarNodes); } void diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h index 8fa7ed67..604bed17 100644 --- a/src/vehicles/Automobile.h +++ b/src/vehicles/Automobile.h @@ -30,22 +30,6 @@ enum eCarNodes NUM_CAR_NODES, }; -enum eCarPositions -{ - CAR_POS_HEADLIGHTS, - CAR_POS_TAILLIGHTS, - CAR_POS_FRONTSEAT, - CAR_POS_BACKSEAT, - // these are unused so we don't know the actual values - CAR_POS_REVERSELIGHTS, - CAR_POS_BRAKELIGHTS, - CAR_POS_INDICATORS_FRONT, - CAR_POS_INDICATORS_BACK, - CAR_POS_STEERWHEEL, - // - CAR_POS_EXHAUST -}; - // These are used for all the wheel arrays // DON'T confuse with VEHWHEEL, which are vehicle components enum { diff --git a/src/vehicles/Plane.h b/src/vehicles/Plane.h index a6f6e1d9..783c53b3 100644 --- a/src/vehicles/Plane.h +++ b/src/vehicles/Plane.h @@ -9,13 +9,6 @@ enum ePlaneNodes NUM_PLANE_NODES }; -enum ePlanePositions -{ - PLANE_POS_LIGHT_LEFT, - PLANE_POS_LIGHT_RIGHT, - PLANE_POS_LIGHT_TAIL, -}; - struct CPlaneNode { CVector p; // position diff --git a/src/vehicles/Train.h b/src/vehicles/Train.h index c645ecaf..3446eeb5 100644 --- a/src/vehicles/Train.h +++ b/src/vehicles/Train.h @@ -24,15 +24,6 @@ enum eTrainNodes NUM_TRAIN_NODES }; -enum eTrainPositions -{ - TRAIN_POS_LIGHT_FRONT, - TRAIN_POS_LIGHT_REAR, - TRAIN_POS_LEFT_ENTRY, - TRAIN_POS_MID_ENTRY, - TRAIN_POS_RIGHT_ENTRY -}; - struct CTrainNode { CVector p; // position diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h index 89117d40..c9b6c9e3 100644 --- a/src/vehicles/Vehicle.h +++ b/src/vehicles/Vehicle.h @@ -28,12 +28,6 @@ enum eCarLock { CARLOCK_SKIP_SHUT_DOORS }; - -enum -{ - BOAT_POS_FRONTSEAT -}; - enum eDoors { DOOR_BONNET = 0, diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp index 93481105..378e621a 100644 --- a/src/weapons/Weapon.cpp +++ b/src/weapons/Weapon.cpp @@ -25,7 +25,8 @@ #include "Stats.h" #include "TempColModels.h" #include "Timer.h" -#include "Vehicle.h" +#include "Automobile.h" +#include "Boat.h" #include "WaterLevel.h" #include "WeaponInfo.h" #include "World.h" @@ -1631,31 +1632,29 @@ CWeapon::FireInstantHitFromCar(CAutomobile *shooter, bool left) CVehicleModelInfo *modelInfo = shooter->GetModelInfo(); - #define FRONTSEATPOS() (&(shooter->IsBoat() ? modelInfo->m_positions[BOAT_POS_FRONTSEAT] : modelInfo->m_positions[CAR_POS_FRONTSEAT])) - CVector source, target; if ( left ) { source = shooter->GetMatrix() * CVector(-shooter->GetColModel()->boundingBox.max.x + -0.2f, - float(CGeneral::GetRandomNumber() & 255) * 0.001f + FRONTSEATPOS()->y, - FRONTSEATPOS()->z + 0.5f); + float(CGeneral::GetRandomNumber() & 255) * 0.001f + modelInfo->GetFrontSeatPosn().y, + modelInfo->GetFrontSeatPosn().z + 0.5f); source += CTimer::GetTimeStep() * shooter->m_vecMoveSpeed; target = shooter->GetMatrix() * CVector(-info->m_fRange, - FRONTSEATPOS()->y, - FRONTSEATPOS()->z + 0.5f); + modelInfo->GetFrontSeatPosn().y, + modelInfo->GetFrontSeatPosn().z + 0.5f); } else { source = shooter->GetMatrix() * CVector(shooter->GetColModel()->boundingBox.max.x + 0.2f, - float(CGeneral::GetRandomNumber() & 255) * 0.001f + FRONTSEATPOS()->y, - FRONTSEATPOS()->z + 0.5f); + float(CGeneral::GetRandomNumber() & 255) * 0.001f + modelInfo->GetFrontSeatPosn().y, + modelInfo->GetFrontSeatPosn().z + 0.5f); source += CTimer::GetTimeStep() * shooter->m_vecMoveSpeed; target = shooter->GetMatrix() * CVector(info->m_fRange, - FRONTSEATPOS()->y, - FRONTSEATPOS()->z + 0.5f); + modelInfo->GetFrontSeatPosn().y, + modelInfo->GetFrontSeatPosn().z + 0.5f); } #undef FRONTSEATPOS